Skip to content

Commit dd6b3ab

Browse files
Implement memory management features with add, retrieve, and clear functionalities
1 parent be80e15 commit dd6b3ab

5 files changed

Lines changed: 127 additions & 16 deletions

File tree

src/config/constants.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {join} from "jsr:@std/path"
2+
import Anthropic from "npm:@anthropic-ai/sdk"
3+
import {homedir} from "node:os"
24

3-
export const EDITOR_DIR = join(Deno.cwd(), "editor_dir")
4-
export const SESSIONS_DIR = join(Deno.cwd(), "sessions")
5+
export const EDITOR_DIR = join(homedir(), ".ComputerUseAgent", "editor_dir")
6+
export const SESSIONS_DIR = join(homedir(), ".ComputerUseAgent", "sessions")
57

68
export const EDITOR_SYSTEM_PROMPT = Deno.env.get("EDITOR_SYSTEM_PROMPT") ??
79
`You are a helpful assistant that helps users edit and work with text files.
@@ -22,4 +24,41 @@ export const API_CONFIG = {
2224
MODEL: "claude-3-5-sonnet-20241022",
2325
INTENT_MODEL: "claude-3-5-haiku-20241022",
2426
MAX_TOKENS: 4096,
27+
MAX_INTENT_TOKENS: 20,
2528
}
29+
30+
export const MEMORY_TOOLS: Anthropic.Beta.BetaToolUnion[] = [
31+
{
32+
name: "add_memory",
33+
description: "Add a new memory to the system",
34+
type: "custom",
35+
input_schema: {
36+
type: "object",
37+
properties: {
38+
content: {
39+
type: "string",
40+
description: "The content to store in memory",
41+
},
42+
},
43+
required: ["content"],
44+
},
45+
},
46+
{
47+
type: "custom",
48+
name: "get_memories",
49+
description: "Retrieve all stored memories",
50+
input_schema: {
51+
type: "object",
52+
properties: {},
53+
},
54+
},
55+
{
56+
type: "custom",
57+
name: "clear_memories",
58+
description: "Clear all stored memories",
59+
input_schema: {
60+
type: "object",
61+
properties: {},
62+
},
63+
},
64+
]

src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ async function determineIntent(prompt: string): Promise<string> {
1818

1919
const message = await client.messages.create({
2020
model: API_CONFIG.INTENT_MODEL,
21-
max_tokens: 10,
21+
max_tokens: API_CONFIG.MAX_INTENT_TOKENS,
2222
system: `You have following query from user, determine what is the intent of user.
2323
and based on user's intent and available tools, pick the best tool that can help user.
2424

src/modules/editor/editor_session.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import {BaseSession} from "../../utils/session.ts"
2-
import {EDITOR_SYSTEM_PROMPT, API_CONFIG} from "../../config/constants.ts"
3-
import {ToolCall, ToolResult} from "../../types/interfaces.ts"
2+
import {EDITOR_SYSTEM_PROMPT, API_CONFIG, MEMORY_TOOLS} from "../../config/constants.ts"
3+
import {ToolResult} from "../../types/interfaces.ts"
44
import {log} from "../../config/logging.ts"
55
import {EditorHandlers} from "./handlers.ts"
6+
import {MemoryManager} from "../memory/memory_manager.ts"
67

78
export class EditorSession extends BaseSession {
89
private handlers: EditorHandlers
10+
private memoryManager: MemoryManager
911

1012
constructor(sessionId?: string) {
1113
super(sessionId)
1214
this.handlers = new EditorHandlers()
15+
this.memoryManager = new MemoryManager()
1316
}
1417

1518
async processEdit(prompt: string): Promise<void> {
@@ -20,14 +23,17 @@ export class EditorSession extends BaseSession {
2023
}
2124
this.messages = [message]
2225

23-
log.info(`User input: ${JSON.stringify(message)}, System Prompt: ${EDITOR_SYSTEM_PROMPT}`)
26+
log.info(`User input: ${JSON.stringify(message)}`)
2427

2528
while (true) {
2629
const response = await this.client.beta.messages.create({
2730
model: API_CONFIG.MODEL,
2831
max_tokens: API_CONFIG.MAX_TOKENS,
2932
messages: this.messages,
30-
tools: [{type: "text_editor_20241022", name: "str_replace_editor"}],
33+
tools: [
34+
{type: "text_editor_20241022", name: "str_replace_editor"},
35+
...MEMORY_TOOLS
36+
],
3137
system: EDITOR_SYSTEM_PROMPT,
3238
betas: ["computer-use-2024-10-22"],
3339
})
@@ -77,20 +83,35 @@ export class EditorSession extends BaseSession {
7783
const results: ToolResult[] = []
7884

7985
for (const toolCall of content) {
80-
if (toolCall.type === "tool_use" && toolCall.name === "str_replace_editor") {
81-
log.info(`Editor tool call input: ${JSON.stringify(toolCall.input)}`)
82-
83-
const result = await this.handlers.handleTextEditorTool(toolCall.input)
84-
const isError = "error" in result
85-
const toolResultContent = isError
86-
? [{type: "text", text: result.error}]
87-
: [{type: "text", text: result.content || ""}]
86+
if (toolCall.type === "tool_use") {
87+
let result
88+
let isError = false
89+
90+
switch (toolCall.name) {
91+
case "str_replace_editor":
92+
result = await this.handlers.handleTextEditorTool(toolCall.input)
93+
isError = "error" in result
94+
break
95+
case "add_memory":
96+
result = await this.memoryManager.addMemory(toolCall.input.content)
97+
break
98+
case "get_memories":
99+
result = await this.memoryManager.getMemories()
100+
break
101+
case "clear_memories":
102+
await this.memoryManager.clearMemories()
103+
result = {message: "Memories cleared successfully"}
104+
break
105+
}
88106

89107
results.push({
90108
tool_call_id: toolCall.id,
91109
output: {
92110
type: "tool_result",
93-
content: toolResultContent,
111+
content: [{
112+
type: "text",
113+
text: JSON.stringify(result)
114+
}],
94115
tool_use_id: toolCall.id,
95116
is_error: isError,
96117
},
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Memory, MemoryFile } from "../../types/interfaces.ts";
2+
import { log } from "../../config/logging.ts";
3+
4+
export class MemoryManager {
5+
private memoryPath = "/root/memory.json";
6+
7+
private async readMemoryFile(): Promise<MemoryFile> {
8+
try {
9+
const content = await Deno.readTextFile(this.memoryPath);
10+
return JSON.parse(content);
11+
} catch {
12+
return { memories: [] };
13+
}
14+
}
15+
16+
private async writeMemoryFile(data: MemoryFile): Promise<void> {
17+
await Deno.writeTextFile(this.memoryPath, JSON.stringify(data, null, 2));
18+
}
19+
20+
async addMemory(content: string): Promise<Memory> {
21+
const memoryFile = await this.readMemoryFile();
22+
const newMemory: Memory = {
23+
id: crypto.randomUUID(),
24+
content,
25+
timestamp: Date.now(),
26+
};
27+
28+
memoryFile.memories.push(newMemory);
29+
await this.writeMemoryFile(memoryFile);
30+
return newMemory;
31+
}
32+
33+
async getMemories(): Promise<Memory[]> {
34+
const memoryFile = await this.readMemoryFile();
35+
return memoryFile.memories;
36+
}
37+
38+
async clearMemories(): Promise<void> {
39+
await this.writeMemoryFile({ memories: [] });
40+
}
41+
}

src/types/interfaces.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,13 @@ export interface SystemInfo {
2828
isWsl: boolean;
2929
shell: string;
3030
}
31+
32+
export interface Memory {
33+
id: string;
34+
content: string;
35+
timestamp: number;
36+
}
37+
38+
export interface MemoryFile {
39+
memories: Memory[];
40+
}

0 commit comments

Comments
 (0)