mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-08-02 13:25:31 +02:00
commit
a95fa33266
10 changed files with 51 additions and 17 deletions
|
@ -17,6 +17,14 @@
|
||||||
},
|
},
|
||||||
"type": "debug"
|
"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": {
|
"construction": {
|
||||||
"type": "construction",
|
"type": "construction",
|
||||||
"goal": "Build a house",
|
"goal": "Build a house",
|
||||||
|
|
|
@ -35,7 +35,8 @@ export default
|
||||||
"code_timeout_mins": 10, // minutes code is allowed to run. -1 for no timeout
|
"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_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
|
"verbose_commands": true, // show full command syntax
|
||||||
"narrate_behavior": true, // chat simple automatic actions ('Picking up item!')
|
"narrate_behavior": true, // chat simple automatic actions ('Picking up item!')
|
||||||
"chat_bot_messages": true, // publicly chat messages to other bots
|
"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 { Prompter } from './prompter.js';
|
||||||
import { initModes } from './modes.js';
|
import { initModes } from './modes.js';
|
||||||
import { initBot } from '../utils/mcdata.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 { ActionManager } from './action_manager.js';
|
||||||
import { NPCContoller } from './npc/controller.js';
|
import { NPCContoller } from './npc/controller.js';
|
||||||
import { MemoryBank } from './memory_bank.js';
|
import { MemoryBank } from './memory_bank.js';
|
||||||
|
@ -47,7 +47,8 @@ export class Agent {
|
||||||
await this.prompter.initExamples();
|
await this.prompter.initExamples();
|
||||||
console.log('Initializing task...');
|
console.log('Initializing task...');
|
||||||
this.task = new Task(this, task_path, task_id);
|
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);
|
serverProxy.connect(this);
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,18 @@ export function getCommand(name) {
|
||||||
return commandMap[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 commandRegex = /!(\w+)(?:\(((?:-?\d+(?:\.\d+)?|true|false|"[^"]*")(?:\s*,\s*(?:-?\d+(?:\.\d+)?|true|false|"[^"]*"))*)\))?/
|
||||||
const argRegex = /-?\d+(?:\.\d+)?|true|false|"[^"]*"/g;
|
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 = {
|
const typeTranslations = {
|
||||||
//This was added to keep the prompt the same as before type checks were implemented.
|
//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.
|
//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
|
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`;
|
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) {
|
for (let command of commandList) {
|
||||||
if (blacklist && blacklist.includes(command.name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
docs += command.name + ': ' + command.description + '\n';
|
docs += command.name + ': ' + command.description + '\n';
|
||||||
if (command.params) {
|
if (command.params) {
|
||||||
docs += 'Params:\n';
|
docs += 'Params:\n';
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as world from '../library/world.js';
|
import * as world from '../library/world.js';
|
||||||
import * as mc from '../../utils/mcdata.js';
|
import * as mc from '../../utils/mcdata.js';
|
||||||
|
import { getCommandDocs } from './index.js';
|
||||||
import convoManager from '../conversation.js';
|
import convoManager from '../conversation.js';
|
||||||
|
|
||||||
const pad = (str) => {
|
const pad = (str) => {
|
||||||
|
@ -181,12 +182,7 @@ export const queryList = [
|
||||||
name: '!help',
|
name: '!help',
|
||||||
description: 'Lists all available commands and their descriptions.',
|
description: 'Lists all available commands and their descriptions.',
|
||||||
perform: async function (agent) {
|
perform: async function (agent) {
|
||||||
const commandList = actionsList.map(action => {
|
return getCommandDocs();
|
||||||
return `${action.name.padEnd(15)} - ${action.description}`; // Ensure consistent spacing
|
|
||||||
}).join('\n');
|
|
||||||
|
|
||||||
console.log(commandList);
|
|
||||||
return `Available Commands:\n${commandList}`;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -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));
|
const target_dest = new Vec3(Math.floor(x), Math.floor(y), Math.floor(z));
|
||||||
if (bot.modes.isOn('cheat') && !dontCheat) {
|
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
|
// invert the facing direction
|
||||||
let face = placeOn === 'north' ? 'south' : placeOn === 'south' ? 'north' : placeOn === 'east' ? 'west' : 'east';
|
let face = placeOn === 'north' ? 'south' : placeOn === 'south' ? 'north' : placeOn === 'east' ? 'west' : 'east';
|
||||||
if (blockType.includes('torch') && placeOn !== 'bottom') {
|
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")
|
if (item_name == "redstone_wire")
|
||||||
item_name = "redstone";
|
item_name = "redstone";
|
||||||
let block = bot.inventory.items().find(item => item.name === item_name);
|
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
|
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);
|
block = bot.inventory.items().find(item => item.name === item_name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,6 +404,9 @@ export function initModes(agent) {
|
||||||
_agent = agent;
|
_agent = agent;
|
||||||
// the mode controller is added to the bot object so it is accessible from anywhere the bot is used
|
// the mode controller is added to the bot object so it is accessible from anywhere the bot is used
|
||||||
agent.bot.modes = new ModeController();
|
agent.bot.modes = new ModeController();
|
||||||
|
if (agent.task) {
|
||||||
|
agent.bot.restrict_to_inventory = agent.task.restrict_to_inventory;
|
||||||
|
}
|
||||||
let modes_json = agent.prompter.getInitModes();
|
let modes_json = agent.prompter.getInitModes();
|
||||||
if (modes_json) {
|
if (modes_json) {
|
||||||
agent.bot.modes.loadJson(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 { getSkillDocs } from './library/index.js';
|
||||||
import { stringifyTurns } from '../utils/text.js';
|
import { stringifyTurns } from '../utils/text.js';
|
||||||
import { getCommand } from './commands/index.js';
|
import { getCommand } from './commands/index.js';
|
||||||
|
import settings from '../../settings.js';
|
||||||
|
|
||||||
import { Gemini } from '../models/gemini.js';
|
import { Gemini } from '../models/gemini.js';
|
||||||
import { GPT } from '../models/gpt.js';
|
import { GPT } from '../models/gpt.js';
|
||||||
|
@ -155,8 +156,8 @@ export class Prompter {
|
||||||
|
|
||||||
async initExamples() {
|
async initExamples() {
|
||||||
try {
|
try {
|
||||||
this.convo_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);
|
this.coding_examples = new Examples(this.embedding_model, settings.num_examples);
|
||||||
|
|
||||||
// Wait for both examples to load before proceeding
|
// Wait for both examples to load before proceeding
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
@ -186,7 +187,7 @@ export class Prompter {
|
||||||
prompt = prompt.replaceAll('$ACTION', this.agent.actions.currentActionLabel);
|
prompt = prompt.replaceAll('$ACTION', this.agent.actions.currentActionLabel);
|
||||||
}
|
}
|
||||||
if (prompt.includes('$COMMAND_DOCS'))
|
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'))
|
if (prompt.includes('$CODE_DOCS'))
|
||||||
prompt = prompt.replaceAll('$CODE_DOCS', getSkillDocs());
|
prompt = prompt.replaceAll('$CODE_DOCS', getSkillDocs());
|
||||||
if (prompt.includes('$EXAMPLES') && examples !== null)
|
if (prompt.includes('$EXAMPLES') && examples !== null)
|
||||||
|
|
|
@ -51,6 +51,7 @@ export class Task {
|
||||||
this.taskStartTime = Date.now();
|
this.taskStartTime = Date.now();
|
||||||
this.validator = new TaskValidator(this.data, this.agent);
|
this.validator = new TaskValidator(this.data, this.agent);
|
||||||
this.blocked_actions = this.data.blocked_actions || [];
|
this.blocked_actions = this.data.blocked_actions || [];
|
||||||
|
this.restrict_to_inventory = !!this.data.restrict_to_inventory;
|
||||||
if (this.data.goal)
|
if (this.data.goal)
|
||||||
this.blocked_actions.push('!endGoal');
|
this.blocked_actions.push('!endGoal');
|
||||||
if (this.data.conversation)
|
if (this.data.conversation)
|
||||||
|
|
|
@ -33,6 +33,9 @@ export class Examples {
|
||||||
this.examples = examples;
|
this.examples = examples;
|
||||||
if (!this.model) return; // Early return if no embedding model
|
if (!this.model) return; // Early return if no embedding model
|
||||||
|
|
||||||
|
if (this.select_num === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Create array of promises first
|
// Create array of promises first
|
||||||
const embeddingPromises = examples.map(example => {
|
const embeddingPromises = examples.map(example => {
|
||||||
|
@ -52,6 +55,9 @@ export class Examples {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRelevant(turns) {
|
async getRelevant(turns) {
|
||||||
|
if (this.select_num === 0)
|
||||||
|
return [];
|
||||||
|
|
||||||
let turn_text = this.turnsToText(turns);
|
let turn_text = this.turnsToText(turns);
|
||||||
if (this.model !== null) {
|
if (this.model !== null) {
|
||||||
let embedding = await this.model.embed(turn_text);
|
let embedding = await this.model.embed(turn_text);
|
||||||
|
|
Loading…
Add table
Reference in a new issue