@desplega.ai/agent-swarm 1.64.0 → 1.65.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/openapi.json +42 -1
- package/package.json +3 -1
- package/src/be/db.ts +18 -290
- package/src/be/embedding.ts +0 -38
- package/src/be/memory/constants.ts +26 -0
- package/src/be/memory/index.ts +22 -0
- package/src/be/memory/providers/openai-embedding.ts +94 -0
- package/src/be/memory/providers/sqlite-store.ts +530 -0
- package/src/be/memory/reranker.ts +59 -0
- package/src/be/memory/types.ts +83 -0
- package/src/be/migrations/036_memory_ttl_staleness.sql +8 -0
- package/src/http/memory.ts +99 -46
- package/src/server.ts +2 -0
- package/src/tests/artifact-sdk.test.ts +2 -1
- package/src/tests/memory-e2e.test.ts +453 -0
- package/src/tests/memory-reranker.test.ts +192 -0
- package/src/tests/memory-store.test.ts +330 -0
- package/src/tests/memory.test.ts +105 -121
- package/src/tests/package-publish.test.ts +47 -0
- package/src/tests/self-improvement.test.ts +18 -19
- package/src/tests/tool-annotations.test.ts +2 -2
- package/src/tools/inject-learning.ts +7 -5
- package/src/tools/memory-delete.ts +89 -0
- package/src/tools/memory-get.ts +2 -2
- package/src/tools/memory-search.ts +13 -7
- package/src/tools/store-progress.ts +12 -11
- package/src/tools/tool-config.ts +1 -0
- package/src/types.ts +3 -0
- package/tsconfig.json +49 -0
|
@@ -4,15 +4,12 @@ import {
|
|
|
4
4
|
closeDb,
|
|
5
5
|
completeTask,
|
|
6
6
|
createAgent,
|
|
7
|
-
createMemory,
|
|
8
7
|
createTaskExtended,
|
|
9
8
|
failTask,
|
|
10
9
|
getAgentById,
|
|
11
10
|
initDb,
|
|
12
|
-
searchMemoriesByVector,
|
|
13
|
-
updateMemoryEmbedding,
|
|
14
11
|
} from "../be/db";
|
|
15
|
-
import {
|
|
12
|
+
import { SqliteMemoryStore } from "../be/memory/providers/sqlite-store";
|
|
16
13
|
import { getBasePrompt } from "../prompts/base-prompt";
|
|
17
14
|
|
|
18
15
|
const TEST_DB_PATH = "./test-self-improvement.sqlite";
|
|
@@ -21,6 +18,7 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
21
18
|
const leadId = "aaaa0000-0000-4000-8000-000000000001";
|
|
22
19
|
const workerId = "bbbb0000-0000-4000-8000-000000000002";
|
|
23
20
|
const otherWorkerId = "cccc0000-0000-4000-8000-000000000003";
|
|
21
|
+
let store: SqliteMemoryStore;
|
|
24
22
|
|
|
25
23
|
beforeAll(async () => {
|
|
26
24
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
@@ -33,6 +31,7 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
33
31
|
|
|
34
32
|
closeDb();
|
|
35
33
|
initDb(TEST_DB_PATH);
|
|
34
|
+
store = new SqliteMemoryStore();
|
|
36
35
|
|
|
37
36
|
createAgent({ id: leadId, name: "Test Lead", isLead: true, status: "idle" });
|
|
38
37
|
createAgent({ id: workerId, name: "Test Worker", isLead: false, status: "idle" });
|
|
@@ -67,7 +66,7 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
67
66
|
|
|
68
67
|
// Simulate what store-progress does: create memory for completed task
|
|
69
68
|
const taskContent = `Task: ${task.task}\n\nOutput:\n${output}`;
|
|
70
|
-
const memory =
|
|
69
|
+
const memory = store.store({
|
|
71
70
|
agentId: workerId,
|
|
72
71
|
content: taskContent,
|
|
73
72
|
name: `Task: ${task.task.slice(0, 80)}`,
|
|
@@ -113,7 +112,7 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
113
112
|
|
|
114
113
|
// Simulate store-progress failed task memory creation
|
|
115
114
|
const taskContent = `Task: ${task.task}\n\nFailure reason:\n${failureReason}\n\nThis task failed. Learn from this to avoid repeating the mistake.`;
|
|
116
|
-
const memory =
|
|
115
|
+
const memory = store.store({
|
|
117
116
|
agentId: workerId,
|
|
118
117
|
content: taskContent,
|
|
119
118
|
name: `Task: ${task.task.slice(0, 80)}`,
|
|
@@ -170,7 +169,7 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
170
169
|
expect(shouldShareWithSwarm).toBe(true);
|
|
171
170
|
|
|
172
171
|
// Verify swarm memory can be created
|
|
173
|
-
const swarmMemory =
|
|
172
|
+
const swarmMemory = store.store({
|
|
174
173
|
agentId: workerId,
|
|
175
174
|
scope: "swarm",
|
|
176
175
|
name: `Shared: ${task.task.slice(0, 80)}`,
|
|
@@ -266,7 +265,7 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
266
265
|
const learning = "Always run lint before committing";
|
|
267
266
|
const content = `[Lead Feedback — ${category}]\n\n${learning}`;
|
|
268
267
|
|
|
269
|
-
const memory =
|
|
268
|
+
const memory = store.store({
|
|
270
269
|
agentId: workerId,
|
|
271
270
|
scope: "swarm",
|
|
272
271
|
name: `Lead feedback: ${category} — ${learning.slice(0, 60)}`,
|
|
@@ -293,7 +292,7 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
293
292
|
test("injected learning is visible to target worker in memory search", () => {
|
|
294
293
|
// Create memory with embedding for searchability
|
|
295
294
|
const content = "[Lead Feedback — mistake-pattern]\n\nNever force-push to main branch";
|
|
296
|
-
const memory =
|
|
295
|
+
const memory = store.store({
|
|
297
296
|
agentId: workerId,
|
|
298
297
|
scope: "agent",
|
|
299
298
|
name: "Lead feedback: mistake-pattern — Never force-push to main branch",
|
|
@@ -302,10 +301,10 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
302
301
|
});
|
|
303
302
|
|
|
304
303
|
const embedding = new Float32Array([0.7, 0.3, 0.0]);
|
|
305
|
-
|
|
304
|
+
store.updateEmbedding(memory.id, embedding, "test-model");
|
|
306
305
|
|
|
307
306
|
// Worker can find it via search
|
|
308
|
-
const results =
|
|
307
|
+
const results = store.search(new Float32Array([0.7, 0.3, 0.0]), workerId, {
|
|
309
308
|
isLead: false,
|
|
310
309
|
scope: "agent",
|
|
311
310
|
});
|
|
@@ -317,7 +316,7 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
317
316
|
|
|
318
317
|
test("injected learning is NOT visible to other workers", () => {
|
|
319
318
|
const content = "[Lead Feedback — preference]\n\nUse bun instead of npm";
|
|
320
|
-
const memory =
|
|
319
|
+
const memory = store.store({
|
|
321
320
|
agentId: workerId,
|
|
322
321
|
scope: "agent",
|
|
323
322
|
name: "Lead feedback: preference — Use bun instead of npm",
|
|
@@ -326,10 +325,10 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
326
325
|
});
|
|
327
326
|
|
|
328
327
|
const embedding = new Float32Array([0.2, 0.8, 0.1]);
|
|
329
|
-
|
|
328
|
+
store.updateEmbedding(memory.id, embedding, "test-model");
|
|
330
329
|
|
|
331
330
|
// Other worker should NOT see it
|
|
332
|
-
const results =
|
|
331
|
+
const results = store.search(new Float32Array([0.2, 0.8, 0.1]), otherWorkerId, {
|
|
333
332
|
isLead: false,
|
|
334
333
|
scope: "agent",
|
|
335
334
|
});
|
|
@@ -355,26 +354,26 @@ describe("Self-Improvement Mechanisms", () => {
|
|
|
355
354
|
describe("memory search agent ID security", () => {
|
|
356
355
|
test("agent can only search their own memories (not others)", () => {
|
|
357
356
|
// Create private memories for worker and other worker
|
|
358
|
-
const workerMemory =
|
|
357
|
+
const workerMemory = store.store({
|
|
359
358
|
agentId: workerId,
|
|
360
359
|
scope: "agent",
|
|
361
360
|
name: "Worker Private Secret",
|
|
362
361
|
content: "My secret API key pattern",
|
|
363
362
|
source: "manual",
|
|
364
363
|
});
|
|
365
|
-
|
|
364
|
+
store.updateEmbedding(workerMemory.id, new Float32Array([0.5, 0.5, 0.0]), "test-model");
|
|
366
365
|
|
|
367
|
-
const otherMemory =
|
|
366
|
+
const otherMemory = store.store({
|
|
368
367
|
agentId: otherWorkerId,
|
|
369
368
|
scope: "agent",
|
|
370
369
|
name: "Other Worker Secret",
|
|
371
370
|
content: "Other agent's private data",
|
|
372
371
|
source: "manual",
|
|
373
372
|
});
|
|
374
|
-
|
|
373
|
+
store.updateEmbedding(otherMemory.id, new Float32Array([0.5, 0.5, 0.0]), "test-model");
|
|
375
374
|
|
|
376
375
|
// Worker searching with their own ID should see their memory but not other's
|
|
377
|
-
const workerResults =
|
|
376
|
+
const workerResults = store.search(new Float32Array([0.5, 0.5, 0.0]), workerId, {
|
|
378
377
|
isLead: false,
|
|
379
378
|
scope: "all",
|
|
380
379
|
});
|
|
@@ -178,8 +178,8 @@ describe("Tool Annotations & Classification", () => {
|
|
|
178
178
|
expect(overlap).toEqual([]);
|
|
179
179
|
});
|
|
180
180
|
|
|
181
|
-
test("CORE_TOOLS contains exactly
|
|
182
|
-
expect(CORE_TOOLS.size).toBe(
|
|
181
|
+
test("CORE_TOOLS contains exactly 14 tools", () => {
|
|
182
|
+
expect(CORE_TOOLS.size).toBe(14);
|
|
183
183
|
});
|
|
184
184
|
|
|
185
185
|
test("ALL_TOOLS equals CORE_TOOLS union DEFERRED_TOOLS", () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import * as z from "zod";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { getAgentById } from "@/be/db";
|
|
4
|
+
import { getEmbeddingProvider, getMemoryStore } from "@/be/memory";
|
|
5
5
|
import { createToolRegistrar } from "@/tools/utils";
|
|
6
6
|
|
|
7
7
|
const LearningCategoryEnum = z.enum([
|
|
@@ -69,7 +69,8 @@ export const registerInjectLearningTool = (server: McpServer) => {
|
|
|
69
69
|
|
|
70
70
|
// Create swarm-scoped memory — lead learnings are organizational knowledge visible to all workers
|
|
71
71
|
const content = `[Lead Feedback — ${category}]\n\n${learning}`;
|
|
72
|
-
const
|
|
72
|
+
const store = getMemoryStore();
|
|
73
|
+
const memory = store.store({
|
|
73
74
|
agentId: targetAgentId,
|
|
74
75
|
scope: "swarm",
|
|
75
76
|
name: `Lead feedback: ${category} — ${learning.slice(0, 60)}`,
|
|
@@ -79,9 +80,10 @@ export const registerInjectLearningTool = (server: McpServer) => {
|
|
|
79
80
|
|
|
80
81
|
// Generate and store embedding (async, best-effort)
|
|
81
82
|
try {
|
|
82
|
-
const
|
|
83
|
+
const provider = getEmbeddingProvider();
|
|
84
|
+
const embedding = await provider.embed(content);
|
|
83
85
|
if (embedding) {
|
|
84
|
-
|
|
86
|
+
store.updateEmbedding(memory.id, embedding, provider.name);
|
|
85
87
|
}
|
|
86
88
|
} catch {
|
|
87
89
|
// Non-blocking — memory was created, embedding is optional
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
import { getAgentById } from "@/be/db";
|
|
4
|
+
import { getMemoryStore } from "@/be/memory";
|
|
5
|
+
import { createToolRegistrar } from "@/tools/utils";
|
|
6
|
+
|
|
7
|
+
export const registerMemoryDeleteTool = (server: McpServer) => {
|
|
8
|
+
createToolRegistrar(server)(
|
|
9
|
+
"memory-delete",
|
|
10
|
+
{
|
|
11
|
+
title: "Delete a memory",
|
|
12
|
+
description:
|
|
13
|
+
"Delete a specific memory by its ID. Agents can delete their own memories; lead agents can also delete swarm-scoped memories.",
|
|
14
|
+
annotations: { destructiveHint: true },
|
|
15
|
+
|
|
16
|
+
inputSchema: z.object({
|
|
17
|
+
memoryId: z.uuid().describe("The ID of the memory to delete."),
|
|
18
|
+
}),
|
|
19
|
+
outputSchema: z.object({
|
|
20
|
+
yourAgentId: z.string().uuid().optional(),
|
|
21
|
+
success: z.boolean(),
|
|
22
|
+
message: z.string(),
|
|
23
|
+
}),
|
|
24
|
+
},
|
|
25
|
+
async ({ memoryId }, requestInfo, _meta) => {
|
|
26
|
+
if (!requestInfo.agentId) {
|
|
27
|
+
return {
|
|
28
|
+
content: [{ type: "text", text: "Agent ID required to delete memories." }],
|
|
29
|
+
structuredContent: {
|
|
30
|
+
yourAgentId: undefined,
|
|
31
|
+
success: false,
|
|
32
|
+
message: "Agent ID required. Are you registered in the swarm?",
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const store = getMemoryStore();
|
|
38
|
+
const memory = store.peek(memoryId);
|
|
39
|
+
|
|
40
|
+
if (!memory) {
|
|
41
|
+
return {
|
|
42
|
+
content: [{ type: "text", text: `Memory "${memoryId}" not found.` }],
|
|
43
|
+
structuredContent: {
|
|
44
|
+
yourAgentId: requestInfo.agentId,
|
|
45
|
+
success: false,
|
|
46
|
+
message: `Memory "${memoryId}" not found.`,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Permission check: own memories or lead can delete swarm-scoped
|
|
52
|
+
const isOwner = memory.agentId === requestInfo.agentId;
|
|
53
|
+
const agent = getAgentById(requestInfo.agentId);
|
|
54
|
+
const isLeadDeletingSwarm = agent?.isLead && memory.scope === "swarm";
|
|
55
|
+
|
|
56
|
+
if (!isOwner && !isLeadDeletingSwarm) {
|
|
57
|
+
return {
|
|
58
|
+
content: [{ type: "text", text: "You don't have permission to delete this memory." }],
|
|
59
|
+
structuredContent: {
|
|
60
|
+
yourAgentId: requestInfo.agentId,
|
|
61
|
+
success: false,
|
|
62
|
+
message:
|
|
63
|
+
"Permission denied. You can only delete your own memories, or swarm memories if you are the lead.",
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const deleted = store.delete(memoryId);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: "text",
|
|
74
|
+
text: deleted
|
|
75
|
+
? `Memory "${memoryId}" deleted.`
|
|
76
|
+
: `Failed to delete memory "${memoryId}".`,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
structuredContent: {
|
|
80
|
+
yourAgentId: requestInfo.agentId,
|
|
81
|
+
success: deleted,
|
|
82
|
+
message: deleted
|
|
83
|
+
? `Memory "${memoryId}" deleted.`
|
|
84
|
+
: `Failed to delete memory "${memoryId}".`,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
};
|
package/src/tools/memory-get.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import * as z from "zod";
|
|
3
|
-
import {
|
|
3
|
+
import { getMemoryStore } from "@/be/memory";
|
|
4
4
|
import { createToolRegistrar } from "@/tools/utils";
|
|
5
5
|
import { AgentMemorySchema } from "@/types";
|
|
6
6
|
|
|
@@ -24,7 +24,7 @@ export const registerMemoryGetTool = (server: McpServer) => {
|
|
|
24
24
|
}),
|
|
25
25
|
},
|
|
26
26
|
async ({ memoryId }, requestInfo, _meta) => {
|
|
27
|
-
const memory =
|
|
27
|
+
const memory = getMemoryStore().get(memoryId);
|
|
28
28
|
|
|
29
29
|
if (!memory) {
|
|
30
30
|
return {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import * as z from "zod";
|
|
3
|
-
import { getAgentById
|
|
4
|
-
import {
|
|
3
|
+
import { getAgentById } from "@/be/db";
|
|
4
|
+
import { getEmbeddingProvider, getMemoryStore } from "@/be/memory";
|
|
5
|
+
import { CANDIDATE_SET_MULTIPLIER } from "@/be/memory/constants";
|
|
6
|
+
import { rerank } from "@/be/memory/reranker";
|
|
5
7
|
import { createToolRegistrar } from "@/tools/utils";
|
|
6
8
|
import { AgentMemoryScopeSchema, AgentMemorySourceSchema } from "@/types";
|
|
7
9
|
|
|
@@ -60,17 +62,21 @@ export const registerMemorySearchTool = (server: McpServer) => {
|
|
|
60
62
|
const isLead = agent?.isLead ?? false;
|
|
61
63
|
|
|
62
64
|
// Try vector search first
|
|
63
|
-
const
|
|
65
|
+
const provider = getEmbeddingProvider();
|
|
66
|
+
const store = getMemoryStore();
|
|
67
|
+
const queryEmbedding = await provider.embed(query);
|
|
64
68
|
|
|
65
69
|
if (queryEmbedding) {
|
|
66
|
-
const
|
|
70
|
+
const candidateLimit = limit * CANDIDATE_SET_MULTIPLIER;
|
|
71
|
+
const candidates = store.search(queryEmbedding, requestInfo.agentId, {
|
|
67
72
|
scope: scope as "agent" | "swarm" | "all",
|
|
68
|
-
limit,
|
|
73
|
+
limit: candidateLimit,
|
|
69
74
|
source,
|
|
70
75
|
isLead,
|
|
71
76
|
});
|
|
77
|
+
const ranked = rerank(candidates, { limit });
|
|
72
78
|
|
|
73
|
-
const mapped =
|
|
79
|
+
const mapped = ranked.map((r) => ({
|
|
74
80
|
id: r.id,
|
|
75
81
|
name: r.name,
|
|
76
82
|
summary: r.summary,
|
|
@@ -97,7 +103,7 @@ export const registerMemorySearchTool = (server: McpServer) => {
|
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
// Fallback: list recent memories (no OPENAI_API_KEY)
|
|
100
|
-
const recent =
|
|
106
|
+
const recent = store.list(requestInfo.agentId, {
|
|
101
107
|
scope: scope as "agent" | "swarm" | "all",
|
|
102
108
|
limit,
|
|
103
109
|
isLead,
|
|
@@ -3,7 +3,6 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
3
3
|
import * as z from "zod";
|
|
4
4
|
import {
|
|
5
5
|
completeTask,
|
|
6
|
-
createMemory,
|
|
7
6
|
createSessionCost,
|
|
8
7
|
createTaskExtended,
|
|
9
8
|
failTask,
|
|
@@ -12,10 +11,9 @@ import {
|
|
|
12
11
|
getLeadAgent,
|
|
13
12
|
getTaskById,
|
|
14
13
|
updateAgentStatusFromCapacity,
|
|
15
|
-
updateMemoryEmbedding,
|
|
16
14
|
updateTaskProgress,
|
|
17
15
|
} from "@/be/db";
|
|
18
|
-
import {
|
|
16
|
+
import { getEmbeddingProvider, getMemoryStore } from "@/be/memory";
|
|
19
17
|
import { resolveTemplate } from "@/prompts/resolver";
|
|
20
18
|
import { createToolRegistrar } from "@/tools/utils";
|
|
21
19
|
import { AgentTaskSchema } from "@/types";
|
|
@@ -258,17 +256,20 @@ export const registerStoreProgressTool = (server: McpServer) => {
|
|
|
258
256
|
// Skip indexing if there's truly no content
|
|
259
257
|
if (taskContent.length < 30) return;
|
|
260
258
|
|
|
261
|
-
const
|
|
262
|
-
|
|
259
|
+
const store = getMemoryStore();
|
|
260
|
+
const provider = getEmbeddingProvider();
|
|
261
|
+
|
|
262
|
+
const memory = store.store({
|
|
263
|
+
agentId: requestInfo.agentId ?? null,
|
|
263
264
|
content: taskContent,
|
|
264
265
|
name: `Task: ${result.task!.task.slice(0, 80)}`,
|
|
265
266
|
scope: "agent",
|
|
266
267
|
source: "task_completion",
|
|
267
268
|
sourceTaskId: taskId,
|
|
268
269
|
});
|
|
269
|
-
const embedding = await
|
|
270
|
+
const embedding = await provider.embed(taskContent);
|
|
270
271
|
if (embedding) {
|
|
271
|
-
|
|
272
|
+
store.updateEmbedding(memory.id, embedding, provider.name);
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
// Auto-promote high-value completions to swarm memory (P3)
|
|
@@ -280,17 +281,17 @@ export const registerStoreProgressTool = (server: McpServer) => {
|
|
|
280
281
|
|
|
281
282
|
if (shouldShareWithSwarm) {
|
|
282
283
|
try {
|
|
283
|
-
const swarmMemory =
|
|
284
|
-
agentId: requestInfo.agentId,
|
|
284
|
+
const swarmMemory = store.store({
|
|
285
|
+
agentId: requestInfo.agentId ?? null,
|
|
285
286
|
scope: "swarm",
|
|
286
287
|
name: `Shared: ${result.task!.task.slice(0, 80)}`,
|
|
287
288
|
content: `Task completed by agent ${requestInfo.agentId}:\n\n${taskContent}`,
|
|
288
289
|
source: "task_completion",
|
|
289
290
|
sourceTaskId: taskId,
|
|
290
291
|
});
|
|
291
|
-
const swarmEmbedding = await
|
|
292
|
+
const swarmEmbedding = await provider.embed(taskContent);
|
|
292
293
|
if (swarmEmbedding) {
|
|
293
|
-
|
|
294
|
+
store.updateEmbedding(swarmMemory.id, swarmEmbedding, provider.name);
|
|
294
295
|
}
|
|
295
296
|
} catch {
|
|
296
297
|
// Non-blocking — swarm memory promotion failure is not critical
|
package/src/tools/tool-config.ts
CHANGED
|
@@ -30,6 +30,7 @@ export const CORE_TOOLS = new Set([
|
|
|
30
30
|
// Memory (used at session start)
|
|
31
31
|
"memory-search", // recall relevant context
|
|
32
32
|
"memory-get", // retrieve full memory content
|
|
33
|
+
"memory-delete", // delete own memories
|
|
33
34
|
|
|
34
35
|
// Swarm awareness
|
|
35
36
|
"get-swarm", // check who's online
|
package/src/types.ts
CHANGED
|
@@ -592,6 +592,9 @@ export const AgentMemorySchema = z.object({
|
|
|
592
592
|
tags: z.array(z.string()),
|
|
593
593
|
createdAt: z.string(),
|
|
594
594
|
accessedAt: z.string(),
|
|
595
|
+
expiresAt: z.string().nullable().optional(),
|
|
596
|
+
accessCount: z.number().int().min(0).default(0).optional(),
|
|
597
|
+
embeddingModel: z.string().nullable().optional(),
|
|
595
598
|
});
|
|
596
599
|
|
|
597
600
|
export type AgentMemoryScope = z.infer<typeof AgentMemoryScopeSchema>;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// Environment setup & latest features
|
|
4
|
+
"lib": ["ESNext"],
|
|
5
|
+
"types": ["bun"],
|
|
6
|
+
"target": "ESNext",
|
|
7
|
+
"module": "Preserve",
|
|
8
|
+
"moduleDetection": "force",
|
|
9
|
+
"jsx": "react-jsx",
|
|
10
|
+
"allowJs": true,
|
|
11
|
+
|
|
12
|
+
// Bundler mode
|
|
13
|
+
"moduleResolution": "bundler",
|
|
14
|
+
"allowImportingTsExtensions": true,
|
|
15
|
+
|
|
16
|
+
// Path aliases
|
|
17
|
+
"baseUrl": ".",
|
|
18
|
+
"paths": {
|
|
19
|
+
"@/*": ["src/*"]
|
|
20
|
+
},
|
|
21
|
+
"verbatimModuleSyntax": true,
|
|
22
|
+
"noEmit": true,
|
|
23
|
+
|
|
24
|
+
// Best practices
|
|
25
|
+
"strict": true,
|
|
26
|
+
"skipLibCheck": true,
|
|
27
|
+
"noFallthroughCasesInSwitch": true,
|
|
28
|
+
"noUncheckedIndexedAccess": true,
|
|
29
|
+
"noImplicitOverride": true,
|
|
30
|
+
|
|
31
|
+
// Some stricter flags (disabled by default)
|
|
32
|
+
"noUnusedLocals": false,
|
|
33
|
+
"noUnusedParameters": false,
|
|
34
|
+
"noPropertyAccessFromIndexSignature": false
|
|
35
|
+
},
|
|
36
|
+
"exclude": [
|
|
37
|
+
"ui",
|
|
38
|
+
"new-ui",
|
|
39
|
+
"templates-ui",
|
|
40
|
+
"landing",
|
|
41
|
+
"node_modules",
|
|
42
|
+
"scripts",
|
|
43
|
+
"src/tests",
|
|
44
|
+
"work",
|
|
45
|
+
"logs",
|
|
46
|
+
"plugin",
|
|
47
|
+
"docs-site"
|
|
48
|
+
]
|
|
49
|
+
}
|