updated memory saving

This commit is contained in:
Kolby Nottingham 2023-11-15 11:38:17 -08:00
parent 0be370d205
commit 3e61d45ace
4 changed files with 22 additions and 27 deletions

1
.gitignore vendored
View file

@ -1,5 +1,6 @@
.vscode/ .vscode/
node_modules/ node_modules/
bots/
package-lock.json package-lock.json
temp.js temp.js
scratch.js scratch.js

View file

@ -7,12 +7,13 @@ import { containsCodeBlock } from './utils/skill_library.js';
export class Agent { export class Agent {
constructor(name) { constructor(name, save_path) {
this.name = name; this.name = name;
this.bot = initBot(name); this.bot = initBot(name);
this.history = new History(this); this.history = new History(this);
this.coder = new Coder(this); this.coder = new Coder(this);
this.history.load(); if (save_path != null)
this.history.load(save_path);
this.bot.on('login', () => { this.bot.on('login', () => {
this.bot.chat('Hello world! I am ' + this.name); this.bot.chat('Hello world! I am ' + this.name);
@ -24,7 +25,8 @@ export class Agent {
console.log('received message from', username, ':', message); console.log('received message from', username, ':', message);
this.respond(username, message); this.respond(username, message);
this.history.save(); if (save_path != null)
this.history.save(save_path);
}); });
this.bot.on('finished_executing', () => { this.bot.on('finished_executing', () => {

View file

@ -1,3 +1,3 @@
import { Agent } from './agent.js'; import { Agent } from './agent.js';
new Agent('andy'); new Agent('andy', 'bots/andy.json');

View file

@ -34,9 +34,7 @@ let history_examples = [
{'role': 'assistant', 'content': 'I could not find a zombie nearby.'}, {'role': 'assistant', 'content': 'I could not find a zombie nearby.'},
{'role': 'user', 'content': 'billybob: stop'}, {'role': 'user', 'content': 'billybob: stop'},
{'role': 'assistant', 'content': '```// I am going to write empty code to stop whatever I am doing\n```'}, {'role': 'assistant', 'content': '```// I am going to write empty code to stop whatever I am doing\n```'}
] ]
export class History { export class History {
@ -47,12 +45,9 @@ export class History {
// These define an agent's long term memory // These define an agent's long term memory
this.bio = ''; this.bio = '';
this.memory = ''; this.memory = '';
this.num_saved_turns = 0;
// Variables for controlling how often we summarize the agent's memory and knowledge // Variables for controlling how often we summarize the agent's memory and knowledge
this.max_messages = 20; this.max_messages = 20;
this.save_size = 10;
this.save_step = 7;
} }
getHistory() { getHistory() {
@ -74,10 +69,14 @@ export class History {
} }
async storeMemories(turns) { async storeMemories(turns) {
let memory_prompt = 'Update your "Memory" with the following conversation. Your "Memory" is for storing information that will help you improve as a Minecraft bot. Include details about your interactions with other players that you may need to remember for later. Also include things that you have learned through player feedback or by executing code. Do not include information found in your Docs or that you got right on the first try. Your output should be a short paragraph summarizing what you have learned.'; let memory_prompt = 'Update your "Memory" with the following conversation. Your "Memory" is for storing information that will help you improve as a Minecraft bot. Include details about your interactions with other players that you may need to remember for later. Also include things that you have learned through player feedback or by executing code. Do not include information found in your Docs or that you got right on the first try.';
if (this.memory != '') { if (this.memory != '') {
memory_prompt += ' Include information from your current memory as well as your output will replace it.'; memory_prompt += ' Include information from your previous memory if it is still relevant. Your output will replace your previous memory.';
} }
memory_prompt += ' Your output should use one of the following formats:\n';
memory_prompt += '- When the player... output...\n';
memory_prompt += '- I learned that player [name]...\n';
for (let turn of turns) { for (let turn of turns) {
if (turn.role === 'assistant') { if (turn.role === 'assistant') {
memory_prompt += `\n\nYou: ${turn.content}`; memory_prompt += `\n\nYou: ${turn.content}`;
@ -102,25 +101,18 @@ export class History {
// Summarize older turns into memory // Summarize older turns into memory
if (this.turns.length >= this.max_messages) { if (this.turns.length >= this.max_messages) {
// Don't summarize the examples let to_summarize = [this.turns.shift()];
if (this.num_saved_turns + this.save_step >= history_examples.length && while (this.turns[0].role != 'user' && this.turns.length > 0)
this.num_saved_turns < history_examples.length) { to_summarize.push(this.turns.shift());
await this.storeMemories( await this.storeMemories(to_summarize);
this.turns.slice(history_examples.length - this.num_saved_turns, this.save_size)
);
} else if (this.num_saved_turns >= history_examples.length) {
await this.storeMemories(this.turns.slice(0, this.save_size));
}
this.turns = this.turns.slice(this.save_step);
this.num_saved_turns += this.save_step;
} }
} }
save() { save(save_path) {
// save history object to json file // save history object to json file
mkdirSync('bots', { recursive: true }); mkdirSync('bots', { recursive: true });
const data = JSON.stringify(this, null, 4); const data = JSON.stringify(this, null, 4);
writeFileSync('bots/' + this.name + '.json', data, (err) => { writeFileSync(save_path, data, (err) => {
if (err) { if (err) {
throw err; throw err;
} }
@ -128,10 +120,10 @@ export class History {
}); });
} }
load() { load(save_path) {
try { try {
// load history object from json file // load history object from json file
const data = readFileSync('bots/' + this.name + '.json', 'utf8'); const data = readFileSync(save_path, 'utf8');
const obj = JSON.parse(data); const obj = JSON.parse(data);
this.turns = obj.turns; this.turns = obj.turns;
this.bio = obj.bio; this.bio = obj.bio;