agent-office 0.3.1 → 0.4.0
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/README.md +18 -40
- package/dist/cli.js +23 -64
- package/dist/commands/communicator.d.ts +2 -2
- package/dist/commands/communicator.js +175 -40
- package/dist/commands/notifier.d.ts +11 -0
- package/dist/commands/notifier.js +100 -0
- package/dist/commands/screensaver.d.ts +1 -1
- package/dist/commands/screensaver.js +47 -3
- package/dist/commands/serve.d.ts +0 -2
- package/dist/commands/serve.js +1 -26
- package/dist/commands/worker.d.ts +1 -4
- package/dist/commands/worker.js +2 -64
- package/dist/db/index.d.ts +1 -0
- package/dist/db/postgresql-storage.d.ts +7 -1
- package/dist/db/postgresql-storage.js +37 -14
- package/dist/db/sqlite-storage.d.ts +7 -1
- package/dist/db/sqlite-storage.js +51 -12
- package/dist/db/storage-base.d.ts +7 -1
- package/dist/db/storage-base.js +1 -1
- package/dist/db/storage.d.ts +7 -1
- package/dist/lib/notifier.d.ts +18 -0
- package/dist/lib/notifier.js +15 -0
- package/dist/manage/components/SessionList.js +0 -266
- package/dist/manage/hooks/useApi.d.ts +0 -24
- package/dist/manage/hooks/useApi.js +0 -24
- package/dist/server/index.d.ts +1 -2
- package/dist/server/index.js +3 -3
- package/dist/server/routes.d.ts +2 -3
- package/dist/server/routes.js +72 -252
- package/package.json +4 -4
- package/dist/server/memory.d.ts +0 -87
- package/dist/server/memory.js +0 -348
package/dist/server/routes.js
CHANGED
|
@@ -4,17 +4,12 @@ const MAIL_INJECTION_BLURB = [
|
|
|
4
4
|
``,
|
|
5
5
|
`---`,
|
|
6
6
|
`You have a new message. Please review the injected message above and respond accordingly.`,
|
|
7
|
-
`IMPORTANT: When reading or responding, note that dollar signs ($) and other special`,
|
|
8
|
-
`characters may be interpreted as markdown. The sender may have included them but they`,
|
|
9
|
-
`could appear differently in your session view. Interpret context accordingly.`,
|
|
10
7
|
``,
|
|
11
8
|
`When responding to the sender:`,
|
|
12
9
|
`- Use the \`agent-office worker send-message\` tool so they can see your reply`,
|
|
13
10
|
`- Avoid excessive length - keep responses concise`,
|
|
14
|
-
`-
|
|
15
|
-
|
|
16
|
-
`Tip: For currency or prices, use code blocks. Example: put numbers in single or`,
|
|
17
|
-
`double quotes to preserve formatting characters like dollar signs.`,
|
|
11
|
+
`- Feel free to use markdown formatting`,
|
|
12
|
+
`- IMPORTANT: Remember when using bash commands certain characters (like dollar signs) may need to be escaped or wrapped in quotes`,
|
|
18
13
|
].join("\n");
|
|
19
14
|
/**
|
|
20
15
|
* Build the persistent system-prompt briefing for a worker session.
|
|
@@ -78,23 +73,22 @@ export function generateSystemPrompt(name, status, humanName, humanDescription,
|
|
|
78
73
|
` agent-office worker cron \\`,
|
|
79
74
|
` ${token}`,
|
|
80
75
|
``,
|
|
81
|
-
`
|
|
82
|
-
` agent-office worker
|
|
83
|
-
` --
|
|
84
|
-
`
|
|
85
|
-
|
|
86
|
-
`
|
|
87
|
-
` agent-office worker memory search \\`,
|
|
88
|
-
` --query "your search" \\`,
|
|
76
|
+
` Create a cron job (scheduled task)`,
|
|
77
|
+
` agent-office worker cron create \\`,
|
|
78
|
+
` --name <job-name> \\`,
|
|
79
|
+
` --schedule "<cron-expression>" \\`,
|
|
80
|
+
` --message "<action-to-perform>" \\`,
|
|
81
|
+
` --respond-to "<who-to-respond-to-when-done>" \\`,
|
|
89
82
|
` ${token}`,
|
|
90
83
|
``,
|
|
91
|
-
`
|
|
92
|
-
`
|
|
93
|
-
`
|
|
84
|
+
` Example: Daily standup reminder at 9am`,
|
|
85
|
+
` --schedule "0 9 * * *" \\`,
|
|
86
|
+
` --message "Prepare your standup update" \\`,
|
|
87
|
+
` --respond-to "${humanName} in the standup channel"`,
|
|
94
88
|
``,
|
|
95
|
-
`
|
|
96
|
-
`
|
|
97
|
-
`
|
|
89
|
+
` The final injected message will be formatted as:`,
|
|
90
|
+
` Action: <message>`,
|
|
91
|
+
` Who to respond to when done: <respond-to>`,
|
|
98
92
|
``,
|
|
99
93
|
`════════════════════════════════════════════════════════`,
|
|
100
94
|
` IMPORTANT: YOUR SESSIONS ARE PRIVATE`,
|
|
@@ -141,7 +135,7 @@ async function loadHumanConfig(storage) {
|
|
|
141
135
|
humanDescription: humanDescription ?? "",
|
|
142
136
|
};
|
|
143
137
|
}
|
|
144
|
-
export function createRouter(storage, agenticCodingServer, serverUrl, scheduler
|
|
138
|
+
export function createRouter(storage, agenticCodingServer, serverUrl, scheduler) {
|
|
145
139
|
const router = Router();
|
|
146
140
|
router.get("/health", (_req, res) => {
|
|
147
141
|
res.json({ ok: true });
|
|
@@ -192,6 +186,27 @@ export function createRouter(storage, agenticCodingServer, serverUrl, scheduler,
|
|
|
192
186
|
res.status(500).json({ error: "Internal server error" });
|
|
193
187
|
}
|
|
194
188
|
});
|
|
189
|
+
router.get("/coworkers", async (_req, res) => {
|
|
190
|
+
try {
|
|
191
|
+
const sessions = await storage.listSessions();
|
|
192
|
+
const humanName = await storage.getConfig('human_name') ?? "Human";
|
|
193
|
+
const unreadCounts = await storage.countUnreadBySender(humanName);
|
|
194
|
+
const coworkers = [
|
|
195
|
+
{ name: humanName, status: null, isHuman: true, unreadMessages: 0 },
|
|
196
|
+
...sessions.map(s => ({
|
|
197
|
+
name: s.name,
|
|
198
|
+
status: s.status,
|
|
199
|
+
isHuman: false,
|
|
200
|
+
unreadMessages: unreadCounts.get(s.name) ?? 0
|
|
201
|
+
}))
|
|
202
|
+
];
|
|
203
|
+
res.json(coworkers);
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
console.error("GET /coworkers error:", err);
|
|
207
|
+
res.status(500).json({ error: "Internal server error" });
|
|
208
|
+
}
|
|
209
|
+
});
|
|
195
210
|
router.post("/sessions", async (req, res) => {
|
|
196
211
|
const { name, agent: agentArg } = req.body;
|
|
197
212
|
if (!name || typeof name !== "string" || !name.trim()) {
|
|
@@ -441,7 +456,7 @@ export function createRouter(storage, agenticCodingServer, serverUrl, scheduler,
|
|
|
441
456
|
rows = await storage.listMessagesFromSender(name);
|
|
442
457
|
}
|
|
443
458
|
else {
|
|
444
|
-
rows = await storage.listMessagesForRecipient(name, unread_only === "true");
|
|
459
|
+
rows = await storage.listMessagesForRecipient(name, unread_only === "true" ? { unread: true } : undefined);
|
|
445
460
|
}
|
|
446
461
|
res.json(rows);
|
|
447
462
|
}
|
|
@@ -524,6 +539,39 @@ export function createRouter(storage, agenticCodingServer, serverUrl, scheduler,
|
|
|
524
539
|
res.status(500).json({ error: "Internal server error" });
|
|
525
540
|
}
|
|
526
541
|
});
|
|
542
|
+
// ── Human Notification API ─────────────────────────────────────────────────
|
|
543
|
+
router.get("/human/unread-old", async (req, res) => {
|
|
544
|
+
try {
|
|
545
|
+
const hoursStr = req.query.hours ?? "";
|
|
546
|
+
const hours = hoursStr !== "" ? parseFloat(hoursStr) : 1;
|
|
547
|
+
const humanName = (await storage.getConfig("human_name")) ?? "Human";
|
|
548
|
+
const msgs = await storage.listMessagesForRecipient(humanName, {
|
|
549
|
+
unread: true,
|
|
550
|
+
olderThanHours: hours,
|
|
551
|
+
notified: false,
|
|
552
|
+
});
|
|
553
|
+
res.json(msgs);
|
|
554
|
+
}
|
|
555
|
+
catch (err) {
|
|
556
|
+
console.error("GET /human/unread-old error:", err);
|
|
557
|
+
res.status(500).json({ error: "Internal server error" });
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
router.post("/human/mark-notified", async (req, res) => {
|
|
561
|
+
try {
|
|
562
|
+
const ids = req.body.ids;
|
|
563
|
+
if (!Array.isArray(ids) || !ids.every((id) => typeof id === "number")) {
|
|
564
|
+
res.status(400).json({ error: "ids must be an array of numbers" });
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
await storage.markMessagesAsNotified(ids);
|
|
568
|
+
res.json({ success: true, count: ids.length });
|
|
569
|
+
}
|
|
570
|
+
catch (err) {
|
|
571
|
+
console.error("POST /human/mark-notified error:", err);
|
|
572
|
+
res.status(500).json({ error: "Internal server error" });
|
|
573
|
+
}
|
|
574
|
+
});
|
|
527
575
|
// ── Cron Jobs Endpoints ────────────────────────────────────────────────────
|
|
528
576
|
router.get("/crons", async (req, res) => {
|
|
529
577
|
try {
|
|
@@ -739,135 +787,9 @@ export function createRouter(storage, agenticCodingServer, serverUrl, scheduler,
|
|
|
739
787
|
res.status(500).json({ error: "Internal server error" });
|
|
740
788
|
}
|
|
741
789
|
});
|
|
742
|
-
// ── Memory Endpoints (authenticated, for manage TUI) ───────────────────────
|
|
743
|
-
router.get("/sessions/:name/memories", async (req, res) => {
|
|
744
|
-
const { name } = req.params;
|
|
745
|
-
const limit = Math.min(parseInt(req.query.limit ?? "50", 10), 200);
|
|
746
|
-
const sessionId = await storage.getSessionIdByName(name);
|
|
747
|
-
if (!sessionId) {
|
|
748
|
-
res.status(404).json({ error: `Session "${name}" not found` });
|
|
749
|
-
return;
|
|
750
|
-
}
|
|
751
|
-
try {
|
|
752
|
-
const memories = memoryManager.listMemories(name, limit);
|
|
753
|
-
const stats = memoryManager.getStats(name);
|
|
754
|
-
res.json({ memories, total: stats.total });
|
|
755
|
-
}
|
|
756
|
-
catch (err) {
|
|
757
|
-
console.error("GET /sessions/:name/memories error:", err);
|
|
758
|
-
res.status(500).json({ error: "Internal server error" });
|
|
759
|
-
}
|
|
760
|
-
});
|
|
761
|
-
router.post("/sessions/:name/memories", async (req, res) => {
|
|
762
|
-
const { name } = req.params;
|
|
763
|
-
const { content, metadata } = req.body;
|
|
764
|
-
if (!content || typeof content !== "string" || !content.trim()) {
|
|
765
|
-
res.status(400).json({ error: "content is required" });
|
|
766
|
-
return;
|
|
767
|
-
}
|
|
768
|
-
const sessionId = await storage.getSessionIdByName(name);
|
|
769
|
-
if (!sessionId) {
|
|
770
|
-
res.status(404).json({ error: `Session "${name}" not found` });
|
|
771
|
-
return;
|
|
772
|
-
}
|
|
773
|
-
try {
|
|
774
|
-
const id = await memoryManager.addMemory(name, content.trim(), metadata ?? {});
|
|
775
|
-
res.status(201).json({ ok: true, id });
|
|
776
|
-
}
|
|
777
|
-
catch (err) {
|
|
778
|
-
console.error("POST /sessions/:name/memories error:", err);
|
|
779
|
-
res.status(500).json({ error: "Internal server error" });
|
|
780
|
-
}
|
|
781
|
-
});
|
|
782
|
-
router.get("/sessions/:name/memories/:memoryId", async (req, res) => {
|
|
783
|
-
const { name, memoryId } = req.params;
|
|
784
|
-
const sessionId = await storage.getSessionIdByName(name);
|
|
785
|
-
if (!sessionId) {
|
|
786
|
-
res.status(404).json({ error: `Session "${name}" not found` });
|
|
787
|
-
return;
|
|
788
|
-
}
|
|
789
|
-
try {
|
|
790
|
-
const memory = memoryManager.getMemory(name, memoryId);
|
|
791
|
-
if (!memory) {
|
|
792
|
-
res.status(404).json({ error: "Memory not found" });
|
|
793
|
-
return;
|
|
794
|
-
}
|
|
795
|
-
res.json(memory);
|
|
796
|
-
}
|
|
797
|
-
catch (err) {
|
|
798
|
-
console.error("GET /sessions/:name/memories/:memoryId error:", err);
|
|
799
|
-
res.status(500).json({ error: "Internal server error" });
|
|
800
|
-
}
|
|
801
|
-
});
|
|
802
|
-
router.put("/sessions/:name/memories/:memoryId", async (req, res) => {
|
|
803
|
-
const { name, memoryId } = req.params;
|
|
804
|
-
const { content, metadata } = req.body;
|
|
805
|
-
if (!content || typeof content !== "string" || !content.trim()) {
|
|
806
|
-
res.status(400).json({ error: "content is required" });
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
const sessionId = await storage.getSessionIdByName(name);
|
|
810
|
-
if (!sessionId) {
|
|
811
|
-
res.status(404).json({ error: `Session "${name}" not found` });
|
|
812
|
-
return;
|
|
813
|
-
}
|
|
814
|
-
try {
|
|
815
|
-
const updated = await memoryManager.updateMemory(name, memoryId, content.trim(), metadata);
|
|
816
|
-
if (!updated) {
|
|
817
|
-
res.status(404).json({ error: "Memory not found" });
|
|
818
|
-
return;
|
|
819
|
-
}
|
|
820
|
-
res.json({ ok: true });
|
|
821
|
-
}
|
|
822
|
-
catch (err) {
|
|
823
|
-
console.error("PUT /sessions/:name/memories/:memoryId error:", err);
|
|
824
|
-
res.status(500).json({ error: "Internal server error" });
|
|
825
|
-
}
|
|
826
|
-
});
|
|
827
|
-
router.delete("/sessions/:name/memories/:memoryId", async (req, res) => {
|
|
828
|
-
const { name, memoryId } = req.params;
|
|
829
|
-
const sessionId = await storage.getSessionIdByName(name);
|
|
830
|
-
if (!sessionId) {
|
|
831
|
-
res.status(404).json({ error: `Session "${name}" not found` });
|
|
832
|
-
return;
|
|
833
|
-
}
|
|
834
|
-
try {
|
|
835
|
-
const deleted = memoryManager.deleteMemory(name, memoryId);
|
|
836
|
-
if (!deleted) {
|
|
837
|
-
res.status(404).json({ error: "Memory not found" });
|
|
838
|
-
return;
|
|
839
|
-
}
|
|
840
|
-
res.json({ deleted: true, id: memoryId });
|
|
841
|
-
}
|
|
842
|
-
catch (err) {
|
|
843
|
-
console.error("DELETE /sessions/:name/memories/:memoryId error:", err);
|
|
844
|
-
res.status(500).json({ error: "Internal server error" });
|
|
845
|
-
}
|
|
846
|
-
});
|
|
847
|
-
router.post("/sessions/:name/memories/search", async (req, res) => {
|
|
848
|
-
const { name } = req.params;
|
|
849
|
-
const { query, limit } = req.body;
|
|
850
|
-
if (!query || typeof query !== "string" || !query.trim()) {
|
|
851
|
-
res.status(400).json({ error: "query is required" });
|
|
852
|
-
return;
|
|
853
|
-
}
|
|
854
|
-
const sessionId = await storage.getSessionIdByName(name);
|
|
855
|
-
if (!sessionId) {
|
|
856
|
-
res.status(404).json({ error: `Session "${name}" not found` });
|
|
857
|
-
return;
|
|
858
|
-
}
|
|
859
|
-
try {
|
|
860
|
-
const results = await memoryManager.searchMemories(name, query.trim(), Math.min(limit ?? 10, 50));
|
|
861
|
-
res.json(results);
|
|
862
|
-
}
|
|
863
|
-
catch (err) {
|
|
864
|
-
console.error("POST /sessions/:name/memories/search error:", err);
|
|
865
|
-
res.status(500).json({ error: "Internal server error" });
|
|
866
|
-
}
|
|
867
|
-
});
|
|
868
790
|
return router;
|
|
869
791
|
}
|
|
870
|
-
export function createWorkerRouter(storage, agenticCodingServer, serverUrl
|
|
792
|
+
export function createWorkerRouter(storage, agenticCodingServer, serverUrl) {
|
|
871
793
|
const router = Router();
|
|
872
794
|
router.get("/worker/list-coworkers", async (req, res) => {
|
|
873
795
|
const { code } = req.query;
|
|
@@ -1255,107 +1177,5 @@ export function createWorkerRouter(storage, agenticCodingServer, serverUrl, memo
|
|
|
1255
1177
|
res.status(500).json({ error: "Internal server error" });
|
|
1256
1178
|
}
|
|
1257
1179
|
});
|
|
1258
|
-
// ── Worker Memory Endpoints (authenticated via agent_code in query) ────────
|
|
1259
|
-
router.post("/worker/memory/add", async (req, res) => {
|
|
1260
|
-
const { code } = req.query;
|
|
1261
|
-
const { content, metadata } = req.body;
|
|
1262
|
-
if (!code || typeof code !== "string") {
|
|
1263
|
-
res.status(400).json({ error: "code query parameter is required" });
|
|
1264
|
-
return;
|
|
1265
|
-
}
|
|
1266
|
-
if (!content || typeof content !== "string" || !content.trim()) {
|
|
1267
|
-
res.status(400).json({ error: "content is required" });
|
|
1268
|
-
return;
|
|
1269
|
-
}
|
|
1270
|
-
const session = await storage.getSessionByAgentCode(code);
|
|
1271
|
-
if (!session) {
|
|
1272
|
-
res.status(401).json({ error: "Invalid agent code" });
|
|
1273
|
-
return;
|
|
1274
|
-
}
|
|
1275
|
-
const sessionName = session.name;
|
|
1276
|
-
try {
|
|
1277
|
-
const id = await memoryManager.addMemory(sessionName, content.trim(), metadata ?? {});
|
|
1278
|
-
res.status(201).json({ ok: true, id });
|
|
1279
|
-
}
|
|
1280
|
-
catch (err) {
|
|
1281
|
-
console.error("POST /worker/memory/add error:", err);
|
|
1282
|
-
res.status(500).json({ error: "Internal server error" });
|
|
1283
|
-
}
|
|
1284
|
-
});
|
|
1285
|
-
router.post("/worker/memory/search", async (req, res) => {
|
|
1286
|
-
const { code } = req.query;
|
|
1287
|
-
const { query, limit } = req.body;
|
|
1288
|
-
if (!code || typeof code !== "string") {
|
|
1289
|
-
res.status(400).json({ error: "code query parameter is required" });
|
|
1290
|
-
return;
|
|
1291
|
-
}
|
|
1292
|
-
if (!query || typeof query !== "string" || !query.trim()) {
|
|
1293
|
-
res.status(400).json({ error: "query is required" });
|
|
1294
|
-
return;
|
|
1295
|
-
}
|
|
1296
|
-
const session = await storage.getSessionByAgentCode(code);
|
|
1297
|
-
if (!session) {
|
|
1298
|
-
res.status(401).json({ error: "Invalid agent code" });
|
|
1299
|
-
return;
|
|
1300
|
-
}
|
|
1301
|
-
const sessionName = session.name;
|
|
1302
|
-
try {
|
|
1303
|
-
const results = await memoryManager.searchMemories(sessionName, query.trim(), Math.min(limit ?? 10, 50));
|
|
1304
|
-
res.json(results);
|
|
1305
|
-
}
|
|
1306
|
-
catch (err) {
|
|
1307
|
-
console.error("POST /worker/memory/search error:", err);
|
|
1308
|
-
res.status(500).json({ error: "Internal server error" });
|
|
1309
|
-
}
|
|
1310
|
-
});
|
|
1311
|
-
router.get("/worker/memory/list", async (req, res) => {
|
|
1312
|
-
const { code, limit: limitStr } = req.query;
|
|
1313
|
-
if (!code || typeof code !== "string") {
|
|
1314
|
-
res.status(400).json({ error: "code query parameter is required" });
|
|
1315
|
-
return;
|
|
1316
|
-
}
|
|
1317
|
-
const session = await storage.getSessionByAgentCode(code);
|
|
1318
|
-
if (!session) {
|
|
1319
|
-
res.status(401).json({ error: "Invalid agent code" });
|
|
1320
|
-
return;
|
|
1321
|
-
}
|
|
1322
|
-
const sessionName = session.name;
|
|
1323
|
-
const limit = Math.min(parseInt(limitStr ?? "50", 10), 200);
|
|
1324
|
-
try {
|
|
1325
|
-
const memories = memoryManager.listMemories(sessionName, limit);
|
|
1326
|
-
const stats = memoryManager.getStats(sessionName);
|
|
1327
|
-
res.json({ memories, total: stats.total });
|
|
1328
|
-
}
|
|
1329
|
-
catch (err) {
|
|
1330
|
-
console.error("GET /worker/memory/list error:", err);
|
|
1331
|
-
res.status(500).json({ error: "Internal server error" });
|
|
1332
|
-
}
|
|
1333
|
-
});
|
|
1334
|
-
router.delete("/worker/memory/:memoryId", async (req, res) => {
|
|
1335
|
-
const { code } = req.query;
|
|
1336
|
-
const { memoryId } = req.params;
|
|
1337
|
-
if (!code || typeof code !== "string") {
|
|
1338
|
-
res.status(400).json({ error: "code query parameter is required" });
|
|
1339
|
-
return;
|
|
1340
|
-
}
|
|
1341
|
-
const session = await storage.getSessionByAgentCode(code);
|
|
1342
|
-
if (!session) {
|
|
1343
|
-
res.status(401).json({ error: "Invalid agent code" });
|
|
1344
|
-
return;
|
|
1345
|
-
}
|
|
1346
|
-
const sessionName = session.name;
|
|
1347
|
-
try {
|
|
1348
|
-
const deleted = memoryManager.deleteMemory(sessionName, memoryId);
|
|
1349
|
-
if (!deleted) {
|
|
1350
|
-
res.status(404).json({ error: "Memory not found" });
|
|
1351
|
-
return;
|
|
1352
|
-
}
|
|
1353
|
-
res.json({ deleted: true, id: memoryId });
|
|
1354
|
-
}
|
|
1355
|
-
catch (err) {
|
|
1356
|
-
console.error("DELETE /worker/memory/:memoryId error:", err);
|
|
1357
|
-
res.status(500).json({ error: "Internal server error" });
|
|
1358
|
-
}
|
|
1359
|
-
});
|
|
1360
1180
|
return router;
|
|
1361
1181
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-office",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "An office for your AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,17 +40,17 @@
|
|
|
40
40
|
"croner": "^10.0.1",
|
|
41
41
|
"dotenv": "^17.0.0",
|
|
42
42
|
"express": "^5.0.0",
|
|
43
|
-
"fastmemory": "^0.1.5",
|
|
44
43
|
"ink": "^6.0.0",
|
|
45
44
|
"postgres": "^3.4.0",
|
|
46
|
-
"react": "^19.0.0"
|
|
45
|
+
"react": "^19.0.0",
|
|
46
|
+
"resend": "^6.9.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/better-sqlite3": "^7.6.13",
|
|
50
50
|
"@types/express": "^5.0.0",
|
|
51
51
|
"@types/node": "^22.0.0",
|
|
52
52
|
"@types/react": "^19.0.0",
|
|
53
|
-
"tsx": "^4.
|
|
53
|
+
"tsx": "^4.21.0",
|
|
54
54
|
"typescript": "^5.0.0"
|
|
55
55
|
}
|
|
56
56
|
}
|
package/dist/server/memory.d.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { type MemoryEntry } from "fastmemory";
|
|
2
|
-
export interface MemoryRecord {
|
|
3
|
-
id: string;
|
|
4
|
-
content: string;
|
|
5
|
-
metadata: Record<string, unknown>;
|
|
6
|
-
createdAt: string;
|
|
7
|
-
}
|
|
8
|
-
export type AgentOfficeMemorySearchResult = MemoryEntry;
|
|
9
|
-
/**
|
|
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).
|
|
56
|
-
* Each session gets its own .db file under <memoryPath>/<sessionName>.db
|
|
57
|
-
*/
|
|
58
|
-
export declare class AgentOfficeFastMemory extends AgentOfficeMemory {
|
|
59
|
-
private basePath;
|
|
60
|
-
private stores;
|
|
61
|
-
constructor(memoryPath: string);
|
|
62
|
-
private dbPathFor;
|
|
63
|
-
private getStore;
|
|
64
|
-
addMemory(sessionName: string, content: string, metadata?: Record<string, unknown>): Promise<string>;
|
|
65
|
-
/**
|
|
66
|
-
* Sanitize a query string for FTS5 MATCH syntax.
|
|
67
|
-
* Wraps each whitespace-delimited token in double quotes so that
|
|
68
|
-
* special characters (apostrophes, parens, asterisks, etc.) are
|
|
69
|
-
* treated as literals rather than FTS5 operators.
|
|
70
|
-
*/
|
|
71
|
-
private sanitizeFts5Query;
|
|
72
|
-
searchMemories(sessionName: string, query: string, limit?: number): Promise<AgentOfficeMemorySearchResult[]>;
|
|
73
|
-
listMemories(sessionName: string, limit?: number): MemoryRecord[];
|
|
74
|
-
getMemory(sessionName: string, memoryId: string): MemoryRecord | null;
|
|
75
|
-
deleteMemory(sessionName: string, memoryId: string): boolean;
|
|
76
|
-
updateMemory(sessionName: string, memoryId: string, content: string, metadata?: Record<string, unknown>): Promise<boolean>;
|
|
77
|
-
getStats(sessionName: string): {
|
|
78
|
-
total: number;
|
|
79
|
-
};
|
|
80
|
-
/**
|
|
81
|
-
* Warm up the embedding model and verify it loads correctly.
|
|
82
|
-
* Uses a temporary DB so no real session data is affected.
|
|
83
|
-
* Throws if the model is corrupt or fails to produce embeddings.
|
|
84
|
-
*/
|
|
85
|
-
warmup(): Promise<void>;
|
|
86
|
-
closeAll(): void;
|
|
87
|
-
}
|