@desplega.ai/agent-swarm 1.173.0 → 2.0.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-ccm9xrep.js → acp-adapter-sj2g0m84.js} +17 -16
- package/dist/{actions-sgeyv08k.js → actions-fegk44gr.js} +39 -34
- package/dist/{amp-adapter-gpxp3kc9.js → amp-adapter-ad8ft89x.js} +8 -7
- package/dist/{app-km9qnv2f.js → app-kfvgbvzy.js} +18 -14
- package/dist/{assistant-5r8tcvvd.js → assistant-z7zdy9ja.js} +40 -35
- package/dist/{boot-reembed-swwzdgd7.js → boot-reembed-5c2z0mbe.js} +10 -9
- package/dist/{boot-reembed-16rv9843.js → boot-reembed-j8xa181e.js} +10 -9
- package/dist/{boot-scrub-sweep-zkr6vkqb.js → boot-scrub-sweep-hnkn3rgt.js} +11 -10
- package/dist/{boot-seeds-d8sp49t2.js → boot-seeds-kwjq4d2z.js} +14 -13
- package/dist/{claude-adapter-yzzzh8jp.js → claude-adapter-9vmvpvgd.js} +19 -18
- package/dist/{claude-managed-adapter-xgxhqrt2.js → claude-managed-adapter-k9qae05j.js} +7 -5
- package/dist/{claude-managed-setup-bnmjarjc.js → claude-managed-setup-q54zx5q2.js} +6 -4
- package/dist/{claude-sdk-session-4whxere4.js → claude-sdk-session-9jye6cxr.js} +11881 -11472
- package/dist/{cli-94b48jhk.js → cli-03gedhng.js} +16 -14
- package/dist/{cli-1w0vj3gw.js → cli-1e4b6bzh.js} +7 -7
- package/dist/{cli-d603qf86.js → cli-29jc5q7w.js} +10 -8
- package/dist/cli-2m1ktfzz.js +17795 -0
- package/dist/{cli-x119kdba.js → cli-3dj8k4vy.js} +1 -1
- package/dist/{cli-srqq3gc5.js → cli-3fbmmawm.js} +5 -5
- package/dist/{cli-gmdajfw5.js → cli-4jxm2qtz.js} +4987 -1708
- package/dist/{cli-tadfgd0t.js → cli-5hkm7whv.js} +33 -4
- package/dist/{cli-42qhyvwx.js → cli-5t4f29ez.js} +3 -3
- package/dist/{cli-7a0sde2x.js → cli-6cagzc96.js} +9 -0
- package/dist/cli-6cvfxs8r.js +47 -0
- package/dist/{cli-0kxf81jj.js → cli-6jyj59nb.js} +2 -2
- package/dist/{cli-w1apjecb.js → cli-6razj6t4.js} +2 -2
- package/dist/{cli-anzdk0z4.js → cli-74ahz61x.js} +2 -2
- package/dist/{cli-m89t9jdf.js → cli-7x0g4sn1.js} +15416 -16024
- package/dist/{cli-yatxqynm.js → cli-9ha6hs2d.js} +1 -290
- package/dist/{cli-81r1wjyv.js → cli-9nfx44eh.js} +1 -1
- package/dist/cli-9traj3dn.js +638 -0
- package/dist/{cli-smcrrmhy.js → cli-agzebbd5.js} +9 -9
- package/dist/{cli-na2pxe4f.js → cli-apx87jne.js} +2 -2
- package/dist/{cli-rfz2ve55.js → cli-bzszjf2p.js} +2855 -862
- package/dist/{cli-c5km5znr.js → cli-c8r3kzzb.js} +1 -1
- package/dist/{cli-hsem16hb.js → cli-cgtksawx.js} +7 -4
- package/dist/{cli-db3m6zdt.js → cli-d2qr7aj4.js} +1 -1
- package/dist/{cli-rfs4vddv.js → cli-d5f9ed5c.js} +5 -5
- package/dist/cli-e3g5mbkz.js +776 -0
- package/dist/{cli-7jykv7ef.js → cli-e6mpjhed.js} +1 -1
- package/dist/{cli-7a93cv8c.js → cli-ee9gtz70.js} +98 -23
- package/dist/{cli-3nxdmjrc.js → cli-eejsgvm4.js} +4 -4
- package/dist/{cli-fmhj1ehj.js → cli-ef1hg1wv.js} +470 -51
- package/dist/cli-f527ce74.js +781 -0
- package/dist/{cli-ppy4nnnh.js → cli-f7kr7svz.js} +2 -2
- package/dist/cli-hjwmhcg1.js +10622 -0
- package/dist/{cli-2bw3w47j.js → cli-hnhtk6cj.js} +1 -1
- package/dist/{cli-ywm1azg9.js → cli-hnmhtzvh.js} +6 -4
- package/dist/{cli-h7k0xtry.js → cli-hvqbtna4.js} +4 -1256
- package/dist/{cli-s8z6x4b4.js → cli-j0pfptdp.js} +218 -102
- package/dist/cli-jta2eyzc.js +619 -0
- package/dist/{cli-5er5gjbm.js → cli-k382tshb.js} +10 -11
- package/dist/{cli-v3zhnxsb.js → cli-k3dp5tpf.js} +2 -2
- package/dist/{cli-wd0hz6ah.js → cli-kbrt8gqa.js} +9 -91
- package/dist/cli-kceah1eh.js +92 -0
- package/dist/{cli-ne7smj1b.js → cli-ke896fcf.js} +10 -10
- package/dist/{cli-xc7p7s3g.js → cli-kt6zqg0e.js} +6 -6
- package/dist/{cli-wrh08zjd.js → cli-m50t4309.js} +5 -18
- package/dist/cli-n2wq4j7m.js +6985 -0
- package/dist/{cli-bv2etw2y.js → cli-n3hzg89b.js} +46 -15
- package/dist/{cli-tmhsxhb8.js → cli-n5vwg842.js} +23 -6
- package/dist/{cli-qm1448f9.js → cli-ne236afy.js} +8 -8
- package/dist/{cli-d161g69q.js → cli-p1x85d2t.js} +50 -2
- package/dist/{cli-7pz3b7x5.js → cli-przpmdgr.js} +25 -0
- package/dist/{cli-0a7mm3zp.js → cli-q0ke1yww.js} +25 -21
- package/dist/{cli-e3pmyt39.js → cli-q50942rs.js} +1 -1
- package/dist/{cli-r44t9wqc.js → cli-r106725k.js} +2 -2
- package/dist/{cli-phcqp1b9.js → cli-r2pnvj8g.js} +2 -2
- package/dist/{cli-jpc4r224.js → cli-r62a35ea.js} +19 -3
- package/dist/{cli-cd0hv9nh.js → cli-ra0xzggj.js} +2 -2
- package/dist/cli-rhs9pz33.js +294 -0
- package/dist/{cli-r4fqfpwf.js → cli-s2sp957d.js} +50 -27
- package/dist/{cli-1x7da0de.js → cli-s4setq91.js} +8 -8
- package/dist/{cli-6thk4jz3.js → cli-se8w6wny.js} +6 -6
- package/dist/cli-skxvvpap.js +10140 -0
- package/dist/{cli-014vns2y.js → cli-stfs0k5s.js} +208 -525
- package/dist/{cli-0p3enk35.js → cli-tqaazemc.js} +9 -1
- package/dist/{cli-nwrdx840.js → cli-tr4sxp68.js} +3 -3
- package/dist/{cli-r0byd61h.js → cli-tsde1hdr.js} +15 -15
- package/dist/{cli-b07hr3bt.js → cli-txqb9s38.js} +2 -2
- package/dist/{cli-6r2f7edk.js → cli-v1yb0rqb.js} +6 -6
- package/dist/{cli-saqyage0.js → cli-vatyhshy.js} +179 -27
- package/dist/{cli-5wpw4rab.js → cli-vdach5a9.js} +5 -5
- package/dist/{cli-7avy4v8w.js → cli-w1q7h2r2.js} +5 -3
- package/dist/{cli-rcp5aqdw.js → cli-w7m81tb7.js} +1 -1
- package/dist/{cli-c3rk1v0x.js → cli-wayw93nt.js} +3 -3
- package/dist/cli-wmgrkscj.js +23254 -0
- package/dist/{cli-9xf7fdtp.js → cli-z5jjpaxw.js} +29 -6
- package/dist/{cli-451ks6aw.js → cli-zkpks3r3.js} +1 -1
- package/dist/cli.js +29 -45
- package/dist/{codex-adapter-r3dn4fp5.js → codex-adapter-y81sssk0.js} +15 -14
- package/dist/{codex-login-841kv5fk.js → codex-login-f2rcfpp9.js} +3 -2
- package/dist/{codex-session-runner-fwt793h4.js → codex-session-runner-8vx4j6a9.js} +15 -14
- package/dist/{commands-z8fq9qna.js → commands-kcpvpcrr.js} +11 -10
- package/dist/{controller-hq5ggpcp.js → controller-ywrmt6yd.js} +5 -4
- package/dist/{controllers-connect-3mf2btyj.js → controllers-connect-kwpvj3rf.js} +42 -37
- package/dist/{cursor-adapter-q8pgv5qa.js → cursor-adapter-cehv1qns.js} +7 -6
- package/dist/{db-yyhqqrbf.js → db-k8ankj20.js} +12 -11
- package/dist/{db-qfpq4bt7.js → db-ww5d7jq3.js} +28 -9
- package/dist/{devin-adapter-xgtj680j.js → devin-adapter-x1022qb1.js} +3 -2
- package/dist/{dispatcher-x0x7qfcq.js → dispatcher-e8gq5m68.js} +38 -33
- package/dist/{docker-f503k9p0.js → docker-ff6y1190.js} +3 -2
- package/dist/{dsh-adapter-34etvb5m.js → dsh-adapter-3epjm3af.js} +7 -6
- package/dist/{e2b-66xra4az.js → e2b-8ygwhg0f.js} +4 -3
- package/dist/{e2b-xwhyj8cw.js → e2b-swhnpw3n.js} +4 -3
- package/dist/{event-bus-vjtv82gm.js → event-bus-6axnngdj.js} +3 -2
- package/dist/{external-channel-h1fjecwe.js → external-channel-h3359cwn.js} +11 -10
- package/dist/{google-generative-ai-szdxbpqg.js → google-generative-ai-g8db7x0f.js} +4 -2
- package/dist/{google-vertex-qzw3p36d.js → google-vertex-r2692q0r.js} +4 -2
- package/dist/{grok-adapter-e7mr287e.js → grok-adapter-0d4x7gkx.js} +18 -17
- package/dist/{handlers-znb9n7d4.js → handlers-an1gzv21.js} +41 -36
- package/dist/{heartbeat-bm4qkn8d.js → heartbeat-6dakeb61.js} +43 -38
- package/dist/{hook-254r4mza.js → hook-6v6cv6d5.js} +11 -23
- package/dist/{hook-xaa3q80s.js → hook-sa5xye4y.js} +12 -11
- package/dist/{http-3dgrgp8y.js → http-r7f3eky0.js} +1499 -251
- package/dist/index-52j1aja4.js +3465 -0
- package/dist/{index-fx3jqq1e.js → index-7ep4gzdk.js} +38 -33
- package/dist/index-9gw58n4k.js +193 -0
- package/dist/index-9j87mcm8.js +56305 -0
- package/dist/index-bsmcresk.js +79424 -0
- package/dist/index-mh85qhec.js +475 -0
- package/dist/{index-g2byveez.js → index-rmpw9a8q.js} +38 -33
- package/dist/{index-2ybk7khy.js → index-s2wxgzr0.js} +468 -683
- package/dist/{index-bdsqa799.js → index-v1v6n7hg.js} +43 -38
- package/dist/index-we27kd31.js +12810 -0
- package/dist/{index-jd7sejm2.js → index-zk96aq1k.js} +10 -9
- package/dist/{keepalive-6ywhpja1.js → keepalive-be9vwy5h.js} +12 -11
- package/dist/{lead-cw45n21s.js → lead-0861cwrf.js} +61 -56
- package/dist/{maintenance-ss1a1ge9.js → maintenance-mzzgc8bn.js} +10 -9
- package/dist/{node-fkajaq96.js → node-mn1zs7an.js} +2 -1
- package/dist/{oauth-refresh-sweep-3c6f8vyy.js → oauth-refresh-sweep-cpdnfwdj.js} +11 -10
- package/dist/{onboard-8hzdhc1k.js → onboard-fh8qs4r3.js} +11 -3
- package/dist/{opencode-adapter-qbchbcfz.js → opencode-adapter-nm42wwj8.js} +18 -13
- package/dist/{otel-impl-e6mnvc4v.js → otel-impl-x6c1c9g4.js} +242 -868
- package/dist/{pi-mono-adapter-3c9g9snh.js → pi-mono-adapter-9n2ya240.js} +244 -106
- package/dist/{pricing-refresh-gedkjdw0.js → pricing-refresh-qb0rv0ap.js} +12 -11
- package/dist/{rbac-roles-dt4vh1yy.js → rbac-roles-1gzdwbh1.js} +11 -10
- package/dist/{rbac-roles-eszdg6pm.js → rbac-roles-3mraey52.js} +12 -11
- package/dist/{render-v2-907cy6sa.js → render-v2-agpa45zz.js} +18 -14
- package/dist/{resume-42stcaz0.js → resume-x0ydy9s9.js} +25 -21
- package/dist/{runtime-qfry88v2.js → runtime-sa2vr16g.js} +2 -2
- package/dist/{setup-adbc1c10.js → setup-as9ga0d6.js} +2 -2
- package/dist/{virtual-modules-rtmt494q.js → virtual-modules-9gkxqrap.js} +6 -5
- package/dist/{work-objects-wpj8ck95.js → work-objects-y5g1y7ev.js} +41 -36
- package/dist/{worker-bzdra9rf.js → worker-860c3e38.js} +61 -56
- package/dist/{x-qfmygqqv.js → x-m477fr0h.js} +3 -2
- package/openapi.json +523 -344
- package/package.json +10 -11
- package/src/be/config-refs.ts +60 -0
- package/src/be/db/page-versions.ts +15 -0
- package/src/be/db/runtime.ts +35 -8
- package/src/be/db/skill-name-resolution.ts +36 -0
- package/src/be/db/tasks/read.ts +230 -0
- package/src/be/db/tasks/write.ts +7 -0
- package/src/be/db.ts +52 -7
- package/src/be/migrations/215_swarm_config_export_to_env.sql +34 -0
- package/src/be/migrations/216_task_resolved_effort.sql +5 -0
- package/src/be/migrations/217_chat_sdk_state.sql +104 -0
- package/src/be/model-catalog-store.ts +5 -1
- package/src/be/model-tier-resolution.ts +12 -1
- package/src/be/model-validation.ts +5 -2
- package/src/be/models-catalog.ts +26 -1
- package/src/be/modelsdev-cache.json +198 -63
- package/src/be/modelsdev-cache.ts +9 -1
- package/src/be/script-credential-broker.ts +39 -2
- package/src/be/scripts/run-saved.ts +1 -0
- package/src/be/scripts/typecheck.ts +10 -8
- package/src/be/seed/runner.ts +13 -1
- package/src/be/seed/state-db.ts +5 -0
- package/src/be/seed/types.ts +6 -0
- package/src/be/seed-pricing.ts +19 -2
- package/src/be/seed-scripts/catalog/ops-catalog-audit.inline.ts +1 -1
- package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +1 -1
- package/src/be/seed-skills/bundled-files.generated.json +0 -18
- package/src/be/seed-skills/index.ts +104 -3
- package/src/be/swarm-config-guard.ts +52 -0
- package/src/cli.tsx +0 -16
- package/src/commands/onboard/non-interactive.ts +4 -2
- package/src/commands/provider-credentials.ts +52 -6
- package/src/commands/runner.ts +190 -54
- package/src/e2b/env.ts +5 -0
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/extensions/contract.ts +45 -0
- package/src/extensions/dispatcher.ts +7 -0
- package/src/extensions/post-bridge.ts +40 -0
- package/src/github/handlers.ts +11 -4
- package/src/heartbeat/templates.ts +8 -5
- package/src/hooks/hook.ts +0 -26
- package/src/http/all-routes.ts +0 -1
- package/src/http/config.ts +36 -17
- package/src/http/core.ts +4 -0
- package/src/http/index.ts +14 -2
- package/src/http/integrations.ts +88 -1
- package/src/http/mcp.ts +15 -5
- package/src/http/page-proxy.ts +2 -4
- package/src/http/pages-public.ts +3 -3
- package/src/http/pages.ts +3 -13
- package/src/http/poll.ts +28 -68
- package/src/http/requested-by.ts +54 -0
- package/src/http/scripts.ts +1 -0
- package/src/http/stats.ts +1 -30
- package/src/http/tasks.ts +61 -5
- package/src/http/utils.ts +14 -0
- package/src/http/webhooks.ts +159 -1
- package/src/http/x.ts +1 -0
- package/src/integrations/chat-sdk/adapters.ts +129 -0
- package/src/integrations/chat-sdk/attachments.ts +232 -0
- package/src/integrations/chat-sdk/background.ts +36 -0
- package/src/integrations/chat-sdk/commands.ts +194 -0
- package/src/integrations/chat-sdk/config.ts +198 -0
- package/src/integrations/chat-sdk/discord-api.ts +63 -0
- package/src/integrations/chat-sdk/discord-gateway.ts +185 -0
- package/src/integrations/chat-sdk/handlers.ts +28 -0
- package/src/integrations/chat-sdk/inbound.ts +426 -0
- package/src/integrations/chat-sdk/limits.ts +48 -0
- package/src/integrations/chat-sdk/logger.ts +81 -0
- package/src/integrations/chat-sdk/outbound.ts +123 -0
- package/src/integrations/chat-sdk/relay.ts +172 -0
- package/src/integrations/chat-sdk/router.ts +169 -0
- package/src/integrations/chat-sdk/runtime.ts +351 -0
- package/src/integrations/chat-sdk/schema.ts +245 -0
- package/src/integrations/chat-sdk/state.ts +243 -0
- package/src/integrations/chat-sdk/status.ts +244 -0
- package/src/integrations/chat-sdk/steering.ts +58 -0
- package/src/integrations/chat-sdk/teams-origin.ts +77 -0
- package/src/integrations/chat-sdk/telegram-api.ts +56 -0
- package/src/integrations/chat-sdk/templates.ts +16 -0
- package/src/integrations/chat-sdk/test-hooks.ts +37 -0
- package/src/integrations/chat-sdk/thread-buffer.ts +100 -0
- package/src/integrations/chat-sdk/typing.ts +65 -0
- package/src/pages/version.ts +4 -5
- package/src/prompts/base-prompt.ts +111 -45
- package/src/providers/acp-target-catalog.ts +6 -0
- package/src/providers/acp-targets.ts +55 -2
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/claude-adapter.ts +1 -1
- package/src/providers/claude-flag-settings.ts +17 -5
- package/src/providers/claude-managed-adapter.ts +1 -1
- package/src/providers/claude-session-events.ts +6 -1
- package/src/providers/dsh-adapter.ts +1 -1
- package/src/providers/opencode-adapter.ts +243 -26
- package/src/providers/opencode-swarm-plugin.ts +31 -0
- package/src/providers/pi-mono-adapter.ts +398 -153
- package/src/providers/pricing-sources.md +33 -2
- package/src/providers/reasoning-effort.ts +27 -0
- package/src/providers/types.ts +6 -2
- package/src/rbac/legacy-policy.ts +8 -2
- package/src/rbac/permissions.ts +21 -0
- package/src/scheduler/scheduler.ts +4 -2
- package/src/scripts-runtime/loader.ts +19 -7
- package/src/scripts-runtime/sdk-allowlist.ts +8 -6
- package/src/scripts-runtime/swarm-sdk.ts +0 -11
- package/src/scripts-runtime/types/stdlib.d.ts +27 -15
- package/src/scripts-runtime/types/swarm-extension.d.ts +63 -1
- package/src/scripts-runtime/types/swarm-sdk.d.ts +27 -15
- package/src/server.ts +52 -18
- package/src/slack/event-dedup.ts +1 -1
- package/src/tasks/additive-buffer.ts +4 -2
- package/src/tasks/context-key.ts +60 -1
- package/src/tasks/model-pin.ts +67 -0
- package/src/tasks/worker-follow-up.ts +4 -31
- package/src/tests/acp-adapter.test.ts +42 -0
- package/src/tests/api-drain-worker-e2e.test.ts +1 -6
- package/src/tests/base-prompt.test.ts +58 -54
- package/src/tests/chat-sdk-commands.test.ts +191 -0
- package/src/tests/chat-sdk-config.test.ts +334 -0
- package/src/tests/chat-sdk-discord-api.test.ts +68 -0
- package/src/tests/chat-sdk-discord-gateway.test.ts +252 -0
- package/src/tests/chat-sdk-discord-webhook.test.ts +126 -0
- package/src/tests/chat-sdk-fields-sync.test.ts +50 -0
- package/src/tests/chat-sdk-harness.ts +146 -0
- package/src/tests/chat-sdk-inbound.test.ts +363 -0
- package/src/tests/chat-sdk-relay.test.ts +470 -0
- package/src/tests/chat-sdk-reload.test.ts +128 -0
- package/src/tests/chat-sdk-shutdown.test.ts +220 -0
- package/src/tests/chat-sdk-slack.test.ts +268 -0
- package/src/tests/chat-sdk-state.test.ts +163 -0
- package/src/tests/chat-sdk-status-route.test.ts +382 -0
- package/src/tests/chat-sdk-teams.test.ts +277 -0
- package/src/tests/chat-sdk-tools.test.ts +520 -0
- package/src/tests/chat-sdk-typing.test.ts +120 -0
- package/src/tests/chat-sdk-webhook-telegram.test.ts +200 -0
- package/src/tests/claude-adapter-binary.test.ts +9 -4
- package/src/tests/claude-flag-settings.test.ts +11 -3
- package/src/tests/claude-managed-adapter.test.ts +1 -1
- package/src/tests/claude-sdk-lifecycle.test.ts +9 -3
- package/src/tests/claude-thinking-tokens.test.ts +57 -0
- package/src/tests/claude-worker-parity.test.ts +2 -7
- package/src/tests/config-env-export-chat-sdk.test.ts +11 -0
- package/src/tests/config-refs.test.ts +66 -0
- package/src/tests/context-key.test.ts +19 -0
- package/src/tests/cors-allowlist.test.ts +25 -0
- package/src/tests/create-page-tool.test.ts +18 -0
- package/src/tests/credential-check.test.ts +139 -0
- package/src/tests/credentials.test.ts +21 -0
- package/src/tests/db-runtime.test.ts +61 -0
- package/src/tests/db-task-read-contract.test.ts +20 -0
- package/src/tests/db-task-write-contract.test.ts +10 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/dsh-adapter.test.ts +1 -1
- package/src/tests/enabled-capabilities.test.ts +20 -0
- package/src/tests/entrypoint-api-readiness.test.ts +14 -8
- package/src/tests/entrypoint-config-env-export.test.ts +5 -2
- package/src/tests/entrypoint-export-to-env.test.ts +78 -0
- package/src/tests/explicit-model-validation.test.ts +105 -1
- package/src/tests/extensions-example-route-chat-channel.test.ts +154 -0
- package/src/tests/extensions-post-bridge.test.ts +51 -0
- package/src/tests/fetch-resolved-env.test.ts +128 -0
- package/src/tests/fixtures/chat-sdk/telegram-private-text.json +10 -0
- package/src/tests/fixtures/extensions/route-chat-channel-to-agent/hooks.ts +27 -0
- package/src/tests/fixtures/extensions/route-chat-channel-to-agent/manifest.json +9 -0
- package/src/tests/fixtures/openai-compatible-registry-extension.child.ts +146 -0
- package/src/tests/fixtures/runner-legacy-resume-prompt.ts +122 -0
- package/src/tests/github-handlers.test.ts +35 -0
- package/src/tests/harness-provider-resolution.test.ts +12 -0
- package/src/tests/heartbeat-checklist.test.ts +3 -2
- package/src/tests/hook-runtime-close.test.ts +0 -2
- package/src/tests/http-api-integration.test.ts +0 -25
- package/src/tests/migration-046-budgets.test.ts +17 -16
- package/src/tests/migration-217-chat-sdk-state.test.ts +113 -0
- package/src/tests/model-tier-resolution.test.ts +93 -0
- package/src/tests/models-catalog.test.ts +42 -1
- package/src/tests/openai-compatible-providers.test.ts +134 -0
- package/src/tests/openai-compatible-registry-extension.test.ts +42 -0
- package/src/tests/opencode-adapter.test.ts +216 -2
- package/src/tests/opencode-helmcode-sdk.test.ts +201 -0
- package/src/tests/opencode-shell-env.test.ts +145 -0
- package/src/tests/openrouter-base-url.test.ts +101 -151
- package/src/tests/page-proxy.test.ts +1 -1
- package/src/tests/pages-browser-sdk.test.ts +76 -0
- package/src/tests/pages-feedback.test.ts +1 -1
- package/src/tests/paused-tasks-requested-by.test.ts +102 -0
- package/src/tests/pi-custom-provider-fake-server.test.ts +442 -0
- package/src/tests/pi-mono-adapter.test.ts +385 -5
- package/src/tests/pi-shell-env.test.ts +170 -0
- package/src/tests/prompt-template-remaining.test.ts +35 -0
- package/src/tests/rbac-engine.test.ts +11 -3
- package/src/tests/runner-exit-after-tasks.test.ts +0 -4
- package/src/tests/runner-legacy-resume-prompt.test.ts +64 -0
- package/src/tests/script-connections.test.ts +2 -0
- package/src/tests/scripts-http.test.ts +201 -1
- package/src/tests/scripts-only-gating.test.ts +2 -3
- package/src/tests/scripts-runtime.test.ts +58 -40
- package/src/tests/secret-scrubber.test.ts +86 -0
- package/src/tests/seed-skills-bundled-files.test.ts +45 -53
- package/src/tests/seed-skills-retire.test.ts +182 -0
- package/src/tests/send-task-requester-gate.test.ts +58 -0
- package/src/tests/session-cost-recompute-unit.test.ts +46 -0
- package/src/tests/skill-get-name-resolution.test.ts +137 -0
- package/src/tests/sonnet-5-5-registry.test.ts +9 -1
- package/src/tests/swarm-config-export-to-env.test.ts +267 -0
- package/src/tests/swarm-config-reserved-keys.test.ts +16 -0
- package/src/tests/swarm-diff.test.ts +1 -1
- package/src/tests/task-model-effort-rerun.test.ts +164 -0
- package/src/tests/task-session-prompts.test.ts +132 -0
- package/src/tests/task-tool-manifest.test.ts +14 -0
- package/src/tests/task-tools-ctx.test.ts +2 -0
- package/src/tests/tool-annotations.test.ts +6 -6
- package/src/tests/ui-logs-parser.test.ts +43 -0
- package/src/tests/used-by-route.test.ts +6 -0
- package/src/tests/vercel-ai-gateway.test.ts +149 -0
- package/src/tests/workflow-swarm-script.test.ts +38 -0
- package/src/tests/workflow-wait-filter.test.ts +5 -3
- package/src/tools/chat-access.ts +41 -0
- package/src/tools/chat-open-dm.ts +59 -0
- package/src/tools/chat-post.ts +74 -0
- package/src/tools/chat-read-thread.ts +100 -0
- package/src/tools/chat-reply.ts +75 -0
- package/src/tools/create-page.ts +3 -13
- package/src/tools/model-catalog/index.ts +2 -1
- package/src/tools/register-chat-channel.ts +139 -0
- package/src/tools/send-task.ts +24 -0
- package/src/tools/skills/skill-get.ts +17 -9
- package/src/tools/swarm-config/get-config.ts +2 -1
- package/src/tools/swarm-config/list-config.ts +2 -1
- package/src/tools/swarm-config/set-config.ts +16 -3
- package/src/tools/tool-config.ts +8 -6
- package/src/types.ts +12 -2
- package/src/utils/config-env-export.ts +74 -0
- package/src/utils/credentials.test.ts +92 -0
- package/src/utils/credentials.ts +52 -4
- package/src/utils/harness-provider.ts +15 -6
- package/src/utils/runtime-model-catalog.ts +11 -1
- package/src/utils/secret-scrubber.ts +71 -2
- package/src/utils/task-tool-manifest.ts +19 -2
- package/src/workflows/executors/swarm-script.ts +1 -0
- package/templates/skills/agent-browser/SKILL.md +1 -1
- package/templates/skills/agent-browser/content.md +1 -1
- package/templates/skills/apps/SKILL.md +8 -1
- package/templates/skills/apps/content.md +8 -1
- package/templates/skills/chat-sdk/config.json +14 -0
- package/templates/skills/chat-sdk/content.md +84 -0
- package/templates/skills/composio-gmail/content.md +7 -0
- package/templates/skills/composio-google-docs/content.md +1 -1
- package/templates/skills/email-domain-health/config.json +14 -0
- package/templates/skills/email-domain-health/content.md +131 -0
- package/templates/skills/kv-storage/content.md +2 -2
- package/templates/skills/pages/content.md +8 -10
- package/templates/skills/swarm-extensions/content.md +2 -0
- package/templates/skills/swarm-scripts/SKILL.md +4 -2
- package/templates/skills/swarm-scripts/config.json +1 -1
- package/templates/skills/swarm-scripts/content.md +4 -2
- package/templates/skills/workflow-iterate/content.md +38 -0
- package/dist/artifact-eczsknc3.js +0 -3843
- package/dist/cli-bd957dgb.js +0 -153
- package/dist/cli-q51yprfq.js +0 -1104
- package/dist/cli-t1ze64h3.js +0 -811
- package/dist/cli-tcc4wd5d.js +0 -56471
- package/dist/index-9ch1n761.js +0 -1102
- package/src/artifact-sdk/index.ts +0 -2
- package/src/artifact-sdk/localtunnel.d.ts +0 -20
- package/src/artifact-sdk/port.ts +0 -12
- package/src/artifact-sdk/server.ts +0 -183
- package/src/artifact-sdk/tunnel.ts +0 -19
- package/src/commands/artifact.ts +0 -249
- package/src/http/ecosystem.ts +0 -77
- package/src/tests/artifact-commands.test.ts +0 -92
- package/src/tests/artifact-sdk.test.ts +0 -793
- package/src/tests/register-service-security.test.ts +0 -194
- package/src/tools/list-services.ts +0 -107
- package/src/tools/register-service.ts +0 -177
- package/src/tools/unregister-service.ts +0 -73
- package/src/tools/update-service-status.ts +0 -96
- package/templates/skills/artifacts/config.json +0 -14
- package/templates/skills/artifacts/content.md +0 -344
- package/templates/skills/artifacts/files/examples/approval-flow.ts +0 -34
- package/templates/skills/artifacts/files/examples/hono-dashboard.ts +0 -31
- package/templates/skills/artifacts/files/examples/multi-artifact.ts +0 -20
- package/templates/skills/artifacts/files/examples/static-report.sh +0 -17
- /package/src/{artifact-sdk → pages}/browser-sdk.ts +0 -0
- /package/src/{artifact-sdk → pages}/feedback-overlay.ts +0 -0
package/src/be/db.ts
CHANGED
|
@@ -136,6 +136,12 @@ import {
|
|
|
136
136
|
CODEX_AUTH_WATCH_NAMESPACE,
|
|
137
137
|
codexAuthBenchMarkerKey,
|
|
138
138
|
} from "../utils/codex-auth-failure";
|
|
139
|
+
import {
|
|
140
|
+
defaultExportToEnv,
|
|
141
|
+
effectiveExportToEnv,
|
|
142
|
+
envExportRestrictedError,
|
|
143
|
+
isEnvExportRestrictedKey,
|
|
144
|
+
} from "../utils/config-env-export";
|
|
139
145
|
import { MASKED_SECRET_VALUE } from "../utils/config-secrets";
|
|
140
146
|
import { deriveProviderFromKeyType } from "../utils/credentials";
|
|
141
147
|
import type { RateLimitWindowTelemetry } from "../utils/error-tracker";
|
|
@@ -205,7 +211,12 @@ import { scrubJsonValue } from "./scrub-json";
|
|
|
205
211
|
import { openSealedJson, sealedJsonForDisplay, sealJson } from "./sealed-json";
|
|
206
212
|
import { configSecretName, registerStoredSecret } from "./secret-registry";
|
|
207
213
|
import { promotePendingSteeringForTask } from "./steering";
|
|
208
|
-
import {
|
|
214
|
+
import {
|
|
215
|
+
isInternalConfigKey,
|
|
216
|
+
isReservedConfigKey,
|
|
217
|
+
reservedKeyError,
|
|
218
|
+
teamsSdkEnvKeysSql,
|
|
219
|
+
} from "./swarm-config-guard";
|
|
209
220
|
import { emitTaskStarted } from "./task-lifecycle-events";
|
|
210
221
|
import { publishWorkerConfigNudge, publishWorkerNudge } from "./worker-nudges";
|
|
211
222
|
import { defineWorkflowPayload, type WorkflowPayloadView } from "./workflow-replay";
|
|
@@ -292,17 +303,21 @@ export {
|
|
|
292
303
|
findTaskByGitHub,
|
|
293
304
|
findTaskByVcs,
|
|
294
305
|
getAgentCurrentTask,
|
|
306
|
+
getAgentWorkingOnContextKey,
|
|
295
307
|
getAgentWorkingOnThread,
|
|
296
308
|
getAllTasks,
|
|
297
309
|
getChildTasks,
|
|
298
310
|
getCompletedSlackTasks,
|
|
299
311
|
getInProgressSlackTasks,
|
|
300
312
|
getInProgressTasksByContextKey,
|
|
313
|
+
getLatestActiveTaskByContextKey,
|
|
301
314
|
getLatestActiveTaskInThread,
|
|
315
|
+
getLatestLeadTaskByContextKey,
|
|
302
316
|
getLatestLeadTaskInThread,
|
|
303
317
|
getLatestScriptRunStepTaskByContextKey,
|
|
304
318
|
getLatestTaskByContextKey,
|
|
305
319
|
getMostRecentTaskInThread,
|
|
320
|
+
getPendingChatRelayTasks,
|
|
306
321
|
getPendingSlackRelayTasks,
|
|
307
322
|
getRecentlyFinishedWorkerTasks,
|
|
308
323
|
getSlackTasksMissingTree,
|
|
@@ -313,13 +328,19 @@ export {
|
|
|
313
328
|
getTasksByAgentId,
|
|
314
329
|
getTasksByStatus,
|
|
315
330
|
getTasksCount,
|
|
331
|
+
giveUpStaleChatRelays,
|
|
316
332
|
hasNonTerminalRerouteDecisionChild,
|
|
317
333
|
hasNonTerminalResumeChild,
|
|
318
334
|
isLinearTrackerContextKey,
|
|
335
|
+
markChatRelayAttempted,
|
|
336
|
+
markChatRelayDelivered,
|
|
337
|
+
markChatRelayGivenUp,
|
|
319
338
|
markFinalizedSlackRelaysDelivered,
|
|
320
339
|
markSlackRelayAttempted,
|
|
321
340
|
markSlackRelayDelivered,
|
|
322
341
|
markTasksNotified,
|
|
342
|
+
type PendingChatRelay,
|
|
343
|
+
recordChatRelayError,
|
|
323
344
|
resetTasksNotified,
|
|
324
345
|
type TaskFilters,
|
|
325
346
|
} from "./db/tasks/read";
|
|
@@ -4375,7 +4396,8 @@ export async function releaseStaleMentionProcessing(timeoutMinutes: number = 30)
|
|
|
4375
4396
|
}
|
|
4376
4397
|
|
|
4377
4398
|
// ============================================================================
|
|
4378
|
-
// Service Operations (PM2
|
|
4399
|
+
// Service Operations (removed PM2 service registry; the table and these
|
|
4400
|
+
// accessors stay until a drop migration lands)
|
|
4379
4401
|
// ============================================================================
|
|
4380
4402
|
|
|
4381
4403
|
type ServiceRow = {
|
|
@@ -6342,6 +6364,7 @@ type SwarmConfigRow = {
|
|
|
6342
6364
|
createdAt: string;
|
|
6343
6365
|
lastUpdatedAt: string;
|
|
6344
6366
|
encrypted: number; // SQLite boolean: 0 = plaintext, 1 = AES-256-GCM ciphertext
|
|
6367
|
+
exportToEnv?: number; // SQLite boolean; absent only on pre-215 test schemas
|
|
6345
6368
|
};
|
|
6346
6369
|
|
|
6347
6370
|
type SwarmConfigLookupRow = {
|
|
@@ -6370,6 +6393,7 @@ function rowToSwarmConfig(row: SwarmConfigRow): SwarmConfig {
|
|
|
6370
6393
|
createdAt: row.createdAt,
|
|
6371
6394
|
lastUpdatedAt: row.lastUpdatedAt,
|
|
6372
6395
|
encrypted: isEncrypted,
|
|
6396
|
+
exportToEnv: effectiveExportToEnv(row.key, row.exportToEnv !== 0),
|
|
6373
6397
|
};
|
|
6374
6398
|
}
|
|
6375
6399
|
|
|
@@ -6396,6 +6420,7 @@ function rowToSwarmConfig(row: SwarmConfigRow): SwarmConfig {
|
|
|
6396
6420
|
createdAt: row.createdAt,
|
|
6397
6421
|
lastUpdatedAt: row.lastUpdatedAt,
|
|
6398
6422
|
encrypted: isEncrypted,
|
|
6423
|
+
exportToEnv: effectiveExportToEnv(row.key, row.exportToEnv !== 0),
|
|
6399
6424
|
};
|
|
6400
6425
|
}
|
|
6401
6426
|
|
|
@@ -6550,7 +6575,7 @@ export async function getInjectableGlobalConfigs(): Promise<SwarmConfig[]> {
|
|
|
6550
6575
|
const rows = await getDbClient().query<SwarmConfigRow>(
|
|
6551
6576
|
`SELECT * FROM swarm_config
|
|
6552
6577
|
WHERE scope = 'global'
|
|
6553
|
-
AND UPPER(key) NOT IN ('API_KEY', 'SECRETS_ENCRYPTION_KEY', 'CORS_ALLOW_ANY_ORIGIN', 'EXTENSION_ALLOW_LEAD_ACTIVATION')
|
|
6578
|
+
AND UPPER(key) NOT IN ('API_KEY', 'SECRETS_ENCRYPTION_KEY', 'CORS_ALLOW_ANY_ORIGIN', 'EXTENSION_ALLOW_LEAD_ACTIVATION', 'CHAT_SDK_API_URL_OVERRIDES', ${teamsSdkEnvKeysSql()})
|
|
6554
6579
|
ORDER BY key ASC`,
|
|
6555
6580
|
);
|
|
6556
6581
|
return rows.filter((row) => !isInternalConfigKey(row.key)).map(rowToSwarmConfig);
|
|
@@ -6604,10 +6629,16 @@ export async function upsertSwarmConfig(data: {
|
|
|
6604
6629
|
isSecret?: boolean;
|
|
6605
6630
|
envPath?: string | null;
|
|
6606
6631
|
description?: string | null;
|
|
6632
|
+
/** Omitted: an update keeps the stored flag; an insert uses `defaultExportToEnv`. */
|
|
6633
|
+
exportToEnv?: boolean;
|
|
6607
6634
|
}): Promise<SwarmConfig> {
|
|
6608
6635
|
if (isReservedConfigKey(data.key)) {
|
|
6609
6636
|
throw reservedKeyError(data.key);
|
|
6610
6637
|
}
|
|
6638
|
+
if (data.exportToEnv === true && isEnvExportRestrictedKey(data.key)) {
|
|
6639
|
+
throw new Error(envExportRestrictedError(data.key));
|
|
6640
|
+
}
|
|
6641
|
+
const restricted = isEnvExportRestrictedKey(data.key);
|
|
6611
6642
|
|
|
6612
6643
|
const now = new Date().toISOString();
|
|
6613
6644
|
const scopeId = data.scope === "global" ? null : (data.scopeId ?? null);
|
|
@@ -6641,17 +6672,30 @@ export async function upsertSwarmConfig(data: {
|
|
|
6641
6672
|
);
|
|
6642
6673
|
|
|
6643
6674
|
if (existing) {
|
|
6675
|
+
// COALESCE keeps the stored flag when the caller did not send one.
|
|
6644
6676
|
return await getDbClient().get<SwarmConfigRow>(
|
|
6645
|
-
`UPDATE swarm_config SET value = ?, isSecret = ?, envPath = ?, description = ?, encrypted = ?, lastUpdatedAt =
|
|
6677
|
+
`UPDATE swarm_config SET value = ?, isSecret = ?, envPath = ?, description = ?, encrypted = ?, lastUpdatedAt = ?,
|
|
6678
|
+
exportToEnv = CASE WHEN ? THEN 0 ELSE COALESCE(?, exportToEnv) END
|
|
6646
6679
|
WHERE id = ? RETURNING *`,
|
|
6647
|
-
[
|
|
6680
|
+
[
|
|
6681
|
+
storedValue,
|
|
6682
|
+
isSecret,
|
|
6683
|
+
envPath,
|
|
6684
|
+
description,
|
|
6685
|
+
encryptedFlag,
|
|
6686
|
+
now,
|
|
6687
|
+
restricted ? 1 : 0,
|
|
6688
|
+
data.exportToEnv === undefined ? null : data.exportToEnv ? 1 : 0,
|
|
6689
|
+
existing.id,
|
|
6690
|
+
],
|
|
6648
6691
|
);
|
|
6649
6692
|
}
|
|
6650
6693
|
|
|
6651
6694
|
const id = crypto.randomUUID();
|
|
6695
|
+
const exportToEnv = restricted ? 0 : (data.exportToEnv ?? defaultExportToEnv(data.key)) ? 1 : 0;
|
|
6652
6696
|
return await getDbClient().get<SwarmConfigRow>(
|
|
6653
|
-
`INSERT INTO swarm_config (id, scope, scopeId, key, value, isSecret, envPath, description, createdAt, lastUpdatedAt, encrypted)
|
|
6654
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`,
|
|
6697
|
+
`INSERT INTO swarm_config (id, scope, scopeId, key, value, isSecret, envPath, description, createdAt, lastUpdatedAt, encrypted, exportToEnv)
|
|
6698
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`,
|
|
6655
6699
|
[
|
|
6656
6700
|
id,
|
|
6657
6701
|
data.scope,
|
|
@@ -6664,6 +6708,7 @@ export async function upsertSwarmConfig(data: {
|
|
|
6664
6708
|
now,
|
|
6665
6709
|
now,
|
|
6666
6710
|
encryptedFlag,
|
|
6711
|
+
exportToEnv,
|
|
6667
6712
|
],
|
|
6668
6713
|
);
|
|
6669
6714
|
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
-- Per-row flag: does this swarm_config row reach an agent's process env?
|
|
2
|
+
-- Workers export a row into the harness env (and so into every agent shell)
|
|
3
|
+
-- only when exportToEnv = 1. Rows with 0 stay server-side and are used through
|
|
4
|
+
-- connections or script credential bindings.
|
|
5
|
+
--
|
|
6
|
+
-- Existing rows keep today's behaviour (exported), so nothing breaks at deploy.
|
|
7
|
+
ALTER TABLE swarm_config ADD COLUMN exportToEnv INTEGER NOT NULL DEFAULT 1;
|
|
8
|
+
|
|
9
|
+
-- Deny list: rows only the API server reads. The first block matches
|
|
10
|
+
-- ENV_EXPORT_RESTRICTED_KEYS in src/utils/config-env-export.ts (never
|
|
11
|
+
-- exportable); the second block (ENV_EXPORT_DEFAULT_OFF_KEYS, also the insert
|
|
12
|
+
-- default for new rows) is off by default but operators may turn it
|
|
13
|
+
-- back on per row.
|
|
14
|
+
UPDATE swarm_config SET exportToEnv = 0
|
|
15
|
+
WHERE upper(key) IN (
|
|
16
|
+
'SLACK_APP_TOKEN',
|
|
17
|
+
'SLACK_SIGNING_SECRET',
|
|
18
|
+
'GITHUB_APP_PRIVATE_KEY',
|
|
19
|
+
'GITHUB_WEBHOOK_SECRET',
|
|
20
|
+
'GITLAB_WEBHOOK_SECRET',
|
|
21
|
+
'LINEAR_CLIENT_SECRET',
|
|
22
|
+
'LINEAR_SIGNING_SECRET',
|
|
23
|
+
'JIRA_CLIENT_SECRET',
|
|
24
|
+
'JIRA_WEBHOOK_TOKEN',
|
|
25
|
+
'AZURE_DEVOPS_WEBHOOK_SECRET',
|
|
26
|
+
'AGENTMAIL_WEBHOOK_SECRET',
|
|
27
|
+
'API_AGENT_FS_API_KEY',
|
|
28
|
+
'KAPSO_WEBHOOK_HMAC_SECRET',
|
|
29
|
+
'SENTRY_TEST_APP_WEBHOOK_SECRET',
|
|
30
|
+
'TELEMETRY_CH_AUTH',
|
|
31
|
+
'HACK_AGENT_FS_ADMIN_KEY',
|
|
32
|
+
'X_CLIENT_SECRET'
|
|
33
|
+
)
|
|
34
|
+
OR key GLOB 'connection.*.secret';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-- The reasoning effort a task's session actually ran at. `effort` stays the
|
|
2
|
+
-- requested value (a task-level pin); the effective one usually comes from the
|
|
3
|
+
-- agent's REASONING_EFFORT_OVERRIDE and was never recorded. NULL means the
|
|
4
|
+
-- harness default applied, or the row predates this column.
|
|
5
|
+
ALTER TABLE agent_tasks ADD COLUMN resolvedEffort TEXT;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
-- Chat SDK (chat-sdk.dev) channel: StateAdapter tables + durable outbound relay.
|
|
2
|
+
--
|
|
3
|
+
-- The five chat_* state tables back `SqliteChatState` (src/integrations/chat-sdk/state.ts).
|
|
4
|
+
-- Keys and thread ids written by the SDK already carry the adapter prefix
|
|
5
|
+
-- (`telegram:...`, `slack:...`), so no adapter column is needed.
|
|
6
|
+
-- Expiry columns are epoch milliseconds; NULL means no expiry.
|
|
7
|
+
|
|
8
|
+
CREATE TABLE chat_state_kv (
|
|
9
|
+
key TEXT PRIMARY KEY,
|
|
10
|
+
value TEXT NOT NULL,
|
|
11
|
+
expires_at INTEGER
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE TABLE chat_subscriptions (
|
|
15
|
+
thread_id TEXT PRIMARY KEY,
|
|
16
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE TABLE chat_locks (
|
|
20
|
+
thread_id TEXT PRIMARY KEY,
|
|
21
|
+
token TEXT NOT NULL,
|
|
22
|
+
expires_at INTEGER NOT NULL
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
CREATE TABLE chat_lists (
|
|
26
|
+
key TEXT NOT NULL,
|
|
27
|
+
seq INTEGER NOT NULL,
|
|
28
|
+
value TEXT NOT NULL,
|
|
29
|
+
expires_at INTEGER,
|
|
30
|
+
PRIMARY KEY (key, seq)
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
CREATE TABLE chat_queue (
|
|
34
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
35
|
+
thread_id TEXT NOT NULL,
|
|
36
|
+
entry TEXT NOT NULL
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
CREATE INDEX idx_chat_queue_thread ON chat_queue(thread_id, id);
|
|
40
|
+
|
|
41
|
+
-- Persist the obligation to publish a terminal result for every Chat SDK-rooted
|
|
42
|
+
-- task. Mirrors 144_slack_relay_obligations.sql, plus an attempt cap: a poison
|
|
43
|
+
-- row is marked given up (with the reason) instead of retrying forever.
|
|
44
|
+
CREATE TABLE chat_relay_obligations (
|
|
45
|
+
task_id TEXT PRIMARY KEY REFERENCES agent_tasks(id) ON DELETE CASCADE,
|
|
46
|
+
delivered_at TEXT,
|
|
47
|
+
attempt_count INTEGER NOT NULL DEFAULT 0,
|
|
48
|
+
last_attempt_at TEXT,
|
|
49
|
+
given_up_at TEXT,
|
|
50
|
+
last_error TEXT,
|
|
51
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
52
|
+
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
53
|
+
created_by TEXT,
|
|
54
|
+
updated_by TEXT
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
CREATE INDEX idx_chat_relay_obligations_pending
|
|
58
|
+
ON chat_relay_obligations(last_attempt_at, created_at)
|
|
59
|
+
WHERE delivered_at IS NULL AND given_up_at IS NULL;
|
|
60
|
+
|
|
61
|
+
-- Lead follow-ups (`source='system'`, `taskType='follow-up'`) inherit the chat
|
|
62
|
+
-- contextKey and carry the lead's final answer, so they relay too. A resume
|
|
63
|
+
-- (`source='system'`, `taskType='resume'`, from `createResumeFollowUp` after a
|
|
64
|
+
-- graceful shutdown or crash recovery) inherits the contextKey too. It relays
|
|
65
|
+
-- only when a lead owns it: a worker task (resumed or not) reports back through
|
|
66
|
+
-- a lead follow-up, and the lead never gets one for its own tasks. Other system
|
|
67
|
+
-- tasks that inherit the key stay silent. GLOB, not LIKE: LIKE is
|
|
68
|
+
-- case-insensitive in SQLite.
|
|
69
|
+
CREATE TRIGGER enqueue_chat_relay_after_terminal_update
|
|
70
|
+
AFTER UPDATE OF status ON agent_tasks
|
|
71
|
+
WHEN OLD.status NOT IN ('completed', 'failed', 'cancelled', 'superseded')
|
|
72
|
+
AND NEW.status IN ('completed', 'failed', 'cancelled')
|
|
73
|
+
AND NEW.contextKey GLOB 'task:chat-sdk:*'
|
|
74
|
+
AND (
|
|
75
|
+
NEW.source = 'chat'
|
|
76
|
+
OR (NEW.source = 'system' AND NEW.taskType = 'follow-up')
|
|
77
|
+
OR (
|
|
78
|
+
NEW.source = 'system'
|
|
79
|
+
AND NEW.taskType = 'resume'
|
|
80
|
+
AND EXISTS (SELECT 1 FROM agents WHERE agents.id = NEW.agentId AND agents.isLead = 1)
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
BEGIN
|
|
84
|
+
INSERT OR IGNORE INTO chat_relay_obligations (task_id)
|
|
85
|
+
VALUES (NEW.id);
|
|
86
|
+
END;
|
|
87
|
+
|
|
88
|
+
CREATE TRIGGER enqueue_chat_relay_after_terminal_insert
|
|
89
|
+
AFTER INSERT ON agent_tasks
|
|
90
|
+
WHEN NEW.status IN ('completed', 'failed', 'cancelled')
|
|
91
|
+
AND NEW.contextKey GLOB 'task:chat-sdk:*'
|
|
92
|
+
AND (
|
|
93
|
+
NEW.source = 'chat'
|
|
94
|
+
OR (NEW.source = 'system' AND NEW.taskType = 'follow-up')
|
|
95
|
+
OR (
|
|
96
|
+
NEW.source = 'system'
|
|
97
|
+
AND NEW.taskType = 'resume'
|
|
98
|
+
AND EXISTS (SELECT 1 FROM agents WHERE agents.id = NEW.agentId AND agents.isLead = 1)
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
BEGIN
|
|
102
|
+
INSERT OR IGNORE INTO chat_relay_obligations (task_id)
|
|
103
|
+
VALUES (NEW.id);
|
|
104
|
+
END;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* See runbooks/model-catalog.md.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
import { withAgentChatRegistrySections } from "@desplega/model-catalog";
|
|
16
17
|
import { type RuntimeCatalog, setRuntimeModelCatalog } from "../utils/runtime-model-catalog";
|
|
17
18
|
import {
|
|
18
19
|
getActivePricingRow,
|
|
@@ -180,7 +181,10 @@ function pickNumber(value: unknown): number | undefined {
|
|
|
180
181
|
}
|
|
181
182
|
|
|
182
183
|
/** Project a models.dev payload into `model_catalog` rows for CATALOG_PROVIDER_IDS. */
|
|
183
|
-
export function buildCatalogEntries(
|
|
184
|
+
export function buildCatalogEntries(raw: ModelsDevCache, checkedAt: number): ModelCatalogEntry[] {
|
|
185
|
+
// A live models.dev payload still carries the embeddings and image models of
|
|
186
|
+
// the registry gateways (`vercel`); pi and opencode cannot run them.
|
|
187
|
+
const cache = withAgentChatRegistrySections(raw);
|
|
184
188
|
const entries: ModelCatalogEntry[] = [];
|
|
185
189
|
for (const providerId of CATALOG_PROVIDER_IDS) {
|
|
186
190
|
const provider = cache[providerId];
|
|
@@ -509,6 +509,8 @@ export type ClaimModelFields = Partial<TaskModelResolution> & {
|
|
|
509
509
|
/**
|
|
510
510
|
* Resolve and record the model for a task the given agent is claiming. Runs
|
|
511
511
|
* inside the claim transaction. Returns the fields to merge into the trigger.
|
|
512
|
+
* `task.model` must be the task's own pin (`taskModelPin`), never the model a
|
|
513
|
+
* previous session reported into the column.
|
|
512
514
|
*/
|
|
513
515
|
export async function recordClaimModelResolution(
|
|
514
516
|
task: { id: string; model?: string | null; modelTier?: string | null },
|
|
@@ -521,7 +523,16 @@ export async function recordClaimModelResolution(
|
|
|
521
523
|
harnessProvider,
|
|
522
524
|
workerOverrides: await getAgentModelTierOverrides(agent.id),
|
|
523
525
|
});
|
|
524
|
-
if (!resolved)
|
|
526
|
+
if (!resolved) {
|
|
527
|
+
// A re-claimed row keeps the claim record of its previous run; drop it so
|
|
528
|
+
// the trigger and the row do not replay that run's model.
|
|
529
|
+
await getDbClient().run(
|
|
530
|
+
`UPDATE agent_tasks SET resolvedModel = NULL, modelSource = NULL, modelAlias = NULL
|
|
531
|
+
WHERE id = ? AND (resolvedModel IS NOT NULL OR modelSource IS NOT NULL OR modelAlias IS NOT NULL)`,
|
|
532
|
+
[task.id],
|
|
533
|
+
);
|
|
534
|
+
return {};
|
|
535
|
+
}
|
|
525
536
|
if ("harnessMismatch" in resolved) return { modelUnsupported: resolved.harnessMismatch };
|
|
526
537
|
const checked = await applyCliSupport(
|
|
527
538
|
resolved,
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
type ModelsDevCatalog,
|
|
30
30
|
parseAlias,
|
|
31
31
|
} from "@desplega/model-catalog";
|
|
32
|
+
import { type TaskModelPinFields, taskModelPin } from "../tasks/model-pin";
|
|
32
33
|
import { ampModelError, ampPinCatalogError, ampPinProviderError } from "../utils/amp-models";
|
|
33
34
|
import { getAgentById, getAllAgents } from "./db";
|
|
34
35
|
import { loadModelsCatalog } from "./model-catalog-store";
|
|
@@ -99,10 +100,12 @@ export async function harnessModelErrorFor(
|
|
|
99
100
|
* stays sync and catalog-free; this runs next to it.
|
|
100
101
|
*/
|
|
101
102
|
export async function poolTaskRunsOnHarness(
|
|
102
|
-
task:
|
|
103
|
+
task: TaskModelPinFields | null | undefined,
|
|
103
104
|
harness: string | null | undefined,
|
|
104
105
|
): Promise<boolean> {
|
|
105
|
-
|
|
106
|
+
// Only the task's own pin restricts harnesses; a model a previous run
|
|
107
|
+
// reported into `model` does not.
|
|
108
|
+
const model = taskModelPin(task ?? {})?.trim();
|
|
106
109
|
if (!model) return true;
|
|
107
110
|
return (await harnessModelErrorFor(model, harness)) === null;
|
|
108
111
|
}
|
package/src/be/models-catalog.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { openAICompatibleProviderIds, registryCatalogSections } from "@desplega/model-catalog";
|
|
1
2
|
import { loadModelsDevCache, type ModelsDevCache, type ModelsDevModel } from "./modelsdev-cache";
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -15,13 +16,18 @@ import { loadModelsDevCache, type ModelsDevCache, type ModelsDevModel } from "./
|
|
|
15
16
|
* same snapshot as its own fallback while the request is in flight.
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Mirrors the provider groups used by the direct harness and ACP model
|
|
21
|
+
* pickers, plus every OpenAI-compatible registry provider
|
|
22
|
+
* (`@desplega/model-catalog`).
|
|
23
|
+
*/
|
|
19
24
|
export const CATALOG_PROVIDER_IDS = [
|
|
20
25
|
"openrouter",
|
|
21
26
|
"anthropic",
|
|
22
27
|
"openai",
|
|
23
28
|
"amazon-bedrock",
|
|
24
29
|
"opencode",
|
|
30
|
+
...openAICompatibleProviderIds(),
|
|
25
31
|
] as const;
|
|
26
32
|
|
|
27
33
|
export type CatalogProviderId = (typeof CATALOG_PROVIDER_IDS)[number];
|
|
@@ -163,6 +169,24 @@ function mergePinnedEntries(catalog: ModelsCatalog): void {
|
|
|
163
169
|
}
|
|
164
170
|
}
|
|
165
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Registry-synthesized sections (`catalog: "registry"` entries such as
|
|
174
|
+
* `helmcode`) are never on models.dev, so the live catalog built from it
|
|
175
|
+
* lacks them. Fill them from the bundled snapshot, which carries them
|
|
176
|
+
* (`loadModelsDevCache`); models already present (an overlay row) win.
|
|
177
|
+
*/
|
|
178
|
+
function mergeRegistrySections(catalog: ModelsCatalog): void {
|
|
179
|
+
const snapshot = bundledSnapshotCatalog();
|
|
180
|
+
for (const providerId of Object.keys(registryCatalogSections()) as CatalogProviderId[]) {
|
|
181
|
+
const section = snapshot[providerId];
|
|
182
|
+
if (!section) continue;
|
|
183
|
+
catalog[providerId] ??= { ...section, models: {} };
|
|
184
|
+
for (const [modelId, model] of Object.entries(section.models)) {
|
|
185
|
+
catalog[providerId].models[modelId] ??= model;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
166
190
|
/**
|
|
167
191
|
* Install a freshly built live catalog (already merged with the persistent
|
|
168
192
|
* table + overlay by `src/be/model-catalog-store.ts`). Pinned snapshot entries
|
|
@@ -170,6 +194,7 @@ function mergePinnedEntries(catalog: ModelsCatalog): void {
|
|
|
170
194
|
*/
|
|
171
195
|
export function setLiveModelsCatalog(catalog: ModelsCatalog, updatedAt: number | null): void {
|
|
172
196
|
mergePinnedEntries(catalog);
|
|
197
|
+
mergeRegistrySections(catalog);
|
|
173
198
|
liveCatalog = catalog;
|
|
174
199
|
liveUpdatedAt = updatedAt;
|
|
175
200
|
}
|