added parent process + crash restarts

This commit is contained in:
MaxRobinsonTheGreat 2023-12-08 16:18:20 -06:00
parent 8d5c9957d1
commit e2aad3df9c
7 changed files with 69 additions and 15 deletions

View file

@ -69,12 +69,10 @@ export class Agent {
this.coder.queueCode(code);
let code_return = await this.coder.execute();
let message = code_return.message;
if (code_return.timedout)
message += "\n Code ran for a while and was stopped.";
else if (code_return.interrupted)
if (code_return.interrupted && !code_return.timedout)
break; // when interupted but not timed out, we were interupted by another conversation. end this one.
if (!code_return.success) {
message += "\n Write code to fix the problem and try again.";
message += "\nWrite code to fix the problem and try again.";
}
console.log('code return:', message);
this.history.add('system', message);

32
controller.js Normal file
View file

@ -0,0 +1,32 @@
import { spawn } from 'child_process';
class AgentController {
constructor(name) {
this.name = name;
}
async start(restart_memory=false) {
let args = ['init_agent.js', this.name];
if (restart_memory)
args.push('-r');
const agentProcess = spawn('node', args, {
stdio: 'inherit',
stderr: 'inherit',
});
agentProcess.on('exit', (code, signal) => {
console.log(`Agent process exited with code ${code} and signal ${signal}`);
// Restart the agent if it exited due to an error
if (code !== 0) {
console.log('Restarting agent...');
this.start();
}
});
agentProcess.on('error', (err) => {
console.error('Failed to start agent process:', err);
});
}
}
new AgentController('andy').start();

22
init_agent.js Normal file
View file

@ -0,0 +1,22 @@
import { Agent } from './agent.js';
import yargs from 'yargs';
const args = process.argv.slice(2);
if (args.length < 1) {
console.log('Usage: node init_agent.js <agent_name> [options]');
process.exit(1);
}
const argv = yargs(args)
.option('restart_memory', {
alias: 'r',
type: 'boolean',
description: 'restart memory from scratch'
}).argv;
const name = argv._[0];
const restart_memory = !!argv.restart_memory;
const save_path = './bots/'+name+'.json';
let agent = new Agent(name, save_path, restart_memory);
agent.start();

View file

@ -1,4 +0,0 @@
import { Agent } from './agent.js';
let agent = new Agent('andy', './bots/andy.json', true);
agent.start();

View file

@ -7,6 +7,7 @@
"mineflayer-pathfinder": "^2.4.4",
"mineflayer-pvp": "^1.3.2",
"openai": "^4.4.0",
"patch-package": "^8.0.0"
"patch-package": "^8.0.0",
"yargs": "^17.7.2"
}
}

View file

@ -48,7 +48,7 @@ export class Coder {
}
// returns {success: bool, message: string, interrupted: bool}
// returns {success: bool, message: string, interrupted: bool, timedout: false}
async execute() {
if (!this.queued_code) return {success: false, message: "No code to execute.", interrupted: false, timedout: false};
if (!this.code_template) return {success: false, message: "Code template not loaded.", interrupted: false, timedout: false};
@ -114,7 +114,7 @@ export class Coder {
}
formatOutput(bot) {
if (bot.interrupt_code) return '';
if (bot.interrupt_code && !this.timedout) return '';
let output = bot.output;
const MAX_OUT = 1000;
if (output.length > MAX_OUT) {
@ -151,11 +151,15 @@ export class Coder {
return setTimeout(async () => {
console.warn(`Code execution timed out after ${TIMEOUT_MINS} minutes. Attempting force stop.`);
this.timedout = true;
this.agent.bot.output += `\nAction performed for ${TIMEOUT_MINS} minutes and then timed out and stopped. You may want to continue or do something else.`;
this.stop(); // last attempt to stop
await new Promise(resolve => setTimeout(resolve, 5 * 1000));
await new Promise(resolve => setTimeout(resolve, 5 * 1000)); // wait 5 seconds
if (this.executing) {
console.error(`Failed to stop. Killing process. Goodbye.`);
// TODO: force save memories
this.agent.bot.output += `\nForce stop failed! Killing bot.`;
let output = this.formatOutput(this.agent.bot);
this.agent.history.add('system', output);
this.agent.history.save();
process.exit(1); // force exit program
}
console.log('Code execution stopped successfully.');

View file

@ -259,7 +259,9 @@ export async function collectBlock(bot, blockType, num=1) {
log(bot, `Failed to collect ${blockType}: ${err}.`);
continue;
}
}
}
if (bot.interrupt_code)
break;
}
log(bot, `Collected ${collected} ${blockType}.`);
return true;
@ -569,7 +571,6 @@ export async function followPlayer(bot, username) {
log(bot, `You are now actively following player ${username}.`);
while (!bot.interrupt_code) {
console.log('followPlayer waiting for interrupt...', bot.interrupt_code);
await new Promise(resolve => setTimeout(resolve, 1000));
}