@desplega.ai/agent-swarm 1.164.1 → 1.166.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 +1 -1
- package/dist/acp-adapter-yzfxn8vj.js +23 -0
- package/dist/{actions-hp2h32dx.js → actions-qz3m692w.js} +24 -28
- package/dist/{amp-adapter-zfd7djyx.js → amp-adapter-j1xbmsqz.js} +7 -7
- package/dist/{app-w2d26h4f.js → app-43vrdmv8.js} +9 -10
- package/dist/{assistant-45pc4en7.js → assistant-ertffmka.js} +25 -29
- package/dist/{boot-reembed-k1q2s4fc.js → boot-reembed-998jtpdg.js} +12 -15
- package/dist/{boot-reembed-6rhcpsjf.js → boot-reembed-s7k7c6v2.js} +13 -15
- package/dist/boot-scrub-sweep-nepsk4t1.js +211 -0
- package/dist/{boot-seeds-ex93edx7.js → boot-seeds-vvzs1zhk.js} +12 -12
- package/dist/{claude-adapter-hcxd0szm.js → claude-adapter-2zvmekrp.js} +15 -17
- package/dist/{claude-managed-adapter-fz7xps2r.js → claude-managed-adapter-s49wbk8t.js} +5 -5
- package/dist/{claude-managed-setup-xx6f15h9.js → claude-managed-setup-cvhqq8qn.js} +4 -4
- package/dist/{claude-sdk-session-6nb9raem.js → claude-sdk-session-kkbxtw5q.js} +2624 -2606
- package/dist/{cli-etbrt8x1.js → cli-0nhdwxd5.js} +4 -4
- package/dist/{cli-jeefgppq.js → cli-0qjcsxgz.js} +7 -7
- package/dist/{cli-6behs2bt.js → cli-32bca7nr.js} +1 -1
- package/dist/{cli-gt8v96qx.js → cli-3ddybbbx.js} +4 -4
- package/dist/{acp-adapter-rxvek4ym.js → cli-3qn4r334.js} +317 -35
- package/dist/{cli-1d3w4xm3.js → cli-4r1sjfc4.js} +14 -6
- package/dist/{cli-691f2rxm.js → cli-66zh26sp.js} +68 -16
- package/dist/{cli-et8wdyqh.js → cli-68r1j4sg.js} +9 -9
- package/dist/{cli-xb7kyanp.js → cli-8kgvmkak.js} +3 -3
- package/dist/{cli-fdpkw8vk.js → cli-8t229cmr.js} +8 -8
- package/dist/{cli-gc54qc0p.js → cli-aqcey741.js} +1 -1
- package/dist/{cli-4q4cmr4t.js → cli-cpfmqz3n.js} +8 -8
- package/dist/{cli-a9bw0xxt.js → cli-df56tqdw.js} +997 -408
- package/dist/{cli-n7h1kqpf.js → cli-dmtrxqhg.js} +6 -1
- package/dist/{cli-xfb7333f.js → cli-dw2q9f7g.js} +5 -5
- package/dist/{cli-4drstbb9.js → cli-ecknp7p1.js} +81 -23
- package/dist/{cli-v0pvvhfq.js → cli-efnd2kce.js} +36 -1
- package/dist/{cli-1wetf34q.js → cli-f2n17zhp.js} +1 -1
- package/dist/{cli-2c8eky5y.js → cli-feh3dkah.js} +1 -1
- package/dist/cli-fn697bnt.js +126 -0
- package/dist/{cli-v5pr2fgt.js → cli-gt8azyet.js} +3 -3
- package/dist/{cli-dbszf3rw.js → cli-h3x613ze.js} +4 -4
- package/dist/{cli-nwhb8y2e.js → cli-hf5s9pgf.js} +1 -1
- package/dist/cli-j2jbr8af.js +516 -0
- package/dist/{cli-agjzafns.js → cli-jhm6hzjn.js} +593 -10
- package/dist/{cli-j0tmc908.js → cli-jvj6a0cv.js} +484 -477
- package/dist/{cli-xxz89c2n.js → cli-mb75wpxf.js} +1 -1
- package/dist/{cli-07s39g1n.js → cli-mv2520nm.js} +1 -1
- package/dist/{cli-v90vfwyb.js → cli-mwegs4af.js} +5 -5
- package/dist/{cli-bz1gbac9.js → cli-p4ztb80h.js} +2 -2
- package/dist/{cli-1wd1n2ya.js → cli-rfphkzh5.js} +1 -1
- package/dist/{cli-976r1zqx.js → cli-rggdq8wq.js} +5 -5
- package/dist/{cli-3ajw5v5v.js → cli-rsy933yz.js} +6 -6
- package/dist/{cli-yj790e19.js → cli-tadfgd0t.js} +8 -1
- package/dist/{cli-cn53e7vc.js → cli-ttbsse3f.js} +6 -1
- package/dist/{cli-dyqsrqcf.js → cli-v2a8x45d.js} +4 -4
- package/dist/{cli-wbvnn6tk.js → cli-v6vv7dy8.js} +91 -9
- package/dist/{cli-z2ap2c0c.js → cli-vzc73wet.js} +90 -55
- package/dist/cli-wt7ccy4r.js +2654 -0
- package/dist/{cli-4cn19jvn.js → cli-x7kpr72a.js} +3 -3
- package/dist/{cli-003785v9.js → cli-xvc3q9br.js} +1 -1
- package/dist/{cli-v0e7jpr5.js → cli-xvdgasgy.js} +13 -4
- package/dist/{cli-asqeg4ve.js → cli-y59h2pk9.js} +2 -2
- package/dist/{cli-0wn3ypqv.js → cli-yshaazs1.js} +14121 -3478
- package/dist/{cli-wg8yjqtw.js → cli-ysnyhws9.js} +16 -3
- package/dist/cli-zp67qg5x.js +92 -0
- package/dist/{cli-g3qgrzck.js → cli-zsh093hk.js} +71 -3
- package/dist/{cli-ma3zvh39.js → cli-zy7vwsne.js} +6066 -5829
- package/dist/cli.js +79 -26
- package/dist/{codex-adapter-pcxdn10v.js → codex-adapter-dw1wxqt8.js} +10 -10
- package/dist/{codex-hook-b1fb7c2k.js → codex-hook-d2rkvf39.js} +1 -1
- package/dist/{codex-login-059nm145.js → codex-login-terbdsqq.js} +2 -2
- package/dist/{codex-session-runner-xzwwddp8.js → codex-session-runner-3cgb8y1g.js} +10 -10
- package/dist/{commands-98at8mkn.js → commands-mhxam6z2.js} +9 -9
- package/dist/{cursor-adapter-dkg6qnkp.js → cursor-adapter-2qda3st7.js} +6 -6
- package/dist/{db-01g8wtvw.js → db-sjks418k.js} +11 -9
- package/dist/{devin-adapter-qmttt2fz.js → devin-adapter-bffjj5n4.js} +2 -2
- package/dist/{dispatcher-nn2k1wxd.js → dispatcher-1es759rn.js} +22 -26
- package/dist/{dsh-adapter-w4d4vwdq.js → dsh-adapter-bek4cyw9.js} +6 -6
- package/dist/{e2b-9e4g2hvt.js → e2b-nd50eccg.js} +1 -1
- package/dist/{event-bus-z7v2t26e.js → event-bus-vnfthafg.js} +2 -2
- package/dist/grok-adapter-ar9cw9jg.js +29 -0
- package/dist/{handlers-b0kqsbg8.js → handlers-1gkbhktr.js} +25 -29
- package/dist/{hook-sap7v1aj.js → hook-ds2zxq9v.js} +16 -18
- package/dist/{hook-pz50gqep.js → hook-vxa3tcsy.js} +10 -12
- package/dist/{http-ncr8rmd0.js → http-3h21z9md.js} +679 -227
- package/dist/{index-c4aqcyz1.js → index-9b65j1m5.js} +11 -11
- package/dist/{index-r46s01nq.js → index-bn6cy8ps.js} +22 -26
- package/dist/{index-38kqdt3e.js → index-dkfxpkmm.js} +23 -27
- package/dist/{index-630kj5vd.js → index-f8xnqrye.js} +55 -43
- package/dist/{index-fdk1t4d6.js → index-n0rxa4ca.js} +11962 -9900
- package/dist/{index-9nrj7797.js → index-n99fycq7.js} +22 -26
- package/dist/{keepalive-31613r2h.js → keepalive-3xspa9jw.js} +14 -11
- package/dist/{lead-mx59tr5s.js → lead-6qphc124.js} +43 -43
- package/dist/{maintenance-55ff39ca.js → maintenance-0teem1bb.js} +10 -12
- package/dist/{node-f0ykebbv.js → node-9sg7ajby.js} +25 -7
- package/dist/{oauth-refresh-sweep-anma954w.js → oauth-refresh-sweep-sh9q25xp.js} +13 -10
- package/dist/{onboard-b2fy8ftb.js → onboard-54qmnqxe.js} +4 -3
- package/dist/{opencode-adapter-p1s92tmy.js → opencode-adapter-wjfa2wvd.js} +6 -6
- package/dist/{otel-impl-9brvt7xv.js → otel-impl-ycqzp2a1.js} +2 -2
- package/dist/{pi-mono-adapter-kz4rrwvd.js → pi-mono-adapter-e77e9zst.js} +6 -6
- package/dist/{pricing-refresh-7w8mbmva.js → pricing-refresh-atnkngqs.js} +10 -10
- package/dist/{rbac-roles-ejp7qwvb.js → rbac-roles-9pjphh9q.js} +10 -10
- package/dist/{rbac-roles-nhk4r7bc.js → rbac-roles-j78wdksm.js} +10 -10
- package/dist/{render-v2-2gzt8skq.js → render-v2-pxjs49fx.js} +9 -10
- package/dist/{setup-5et8t412.js → setup-ymej0xtx.js} +2 -2
- package/dist/{work-objects-tb0er7qa.js → work-objects-3nh4ymzb.js} +26 -30
- package/dist/{worker-62cv075d.js → worker-qa9fkz5s.js} +43 -43
- package/dist/{x-vbxb31jr.js → x-ma4gnfgy.js} +2 -2
- package/openapi.json +457 -31
- package/package.json +14 -6
- package/plugin/commands/create-pr.md +7 -1
- package/plugin/pi-skills/create-pr/SKILL.md +7 -1
- package/src/agentmail/app.ts +5 -4
- package/src/be/automation-preflight.ts +11 -9
- package/src/be/boot-scrub-sweep.ts +302 -0
- package/src/be/connector-codes.ts +81 -0
- package/src/be/crypto/key-bootstrap.ts +1 -1
- package/src/be/db/approvals.ts +15 -1
- package/src/be/db/codex-oauth-device-flows.ts +40 -0
- package/src/be/db/config-secrets.ts +31 -0
- package/src/be/db/runtime.ts +4 -0
- package/src/be/db/script-runs.ts +15 -0
- package/src/be/db/tasks/write.ts +1 -1
- package/src/be/db-queries/mcp-oauth.ts +5 -0
- package/src/be/db-queries/oauth.ts +77 -0
- package/src/be/db.ts +162 -59
- package/src/be/events.ts +17 -1
- package/src/be/memory/index-content.ts +2 -2
- package/src/be/memory/providers/sqlite-store.ts +63 -11
- package/src/be/memory/types.ts +14 -0
- package/src/be/migrations/197_connector_codes.sql +23 -0
- package/src/be/migrations/198_permission_audit_guest.sql +33 -0
- package/src/be/migrations/200_backfill_auto_memory_expiry.sql +20 -0
- package/src/be/migrations/201_workflow_replay_columns.sql +10 -0
- package/src/be/migrations/202_codex_oauth_device_flows.sql +24 -0
- package/src/be/model-tier-resolution.ts +2 -1
- package/src/be/model-validation.ts +1 -1
- package/src/be/pricing-normalize.ts +3 -0
- package/src/be/rbac-audit.ts +2 -1
- package/src/be/scripts/db.ts +28 -4
- package/src/be/scripts/source-secrets.ts +37 -0
- package/src/be/scripts/typecheck.ts +23 -2
- package/src/be/scrub-json.ts +32 -0
- package/src/be/sealed-json.ts +59 -0
- package/src/be/secret-registry.ts +131 -0
- package/src/be/seed-pricing.ts +14 -0
- package/src/be/users.ts +7 -1
- package/src/be/workflow-replay.ts +77 -0
- package/src/cli.tsx +7 -0
- package/src/commands/provider-credentials.ts +46 -8
- package/src/commands/runner.ts +2 -10
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/github/app.ts +4 -4
- package/src/heartbeat/heartbeat.ts +20 -8
- package/src/hooks/pr-body-guard.ts +1 -1
- package/src/http/agents.ts +1 -0
- package/src/http/approval-requests.ts +1 -0
- package/src/http/apps.ts +3 -0
- package/src/http/auth.ts +4 -1
- package/src/http/codex-oauth-device.ts +8 -10
- package/src/http/codex-oauth-keep-warm.ts +2 -2
- package/src/http/config-values.ts +59 -0
- package/src/http/config.ts +5 -0
- package/src/http/db-query-bounded.ts +3 -0
- package/src/http/db-query-shared.ts +107 -15
- package/src/http/db-query.ts +10 -2
- package/src/http/extensions.ts +1 -0
- package/src/http/index.ts +23 -6
- package/src/http/integrations.ts +1 -38
- package/src/http/ip-rate-limit.ts +82 -0
- package/src/http/kv.ts +38 -4
- package/src/http/mcp-servers.ts +1 -0
- package/src/http/memory.ts +9 -0
- package/src/http/models-catalog.ts +2 -0
- package/src/http/operator-actor.ts +4 -0
- package/src/http/page-proxy.ts +22 -0
- package/src/http/pages.ts +4 -2
- package/src/http/realtime.ts +1 -1
- package/src/http/request-principal.ts +14 -1
- package/src/http/script-connections.ts +8 -0
- package/src/http/script-runs.ts +12 -4
- package/src/http/scripts.ts +15 -0
- package/src/http/session-cost-recompute.ts +3 -2
- package/src/http/tasks.ts +9 -0
- package/src/http/users.ts +226 -0
- package/src/http/workflows.ts +3 -2
- package/src/http.ts +1 -0
- package/src/integrations/kapso/client.ts +3 -1
- package/src/jira/app.ts +2 -2
- package/src/kv-view.ts +324 -0
- package/src/linear/app.ts +2 -2
- package/src/oauth/mcp-wrapper.ts +1 -1
- package/src/prompts/memories.ts +42 -1
- package/src/providers/acp-adapter.ts +85 -24
- package/src/providers/acp-target-catalog.ts +54 -1
- package/src/providers/acp-targets.ts +358 -4
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/cursor-adapter.ts +1 -1
- package/src/providers/grok-adapter.ts +186 -0
- package/src/providers/index.ts +5 -1
- package/src/providers/pricing-sources.md +6 -0
- package/src/providers/reasoning-effort.ts +17 -1
- package/src/providers/types.ts +2 -1
- package/src/rbac/can.ts +4 -3
- package/src/rbac/legacy-policy.ts +3 -3
- package/src/rbac/types.ts +6 -0
- package/src/script-workflows/supervisor.ts +11 -2
- package/src/scripts-runtime/eval-harness.ts +2 -12
- package/src/scripts-runtime/executors/quickjs-bundle.ts +152 -0
- package/src/scripts-runtime/executors/quickjs-prelude.ts +285 -0
- package/src/scripts-runtime/executors/quickjs-runner.ts +580 -0
- package/src/scripts-runtime/executors/quickjs-worker.ts +81 -0
- package/src/scripts-runtime/executors/quickjs.ts +196 -0
- package/src/scripts-runtime/executors/registry.ts +2 -0
- package/src/scripts-runtime/executors/sourcemap.ts +79 -0
- package/src/scripts-runtime/script-error-hints.ts +14 -0
- package/src/scripts-runtime/swarm-sdk.ts +9 -2
- package/src/scripts-runtime/types/stdlib.d.ts +27 -8
- package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +27 -8
- package/src/server-user.ts +2 -20
- package/src/server.ts +3 -1
- package/src/slack/app.ts +4 -0
- package/src/slack/config.ts +3 -1
- package/src/slack/egress-scrub.ts +87 -0
- package/src/tests/acp-adapter.test.ts +191 -2
- package/src/tests/boot-scrub-sweep.test.ts +390 -0
- package/src/tests/budget-user-scope.test.ts +7 -21
- package/src/tests/check-pr-body.test.ts +149 -6
- package/src/tests/check-text-columns.test.ts +145 -0
- package/src/tests/claude-adapter-binary.test.ts +1 -1
- package/src/tests/claude-sdk-process.fixture.ts +13 -2
- package/src/tests/codex-oauth-device.test.ts +23 -37
- package/src/tests/codex-oauth-keep-warm.test.ts +29 -0
- package/src/tests/console-scrub.test.ts +141 -0
- package/src/tests/credential-check.test.ts +90 -0
- package/src/tests/db-query-denylist.test.ts +202 -0
- package/src/tests/db-task-read-contract.test.ts +1 -0
- package/src/tests/db-task-write-contract.test.ts +1 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/entrypoint-acp-target-binary.test.ts +44 -1
- package/src/tests/events-scrub.test.ts +88 -0
- package/src/tests/explicit-model-validation.test.ts +81 -0
- package/src/tests/extensions-pre-task.test.ts +33 -1
- package/src/tests/fixtures/grok/acp-updates-recorded.jsonl +53 -0
- package/src/tests/fixtures/grok/prompt-response-meta.json +36 -0
- package/src/tests/fixtures/secret-corpus.ts +320 -0
- package/src/tests/grok-adapter.test.ts +647 -0
- package/src/tests/heartbeat-checklist.test.ts +44 -0
- package/src/tests/integration-disable-flags.test.ts +156 -0
- package/src/tests/kv-http.test.ts +34 -0
- package/src/tests/kv-tool.test.ts +274 -1
- package/src/tests/kv-view.test.ts +147 -0
- package/src/tests/mcp-user-route.test.ts +257 -15
- package/src/tests/memory-injection-outcome.test.ts +143 -0
- package/src/tests/model-tier-resolution.test.ts +76 -3
- package/src/tests/page-guest-session.test.ts +424 -0
- package/src/tests/page-proxy.test.ts +1 -1
- package/src/tests/page-viewer-auth.test.ts +22 -1
- package/src/tests/pr-body-leaks.test.ts +157 -2
- package/src/tests/preload.ts +10 -0
- package/src/tests/provider-registration.test.ts +3 -1
- package/src/tests/rbac-audit.test.ts +32 -0
- package/src/tests/rbac-mcp-admission-e2e.test.ts +4 -62
- package/src/tests/script-connections.test.ts +9 -0
- package/src/tests/script-executor-conformance.test.ts +3 -0
- package/src/tests/script-executor-quickjs.test.ts +442 -0
- package/src/tests/script-executor-registry.test.ts +6 -1
- package/src/tests/script-runs-http.test.ts +126 -1
- package/src/tests/script-runs-scrub.test.ts +275 -0
- package/src/tests/scripts-http.test.ts +82 -1
- package/src/tests/scripts-mcp-e2e.test.ts +42 -6
- package/src/tests/scripts-runtime.test.ts +37 -0
- package/src/tests/scrubbed-text-12e.test.ts +289 -0
- package/src/tests/sealed-key-guard.test.ts +166 -0
- package/src/tests/secret-canary-sweep.test.ts +958 -0
- package/src/tests/secret-registry.test.ts +355 -0
- package/src/tests/secret-rules.test.ts +230 -0
- package/src/tests/secret-scrubber.test.ts +317 -1
- package/src/tests/session-costs-golden.test.ts +17 -0
- package/src/tests/slack-egress-scrub.test.ts +216 -0
- package/src/tests/swarm-tool-result-gate.test.ts +143 -30
- package/src/tests/task-tools-ctx.test.ts +3 -0
- package/src/tests/user-token-routes.test.ts +342 -3
- package/src/tests/workflow-replay.test.ts +518 -0
- package/src/tests/workflow-scrub.test.ts +242 -0
- package/src/tests/workflow-system-one-decision-providers.test.ts +737 -0
- package/src/tools/db-query.ts +1 -1
- package/src/tools/inject-learning.ts +1 -1
- package/src/tools/kv/kv-get.ts +136 -6
- package/src/tools/send-task.ts +61 -17
- package/src/tools/utils.ts +186 -43
- package/src/tools/workflows/get-workflow-run.ts +3 -2
- package/src/types.ts +16 -1
- package/src/utils/console-scrub-install.ts +5 -0
- package/src/utils/console-scrub.ts +57 -0
- package/src/utils/credentials.ts +8 -0
- package/src/utils/page-session.ts +6 -2
- package/src/utils/pr-body-leaks.ts +149 -10
- package/src/utils/request-auth-context.ts +2 -0
- package/src/utils/secret-rules.generated.ts +2055 -0
- package/src/utils/secret-scrubber.ts +662 -36
- package/src/workflows/engine.ts +39 -4
- package/src/workflows/executors/notify.ts +6 -1
- package/src/workflows/executors/system-one-decision.ts +31 -12
- package/src/workflows/executors/system-one-openai-wire.ts +168 -0
- package/src/workflows/executors/system-one-providers.ts +112 -11
- package/src/workflows/executors/system-one-wire.ts +79 -0
- package/src/workflows/recovery.ts +10 -1
- package/src/workflows/resume.ts +62 -3
- package/src/workflows/retry-poller.ts +3 -0
- package/templates/ai-toolbox.manifest.json +2 -2
- package/templates/skills/agent-browser/SKILL.md +5 -5
- package/templates/skills/agent-browser/config.json +1 -1
- package/templates/skills/agent-browser/content.md +4 -4
- package/templates/skills/artifacts/content.md +17 -7
- package/templates/skills/jira-interaction/config.json +1 -1
- package/templates/skills/jira-interaction/content.md +56 -205
- package/templates/skills/linear-interaction/config.json +1 -1
- package/templates/skills/linear-interaction/content.md +31 -50
- package/templates/skills/pages/content.md +8 -4
- package/templates/skills/qa/content.md +2 -2
- package/templates/skills/workflow-iterate/content.md +4 -4
- package/tsconfig.json +3 -3
- package/dist/boot-scrub-logs-t8xg7wd7.js +0 -99
- package/dist/cli-0a7r5331.js +0 -168
- package/dist/cli-93rxw9yd.js +0 -951
- package/dist/cli-cvk6yzw5.js +0 -40
- package/dist/cli-dgnj0zcc.js +0 -40
- package/dist/cli-qt5wzq6v.js +0 -256
- package/dist/cli-v7fqehqd.js +0 -9281
- package/dist/cli-vbr859rz.js +0 -572
- package/src/be/boot-scrub-logs.ts +0 -132
package/src/tools/db-query.ts
CHANGED
|
@@ -26,7 +26,7 @@ export const registerDbQueryTool = (server: McpServer) => {
|
|
|
26
26
|
{
|
|
27
27
|
title: "Execute database query",
|
|
28
28
|
description:
|
|
29
|
-
"Execute a read-only SQL query against the swarm database (SQLite). Available to all authenticated agents
|
|
29
|
+
"Execute a read-only SQL query against the swarm database (SQLite). Available to all authenticated agents. Queries that read credential tables (OAuth authorizations, apps and pending flows, user and session tokens, script API bearers, Codex device-login state) are rejected, and secret-shaped values in results are redacted. Runs in a short-lived child process with a wall-clock budget by default (fails gracefully with a timeout or a 429-style concurrency error rather than freezing); results capped at a default row count (operator-configurable via `DB_QUERY_MCP_MAX_ROWS`) regardless of how many the query matched. See the sql parameter's description for which tables are unsafe to read whole, and the db-query-guidance skill for config knobs.",
|
|
30
30
|
annotations: { readOnlyHint: true },
|
|
31
31
|
inputSchema: DbQueryToolInputSchema,
|
|
32
32
|
outputSchema: swarmToolOutputSchema({
|
|
@@ -73,7 +73,7 @@ export const registerInjectLearningTool = (server: McpServer) => {
|
|
|
73
73
|
// Generate and store embedding (async, best-effort)
|
|
74
74
|
try {
|
|
75
75
|
const provider = getEmbeddingProvider();
|
|
76
|
-
const embedding = await provider.embed(content);
|
|
76
|
+
const embedding = await provider.embed(memory.content);
|
|
77
77
|
if (embedding) {
|
|
78
78
|
await store.updateEmbedding(memory.id, embedding, provider.name);
|
|
79
79
|
}
|
package/src/tools/kv/kv-get.ts
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { getKv } from "@/be/db";
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
hasKvViewArgs,
|
|
6
|
+
joinKvPath,
|
|
7
|
+
KV_PATH_MAX_CHARS,
|
|
8
|
+
type KvView,
|
|
9
|
+
resolveKvTarget,
|
|
10
|
+
resolveKvView,
|
|
11
|
+
sliceKvTarget,
|
|
12
|
+
} from "@/kv-view";
|
|
13
|
+
import {
|
|
14
|
+
createToolRegistrar,
|
|
15
|
+
MCP_RESULT_WIRE_LIMIT_BYTES,
|
|
16
|
+
type SwarmToolResult,
|
|
17
|
+
swarmToolOutputSchema,
|
|
18
|
+
swarmToolResultBytes,
|
|
19
|
+
toolErr,
|
|
20
|
+
toolOk,
|
|
21
|
+
} from "@/tools/utils";
|
|
22
|
+
import { type KvEntry, KvKeySchema, KvNamespaceSchema, KvValueTypeSchema } from "@/types";
|
|
6
23
|
import { kvReadAuthError } from "./kv-read-auth";
|
|
7
24
|
import { resolveNamespace } from "./resolve-namespace";
|
|
8
25
|
|
|
@@ -28,13 +45,102 @@ function renderKvEntry(entry: {
|
|
|
28
45
|
return `value (${entry.valueType}): ${valueText}${expiry}`;
|
|
29
46
|
}
|
|
30
47
|
|
|
48
|
+
const kvViewOutputSchema = z.looseObject({
|
|
49
|
+
path: z.string().optional(),
|
|
50
|
+
type: z.string().optional(),
|
|
51
|
+
total: z.number().optional(),
|
|
52
|
+
offset: z.number().optional(),
|
|
53
|
+
returned: z.number().optional(),
|
|
54
|
+
nextOffset: z.number().nullable().optional(),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
function describeView(view: KvView): string {
|
|
58
|
+
const target = view.path ? `"${view.path}"` : "the value";
|
|
59
|
+
if (view.total === undefined) return `${target} (${view.type})`;
|
|
60
|
+
const unit =
|
|
61
|
+
view.type === "array" ? "items" : view.type === "object" ? "keys" : "chars (JSON-encoded)";
|
|
62
|
+
const offset = view.offset ?? 0;
|
|
63
|
+
return `${target} ${unit} ${offset}..${offset + (view.returned ?? 0)} of ${view.total}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A targeted read shrunk to the per-channel MCP budget. kv-get is spill-exempt,
|
|
68
|
+
* so the tool bounds its own views: the page shrinks (binary search on items,
|
|
69
|
+
* keys, or chars) and `view.nextOffset` says where to resume.
|
|
70
|
+
*/
|
|
71
|
+
function boundedView(
|
|
72
|
+
entry: KvEntry,
|
|
73
|
+
agentId: string | undefined,
|
|
74
|
+
args: { path?: string; offset?: number; limit?: number },
|
|
75
|
+
): SwarmToolResult {
|
|
76
|
+
const { namespace, key } = entry;
|
|
77
|
+
const failed = (error: string) => toolErr(error, { data: { yourAgentId: agentId, namespace } });
|
|
78
|
+
// Validates path and offset/limit applicability; the page itself is sized below.
|
|
79
|
+
const checked = resolveKvView(entry.value, args);
|
|
80
|
+
if (!checked.ok) return failed(checked.error);
|
|
81
|
+
const target = resolveKvTarget(entry.value, args.path ?? "");
|
|
82
|
+
if (!target.ok) return failed(target.error);
|
|
83
|
+
|
|
84
|
+
const { value: _value, ...meta } = entry;
|
|
85
|
+
// Strings go out JSON-encoded too: the wire composer trims `details`, which
|
|
86
|
+
// would drop a slice's edge whitespace and erase a whitespace-only slice.
|
|
87
|
+
const render = (value: unknown, view: KvView) =>
|
|
88
|
+
toolOk(`Read ${describeView(view)} from "${key}" in "${namespace}".`, {
|
|
89
|
+
details: JSON.stringify(value),
|
|
90
|
+
data: { yourAgentId: agentId, namespace, entry: meta, view },
|
|
91
|
+
});
|
|
92
|
+
const baseView = checked.view;
|
|
93
|
+
if (baseView.total === undefined) return render(checked.value, baseView);
|
|
94
|
+
|
|
95
|
+
const offset = baseView.offset ?? 0;
|
|
96
|
+
const wanted = Math.min(args.limit ?? baseView.total, Math.max(0, baseView.total - offset));
|
|
97
|
+
const firstKey =
|
|
98
|
+
baseView.type === "array"
|
|
99
|
+
? String(offset)
|
|
100
|
+
: baseView.type === "object"
|
|
101
|
+
? Object.keys(target.value as object)[offset]
|
|
102
|
+
: undefined;
|
|
103
|
+
// An empty key or an over-long path cannot be passed back as `path`.
|
|
104
|
+
const firstPath =
|
|
105
|
+
firstKey === undefined || firstKey === ""
|
|
106
|
+
? undefined
|
|
107
|
+
: `${baseView.path ? `${baseView.path}.` : ""}${joinKvPath([firstKey])}`;
|
|
108
|
+
const narrowTo = firstPath !== undefined && firstPath.length <= KV_PATH_MAX_CHARS;
|
|
109
|
+
// A shrunk page carries its note, so the note is part of what gets sized.
|
|
110
|
+
const page = (count: number) => {
|
|
111
|
+
const sliced = sliceKvTarget(target.value, offset, count);
|
|
112
|
+
const result = render(sliced?.value, {
|
|
113
|
+
...baseView,
|
|
114
|
+
returned: sliced?.returned ?? 0,
|
|
115
|
+
nextOffset: sliced?.nextOffset ?? null,
|
|
116
|
+
});
|
|
117
|
+
if (count >= wanted) return result;
|
|
118
|
+
const note =
|
|
119
|
+
count === 0 && narrowTo
|
|
120
|
+
? ` The entry at offset ${offset} alone exceeds the ${MCP_RESULT_WIRE_LIMIT_BYTES}-byte cap; narrow the path to "${firstPath}".`
|
|
121
|
+
: ` Page shrunk to fit the ${MCP_RESULT_WIRE_LIMIT_BYTES}-byte cap; continue at view.nextOffset.`;
|
|
122
|
+
return { ...result, message: `${result.message}${note}` };
|
|
123
|
+
};
|
|
124
|
+
const fits = (count: number) => swarmToolResultBytes(page(count)) <= MCP_RESULT_WIRE_LIMIT_BYTES;
|
|
125
|
+
if (fits(wanted)) return page(wanted);
|
|
126
|
+
|
|
127
|
+
let low = 0;
|
|
128
|
+
let high = wanted;
|
|
129
|
+
while (low < high) {
|
|
130
|
+
const mid = Math.ceil((low + high) / 2);
|
|
131
|
+
if (fits(mid)) low = mid;
|
|
132
|
+
else high = mid - 1;
|
|
133
|
+
}
|
|
134
|
+
return page(low);
|
|
135
|
+
}
|
|
136
|
+
|
|
31
137
|
export const registerKvGetTool = (server: McpServer) => {
|
|
32
138
|
createToolRegistrar(server)(
|
|
33
139
|
"kv-get",
|
|
34
140
|
{
|
|
35
141
|
title: "KV Get",
|
|
36
142
|
description:
|
|
37
|
-
"Read a key from the swarm KV store. Returns the entry or null if missing/expired. Namespace defaults to your current context (Slack thread / PR / Linear issue when invoked from a task; otherwise your agent scratchpad).",
|
|
143
|
+
"Read a key from the swarm KV store. Returns the entry or null if missing/expired. Namespace defaults to your current context (Slack thread / PR / Linear issue when invoked from a task; otherwise your agent scratchpad). Without path/offset/limit the whole value comes back unbounded. With any of them you get a bounded view (≤10KB per channel): `path` is a dot path into a JSON value (string entries holding JSON, such as spilled tool results, count as JSON; numeric segments index arrays, e.g. `outcome.data.rows` or `rows.3`; escape a dot inside a key as `\\.`), and `offset`/`limit` page the array items, object keys, or string characters found there. The result's `view.nextOffset` says where the next page starts.",
|
|
38
144
|
annotations: { readOnlyHint: true },
|
|
39
145
|
|
|
40
146
|
inputSchema: z.object({
|
|
@@ -42,14 +148,34 @@ export const registerKvGetTool = (server: McpServer) => {
|
|
|
42
148
|
namespace: KvNamespaceSchema.optional().describe(
|
|
43
149
|
"Optional explicit namespace. Defaults to the caller's contextKey.",
|
|
44
150
|
),
|
|
151
|
+
path: z
|
|
152
|
+
.string()
|
|
153
|
+
.max(KV_PATH_MAX_CHARS)
|
|
154
|
+
.optional()
|
|
155
|
+
.describe(
|
|
156
|
+
'Dot path into the JSON value, e.g. "outcome.data.rows" or "rows.3". "" is the whole value. A dot inside a key is escaped as "\\.".',
|
|
157
|
+
),
|
|
158
|
+
offset: z
|
|
159
|
+
.number()
|
|
160
|
+
.int()
|
|
161
|
+
.nonnegative()
|
|
162
|
+
.optional()
|
|
163
|
+
.describe("First array item / object key / string char to return. Default 0."),
|
|
164
|
+
limit: z
|
|
165
|
+
.number()
|
|
166
|
+
.int()
|
|
167
|
+
.positive()
|
|
168
|
+
.optional()
|
|
169
|
+
.describe("Max items / keys / chars to return; the page also shrinks to fit the cap."),
|
|
45
170
|
}),
|
|
46
171
|
outputSchema: swarmToolOutputSchema({
|
|
47
172
|
yourAgentId: z.string().optional(),
|
|
48
173
|
namespace: z.string().optional(),
|
|
49
174
|
entry: kvEntryOutputSchema.nullable().optional(),
|
|
175
|
+
view: kvViewOutputSchema.optional(),
|
|
50
176
|
}),
|
|
51
177
|
},
|
|
52
|
-
async ({ key, namespace }, requestInfo) => {
|
|
178
|
+
async ({ key, namespace, path, offset, limit }, requestInfo) => {
|
|
53
179
|
const resolved = await resolveNamespace(namespace, requestInfo);
|
|
54
180
|
if ("error" in resolved) {
|
|
55
181
|
return toolErr(resolved.error, { data: { yourAgentId: requestInfo.agentId } });
|
|
@@ -62,9 +188,13 @@ export const registerKvGetTool = (server: McpServer) => {
|
|
|
62
188
|
}
|
|
63
189
|
|
|
64
190
|
// kv-get is exempt from the ctx-control spill (see CTX_CONTROL_EXEMPT_TOOLS):
|
|
65
|
-
// it is the retrieval path for spilled values
|
|
66
|
-
// whole and the harness applies its own truncation
|
|
191
|
+
// it is the retrieval path for spilled values. Without view args oversized
|
|
192
|
+
// entries go out whole and the harness applies its own truncation; with
|
|
193
|
+
// path/offset/limit the tool bounds the page itself.
|
|
67
194
|
const entry = await getKv(resolved.namespace, key);
|
|
195
|
+
if (entry && hasKvViewArgs({ path, offset, limit })) {
|
|
196
|
+
return boundedView(entry, requestInfo.agentId, { path, offset, limit });
|
|
197
|
+
}
|
|
68
198
|
return toolOk(
|
|
69
199
|
entry
|
|
70
200
|
? `Found "${key}" in "${resolved.namespace}".`
|
package/src/tools/send-task.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
getActiveTaskCount,
|
|
12
12
|
getAgentById,
|
|
13
13
|
getDbClient,
|
|
14
|
+
getLeadAgent,
|
|
14
15
|
getTaskById,
|
|
15
16
|
getUserById,
|
|
16
17
|
hasCapacity,
|
|
@@ -289,11 +290,28 @@ export async function sendTaskHandler(
|
|
|
289
290
|
outputSchema,
|
|
290
291
|
}: SendTaskArgs,
|
|
291
292
|
): Promise<SwarmToolResult> {
|
|
293
|
+
const userLead = ctx.kind === "user" ? await getLeadAgent() : null;
|
|
294
|
+
if (ctx.kind === "user" && (!userLead || userLead.status === "offline")) {
|
|
295
|
+
return toolErr("No online Lead is available. Start or register a Lead before sending a task.");
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const requestedAgentId = ctx.kind === "user" ? userLead!.id : agentId;
|
|
299
|
+
const requestedRoutingReason = ctx.kind === "user" ? "skill" : routingReason;
|
|
300
|
+
const requestedRoutingNote =
|
|
301
|
+
ctx.kind === "user"
|
|
302
|
+
? "User MCP ingress assigns new work to the Lead for delegation."
|
|
303
|
+
: routingNote;
|
|
304
|
+
const requestedOfferMode = ctx.kind === "user" ? false : offerMode;
|
|
305
|
+
const requestedLeadOnly = ctx.kind === "user" ? false : leadOnly;
|
|
306
|
+
const requestedCapabilities = ctx.kind === "user" ? undefined : requiredCapabilities;
|
|
307
|
+
const requestedAllowDuplicate = ctx.kind === "user" ? false : allowDuplicate;
|
|
308
|
+
const requestedOverrideSlackContext = ctx.kind === "user" ? false : overrideSlackContext;
|
|
309
|
+
|
|
292
310
|
// Defense in depth for direct TypeScript callers that bypass MCP schema parsing.
|
|
293
|
-
if (
|
|
311
|
+
if (requestedAgentId !== undefined && requestedRoutingReason === undefined) {
|
|
294
312
|
return toolErr("routingReason is required when agentId is supplied.");
|
|
295
313
|
}
|
|
296
|
-
if (
|
|
314
|
+
if (requestedAgentId !== undefined && (requestedRoutingNote?.trim().length ?? 0) < 10) {
|
|
297
315
|
return toolErr(
|
|
298
316
|
"routingNote is required when agentId is supplied (at least 10 characters after trim).",
|
|
299
317
|
);
|
|
@@ -337,7 +355,7 @@ export async function sendTaskHandler(
|
|
|
337
355
|
});
|
|
338
356
|
}
|
|
339
357
|
|
|
340
|
-
if (ctx.kind === "owner" &&
|
|
358
|
+
if (ctx.kind === "owner" && requestedAgentId === ctx.agentId) {
|
|
341
359
|
return toolErr("Cannot send a task to yourself, are you drunk?", {
|
|
342
360
|
data: { yourAgentId: ctx.agentId },
|
|
343
361
|
});
|
|
@@ -358,7 +376,10 @@ export async function sendTaskHandler(
|
|
|
358
376
|
}
|
|
359
377
|
// A public continuation cannot accidentally declassify its parent before
|
|
360
378
|
// createTaskExtended performs the authoritative merge.
|
|
361
|
-
const effectiveLeadOnly =
|
|
379
|
+
const effectiveLeadOnly =
|
|
380
|
+
ctx.kind === "user"
|
|
381
|
+
? false
|
|
382
|
+
: requestedLeadOnly || effectiveParentTask?.routingAffinity?.leadOnly === true;
|
|
362
383
|
|
|
363
384
|
// Slack-routing coherence guard: reject a hand-typed slackChannelId/slackThreadTs
|
|
364
385
|
// that disagrees with the parent task or the contextKey this child will inherit.
|
|
@@ -367,7 +388,7 @@ export async function sendTaskHandler(
|
|
|
367
388
|
// dispatch-slack-channel-must-match-parent-context-2026-07-10). Omitting the
|
|
368
389
|
// three Slack fields lets inheritance do the right thing; overrideSlackContext
|
|
369
390
|
// opts into a deliberate cross-channel dispatch.
|
|
370
|
-
if (!
|
|
391
|
+
if (!requestedOverrideSlackContext) {
|
|
371
392
|
// send-task never passes contextKey explicitly, so the child inherits the
|
|
372
393
|
// parent's contextKey verbatim (createTaskExtended, src/be/db.ts:3556-3558).
|
|
373
394
|
const inheritedContextKey = effectiveParentTask?.contextKey;
|
|
@@ -406,8 +427,8 @@ export async function sendTaskHandler(
|
|
|
406
427
|
}
|
|
407
428
|
|
|
408
429
|
// Auto-route to parent's worker if parentTaskId is set and no explicit agentId
|
|
409
|
-
let effectiveAgentId =
|
|
410
|
-
if (effectiveParentTaskId && !
|
|
430
|
+
let effectiveAgentId = requestedAgentId;
|
|
431
|
+
if (effectiveParentTaskId && !requestedAgentId) {
|
|
411
432
|
if (effectiveParentTask?.agentId) {
|
|
412
433
|
effectiveAgentId = effectiveParentTask.agentId;
|
|
413
434
|
}
|
|
@@ -421,15 +442,25 @@ export async function sendTaskHandler(
|
|
|
421
442
|
});
|
|
422
443
|
if (modelError) return toolErr(modelError, { data: { yourAgentId: creatorAgentId } });
|
|
423
444
|
const effectiveRoutingReason =
|
|
424
|
-
|
|
425
|
-
|
|
445
|
+
requestedAgentId !== undefined
|
|
446
|
+
? requestedRoutingReason
|
|
447
|
+
: effectiveAgentId
|
|
448
|
+
? "continuity"
|
|
449
|
+
: undefined;
|
|
450
|
+
const effectiveRoutingNote = effectiveRoutingReason ? requestedRoutingNote : undefined;
|
|
426
451
|
const effectiveRoutingSource =
|
|
427
|
-
|
|
452
|
+
ctx.kind === "user"
|
|
453
|
+
? "engine_default"
|
|
454
|
+
: requestedAgentId !== undefined
|
|
455
|
+
? "declared"
|
|
456
|
+
: effectiveAgentId
|
|
457
|
+
? "engine_default"
|
|
458
|
+
: undefined;
|
|
428
459
|
|
|
429
460
|
const requestedTaskOptions: CreateTaskOptions = {
|
|
430
461
|
key: assetKey,
|
|
431
|
-
agentId:
|
|
432
|
-
offeredTo:
|
|
462
|
+
agentId: requestedOfferMode ? undefined : effectiveAgentId,
|
|
463
|
+
offeredTo: requestedOfferMode ? effectiveAgentId : undefined,
|
|
433
464
|
creatorAgentId,
|
|
434
465
|
requestedByUserId,
|
|
435
466
|
source: "mcp",
|
|
@@ -447,7 +478,7 @@ export async function sendTaskHandler(
|
|
|
447
478
|
slackChannelId,
|
|
448
479
|
slackThreadTs,
|
|
449
480
|
slackUserId,
|
|
450
|
-
overrideSlackContext,
|
|
481
|
+
overrideSlackContext: requestedOverrideSlackContext,
|
|
451
482
|
followUpConfig,
|
|
452
483
|
// A delegation with parentTaskId is new work and starts without the
|
|
453
484
|
// parent's followUpConfig. A `resume` re-delegation (the reroute-decision
|
|
@@ -458,8 +489,8 @@ export async function sendTaskHandler(
|
|
|
458
489
|
routingSource: effectiveRoutingSource,
|
|
459
490
|
routingNote: effectiveRoutingNote,
|
|
460
491
|
routingAffinity:
|
|
461
|
-
effectiveLeadOnly ||
|
|
462
|
-
? { leadOnly: effectiveLeadOnly, capabilities:
|
|
492
|
+
effectiveLeadOnly || requestedCapabilities?.length
|
|
493
|
+
? { leadOnly: effectiveLeadOnly, capabilities: requestedCapabilities ?? [] }
|
|
463
494
|
: undefined,
|
|
464
495
|
};
|
|
465
496
|
const preCreate = await applyPreTaskCreate({
|
|
@@ -477,6 +508,12 @@ export async function sendTaskHandler(
|
|
|
477
508
|
}
|
|
478
509
|
const taskDescription = preCreate.description;
|
|
479
510
|
const taskOptions = preCreate.options;
|
|
511
|
+
if (
|
|
512
|
+
ctx.kind === "user" &&
|
|
513
|
+
(taskOptions.agentId !== userLead!.id || taskOptions.offeredTo !== undefined)
|
|
514
|
+
) {
|
|
515
|
+
return toolErr("A pre.task.create extension cannot change the user task's Lead assignment.");
|
|
516
|
+
}
|
|
480
517
|
|
|
481
518
|
// The three dedup guards are pure reads, so they run twice: once here as a
|
|
482
519
|
// fast path (keeping this tool's existing early-exit responses), and once
|
|
@@ -500,7 +537,7 @@ export async function sendTaskHandler(
|
|
|
500
537
|
}
|
|
501
538
|
|
|
502
539
|
// Dedup guard: check for similar recent tasks
|
|
503
|
-
if (!
|
|
540
|
+
if (!requestedAllowDuplicate && creatorAgentId) {
|
|
504
541
|
const duplicate = await findDuplicateTask({
|
|
505
542
|
taskDescription,
|
|
506
543
|
creatorAgentId: taskOptions.creatorAgentId ?? creatorAgentId,
|
|
@@ -616,6 +653,13 @@ export async function sendTaskHandler(
|
|
|
616
653
|
};
|
|
617
654
|
}
|
|
618
655
|
|
|
656
|
+
if (ctx.kind === "user" && (!agent.isLead || agent.status === "offline")) {
|
|
657
|
+
return {
|
|
658
|
+
success: false,
|
|
659
|
+
message: "The Lead is no longer online. No task was created.",
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
|
|
619
663
|
if (isExtensionAgent(agent)) {
|
|
620
664
|
return { success: false, message: extensionAgentAssignmentError(agent) };
|
|
621
665
|
}
|
|
@@ -628,7 +672,7 @@ export async function sendTaskHandler(
|
|
|
628
672
|
}
|
|
629
673
|
|
|
630
674
|
// For direct assignment (not offer), check if agent has capacity
|
|
631
|
-
if (!taskOptions.offeredTo && !(await hasCapacity(targetAgentId))) {
|
|
675
|
+
if (ctx.kind !== "user" && !taskOptions.offeredTo && !(await hasCapacity(targetAgentId))) {
|
|
632
676
|
const activeCount = await getActiveTaskCount(targetAgentId);
|
|
633
677
|
return {
|
|
634
678
|
success: false,
|