diff --git a/src/agent/agent.js b/src/agent/agent.js index 4ec5805..ca9cfa7 100644 --- a/src/agent/agent.js +++ b/src/agent/agent.js @@ -169,13 +169,13 @@ export class Agent { this.coder.executeDefault(); }); - this.self_defense = true; - this.defending = false; - this._pause_defending = false; - // set interval every 300ms to update the bot's state this.update_interval = setInterval(async () => { this.bot.modes.update(); }, 300); } + + isIdle() { + return !this.coder.executing && !this.coder.generating; + } } diff --git a/src/agent/coder.js b/src/agent/coder.js index ec98da0..9e973c7 100644 --- a/src/agent/coder.js +++ b/src/agent/coder.js @@ -10,6 +10,7 @@ export class Coder { this.file_counter = 0; this.fp = '/bots/'+agent.name+'/action-code/'; this.executing = false; + this.generating = false; this.code_template = ''; this.timedout = false; this.default_func = null; @@ -65,7 +66,7 @@ export class Coder { } santitizeCode(code) { - const remove_strs = ['javascript', 'js'] + const remove_strs = ['Javascript', 'javascript', 'js'] for (let r of remove_strs) { if (code.startsWith(r)) { code = code.slice(r.length); @@ -89,6 +90,15 @@ export class Coder { } async generateCode(agent_history) { + // wrapper to prevent overlapping code generation loops + await this.stop(); + this.generating = true; + await this.generateCodeLoop(agent_history); + this.generating = false; + } + + + async generateCodeLoop(agent_history) { let system_message = "You are a minecraft mineflayer bot that plays minecraft by writing javascript codeblocks. Given the conversation between you and the user, use the provided skills and world functions to write your code in a codeblock. Example response: ``` // your code here ``` You will then be given a response to your code. If you are satisfied with the response, respond without a codeblock in a conversational way. If something went wrong, write another codeblock and try to fix the problem."; system_message += getSkillDocs(); @@ -99,6 +109,8 @@ export class Coder { let code_return = null; let failures = 0; for (let i=0; i<5; i++) { + if (this.agent.bot.interrupt_code) + return; console.log(messages) let res = await sendRequest(messages, system_message); console.log('Code generation response:', res) @@ -144,11 +156,7 @@ export class Coder { role: 'system', content: code_return.message }); - - if (this.agent.bot.interrupt_code) - return; } - return; } @@ -191,8 +199,10 @@ export class Coder { if (!interrupted) this.agent.bot.emit('idle'); return {success:true, message: output, interrupted, timedout}; } catch (err) { - console.error("Code execution triggered catch: " + err); + this.executing = false; clearTimeout(TIMEOUT); + + console.error("Code execution triggered catch: " + err); await this.stop(); let message = this.formatOutput(this.agent.bot) + '!!Code threw exception!! Error: ' + err; diff --git a/src/agent/commands/actions.js b/src/agent/commands/actions.js index 49b1ac6..ca2cbb3 100644 --- a/src/agent/commands/actions.js +++ b/src/agent/commands/actions.js @@ -73,10 +73,14 @@ export const actionsList = [ }, { name: '!givePlayer', - description: 'Give the specified item to the given player. Ex: !givePlayer("steve", "stone_pickaxe")', - params: { 'player_name': '(string) The name of the player to give the item to.', 'item_name': '(string) The name of the item to give.' }, - perform: wrapExecution(async (agent, player_name, item_name) => { - await skills.giveToPlayer(agent.bot, item_name, player_name); + description: 'Give the specified item to the given player. Ex: !givePlayer("steve", "stone_pickaxe", 1)', + params: { + 'player_name': '(string) The name of the player to give the item to.', + 'item_name': '(string) The name of the item to give.' , + 'num': '(number) The number of items to give.' + }, + perform: wrapExecution(async (agent, player_name, item_name, num) => { + await skills.giveToPlayer(agent.bot, item_name, player_name, num); }) }, { diff --git a/src/agent/library/skills.js b/src/agent/library/skills.js index 9753ed3..e2fc8c0 100644 --- a/src/agent/library/skills.js +++ b/src/agent/library/skills.js @@ -4,7 +4,7 @@ import pf from 'mineflayer-pathfinder'; import Vec3 from 'vec3'; -function log(bot, message, chat=false) { +export function log(bot, message, chat=false) { bot.output += message + '\n'; if (chat) bot.chat(message); diff --git a/src/agent/modes.js b/src/agent/modes.js index de0f09c..873245d 100644 --- a/src/agent/modes.js +++ b/src/agent/modes.js @@ -166,7 +166,7 @@ class ModeController { } update() { - if (!this.agent.coder.executing) { + if (this.agent.isIdle()) { // other actions might pause a mode to override it // when idle, unpause all modes for (let mode of this.modes_list) { @@ -175,7 +175,7 @@ class ModeController { } } for (let mode of this.modes_list) { - let available = mode.interrupts.includes('all') || !this.agent.coder.executing; + let available = mode.interrupts.includes('all') || this.agent.isIdle(); let interruptible = this.agent.coder.interruptible && (mode.interrupts.includes('defaults') || mode.interrupts.includes(this.agent.coder.default_name)); if (mode.on && !mode.paused && !mode.active && (available || interruptible)) { mode.update(this.agent);