agent-office 0.3.0 → 0.3.1
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 +1 -0
- package/dist/commands/serve.d.ts +1 -0
- package/dist/commands/serve.js +21 -13
- package/dist/server/index.d.ts +2 -2
- package/dist/server/memory.d.ts +51 -28
- package/dist/server/memory.js +159 -25
- package/dist/server/routes.d.ts +3 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -16,6 +16,7 @@ program
|
|
|
16
16
|
.option("--memory-path <path>", "Directory for memory storage (default: ./.memory)", "./.memory")
|
|
17
17
|
.option("--password <password>", "REQUIRED. API password", process.env.AGENT_OFFICE_PASSWORD)
|
|
18
18
|
.option("--opencode-url <url>", "URL of the OpenCode server (default: http://127.0.0.1:4096)", process.env.OPENCODE_URL ?? "http://127.0.0.1:4096")
|
|
19
|
+
.option("--simple-memory", "Use lightweight SQLite+BM25 memory instead of the default fastmemory (no embeddings, no model download)")
|
|
19
20
|
.action(async (options) => {
|
|
20
21
|
const { serve } = await import("./commands/serve.js");
|
|
21
22
|
await serve(options);
|
package/dist/commands/serve.d.ts
CHANGED
package/dist/commands/serve.js
CHANGED
|
@@ -3,7 +3,7 @@ import { runMigrations } from "../db/migrate.js";
|
|
|
3
3
|
import { OpenCodeCodingServer } from "../lib/opencode-coding-server.js";
|
|
4
4
|
import { createApp } from "../server/index.js";
|
|
5
5
|
import { CronScheduler } from "../server/cron.js";
|
|
6
|
-
import {
|
|
6
|
+
import { AgentOfficeFastMemory, AgentOfficeSimpleMemory } from "../server/memory.js";
|
|
7
7
|
export async function serve(options) {
|
|
8
8
|
const password = options.password;
|
|
9
9
|
if (!password) {
|
|
@@ -44,20 +44,28 @@ export async function serve(options) {
|
|
|
44
44
|
const agenticCodingServer = new OpenCodeCodingServer(options.opencodeUrl);
|
|
45
45
|
console.log(`Connecting to OpenCode server at ${options.opencodeUrl}...`);
|
|
46
46
|
const serverUrl = `http://${options.host}:${port}`;
|
|
47
|
-
// Create memory manager
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
// Create memory manager
|
|
48
|
+
let memoryManager;
|
|
49
|
+
if (options.simpleMemory) {
|
|
50
|
+
console.log("Using simple SQLite+BM25 memory backend.");
|
|
51
|
+
memoryManager = new AgentOfficeSimpleMemory(options.memoryPath);
|
|
51
52
|
await memoryManager.warmup();
|
|
52
|
-
console.log("Embedding model ready.");
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
console.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
else {
|
|
55
|
+
memoryManager = new AgentOfficeFastMemory(options.memoryPath);
|
|
56
|
+
console.log("Warming up embedding model...");
|
|
57
|
+
try {
|
|
58
|
+
await memoryManager.warmup();
|
|
59
|
+
console.log("Embedding model ready.");
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
console.error("Embedding model failed to load:", err);
|
|
63
|
+
console.error("Try deleting the model cache and restarting:");
|
|
64
|
+
console.error(` rm -rf ${options.memoryPath}/.model-cache`);
|
|
65
|
+
memoryManager.closeAll();
|
|
66
|
+
await storage.close();
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
61
69
|
}
|
|
62
70
|
// Create cron scheduler
|
|
63
71
|
const cronScheduler = new CronScheduler();
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentOfficeStorage } from "../db/index.js";
|
|
2
2
|
import type { AgenticCodingServer } from "../lib/agentic-coding-server.js";
|
|
3
3
|
import { CronScheduler } from "./cron.js";
|
|
4
|
-
import type {
|
|
5
|
-
export declare function createApp(storage: AgentOfficeStorage, agenticCodingServer: AgenticCodingServer, password: string, serverUrl: string, cronScheduler: CronScheduler, memoryManager:
|
|
4
|
+
import type { AgentOfficeMemory } from "./memory.js";
|
|
5
|
+
export declare function createApp(storage: AgentOfficeStorage, agenticCodingServer: AgenticCodingServer, password: string, serverUrl: string, cronScheduler: CronScheduler, memoryManager: AgentOfficeMemory): import("express-serve-static-core").Express;
|
package/dist/server/memory.d.ts
CHANGED
|
@@ -1,24 +1,66 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type MemoryEntry } from "fastmemory";
|
|
2
2
|
export interface MemoryRecord {
|
|
3
3
|
id: string;
|
|
4
4
|
content: string;
|
|
5
5
|
metadata: Record<string, unknown>;
|
|
6
6
|
createdAt: string;
|
|
7
7
|
}
|
|
8
|
-
type
|
|
8
|
+
export type AgentOfficeMemorySearchResult = MemoryEntry;
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Abstract base class for agent memory backends.
|
|
11
|
+
* Consumers should depend on this type rather than any concrete implementation.
|
|
12
|
+
*/
|
|
13
|
+
export declare abstract class AgentOfficeMemory {
|
|
14
|
+
abstract addMemory(sessionName: string, content: string, metadata?: Record<string, unknown>): Promise<string>;
|
|
15
|
+
abstract searchMemories(sessionName: string, query: string, limit?: number): Promise<AgentOfficeMemorySearchResult[]>;
|
|
16
|
+
abstract listMemories(sessionName: string, limit?: number): MemoryRecord[];
|
|
17
|
+
abstract getMemory(sessionName: string, memoryId: string): MemoryRecord | null;
|
|
18
|
+
abstract deleteMemory(sessionName: string, memoryId: string): boolean;
|
|
19
|
+
abstract updateMemory(sessionName: string, memoryId: string, content: string, metadata?: Record<string, unknown>): Promise<boolean>;
|
|
20
|
+
abstract getStats(sessionName: string): {
|
|
21
|
+
total: number;
|
|
22
|
+
};
|
|
23
|
+
abstract warmup(): Promise<void>;
|
|
24
|
+
abstract closeAll(): void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Lightweight memory backend using a single SQLite database file at
|
|
28
|
+
* <memoryPath>/simple-memory.db. All sessions share the same file; rows are
|
|
29
|
+
* partitioned by session_name. Full-text search is provided by SQLite's
|
|
30
|
+
* built-in FTS5 (BM25 ranking). No embeddings, no external dependencies
|
|
31
|
+
* beyond better-sqlite3.
|
|
32
|
+
*
|
|
33
|
+
* Activate with: agent-office serve --simple-memory
|
|
34
|
+
*/
|
|
35
|
+
export declare class AgentOfficeSimpleMemory extends AgentOfficeMemory {
|
|
36
|
+
private basePath;
|
|
37
|
+
private db;
|
|
38
|
+
constructor(memoryPath: string);
|
|
39
|
+
private _migrate;
|
|
40
|
+
private newId;
|
|
41
|
+
private sanitizeFts5Query;
|
|
42
|
+
addMemory(sessionName: string, content: string, metadata?: Record<string, unknown>): Promise<string>;
|
|
43
|
+
searchMemories(sessionName: string, query: string, limit?: number): Promise<AgentOfficeMemorySearchResult[]>;
|
|
44
|
+
listMemories(sessionName: string, limit?: number): MemoryRecord[];
|
|
45
|
+
getMemory(sessionName: string, memoryId: string): MemoryRecord | null;
|
|
46
|
+
deleteMemory(sessionName: string, memoryId: string): boolean;
|
|
47
|
+
updateMemory(sessionName: string, memoryId: string, content: string, metadata?: Record<string, unknown>): Promise<boolean>;
|
|
48
|
+
getStats(sessionName: string): {
|
|
49
|
+
total: number;
|
|
50
|
+
};
|
|
51
|
+
warmup(): Promise<void>;
|
|
52
|
+
closeAll(): void;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Concrete AgentOfficeMemory implementation backed by fastmemory (SQLite + embeddings).
|
|
11
56
|
* Each session gets its own .db file under <memoryPath>/<sessionName>.db
|
|
12
57
|
*/
|
|
13
|
-
export declare class
|
|
58
|
+
export declare class AgentOfficeFastMemory extends AgentOfficeMemory {
|
|
14
59
|
private basePath;
|
|
15
60
|
private stores;
|
|
16
61
|
constructor(memoryPath: string);
|
|
17
62
|
private dbPathFor;
|
|
18
|
-
getStore
|
|
19
|
-
/**
|
|
20
|
-
* Add a memory for a session
|
|
21
|
-
*/
|
|
63
|
+
private getStore;
|
|
22
64
|
addMemory(sessionName: string, content: string, metadata?: Record<string, unknown>): Promise<string>;
|
|
23
65
|
/**
|
|
24
66
|
* Sanitize a query string for FTS5 MATCH syntax.
|
|
@@ -27,29 +69,11 @@ export declare class MemoryManager {
|
|
|
27
69
|
* treated as literals rather than FTS5 operators.
|
|
28
70
|
*/
|
|
29
71
|
private sanitizeFts5Query;
|
|
30
|
-
|
|
31
|
-
* Search memories using hybrid search (BM25 + vector + RRF)
|
|
32
|
-
*/
|
|
33
|
-
searchMemories(sessionName: string, query: string, limit?: number): Promise<MemoryEntry[]>;
|
|
34
|
-
/**
|
|
35
|
-
* List all memories for a session (direct SQLite access since fastmemory has no list method)
|
|
36
|
-
*/
|
|
72
|
+
searchMemories(sessionName: string, query: string, limit?: number): Promise<AgentOfficeMemorySearchResult[]>;
|
|
37
73
|
listMemories(sessionName: string, limit?: number): MemoryRecord[];
|
|
38
|
-
/**
|
|
39
|
-
* Get a single memory by ID
|
|
40
|
-
*/
|
|
41
74
|
getMemory(sessionName: string, memoryId: string): MemoryRecord | null;
|
|
42
|
-
/**
|
|
43
|
-
* Delete a memory by ID (direct SQLite - fastmemory has no delete method)
|
|
44
|
-
*/
|
|
45
75
|
deleteMemory(sessionName: string, memoryId: string): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Update a memory's content (direct SQLite, re-embeds via delete+add)
|
|
48
|
-
*/
|
|
49
76
|
updateMemory(sessionName: string, memoryId: string, content: string, metadata?: Record<string, unknown>): Promise<boolean>;
|
|
50
|
-
/**
|
|
51
|
-
* Get stats for a session's memory store
|
|
52
|
-
*/
|
|
53
77
|
getStats(sessionName: string): {
|
|
54
78
|
total: number;
|
|
55
79
|
};
|
|
@@ -61,4 +85,3 @@ export declare class MemoryManager {
|
|
|
61
85
|
warmup(): Promise<void>;
|
|
62
86
|
closeAll(): void;
|
|
63
87
|
}
|
|
64
|
-
export {};
|
package/dist/server/memory.js
CHANGED
|
@@ -3,13 +3,169 @@ import { mkdirSync, existsSync } from "fs";
|
|
|
3
3
|
import { join, resolve } from "path";
|
|
4
4
|
import Database from "better-sqlite3";
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Abstract base class for agent memory backends.
|
|
7
|
+
* Consumers should depend on this type rather than any concrete implementation.
|
|
8
|
+
*/
|
|
9
|
+
export class AgentOfficeMemory {
|
|
10
|
+
}
|
|
11
|
+
// ── AgentOfficeSimpleMemory ───────────────────────────────────────────────────
|
|
12
|
+
/**
|
|
13
|
+
* Lightweight memory backend using a single SQLite database file at
|
|
14
|
+
* <memoryPath>/simple-memory.db. All sessions share the same file; rows are
|
|
15
|
+
* partitioned by session_name. Full-text search is provided by SQLite's
|
|
16
|
+
* built-in FTS5 (BM25 ranking). No embeddings, no external dependencies
|
|
17
|
+
* beyond better-sqlite3.
|
|
18
|
+
*
|
|
19
|
+
* Activate with: agent-office serve --simple-memory
|
|
20
|
+
*/
|
|
21
|
+
export class AgentOfficeSimpleMemory extends AgentOfficeMemory {
|
|
22
|
+
basePath;
|
|
23
|
+
db;
|
|
24
|
+
constructor(memoryPath) {
|
|
25
|
+
super();
|
|
26
|
+
this.basePath = resolve(memoryPath);
|
|
27
|
+
if (!existsSync(this.basePath)) {
|
|
28
|
+
mkdirSync(this.basePath, { recursive: true });
|
|
29
|
+
}
|
|
30
|
+
const dbPath = join(this.basePath, "simple-memory.db");
|
|
31
|
+
this.db = new Database(dbPath);
|
|
32
|
+
this.db.pragma("journal_mode = WAL");
|
|
33
|
+
this.db.pragma("foreign_keys = ON");
|
|
34
|
+
this._migrate();
|
|
35
|
+
}
|
|
36
|
+
_migrate() {
|
|
37
|
+
this.db.exec(`
|
|
38
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
39
|
+
id TEXT PRIMARY KEY,
|
|
40
|
+
session_name TEXT NOT NULL,
|
|
41
|
+
content TEXT NOT NULL,
|
|
42
|
+
metadata TEXT NOT NULL DEFAULT '{}',
|
|
43
|
+
created_at TEXT NOT NULL
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
CREATE INDEX IF NOT EXISTS memories_session_idx ON memories (session_name);
|
|
47
|
+
|
|
48
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
|
|
49
|
+
content,
|
|
50
|
+
session_name UNINDEXED,
|
|
51
|
+
memory_id UNINDEXED,
|
|
52
|
+
content='memories',
|
|
53
|
+
content_rowid='rowid',
|
|
54
|
+
tokenize='porter unicode61'
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
|
|
58
|
+
INSERT INTO memories_fts(rowid, content, session_name, memory_id)
|
|
59
|
+
VALUES (new.rowid, new.content, new.session_name, new.id);
|
|
60
|
+
END;
|
|
61
|
+
|
|
62
|
+
CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
|
|
63
|
+
INSERT INTO memories_fts(memories_fts, rowid, content, session_name, memory_id)
|
|
64
|
+
VALUES ('delete', old.rowid, old.content, old.session_name, old.id);
|
|
65
|
+
END;
|
|
66
|
+
|
|
67
|
+
CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN
|
|
68
|
+
INSERT INTO memories_fts(memories_fts, rowid, content, session_name, memory_id)
|
|
69
|
+
VALUES ('delete', old.rowid, old.content, old.session_name, old.id);
|
|
70
|
+
INSERT INTO memories_fts(rowid, content, session_name, memory_id)
|
|
71
|
+
VALUES (new.rowid, new.content, new.session_name, new.id);
|
|
72
|
+
END;
|
|
73
|
+
`);
|
|
74
|
+
}
|
|
75
|
+
newId() {
|
|
76
|
+
// Compact random UUID without hyphens
|
|
77
|
+
return crypto.randomUUID().replace(/-/g, "");
|
|
78
|
+
}
|
|
79
|
+
sanitizeFts5Query(query) {
|
|
80
|
+
return query
|
|
81
|
+
.split(/\s+/)
|
|
82
|
+
.filter((t) => t.length > 0)
|
|
83
|
+
.map((t) => `"${t.replace(/"/g, '""')}"`)
|
|
84
|
+
.join(" ");
|
|
85
|
+
}
|
|
86
|
+
async addMemory(sessionName, content, metadata = {}) {
|
|
87
|
+
const id = this.newId();
|
|
88
|
+
const createdAt = new Date().toISOString();
|
|
89
|
+
this.db.prepare(`INSERT INTO memories (id, session_name, content, metadata, created_at) VALUES (?, ?, ?, ?, ?)`).run(id, sessionName, content, JSON.stringify(metadata), createdAt);
|
|
90
|
+
return id;
|
|
91
|
+
}
|
|
92
|
+
async searchMemories(sessionName, query, limit = 10) {
|
|
93
|
+
if (!query.trim())
|
|
94
|
+
return [];
|
|
95
|
+
const safeQuery = this.sanitizeFts5Query(query);
|
|
96
|
+
const rows = this.db.prepare(`
|
|
97
|
+
SELECT m.id, m.content, m.metadata, m.created_at,
|
|
98
|
+
-bm25(memories_fts) AS score
|
|
99
|
+
FROM memories_fts
|
|
100
|
+
JOIN memories m ON m.id = memories_fts.memory_id
|
|
101
|
+
WHERE memories_fts MATCH ?
|
|
102
|
+
AND memories_fts.session_name = ?
|
|
103
|
+
ORDER BY score DESC
|
|
104
|
+
LIMIT ?
|
|
105
|
+
`).all(safeQuery, sessionName, limit);
|
|
106
|
+
return rows.map((r) => ({
|
|
107
|
+
id: r.id,
|
|
108
|
+
content: r.content,
|
|
109
|
+
metadata: r.metadata ? JSON.parse(r.metadata) : {},
|
|
110
|
+
createdAt: r.created_at,
|
|
111
|
+
score: r.score,
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
listMemories(sessionName, limit = 50) {
|
|
115
|
+
const rows = this.db.prepare(`SELECT id, content, metadata, created_at FROM memories WHERE session_name = ? ORDER BY created_at DESC LIMIT ?`).all(sessionName, limit);
|
|
116
|
+
return rows.map((r) => ({
|
|
117
|
+
id: r.id,
|
|
118
|
+
content: r.content,
|
|
119
|
+
metadata: r.metadata ? JSON.parse(r.metadata) : {},
|
|
120
|
+
createdAt: r.created_at,
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
getMemory(sessionName, memoryId) {
|
|
124
|
+
const row = this.db.prepare(`SELECT id, content, metadata, created_at FROM memories WHERE id = ? AND session_name = ?`).get(memoryId, sessionName);
|
|
125
|
+
if (!row)
|
|
126
|
+
return null;
|
|
127
|
+
return {
|
|
128
|
+
id: row.id,
|
|
129
|
+
content: row.content,
|
|
130
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : {},
|
|
131
|
+
createdAt: row.created_at,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
deleteMemory(sessionName, memoryId) {
|
|
135
|
+
const result = this.db.prepare(`DELETE FROM memories WHERE id = ? AND session_name = ?`).run(memoryId, sessionName);
|
|
136
|
+
return result.changes > 0;
|
|
137
|
+
}
|
|
138
|
+
async updateMemory(sessionName, memoryId, content, metadata) {
|
|
139
|
+
const existing = this.getMemory(sessionName, memoryId);
|
|
140
|
+
if (!existing)
|
|
141
|
+
return false;
|
|
142
|
+
const finalMetadata = metadata ?? existing.metadata;
|
|
143
|
+
const result = this.db.prepare(`UPDATE memories SET content = ?, metadata = ? WHERE id = ? AND session_name = ?`).run(content, JSON.stringify(finalMetadata), memoryId, sessionName);
|
|
144
|
+
return result.changes > 0;
|
|
145
|
+
}
|
|
146
|
+
getStats(sessionName) {
|
|
147
|
+
const row = this.db.prepare(`SELECT COUNT(*) as total FROM memories WHERE session_name = ?`).get(sessionName);
|
|
148
|
+
return { total: row.total };
|
|
149
|
+
}
|
|
150
|
+
async warmup() {
|
|
151
|
+
// No model to warm up — DB is already open and ready.
|
|
152
|
+
}
|
|
153
|
+
closeAll() {
|
|
154
|
+
try {
|
|
155
|
+
this.db.close();
|
|
156
|
+
}
|
|
157
|
+
catch { /* ignore */ }
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Concrete AgentOfficeMemory implementation backed by fastmemory (SQLite + embeddings).
|
|
7
162
|
* Each session gets its own .db file under <memoryPath>/<sessionName>.db
|
|
8
163
|
*/
|
|
9
|
-
export class
|
|
164
|
+
export class AgentOfficeFastMemory extends AgentOfficeMemory {
|
|
10
165
|
basePath;
|
|
11
166
|
stores = new Map();
|
|
12
167
|
constructor(memoryPath) {
|
|
168
|
+
super();
|
|
13
169
|
this.basePath = resolve(memoryPath);
|
|
14
170
|
if (!existsSync(this.basePath)) {
|
|
15
171
|
mkdirSync(this.basePath, { recursive: true });
|
|
@@ -34,9 +190,6 @@ export class MemoryManager {
|
|
|
34
190
|
this.stores.set(sessionName, store);
|
|
35
191
|
return store;
|
|
36
192
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Add a memory for a session
|
|
39
|
-
*/
|
|
40
193
|
async addMemory(sessionName, content, metadata = {}) {
|
|
41
194
|
const store = await this.getStore(sessionName);
|
|
42
195
|
return await store.add(content, metadata);
|
|
@@ -54,17 +207,11 @@ export class MemoryManager {
|
|
|
54
207
|
.map((t) => `"${t.replace(/"/g, '""')}"`)
|
|
55
208
|
.join(" ");
|
|
56
209
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Search memories using hybrid search (BM25 + vector + RRF)
|
|
59
|
-
*/
|
|
60
210
|
async searchMemories(sessionName, query, limit = 10) {
|
|
61
211
|
const store = await this.getStore(sessionName);
|
|
62
212
|
const safeQuery = this.sanitizeFts5Query(query);
|
|
63
213
|
return await store.searchHybrid(safeQuery, limit);
|
|
64
214
|
}
|
|
65
|
-
/**
|
|
66
|
-
* List all memories for a session (direct SQLite access since fastmemory has no list method)
|
|
67
|
-
*/
|
|
68
215
|
listMemories(sessionName, limit = 50) {
|
|
69
216
|
const dbPath = this.dbPathFor(sessionName);
|
|
70
217
|
if (!existsSync(dbPath))
|
|
@@ -84,9 +231,6 @@ export class MemoryManager {
|
|
|
84
231
|
db.close();
|
|
85
232
|
}
|
|
86
233
|
}
|
|
87
|
-
/**
|
|
88
|
-
* Get a single memory by ID
|
|
89
|
-
*/
|
|
90
234
|
getMemory(sessionName, memoryId) {
|
|
91
235
|
const dbPath = this.dbPathFor(sessionName);
|
|
92
236
|
if (!existsSync(dbPath))
|
|
@@ -108,9 +252,6 @@ export class MemoryManager {
|
|
|
108
252
|
db.close();
|
|
109
253
|
}
|
|
110
254
|
}
|
|
111
|
-
/**
|
|
112
|
-
* Delete a memory by ID (direct SQLite - fastmemory has no delete method)
|
|
113
|
-
*/
|
|
114
255
|
deleteMemory(sessionName, memoryId) {
|
|
115
256
|
const dbPath = this.dbPathFor(sessionName);
|
|
116
257
|
if (!existsSync(dbPath))
|
|
@@ -125,9 +266,6 @@ export class MemoryManager {
|
|
|
125
266
|
db.close();
|
|
126
267
|
}
|
|
127
268
|
}
|
|
128
|
-
/**
|
|
129
|
-
* Update a memory's content (direct SQLite, re-embeds via delete+add)
|
|
130
|
-
*/
|
|
131
269
|
async updateMemory(sessionName, memoryId, content, metadata) {
|
|
132
270
|
const existing = this.getMemory(sessionName, memoryId);
|
|
133
271
|
if (!existing)
|
|
@@ -140,14 +278,10 @@ export class MemoryManager {
|
|
|
140
278
|
this.stores.delete(sessionName);
|
|
141
279
|
}
|
|
142
280
|
const store = await this.getStore(sessionName);
|
|
143
|
-
// Re-add with new content but preserve metadata if not provided
|
|
144
281
|
const finalMetadata = metadata ?? existing.metadata;
|
|
145
282
|
await store.add(content, finalMetadata);
|
|
146
283
|
return true;
|
|
147
284
|
}
|
|
148
|
-
/**
|
|
149
|
-
* Get stats for a session's memory store
|
|
150
|
-
*/
|
|
151
285
|
getStats(sessionName) {
|
|
152
286
|
const dbPath = this.dbPathFor(sessionName);
|
|
153
287
|
if (!existsSync(dbPath))
|
|
@@ -177,7 +311,7 @@ export class MemoryManager {
|
|
|
177
311
|
});
|
|
178
312
|
try {
|
|
179
313
|
// Force an embedding by adding and searching
|
|
180
|
-
|
|
314
|
+
await store.add("warmup test memory");
|
|
181
315
|
const results = await store.searchHybrid("warmup test", 1);
|
|
182
316
|
if (results.length === 0) {
|
|
183
317
|
throw new Error("Embedding model warmup: search returned no results");
|
package/dist/server/routes.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Router } from "express";
|
|
|
2
2
|
import type { AgentOfficeStorage } from "../db/index.js";
|
|
3
3
|
import type { AgenticCodingServer } from "../lib/agentic-coding-server.js";
|
|
4
4
|
import { CronScheduler } from "./cron.js";
|
|
5
|
-
import type {
|
|
5
|
+
import type { AgentOfficeMemory } from "./memory.js";
|
|
6
6
|
/**
|
|
7
7
|
* Build the persistent system-prompt briefing for a worker session.
|
|
8
8
|
* This is injected as the `system` field on every `promptAsync` call so the
|
|
@@ -10,5 +10,5 @@ import type { MemoryManager } from "./memory.js";
|
|
|
10
10
|
* without consuming a user-message turn.
|
|
11
11
|
*/
|
|
12
12
|
export declare function generateSystemPrompt(name: string, status: string | null, humanName: string, humanDescription: string, token: string): string;
|
|
13
|
-
export declare function createRouter(storage: AgentOfficeStorage, agenticCodingServer: AgenticCodingServer, serverUrl: string, scheduler: CronScheduler, memoryManager:
|
|
14
|
-
export declare function createWorkerRouter(storage: AgentOfficeStorage, agenticCodingServer: AgenticCodingServer, serverUrl: string, memoryManager:
|
|
13
|
+
export declare function createRouter(storage: AgentOfficeStorage, agenticCodingServer: AgenticCodingServer, serverUrl: string, scheduler: CronScheduler, memoryManager: AgentOfficeMemory): Router;
|
|
14
|
+
export declare function createWorkerRouter(storage: AgentOfficeStorage, agenticCodingServer: AgenticCodingServer, serverUrl: string, memoryManager: AgentOfficeMemory): Router;
|