@desplega.ai/agent-swarm 1.173.0 → 2.1.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-kr4abrsk.js} +17 -16
- package/dist/{actions-sgeyv08k.js → actions-eh4g6w2r.js} +39 -34
- package/dist/{amp-adapter-gpxp3kc9.js → amp-adapter-7h7wdt8q.js} +8 -7
- package/dist/{app-km9qnv2f.js → app-7k8s9w5p.js} +18 -14
- package/dist/{assistant-5r8tcvvd.js → assistant-wswt2y7p.js} +40 -35
- package/dist/{boot-reembed-16rv9843.js → boot-reembed-9apm9qw6.js} +10 -9
- package/dist/{boot-reembed-swwzdgd7.js → boot-reembed-whzbdthj.js} +10 -9
- package/dist/{boot-scrub-sweep-zkr6vkqb.js → boot-scrub-sweep-ndzmvmgt.js} +11 -10
- package/dist/{boot-seeds-d8sp49t2.js → boot-seeds-e9sta0yt.js} +16 -13
- package/dist/{claude-adapter-yzzzh8jp.js → claude-adapter-4mqd3r6r.js} +19 -18
- package/dist/{claude-managed-adapter-xgxhqrt2.js → claude-managed-adapter-9wswb52m.js} +7 -5
- package/dist/{claude-managed-setup-bnmjarjc.js → claude-managed-setup-tpe1effx.js} +6 -4
- package/dist/{claude-sdk-session-4whxere4.js → claude-sdk-session-q49ghmh9.js} +12402 -11850
- package/dist/{cli-ne7smj1b.js → cli-01xvj1rq.js} +10 -10
- package/dist/{cli-nwrdx840.js → cli-035vekcw.js} +3 -3
- package/dist/{cli-9xf7fdtp.js → cli-0pd8hzhc.js} +29 -6
- package/dist/{cli-tmhsxhb8.js → cli-0veb92a3.js} +28 -6
- package/dist/{cli-c3rk1v0x.js → cli-10jesr25.js} +3 -3
- package/dist/{cli-6thk4jz3.js → cli-1y7yywmj.js} +6 -6
- package/dist/{cli-6r2f7edk.js → cli-20krdhz5.js} +47 -19
- package/dist/{cli-rfs4vddv.js → cli-29rja109.js} +39 -20
- package/dist/cli-2m1ktfzz.js +17795 -0
- package/dist/{cli-na2pxe4f.js → cli-2pwa0q4d.js} +15 -4
- package/dist/{cli-7a93cv8c.js → cli-4mengw46.js} +441 -43
- package/dist/{cli-94b48jhk.js → cli-5twdke5x.js} +16 -14
- package/dist/{cli-7a0sde2x.js → cli-6cagzc96.js} +9 -0
- package/dist/cli-6cvfxs8r.js +47 -0
- package/dist/{cli-w1apjecb.js → cli-711vwbxn.js} +2 -2
- package/dist/{cli-r4fqfpwf.js → cli-78vv7446.js} +50 -27
- package/dist/{cli-srqq3gc5.js → cli-7n6s5man.js} +5 -5
- package/dist/{cli-m89t9jdf.js → cli-7x0g4sn1.js} +15416 -16024
- package/dist/{cli-2bw3w47j.js → cli-8wwxw8a3.js} +1 -1
- package/dist/{cli-yatxqynm.js → cli-9ha6hs2d.js} +1 -290
- package/dist/{cli-ywm1azg9.js → cli-9jzdj90z.js} +8 -4
- package/dist/cli-9traj3dn.js +638 -0
- package/dist/{cli-smcrrmhy.js → cli-agzebbd5.js} +9 -9
- package/dist/{cli-c5km5znr.js → cli-c8r3kzzb.js} +1 -1
- package/dist/cli-cvv9k0hh.js +10143 -0
- package/dist/{cli-anzdk0z4.js → cli-d9286m9h.js} +2 -2
- package/dist/cli-e3g5mbkz.js +776 -0
- package/dist/cli-f527ce74.js +781 -0
- package/dist/{cli-gmdajfw5.js → cli-gxzkg1de.js} +5020 -1729
- package/dist/{cli-451ks6aw.js → cli-h1arqn31.js} +1 -1
- package/dist/cli-hjwmhcg1.js +10622 -0
- package/dist/{cli-jpc4r224.js → cli-hqr88ew6.js} +19 -3
- package/dist/{cli-h7k0xtry.js → cli-hvqbtna4.js} +4 -1256
- package/dist/{cli-cd0hv9nh.js → cli-j67mh2vg.js} +2 -2
- package/dist/cli-jta2eyzc.js +619 -0
- package/dist/{cli-wd0hz6ah.js → cli-kbrt8gqa.js} +9 -91
- package/dist/cli-kceah1eh.js +92 -0
- package/dist/{cli-d603qf86.js → cli-ksphgh48.js} +10 -8
- package/dist/{cli-3nxdmjrc.js → cli-mgz4nbgg.js} +4 -4
- package/dist/{cli-saqyage0.js → cli-mz5as5ha.js} +179 -27
- package/dist/cli-n2wq4j7m.js +6985 -0
- package/dist/{cli-ppy4nnnh.js → cli-n8ndw8j7.js} +2 -2
- package/dist/{cli-1w0vj3gw.js → cli-naqzr17j.js} +7 -7
- package/dist/{cli-0a7mm3zp.js → cli-nm1p8jfr.js} +25 -21
- package/dist/{cli-wrh08zjd.js → cli-p3zbc1rw.js} +5 -18
- package/dist/{cli-hsem16hb.js → cli-pe05f8yk.js} +29 -6
- package/dist/{cli-5wpw4rab.js → cli-qmzsbkvy.js} +5 -5
- package/dist/{cli-bv2etw2y.js → cli-qnm4e9e4.js} +99 -590
- package/dist/{cli-1x7da0de.js → cli-qqy4q48b.js} +8 -8
- package/dist/{cli-r44t9wqc.js → cli-r106725k.js} +2 -2
- package/dist/{cli-5er5gjbm.js → cli-r35rw5de.js} +15 -15
- package/dist/{cli-v3zhnxsb.js → cli-r610p9bs.js} +2 -2
- package/dist/{cli-7jykv7ef.js → cli-rc6pf5kv.js} +1 -1
- package/dist/{cli-x119kdba.js → cli-rdxm77k3.js} +1 -1
- package/dist/cli-rhs9pz33.js +294 -0
- package/dist/{cli-0p3enk35.js → cli-s69nfyeh.js} +9 -1
- package/dist/{cli-0kxf81jj.js → cli-sawv63e8.js} +2 -2
- package/dist/{cli-e3pmyt39.js → cli-sg19gbf0.js} +1 -1
- package/dist/{cli-d161g69q.js → cli-shk7r5cs.js} +57 -6
- package/dist/{cli-7pz3b7x5.js → cli-sksetb2q.js} +36 -1
- package/dist/{cli-014vns2y.js → cli-stfs0k5s.js} +208 -525
- package/dist/{cli-db3m6zdt.js → cli-t02z59f2.js} +1 -1
- package/dist/{cli-b07hr3bt.js → cli-txqb9s38.js} +2 -2
- package/dist/{cli-s8z6x4b4.js → cli-v7g551te.js} +225 -113
- package/dist/{cli-rfz2ve55.js → cli-vgqzp4em.js} +3341 -955
- package/dist/{cli-7avy4v8w.js → cli-w1q7h2r2.js} +5 -3
- package/dist/{cli-rcp5aqdw.js → cli-w7m81tb7.js} +1 -1
- package/dist/cli-wfnemr1t.js +86 -0
- package/dist/cli-wmgrkscj.js +23254 -0
- package/dist/{cli-qm1448f9.js → cli-wms6x9db.js} +8 -8
- package/dist/{cli-tadfgd0t.js → cli-x1r545x8.js} +33 -4
- package/dist/{cli-xc7p7s3g.js → cli-xczsgshn.js} +6 -6
- package/dist/{cli-fmhj1ehj.js → cli-y3167wt1.js} +882 -271
- package/dist/{cli-r0byd61h.js → cli-yjmqpxt3.js} +17 -16
- package/dist/{cli-81r1wjyv.js → cli-z780ec7c.js} +1 -1
- package/dist/{cli-phcqp1b9.js → cli-zm9t2vde.js} +2 -2
- package/dist/cli.js +34 -49
- package/dist/{codex-adapter-r3dn4fp5.js → codex-adapter-4z16v9n0.js} +15 -14
- package/dist/{codex-login-841kv5fk.js → codex-login-pkepy2j1.js} +3 -2
- package/dist/{codex-session-runner-fwt793h4.js → codex-session-runner-rvms9y2x.js} +15 -14
- package/dist/{commands-z8fq9qna.js → commands-2a9rtyat.js} +11 -10
- package/dist/{controller-hq5ggpcp.js → controller-3k3madbn.js} +5 -4
- package/dist/{controllers-connect-3mf2btyj.js → controllers-connect-v9yn8zb9.js} +42 -37
- package/dist/{cursor-adapter-q8pgv5qa.js → cursor-adapter-98gbhyzn.js} +7 -6
- package/dist/{db-qfpq4bt7.js → db-eywwsnjw.js} +30 -9
- package/dist/{db-yyhqqrbf.js → db-ncypk9np.js} +12 -11
- package/dist/{devin-adapter-xgtj680j.js → devin-adapter-zeq8b9gz.js} +3 -2
- package/dist/{dispatcher-x0x7qfcq.js → dispatcher-w94kc575.js} +38 -33
- package/dist/{docker-f503k9p0.js → docker-b1e4cqab.js} +3 -2
- package/dist/{dsh-adapter-34etvb5m.js → dsh-adapter-47ztej36.js} +7 -6
- package/dist/{e2b-66xra4az.js → e2b-bbt8ey45.js} +4 -3
- package/dist/{e2b-xwhyj8cw.js → e2b-dp804sen.js} +4 -3
- package/dist/{event-bus-vjtv82gm.js → event-bus-j2jdg3qb.js} +3 -2
- package/dist/{external-channel-h1fjecwe.js → external-channel-zrkg8ar9.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-s9ncp9vy.js} +18 -17
- package/dist/{handlers-znb9n7d4.js → handlers-kqftvjgw.js} +41 -36
- package/dist/{heartbeat-bm4qkn8d.js → heartbeat-9q96p8v9.js} +43 -38
- package/dist/{hook-254r4mza.js → hook-56qe10dp.js} +11 -23
- package/dist/{hook-xaa3q80s.js → hook-yy6rw42k.js} +12 -11
- package/dist/{http-3dgrgp8y.js → http-r2dnb8f8.js} +2411 -275
- package/dist/{index-fx3jqq1e.js → index-3gtmkhc6.js} +38 -33
- package/dist/{index-bdsqa799.js → index-3k5hkz7r.js} +43 -38
- package/dist/index-52j1aja4.js +3465 -0
- package/dist/{index-g2byveez.js → index-5e101240.js} +38 -33
- package/dist/{index-2ybk7khy.js → index-5wyfjc2c.js} +845 -683
- 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-jd7sejm2.js → index-vxvhxxbn.js} +10 -9
- package/dist/index-we27kd31.js +12810 -0
- package/dist/{keepalive-6ywhpja1.js → keepalive-psj6j54c.js} +12 -11
- package/dist/{lead-cw45n21s.js → lead-hajz4688.js} +61 -56
- package/dist/{maintenance-ss1a1ge9.js → maintenance-ps02sb5m.js} +10 -9
- package/dist/{node-fkajaq96.js → node-mwb5r697.js} +2 -1
- package/dist/{oauth-refresh-sweep-3c6f8vyy.js → oauth-refresh-sweep-0284h93b.js} +11 -10
- package/dist/{onboard-8hzdhc1k.js → onboard-rbf6bg01.js} +11 -3
- package/dist/{opencode-adapter-qbchbcfz.js → opencode-adapter-13dcatgq.js} +18 -13
- package/dist/{otel-impl-e6mnvc4v.js → otel-impl-zvqcbhp7.js} +242 -868
- package/dist/{pi-mono-adapter-3c9g9snh.js → pi-mono-adapter-xxy47q4v.js} +244 -106
- package/dist/{pricing-refresh-gedkjdw0.js → pricing-refresh-kefx9v3t.js} +12 -11
- package/dist/{rbac-roles-dt4vh1yy.js → rbac-roles-3m36rxm2.js} +11 -10
- package/dist/{rbac-roles-eszdg6pm.js → rbac-roles-z76xv0hq.js} +12 -11
- package/dist/{render-v2-907cy6sa.js → render-v2-wz73bs25.js} +18 -14
- package/dist/{resume-42stcaz0.js → resume-k4wzge8w.js} +25 -21
- package/dist/{runtime-qfry88v2.js → runtime-sa2vr16g.js} +2 -2
- package/dist/{setup-adbc1c10.js → setup-2fp2pypp.js} +2 -2
- package/dist/{virtual-modules-rtmt494q.js → virtual-modules-9gkxqrap.js} +6 -5
- package/dist/{work-objects-wpj8ck95.js → work-objects-6k0ywz3m.js} +41 -36
- package/dist/{worker-bzdra9rf.js → worker-5v3rxsdh.js} +61 -56
- package/dist/{x-qfmygqqv.js → x-4mtdeym1.js} +3 -2
- package/openapi.json +1279 -329
- package/package.json +15 -15
- package/src/agentmail/handlers.ts +21 -11
- package/src/apps/definition.ts +16 -0
- package/src/azure-devops/api.ts +52 -2
- package/src/azure-devops/boards-sync.ts +50 -20
- package/src/azure-devops/index.ts +1 -0
- package/src/azure-devops/outbound.ts +95 -0
- package/src/be/boot-seeds.ts +11 -0
- package/src/be/config-refs.ts +60 -0
- package/src/be/db/model-profiles.ts +315 -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 +237 -0
- package/src/be/db/tasks/write.ts +7 -0
- package/src/be/db.ts +87 -36
- 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/migrations/219_relabel_pi_context_compactions.sql +22 -0
- package/src/be/migrations/220_model_profiles.sql +137 -0
- package/src/be/model-catalog-store.ts +5 -1
- package/src/be/model-tier-resolution.ts +155 -10
- package/src/be/model-validation.ts +12 -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 +22 -8
- package/src/be/secret-registry.ts +6 -2
- 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-model-profiles.ts +41 -0
- package/src/be/seed-pricing.ts +19 -2
- package/src/be/seed-scripts/catalog/heartbeat-jev-gate.ts +368 -0
- 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-scripts/index.ts +9 -0
- 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 +53 -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 +193 -71
- package/src/e2b/env.ts +5 -0
- package/src/extensions/catalog.generated.json +17 -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/loader.ts +10 -5
- package/src/extensions/post-bridge.ts +40 -0
- package/src/github/handlers.ts +11 -4
- package/src/heartbeat/heartbeat.ts +2 -1
- package/src/heartbeat/templates.ts +8 -5
- package/src/hooks/hook.ts +0 -26
- package/src/http/agents.ts +49 -2
- package/src/http/all-routes.ts +1 -1
- package/src/http/apps.ts +30 -3
- package/src/http/config.ts +62 -19
- package/src/http/core.ts +8 -0
- package/src/http/index.ts +25 -3
- package/src/http/integrations.ts +88 -1
- package/src/http/mcp.ts +15 -5
- package/src/http/model-profiles.ts +303 -0
- package/src/http/page-proxy.ts +2 -4
- package/src/http/pages-public.ts +13 -7
- package/src/http/pages.ts +3 -13
- package/src/http/poll.ts +42 -71
- package/src/http/requested-by.ts +54 -0
- package/src/http/script-runs.ts +1 -1
- package/src/http/scripts.ts +26 -2
- package/src/http/stats.ts +1 -30
- package/src/http/tasks.ts +79 -5
- package/src/http/utils.ts +14 -0
- package/src/http/webhooks.ts +160 -3
- 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/{artifact-sdk → pages}/feedback-overlay.ts +65 -6
- 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 +56 -3
- 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/pi-mono-extension.ts +17 -3
- package/src/providers/pricing-sources.md +33 -2
- package/src/providers/reasoning-effort.ts +37 -0
- package/src/providers/types.ts +6 -2
- package/src/rbac/legacy-policy.ts +16 -2
- package/src/rbac/permissions.ts +26 -0
- package/src/scheduler/deferred-task-waits.ts +18 -5
- package/src/scheduler/scheduler.ts +11 -3
- package/src/scripts-runtime/executors/quickjs-prelude.ts +75 -6
- package/src/scripts-runtime/executors/quickjs-runner.ts +85 -8
- package/src/scripts-runtime/executors/quickjs-web-shims.ts +1041 -0
- package/src/scripts-runtime/extract-args-schema.ts +9 -8
- package/src/scripts-runtime/loader.ts +19 -7
- package/src/scripts-runtime/quickjs-compat.ts +464 -0
- package/src/scripts-runtime/sdk-allowlist.ts +12 -6
- package/src/scripts-runtime/swarm-sdk.ts +0 -11
- package/src/scripts-runtime/types/stdlib.d.ts +39 -15
- package/src/scripts-runtime/types/swarm-extension.d.ts +66 -1
- package/src/scripts-runtime/types/swarm-sdk.d.ts +39 -15
- package/src/server.ts +62 -19
- package/src/slack/blocks.ts +4 -2
- package/src/slack/event-dedup.ts +1 -1
- package/src/slack/reaction-shortcode.ts +14 -0
- package/src/slack/render-v2.ts +12 -7
- package/src/slack/responses.ts +5 -4
- package/src/slack/thread-buffer.ts +41 -22
- 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 +15 -33
- package/src/tests/acp-adapter.test.ts +42 -0
- package/src/tests/agentmail-filters.test.ts +47 -0
- package/src/tests/api-drain-worker-e2e.test.ts +1 -6
- package/src/tests/apps-spike2.test.ts +35 -0
- package/src/tests/azure-devops-outbound.test.ts +420 -0
- 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 +22 -0
- package/src/tests/db-task-write-contract.test.ts +11 -0
- package/src/tests/deferred-task-wake.test.ts +78 -1
- 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/env-flag.test.ts +1 -0
- package/src/tests/explicit-model-validation.test.ts +105 -1
- package/src/tests/extensions-catalog.test.ts +1 -0
- package/src/tests/extensions-example-comms-adherence-gate.test.ts +413 -0
- package/src/tests/extensions-example-route-chat-channel.test.ts +154 -0
- package/src/tests/extensions-loader.test.ts +15 -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/heartbeat-jev-gate-credentials.test.ts +168 -0
- package/src/tests/heartbeat-jev-gate.test.ts +385 -0
- 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-profile-backcompat.test.ts +327 -0
- package/src/tests/model-profile-providers.test.ts +302 -0
- package/src/tests/model-profile-runtime-secrets.test.ts +223 -0
- package/src/tests/model-profiles-api.test.ts +614 -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-keys.test.ts +121 -0
- package/src/tests/pages-feedback.test.ts +4 -1
- package/src/tests/paused-tasks-requested-by.test.ts +102 -0
- package/src/tests/pi-context-compaction.test.ts +193 -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/profile-claim.test.ts +269 -0
- package/src/tests/prompt-template-remaining.test.ts +35 -0
- package/src/tests/quickjs-compat.test.ts +213 -0
- package/src/tests/rbac-engine.test.ts +32 -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 +6 -0
- package/src/tests/script-executor-conformance.test.ts +252 -1
- package/src/tests/script-executor-quickjs.test.ts +96 -0
- package/src/tests/script-runs-http.test.ts +89 -0
- package/src/tests/scripts-http.test.ts +217 -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 +96 -0
- package/src/tests/seed-model-profiles.test.ts +174 -0
- package/src/tests/seed-scripts.test.ts +2 -2
- 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/skill-invocations.test.ts +4 -2
- package/src/tests/slack-blocks.test.ts +36 -0
- package/src/tests/slack-inline-output.test.ts +14 -0
- package/src/tests/slack-reaction-config.test.ts +20 -0
- package/src/tests/slack-render-v2.test.ts +37 -0
- package/src/tests/slack-thread-buffer.test.ts +98 -1
- 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-llm.test.ts +61 -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/model-profiles/list-model-profiles.ts +54 -0
- package/src/tools/register-chat-channel.ts +139 -0
- package/src/tools/request-human-input.ts +11 -3
- package/src/tools/script-apis.ts +5 -1
- package/src/tools/script-upsert.ts +4 -1
- package/src/tools/send-task.ts +48 -1
- 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/system-one-decide.ts +104 -0
- package/src/tools/task-action.ts +22 -1
- package/src/tools/tool-config.ts +14 -6
- package/src/types.ts +48 -3
- 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 +86 -10
- package/src/utils/task-tool-manifest.ts +19 -2
- package/src/utils/vcs-repo-match.ts +29 -0
- package/src/workflows/executors/raw-llm.ts +8 -3
- package/src/workflows/executors/swarm-script.ts +1 -0
- package/src/workflows/executors/system-one-decision.ts +21 -11
- package/src/workflows/executors/workflow-llm.ts +22 -0
- package/src/workflows/index.ts +21 -12
- package/templates/extensions/README.md +1 -0
- package/templates/extensions/comms-adherence-gate/README.md +88 -0
- package/templates/extensions/comms-adherence-gate/hooks.ts +489 -0
- package/templates/extensions/comms-adherence-gate/manifest.json +8 -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-42qhyvwx.js +0 -33
- 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/http/apps.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
parseAppDefinition,
|
|
13
13
|
SORTABLE_SYSTEM_DATE_COLUMNS,
|
|
14
14
|
SYSTEM_COLUMN_KINDS,
|
|
15
|
+
scriptCompatWarnings,
|
|
15
16
|
} from "../apps/definition";
|
|
16
17
|
import {
|
|
17
18
|
type AppRow,
|
|
@@ -227,9 +228,14 @@ const AppUserConfigFieldSchema = z.object({
|
|
|
227
228
|
/** Mirrors an app definition's `userConfig` declaration map. */
|
|
228
229
|
const AppUserConfigSchema = z.record(AppNameSchema, AppUserConfigFieldSchema);
|
|
229
230
|
|
|
231
|
+
const compatWarningsSchema = z
|
|
232
|
+
.array(z.string())
|
|
233
|
+
.optional()
|
|
234
|
+
.describe("Advisory quickjs-executor compatibility findings for the app's scripts.");
|
|
230
235
|
const appWriteResponseSchema = z.object({
|
|
231
236
|
app: AppRecordSchema,
|
|
232
237
|
migration: AppMigrationReportSchema,
|
|
238
|
+
warnings: compatWarningsSchema,
|
|
233
239
|
});
|
|
234
240
|
const userConfigBodySchema = z.object({ values: z.record(z.string(), z.unknown()) }).strict();
|
|
235
241
|
|
|
@@ -307,7 +313,10 @@ const createAppRoute = route({
|
|
|
307
313
|
forceElementBreak: ForceElementBreakSchema.optional(),
|
|
308
314
|
}),
|
|
309
315
|
responses: {
|
|
310
|
-
201: {
|
|
316
|
+
201: {
|
|
317
|
+
description: "Created app",
|
|
318
|
+
schema: z.object({ app: AppRecordSchema, warnings: compatWarningsSchema }),
|
|
319
|
+
},
|
|
311
320
|
400: { description: "Invalid app definition" },
|
|
312
321
|
403: { description: "Permission denied" },
|
|
313
322
|
},
|
|
@@ -1020,12 +1029,14 @@ export async function handleApps(
|
|
|
1020
1029
|
invalidDefinition(res, definition.issues);
|
|
1021
1030
|
return true;
|
|
1022
1031
|
}
|
|
1032
|
+
const warnings = await scriptCompatWarnings(definition.definition);
|
|
1023
1033
|
createAppRoute.respond(res, 201, {
|
|
1024
1034
|
app: await createApp({
|
|
1025
1035
|
name: parsed.body.name,
|
|
1026
1036
|
description: parsed.body.description,
|
|
1027
1037
|
definition: definition.definition,
|
|
1028
1038
|
}),
|
|
1039
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
1029
1040
|
});
|
|
1030
1041
|
return true;
|
|
1031
1042
|
}
|
|
@@ -1482,6 +1493,7 @@ export async function handleApps(
|
|
|
1482
1493
|
}
|
|
1483
1494
|
let app: Awaited<ReturnType<typeof updateApp>> = null;
|
|
1484
1495
|
let migration!: AppMigrationReport;
|
|
1496
|
+
let writtenDefinition: unknown;
|
|
1485
1497
|
let responseHandled = false;
|
|
1486
1498
|
try {
|
|
1487
1499
|
await withAppDefinitionLock(parsed.params.id, async () => {
|
|
@@ -1513,6 +1525,7 @@ export async function handleApps(
|
|
|
1513
1525
|
responseHandled = true;
|
|
1514
1526
|
return;
|
|
1515
1527
|
}
|
|
1528
|
+
if (parsed.body.definition !== undefined) writtenDefinition = definition.definition;
|
|
1516
1529
|
const migrated = await migrateAppSchema({
|
|
1517
1530
|
appId: parsed.params.id,
|
|
1518
1531
|
previousDefinition: existing.definition,
|
|
@@ -1553,7 +1566,13 @@ export async function handleApps(
|
|
|
1553
1566
|
jsonError(res, "app not found", 404);
|
|
1554
1567
|
return true;
|
|
1555
1568
|
}
|
|
1556
|
-
|
|
1569
|
+
const warnings =
|
|
1570
|
+
writtenDefinition === undefined ? [] : await scriptCompatWarnings(writtenDefinition);
|
|
1571
|
+
patchAppRoute.respond(res, 200, {
|
|
1572
|
+
app,
|
|
1573
|
+
migration,
|
|
1574
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
1575
|
+
});
|
|
1557
1576
|
return true;
|
|
1558
1577
|
}
|
|
1559
1578
|
|
|
@@ -1568,6 +1587,7 @@ export async function handleApps(
|
|
|
1568
1587
|
}
|
|
1569
1588
|
let app: Awaited<ReturnType<typeof updateApp>> = null;
|
|
1570
1589
|
let migration!: AppMigrationReport;
|
|
1590
|
+
let writtenDefinition: unknown;
|
|
1571
1591
|
let responseHandled = false;
|
|
1572
1592
|
try {
|
|
1573
1593
|
await withAppDefinitionLock(parsed.params.id, async () => {
|
|
@@ -1597,6 +1617,7 @@ export async function handleApps(
|
|
|
1597
1617
|
return;
|
|
1598
1618
|
}
|
|
1599
1619
|
const nextDefinition = definition ?? existing.definition;
|
|
1620
|
+
writtenDefinition = definition;
|
|
1600
1621
|
const migrated = await migrateAppSchema({
|
|
1601
1622
|
appId: parsed.params.id,
|
|
1602
1623
|
previousDefinition: appDefinitionNeedsRepair(existing) ? undefined : existing.definition,
|
|
@@ -1637,7 +1658,13 @@ export async function handleApps(
|
|
|
1637
1658
|
jsonError(res, "app not found", 404);
|
|
1638
1659
|
return true;
|
|
1639
1660
|
}
|
|
1640
|
-
|
|
1661
|
+
const warnings =
|
|
1662
|
+
writtenDefinition === undefined ? [] : await scriptCompatWarnings(writtenDefinition);
|
|
1663
|
+
updateAppRoute.respond(res, 200, {
|
|
1664
|
+
app,
|
|
1665
|
+
migration,
|
|
1666
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
1667
|
+
});
|
|
1641
1668
|
return true;
|
|
1642
1669
|
}
|
|
1643
1670
|
|
package/src/http/config.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
getSwarmConfigs,
|
|
10
10
|
maskSecrets,
|
|
11
11
|
} from "../be/db";
|
|
12
|
+
import { modelProfileRefError } from "../be/db/model-profiles";
|
|
12
13
|
import {
|
|
13
14
|
AGENT_MAX_TASKS_CONFIG_KEY,
|
|
14
15
|
resetAgentMaxTasksMirror,
|
|
@@ -18,14 +19,16 @@ import { fillOrgLogoFromWebsite } from "../be/org-profile";
|
|
|
18
19
|
import { getUserGrant } from "../be/rbac-roles";
|
|
19
20
|
import {
|
|
20
21
|
internalConfigKeyError,
|
|
22
|
+
isApiOnlyConfigKey,
|
|
21
23
|
isInternalConfigKey,
|
|
22
24
|
isReservedConfigKey,
|
|
23
25
|
reservedKeyError,
|
|
24
26
|
validateConfigValue,
|
|
27
|
+
validateExportToEnv,
|
|
25
28
|
} from "../be/swarm-config-guard";
|
|
26
29
|
import { can, isRbacEnabled, type PermissionVerb } from "../rbac";
|
|
27
30
|
import { SwarmConfigSchema } from "../types";
|
|
28
|
-
import { getRequestAuth } from "../utils/request-auth-context";
|
|
31
|
+
import { getRequestAuth, type HttpRequestAuth } from "../utils/request-auth-context";
|
|
29
32
|
import { registerVolatileSecret } from "../utils/secret-scrubber";
|
|
30
33
|
import { reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload } from "./core";
|
|
31
34
|
import { route } from "./route-def";
|
|
@@ -35,16 +38,9 @@ const MAX_ENV_PRESENCE_KEYS = 200;
|
|
|
35
38
|
const SECRETS_FORCE_MASK_NOTE =
|
|
36
39
|
" (secret values masked: this token cannot read secrets in this scope)";
|
|
37
40
|
|
|
38
|
-
// Config keys the API server owns for its own use and must NEVER hand out over
|
|
39
|
-
// HTTP — workers/entrypoints read config to build their env, and the agent-fs
|
|
40
|
-
// bootstrap admin key would let a compromised worker administer the shared org.
|
|
41
|
-
// The API materializes these into its own process.env at boot via
|
|
42
|
-
// getInjectableGlobalConfigs, so no HTTP consumer legitimately needs them.
|
|
43
|
-
const API_ONLY_CONFIG_KEYS = new Set(["API_AGENT_FS_API_KEY", "SLACK_SIGNING_SECRET"]);
|
|
44
|
-
|
|
45
41
|
function stripApiOnlyKeys<T extends { key: string }>(configs: T[]): T[] {
|
|
46
42
|
return configs.filter(
|
|
47
|
-
(config) => !
|
|
43
|
+
(config) => !isApiOnlyConfigKey(config.key) && !isInternalConfigKey(config.key),
|
|
48
44
|
);
|
|
49
45
|
}
|
|
50
46
|
|
|
@@ -53,6 +49,25 @@ function singleHeader(req: IncomingMessage, name: string): string | undefined {
|
|
|
53
49
|
return Array.isArray(raw) ? raw[0] : raw;
|
|
54
50
|
}
|
|
55
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Whether this caller's `/api/config/resolved` carries secret repo rows (the
|
|
54
|
+
* `includeRepoSecrets` of {@link resolveSecretsRead}): a runtime-token agent
|
|
55
|
+
* gets them only with `config.read.secrets`. Claim uses it so an agent's
|
|
56
|
+
* default profile yields only to repo rows that worker's env really gets.
|
|
57
|
+
*/
|
|
58
|
+
export function readsRepoSecrets(
|
|
59
|
+
auth: HttpRequestAuth | null,
|
|
60
|
+
agent: { isLead?: boolean } | null | undefined,
|
|
61
|
+
): boolean {
|
|
62
|
+
if (auth?.kind !== "agent" || !auth.runtimeId) return true;
|
|
63
|
+
return can({
|
|
64
|
+
principal: { kind: "agent", agentId: auth.agentId, isLead: agent?.isLead ?? false },
|
|
65
|
+
verb: "config.read.secrets",
|
|
66
|
+
resource: { kind: "none" },
|
|
67
|
+
source: "http",
|
|
68
|
+
}).allow;
|
|
69
|
+
}
|
|
70
|
+
|
|
56
71
|
async function requestSecretReadScope(
|
|
57
72
|
req: IncomingMessage,
|
|
58
73
|
resolvedScope?: { agentId?: string; repoId?: string },
|
|
@@ -116,6 +131,28 @@ export async function ensureConfigAdmin(
|
|
|
116
131
|
req: IncomingMessage,
|
|
117
132
|
res: ServerResponse,
|
|
118
133
|
verb: Extract<PermissionVerb, "config.write.any" | "config.delete.any">,
|
|
134
|
+
): Promise<boolean> {
|
|
135
|
+
return ensureHttpPermission(
|
|
136
|
+
req,
|
|
137
|
+
res,
|
|
138
|
+
verb,
|
|
139
|
+
verb === "config.write.any"
|
|
140
|
+
? "Writing swarm config requires the lead agent"
|
|
141
|
+
: "Deleting swarm config requires the lead agent",
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The general form of `ensureConfigAdmin`: operators and users pass, guests
|
|
147
|
+
* get a plain 403, and an agent principal (session identity first, then the
|
|
148
|
+
* legacy X-Agent-ID header) must hold `verb`. On denial it writes a 403 with
|
|
149
|
+
* `forbiddenMessage` and returns false.
|
|
150
|
+
*/
|
|
151
|
+
export async function ensureHttpPermission(
|
|
152
|
+
req: IncomingMessage,
|
|
153
|
+
res: ServerResponse,
|
|
154
|
+
verb: PermissionVerb,
|
|
155
|
+
forbiddenMessage: string,
|
|
119
156
|
): Promise<boolean> {
|
|
120
157
|
const auth = getRequestAuth(req);
|
|
121
158
|
if (auth?.kind === "operator" || auth?.kind === "user") return true;
|
|
@@ -132,13 +169,7 @@ export async function ensureConfigAdmin(
|
|
|
132
169
|
source: "http",
|
|
133
170
|
});
|
|
134
171
|
if (!decision.allow) {
|
|
135
|
-
jsonError(
|
|
136
|
-
res,
|
|
137
|
-
verb === "config.write.any"
|
|
138
|
-
? "Writing swarm config requires the lead agent"
|
|
139
|
-
: "Deleting swarm config requires the lead agent",
|
|
140
|
-
403,
|
|
141
|
-
);
|
|
172
|
+
jsonError(res, forbiddenMessage, 403);
|
|
142
173
|
return false;
|
|
143
174
|
}
|
|
144
175
|
return true;
|
|
@@ -276,6 +307,12 @@ const upsertConfig = route({
|
|
|
276
307
|
isSecret: z.boolean().optional(),
|
|
277
308
|
envPath: z.string().nullish(),
|
|
278
309
|
description: z.string().nullish(),
|
|
310
|
+
exportToEnv: z
|
|
311
|
+
.boolean()
|
|
312
|
+
.optional()
|
|
313
|
+
.describe(
|
|
314
|
+
"Export this row into agent process env (default true on create, false for a few server-side secrets; omitted on update keeps the stored flag). Rejected as true for keys only the API server reads.",
|
|
315
|
+
),
|
|
279
316
|
}),
|
|
280
317
|
responses: {
|
|
281
318
|
200: { description: "Config entry upserted", schema: SwarmConfigSchema },
|
|
@@ -442,7 +479,7 @@ export async function handleConfig(
|
|
|
442
479
|
const parsed = await upsertConfig.parse(req, res, pathSegments, queryParams);
|
|
443
480
|
if (!parsed) return true;
|
|
444
481
|
if (!(await ensureConfigAdmin(req, res, "config.write.any"))) return true;
|
|
445
|
-
const { scope, scopeId, key, value, isSecret, envPath, description } = parsed.body;
|
|
482
|
+
const { scope, scopeId, key, value, isSecret, envPath, description, exportToEnv } = parsed.body;
|
|
446
483
|
|
|
447
484
|
if (scope === "global" && scopeId) {
|
|
448
485
|
jsonError(res, "Global scope must not have scopeId", 400);
|
|
@@ -464,7 +501,8 @@ export async function handleConfig(
|
|
|
464
501
|
return true;
|
|
465
502
|
}
|
|
466
503
|
|
|
467
|
-
const validationError =
|
|
504
|
+
const validationError =
|
|
505
|
+
validateConfigValue(key, value) ?? validateExportToEnv(key, exportToEnv);
|
|
468
506
|
if (validationError) {
|
|
469
507
|
jsonError(res, validationError, 400);
|
|
470
508
|
return true;
|
|
@@ -480,6 +518,7 @@ export async function handleConfig(
|
|
|
480
518
|
isSecret: isSecret || false,
|
|
481
519
|
envPath: envPath || null,
|
|
482
520
|
description: description || null,
|
|
521
|
+
exportToEnv,
|
|
483
522
|
});
|
|
484
523
|
// Auto-reload integrations when a global-scoped config changes so callers
|
|
485
524
|
// (CLI, automation, dashboard) don't have to remember to hit /reload.
|
|
@@ -493,7 +532,11 @@ export async function handleConfig(
|
|
|
493
532
|
}
|
|
494
533
|
const result = includeSecrets || !config.isSecret ? config : maskSecrets([config])[0]!;
|
|
495
534
|
upsertConfig.respond(res, 200, result);
|
|
496
|
-
} catch (
|
|
535
|
+
} catch (error) {
|
|
536
|
+
if (modelProfileRefError(error) === "missing") {
|
|
537
|
+
jsonError(res, `Unknown model profile "${String(value)}"`, 400);
|
|
538
|
+
return true;
|
|
539
|
+
}
|
|
497
540
|
jsonError(res, "Failed to upsert config", 500);
|
|
498
541
|
}
|
|
499
542
|
return true;
|
package/src/http/core.ts
CHANGED
|
@@ -3,9 +3,11 @@ import { z } from "zod";
|
|
|
3
3
|
import { initAgentMail, resetAgentMail } from "../agentmail";
|
|
4
4
|
import {
|
|
5
5
|
initAzureDevOps,
|
|
6
|
+
initAzureDevOpsOutbound,
|
|
6
7
|
isAzureDevOpsEnabled,
|
|
7
8
|
resetAzureDevOps,
|
|
8
9
|
resetAzureDevOpsBotIdCache,
|
|
10
|
+
teardownAzureDevOpsOutbound,
|
|
9
11
|
} from "../azure-devops";
|
|
10
12
|
import {
|
|
11
13
|
getAgentById,
|
|
@@ -29,6 +31,7 @@ import { getUserGrant } from "../be/rbac-roles";
|
|
|
29
31
|
import { syncTelemetryEnabled } from "../be/telemetry-enable";
|
|
30
32
|
import { initGitHub, resetGitHub } from "../github";
|
|
31
33
|
import { initGitLab, isGitLabEnabled, resetGitLab } from "../gitlab";
|
|
34
|
+
import { restartChatSdkIfConfigChanged } from "../integrations/chat-sdk/runtime";
|
|
32
35
|
import { initJira, resetJira } from "../jira";
|
|
33
36
|
import { initLinear, resetLinear } from "../linear";
|
|
34
37
|
import { can, decideAdmission, isRbacEnabled } from "../rbac";
|
|
@@ -234,6 +237,8 @@ async function reloadGlobalConfigsAndIntegrationsInner(): Promise<ReloadConfigRe
|
|
|
234
237
|
resetAzureDevOpsBotIdCache();
|
|
235
238
|
initAzureDevOps();
|
|
236
239
|
if (isAzureDevOpsEnabled()) integrations.push("azure-devops");
|
|
240
|
+
teardownAzureDevOpsOutbound();
|
|
241
|
+
if (isAzureDevOpsEnabled()) initAzureDevOpsOutbound();
|
|
237
242
|
|
|
238
243
|
resetLinear();
|
|
239
244
|
if (await initLinear()) integrations.push("linear");
|
|
@@ -243,6 +248,9 @@ async function reloadGlobalConfigsAndIntegrationsInner(): Promise<ReloadConfigRe
|
|
|
243
248
|
|
|
244
249
|
if (await startSlackApp()) integrations.push("slack");
|
|
245
250
|
|
|
251
|
+
// After Slack: the Chat SDK Slack clash check reads SLACK_DISABLE.
|
|
252
|
+
if (await restartChatSdkIfConfigChanged()) integrations.push("chat-sdk");
|
|
253
|
+
|
|
246
254
|
return {
|
|
247
255
|
configsLoaded: updated.length,
|
|
248
256
|
keysUpdated: updated,
|
package/src/http/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import type { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
8
8
|
import { getEnabledCapabilities, hasCapability } from "@/server";
|
|
9
9
|
import { initAgentMail } from "../agentmail";
|
|
10
|
-
import { initAzureDevOps } from "../azure-devops";
|
|
10
|
+
import { initAzureDevOps, initAzureDevOpsOutbound } from "../azure-devops";
|
|
11
11
|
import { drainApi, isApiDraining } from "../be/api-drain";
|
|
12
12
|
import {
|
|
13
13
|
closeDb,
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
import { initGitHub } from "../github";
|
|
42
42
|
import { initGitLab } from "../gitlab";
|
|
43
43
|
import { stopHeartbeat } from "../heartbeat";
|
|
44
|
+
import { startChatSdk, stopChatSdk } from "../integrations/chat-sdk/runtime";
|
|
44
45
|
import { initJira } from "../jira";
|
|
45
46
|
import { initLinear } from "../linear";
|
|
46
47
|
import {
|
|
@@ -81,7 +82,6 @@ import { handleConfig } from "./config";
|
|
|
81
82
|
import { handleContext } from "./context";
|
|
82
83
|
import { handleCore, loadGlobalConfigsIntoEnv } from "./core";
|
|
83
84
|
import { handleDbQuery } from "./db-query";
|
|
84
|
-
import { handleEcosystem } from "./ecosystem";
|
|
85
85
|
import { handleEvents } from "./events";
|
|
86
86
|
import { handleExtensions } from "./extensions";
|
|
87
87
|
import { handleFavorites } from "./favorites";
|
|
@@ -104,6 +104,7 @@ import { handleMcpServers } from "./mcp-servers";
|
|
|
104
104
|
import { closeIdleMcpUserTransports, handleMcpUser } from "./mcp-user";
|
|
105
105
|
import { handleMemory, startMemoryGc, stopMemoryGc } from "./memory";
|
|
106
106
|
import { handleMetrics } from "./metrics";
|
|
107
|
+
import { handleModelProfiles } from "./model-profiles";
|
|
107
108
|
import { handleModelsCatalog } from "./models-catalog";
|
|
108
109
|
import { handleOAuthCallback, startOAuthPendingGc, stopOAuthPendingGc } from "./oauth-callback";
|
|
109
110
|
import { handleGenericOAuth } from "./oauth-generic";
|
|
@@ -345,7 +346,6 @@ const httpServer = createHttpServer(async (req, res) => {
|
|
|
345
346
|
() => handleAgentRegister(req, res, pathSegments, myAgentId),
|
|
346
347
|
() => handlePoll(req, res, pathSegments, queryParams, myAgentId),
|
|
347
348
|
() => handleSessionData(req, res, pathSegments, queryParams, myAgentId),
|
|
348
|
-
() => handleEcosystem(req, res, pathSegments, myAgentId),
|
|
349
349
|
() => handleTrackers(req, res, pathSegments),
|
|
350
350
|
() => handleWebhooks(req, res, pathSegments),
|
|
351
351
|
() => handleAgentsRest(req, res, pathSegments, queryParams, myAgentId),
|
|
@@ -377,6 +377,7 @@ const httpServer = createHttpServer(async (req, res) => {
|
|
|
377
377
|
() => handleDbQuery(req, res, pathSegments, queryParams),
|
|
378
378
|
() => handleMetrics(req, res, pathSegments, queryParams, myAgentId),
|
|
379
379
|
() => handleModelsCatalog(req, res, pathSegments, queryParams),
|
|
380
|
+
() => handleModelProfiles(req, res, pathSegments, queryParams, myAgentId),
|
|
380
381
|
() => handleRepos(req, res, pathSegments, queryParams, myAgentId),
|
|
381
382
|
() => handleSkills(req, res, pathSegments, queryParams, myAgentId),
|
|
382
383
|
() => handleScriptConnections(req, res, pathSegments, queryParams, myAgentId),
|
|
@@ -503,6 +504,9 @@ async function shutdown() {
|
|
|
503
504
|
// Stop Slack bot
|
|
504
505
|
await stopSlackApp();
|
|
505
506
|
|
|
507
|
+
// Stop Chat SDK adapters and drain their background handlers before the DB closes
|
|
508
|
+
await stopChatSdk();
|
|
509
|
+
|
|
506
510
|
// Stop OAuth keepalive
|
|
507
511
|
if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
|
|
508
512
|
const { stopOAuthKeepalive } = await import("../oauth/keepalive");
|
|
@@ -663,6 +667,13 @@ try {
|
|
|
663
667
|
console.error("[startup] Failed to seed pricing rows:", err);
|
|
664
668
|
}
|
|
665
669
|
|
|
670
|
+
try {
|
|
671
|
+
const { ensureModelProfilesSeeded } = await import("../be/boot-seeds");
|
|
672
|
+
await ensureModelProfilesSeeded();
|
|
673
|
+
} catch (err) {
|
|
674
|
+
console.error("[startup] Failed to seed model profiles:", err);
|
|
675
|
+
}
|
|
676
|
+
|
|
666
677
|
try {
|
|
667
678
|
const { ensureRbacSeeded } = await import("../be/boot-seeds");
|
|
668
679
|
ensureRbacSeeded();
|
|
@@ -762,6 +773,16 @@ httpServer
|
|
|
762
773
|
console.error("[Slack] Failed to start, continuing boot without Slack:", err);
|
|
763
774
|
}
|
|
764
775
|
|
|
776
|
+
// Chat SDK channel: never the boot path, so not awaited. Adapter init
|
|
777
|
+
// makes network calls (Slack's auth.test retries for up to ~30 min), and
|
|
778
|
+
// the scheduler, heartbeat and supervisor below must start regardless.
|
|
779
|
+
void startChatSdk().catch((err: unknown) => {
|
|
780
|
+
console.error(
|
|
781
|
+
"[chat-sdk] Failed to start, continuing without Chat SDK:",
|
|
782
|
+
scrubSecrets(err instanceof Error ? err.message : String(err)),
|
|
783
|
+
);
|
|
784
|
+
});
|
|
785
|
+
|
|
765
786
|
// Independent of workers, scheduler targets, and heartbeat agent tasks.
|
|
766
787
|
startQueueStallAlarm();
|
|
767
788
|
|
|
@@ -773,6 +794,7 @@ httpServer
|
|
|
773
794
|
|
|
774
795
|
// Initialize Azure DevOps service-hook handler (if configured)
|
|
775
796
|
initAzureDevOps();
|
|
797
|
+
initAzureDevOpsOutbound();
|
|
776
798
|
|
|
777
799
|
// Initialize AgentMail webhook handler (if configured)
|
|
778
800
|
initAgentMail();
|
package/src/http/integrations.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import Anthropic from "@anthropic-ai/sdk";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import {
|
|
5
|
+
ChatSdkActionError,
|
|
6
|
+
ChatSdkStatusSchema,
|
|
7
|
+
getChatSdkStatus,
|
|
8
|
+
registerTelegramWebhook,
|
|
9
|
+
} from "../integrations/chat-sdk/status";
|
|
4
10
|
import { buildSlackManifest } from "../slack/manifest";
|
|
11
|
+
import { ensureHttpPermission } from "./config";
|
|
5
12
|
import { resolveConfigValue, resolveMcpBaseUrl } from "./config-values";
|
|
6
13
|
import { route } from "./route-def";
|
|
14
|
+
import { jsonError } from "./utils";
|
|
7
15
|
|
|
8
16
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
9
17
|
|
|
@@ -48,6 +56,20 @@ const McpUserConfigSchema = z.object({
|
|
|
48
56
|
|
|
49
57
|
const SlackManifestSchema = z.record(z.string(), z.unknown());
|
|
50
58
|
|
|
59
|
+
const TelegramRegisterWebhookSchema = z.object({
|
|
60
|
+
webhookUrl: z.string(),
|
|
61
|
+
webhookInfo: z.looseObject({
|
|
62
|
+
url: z.string(),
|
|
63
|
+
has_custom_certificate: z.boolean().optional(),
|
|
64
|
+
pending_update_count: z.number().optional(),
|
|
65
|
+
last_error_date: z.number().optional(),
|
|
66
|
+
last_error_message: z.string().optional(),
|
|
67
|
+
max_connections: z.number().optional(),
|
|
68
|
+
ip_address: z.string().optional(),
|
|
69
|
+
allowed_updates: z.array(z.string()).optional(),
|
|
70
|
+
}),
|
|
71
|
+
});
|
|
72
|
+
|
|
51
73
|
// ─── Route Definition ────────────────────────────────────────────────────────
|
|
52
74
|
|
|
53
75
|
const claudeManagedTestRoute = route({
|
|
@@ -94,7 +116,38 @@ const slackManifestRoute = route({
|
|
|
94
116
|
},
|
|
95
117
|
});
|
|
96
118
|
|
|
97
|
-
|
|
119
|
+
const chatSdkStatusRoute = route({
|
|
120
|
+
method: "get",
|
|
121
|
+
path: "/api/integrations/chat/status",
|
|
122
|
+
pattern: ["api", "integrations", "chat", "status"],
|
|
123
|
+
summary:
|
|
124
|
+
"Chat SDK channel status: enabled flag, Slack clash, per-adapter health and webhook URL.",
|
|
125
|
+
tags: ["Integrations"],
|
|
126
|
+
responses: {
|
|
127
|
+
200: {
|
|
128
|
+
description:
|
|
129
|
+
"Per-adapter status. `health` is `disabled` for an adapter that is not running. Never contains secret values.",
|
|
130
|
+
schema: ChatSdkStatusSchema,
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const chatSdkTelegramRegisterWebhookRoute = route({
|
|
136
|
+
method: "post",
|
|
137
|
+
path: "/api/integrations/chat/telegram/register-webhook",
|
|
138
|
+
pattern: ["api", "integrations", "chat", "telegram", "register-webhook"],
|
|
139
|
+
summary:
|
|
140
|
+
"Register this swarm's public Telegram webhook URL and secret token with the Bot API (setWebhook), then return getWebhookInfo.",
|
|
141
|
+
tags: ["Integrations"],
|
|
142
|
+
body: z.object({}).optional(),
|
|
143
|
+
responses: {
|
|
144
|
+
200: { description: "Webhook registered", schema: TelegramRegisterWebhookSchema },
|
|
145
|
+
400: { description: "Telegram is not configured for webhook mode" },
|
|
146
|
+
403: { description: "Only the lead agent or a dashboard user can register the webhook" },
|
|
147
|
+
502: { description: "The Telegram Bot API rejected the call" },
|
|
148
|
+
},
|
|
149
|
+
rbac: { permission: "integration.chat.manage" },
|
|
150
|
+
});
|
|
98
151
|
|
|
99
152
|
// ─── Public handler factory ──────────────────────────────────────────────────
|
|
100
153
|
|
|
@@ -122,6 +175,40 @@ export function createIntegrationsHandler(deps: TestConnectionDeps = {}) {
|
|
|
122
175
|
return true;
|
|
123
176
|
}
|
|
124
177
|
|
|
178
|
+
if (chatSdkStatusRoute.match(req.method, pathSegments)) {
|
|
179
|
+
chatSdkStatusRoute.respond(res, 200, await getChatSdkStatus());
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (chatSdkTelegramRegisterWebhookRoute.match(req.method, pathSegments)) {
|
|
184
|
+
const parsed = await chatSdkTelegramRegisterWebhookRoute.parse(
|
|
185
|
+
req,
|
|
186
|
+
res,
|
|
187
|
+
pathSegments,
|
|
188
|
+
queryParams,
|
|
189
|
+
);
|
|
190
|
+
if (!parsed) return true;
|
|
191
|
+
// Operators and dashboard users pass; agents need the verb (lead-only
|
|
192
|
+
// under the legacy policy).
|
|
193
|
+
if (
|
|
194
|
+
!(await ensureHttpPermission(
|
|
195
|
+
req,
|
|
196
|
+
res,
|
|
197
|
+
"integration.chat.manage",
|
|
198
|
+
"Registering the Telegram webhook requires the lead agent",
|
|
199
|
+
))
|
|
200
|
+
) {
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
chatSdkTelegramRegisterWebhookRoute.respond(res, 200, await registerTelegramWebhook());
|
|
205
|
+
} catch (error) {
|
|
206
|
+
if (!(error instanceof ChatSdkActionError)) throw error;
|
|
207
|
+
jsonError(res, error.message, error.status);
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
|
|
125
212
|
if (mcpUserConfigRoute.match(req.method, pathSegments)) {
|
|
126
213
|
const mcpBaseUrl = await resolveMcpBaseUrl();
|
|
127
214
|
mcpUserConfigRoute.respond(res, 200, { mcpBaseUrl, mcpUserUrl: `${mcpBaseUrl}/mcp-user` });
|
package/src/http/mcp.ts
CHANGED
|
@@ -7,7 +7,12 @@ import { createServer } from "@/server";
|
|
|
7
7
|
import { parseEnvFlag } from "@/utils/env-flag";
|
|
8
8
|
import { getRequestAuth } from "@/utils/request-auth-context";
|
|
9
9
|
import { resolveScriptsOnlyMode } from "@/utils/scripts-only-mode";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
CHAT_TASK_ONLY_TOOLS,
|
|
12
|
+
isChatSdkTask,
|
|
13
|
+
parseTaskToolManifest,
|
|
14
|
+
selectTaskTools,
|
|
15
|
+
} from "@/utils/task-tool-manifest";
|
|
11
16
|
|
|
12
17
|
export type McpTransportActivity = Record<string, number>;
|
|
13
18
|
export type McpSessionAgents = Record<string, string>;
|
|
@@ -218,18 +223,22 @@ export async function handleMcp(
|
|
|
218
223
|
true,
|
|
219
224
|
);
|
|
220
225
|
let preloadedTools: string[] = [];
|
|
226
|
+
const sourceTaskId = headerValue(req.headers["x-source-task-id"]);
|
|
227
|
+
const sourceTask = sourceTaskId ? await getTaskById(sourceTaskId) : undefined;
|
|
228
|
+
// A session bound to a non-chat task never sees chat-reply. Without the
|
|
229
|
+
// header the tool stays, and resolves the agent's current task itself.
|
|
230
|
+
const excludedTools =
|
|
231
|
+
sourceTask && !isChatSdkTask(sourceTask) ? [...CHAT_TASK_ONLY_TOOLS] : [];
|
|
221
232
|
if (preloadEnabled) {
|
|
222
|
-
const taskId = headerValue(req.headers["x-source-task-id"]);
|
|
223
|
-
const task = taskId ? await getTaskById(taskId) : undefined;
|
|
224
233
|
// Never select a manifest using another agent's task. Session-token
|
|
225
234
|
// identity is also checked above, before any MCP session is created.
|
|
226
|
-
if (
|
|
235
|
+
if (sourceTask?.agentId === agentId) {
|
|
227
236
|
const manifestValue =
|
|
228
237
|
configs.find((config) => config.key === "TASK_TOOL_MANIFESTS")?.value ??
|
|
229
238
|
process.env.TASK_TOOL_MANIFESTS ??
|
|
230
239
|
"{}";
|
|
231
240
|
try {
|
|
232
|
-
preloadedTools = selectTaskTools(parseTaskToolManifest(manifestValue),
|
|
241
|
+
preloadedTools = selectTaskTools(parseTaskToolManifest(manifestValue), sourceTask);
|
|
233
242
|
} catch {
|
|
234
243
|
// An invalid deployment value must not prevent tool discovery.
|
|
235
244
|
// Avoid logging its contents, which may contain misfiled secrets.
|
|
@@ -239,6 +248,7 @@ export async function handleMcp(
|
|
|
239
248
|
}
|
|
240
249
|
const server = await createServer({
|
|
241
250
|
preloadedTools,
|
|
251
|
+
excludedTools,
|
|
242
252
|
// Agent row, then global row, then deployment env. A blank agent row
|
|
243
253
|
// resolves to "unset" for that agent.
|
|
244
254
|
enabledTools:
|