Memory / history fixes
All checks were successful
Publish Library / Build NPM Project (push) Successful in 52s
Publish Library / Tag Version (push) Successful in 14s

This commit is contained in:
2026-06-07 21:35:26 -04:00
parent 7dd3307a07
commit 51ab8f2538
4 changed files with 44 additions and 37 deletions

View File

@@ -1,5 +1,6 @@
// memory.ts
import {LLMRequest, LLMMessage} from './llm.ts';
import {AiTool} from './tools.ts';
/** Background information the AI will be fed as a knowledge document */
export type Memory = {
@@ -25,9 +26,9 @@ export type MemoryCollection = {
export class MemoryManager {
tools = {
edit: (memory: Memory) => ({
name: 'edit',
description: 'Edit a memory. Omit start/end to append. Pass start only to replace from that line on. Pass start+end to replace a specific range. start=0 replaces the whole document.',
edit: (memory: Memory): AiTool => ({
name: 'edit_memory',
description: 'Edit a memory. Omit start/end to append. Pass start only to replace from that line on (Note line 0 = first line of content / line AFTER description). Pass start+end to replace a specific range. start=0 replaces the whole document. Returns updated document',
args: {
content: {type: 'string', description: 'New content', required: true},
start: {type: 'number', description: 'First line to replace (0-indexed, inclusive). Omit to append.'},
@@ -40,15 +41,15 @@ export class MemoryManager {
else if(args.end === undefined) lines.splice(args.start, lines.length - args.start, ...newLines);
else lines.splice(args.start, args.end - args.start + 1, ...newLines);
memory.content = lines.join('\n');
return `Updated memory:\n${memory.content}`;
return memory.content;
}
}),
extract: (pools: MemoryCollection[]) => ({
name: 'extract',
extract: (pools: MemoryCollection[]): AiTool => ({
name: 'extract_facts',
description: 'Extract a list of facts to group into a single memory',
args: {
name: {type: 'string', description: 'Exact name of an existing memory, or a new name if none fits ([pro]nouns only)', required: true},
description: {type: 'string', description: 'One sentence description of the memory subject, only required if new'},
description: {type: 'string', description: 'One sentence description of the memory subject', required: true},
facts: {type: 'string', description: 'Comma separated list of extracted facts', required: true},
},
fn: (args: any) => {
@@ -59,8 +60,8 @@ export class MemoryManager {
});
return 'Success';
}}),
read: (memories: Memory[]) => ({
name: 'read',
read: (memories: Memory[]): AiTool => ({
name: 'read_memory',
description: 'Read entire memory',
args: {
name: {type: 'string', description: 'Exact memory name', required: true},
@@ -96,7 +97,7 @@ Rules:
- DO NOT extract greetings, pleasantries or generic exchanges
- If nothing worth remembering was said, call NO tools
For each fact decide whether it belongs in an existing document or needs a new one, then call the \`extract\` tool.
For each fact decide whether it belongs in an existing document or needs a new one, then call the \`extract_facts\` tool.
Existing documents:\n${existingDocs || 'None yet.'}`,
tools: [this.tools.extract(pools)]
@@ -120,18 +121,17 @@ Existing documents:\n${existingDocs || 'None yet.'}`,
{
model: this.model || options.model,
temperature: 0.2,
system: `You are a document editor. Merge the users list of facts into the following document using the \`edit\` tool; call it as many times as necessary.
Name: ${mem.name}
Description: ${mem.description}
${mem.content}`,
system: `You are a document editor. Merge the users list of facts into the following document using the \`edit_memory\` tool; call it as many times as necessary:
\`\`\`
${mem.content}
\`\`\``,
tools: [this.tools.edit(mem)]
}
);
if(isNew || mem.description !== existing?.description) {
const [e] = await this.llm.embedding(mem.description);
mem.embedding = e.embedding;
const e = await this.llm.embedding(mem.description);
mem.embedding = e?.[0]?.embedding;
}
if(isNew) memories.push(mem);