@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
|
@@ -25,6 +25,43 @@ export function isPageFeedbackRequested(queryParams: URLSearchParams): boolean {
|
|
|
25
25
|
return value !== "0" && value !== "false";
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
// Keys typed in the overlay must never reach the page's own key handlers. A
|
|
29
|
+
// listener on the overlay runs too late: page capture listeners on window and
|
|
30
|
+
// document fire first. So this guard is served at the top of <head>, before any
|
|
31
|
+
// page script, and is the first window capture listener. For a key from the
|
|
32
|
+
// overlay it stops dispatch outright and hands the event to the overlay
|
|
33
|
+
// (window.__swarmFeedbackKeys.handle). A press that started in the overlay
|
|
34
|
+
// stays owned until its keyup, so the release is swallowed even after the
|
|
35
|
+
// composer closed and focus moved to the page. Every other key passes through.
|
|
36
|
+
// The overlay script repeats it as a fallback; the second run is a no-op.
|
|
37
|
+
const FEEDBACK_KEY_GUARD_JS = `
|
|
38
|
+
(function () {
|
|
39
|
+
if (window.__swarmFeedbackKeys) return;
|
|
40
|
+
var keys = window.__swarmFeedbackKeys = { host: null, handle: null };
|
|
41
|
+
var owned = {};
|
|
42
|
+
function id(e) { return e.code || e.key; }
|
|
43
|
+
function fromOverlay(e) {
|
|
44
|
+
return !!keys.host && typeof e.composedPath === 'function' && e.composedPath().indexOf(keys.host) !== -1;
|
|
45
|
+
}
|
|
46
|
+
function guard(e) {
|
|
47
|
+
var k = id(e);
|
|
48
|
+
var mine = fromOverlay(e);
|
|
49
|
+
if (!mine && !owned[k]) return;
|
|
50
|
+
if (e.type === 'keydown') {
|
|
51
|
+
if (mine) owned[k] = true;
|
|
52
|
+
else if (!e.repeat) { delete owned[k]; return; }
|
|
53
|
+
}
|
|
54
|
+
if (e.type === 'keyup') delete owned[k];
|
|
55
|
+
e.stopImmediatePropagation();
|
|
56
|
+
if (mine && keys.handle) keys.handle(e);
|
|
57
|
+
}
|
|
58
|
+
['keydown', 'keypress', 'keyup'].forEach(function (type) {
|
|
59
|
+
window.addEventListener(type, guard, true);
|
|
60
|
+
});
|
|
61
|
+
window.addEventListener('blur', function () { owned = {}; });
|
|
62
|
+
})();
|
|
63
|
+
`;
|
|
64
|
+
|
|
28
65
|
const FEEDBACK_OVERLAY_JS = `
|
|
29
66
|
(function () {
|
|
30
67
|
var cfg = window.__swarmFeedback;
|
|
@@ -135,6 +172,7 @@ const FEEDBACK_OVERLAY_JS = `
|
|
|
135
172
|
var panel = document.createElement('div');
|
|
136
173
|
panel.className = 'panel';
|
|
137
174
|
var composer = null;
|
|
175
|
+
var composerInput = null;
|
|
138
176
|
root.appendChild(hl);
|
|
139
177
|
root.appendChild(markers);
|
|
140
178
|
root.appendChild(panel);
|
|
@@ -207,11 +245,25 @@ const FEEDBACK_OVERLAY_JS = `
|
|
|
207
245
|
}
|
|
208
246
|
render();
|
|
209
247
|
}
|
|
210
|
-
|
|
211
|
-
if (e.key !== 'Escape') return;
|
|
248
|
+
function onEscape() {
|
|
212
249
|
if (state.draft) { closeComposer(); return; }
|
|
213
250
|
if (state.selecting) setSelecting(false);
|
|
251
|
+
}
|
|
252
|
+
// Escape pressed on the page while selecting. Keys typed in the overlay never
|
|
253
|
+
// get here: the key guard stops them and calls onOverlayKey instead.
|
|
254
|
+
document.addEventListener('keydown', function (e) {
|
|
255
|
+
if (e.key === 'Escape') onEscape();
|
|
214
256
|
}, true);
|
|
257
|
+
function onOverlayKey(e) {
|
|
258
|
+
if (e.type !== 'keydown') return;
|
|
259
|
+
if (e.key === 'Escape') { onEscape(); return; }
|
|
260
|
+
if (e.key === 'Enter' && (e.metaKey || e.ctrlKey) && composerInput && e.composedPath()[0] === composerInput) {
|
|
261
|
+
e.preventDefault();
|
|
262
|
+
commitDraft(composerInput.value);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
window.__swarmFeedbackKeys.host = host;
|
|
266
|
+
window.__swarmFeedbackKeys.handle = onOverlayKey;
|
|
215
267
|
|
|
216
268
|
// ─── Composer ──────────────────────────────────────────────────────────
|
|
217
269
|
function openComposer(target) {
|
|
@@ -230,9 +282,7 @@ const FEEDBACK_OVERLAY_JS = `
|
|
|
230
282
|
add.type = 'button';
|
|
231
283
|
cancel.addEventListener('click', closeComposer);
|
|
232
284
|
add.addEventListener('click', function () { commitDraft(input.value); });
|
|
233
|
-
|
|
234
|
-
if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) { e.preventDefault(); commitDraft(input.value); }
|
|
235
|
-
});
|
|
285
|
+
composerInput = input;
|
|
236
286
|
row.appendChild(cancel);
|
|
237
287
|
row.appendChild(add);
|
|
238
288
|
composer.appendChild(row);
|
|
@@ -253,6 +303,7 @@ const FEEDBACK_OVERLAY_JS = `
|
|
|
253
303
|
function closeComposer() {
|
|
254
304
|
if (composer) composer.remove();
|
|
255
305
|
composer = null;
|
|
306
|
+
composerInput = null;
|
|
256
307
|
state.draft = null;
|
|
257
308
|
hideHighlight();
|
|
258
309
|
}
|
|
@@ -524,5 +575,13 @@ const FEEDBACK_OVERLAY_JS = `
|
|
|
524
575
|
*/
|
|
525
576
|
export function feedbackOverlayScripts(pageId: string): string {
|
|
526
577
|
const config = JSON.stringify({ pageId }).replace(/</g, "\\u003c");
|
|
527
|
-
return `<script>window.__swarmFeedback = ${config};</script><script>${FEEDBACK_OVERLAY_JS}</script>`;
|
|
578
|
+
return `<script>window.__swarmFeedback = ${config};</script><script>${FEEDBACK_KEY_GUARD_JS}${FEEDBACK_OVERLAY_JS}</script>`;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Key guard served at the top of `<head>` when feedback mode is on, so it runs
|
|
583
|
+
* before any page script and its window capture listeners come first.
|
|
584
|
+
*/
|
|
585
|
+
export function feedbackKeyGuardScript(): string {
|
|
586
|
+
return `<script>${FEEDBACK_KEY_GUARD_JS}</script>`;
|
|
528
587
|
}
|
package/src/pages/version.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { createPageVersion, getPage
|
|
1
|
+
import { createPageVersion, getPage } from "../be/db";
|
|
2
|
+
import { getPageEditCounter } from "../be/db/page-versions";
|
|
2
3
|
import type { PageSnapshot, PageVersion } from "../types";
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -8,7 +9,7 @@ import type { PageSnapshot, PageVersion } from "../types";
|
|
|
8
9
|
* Mirrors `snapshotWorkflow` (src/workflows/version.ts:13-44).
|
|
9
10
|
*
|
|
10
11
|
* 1. Load current page state
|
|
11
|
-
* 2. Get max version number for this page (page_versions
|
|
12
|
+
* 2. Get max version number for this page (MAX(page_versions.version))
|
|
12
13
|
* 3. Insert page_versions row with version+1 and the pre-update snapshot
|
|
13
14
|
*
|
|
14
15
|
* Throws on missing parent. Callers in HTTP handlers wrap this in a try/catch
|
|
@@ -24,9 +25,7 @@ export async function snapshotPage(
|
|
|
24
25
|
throw new Error(`Page ${pageId} not found — cannot create snapshot`);
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
const
|
|
28
|
-
const maxVersion = existingVersions.length > 0 ? existingVersions[0]!.version : 0;
|
|
29
|
-
const nextVersion = maxVersion + 1;
|
|
28
|
+
const nextVersion = await getPageEditCounter(pageId);
|
|
30
29
|
|
|
31
30
|
const snapshot: PageSnapshot = {
|
|
32
31
|
title: page.title,
|
|
@@ -8,11 +8,15 @@
|
|
|
8
8
|
* E outputs (gated on AGENT_FS_API_URL and the pages capability)
|
|
9
9
|
* H deployment-gated notes: slack, steering
|
|
10
10
|
* I tools and skills (harness tool discovery, skills, MCP server names)
|
|
11
|
-
* J agent notes: CLAUDE.md
|
|
12
|
-
* K repository (per task)
|
|
11
|
+
* J agent notes: CLAUDE.md, only when edited
|
|
13
12
|
*
|
|
14
|
-
* The runner appends the
|
|
15
|
-
*
|
|
13
|
+
* The runner appends the operator SYSTEM_PROMPT after this.
|
|
14
|
+
*
|
|
15
|
+
* Nothing here may vary per task, requester, or session: the provider caches
|
|
16
|
+
* the system prompt as a prefix, and one changed byte re-bills everything
|
|
17
|
+
* after it. Per-task context (repository, scripts-only Slack, requester
|
|
18
|
+
* profile, cwd warning) goes into the task prompt instead; see
|
|
19
|
+
* `getTaskContextPrompt` and the runner's `buildTaskSessionPrompts`.
|
|
16
20
|
*/
|
|
17
21
|
|
|
18
22
|
import type { ProviderTraits } from "../providers/types";
|
|
@@ -44,13 +48,28 @@ const BOOTSTRAP_TOTAL_MAX_CHARS = 120_000;
|
|
|
44
48
|
|
|
45
49
|
/**
|
|
46
50
|
* Per-section cap applied to the *repo* CLAUDE.md when it is inlined (opencode
|
|
47
|
-
* only). The agent-swarm OSS one is ~18 KB and the biggest
|
|
48
|
-
*
|
|
51
|
+
* only). The agent-swarm OSS one is ~18 KB and the biggest piece of the task
|
|
52
|
+
* context.
|
|
49
53
|
*/
|
|
50
54
|
const REPO_CLAUDE_MD_MAX_CHARS = 12_000;
|
|
51
55
|
|
|
52
|
-
/**
|
|
53
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Providers that get the agent's CLAUDE.md in the system prompt. Claude also
|
|
58
|
+
* keeps the editable copy at ~/.claude/CLAUDE.md but excludes it from its
|
|
59
|
+
* memory load (claude-flag-settings.ts), so it is read once, from the cached
|
|
60
|
+
* system prompt instead of an uncached message.
|
|
61
|
+
*/
|
|
62
|
+
const CLAUDE_MD_INJECT_PROVIDERS: ReadonlySet<string> = new Set([
|
|
63
|
+
"claude",
|
|
64
|
+
"codex",
|
|
65
|
+
"opencode",
|
|
66
|
+
"pi",
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
/** Where each provider's editable CLAUDE.md lives, for the truncation notice. */
|
|
70
|
+
function claudeMdSourcePath(provider: string): string {
|
|
71
|
+
return provider === "claude" ? "~/.claude/CLAUDE.md" : "/workspace/CLAUDE.md";
|
|
72
|
+
}
|
|
54
73
|
|
|
55
74
|
/** Providers that get the repo CLAUDE.md inlined until native loading is verified. */
|
|
56
75
|
const REPO_CLAUDE_MD_INLINE_PROVIDERS: ReadonlySet<string> = new Set(["opencode"]);
|
|
@@ -95,36 +114,61 @@ export type BasePromptArgs = {
|
|
|
95
114
|
soulMd?: string;
|
|
96
115
|
identityMd?: string;
|
|
97
116
|
claudeMd?: string;
|
|
98
|
-
repoContext?: {
|
|
99
|
-
claudeMd?: string | null;
|
|
100
|
-
clonePath: string;
|
|
101
|
-
warning?: string | null;
|
|
102
|
-
autoStashes?: { ref: string; message: string }[];
|
|
103
|
-
guidelines?: {
|
|
104
|
-
prChecks: string[];
|
|
105
|
-
mergeChecks: string[];
|
|
106
|
-
allowMerge?: boolean;
|
|
107
|
-
review: string[];
|
|
108
|
-
} | null;
|
|
109
|
-
};
|
|
110
|
-
/** Slack context from the current task, if present */
|
|
111
|
-
slackContext?: { channelId: string; threadTs?: string };
|
|
112
117
|
/** Pre-fetched skill summaries for the tools and skills section */
|
|
113
118
|
skillsSummary?: { name: string; description: string }[];
|
|
114
119
|
/** Names of the MCP servers connected for this agent */
|
|
115
120
|
mcpServers?: string[];
|
|
116
121
|
};
|
|
117
122
|
|
|
118
|
-
export
|
|
119
|
-
|
|
123
|
+
export type RepoContext = {
|
|
124
|
+
claudeMd?: string | null;
|
|
125
|
+
clonePath: string;
|
|
126
|
+
warning?: string | null;
|
|
127
|
+
autoStashes?: { ref: string; message: string }[];
|
|
128
|
+
guidelines?: {
|
|
129
|
+
prChecks: string[];
|
|
130
|
+
mergeChecks: string[];
|
|
131
|
+
allowMerge?: boolean;
|
|
132
|
+
review: string[];
|
|
133
|
+
} | null;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export type SlackTaskContext = { channelId: string; threadTs?: string };
|
|
137
|
+
|
|
138
|
+
/** Inputs for the per-task context that rides in the task prompt. */
|
|
139
|
+
export type TaskContextPromptArgs = Pick<
|
|
140
|
+
BasePromptArgs,
|
|
141
|
+
"role" | "traits" | "provider" | "scriptsOnly" | "serverCapabilities"
|
|
142
|
+
> & {
|
|
143
|
+
repoContext?: RepoContext;
|
|
144
|
+
/** Slack context from the current task, if present */
|
|
145
|
+
slackContext?: SlackTaskContext;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
function promptFlags(args: Pick<BasePromptArgs, "traits" | "provider" | "scriptsOnly">) {
|
|
120
149
|
const {
|
|
121
150
|
hasMcp = true,
|
|
122
151
|
hasToolSearch = false,
|
|
123
152
|
hasLocalEnvironment: hasLocalEnv = true,
|
|
124
153
|
nativeSkillDiscovery = true,
|
|
125
|
-
} = traits ?? {};
|
|
154
|
+
} = args.traits ?? {};
|
|
155
|
+
const scriptsOnly = args.scriptsOnly ?? process.env.SCRIPTS_ONLY_MCP === "true";
|
|
156
|
+
return {
|
|
157
|
+
hasMcp,
|
|
158
|
+
hasToolSearch,
|
|
159
|
+
hasLocalEnv,
|
|
160
|
+
nativeSkillDiscovery,
|
|
161
|
+
provider: args.provider ?? "claude",
|
|
162
|
+
// Experimental scripts-only MCP surface (code-mode).
|
|
163
|
+
scriptsOnlyMode: hasMcp && scriptsOnly,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export const getBasePrompt = async (args: BasePromptArgs): Promise<string> => {
|
|
168
|
+
const { role, agentId, traits } = args;
|
|
169
|
+
const { hasMcp, hasToolSearch, hasLocalEnv, nativeSkillDiscovery, provider, scriptsOnlyMode } =
|
|
170
|
+
promptFlags(args);
|
|
126
171
|
const steerModes = traits?.steerModes ?? [];
|
|
127
|
-
const provider = args.provider ?? "claude";
|
|
128
172
|
|
|
129
173
|
const defaultsInput = {
|
|
130
174
|
name: args.name ?? agentId,
|
|
@@ -168,8 +212,6 @@ export const getBasePrompt = async (args: BasePromptArgs): Promise<string> => {
|
|
|
168
212
|
|
|
169
213
|
// Experimental scripts-only MCP surface (code-mode): named swarm tools are
|
|
170
214
|
// not registered, so tell the agent everything goes through script-run.
|
|
171
|
-
const scriptsOnly = args.scriptsOnly ?? process.env.SCRIPTS_ONLY_MCP === "true";
|
|
172
|
-
const scriptsOnlyMode = hasMcp && scriptsOnly;
|
|
173
215
|
if (scriptsOnlyMode) {
|
|
174
216
|
const scriptsOnlyResult = await resolveTemplateAsync("system.agent.scripts_only_mode", {});
|
|
175
217
|
prompt += `\n${scriptsOnlyResult.text}`;
|
|
@@ -199,13 +241,6 @@ export const getBasePrompt = async (args: BasePromptArgs): Promise<string> => {
|
|
|
199
241
|
const slackResult = await resolveTemplateAsync("system.agent.slack", {});
|
|
200
242
|
prompt += slackResult.text;
|
|
201
243
|
}
|
|
202
|
-
if (role !== "lead" && args.slackContext && scriptsOnlyMode && slackPromptToolsEnabled) {
|
|
203
|
-
const slackResult = await resolveTemplateAsync("system.agent.scripts_only_mode.slack", {
|
|
204
|
-
slackChannelId: args.slackContext.channelId,
|
|
205
|
-
slackThreadTs: args.slackContext.threadTs ?? "",
|
|
206
|
-
});
|
|
207
|
-
prompt += slackResult.text;
|
|
208
|
-
}
|
|
209
244
|
|
|
210
245
|
if (
|
|
211
246
|
hasMcp &&
|
|
@@ -244,9 +279,9 @@ export const getBasePrompt = async (args: BasePromptArgs): Promise<string> => {
|
|
|
244
279
|
prompt += toolsResult.text;
|
|
245
280
|
}
|
|
246
281
|
|
|
247
|
-
// J. Agent notes (CLAUDE.md)
|
|
248
|
-
// excludes
|
|
249
|
-
//
|
|
282
|
+
// J. Agent notes (CLAUDE.md), only when it differs from the generated
|
|
283
|
+
// default. Claude excludes both ~/.claude/CLAUDE.md and /workspace/CLAUDE.md
|
|
284
|
+
// from its memory load (claude-flag-settings.ts), so this is its only copy.
|
|
250
285
|
if (
|
|
251
286
|
hasLocalEnv &&
|
|
252
287
|
args.claudeMd &&
|
|
@@ -257,10 +292,42 @@ export const getBasePrompt = async (args: BasePromptArgs): Promise<string> => {
|
|
|
257
292
|
BOOTSTRAP_MAX_CHARS,
|
|
258
293
|
Math.max(0, BOOTSTRAP_TOTAL_MAX_CHARS - prompt.length),
|
|
259
294
|
);
|
|
260
|
-
prompt += truncateSection(
|
|
295
|
+
prompt += truncateSection(
|
|
296
|
+
args.claudeMd,
|
|
297
|
+
"## Your notes (CLAUDE.md)",
|
|
298
|
+
claudeMdSourcePath(provider),
|
|
299
|
+
budget,
|
|
300
|
+
);
|
|
261
301
|
}
|
|
262
302
|
|
|
263
|
-
//
|
|
303
|
+
// Blocks start and end with a newline; collapse the seams to one blank line.
|
|
304
|
+
return prompt.replace(/\n{3,}/g, "\n\n");
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Per-task context that used to close the system prompt: the repository block
|
|
309
|
+
* and the scripts-only Slack note. It rides in the task prompt so the system
|
|
310
|
+
* prompt stays byte-identical across an agent's sessions. Empty when the task
|
|
311
|
+
* has neither.
|
|
312
|
+
*/
|
|
313
|
+
export const getTaskContextPrompt = async (args: TaskContextPromptArgs): Promise<string> => {
|
|
314
|
+
const { hasMcp, hasLocalEnv, provider, scriptsOnlyMode } = promptFlags(args);
|
|
315
|
+
let prompt = "";
|
|
316
|
+
|
|
317
|
+
if (
|
|
318
|
+
args.role !== "lead" &&
|
|
319
|
+
args.slackContext &&
|
|
320
|
+
scriptsOnlyMode &&
|
|
321
|
+
areSlackPromptToolsEnabled(process.env, args.serverCapabilities)
|
|
322
|
+
) {
|
|
323
|
+
const slackResult = await resolveTemplateAsync("system.agent.scripts_only_mode.slack", {
|
|
324
|
+
slackChannelId: args.slackContext.channelId,
|
|
325
|
+
slackThreadTs: args.slackContext.threadTs ?? "",
|
|
326
|
+
});
|
|
327
|
+
prompt += slackResult.text;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Repository. Never truncated except the inlined repo CLAUDE.md.
|
|
264
331
|
if (args.repoContext) {
|
|
265
332
|
const repoResult = await resolveTemplateAsync(
|
|
266
333
|
"system.agent.repository",
|
|
@@ -269,8 +336,7 @@ export const getBasePrompt = async (args: BasePromptArgs): Promise<string> => {
|
|
|
269
336
|
prompt += repoResult.text;
|
|
270
337
|
}
|
|
271
338
|
|
|
272
|
-
|
|
273
|
-
return prompt.replace(/\n{3,}/g, "\n\n");
|
|
339
|
+
return prompt.replace(/\n{3,}/g, "\n\n").trim();
|
|
274
340
|
};
|
|
275
341
|
|
|
276
342
|
/**
|
|
@@ -331,7 +397,7 @@ function renderToolsAndSkillsVars(input: {
|
|
|
331
397
|
* the heading lives in the template, the per-task pieces are built here.
|
|
332
398
|
*/
|
|
333
399
|
function renderRepositoryVars(
|
|
334
|
-
repo:
|
|
400
|
+
repo: RepoContext,
|
|
335
401
|
ctx: { hasMcp: boolean; hasLocalEnv: boolean; provider: string },
|
|
336
402
|
): Record<string, string> {
|
|
337
403
|
const vars: Record<string, string> = {
|
|
@@ -432,7 +498,7 @@ export function truncateRepoClaudeMd(content: string, clonePath: string, budget:
|
|
|
432
498
|
function truncateSection(
|
|
433
499
|
content: string | undefined,
|
|
434
500
|
header: string,
|
|
435
|
-
|
|
501
|
+
sourcePath: string,
|
|
436
502
|
budget: number,
|
|
437
503
|
): string {
|
|
438
504
|
if (!content || budget <= 0) return "";
|
|
@@ -441,7 +507,7 @@ function truncateSection(
|
|
|
441
507
|
if (fullSection.length <= budget) return fullSection;
|
|
442
508
|
|
|
443
509
|
const headerStr = `\n\n${header}\n\n`;
|
|
444
|
-
const notice = `\n\n[...truncated, see
|
|
510
|
+
const notice = `\n\n[...truncated, see ${sourcePath} for full content]\n`;
|
|
445
511
|
const contentBudget = budget - headerStr.length - notice.length;
|
|
446
512
|
|
|
447
513
|
if (contentBudget > 0) {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { openAICompatibleBaseUrlVars, openAICompatibleKeyVars } from "@desplega/model-catalog";
|
|
2
|
+
|
|
1
3
|
export const ACP_TARGET_IDS = [
|
|
2
4
|
"opencode",
|
|
3
5
|
"gemini",
|
|
@@ -40,6 +42,10 @@ export const ACP_TARGET_CATALOG: readonly AcpTargetCatalogEntry[] = [
|
|
|
40
42
|
"OPENAI_API_KEY",
|
|
41
43
|
"OPENROUTER_API_KEY",
|
|
42
44
|
"OPENROUTER_BASE_URL",
|
|
45
|
+
// OpenAI-compatible registry providers: keys (canonical and alias),
|
|
46
|
+
// then their `<ID>_BASE_URL` overrides.
|
|
47
|
+
...openAICompatibleKeyVars(),
|
|
48
|
+
...openAICompatibleBaseUrlVars(),
|
|
43
49
|
"GOOGLE_API_KEY",
|
|
44
50
|
"GEMINI_API_KEY",
|
|
45
51
|
"OPENCODE_CONFIG",
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { mkdir, mkdtemp, rm } from "node:fs/promises";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
baseUrlOverride,
|
|
6
|
+
normalizeGrokModel,
|
|
7
|
+
providerBaseUrl,
|
|
8
|
+
providerForModel,
|
|
9
|
+
} from "@desplega/model-catalog";
|
|
5
10
|
import { clampContextPercent, getContextWindowSize } from "../utils/context-window";
|
|
6
11
|
import {
|
|
7
12
|
ACP_TARGET_IDS,
|
|
@@ -9,7 +14,11 @@ import {
|
|
|
9
14
|
getAcpTargetCatalogEntry,
|
|
10
15
|
isAcpTarget,
|
|
11
16
|
} from "./acp-target-catalog";
|
|
12
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
applyOpenRouterBaseUrlOverride,
|
|
19
|
+
buildOpenAICompatibleProviderBlock,
|
|
20
|
+
type OpencodeConfig,
|
|
21
|
+
} from "./opencode-adapter";
|
|
13
22
|
import { applyReasoningEffort } from "./reasoning-effort";
|
|
14
23
|
import type { CostData, CostModelUsage, ProviderEvent, ProviderSessionConfig } from "./types";
|
|
15
24
|
|
|
@@ -140,10 +149,54 @@ function withOpencodeConfig(env: Record<string, string>, model: string): void {
|
|
|
140
149
|
}
|
|
141
150
|
}
|
|
142
151
|
if (model.trim()) value.model = model.trim();
|
|
152
|
+
withCustomProviderBlock(value as OpencodeConfig, model.trim(), env);
|
|
143
153
|
applyOpenRouterBaseUrlOverride(value as OpencodeConfig, env);
|
|
144
154
|
env[key] = JSON.stringify(value);
|
|
145
155
|
}
|
|
146
156
|
|
|
157
|
+
/**
|
|
158
|
+
* OpenCode ships no provider for a registry entry models.dev does not list
|
|
159
|
+
* (`catalog: "registry"`, e.g. `helmcode`), so its models need the custom
|
|
160
|
+
* block. The key stays an `{env:…}` reference: the ACP subprocess env is the
|
|
161
|
+
* forwarded per-task env, where the var holds one picked key, so no literal
|
|
162
|
+
* key lands in `OPENCODE_CONFIG_CONTENT`. A built-in registry provider
|
|
163
|
+
* (`nan`) only gets `options.baseURL` when `<ID>_BASE_URL` is set. Values the
|
|
164
|
+
* operator already set in `OPENCODE_CONFIG_CONTENT` win over the defaults.
|
|
165
|
+
*/
|
|
166
|
+
function withCustomProviderBlock(
|
|
167
|
+
config: OpencodeConfig,
|
|
168
|
+
model: string,
|
|
169
|
+
env: Record<string, string>,
|
|
170
|
+
): void {
|
|
171
|
+
const provider = providerForModel(model);
|
|
172
|
+
if (!provider) return;
|
|
173
|
+
const existing = config.provider?.[provider.id];
|
|
174
|
+
if (provider.catalog !== "registry") {
|
|
175
|
+
const baseURL = baseUrlOverride(provider, env);
|
|
176
|
+
if (!baseURL) return;
|
|
177
|
+
config.provider = {
|
|
178
|
+
...config.provider,
|
|
179
|
+
[provider.id]: { ...existing, options: { baseURL, ...existing?.options } },
|
|
180
|
+
};
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const block = buildOpenAICompatibleProviderBlock(
|
|
184
|
+
provider,
|
|
185
|
+
`{env:${provider.envVar}}`,
|
|
186
|
+
model.slice(provider.id.length + 1),
|
|
187
|
+
providerBaseUrl(provider, env),
|
|
188
|
+
);
|
|
189
|
+
config.provider = {
|
|
190
|
+
...config.provider,
|
|
191
|
+
[provider.id]: {
|
|
192
|
+
...block,
|
|
193
|
+
...existing,
|
|
194
|
+
options: { ...block.options, ...existing?.options },
|
|
195
|
+
models: { ...block.models, ...existing?.models },
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
147
200
|
function parseCommand(command: string, args: string | undefined): string[] {
|
|
148
201
|
const trimmed = command.trim();
|
|
149
202
|
if (!trimmed) {
|
|
@@ -306,7 +359,7 @@ const copilotTargetProfile: AcpTargetProfile = {
|
|
|
306
359
|
},
|
|
307
360
|
};
|
|
308
361
|
|
|
309
|
-
/** Qwen Code's `--auth-type` choices (0.25.
|
|
362
|
+
/** Qwen Code's `--auth-type` choices (0.25.2). `qwen-oauth` needs a browser, so it is left out. */
|
|
310
363
|
const QWEN_AUTH_TYPES = ["openai", "openai-responses", "anthropic", "gemini", "vertex-ai"] as const;
|
|
311
364
|
|
|
312
365
|
// Qwen Code is a Gemini CLI fork: QWEN_SYSTEM_MD replaces its built-in prompt
|
|
@@ -44,7 +44,7 @@ import type {
|
|
|
44
44
|
* default; the image installs exactly this version and the per-task settings
|
|
45
45
|
* set `amp.updates.mode: "disabled"`. Bump it deliberately, with a live run.
|
|
46
46
|
*/
|
|
47
|
-
export const AMP_PACKAGE = "@ampcode/cli@0.0.
|
|
47
|
+
export const AMP_PACKAGE = "@ampcode/cli@0.0.1792152053-g57ff9b";
|
|
48
48
|
|
|
49
49
|
/** MCP server name. Amp exposes its tools as `agent_swarm` / `store_progress` (dashes become underscores). */
|
|
50
50
|
const AMP_MCP_SERVER_NAME = "agent-swarm";
|
|
@@ -1041,7 +1041,7 @@ class ClaudeSession implements ProviderSession {
|
|
|
1041
1041
|
"--allow-dangerously-skip-permissions",
|
|
1042
1042
|
"--permission-mode",
|
|
1043
1043
|
"bypassPermissions",
|
|
1044
|
-
// Skip
|
|
1044
|
+
// Skip both on-disk copies of claudeMd; the system prompt already carries it.
|
|
1045
1045
|
// createSession merged caller `--settings` into these, so this is the only one.
|
|
1046
1046
|
"--settings",
|
|
1047
1047
|
JSON.stringify(this.flagSettings),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
3
4
|
import { scrubSecrets } from "../utils/secret-scrubber";
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -9,17 +10,28 @@ import { scrubSecrets } from "../utils/secret-scrubber";
|
|
|
9
10
|
* and it walks up from its cwd (`/workspace/...`) to load `/workspace/CLAUDE.md`
|
|
10
11
|
* as project memory too, so every Claude session paid for the notes twice.
|
|
11
12
|
*
|
|
12
|
-
* `claudeMdExcludes` drops
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* `claudeMdExcludes` drops that path from Claude's memory load. The file stays
|
|
14
|
+
* on disk for the other harnesses (one container can live-swap providers
|
|
15
|
+
* mid-run), and repo-level `CLAUDE.md` files still load.
|
|
16
|
+
*
|
|
17
|
+
* The user-memory copy (`~/.claude/CLAUDE.md`) is excluded too: the system
|
|
18
|
+
* prompt carries the same notes (base-prompt.ts block J), where the provider
|
|
19
|
+
* caches them across sessions. Claude would load the user-memory copy into an
|
|
20
|
+
* uncached message instead. The SessionStart hook still writes that file: it
|
|
21
|
+
* is the copy the agent edits and the Stop hook syncs back to the profile.
|
|
15
22
|
*/
|
|
16
23
|
export const WORKSPACE_CLAUDE_MD_EXCLUDE = "/workspace/CLAUDE.md";
|
|
17
24
|
|
|
25
|
+
/** `~/.claude/CLAUDE.md` for the HOME the Claude session runs under. */
|
|
26
|
+
export function userClaudeMdExclude(home: string = process.env.HOME ?? homedir()): string {
|
|
27
|
+
return join(home, ".claude", "CLAUDE.md");
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
export type ClaudeFlagSettings = Record<string, unknown> & { claudeMdExcludes: string[] };
|
|
19
31
|
|
|
20
32
|
/** Flag-level settings (`--settings` / SDK `settings`) for every Claude session. */
|
|
21
33
|
export function claudeFlagSettings(): ClaudeFlagSettings {
|
|
22
|
-
return { claudeMdExcludes: [WORKSPACE_CLAUDE_MD_EXCLUDE] };
|
|
34
|
+
return { claudeMdExcludes: [WORKSPACE_CLAUDE_MD_EXCLUDE, userClaudeMdExclude()] };
|
|
23
35
|
}
|
|
24
36
|
|
|
25
37
|
const SETTINGS_FLAG = "--settings";
|
|
@@ -806,7 +806,7 @@ class ClaudeManagedSession implements ProviderSession {
|
|
|
806
806
|
export class ClaudeManagedAdapter implements ProviderAdapter {
|
|
807
807
|
readonly name = "claude-managed";
|
|
808
808
|
// Anthropic's cloud sandbox calls back into our /mcp endpoint, but the worker
|
|
809
|
-
// process is a thin SSE relay — no /workspace, no
|
|
809
|
+
// process is a thin SSE relay — no /workspace, no agent-fs, no skills FS.
|
|
810
810
|
readonly traits: ProviderTraits = {
|
|
811
811
|
hasMcp: true,
|
|
812
812
|
hasToolSearch: false,
|
|
@@ -32,6 +32,7 @@ type ClaudeUsage = {
|
|
|
32
32
|
cache_read_input_tokens?: number;
|
|
33
33
|
cache_creation_input_tokens?: number;
|
|
34
34
|
thinking_input_tokens?: number;
|
|
35
|
+
output_tokens_details?: { thinking_tokens?: number };
|
|
35
36
|
cache_creation?: Record<string, unknown>;
|
|
36
37
|
};
|
|
37
38
|
|
|
@@ -125,7 +126,11 @@ function costFromResult(
|
|
|
125
126
|
cacheWriteTokens: usage?.cache_creation_input_tokens ?? 0,
|
|
126
127
|
cacheWrite5mTokens: finiteNumber(cacheCreation?.ephemeral_5m_input_tokens),
|
|
127
128
|
cacheWrite1hTokens: finiteNumber(cacheCreation?.ephemeral_1h_input_tokens),
|
|
128
|
-
|
|
129
|
+
// A subset of output_tokens, already billed at the output rate.
|
|
130
|
+
thinkingTokens:
|
|
131
|
+
tokenCount(usage?.output_tokens_details?.thinking_tokens) ??
|
|
132
|
+
tokenCount(usage?.thinking_input_tokens) ??
|
|
133
|
+
0,
|
|
129
134
|
models,
|
|
130
135
|
durationMs: json.duration_ms || 0,
|
|
131
136
|
numTurns: json.num_turns ?? null,
|
|
@@ -37,7 +37,7 @@ import type {
|
|
|
37
37
|
} from "./types";
|
|
38
38
|
|
|
39
39
|
// npm's `latest` is older and lacks the JSON/stdin contract used here.
|
|
40
|
-
export const DSH_PACKAGE = "@deepseek-ai/dsh@0.2.1-alpha.
|
|
40
|
+
export const DSH_PACKAGE = "@deepseek-ai/dsh@0.2.1-alpha.5";
|
|
41
41
|
|
|
42
42
|
export function checkDshCredentials(env: Record<string, string | undefined>): CredStatus {
|
|
43
43
|
return env.DEEPSEEK_API_KEY?.trim() || env.OPENROUTER_API_KEY?.trim()
|