mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-07-31 12:25:31 +02:00
commit
a95fa33266
10 changed files with 51 additions and 17 deletions
|
@ -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",
|
||||
|
|
|
@ -35,7 +35,8 @@ export default
|
|||
"code_timeout_mins": 10, // minutes code is allowed to run. -1 for no timeout
|
||||
|
||||
"max_messages": 15, // max number of messages to keep in context
|
||||
"max_commands": -1, // max number of commands to use in a response. -1 for no limit
|
||||
"num_examples": 2, // number of examples to give to the model
|
||||
"max_commands": -1, // max number of commands that can be used in consecutive responses. -1 for no limit
|
||||
"verbose_commands": true, // show full command syntax
|
||||
"narrate_behavior": true, // chat simple automatic actions ('Picking up item!')
|
||||
"chat_bot_messages": true, // publicly chat messages to other bots
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -14,6 +14,18 @@ export function getCommand(name) {
|
|||
return commandMap[name];
|
||||
}
|
||||
|
||||
export function blacklistCommands(commands) {
|
||||
const unblockable = ['!stop', '!stats', '!inventory', '!goal'];
|
||||
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';
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as world from '../library/world.js';
|
||||
import * as mc from '../../utils/mcdata.js';
|
||||
import { getCommandDocs } from './index.js';
|
||||
import convoManager from '../conversation.js';
|
||||
|
||||
const pad = (str) => {
|
||||
|
@ -181,12 +182,7 @@ export const queryList = [
|
|||
name: '!help',
|
||||
description: 'Lists all available commands and their descriptions.',
|
||||
perform: async function (agent) {
|
||||
const commandList = actionsList.map(action => {
|
||||
return `${action.name.padEnd(15)} - ${action.description}`; // Ensure consistent spacing
|
||||
}).join('\n');
|
||||
|
||||
console.log(commandList);
|
||||
return `Available Commands:\n${commandList}`;
|
||||
return getCommandDocs();
|
||||
}
|
||||
},
|
||||
];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -4,6 +4,7 @@ import { getCommandDocs } from './commands/index.js';
|
|||
import { getSkillDocs } from './library/index.js';
|
||||
import { stringifyTurns } from '../utils/text.js';
|
||||
import { getCommand } from './commands/index.js';
|
||||
import settings from '../../settings.js';
|
||||
|
||||
import { Gemini } from '../models/gemini.js';
|
||||
import { GPT } from '../models/gpt.js';
|
||||
|
@ -155,8 +156,8 @@ export class Prompter {
|
|||
|
||||
async initExamples() {
|
||||
try {
|
||||
this.convo_examples = new Examples(this.embedding_model);
|
||||
this.coding_examples = new Examples(this.embedding_model);
|
||||
this.convo_examples = new Examples(this.embedding_model, settings.num_examples);
|
||||
this.coding_examples = new Examples(this.embedding_model, settings.num_examples);
|
||||
|
||||
// Wait for both examples to load before proceeding
|
||||
await Promise.all([
|
||||
|
@ -186,7 +187,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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -33,6 +33,9 @@ export class Examples {
|
|||
this.examples = examples;
|
||||
if (!this.model) return; // Early return if no embedding model
|
||||
|
||||
if (this.select_num === 0)
|
||||
return;
|
||||
|
||||
try {
|
||||
// Create array of promises first
|
||||
const embeddingPromises = examples.map(example => {
|
||||
|
@ -52,6 +55,9 @@ export class Examples {
|
|||
}
|
||||
|
||||
async getRelevant(turns) {
|
||||
if (this.select_num === 0)
|
||||
return [];
|
||||
|
||||
let turn_text = this.turnsToText(turns);
|
||||
if (this.model !== null) {
|
||||
let embedding = await this.model.embed(turn_text);
|
||||
|
|
Loading…
Add table
Reference in a new issue