simplified memory

This commit is contained in:
Kolby Nottingham 2023-11-13 20:33:34 -08:00
parent 7e020b35ba
commit 0be370d205
4 changed files with 49 additions and 47 deletions

View file

@ -2,25 +2,17 @@ import { initBot } from './utils/mcdata.js';
import { sendRequest } from './utils/gpt.js';
import { History } from './utils/history.js';
import { Coder } from './utils/coder.js';
import { getQuery, containsQuery, getQueryDocs } from './utils/queries.js';
import { getSkillDocs, containsCodeBlock } from './utils/skill_library.js';
import { getQuery, containsQuery } from './utils/queries.js';
import { containsCodeBlock } from './utils/skill_library.js';
export class Agent {
constructor(name) {
this.name = name;
this.system_message = `You are a playful Minecraft bot named '${name}' that can communicate with players, see, move, mine, build, and interact with the world by writing and executing code.
Act human-like as if you were a typical Minecraft player, rather than an AI. Be brief in your responses, omit needless words, and do not give instructions unless asked.`;
this.system_message += getQueryDocs();
this.system_message += getSkillDocs();
this.current_system_message = this.system_message;
this.bot = initBot(name);
this.history = new History(this);
this.coder = new Coder(this);
this.history.load();
this.updateSystemMessage();
this.bot.on('login', () => {
this.bot.chat('Hello world! I am ' + this.name);
@ -33,7 +25,6 @@ export class Agent {
this.respond(username, message);
this.history.save();
this.updateSystemMessage();
});
this.bot.on('finished_executing', () => {
@ -45,22 +36,10 @@ export class Agent {
})
}
updateSystemMessage() {
if (this.history.bio != '') {
this.current_system_message = this.system_message + '\n\nBio:\n' + this.history.bio;
}
if (this.history.memory != '') {
this.current_system_message = this.current_system_message + '\n\nMemories:\n' + this.history.memory;
}
if (this.history.knowledge != '') {
this.current_system_message = this.current_system_message + '\n\nKnowledge:\n' + this.history.knowledge;
}
}
async respond(username, message) {
this.history.add(username, message);
for (let i=0; i<5; i++) {
let res = await sendRequest(this.history.getHistory(), this.current_system_message);
let res = await sendRequest(this.history.getHistory(), this.history.getSystemMessage());
this.history.add(this.name, res);
let query_cmd = containsQuery(res);
if (query_cmd) { // contains query

View file

@ -22,7 +22,7 @@ export async function sendRequest(turns, systemMessage, stop_seq='***') {
let res = null;
try {
let completion = await openai.chat.completions.create({
model: 'gpt-3.5-turbo',
model: 'gpt-3.5-turbo-1106',
messages: messages,
stop: stop_seq,
});

View file

@ -1,4 +1,6 @@
import { writeFileSync, readFileSync, mkdirSync } from 'fs';
import { getQueryDocs } from './queries.js';
import { getSkillDocs } from './skill_library.js';
import { sendRequest } from './gpt.js';
@ -43,9 +45,8 @@ export class History {
this.turns = history_examples;
// These define an agent's long term memory
this.bio = 'Your personality is friendly. Your goal is to help.';
this.bio = '';
this.memory = '';
this.knowledge = '';
this.num_saved_turns = 0;
// Variables for controlling how often we summarize the agent's memory and knowledge
@ -58,30 +59,34 @@ export class History {
return this.turns;
}
getSystemMessage() {
let system_message = `You are a playful Minecraft bot named '${this.name}' that can communicate with players, see, move, mine, build, and interact with the world by writing and executing code.
Act human-like as if you were a typical Minecraft player, rather than an AI. Be brief in your responses, omit needless words, and do not give instructions unless asked.`;
system_message += getQueryDocs();
system_message += getSkillDocs();
if (this.bio != '') {
system_message = system_message + '\n\nBio:\n' + this.bio;
}
if (this.memory != '') {
system_message = system_message + '\n\nMemory:\n' + this.memory;
}
return system_message;
}
async storeMemories(turns) {
const memory_message = 'You are a minecraft bot. ' + this.bio + '\n\nCurrent Memory:\n' + this.memory;
let memory_prompt = 'Update your memory with the following conversation. Include only conversational details about other players that you may need to remember for later. Your output should be a short paragraph summarizing what you have experienced.\n';
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.';
if (this.memory != '') {
memory_prompt += ' Include information from your current memory as well as your output will replace it.';
}
for (let turn of turns) {
if (turn.role === 'user') {
memory_prompt += `\n${turn.content}`;
if (turn.role === 'assistant') {
memory_prompt += `\n\nYou: ${turn.content}`;
} else {
memory_prompt += `\nYou: ${turn.content}`;
memory_prompt += `\n\n${turn.content}`;
}
}
let memory_turns = [{'role': 'user', 'content': memory_prompt}]
this.memory = await sendRequest(memory_turns, memory_message);
const knowledge_message = 'You are a minecraft bot. ' + this.bio + '\n\nCurrent Knowledge: ' + this.knowledge;
let knowledge_prompt = 'Update your current knowledge with the following conversation. Include only knowledge you have gained about how to interact with the world and execute actions that you may need to remember for later. Your output should be a short paragraph summarizing what you have learned.\n';
for (let turn of turns) {
if (turn.role === 'user') {
knowledge_prompt += `\n${turn.content}`;
} else {
knowledge_prompt += `\nYou: ${turn.content}`;
}
}
let knowledge_turns = [{'role': 'user', 'content': knowledge_prompt}]
this.knowledge = await sendRequest(knowledge_turns, knowledge_message);
this.memory = await sendRequest(memory_turns, this.getSystemMessage());
}
async add(name, content) {
@ -89,7 +94,7 @@ export class History {
if (name === 'system') {
role = 'system';
}
else if (name !== this.agent.name) {
else if (name !== this.name) {
role = 'user';
content = `${name}: ${content}`;
}
@ -131,7 +136,6 @@ export class History {
this.turns = obj.turns;
this.bio = obj.bio;
this.memory = obj.memory;
this.knowledge = obj.knowledge;
this.num_saved_turns = obj.num_saved_turns;
} catch (err) {
console.log('No history file found for ' + this.name + '.');

View file

@ -181,3 +181,22 @@ export function getNearbyBlockTypes(bot) {
}
return found;
}
export function getNearestBlockPosition(bot, blockType) {
/**
* Get the position of the nearest block of the given type.
* @param {Bot} bot - The bot to get the nearest block for.
* @param {string} blockType - The type of the block to search for.
* @returns {Vec3} - The position of the nearest block of the given type if found else null.
* @example
* let position = world.getNearestBlockPosition(bot, 'coal_ore');
**/
let blocks = getNearbyBlocks(bot, 16);
for (let i = 0; i < blocks.length; i++) {
if (blocks[i].name == blockType) {
return blocks[i].position;
}
}
return null;
}