added restrict to inventory and better blacklist

This commit is contained in:
MaxRobinsonTheGreat 2025-01-09 15:15:25 -06:00
parent 85ef0e8103
commit 6167aeeec4
7 changed files with 38 additions and 8 deletions

View file

@ -17,6 +17,14 @@
},
"type": "debug"
},
"debug_inventory_restriction": {
"goal": "Place 1 oak plank, then place 1 stone brick",
"initial_inventory": {
"oak_planks": 20
},
"type": "debug",
"restrict_to_inventory": true
},
"construction": {
"type": "construction",
"goal": "Build a house",

View file

@ -3,7 +3,7 @@ import { Coder } from './coder.js';
import { Prompter } from './prompter.js';
import { initModes } from './modes.js';
import { initBot } from '../utils/mcdata.js';
import { containsCommand, commandExists, executeCommand, truncCommandMessage, isAction } from './commands/index.js';
import { containsCommand, commandExists, executeCommand, truncCommandMessage, isAction, blacklistCommands } from './commands/index.js';
import { ActionManager } from './action_manager.js';
import { NPCContoller } from './npc/controller.js';
import { MemoryBank } from './memory_bank.js';
@ -47,7 +47,8 @@ export class Agent {
await this.prompter.initExamples();
console.log('Initializing task...');
this.task = new Task(this, task_path, task_id);
this.blocked_actions = this.task.blocked_actions || [];
const blocked_actions = this.task.blocked_actions || [];
blacklistCommands(blocked_actions);
serverProxy.connect(this);

View file

@ -14,6 +14,18 @@ export function getCommand(name) {
return commandMap[name];
}
export function blacklistCommands(commands) {
const unblockable = ['!stop', '!stats', '!goal', '!endGoal', '!endConversation'];
for (let command_name of commands) {
if (unblockable.includes(command_name)){
console.warn(`Command ${command_name} is unblockable`);
continue;
}
delete commandMap[command_name];
delete commandList.find(command => command.name === command_name);
}
}
const commandRegex = /!(\w+)(?:\(((?:-?\d+(?:\.\d+)?|true|false|"[^"]*")(?:\s*,\s*(?:-?\d+(?:\.\d+)?|true|false|"[^"]*"))*)\))?/
const argRegex = /-?\d+(?:\.\d+)?|true|false|"[^"]*"/g;
@ -214,7 +226,7 @@ export async function executeCommand(agent, message) {
}
}
export function getCommandDocs(blacklist=null) {
export function getCommandDocs() {
const typeTranslations = {
//This was added to keep the prompt the same as before type checks were implemented.
//If the language model is giving invalid inputs changing this might help.
@ -228,9 +240,6 @@ export function getCommandDocs(blacklist=null) {
Use the commands with the syntax: !commandName or !commandName("arg1", 1.2, ...) if the command takes arguments.\n
Do not use codeblocks. Use double quotes for strings. Only use one command in each response, trailing commands and comments will be ignored.\n`;
for (let command of commandList) {
if (blacklist && blacklist.includes(command.name)) {
continue;
}
docs += command.name + ': ' + command.description + '\n';
if (command.params) {
docs += 'Params:\n';

View file

@ -558,6 +558,14 @@ export async function placeBlock(bot, blockType, x, y, z, placeOn='bottom', dont
const target_dest = new Vec3(Math.floor(x), Math.floor(y), Math.floor(z));
if (bot.modes.isOn('cheat') && !dontCheat) {
if (bot.restrict_to_inventory) {
let block = bot.inventory.items().find(item => item.name === blockType);
if (!block) {
log(bot, `Cannot place ${blockType}, you are restricted to your current inventory.`);
return false;
}
}
// invert the facing direction
let face = placeOn === 'north' ? 'south' : placeOn === 'south' ? 'north' : placeOn === 'east' ? 'west' : 'east';
if (blockType.includes('torch') && placeOn !== 'bottom') {
@ -599,7 +607,7 @@ export async function placeBlock(bot, blockType, x, y, z, placeOn='bottom', dont
if (item_name == "redstone_wire")
item_name = "redstone";
let block = bot.inventory.items().find(item => item.name === item_name);
if (!block && bot.game.gameMode === 'creative') {
if (!block && bot.game.gameMode === 'creative' && !bot.restrict_to_inventory) {
await bot.creative.setInventorySlot(36, mc.makeItem(item_name, 1)); // 36 is first hotbar slot
block = bot.inventory.items().find(item => item.name === item_name);
}

View file

@ -404,6 +404,9 @@ export function initModes(agent) {
_agent = agent;
// the mode controller is added to the bot object so it is accessible from anywhere the bot is used
agent.bot.modes = new ModeController();
if (agent.task) {
agent.bot.restrict_to_inventory = agent.task.restrict_to_inventory;
}
let modes_json = agent.prompter.getInitModes();
if (modes_json) {
agent.bot.modes.loadJson(modes_json);

View file

@ -186,7 +186,7 @@ export class Prompter {
prompt = prompt.replaceAll('$ACTION', this.agent.actions.currentActionLabel);
}
if (prompt.includes('$COMMAND_DOCS'))
prompt = prompt.replaceAll('$COMMAND_DOCS', getCommandDocs(this.agent.blocked_actions));
prompt = prompt.replaceAll('$COMMAND_DOCS', getCommandDocs());
if (prompt.includes('$CODE_DOCS'))
prompt = prompt.replaceAll('$CODE_DOCS', getSkillDocs());
if (prompt.includes('$EXAMPLES') && examples !== null)

View file

@ -51,6 +51,7 @@ export class Task {
this.taskStartTime = Date.now();
this.validator = new TaskValidator(this.data, this.agent);
this.blocked_actions = this.data.blocked_actions || [];
this.restrict_to_inventory = !!this.data.restrict_to_inventory;
if (this.data.goal)
this.blocked_actions.push('!endGoal');
if (this.data.conversation)