@desplega.ai/agent-swarm 1.129.0 → 1.131.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 +2 -2
- package/dist/{actions-kfv2dawe.js → actions-w53mbns9.js} +11 -11
- package/dist/{anthropic-messages-3xgme8my.js → anthropic-messages-rjmd2e7n.js} +5 -5
- package/dist/{app-q8vjk6e8.js → app-m9gwqsqv.js} +8 -8
- package/dist/{artifact-hg4t1nx7.js → artifact-jysj3wrg.js} +2 -2
- package/dist/{assistant-g037r345.js → assistant-bp65m6f3.js} +13 -13
- package/dist/{azure-openai-responses-xa4sh9f6.js → azure-openai-responses-c0yjmbfd.js} +8 -5
- package/dist/{boot-reembed-18pzsrxa.js → boot-reembed-62p0at2k.js} +6 -6
- package/dist/{boot-reembed-wpks2cj8.js → boot-reembed-xmfp6wdh.js} +7 -7
- package/dist/{boot-scrub-logs-n7szd57r.js → boot-scrub-logs-rr8q2dms.js} +5 -5
- package/dist/{claude-adapter-qz4r0ajt.js → claude-adapter-2y47mrkd.js} +9 -9
- package/dist/{cli-mhjnbgb6.js → cli-0rcyq6d9.js} +450 -186
- package/dist/{cli-ttkmehy0.js → cli-2q72qz2s.js} +274 -25
- package/dist/{cli-gztgc3hz.js → cli-2wadx7p2.js} +2 -2
- package/dist/cli-3fj60etf.js +153 -0
- package/dist/{cli-7ecgm5v0.js → cli-3kf51j15.js} +1 -1
- package/dist/{cli-vgexpfsr.js → cli-57khth04.js} +6 -3
- package/dist/{cli-2mbe7vk0.js → cli-5dsbcjjw.js} +1 -1
- package/dist/{cli-etr62zy6.js → cli-5kx36evn.js} +2 -2
- package/dist/{cli-v2tr6amf.js → cli-5n6e5yfn.js} +30 -8
- package/dist/{cli-hx02s9zq.js → cli-5v4rw6yd.js} +2 -2
- package/dist/{cli-v37yr6mf.js → cli-5ze9rv97.js} +4 -4
- package/dist/{cli-ch7t5v7n.js → cli-6map995v.js} +9 -4
- package/dist/{cli-h0457a67.js → cli-70xqj0z3.js} +3 -3
- package/dist/{cli-kk4f9r17.js → cli-72q8m8gk.js} +8 -6
- package/dist/{cli-7padk69a.js → cli-78xwvkhj.js} +2 -2
- package/dist/{cli-dxtxacy7.js → cli-9dr5qzc0.js} +45 -8
- package/dist/{cli-17zxdgsq.js → cli-a40rnf71.js} +6 -6
- package/dist/{cli-t53vnnxz.js → cli-a4jzdpa3.js} +2514 -1055
- package/dist/{cli-w10fkrf1.js → cli-akdvwc9v.js} +354 -115
- package/dist/{cli-1qkk5er0.js → cli-bmze986d.js} +1 -1
- package/dist/{cli-ga12dc1d.js → cli-bqw0mt1n.js} +3 -3
- package/dist/{cli-0sf92efp.js → cli-cdeg08wx.js} +1 -1
- package/dist/{cli-a8ynhkyj.js → cli-cvgjwnh1.js} +17 -15
- package/dist/{cli-9fxg3v5m.js → cli-d2tfkcga.js} +4 -4
- package/dist/{cli-nhcd7x43.js → cli-d3x3x1c9.js} +2 -2
- package/dist/{cli-6nh2qxvh.js → cli-darcwax3.js} +1 -1
- package/dist/{cli-yjbgmysx.js → cli-e7ckcg4v.js} +12 -12
- package/dist/{cli-4n2gcjpd.js → cli-efxfnq6q.js} +4 -3
- package/dist/{cli-z9xqqhfk.js → cli-er3a4bb0.js} +1 -1
- package/dist/{cli-xg2eezyv.js → cli-f1am9szv.js} +1 -1
- package/dist/{cli-xy4cwsm9.js → cli-fywms69x.js} +1 -1
- package/dist/{cli-33jj76y8.js → cli-g6b8x1h8.js} +1 -1
- package/dist/{cli-epsvdckx.js → cli-gm9cbhbq.js} +20 -10
- package/dist/{cli-rkndnn90.js → cli-k9qkf1hw.js} +6 -4
- package/dist/{cli-zejvt395.js → cli-kh3ba2zf.js} +1 -1
- package/dist/{cli-gb25p1h2.js → cli-nm5gtp1x.js} +2 -2
- package/dist/{cli-akxnpx17.js → cli-pm6xbh84.js} +1829 -1629
- package/dist/{cli-2k0ztbfp.js → cli-psh3c4va.js} +1 -1
- package/dist/{cli-39vgrsep.js → cli-qv61hp37.js} +2 -2
- package/dist/{cli-hv2fndhm.js → cli-r6kqqbj0.js} +6 -4
- package/dist/{cli-1y1cm570.js → cli-rzbpmxdr.js} +1 -1
- package/dist/{cli-mmrk00vp.js → cli-t1xze5qh.js} +1 -1
- package/dist/{cli-g252a9ky.js → cli-t55yw3a1.js} +2 -2
- package/dist/{cli-7bz8dzqa.js → cli-t76vw5db.js} +1184 -1522
- package/dist/{cli-4n4mdv21.js → cli-xpxde7rm.js} +7 -3
- package/dist/{cli-fpaa5k2q.js → cli-yw8vghx2.js} +54 -18
- package/dist/cli-zsspvvm2.js +490 -0
- package/dist/cli.js +27 -25
- package/dist/{codex-adapter-7v6t7ff6.js → codex-adapter-d24q75wk.js} +7 -7
- package/dist/{codex-hook-amndawyb.js → codex-hook-hq54t9ft.js} +2 -2
- package/dist/{codex-session-runner-e7j4khe2.js → codex-session-runner-g50vcsex.js} +7 -7
- package/dist/{commands-ex0k5tbf.js → commands-c3nrc5hg.js} +5 -5
- package/dist/{db-df7jatfc.js → db-nt7fg3tw.js} +5 -5
- package/dist/{google-generative-ai-y42hnw9p.js → google-generative-ai-hysrd8qx.js} +7 -5
- package/dist/{google-vertex-4sg66gb6.js → google-vertex-p5arrga0.js} +7 -5
- package/dist/{handlers-1j2cfqt2.js → handlers-fkr6swat.js} +13 -13
- package/dist/{hook-nx9a0mj3.js → hook-77wpvnjc.js} +7 -7
- package/dist/{hook-w6yaf6sy.js → hook-g019yehy.js} +8 -8
- package/dist/{http-4tz5h8wg.js → http-jewj0syk.js} +2993 -716
- package/dist/{index-0bpkzb09.js → index-070v4eyb.js} +3 -3
- package/dist/{index-0s67qv7h.js → index-6gm5he8h.js} +11 -11
- package/dist/{index-35gtv6gj.js → index-7n2xpbd4.js} +310 -40
- package/dist/{index-ker3gccb.js → index-9znhar3x.js} +4 -4
- package/dist/{index-5n2c8yay.js → index-hase6zbe.js} +2 -2
- package/dist/{index-kcf3tm9h.js → index-hfvggd0z.js} +12 -12
- package/dist/{index-7c0jqna0.js → index-hp1kdbjj.js} +13 -13
- package/dist/{keepalive-3j4a9168.js → keepalive-j0fjvqfd.js} +7 -7
- package/dist/{lead-6kpevymb.js → lead-1n8x30xe.js} +33 -33
- package/dist/{maintenance-m1k82ean.js → maintenance-gvev11sa.js} +7 -7
- package/dist/{mistral-conversations-bjkdfb6z.js → mistral-conversations-81fwav0j.js} +6 -6
- package/dist/{oauth-refresh-sweep-881k8e4q.js → oauth-refresh-sweep-s9ecsvh0.js} +6 -6
- package/dist/{onboard-c0ykffjn.js → onboard-pvm5b38w.js} +2 -2
- package/dist/{openai-codex-responses-xetseqvt.js → openai-codex-responses-5g27pd6f.js} +43 -23
- package/dist/{openai-completions-5r2g5axa.js → openai-completions-3vkmfz2a.js} +55 -11
- package/dist/{openai-responses-ce67hd23.js → openai-responses-dg4t7j7a.js} +8 -5
- package/dist/{openrouter-images-pzfp22jb.js → openrouter-images-g3gm8931.js} +1 -1
- package/dist/{otel-impl-sqagjerv.js → otel-impl-p6jvgd9c.js} +6 -4
- package/dist/{otel-3mp81ppd.js → otel-nqa12wf3.js} +2 -2
- package/dist/{pi-mono-adapter-k584k16g.js → pi-mono-adapter-t091s27g.js} +17117 -7517
- package/dist/{pricing-refresh-y82whbf9.js → pricing-refresh-k49rcyed.js} +7 -7
- package/dist/{rbac-roles-nvkqmzyd.js → rbac-roles-30pspvy7.js} +7 -7
- package/dist/{rbac-roles-4ht8gegc.js → rbac-roles-cr80g96t.js} +6 -6
- package/dist/{render-v2-wvqdgvvp.js → render-v2-xm457ng1.js} +8 -8
- package/dist/{seed-pricing-fy3rxhde.js → seed-pricing-yhpv35fr.js} +6 -6
- package/dist/{setup-ak5cnc6f.js → setup-nytnmwwr.js} +2 -2
- package/dist/{worker-d8769q8a.js → worker-msytr2cw.js} +33 -33
- package/openapi.json +34039 -11036
- package/package.json +8 -6
- package/src/apps/definition.ts +368 -26
- package/src/apps/row-store.ts +66 -10
- package/src/apps/schema-migrate.ts +95 -1
- package/src/apps/store.ts +13 -4
- package/src/apps/sync-run-as.ts +18 -0
- package/src/apps/sync.ts +934 -0
- package/src/apps/version.ts +16 -2
- package/src/assets/key.ts +8 -1
- package/src/be/asset-key-audit.ts +3 -1
- package/src/be/db-queries/mcp-oauth.ts +297 -24
- package/src/be/db.ts +42 -1
- package/src/be/migrations/129_asset_keys_apps_scripts.sql +161 -0
- package/src/be/scripts/db.ts +5 -2
- package/src/be/scripts/typecheck.ts +1 -0
- package/src/be/seed-scripts/catalog/app-sync-run.ts +32 -0
- package/src/be/seed-scripts/catalog/github-issues-pull.ts +102 -0
- package/src/be/seed-scripts/index.ts +18 -0
- package/src/be/seed-skills/index.ts +7 -0
- package/src/http/active-sessions.ts +26 -18
- package/src/http/agents.ts +94 -27
- package/src/http/api-keys.ts +91 -17
- package/src/http/approval-requests.ts +87 -10
- package/src/http/apps.ts +361 -53
- package/src/http/assets.ts +165 -31
- package/src/http/budgets.ts +7 -5
- package/src/http/codex-oauth-keep-warm.ts +21 -3
- package/src/http/config.ts +46 -16
- package/src/http/context.ts +33 -6
- package/src/http/ecosystem.ts +20 -6
- package/src/http/events.ts +24 -9
- package/src/http/favorites.ts +20 -6
- package/src/http/fs.ts +60 -17
- package/src/http/heartbeat.ts +18 -4
- package/src/http/inbox-state.ts +12 -6
- package/src/http/integrations.ts +25 -5
- package/src/http/kv.ts +36 -15
- package/src/http/mcp-bridge.ts +5 -1
- package/src/http/mcp-oauth.ts +332 -17
- package/src/http/mcp-servers.ts +56 -18
- package/src/http/memory.ts +282 -29
- package/src/http/metrics.ts +80 -17
- package/src/http/oauth-callback.ts +10 -4
- package/src/http/oauth-generic.ts +5 -1
- package/src/http/oauth-locks.ts +6 -3
- package/src/http/openapi.ts +57 -9
- package/src/http/page-proxy.ts +25 -5
- package/src/http/pages-public.ts +37 -20
- package/src/http/pages.ts +93 -28
- package/src/http/poll.ts +89 -5
- package/src/http/pricing.ts +9 -6
- package/src/http/prompt-templates.ts +85 -21
- package/src/http/route-def.ts +67 -4
- package/src/http/schedules.ts +63 -14
- package/src/http/script-connection-proxy.ts +30 -4
- package/src/http/script-connections.ts +393 -43
- package/src/http/script-runs.ts +73 -19
- package/src/http/scripts.ts +257 -39
- package/src/http/session-data.ts +87 -14
- package/src/http/sessions.ts +80 -5
- package/src/http/skills.ts +115 -35
- package/src/http/stats.ts +94 -13
- package/src/http/task-templates.ts +6 -4
- package/src/http/tasks.ts +230 -61
- package/src/http/trackers/jira.ts +90 -30
- package/src/http/trackers/linear.ts +46 -12
- package/src/http/users.ts +162 -25
- package/src/http/utils.ts +12 -2
- package/src/http/webhooks.ts +30 -16
- package/src/http/workflow-events.ts +18 -5
- package/src/http/workflows.ts +128 -39
- package/src/http/x.ts +37 -6
- package/src/oauth/ensure-mcp-token.ts +16 -1
- package/src/oauth/mcp-wrapper.ts +281 -26
- package/src/providers/pi-mono-adapter.ts +1 -1
- package/src/scripts-runtime/credential-broker/README.md +1 -1
- package/src/scripts-runtime/credential-broker/fetch-patch.ts +12 -2
- package/src/scripts-runtime/sdk-allowlist.ts +1 -0
- package/src/scripts-runtime/stdlib/fetch.ts +6 -0
- package/src/scripts-runtime/types/stdlib.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
- package/src/server.ts +2 -0
- package/src/tests/apps-rbac.test.ts +110 -0
- package/src/tests/apps-spike2.test.ts +4 -1
- package/src/tests/apps-sync-engine.test.ts +2540 -0
- package/src/tests/apps-sync.test.ts +1627 -0
- package/src/tests/asset-key-api.test.ts +48 -2
- package/src/tests/asset-key-invariants.test.ts +92 -0
- package/src/tests/asset-key-migration.test.ts +174 -8
- package/src/tests/asset-key-normalization.test.ts +2 -0
- package/src/tests/credential-broker.test.ts +27 -2
- package/src/tests/mcp-oauth-dcr-reuse.test.ts +743 -0
- package/src/tests/mcp-oauth-ensure-token.test.ts +45 -0
- package/src/tests/mcp-oauth-manual-client.test.ts +135 -2
- package/src/tests/mcp-oauth-queries.test.ts +153 -0
- package/src/tests/mcp-oauth-wrapper.test.ts +432 -0
- package/src/tests/memory-http-recall-gating.test.ts +2 -0
- package/src/tests/openapi-response-contract.test.ts +138 -0
- package/src/tests/rbac-admission-e2e.test.ts +68 -0
- package/src/tests/script-connections.test.ts +3 -0
- package/src/tests/scripts-runtime-fetch.test.ts +121 -0
- package/src/tests/scripts-runtime-secret-egress.test.ts +4 -2
- package/src/tests/seed-scripts.test.ts +2 -2
- package/src/tests/swarm-tool-result-gate.test.ts +32 -0
- package/src/tests/task-working-dir.test.ts +8 -4
- package/src/tests/whoami-route.test.ts +127 -0
- package/src/tests/workflow-engine-v2.test.ts +80 -7
- package/src/tests/workflow-swarm-script.test.ts +104 -0
- package/src/tools/app-get.ts +10 -2
- package/src/tools/app-rollback.ts +1 -0
- package/src/tools/app-sync.ts +112 -0
- package/src/tools/script-common.ts +20 -0
- package/src/tools/tool-config.ts +2 -1
- package/src/tools/utils.ts +11 -0
- package/src/tools/workflows/create-workflow.ts +4 -1
- package/src/types.ts +1394 -1206
- package/src/utils/template.ts +8 -1
- package/src/utils/zod-openapi.ts +11 -0
- package/src/workflows/engine.ts +27 -4
- package/src/workflows/executors/swarm-script.ts +28 -0
- package/src/workflows/retry-poller.ts +19 -2
- package/templates/skills/apps/content.md +94 -5
- package/templates/skills/asset-namespaces/content.md +2 -2
- package/templates/skills/scheduled-task-resilience/SKILL.md +102 -0
- package/templates/skills/scheduled-task-resilience/config.json +14 -0
- package/templates/skills/scheduled-task-resilience/content.md +97 -0
- package/dist/cli-7wmybrt5.js +0 -115
- package/dist/cli-d91pvmq1.js +0 -14
package/src/http/memory.ts
CHANGED
|
@@ -20,12 +20,27 @@ import { rerank } from "../be/memory/reranker";
|
|
|
20
20
|
import { getRetrievalsForAgent, hasRetrievalForTask } from "../be/memory/retrieval-store";
|
|
21
21
|
import { getUsefulnessStats } from "../be/memory/usefulness-stats";
|
|
22
22
|
import { shouldPersistAutomaticTaskMemory } from "../memory/automatic-task-gate";
|
|
23
|
-
import { AgentMemoryScopeSchema, AgentMemorySourceSchema } from "../types";
|
|
23
|
+
import { AgentMemorySchema, AgentMemoryScopeSchema, AgentMemorySourceSchema } from "../types";
|
|
24
24
|
import { route } from "./route-def";
|
|
25
|
-
import {
|
|
25
|
+
import { jsonError, parseQueryParams } from "./utils";
|
|
26
|
+
|
|
27
|
+
// ─── Response Schemas ────────────────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
// Mirrors `MemoryRetrievalSource` (src/be/memory/types.ts) — the arm that
|
|
30
|
+
// surfaced a search candidate. Shared by the search and list result shapes.
|
|
31
|
+
const MemoryRetrievalSourceSchema = z.enum(["vec", "fts", "hybrid", "fallback", "graph"]);
|
|
26
32
|
|
|
27
33
|
// ─── Route Definitions ───────────────────────────────────────────────────────
|
|
28
34
|
|
|
35
|
+
// Shared shape across the three 202 sends: (1) automatic-task-memory skip,
|
|
36
|
+
// (2) single-chunk re-index of an existing sourcePath, (3) fresh batch queue.
|
|
37
|
+
const IndexMemoryResponseSchema = z.object({
|
|
38
|
+
queued: z.boolean(),
|
|
39
|
+
memoryIds: z.array(z.string()),
|
|
40
|
+
skipped: z.string().optional(),
|
|
41
|
+
edited: z.boolean().optional(),
|
|
42
|
+
});
|
|
43
|
+
|
|
29
44
|
const indexMemory = route({
|
|
30
45
|
method: "post",
|
|
31
46
|
path: "/api/memory/index",
|
|
@@ -45,11 +60,24 @@ const indexMemory = route({
|
|
|
45
60
|
contextKey: z.string().optional(),
|
|
46
61
|
}),
|
|
47
62
|
responses: {
|
|
48
|
-
202: { description: "Content queued for embedding" },
|
|
63
|
+
202: { description: "Content queued for embedding", schema: IndexMemoryResponseSchema },
|
|
49
64
|
400: { description: "Validation error" },
|
|
50
65
|
},
|
|
51
66
|
});
|
|
52
67
|
|
|
68
|
+
const MemorySearchResultItemSchema = z.object({
|
|
69
|
+
id: z.string(),
|
|
70
|
+
name: z.string(),
|
|
71
|
+
content: z.string(),
|
|
72
|
+
similarity: z.number(),
|
|
73
|
+
rawSimilarity: z.number().optional(),
|
|
74
|
+
compositeScore: z.number().optional(),
|
|
75
|
+
retrievalSource: MemoryRetrievalSourceSchema.optional(),
|
|
76
|
+
source: AgentMemorySourceSchema,
|
|
77
|
+
scope: AgentMemoryScopeSchema,
|
|
78
|
+
tags: z.array(z.string()),
|
|
79
|
+
});
|
|
80
|
+
|
|
53
81
|
const searchMemory = route({
|
|
54
82
|
method: "post",
|
|
55
83
|
path: "/api/memory/search",
|
|
@@ -71,11 +99,24 @@ const searchMemory = route({
|
|
|
71
99
|
source: z.enum(["manual", "file_index", "session_summary", "task_completion"]).optional(),
|
|
72
100
|
}),
|
|
73
101
|
responses: {
|
|
74
|
-
200: {
|
|
102
|
+
200: {
|
|
103
|
+
description: "Search results",
|
|
104
|
+
schema: z.object({ results: z.array(MemorySearchResultItemSchema) }),
|
|
105
|
+
},
|
|
75
106
|
400: { description: "Missing query or agent ID" },
|
|
76
107
|
},
|
|
77
108
|
});
|
|
78
109
|
|
|
110
|
+
// Mirrors `MemoryEditResult` (src/be/memory/types.ts) — `store.edit()`'s
|
|
111
|
+
// return value, sent verbatim.
|
|
112
|
+
const MemoryEditResultSchema = z.object({
|
|
113
|
+
memory: AgentMemorySchema,
|
|
114
|
+
changed: z.boolean(),
|
|
115
|
+
previousVersion: z.number(),
|
|
116
|
+
version: z.number(),
|
|
117
|
+
contentHash: z.string(),
|
|
118
|
+
});
|
|
119
|
+
|
|
79
120
|
const editMemory = route({
|
|
80
121
|
method: "post",
|
|
81
122
|
path: "/api/memory/edit",
|
|
@@ -96,7 +137,7 @@ const editMemory = route({
|
|
|
96
137
|
expectedVersion: z.number().int().min(1).optional(),
|
|
97
138
|
}),
|
|
98
139
|
responses: {
|
|
99
|
-
200: { description: "Memory edited" },
|
|
140
|
+
200: { description: "Memory edited", schema: MemoryEditResultSchema },
|
|
100
141
|
400: { description: "Validation error" },
|
|
101
142
|
404: { description: "Memory not found" },
|
|
102
143
|
409: { description: "Version conflict" },
|
|
@@ -119,10 +160,39 @@ const reEmbedMemory = route({
|
|
|
119
160
|
batchSize: z.number().int().min(1).max(100).default(20).describe("Memories per batch"),
|
|
120
161
|
}),
|
|
121
162
|
responses: {
|
|
122
|
-
202: {
|
|
163
|
+
202: {
|
|
164
|
+
description: "Re-embedding started",
|
|
165
|
+
schema: z.object({ started: z.boolean(), totalMemories: z.number() }),
|
|
166
|
+
},
|
|
123
167
|
},
|
|
124
168
|
});
|
|
125
169
|
|
|
170
|
+
// Shared result item across both listMemory branches: the semantic-search
|
|
171
|
+
// branch (query set) populates similarity/rawSimilarity/compositeScore/
|
|
172
|
+
// retrievalSource; the plain-list branch (query empty) omits them.
|
|
173
|
+
const MemoryListResultItemSchema = z.object({
|
|
174
|
+
id: z.string(),
|
|
175
|
+
name: z.string(),
|
|
176
|
+
content: z.string(),
|
|
177
|
+
agentId: z.string().nullable(),
|
|
178
|
+
scope: AgentMemoryScopeSchema,
|
|
179
|
+
source: AgentMemorySourceSchema,
|
|
180
|
+
similarity: z.number().optional(),
|
|
181
|
+
rawSimilarity: z.number().optional(),
|
|
182
|
+
compositeScore: z.number().optional(),
|
|
183
|
+
retrievalSource: MemoryRetrievalSourceSchema.optional(),
|
|
184
|
+
createdAt: z.string(),
|
|
185
|
+
accessedAt: z.string(),
|
|
186
|
+
accessCount: z.number(),
|
|
187
|
+
expiresAt: z.string().nullable(),
|
|
188
|
+
embeddingModel: z.string().nullable(),
|
|
189
|
+
sourceTaskId: z.string().nullable(),
|
|
190
|
+
sourcePath: z.string().nullable(),
|
|
191
|
+
chunkIndex: z.number(),
|
|
192
|
+
totalChunks: z.number(),
|
|
193
|
+
tags: z.array(z.string()),
|
|
194
|
+
});
|
|
195
|
+
|
|
126
196
|
const listMemory = route({
|
|
127
197
|
method: "post",
|
|
128
198
|
path: "/api/memory/list",
|
|
@@ -150,11 +220,56 @@ const listMemory = route({
|
|
|
150
220
|
offset: z.number().int().min(0).default(0),
|
|
151
221
|
}),
|
|
152
222
|
responses: {
|
|
153
|
-
200: {
|
|
223
|
+
200: {
|
|
224
|
+
description: "Memory list / search results",
|
|
225
|
+
schema: z.object({
|
|
226
|
+
results: z.array(MemoryListResultItemSchema),
|
|
227
|
+
total: z.number(),
|
|
228
|
+
limit: z.number(),
|
|
229
|
+
offset: z.number(),
|
|
230
|
+
mode: z.enum(["semantic", "list"]),
|
|
231
|
+
}),
|
|
232
|
+
},
|
|
154
233
|
400: { description: "Validation error" },
|
|
155
234
|
},
|
|
156
235
|
});
|
|
157
236
|
|
|
237
|
+
// Mirrors `MemoryVecPopulateStats` (src/be/memory/types.ts).
|
|
238
|
+
const MemoryVecPopulateStatsSchema = z.object({
|
|
239
|
+
attempted: z.number(),
|
|
240
|
+
inserted: z.number(),
|
|
241
|
+
skippedInvalidDimensions: z.number(),
|
|
242
|
+
failed: z.number(),
|
|
243
|
+
beforeCount: z.number(),
|
|
244
|
+
afterCount: z.number(),
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
// Mirrors `MemoryHealth` (src/be/memory/types.ts) — `store.getHealth()`'s
|
|
248
|
+
// return value, sent verbatim.
|
|
249
|
+
const MemoryHealthSchema = z.object({
|
|
250
|
+
sqliteVec: z.object({
|
|
251
|
+
extensionLoaded: z.boolean(),
|
|
252
|
+
tableExists: z.boolean(),
|
|
253
|
+
initialized: z.boolean(),
|
|
254
|
+
vectorDimensions: z.number(),
|
|
255
|
+
distanceMetric: z.literal("cosine"),
|
|
256
|
+
schema: z.string().nullable(),
|
|
257
|
+
lastPopulate: MemoryVecPopulateStatsSchema.nullable(),
|
|
258
|
+
}),
|
|
259
|
+
counts: z.object({
|
|
260
|
+
total: z.number(),
|
|
261
|
+
withEmbedding: z.number(),
|
|
262
|
+
validEmbedding: z.number(),
|
|
263
|
+
invalidEmbedding: z.number(),
|
|
264
|
+
searchable: z.number(),
|
|
265
|
+
memoryVec: z.number(),
|
|
266
|
+
missingFromVec: z.number(),
|
|
267
|
+
extraInVec: z.number(),
|
|
268
|
+
}),
|
|
269
|
+
retrievalMode: z.enum(["vec", "fallback"]),
|
|
270
|
+
reasons: z.array(z.string()),
|
|
271
|
+
});
|
|
272
|
+
|
|
158
273
|
const memoryHealth = route({
|
|
159
274
|
method: "get",
|
|
160
275
|
path: "/api/memory/health",
|
|
@@ -163,13 +278,57 @@ const memoryHealth = route({
|
|
|
163
278
|
tags: ["Memory"],
|
|
164
279
|
auth: { apiKey: true },
|
|
165
280
|
responses: {
|
|
166
|
-
200: { description: "Memory vector index health" },
|
|
281
|
+
200: { description: "Memory vector index health", schema: MemoryHealthSchema },
|
|
167
282
|
},
|
|
168
283
|
});
|
|
169
284
|
|
|
170
285
|
// Windowed usefulness analytics — sibling of the cheap /health probe.
|
|
171
286
|
// Reads memory_retrieval + memory_rating + agent_memory posteriors; plan:
|
|
172
287
|
// thoughts/taras/plans/2026-07-02-memory-retrieval-v2-graph-and-measurement.md Phase 1.
|
|
288
|
+
// Mirrors `UsefulnessStats` and its nested shapes (src/be/memory/usefulness-stats.ts)
|
|
289
|
+
// — `getUsefulnessStats()`'s return value, sent verbatim.
|
|
290
|
+
const UsefulnessStatsSchema = z.object({
|
|
291
|
+
windowDays: z.number(),
|
|
292
|
+
threshold: z.number(),
|
|
293
|
+
cutoff: z.string(),
|
|
294
|
+
volume: z.object({
|
|
295
|
+
retrievals: z.number(),
|
|
296
|
+
distinctMemories: z.number(),
|
|
297
|
+
retrievalGroups: z.number(),
|
|
298
|
+
byEventType: z.object({ search: z.number(), get: z.number() }),
|
|
299
|
+
}),
|
|
300
|
+
byArm: z.array(
|
|
301
|
+
z.object({
|
|
302
|
+
retrievalSource: z.string().nullable(),
|
|
303
|
+
retrievals: z.number(),
|
|
304
|
+
distinctMemories: z.number(),
|
|
305
|
+
citedRetrievals: z.number(),
|
|
306
|
+
citationRate: z.number(),
|
|
307
|
+
}),
|
|
308
|
+
),
|
|
309
|
+
citationBySource: z.array(
|
|
310
|
+
z.object({
|
|
311
|
+
source: z.string(),
|
|
312
|
+
ratings: z.number(),
|
|
313
|
+
positive: z.number(),
|
|
314
|
+
citationRate: z.number(),
|
|
315
|
+
avgSignal: z.number(),
|
|
316
|
+
}),
|
|
317
|
+
),
|
|
318
|
+
posterior: z.object({
|
|
319
|
+
totalMemories: z.number(),
|
|
320
|
+
movedFromPrior: z.number(),
|
|
321
|
+
avgPosteriorMean: z.number().nullable(),
|
|
322
|
+
avgPosteriorMeanMoved: z.number().nullable(),
|
|
323
|
+
aboveThreshold: z.number(),
|
|
324
|
+
}),
|
|
325
|
+
sanity: z.object({
|
|
326
|
+
totalRetrievalRows: z.number(),
|
|
327
|
+
totalRatingRows: z.number(),
|
|
328
|
+
ratingsBySource: z.array(z.object({ source: z.string(), count: z.number() })),
|
|
329
|
+
}),
|
|
330
|
+
});
|
|
331
|
+
|
|
173
332
|
const memoryUsefulness = route({
|
|
174
333
|
method: "get",
|
|
175
334
|
path: "/api/memory/usefulness",
|
|
@@ -194,7 +353,7 @@ const memoryUsefulness = route({
|
|
|
194
353
|
.describe("Posterior-mean threshold for the aboveThreshold count (default 0.6)"),
|
|
195
354
|
}),
|
|
196
355
|
responses: {
|
|
197
|
-
200: { description: "Usefulness stats for the window" },
|
|
356
|
+
200: { description: "Usefulness stats for the window", schema: UsefulnessStatsSchema },
|
|
198
357
|
400: { description: "Validation error" },
|
|
199
358
|
},
|
|
200
359
|
});
|
|
@@ -208,11 +367,53 @@ const deleteMemoryById = route({
|
|
|
208
367
|
auth: { apiKey: true },
|
|
209
368
|
params: z.object({ id: z.string().uuid() }),
|
|
210
369
|
responses: {
|
|
211
|
-
200: { description: "Memory deleted" },
|
|
370
|
+
200: { description: "Memory deleted", schema: z.object({ deleted: z.boolean() }) },
|
|
212
371
|
404: { description: "Memory not found" },
|
|
213
372
|
},
|
|
214
373
|
});
|
|
215
374
|
|
|
375
|
+
// Mirrors `LinkType` / `TargetKind` (src/be/memory/link-resolver.ts).
|
|
376
|
+
const LinkTypeSchema = z.enum([
|
|
377
|
+
"wikilink",
|
|
378
|
+
"sequel",
|
|
379
|
+
"agent-fs-file",
|
|
380
|
+
"agent-ui",
|
|
381
|
+
"pr",
|
|
382
|
+
"external-source",
|
|
383
|
+
]);
|
|
384
|
+
const TargetKindSchema = z.enum(["memory", "agent-fs-file", "agent-ui", "pr", "external-source"]);
|
|
385
|
+
|
|
386
|
+
// Mirrors `LinkedMemoryRef` (src/be/memory/links-store.ts).
|
|
387
|
+
const LinkedMemoryRefSchema = z.object({
|
|
388
|
+
id: z.string(),
|
|
389
|
+
name: z.string(),
|
|
390
|
+
scope: z.string(),
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
// Mirrors `MemoryLinkView` (src/be/memory/links-store.ts).
|
|
394
|
+
const MemoryLinkViewSchema = z.object({
|
|
395
|
+
id: z.string(),
|
|
396
|
+
linkType: LinkTypeSchema,
|
|
397
|
+
targetKind: TargetKindSchema,
|
|
398
|
+
targetId: z.string(),
|
|
399
|
+
strength: z.number(),
|
|
400
|
+
resolver: z.string(),
|
|
401
|
+
sourceText: z.string().nullable(),
|
|
402
|
+
createdAt: z.string(),
|
|
403
|
+
resolved: z.boolean(),
|
|
404
|
+
target: LinkedMemoryRefSchema.optional(),
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// Mirrors `MemoryBacklinkView` (src/be/memory/links-store.ts).
|
|
408
|
+
const MemoryBacklinkViewSchema = z.object({
|
|
409
|
+
id: z.string(),
|
|
410
|
+
linkType: LinkTypeSchema,
|
|
411
|
+
strength: z.number(),
|
|
412
|
+
sourceText: z.string().nullable(),
|
|
413
|
+
createdAt: z.string(),
|
|
414
|
+
from: LinkedMemoryRefSchema,
|
|
415
|
+
});
|
|
416
|
+
|
|
216
417
|
const getMemoryById = route({
|
|
217
418
|
method: "get",
|
|
218
419
|
path: "/api/memory/{id}",
|
|
@@ -234,6 +435,11 @@ const getMemoryById = route({
|
|
|
234
435
|
200: {
|
|
235
436
|
description:
|
|
236
437
|
"Memory details, plus `links` (outgoing memory_link rows; memory-kind targets carry `resolved` + ACL-filtered `target` metadata) and `backlinks` (inbound links from other memories, ACL-filtered)",
|
|
438
|
+
schema: z.object({
|
|
439
|
+
memory: AgentMemorySchema,
|
|
440
|
+
links: z.array(MemoryLinkViewSchema),
|
|
441
|
+
backlinks: z.array(MemoryBacklinkViewSchema),
|
|
442
|
+
}),
|
|
237
443
|
},
|
|
238
444
|
404: { description: "Memory not found" },
|
|
239
445
|
},
|
|
@@ -291,12 +497,31 @@ const rateMemory = route({
|
|
|
291
497
|
events: z.array(RateEventSchema).min(1).max(50),
|
|
292
498
|
}),
|
|
293
499
|
responses: {
|
|
294
|
-
200: {
|
|
500
|
+
200: {
|
|
501
|
+
description: "Ratings applied; per-event rejections returned in body",
|
|
502
|
+
schema: z.object({
|
|
503
|
+
applied: z.number(),
|
|
504
|
+
rejected: z.array(z.object({ memoryId: z.string(), reason: z.string() })),
|
|
505
|
+
}),
|
|
506
|
+
},
|
|
295
507
|
400: { description: "Validation error or explicit-self R6 spam-guard rejection" },
|
|
296
508
|
409: { description: "Duplicate explicit-self rating for (taskId, memoryId)" },
|
|
297
509
|
},
|
|
298
510
|
});
|
|
299
511
|
|
|
512
|
+
// Mirrors `RetrievalListRow` (src/be/memory/retrieval-store.ts).
|
|
513
|
+
const RetrievalListRowSchema = z.object({
|
|
514
|
+
id: z.string(),
|
|
515
|
+
name: z.string(),
|
|
516
|
+
content: z.string(),
|
|
517
|
+
scope: z.string(),
|
|
518
|
+
source: z.string(),
|
|
519
|
+
scheduleId: z.string().nullable(),
|
|
520
|
+
similarity: z.number().nullable(),
|
|
521
|
+
retrievalSource: z.string().nullable(),
|
|
522
|
+
retrievedAt: z.string(),
|
|
523
|
+
});
|
|
524
|
+
|
|
300
525
|
const getRetrievals = route({
|
|
301
526
|
method: "get",
|
|
302
527
|
path: "/api/memory/retrievals",
|
|
@@ -313,7 +538,10 @@ const getRetrievals = route({
|
|
|
313
538
|
message: "taskId or sessionId required",
|
|
314
539
|
}),
|
|
315
540
|
responses: {
|
|
316
|
-
200: {
|
|
541
|
+
200: {
|
|
542
|
+
description: "Retrieval rows joined with agent_memory",
|
|
543
|
+
schema: z.object({ results: z.array(RetrievalListRowSchema) }),
|
|
544
|
+
},
|
|
317
545
|
400: { description: "Missing taskId/sessionId or X-Agent-ID" },
|
|
318
546
|
},
|
|
319
547
|
});
|
|
@@ -322,6 +550,16 @@ const getRetrievals = route({
|
|
|
322
550
|
// homepage demo ("this memory references PR #377"). Auth by X-Agent-ID +
|
|
323
551
|
// Bearer with defence-in-depth: the joined `agent_memory` row must either
|
|
324
552
|
// be swarm-scope or owned by the requesting agent. Plan §7.
|
|
553
|
+
// Mirrors `MemoryEdgeRow` (src/be/memory/edges-store.ts).
|
|
554
|
+
const MemoryEdgeRowSchema = z.object({
|
|
555
|
+
to: z.string(),
|
|
556
|
+
type: z.literal("references-source"),
|
|
557
|
+
alpha: z.number(),
|
|
558
|
+
beta: z.number(),
|
|
559
|
+
usefulness: z.number(),
|
|
560
|
+
createdAt: z.string(),
|
|
561
|
+
});
|
|
562
|
+
|
|
325
563
|
const getMemoryEdges = route({
|
|
326
564
|
method: "get",
|
|
327
565
|
path: "/api/memory/edges",
|
|
@@ -333,7 +571,10 @@ const getMemoryEdges = route({
|
|
|
333
571
|
memoryId: z.string().min(1),
|
|
334
572
|
}),
|
|
335
573
|
responses: {
|
|
336
|
-
200: {
|
|
574
|
+
200: {
|
|
575
|
+
description: "Edges with computed usefulness scores",
|
|
576
|
+
schema: z.object({ edges: z.array(MemoryEdgeRowSchema) }),
|
|
577
|
+
},
|
|
337
578
|
400: { description: "Missing memoryId or X-Agent-ID" },
|
|
338
579
|
},
|
|
339
580
|
});
|
|
@@ -367,7 +608,11 @@ export async function handleMemory(
|
|
|
367
608
|
if (source === "session_summary" && sourceTaskId) {
|
|
368
609
|
const sourceTask = getTaskById(sourceTaskId);
|
|
369
610
|
if (sourceTask && !shouldPersistAutomaticTaskMemory(sourceTask, persistMemory)) {
|
|
370
|
-
|
|
611
|
+
indexMemory.respond(res, 202, {
|
|
612
|
+
queued: false,
|
|
613
|
+
memoryIds: [],
|
|
614
|
+
skipped: "automatic_task_memory_disabled",
|
|
615
|
+
});
|
|
371
616
|
return true;
|
|
372
617
|
}
|
|
373
618
|
}
|
|
@@ -414,7 +659,11 @@ export async function handleMemory(
|
|
|
414
659
|
(err as Error).message,
|
|
415
660
|
);
|
|
416
661
|
}
|
|
417
|
-
|
|
662
|
+
indexMemory.respond(res, 202, {
|
|
663
|
+
queued: false,
|
|
664
|
+
memoryIds: [result.memory.id],
|
|
665
|
+
edited: result.changed,
|
|
666
|
+
});
|
|
418
667
|
return true;
|
|
419
668
|
}
|
|
420
669
|
}
|
|
@@ -478,7 +727,7 @@ export async function handleMemory(
|
|
|
478
727
|
}
|
|
479
728
|
})();
|
|
480
729
|
|
|
481
|
-
|
|
730
|
+
indexMemory.respond(res, 202, { queued: true, memoryIds: memories.map((m) => m.id) });
|
|
482
731
|
return true;
|
|
483
732
|
}
|
|
484
733
|
|
|
@@ -544,7 +793,7 @@ export async function handleMemory(
|
|
|
544
793
|
}
|
|
545
794
|
}
|
|
546
795
|
|
|
547
|
-
|
|
796
|
+
searchMemory.respond(res, 200, {
|
|
548
797
|
results: ranked.map((r) => ({
|
|
549
798
|
id: r.id,
|
|
550
799
|
name: r.name,
|
|
@@ -560,7 +809,7 @@ export async function handleMemory(
|
|
|
560
809
|
});
|
|
561
810
|
} catch (err) {
|
|
562
811
|
console.error("[memory-search] Error:", (err as Error).message);
|
|
563
|
-
|
|
812
|
+
searchMemory.respond(res, 200, { results: [] });
|
|
564
813
|
}
|
|
565
814
|
return true;
|
|
566
815
|
}
|
|
@@ -601,7 +850,7 @@ export async function handleMemory(
|
|
|
601
850
|
const ranked = rerank(candidates, { limit: candidates.length });
|
|
602
851
|
const page = ranked.slice(offset, offset + pageLimit);
|
|
603
852
|
|
|
604
|
-
|
|
853
|
+
listMemory.respond(res, 200, {
|
|
605
854
|
results: page.map((r) => ({
|
|
606
855
|
id: r.id,
|
|
607
856
|
name: r.name,
|
|
@@ -644,7 +893,7 @@ export async function handleMemory(
|
|
|
644
893
|
const rows = store.list(agentId ?? "", listOptions);
|
|
645
894
|
const total = store.count(agentId ?? "", listOptions);
|
|
646
895
|
|
|
647
|
-
|
|
896
|
+
listMemory.respond(res, 200, {
|
|
648
897
|
results: rows.map((r) => ({
|
|
649
898
|
id: r.id,
|
|
650
899
|
name: r.name,
|
|
@@ -720,7 +969,7 @@ export async function handleMemory(
|
|
|
720
969
|
);
|
|
721
970
|
}
|
|
722
971
|
}
|
|
723
|
-
|
|
972
|
+
editMemory.respond(res, 200, result);
|
|
724
973
|
} catch (err) {
|
|
725
974
|
const message = (err as Error).message;
|
|
726
975
|
if (message.includes("not found")) jsonError(res, message, 404);
|
|
@@ -734,7 +983,7 @@ export async function handleMemory(
|
|
|
734
983
|
const parsed = await memoryHealth.parse(req, res, pathSegments, new URLSearchParams());
|
|
735
984
|
if (!parsed) return true;
|
|
736
985
|
|
|
737
|
-
|
|
986
|
+
memoryHealth.respond(res, 200, getMemoryStore().getHealth());
|
|
738
987
|
return true;
|
|
739
988
|
}
|
|
740
989
|
|
|
@@ -744,7 +993,7 @@ export async function handleMemory(
|
|
|
744
993
|
if (!parsed) return true;
|
|
745
994
|
|
|
746
995
|
const { days, threshold } = parsed.query;
|
|
747
|
-
|
|
996
|
+
memoryUsefulness.respond(res, 200, getUsefulnessStats({ days, threshold }));
|
|
748
997
|
return true;
|
|
749
998
|
}
|
|
750
999
|
|
|
@@ -758,7 +1007,7 @@ export async function handleMemory(
|
|
|
758
1007
|
jsonError(res, "Memory not found", 404);
|
|
759
1008
|
return true;
|
|
760
1009
|
}
|
|
761
|
-
|
|
1010
|
+
deleteMemoryById.respond(res, 200, { deleted: true });
|
|
762
1011
|
return true;
|
|
763
1012
|
}
|
|
764
1013
|
|
|
@@ -771,7 +1020,7 @@ export async function handleMemory(
|
|
|
771
1020
|
const provider = getEmbeddingProvider();
|
|
772
1021
|
const memories = store.listForReembedding(agentId ? { agentId } : undefined);
|
|
773
1022
|
|
|
774
|
-
|
|
1023
|
+
reEmbedMemory.respond(res, 202, { started: true, totalMemories: memories.length });
|
|
775
1024
|
|
|
776
1025
|
// Async re-embed in batches
|
|
777
1026
|
(async () => {
|
|
@@ -865,7 +1114,7 @@ export async function handleMemory(
|
|
|
865
1114
|
throw err;
|
|
866
1115
|
}
|
|
867
1116
|
|
|
868
|
-
|
|
1117
|
+
rateMemory.respond(res, 200, { applied, rejected });
|
|
869
1118
|
return true;
|
|
870
1119
|
}
|
|
871
1120
|
|
|
@@ -881,7 +1130,7 @@ export async function handleMemory(
|
|
|
881
1130
|
|
|
882
1131
|
const { taskId, sessionId } = parsed.query;
|
|
883
1132
|
const rows = getRetrievalsForAgent(myAgentId, { taskId, sessionId });
|
|
884
|
-
|
|
1133
|
+
getRetrievals.respond(res, 200, { results: rows });
|
|
885
1134
|
return true;
|
|
886
1135
|
}
|
|
887
1136
|
|
|
@@ -897,7 +1146,7 @@ export async function handleMemory(
|
|
|
897
1146
|
|
|
898
1147
|
const { memoryId } = parsed.query;
|
|
899
1148
|
const edges = listEdgesForAgent(myAgentId, memoryId);
|
|
900
|
-
|
|
1149
|
+
getMemoryEdges.respond(res, 200, { edges });
|
|
901
1150
|
return true;
|
|
902
1151
|
}
|
|
903
1152
|
|
|
@@ -951,7 +1200,11 @@ export async function handleMemory(
|
|
|
951
1200
|
console.error("[memory-get] link traversal failed:", (err as Error).message);
|
|
952
1201
|
}
|
|
953
1202
|
|
|
954
|
-
|
|
1203
|
+
getMemoryById.respond(res, 200, {
|
|
1204
|
+
memory,
|
|
1205
|
+
links: linkBlocks.links,
|
|
1206
|
+
backlinks: linkBlocks.backlinks,
|
|
1207
|
+
});
|
|
955
1208
|
return true;
|
|
956
1209
|
}
|
|
957
1210
|
|