@desplega.ai/agent-swarm 1.158.0 → 1.159.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/dist/{acp-adapter-xaq4n6pc.js → acp-adapter-qhch0n2v.js} +1 -1
- package/dist/{actions-p9hz5yat.js → actions-dtsh1mfb.js} +33 -29
- package/dist/{anthropic-messages-51pz26qe.js → anthropic-messages-f2h06k64.js} +8 -3
- package/dist/{app-g26wdcz6.js → app-y1b9srva.js} +10 -9
- package/dist/{assistant-wydfqkb3.js → assistant-31hwy5xj.js} +34 -30
- package/dist/{azure-openai-responses-8gksqtmz.js → azure-openai-responses-0k1mfax5.js} +12 -13
- package/dist/{boot-reembed-se8zmdcp.js → boot-reembed-48d2qpkt.js} +11 -11
- package/dist/{boot-reembed-g5ckg9yb.js → boot-reembed-w0bryhkr.js} +12 -12
- package/dist/{boot-scrub-logs-wfxqan61.js → boot-scrub-logs-t65wbrn7.js} +9 -8
- package/dist/{boot-seeds-s3q01xj3.js → boot-seeds-h7c32hvm.js} +12 -11
- package/dist/{claude-adapter-tv2x4f36.js → claude-adapter-1t6611ne.js} +26 -21
- package/dist/{claude-managed-adapter-41b2s7fd.js → claude-managed-adapter-werp659j.js} +4 -2
- package/dist/{claude-managed-setup-60g8aazx.js → claude-managed-setup-y6rdgbc1.js} +11 -2
- package/dist/claude-sdk-session-zhkyk8yw.js +29319 -0
- package/dist/{cli-vj6h9kc2.js → cli-0m7wct0d.js} +59 -1
- package/dist/{cli-wscdvcqz.js → cli-0n2e4x49.js} +1 -1
- package/dist/cli-0xqde53b.js +176 -0
- package/dist/{cli-xberxa1r.js → cli-10ym38qc.js} +2 -2
- package/dist/{cli-5b6b62tz.js → cli-13hw4z91.js} +1 -1
- package/dist/{cli-rqz8qbw7.js → cli-20035trh.js} +50 -18
- package/dist/{cli-k0g1sjzm.js → cli-31nkw3g3.js} +3 -3
- package/dist/cli-3gvrr8vj.js +1422 -0
- package/dist/{cli-c07r9a2m.js → cli-48527fpw.js} +9 -8
- package/dist/{cli-24k806sc.js → cli-4aj25szq.js} +2 -2
- package/dist/{cli-7gtvvpbh.js → cli-4tvgz99m.js} +7 -7
- package/dist/cli-503ya656.js +455 -0
- package/dist/{cli-cw9zck8j.js → cli-5f2hq128.js} +8 -4
- package/dist/{cli-s8eet254.js → cli-68bmme5p.js} +11078 -27833
- package/dist/{cli-ftfvggzx.js → cli-79aq9cgb.js} +794 -563
- package/dist/cli-7cxw8b60.js +14910 -0
- package/dist/cli-7kyk9jr3.js +22 -0
- package/dist/cli-7zttzetj.js +324 -0
- package/dist/{cli-y95wp3tg.js → cli-96qd5psa.js} +1 -1
- package/dist/{cli-g8djp6qe.js → cli-9yg65c1j.js} +22 -0
- package/dist/{cli-3gmcwfyx.js → cli-ardpzhjm.js} +5 -5
- package/dist/{cli-7s3syk22.js → cli-b6thtzac.js} +5 -5
- package/dist/{cli-00w2c66p.js → cli-bgv70kym.js} +13 -2
- package/dist/{cli-j55n64b6.js → cli-bv0a38v9.js} +163 -44
- package/dist/cli-ca2w7zv7.js +115 -0
- package/dist/cli-cpvsaqsw.js +333 -0
- package/dist/cli-cygyqj3b.js +754 -0
- package/dist/{cli-x24pshtq.js → cli-dvjpkkjd.js} +6 -6
- package/dist/{cli-5d10vd2m.js → cli-e0ndxhtk.js} +4 -4
- package/dist/{cli-4198qc9v.js → cli-e4xnc0qp.js} +15 -3
- package/dist/{cli-rjehvrts.js → cli-eg7cdg68.js} +8 -8
- package/dist/cli-ejpygnqz.js +3815 -0
- package/dist/{cli-fgqxwrpv.js → cli-fjtp3463.js} +1631 -127
- package/dist/{cli-zt1227k1.js → cli-fkqhbg8g.js} +5 -3
- package/dist/{cli-47m6dkd3.js → cli-g9df2m37.js} +409 -168
- package/dist/cli-gzyh0j0g.js +8455 -0
- package/dist/cli-hgqfttfc.js +183 -0
- package/dist/cli-hj65wsts.js +17755 -0
- package/dist/cli-j9z8mfx3.js +476 -0
- package/dist/{cli-aehm1rbq.js → cli-kc3dp84d.js} +1135 -61
- package/dist/{cli-h38x0qhg.js → cli-kdnehe0t.js} +4 -3
- package/dist/{cli-20cj37vt.js → cli-m4excttz.js} +136 -2216
- package/dist/{cli-8qmme6vd.js → cli-mg24hkt4.js} +2 -2
- package/dist/{cli-xhaeg2nc.js → cli-mzkqpxee.js} +1 -1
- package/dist/{cli-q67y4wzm.js → cli-phsaj4xq.js} +24 -2
- package/dist/{cli-pw9rj5t9.js → cli-pqetb83f.js} +1 -176
- package/dist/{cli-rj19hc34.js → cli-qjxy52w7.js} +1 -1
- package/dist/{cli-53sz8gkz.js → cli-qv4jv8bx.js} +1 -1
- package/dist/cli-qvnnx4ct.js +1051 -0
- package/dist/cli-rb9m6rpe.js +4980 -0
- package/dist/{cli-tt9k8r35.js → cli-rfezr056.js} +476 -909
- package/dist/{cli-ggm92wcn.js → cli-rgjprct3.js} +1 -0
- package/dist/{cli-9httdpyq.js → cli-rrqmqr1s.js} +1 -1
- package/dist/cli-rykfmgwg.js +102 -0
- package/dist/{cli-eetrvv91.js → cli-t3p77qk1.js} +1 -1
- package/dist/{cli-68w09sjw.js → cli-vn0qv9cj.js} +25 -88
- package/dist/{cli-987hg0aa.js → cli-vwbbaecp.js} +2 -2
- package/dist/cli-wd9hz40d.js +69 -0
- package/dist/{cli-j57qkrpq.js → cli-wgjx0q33.js} +13 -13
- package/dist/cli-xgpf00sk.js +2149 -0
- package/dist/{cli-mcnhgnn1.js → cli-ykk5jaax.js} +184 -26
- package/dist/{cli-aky8tctm.js → cli-z9x0sh1t.js} +3 -3
- package/dist/{cli-1hkrch3k.js → cli-zw65mab6.js} +5 -5
- package/dist/cli.js +38 -29
- package/dist/cloudflare-workers-ai-system-one-1sg586qv.js +46 -0
- package/dist/{codex-adapter-cnm8wk11.js → codex-adapter-jqfqqa21.js} +21 -14
- package/dist/{codex-hook-9hptmdhj.js → codex-hook-5eys3dya.js} +2 -2
- package/dist/{codex-session-runner-gfg547zj.js → codex-session-runner-zd341dsm.js} +21 -14
- package/dist/{commands-e3bn0p75.js → commands-vfsysz4s.js} +9 -8
- package/dist/{db-03v9kzr2.js → db-s3znhvbn.js} +15 -10
- package/dist/{dispatcher-nrmg8yht.js → dispatcher-5xn0c7rf.js} +32 -28
- package/dist/{dsh-adapter-k03nfqa6.js → dsh-adapter-894mgfvs.js} +3 -3
- package/dist/{e2b-93x1k0j5.js → e2b-ez07znam.js} +4 -3
- package/dist/execute-71ysgv35.js +965 -0
- package/dist/{google-generative-ai-bxmv50nc.js → google-generative-ai-1nfcdphp.js} +5 -4
- package/dist/{google-vertex-809af514.js → google-vertex-1tqcd7b1.js} +5 -4
- package/dist/{handlers-aqcedbyb.js → handlers-5w4jwycr.js} +35 -31
- package/dist/{hook-7vkskkre.js → hook-853bxrr6.js} +16 -13
- package/dist/{hook-ybvmrmhq.js → hook-z0hbxj85.js} +16 -13
- package/dist/{http-2eqa8t24.js → http-akc3wy3m.js} +600 -123
- package/dist/{index-f6cryxwe.js → index-4a5njnm1.js} +2 -59
- package/dist/{index-a3vn96n8.js → index-5sz16ksh.js} +187 -47
- package/dist/{index-c6zsv1bd.js → index-bjmjh9h4.js} +11 -11
- package/dist/{index-chgdkq36.js → index-cd151qkq.js} +32 -28
- package/dist/{index-x71bvq0p.js → index-k661dzzr.js} +33 -29
- package/dist/{index-1yks3qcr.js → index-ttpbhnjg.js} +32 -28
- package/dist/{keepalive-vtkf5n99.js → keepalive-8p9rpvz5.js} +11 -10
- package/dist/{lead-h3sp357x.js → lead-jp69z5h3.js} +49 -45
- package/dist/llama-cpp-classify-t2tccams.js +335 -0
- package/dist/{maintenance-jzeqtk3q.js → maintenance-fwx4ev0k.js} +12 -12
- package/dist/{mistral-conversations-zx0kn554.js → mistral-conversations-bhvwqcnk.js} +14 -17
- package/dist/{oauth-refresh-sweep-qp3dzmdp.js → oauth-refresh-sweep-cwcq1ctx.js} +10 -9
- package/dist/{onboard-tmsp0qbz.js → onboard-2b4q0t84.js} +6 -5
- package/dist/{openai-codex-responses-4vjqzvjp.js → openai-codex-responses-nekthgks.js} +21 -8
- package/dist/{openai-completions-9hjrqbw8.js → openai-completions-hxtzwj0s.js} +8 -11
- package/dist/{openai-responses-7b1pn0xt.js → openai-responses-w4r118w7.js} +22 -17
- package/dist/{opencode-adapter-x6x2da1z.js → opencode-adapter-zz7xvjj6.js} +6 -4
- package/dist/{openrouter-images-9f9ek4rw.js → openrouter-images-b6sqqjgn.js} +4 -6
- package/dist/{otel-impl-9mz73q65.js → otel-impl-g8rs4vwr.js} +1 -1
- package/dist/{pi-messages-txpjj39q.js → pi-messages-vxdt8v7j.js} +2 -1
- package/dist/{pi-mono-adapter-m6dvv0dz.js → pi-mono-adapter-n0me28wt.js} +29 -17
- package/dist/pricing-refresh-0v77385v.js +39 -0
- package/dist/{rbac-roles-c9wqz83x.js → rbac-roles-krjyazbj.js} +10 -9
- package/dist/{render-v2-gryrh9h8.js → render-v2-3wjsp9aw.js} +10 -9
- package/dist/runtime-ktjysacx.js +24 -0
- package/dist/{setup-q9720bt6.js → setup-yeqryke6.js} +6 -5
- package/dist/typesafe-system-one-96960jxp.js +27 -0
- package/dist/{virtual-modules-3htpgn8x.js → virtual-modules-dzdeq1sf.js} +21 -13
- package/dist/{work-objects-b76x7deb.js → work-objects-3pakpkw0.js} +35 -31
- package/dist/{worker-6vrxbv41.js → worker-85testgj.js} +49 -45
- package/openapi.json +863 -14
- package/package.json +9 -8
- package/src/be/db/agents.ts +20 -0
- package/src/be/db/tasks/human-free.ts +442 -0
- package/src/be/db/tasks/read.ts +56 -1
- package/src/be/db/tasks/write.ts +107 -11
- package/src/be/db.ts +89 -165
- package/src/be/harness-model-support.ts +182 -0
- package/src/be/human-free-drain.ts +67 -0
- package/src/be/migrations/182_task_human_free_flag.sql +63 -0
- package/src/be/migrations/183_human_free_reclassify_queue.sql +25 -0
- package/src/be/migrations/184_model_catalog.sql +120 -0
- package/src/be/model-catalog-store.ts +644 -0
- package/src/be/model-tier-keys.ts +31 -0
- package/src/be/model-tier-resolution.ts +489 -0
- package/src/be/model-validation.ts +112 -0
- package/src/be/models-catalog.ts +61 -7
- package/src/be/modelsdev-cache.json +82 -0
- package/src/be/modelsdev-cache.ts +2 -0
- package/src/be/pricing-refresh.ts +154 -12
- package/src/be/scripts/typecheck.ts +15 -0
- package/src/be/seed-scripts/catalog/task-failure-audit.ts +61 -9
- package/src/be/swarm-config-guard.ts +6 -0
- package/src/cli.tsx +10 -0
- package/src/commands/claude-managed-setup.ts +3 -1
- package/src/commands/runner.ts +76 -2
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/heartbeat/heartbeat.ts +64 -15
- package/src/heartbeat/templates.ts +2 -2
- package/src/http/agents.ts +49 -1
- package/src/http/index.ts +8 -0
- package/src/http/models-catalog.ts +357 -8
- package/src/http/poll.ts +45 -2
- package/src/http/schedules.ts +36 -6
- package/src/http/session-data.ts +2 -5
- package/src/http/stats.ts +6 -8
- package/src/http/tasks.ts +26 -1
- package/src/http/usage-cache.ts +56 -15
- package/src/http/workflows.ts +35 -8
- package/src/prompts/session-templates.ts +1 -0
- package/src/providers/claude-managed-models.ts +47 -161
- package/src/providers/codex-adapter.ts +4 -4
- package/src/providers/codex-models.ts +65 -198
- package/src/providers/reasoning-effort.ts +44 -140
- package/src/rbac/legacy-policy.ts +25 -0
- package/src/rbac/permissions.ts +10 -0
- package/src/scripts-runtime/sdk-allowlist.ts +4 -0
- package/src/scripts-runtime/types/stdlib.d.ts +15 -0
- package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +15 -0
- package/src/server.ts +6 -0
- package/src/slack/message-text.ts +56 -2
- package/src/slack/thread-buffer.ts +10 -2
- package/src/tests/agents-list-model-display.test.ts +4 -6
- package/src/tests/base-prompt.test.ts +3 -0
- package/src/tests/claude-adapter.test.ts +10 -0
- package/src/tests/claude-managed-adapter.test.ts +12 -18
- package/src/tests/codex-adapter.test.ts +2 -1
- package/src/tests/codex-gpt6-release.test.ts +66 -5
- package/src/tests/context-window.test.ts +7 -5
- package/src/tests/db-extraction-contract.test.ts +1 -0
- package/src/tests/db-task-read-contract.test.ts +5 -1
- package/src/tests/db-task-write-contract.test.ts +4 -1
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/explicit-model-validation.test.ts +332 -0
- package/src/tests/harness-model-support.test.ts +374 -0
- package/src/tests/heartbeat-checklist-config.test.ts +71 -0
- package/src/tests/heartbeat-checklist.test.ts +4 -2
- package/src/tests/heartbeat-orphan-resume.test.ts +48 -0
- package/src/tests/human-free-flag.test.ts +279 -0
- package/src/tests/human-free-oracle.ts +57 -0
- package/src/tests/human-free-reclassify.test.ts +669 -0
- package/src/tests/migration-046-budgets.test.ts +3 -3
- package/src/tests/model-catalog-migration.test.ts +134 -0
- package/src/tests/model-catalog-table.test.ts +249 -0
- package/src/tests/model-catalog-write-access.test.ts +387 -0
- package/src/tests/model-tier-resolution.test.ts +519 -0
- package/src/tests/models-catalog.test.ts +1 -1
- package/src/tests/multi-runtime-enabled-stats.test.ts +65 -1
- package/src/tests/package-publish.test.ts +137 -36
- package/src/tests/pricing-routes.test.ts +2 -2
- package/src/tests/rbac-engine.test.ts +42 -2
- package/src/tests/reasoning-effort.test.ts +109 -0
- package/src/tests/refresh-modelsdev-carryforward.test.ts +5 -5
- package/src/tests/runtime-model-catalog.test.ts +86 -0
- package/src/tests/script-connections.test.ts +5 -0
- package/src/tests/seed-scripts.test.ts +89 -0
- package/src/tests/session-costs.test.ts +14 -11
- package/src/tests/slack-message-text.test.ts +101 -0
- package/src/tests/slack-thread-buffer-context.test.ts +93 -0
- package/src/tests/task-cascade-fail.test.ts +148 -2
- package/src/tests/tool-annotations.test.ts +1 -1
- package/src/tests/usage-cache.test.ts +166 -0
- package/src/tests/workflow-executors.test.ts +5 -2
- package/src/tests/workflow-system-one-decision-review.test.ts +1021 -0
- package/src/tests/workflow-system-one-decision-save-warnings.test.ts +365 -0
- package/src/tests/workflow-system-one-decision.test.ts +2063 -0
- package/src/tools/model-catalog/index.ts +137 -0
- package/src/tools/schedules/create-schedule.ts +16 -1
- package/src/tools/schedules/patch-schedule.ts +17 -0
- package/src/tools/schedules/update-schedule.ts +17 -0
- package/src/tools/send-task.ts +14 -0
- package/src/tools/task-action.ts +12 -0
- package/src/tools/tool-config.ts +3 -1
- package/src/tools/workflows/create-workflow.ts +9 -2
- package/src/tools/workflows/patch-workflow-node.ts +17 -7
- package/src/tools/workflows/patch-workflow.ts +9 -2
- package/src/tools/workflows/update-workflow.ts +9 -2
- package/src/types.ts +30 -1
- package/src/utils/context-window.ts +47 -53
- package/src/utils/harness-cli-version.ts +115 -0
- package/src/utils/harness-model-error.ts +33 -0
- package/src/utils/runtime-model-catalog.ts +137 -0
- package/src/workflows/approval-resolution.ts +39 -0
- package/src/workflows/definition.ts +7 -0
- package/src/workflows/engine.ts +69 -1
- package/src/workflows/executors/agent-task.ts +9 -0
- package/src/workflows/executors/base.ts +53 -0
- package/src/workflows/executors/human-in-the-loop.ts +8 -8
- package/src/workflows/executors/index.ts +1 -0
- package/src/workflows/executors/registry.ts +2 -0
- package/src/workflows/executors/system-one-decision.ts +1232 -0
- package/src/workflows/executors/system-one-providers.ts +301 -0
- package/src/workflows/executors/workflow-llm.ts +13 -1
- package/src/workflows/readiness.ts +86 -0
- package/src/workflows/recovery.ts +12 -12
- package/src/workflows/resume.ts +23 -9
- package/templates/schedules/daily-blocker-digest/content.md +4 -5
- package/templates/skills/agent-browser/SKILL.md +6 -5
- package/templates/skills/agent-browser/content.md +6 -5
- package/templates/skills/heartbeat-runbook/config.json +1 -1
- package/templates/skills/heartbeat-runbook/content.md +2 -2
- package/templates/skills/swarm-scripts/SKILL.md +1 -1
- package/templates/skills/swarm-scripts/content.md +1 -1
- package/templates/skills/workflow-iterate/content.md +81 -1
- package/templates/workflows/claude-code-changelog-watch/content.md +2 -0
- package/templates/workflows/pr-review-status-sweep/content.md +2 -0
- package/dist/claude-sdk-session-t442qz6f.js +0 -39108
- package/dist/cli-0xjkj1j7.js +0 -61
- package/dist/cli-65hjmev5.js +0 -1141
- package/dist/cli-aw1jwp1r.js +0 -14075
- package/dist/cli-h967nb6r.js +0 -6603
- package/dist/cli-vapyk8sw.js +0 -20
- package/dist/cli-ws6rqycm.js +0 -247
- package/dist/pricing-refresh-v1cbr9te.js +0 -27
- package/src/providers/modelsdev-reasoning.json +0 -6453
- package/dist/{codex-login-x3jk4etn.js → codex-login-he9vrn90.js} +3 -3
- package/dist/{index-f24115ge.js → index-2wsdsnmm.js} +3 -3
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import {
|
|
2
|
+
init_zod
|
|
3
|
+
} from "./cli-sd0mxa3c.js";
|
|
4
|
+
import {
|
|
5
|
+
exports_external
|
|
6
|
+
} from "./cli-w5e1d1vv.js";
|
|
7
|
+
|
|
8
|
+
// plugin/opencode-plugins/lib/memory-raters.ts
|
|
9
|
+
function getMemoryRaterNames() {
|
|
10
|
+
return (process.env.MEMORY_RATERS ?? "implicit-citation,explicit-self").split(",").map((name) => name.trim()).filter(Boolean);
|
|
11
|
+
}
|
|
12
|
+
// src/be/memory/raters/llm.ts
|
|
13
|
+
init_zod();
|
|
14
|
+
|
|
15
|
+
// src/be/memory/raters/llm-client.ts
|
|
16
|
+
var DEFAULT_TIMEOUT_MS = 30000;
|
|
17
|
+
var PROMPT_TEMPLATE = `You are scoring the usefulness of one retrieved memory.
|
|
18
|
+
|
|
19
|
+
Return ONLY a JSON object with these fields (no prose, no markdown):
|
|
20
|
+
{
|
|
21
|
+
"score": number, // 0 = misleading/unhelpful, 1 = highly useful
|
|
22
|
+
"reasoning": string // 1..500 chars, why
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
QUERY:
|
|
26
|
+
\${query}
|
|
27
|
+
|
|
28
|
+
MEMORY:
|
|
29
|
+
id: \${memoryId}
|
|
30
|
+
name: \${memoryName}
|
|
31
|
+
content: \${memoryContent}
|
|
32
|
+
|
|
33
|
+
AGENT RESPONSE / SUMMARY:
|
|
34
|
+
\${response}
|
|
35
|
+
|
|
36
|
+
Score 0..1.`;
|
|
37
|
+
var PLACEHOLDER_PREFIX = "$";
|
|
38
|
+
var QUERY_PLACEHOLDER = `${PLACEHOLDER_PREFIX}{query}`;
|
|
39
|
+
var MEMORY_ID_PLACEHOLDER = `${PLACEHOLDER_PREFIX}{memoryId}`;
|
|
40
|
+
var MEMORY_NAME_PLACEHOLDER = `${PLACEHOLDER_PREFIX}{memoryName}`;
|
|
41
|
+
var MEMORY_CONTENT_PLACEHOLDER = `${PLACEHOLDER_PREFIX}{memoryContent}`;
|
|
42
|
+
var RESPONSE_PLACEHOLDER = `${PLACEHOLDER_PREFIX}{response}`;
|
|
43
|
+
function buildPrompt(input) {
|
|
44
|
+
return PROMPT_TEMPLATE.replace(QUERY_PLACEHOLDER, input.query).replace(MEMORY_ID_PLACEHOLDER, input.memory.id).replace(MEMORY_NAME_PLACEHOLDER, input.memory.name).replace(MEMORY_CONTENT_PLACEHOLDER, input.memory.content).replace(RESPONSE_PLACEHOLDER, input.response);
|
|
45
|
+
}
|
|
46
|
+
function parseScoreAndReasoning(raw) {
|
|
47
|
+
if (typeof raw !== "string")
|
|
48
|
+
return null;
|
|
49
|
+
let parsed;
|
|
50
|
+
try {
|
|
51
|
+
parsed = JSON.parse(raw.trim());
|
|
52
|
+
} catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
if (!parsed || typeof parsed !== "object")
|
|
56
|
+
return null;
|
|
57
|
+
const obj = parsed;
|
|
58
|
+
const score = typeof obj.score === "number" ? obj.score : null;
|
|
59
|
+
const reasoning = typeof obj.reasoning === "string" ? obj.reasoning : null;
|
|
60
|
+
if (score == null || reasoning == null)
|
|
61
|
+
return null;
|
|
62
|
+
if (!Number.isFinite(score) || score < 0 || score > 1)
|
|
63
|
+
return null;
|
|
64
|
+
if (reasoning.length === 0 || reasoning.length > 500)
|
|
65
|
+
return null;
|
|
66
|
+
return { score, reasoning };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
class ClaudeCliLlmRaterClient {
|
|
70
|
+
model;
|
|
71
|
+
timeoutMs;
|
|
72
|
+
constructor(opts = {}) {
|
|
73
|
+
this.model = opts.model ?? process.env.MEMORY_LLM_RATER_MODEL ?? "haiku";
|
|
74
|
+
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
75
|
+
}
|
|
76
|
+
async rate(input) {
|
|
77
|
+
const prompt = buildPrompt(input);
|
|
78
|
+
const tmpFile = `/tmp/llm-rater-${Date.now()}-${Math.random().toString(36).slice(2)}.txt`;
|
|
79
|
+
let stdout = "";
|
|
80
|
+
try {
|
|
81
|
+
await Bun.write(tmpFile, prompt);
|
|
82
|
+
const proc = Bun.spawn(["bash", "-c", `cat "${tmpFile}" | claude -p --model ${this.model} --output-format json`], {
|
|
83
|
+
stdout: "pipe",
|
|
84
|
+
stderr: "pipe",
|
|
85
|
+
env: { ...process.env, SKIP_SESSION_SUMMARY: "1" }
|
|
86
|
+
});
|
|
87
|
+
const timeoutId = setTimeout(() => proc.kill(), this.timeoutMs);
|
|
88
|
+
stdout = await new Response(proc.stdout).text();
|
|
89
|
+
clearTimeout(timeoutId);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
console.error("[memory-rater:llm] claude -p shell-out failed:", err.message);
|
|
92
|
+
return null;
|
|
93
|
+
} finally {
|
|
94
|
+
try {
|
|
95
|
+
await Bun.$`rm -f ${tmpFile}`.quiet();
|
|
96
|
+
} catch {}
|
|
97
|
+
}
|
|
98
|
+
let envelope;
|
|
99
|
+
try {
|
|
100
|
+
envelope = JSON.parse(stdout);
|
|
101
|
+
} catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return parseScoreAndReasoning(envelope.result);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/be/memory/raters/types.ts
|
|
109
|
+
var REFERENCES_SOURCE_MAX_LENGTH = 512;
|
|
110
|
+
var NUL_CHAR_CODE = 0;
|
|
111
|
+
var DEL_CHAR_CODE = 127;
|
|
112
|
+
var FIRST_PRINTABLE_ASCII = 32;
|
|
113
|
+
function sanitizeReferencesSource(input) {
|
|
114
|
+
let stripped = "";
|
|
115
|
+
for (let i = 0;i < input.length; i++) {
|
|
116
|
+
const code = input.charCodeAt(i);
|
|
117
|
+
if (code === NUL_CHAR_CODE)
|
|
118
|
+
return null;
|
|
119
|
+
if (code < FIRST_PRINTABLE_ASCII || code === DEL_CHAR_CODE) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
stripped += input[i];
|
|
123
|
+
}
|
|
124
|
+
if (stripped.length === 0)
|
|
125
|
+
return null;
|
|
126
|
+
return stripped;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/be/memory/raters/llm.ts
|
|
130
|
+
var LLM_RATER_WEIGHT = 0.8;
|
|
131
|
+
var RatingSchema = exports_external.object({
|
|
132
|
+
id: exports_external.string().min(1),
|
|
133
|
+
score: exports_external.number().min(0).max(1),
|
|
134
|
+
reasoning: exports_external.string().min(1).max(500),
|
|
135
|
+
referencesSource: exports_external.string().min(1).max(REFERENCES_SOURCE_MAX_LENGTH).optional()
|
|
136
|
+
});
|
|
137
|
+
var SummaryWithRatingsSchema = exports_external.object({
|
|
138
|
+
summary: exports_external.string(),
|
|
139
|
+
ratings: exports_external.array(RatingSchema).default([])
|
|
140
|
+
});
|
|
141
|
+
var BASE_SUMMARIZE_PROMPT = `You are summarizing an AI agent's work session. Extract ONLY high-value learnings.
|
|
142
|
+
|
|
143
|
+
DO NOT include:
|
|
144
|
+
- Generic descriptions of what was done ("worked on task X")
|
|
145
|
+
- Tool calls or file reads
|
|
146
|
+
- Routine progress updates
|
|
147
|
+
|
|
148
|
+
DO include (if present):
|
|
149
|
+
- **Mistakes made and corrections** — what went wrong and what fixed it
|
|
150
|
+
- **Discovered patterns** — reusable approaches, APIs, or codebase conventions
|
|
151
|
+
- **Codebase knowledge** — important file paths, architecture decisions, gotchas
|
|
152
|
+
- **Environment knowledge** — service URLs, config details, tool quirks
|
|
153
|
+
- **Failed approaches** — what was tried and didn't work (and why)
|
|
154
|
+
|
|
155
|
+
Format as a bulleted list of concrete, reusable facts. If the session was routine with no significant learnings, respond with exactly: "No significant learnings."`;
|
|
156
|
+
|
|
157
|
+
class LlmRater {
|
|
158
|
+
client;
|
|
159
|
+
name = "llm";
|
|
160
|
+
constructor(client = new ClaudeCliLlmRaterClient) {
|
|
161
|
+
this.client = client;
|
|
162
|
+
}
|
|
163
|
+
async rate(ctx) {
|
|
164
|
+
const enriched = ctx;
|
|
165
|
+
if (enriched.retrievedMemoryIds.length === 0)
|
|
166
|
+
return [];
|
|
167
|
+
const memories = enriched.retrievedMemories;
|
|
168
|
+
if (!memories || memories.length === 0)
|
|
169
|
+
return [];
|
|
170
|
+
const events = [];
|
|
171
|
+
for (const memoryId of enriched.retrievedMemoryIds) {
|
|
172
|
+
const memory = memories.find((m) => m.id === memoryId);
|
|
173
|
+
if (!memory)
|
|
174
|
+
continue;
|
|
175
|
+
let result;
|
|
176
|
+
try {
|
|
177
|
+
result = await this.client.rate({
|
|
178
|
+
query: enriched.query ?? "",
|
|
179
|
+
memory,
|
|
180
|
+
response: enriched.response ?? enriched.evidence ?? ""
|
|
181
|
+
});
|
|
182
|
+
} catch (err) {
|
|
183
|
+
console.error(`[memory-rater:llm] client.rate threw for memoryId=${memoryId}:`, err.message);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (!result)
|
|
187
|
+
continue;
|
|
188
|
+
events.push({
|
|
189
|
+
memoryId,
|
|
190
|
+
signal: 2 * result.score - 1,
|
|
191
|
+
weight: LLM_RATER_WEIGHT,
|
|
192
|
+
source: "",
|
|
193
|
+
reasoning: result.reasoning
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
return events;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function buildRatingsFromLlm(ratings, retrievals) {
|
|
200
|
+
const allowed = new Set(retrievals.map((r) => r.id));
|
|
201
|
+
const events = [];
|
|
202
|
+
for (const r of ratings) {
|
|
203
|
+
if (!allowed.has(r.id))
|
|
204
|
+
continue;
|
|
205
|
+
let cleanedReferencesSource;
|
|
206
|
+
if (r.referencesSource !== undefined) {
|
|
207
|
+
const cleaned = sanitizeReferencesSource(r.referencesSource);
|
|
208
|
+
if (cleaned !== null) {
|
|
209
|
+
cleanedReferencesSource = cleaned;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
events.push({
|
|
213
|
+
memoryId: r.id,
|
|
214
|
+
signal: 2 * r.score - 1,
|
|
215
|
+
weight: LLM_RATER_WEIGHT,
|
|
216
|
+
source: "llm",
|
|
217
|
+
reasoning: r.reasoning,
|
|
218
|
+
...cleanedReferencesSource !== undefined ? { referencesSource: cleanedReferencesSource } : {}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return events;
|
|
222
|
+
}
|
|
223
|
+
var RETRIEVAL_PROMPT_CONTENT_CAP = 600;
|
|
224
|
+
function buildSummaryWithRatingsPrompt(basePrompt, retrievals) {
|
|
225
|
+
if (retrievals.length === 0)
|
|
226
|
+
return basePrompt;
|
|
227
|
+
const memoryBlock = retrievals.map((m, i) => {
|
|
228
|
+
const content = m.content.length > RETRIEVAL_PROMPT_CONTENT_CAP ? `${m.content.slice(0, RETRIEVAL_PROMPT_CONTENT_CAP)}…` : m.content;
|
|
229
|
+
return `Memory #${i + 1}
|
|
230
|
+
id: ${m.id}
|
|
231
|
+
name: ${m.name}
|
|
232
|
+
content: ${content}`;
|
|
233
|
+
}).join(`
|
|
234
|
+
|
|
235
|
+
`);
|
|
236
|
+
return `${basePrompt}
|
|
237
|
+
|
|
238
|
+
CRITICAL: Your entire response MUST be a single JSON object that conforms to the schema below. Do NOT wrap it in triple-backtick fences (no \`\`\`json or \`\`\`), do NOT add a prose preamble, do NOT add trailing commentary. Just the JSON object, nothing else.
|
|
239
|
+
|
|
240
|
+
Schema:
|
|
241
|
+
{
|
|
242
|
+
"summary": string, // your existing summary text
|
|
243
|
+
"ratings": [ // one entry per memory you can score
|
|
244
|
+
{
|
|
245
|
+
"id": string, // memory id, copied from the list below
|
|
246
|
+
"score": number, // 0 = misleading/unhelpful, 1 = highly useful
|
|
247
|
+
"reasoning": string, // 1..500 chars, why
|
|
248
|
+
"referencesSource": string // OPTIONAL — see note below
|
|
249
|
+
}
|
|
250
|
+
]
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
Score ONLY memories present in the list below. Use the exact ids. Omit any you cannot evaluate.
|
|
254
|
+
|
|
255
|
+
Optionally for each rating, if the memory clearly references a specific external source (a GitHub PR/issue, a Linear issue, a customer, a Slack thread, an AgentMail thread, etc.), include a \`referencesSource\` string using the convention "<source>:<identifier>" (e.g. "github:owner/repo#N", "linear:KEY-N", "customer:<slug>"). Any prefix is fine — pick what matches the source. Omit the field if no clear external source.
|
|
256
|
+
|
|
257
|
+
Memories retrieved during this session:
|
|
258
|
+
|
|
259
|
+
${memoryBlock}`;
|
|
260
|
+
}
|
|
261
|
+
function isLlmRaterEnabled() {
|
|
262
|
+
return getMemoryRaterNames().includes("llm");
|
|
263
|
+
}
|
|
264
|
+
function dedupeRetrievalsForRater(rows) {
|
|
265
|
+
const seenSchedules = new Set;
|
|
266
|
+
const out = [];
|
|
267
|
+
for (const row of rows) {
|
|
268
|
+
const scheduleId = row.scheduleId;
|
|
269
|
+
if (typeof scheduleId === "string" && scheduleId.length > 0) {
|
|
270
|
+
if (seenSchedules.has(scheduleId))
|
|
271
|
+
continue;
|
|
272
|
+
seenSchedules.add(scheduleId);
|
|
273
|
+
}
|
|
274
|
+
out.push(row);
|
|
275
|
+
}
|
|
276
|
+
return out;
|
|
277
|
+
}
|
|
278
|
+
async function fetchRetrievalsForTask(opts) {
|
|
279
|
+
const fetchFn = opts.fetchImpl ?? fetch;
|
|
280
|
+
try {
|
|
281
|
+
const url = `${opts.apiUrl}/api/memory/retrievals?taskId=${encodeURIComponent(opts.taskId)}`;
|
|
282
|
+
const res = await fetchFn(url, {
|
|
283
|
+
headers: {
|
|
284
|
+
"X-Agent-ID": opts.agentId,
|
|
285
|
+
...opts.apiKey ? { Authorization: `Bearer ${opts.apiKey}` } : {}
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
if (!res.ok) {
|
|
289
|
+
console.error(`[memory-rater:llm] GET /api/memory/retrievals failed: ${res.status} ${res.statusText}`);
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
const body = await res.json();
|
|
293
|
+
return body.results ?? [];
|
|
294
|
+
} catch (err) {
|
|
295
|
+
console.error("[memory-rater:llm] fetchRetrievalsForTask threw:", err.message);
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async function postRatings(opts) {
|
|
300
|
+
if (opts.events.length === 0)
|
|
301
|
+
return { ok: true, status: 0 };
|
|
302
|
+
const fetchFn = opts.fetchImpl ?? fetch;
|
|
303
|
+
const events = opts.events.map((e) => ({
|
|
304
|
+
memoryId: e.memoryId,
|
|
305
|
+
signal: e.signal,
|
|
306
|
+
weight: e.weight,
|
|
307
|
+
source: e.source,
|
|
308
|
+
...e.reasoning !== undefined ? { reasoning: e.reasoning } : {},
|
|
309
|
+
...e.referencesSource !== undefined ? { referencesSource: e.referencesSource } : {},
|
|
310
|
+
...opts.taskId ? { taskId: opts.taskId } : {}
|
|
311
|
+
}));
|
|
312
|
+
try {
|
|
313
|
+
const res = await fetchFn(`${opts.apiUrl}/api/memory/rate`, {
|
|
314
|
+
method: "POST",
|
|
315
|
+
headers: {
|
|
316
|
+
"Content-Type": "application/json",
|
|
317
|
+
"X-Agent-ID": opts.agentId,
|
|
318
|
+
...opts.apiKey ? { Authorization: `Bearer ${opts.apiKey}` } : {}
|
|
319
|
+
},
|
|
320
|
+
body: JSON.stringify({ events })
|
|
321
|
+
});
|
|
322
|
+
if (!res.ok) {
|
|
323
|
+
const text = await res.text().catch(() => "");
|
|
324
|
+
console.error(`[memory-rater:llm] POST /api/memory/rate failed: ${res.status} ${res.statusText} ${text.slice(0, 200)}`);
|
|
325
|
+
}
|
|
326
|
+
return { ok: res.ok, status: res.status };
|
|
327
|
+
} catch (err) {
|
|
328
|
+
console.error("[memory-rater:llm] postRatings threw:", err.message);
|
|
329
|
+
return { ok: false, status: 0 };
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export { getMemoryRaterNames, REFERENCES_SOURCE_MAX_LENGTH, sanitizeReferencesSource, SummaryWithRatingsSchema, BASE_SUMMARIZE_PROMPT, LlmRater, buildRatingsFromLlm, buildSummaryWithRatingsPrompt, isLlmRaterEnabled, dedupeRetrievalsForRater, fetchRetrievalsForTask, postRatings };
|