agent-office 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +64 -0
- package/dist/commands/serve.d.ts +1 -0
- package/dist/commands/serve.js +18 -1
- package/dist/commands/worker.d.ts +5 -0
- package/dist/commands/worker.js +67 -0
- package/dist/db/index.d.ts +1 -0
- package/dist/db/migrate.js +7 -0
- package/dist/manage/app.js +1 -1
- package/dist/manage/components/SessionList.js +353 -7
- package/dist/manage/components/SessionSidebar.js +7 -1
- package/dist/manage/components/TailMessages.js +54 -5
- package/dist/manage/hooks/useApi.d.ts +35 -2
- package/dist/manage/hooks/useApi.js +28 -0
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +3 -3
- package/dist/server/memory.d.ts +64 -0
- package/dist/server/memory.js +214 -0
- package/dist/server/routes.d.ts +3 -2
- package/dist/server/routes.js +479 -14
- package/package.json +4 -1
package/dist/cli.js
CHANGED
|
@@ -13,6 +13,7 @@ program
|
|
|
13
13
|
.option("--opencode-url <url>", "OpenCode server URL", process.env.OPENCODE_URL ?? "http://localhost:4096")
|
|
14
14
|
.option("--host <host>", "Host to bind to", "127.0.0.1")
|
|
15
15
|
.option("--port <port>", "Port to serve on", "7654")
|
|
16
|
+
.option("--memory-path <path>", "Directory for memory storage (default: ./.memory)", "./.memory")
|
|
16
17
|
.option("--password <password>", "REQUIRED. API password", process.env.AGENT_OFFICE_PASSWORD)
|
|
17
18
|
.action(async (options) => {
|
|
18
19
|
const { serve } = await import("./commands/serve.js");
|
|
@@ -46,6 +47,26 @@ workerCmd
|
|
|
46
47
|
const { listCoworkers } = await import("./commands/worker.js");
|
|
47
48
|
await listCoworkers(token);
|
|
48
49
|
});
|
|
50
|
+
workerCmd
|
|
51
|
+
.command("set-status")
|
|
52
|
+
.description("Set your public status (visible to coworkers and manager)")
|
|
53
|
+
.argument("<token>", "Agent token in the format <agent_code>@<server-url>")
|
|
54
|
+
.option("--status <status>", "Your status message (max 140 characters)")
|
|
55
|
+
.option("--clear", "Clear your status")
|
|
56
|
+
.action(async (token, options) => {
|
|
57
|
+
if (options.clear) {
|
|
58
|
+
const { setStatus } = await import("./commands/worker.js");
|
|
59
|
+
await setStatus(token, null);
|
|
60
|
+
}
|
|
61
|
+
else if (options.status !== undefined) {
|
|
62
|
+
const { setStatus } = await import("./commands/worker.js");
|
|
63
|
+
await setStatus(token, options.status);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.error("Error: either --status or --clear must be provided");
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
49
70
|
workerCmd
|
|
50
71
|
.command("send-message")
|
|
51
72
|
.description("Send a message to one or more coworkers")
|
|
@@ -137,4 +158,47 @@ cronCmd
|
|
|
137
158
|
const { cronHistory } = await import("./commands/worker.js");
|
|
138
159
|
await cronHistory(token, cronId);
|
|
139
160
|
});
|
|
161
|
+
// ── Worker Memory Commands (nested) ──────────────────────────────────────────
|
|
162
|
+
const memoryCmd = workerCmd
|
|
163
|
+
.command("memory")
|
|
164
|
+
.description("Manage your persistent memories");
|
|
165
|
+
memoryCmd
|
|
166
|
+
.command("add")
|
|
167
|
+
.argument("<token>", "Agent token in the format <agent_code>@<server-url>")
|
|
168
|
+
.description("Add a new memory")
|
|
169
|
+
.requiredOption("--content <content>", "Memory content to store")
|
|
170
|
+
.action(async (token, options) => {
|
|
171
|
+
const { memoryAdd } = await import("./commands/worker.js");
|
|
172
|
+
await memoryAdd(token, options.content);
|
|
173
|
+
});
|
|
174
|
+
memoryCmd
|
|
175
|
+
.command("search")
|
|
176
|
+
.argument("<token>", "Agent token in the format <agent_code>@<server-url>")
|
|
177
|
+
.description("Search memories using hybrid search (keyword + semantic)")
|
|
178
|
+
.requiredOption("--query <query>", "Search query")
|
|
179
|
+
.option("--limit <limit>", "Maximum results (default 10)", "10")
|
|
180
|
+
.action(async (token, options) => {
|
|
181
|
+
const limit = parseInt(options.limit ?? "10", 10);
|
|
182
|
+
const { memorySearch } = await import("./commands/worker.js");
|
|
183
|
+
await memorySearch(token, options.query, limit);
|
|
184
|
+
});
|
|
185
|
+
memoryCmd
|
|
186
|
+
.command("list")
|
|
187
|
+
.argument("<token>", "Agent token in the format <agent_code>@<server-url>")
|
|
188
|
+
.description("List all stored memories")
|
|
189
|
+
.option("--limit <limit>", "Maximum memories to list (default 50)", "50")
|
|
190
|
+
.action(async (token, options) => {
|
|
191
|
+
const limit = parseInt(options.limit ?? "50", 10);
|
|
192
|
+
const { memoryList } = await import("./commands/worker.js");
|
|
193
|
+
await memoryList(token, limit);
|
|
194
|
+
});
|
|
195
|
+
memoryCmd
|
|
196
|
+
.command("forget")
|
|
197
|
+
.argument("<token>", "Agent token in the format <agent_code>@<server-url>")
|
|
198
|
+
.argument("<memoryId>", "ID of the memory to forget")
|
|
199
|
+
.description("Delete a memory by ID")
|
|
200
|
+
.action(async (token, memoryId) => {
|
|
201
|
+
const { memoryForget } = await import("./commands/worker.js");
|
|
202
|
+
await memoryForget(token, memoryId);
|
|
203
|
+
});
|
|
140
204
|
program.parse();
|
package/dist/commands/serve.d.ts
CHANGED
package/dist/commands/serve.js
CHANGED
|
@@ -3,6 +3,7 @@ import { runMigrations } from "../db/migrate.js";
|
|
|
3
3
|
import { createOpencodeClient } from "../lib/opencode.js";
|
|
4
4
|
import { createApp } from "../server/index.js";
|
|
5
5
|
import { CronScheduler } from "../server/cron.js";
|
|
6
|
+
import { MemoryManager } from "../server/memory.js";
|
|
6
7
|
export async function serve(options) {
|
|
7
8
|
const password = options.password;
|
|
8
9
|
if (!password) {
|
|
@@ -36,10 +37,25 @@ export async function serve(options) {
|
|
|
36
37
|
// Init OpenCode client
|
|
37
38
|
const opencode = createOpencodeClient(options.opencodeUrl);
|
|
38
39
|
const serverUrl = `http://${options.host}:${port}`;
|
|
40
|
+
// Create memory manager and verify embedding model
|
|
41
|
+
const memoryManager = new MemoryManager(options.memoryPath);
|
|
42
|
+
console.log("Warming up embedding model...");
|
|
43
|
+
try {
|
|
44
|
+
await memoryManager.warmup();
|
|
45
|
+
console.log("Embedding model ready.");
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
console.error("Embedding model failed to load:", err);
|
|
49
|
+
console.error("Try deleting the model cache and restarting:");
|
|
50
|
+
console.error(` rm -rf ${options.memoryPath}/.model-cache`);
|
|
51
|
+
memoryManager.closeAll();
|
|
52
|
+
await sql.end();
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
39
55
|
// Create cron scheduler
|
|
40
56
|
const cronScheduler = new CronScheduler();
|
|
41
57
|
// Create Express app
|
|
42
|
-
const app = createApp(sql, opencode, password, serverUrl, cronScheduler);
|
|
58
|
+
const app = createApp(sql, opencode, password, serverUrl, cronScheduler, memoryManager);
|
|
43
59
|
// Start cron scheduler
|
|
44
60
|
await cronScheduler.start(sql, opencode);
|
|
45
61
|
// Start server
|
|
@@ -51,6 +67,7 @@ export async function serve(options) {
|
|
|
51
67
|
console.log("\nShutting down...");
|
|
52
68
|
server.close(async () => {
|
|
53
69
|
cronScheduler.stop();
|
|
70
|
+
memoryManager.closeAll();
|
|
54
71
|
await sql.end();
|
|
55
72
|
console.log("Goodbye.");
|
|
56
73
|
process.exit(0);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare function clockIn(token: string): Promise<void>;
|
|
2
2
|
export declare function listCoworkers(token: string): Promise<void>;
|
|
3
|
+
export declare function setStatus(token: string, status: string | null): Promise<void>;
|
|
3
4
|
export declare function sendMessage(token: string, recipients: string[], body: string): Promise<void>;
|
|
4
5
|
export declare function listCrons(token: string): Promise<void>;
|
|
5
6
|
export declare function createCron(token: string, options: {
|
|
@@ -12,3 +13,7 @@ export declare function deleteCron(token: string, cronId: number): Promise<void>
|
|
|
12
13
|
export declare function enableCron(token: string, cronId: number): Promise<void>;
|
|
13
14
|
export declare function disableCron(token: string, cronId: number): Promise<void>;
|
|
14
15
|
export declare function cronHistory(token: string, cronId: number): Promise<void>;
|
|
16
|
+
export declare function memoryAdd(token: string, content: string): Promise<void>;
|
|
17
|
+
export declare function memorySearch(token: string, query: string, limit: number): Promise<void>;
|
|
18
|
+
export declare function memoryList(token: string, limit: number): Promise<void>;
|
|
19
|
+
export declare function memoryForget(token: string, memoryId: string): Promise<void>;
|
package/dist/commands/worker.js
CHANGED
|
@@ -112,6 +112,10 @@ export async function listCoworkers(token) {
|
|
|
112
112
|
const workers = await fetchWorker(token, "/worker/list-coworkers");
|
|
113
113
|
console.log(JSON.stringify(workers, null, 2));
|
|
114
114
|
}
|
|
115
|
+
export async function setStatus(token, status) {
|
|
116
|
+
const result = await postWorker(token, "/worker/set-status", { status });
|
|
117
|
+
console.log(JSON.stringify(result, null, 2));
|
|
118
|
+
}
|
|
115
119
|
export async function sendMessage(token, recipients, body) {
|
|
116
120
|
const result = await postWorker(token, "/worker/send-message", { to: recipients, body });
|
|
117
121
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -163,3 +167,66 @@ export async function cronHistory(token, cronId) {
|
|
|
163
167
|
const history = await fetchWorker(token, `/worker/crons/${cronId}/history`);
|
|
164
168
|
console.log(JSON.stringify(history, null, 2));
|
|
165
169
|
}
|
|
170
|
+
// ── Memory Commands ──────────────────────────────────────────────────────────
|
|
171
|
+
export async function memoryAdd(token, content) {
|
|
172
|
+
const result = await postWorker(token, "/worker/memory/add", { content });
|
|
173
|
+
console.log(JSON.stringify(result, null, 2));
|
|
174
|
+
}
|
|
175
|
+
export async function memorySearch(token, query, limit) {
|
|
176
|
+
const result = await postWorker(token, "/worker/memory/search", { query, limit });
|
|
177
|
+
console.log(JSON.stringify(result, null, 2));
|
|
178
|
+
}
|
|
179
|
+
export async function memoryList(token, limit) {
|
|
180
|
+
const { agentCode, serverUrl } = parseToken(token);
|
|
181
|
+
const url = `${serverUrl}/worker/memory/list?code=${encodeURIComponent(agentCode)}&limit=${limit}`;
|
|
182
|
+
let res;
|
|
183
|
+
try {
|
|
184
|
+
res = await fetch(url);
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
console.error(`Error: could not reach ${serverUrl}`);
|
|
188
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
let body;
|
|
192
|
+
try {
|
|
193
|
+
body = await res.json();
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
console.error(`Error: invalid response from server`);
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
if (!res.ok) {
|
|
200
|
+
const msg = body.error ?? `HTTP ${res.status}`;
|
|
201
|
+
console.error(`Error: ${msg}`);
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
console.log(JSON.stringify(body, null, 2));
|
|
205
|
+
}
|
|
206
|
+
export async function memoryForget(token, memoryId) {
|
|
207
|
+
const { agentCode, serverUrl } = parseToken(token);
|
|
208
|
+
const url = `${serverUrl}/worker/memory/${encodeURIComponent(memoryId)}?code=${encodeURIComponent(agentCode)}`;
|
|
209
|
+
let res;
|
|
210
|
+
try {
|
|
211
|
+
res = await fetch(url, { method: "DELETE" });
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
console.error(`Error: could not reach ${serverUrl}`);
|
|
215
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
let body;
|
|
219
|
+
try {
|
|
220
|
+
body = await res.json();
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
console.error(`Error: invalid response from server`);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
if (!res.ok) {
|
|
227
|
+
const msg = body.error ?? `HTTP ${res.status}`;
|
|
228
|
+
console.error(`Error: ${msg}`);
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
console.log(JSON.stringify(body, null, 2));
|
|
232
|
+
}
|
package/dist/db/index.d.ts
CHANGED
package/dist/db/migrate.js
CHANGED
|
@@ -86,6 +86,13 @@ const MIGRATIONS = [
|
|
|
86
86
|
CREATE INDEX IF NOT EXISTS idx_cron_history_job_id ON cron_history(cron_job_id);
|
|
87
87
|
`,
|
|
88
88
|
},
|
|
89
|
+
{
|
|
90
|
+
version: 7,
|
|
91
|
+
name: "add_status_to_sessions",
|
|
92
|
+
sql: `
|
|
93
|
+
ALTER TABLE sessions ADD COLUMN IF NOT EXISTS status TEXT NULL;
|
|
94
|
+
`,
|
|
95
|
+
},
|
|
89
96
|
];
|
|
90
97
|
export async function runMigrations(sql) {
|
|
91
98
|
await sql `
|
package/dist/manage/app.js
CHANGED
|
@@ -23,7 +23,7 @@ const FOOTER_HINTS = {
|
|
|
23
23
|
connecting: "",
|
|
24
24
|
"auth-error": "",
|
|
25
25
|
menu: "↑↓ navigate · Enter select · q quit",
|
|
26
|
-
list: "↑↓ navigate · c create · d delete · r reveal code · g regen · t tail · i inject · m mail · Esc back",
|
|
26
|
+
list: "↑↓ navigate · c create · d delete · r reveal code · g regen · x revert · t tail · i inject · m mail · M memories · Esc back",
|
|
27
27
|
"send-message": "Enter submit · Esc back to menu",
|
|
28
28
|
"my-mail": "↑↓ select message · r reply · m mark read · a mark all read · s sent tab · Esc back",
|
|
29
29
|
"profile": "Enter submit · Esc back to menu",
|