Skip to content

Commit 08214d8

Browse files
Implement memory management features with add, retrieve, and clear functionalities; update logging configuration and paths
1 parent de3ae23 commit 08214d8

5 files changed

Lines changed: 105 additions & 49 deletions

File tree

src/config/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {homedir} from "node:os"
44

55
export const EDITOR_DIR = join(homedir(), ".ComputerUseAgent", "editor_dir")
66
export const SESSIONS_DIR = join(homedir(), ".ComputerUseAgent", "sessions")
7+
export const LOGS_DIR = join(homedir(), ".ComputerUseAgent", "logs")
78

89
export const EDITOR_SYSTEM_PROMPT = Deno.env.get("EDITOR_SYSTEM_PROMPT") ??
910
`You are a helpful assistant that helps users edit and work with text files.

src/config/logging.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import * as log from "jsr:@std/log";
1+
import * as log from "jsr:@std/log"
2+
import {LOGS_DIR} from "./constants.ts"
23

34
export async function setupLogging() {
45
await log.setup({
56
handlers: {
67
console: new log.ConsoleHandler("DEBUG"),
78
file: new log.FileHandler("DEBUG", {
8-
filename: "./app.log",
9+
filename: `${LOGS_DIR}/log.txt`,
910
}),
1011
},
1112
loggers: {
@@ -14,7 +15,7 @@ export async function setupLogging() {
1415
handlers: ["console", "file"],
1516
},
1617
},
17-
});
18+
})
1819
}
1920

20-
export { log };
21+
export {log}

src/modules/bash/bash_session.ts

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import {BaseSession} from "../../utils/session.ts"
2-
import {BASH_SYSTEM_PROMPT, API_CONFIG} from "../../config/constants.ts"
2+
import {BASH_SYSTEM_PROMPT, API_CONFIG, MEMORY_TOOLS} from "../../config/constants.ts"
33
import {ToolResult} from "../../types/interfaces.ts"
44
import {log} from "../../config/logging.ts"
55
import {BashHandlers} from "./handlers.ts"
6+
import {MemoryManager} from "../memory/memory_manager.ts"
67

78
export class BashSession extends BaseSession {
89
private noAgi: boolean
910
private environment: Record<string, string>
11+
private memoryManager: MemoryManager
12+
1013
private handlers: BashHandlers
1114

1215
constructor(sessionId?: string, noAgi = false) {
1316
super(sessionId)
1417
this.noAgi = noAgi
1518
this.environment = {...Deno.env.toObject()}
1619
this.handlers = new BashHandlers(noAgi)
20+
this.memoryManager = new MemoryManager()
1721
}
1822

1923
async processBashCommand(bashPrompt: string): Promise<void> {
@@ -48,7 +52,9 @@ System Context:
4852
model: API_CONFIG.MODEL,
4953
max_tokens: API_CONFIG.MAX_TOKENS,
5054
messages: this.messages,
51-
tools: [{type: "bash_20241022", name: "bash"}],
55+
tools: [{type: "bash_20241022", name: "bash"}
56+
, ...MEMORY_TOOLS
57+
],
5258
system: systemContext,
5359
betas: ["computer-use-2024-10-22"],
5460
})
@@ -94,24 +100,69 @@ System Context:
94100
const results: ToolResult[] = []
95101

96102
for (const toolCall of content) {
97-
if (toolCall.type === "tool_use" && toolCall.name === "bash") {
98-
log.info(`Bash tool call input: ${JSON.stringify(toolCall.input)}`)
99-
100-
const result = await this.handlers.handleBashCommand(toolCall.input)
101-
const isError = "error" in result
102-
const toolResultContent = isError
103-
? [{type: "text", text: result.error}]
104-
: [{type: "text", text: result.content || ""}]
105-
106-
results.push({
107-
tool_call_id: toolCall.id,
108-
output: {
109-
type: "tool_result",
110-
content: toolResultContent,
111-
tool_use_id: toolCall.id,
112-
is_error: isError,
113-
},
114-
})
103+
if (toolCall.type === "tool_use") {
104+
let result
105+
let isError = false
106+
107+
switch (toolCall.name) {
108+
case "bash": {
109+
110+
log.info(`Bash tool call input: ${JSON.stringify(toolCall.input)}`)
111+
result = await this.handlers.handleBashCommand(toolCall.input)
112+
isError = "error" in result
113+
const toolResultContent = isError
114+
? [{type: "text", text: result.error}]
115+
: [{type: "text", text: result.content || "Command executed successfully."}]
116+
117+
results.push({
118+
tool_call_id: toolCall.id,
119+
output: {
120+
type: "tool_result",
121+
content: toolResultContent,
122+
tool_use_id: toolCall.id,
123+
is_error: isError,
124+
},
125+
})
126+
break
127+
}
128+
case "add_memory":
129+
result = await this.memoryManager.addMemory(toolCall.input.content)
130+
results.push({
131+
tool_call_id: toolCall.id,
132+
output: {
133+
type: "tool_result",
134+
content: [{type: "text", text: result.content}],
135+
tool_use_id: toolCall.id,
136+
is_error: false,
137+
},
138+
})
139+
break
140+
case "get_memories":
141+
result = await this.memoryManager.getMemories()
142+
results.push({
143+
tool_call_id: toolCall.id,
144+
output: {
145+
type: "tool_result",
146+
content: [{type: "text", text: JSON.stringify(result)}],
147+
tool_use_id: toolCall.id,
148+
is_error: false,
149+
},
150+
})
151+
break
152+
case "clear_memories":
153+
await this.memoryManager.clearMemories()
154+
result = {message: "Memories cleared successfully"}
155+
results.push({
156+
tool_call_id: toolCall.id,
157+
output: {
158+
type: "tool_result",
159+
content: [{type: "text", text: JSON.stringify(result)}],
160+
tool_use_id: toolCall.id,
161+
is_error: false,
162+
},
163+
})
164+
break
165+
}
115166
}
116167
}
117168

src/modules/bash/handlers.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export class BashHandlers {
1313
toolCall: Record<string, any>,
1414
): Promise<Record<string, any>> {
1515
try {
16-
const command = toolCall.command
16+
const command = toolCall.command as string
1717
const restart = toolCall.restart ?? false
1818

1919
if (restart) {
@@ -34,25 +34,26 @@ export class BashHandlers {
3434

3535
log.info(`Executing bash command: ${command}`)
3636

37-
const process = new Deno.Command("bash", {
37+
const shell = Deno.env.get("SHELL") || "bash"
38+
const process = new Deno.Command(shell, {
3839
args: ["-c", command],
3940
env: this.environment,
4041
stdout: "piped",
4142
stderr: "piped",
4243
})
43-
4444
const {stdout, stderr, code} = await process.output()
4545

4646
const output = new TextDecoder().decode(stdout).trim()
4747
const errorOutput = new TextDecoder().decode(stderr).trim()
4848

49-
if (output) {
50-
log.info(
51-
`Command output:\n\n\`\`\`output for '${command.slice(0, 20)
52-
}...'\n${output}\n\`\`\``,
53-
)
54-
}
55-
if (errorOutput) {
49+
if (code === 0) {
50+
if (output) {
51+
log.info(
52+
`Command output:\n\n\`\`\`output for '${command.slice(0, 20)
53+
}...'\n${output}\n\`\`\``,
54+
)
55+
}
56+
} else if (errorOutput) {
5657
log.error(
5758
`Command error output:\n\n\`\`\`error for '${command}'\n${errorOutput}\n\`\`\``,
5859
)
Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,43 @@
1-
import { Memory, MemoryFile } from "../../types/interfaces.ts";
2-
import { log } from "../../config/logging.ts";
1+
import {Memory, MemoryFile} from "../../types/interfaces.ts"
2+
import {log} from "../../config/logging.ts"
33

44
export class MemoryManager {
55
private memoryPath = "/root/memory.json";
66

77
private async readMemoryFile(): Promise<MemoryFile> {
88
try {
9-
const content = await Deno.readTextFile(this.memoryPath);
10-
return JSON.parse(content);
9+
const content = await Deno.readTextFile(this.memoryPath)
10+
return JSON.parse(content)
1111
} catch {
12-
return { memories: [] };
12+
return {memories: []}
1313
}
1414
}
1515

1616
private async writeMemoryFile(data: MemoryFile): Promise<void> {
17-
await Deno.writeTextFile(this.memoryPath, JSON.stringify(data, null, 2));
17+
console.log(`Writing memory file: ${JSON.stringify(data, null, 2)}`)
18+
await Deno.writeTextFile(this.memoryPath, JSON.stringify(data, null, 2))
1819
}
1920

2021
async addMemory(content: string): Promise<Memory> {
21-
const memoryFile = await this.readMemoryFile();
22+
console.log(`Adding into file: ${content}`)
23+
const memoryFile = await this.readMemoryFile()
2224
const newMemory: Memory = {
2325
id: crypto.randomUUID(),
2426
content,
2527
timestamp: Date.now(),
26-
};
27-
28-
memoryFile.memories.push(newMemory);
29-
await this.writeMemoryFile(memoryFile);
30-
return newMemory;
28+
}
29+
30+
memoryFile.memories.push(newMemory)
31+
await this.writeMemoryFile(memoryFile)
32+
return newMemory
3133
}
3234

3335
async getMemories(): Promise<Memory[]> {
34-
const memoryFile = await this.readMemoryFile();
35-
return memoryFile.memories;
36+
const memoryFile = await this.readMemoryFile()
37+
return memoryFile.memories
3638
}
3739

3840
async clearMemories(): Promise<void> {
39-
await this.writeMemoryFile({ memories: [] });
41+
await this.writeMemoryFile({memories: []})
4042
}
4143
}

0 commit comments

Comments
 (0)