@desplega.ai/agent-swarm 2.5.3 → 2.6.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 +2 -2
- package/dist/{acp-adapter-gr2fcyyj.js → acp-adapter-dgfakfpw.js} +9 -9
- package/dist/{actions-wv766ghf.js → actions-fbqma8aa.js} +21 -21
- package/dist/{amp-adapter-speb906t.js → amp-adapter-en0jy6hs.js} +4 -4
- package/dist/{app-ag29n14f.js → app-k8a5cgpp.js} +3 -3
- package/dist/{assistant-3x8bz3eg.js → assistant-a16433gr.js} +30 -26
- package/dist/{boot-reembed-jsmfrpzf.js → boot-reembed-6c1sjfnr.js} +1 -1
- package/dist/{boot-reembed-5b3d2eea.js → boot-reembed-f4nn561n.js} +1 -1
- package/dist/{boot-scrub-sweep-s73gerxy.js → boot-scrub-sweep-d4w9gajf.js} +4 -4
- package/dist/{boot-seeds-5zmax2wr.js → boot-seeds-9bmkspyw.js} +4 -4
- package/dist/{claude-adapter-hswdnm3t.js → claude-adapter-nys1kjxa.js} +9 -9
- package/dist/{claude-managed-adapter-cvbzj1h6.js → claude-managed-adapter-55207973.js} +3 -3
- package/dist/{claude-managed-setup-3k8m3hhc.js → claude-managed-setup-3cm35gey.js} +11 -4
- package/dist/{claude-sdk-session-fkbyk66x.js → claude-sdk-session-nw5yd8cp.js} +9313 -9260
- package/dist/{cli-210xd1f4.js → cli-03gg9pd1.js} +4 -4
- package/dist/{cli-kxpfx2xr.js → cli-0z1xjzwa.js} +2 -2
- package/dist/cli-1tem6ns9.js +894 -0
- package/dist/{cli-25j01dpj.js → cli-24j1jeeb.js} +3 -3
- package/dist/{cli-ta8bd7th.js → cli-2sjhpsns.js} +2 -2
- package/dist/{cli-p859hcc8.js → cli-39aet655.js} +2 -2
- package/dist/{cli-g1cw7xtt.js → cli-39rrw8yp.js} +1 -1
- package/dist/{cli-e2ar4bp1.js → cli-3aqd4jaa.js} +121 -47
- package/dist/{cli-jjznk3f7.js → cli-3fwqy71j.js} +69 -35
- package/dist/{cli-p9rafdrb.js → cli-3gfvmzht.js} +7 -7
- package/dist/{cli-03vpq45j.js → cli-3ndmpxxv.js} +2 -2
- package/dist/{cli-aecdcr77.js → cli-4hxrf0p4.js} +228 -74
- package/dist/{cli-mz9afxxf.js → cli-4rf0f5vg.js} +15 -3
- package/dist/{cli-qzme5949.js → cli-5rj83bam.js} +284 -202
- package/dist/{cli-fsdprwrg.js → cli-5sckpqcx.js} +2 -2
- package/dist/{cli-cz5nmdxt.js → cli-683y0b3a.js} +2 -2
- package/dist/{cli-3ngdk5te.js → cli-6y51ryva.js} +2 -2
- package/dist/{cli-n4c8e3s5.js → cli-708wdy32.js} +1 -1
- package/dist/{cli-pasyvjmm.js → cli-737pyqxr.js} +1 -1
- package/dist/{cli-gx4rm0qx.js → cli-7enjwya9.js} +1 -1
- package/dist/{cli-6x9ma5w5.js → cli-803188pb.js} +1 -1
- package/dist/{cli-avdvgcay.js → cli-9abdgn5t.js} +28 -9
- package/dist/{cli-99xgw26r.js → cli-a2rr0fmg.js} +1 -1
- package/dist/{cli-e5bxnjps.js → cli-a34pr3w1.js} +7 -7
- package/dist/{cli-502eqv93.js → cli-abkm71vr.js} +1 -1
- package/dist/{cli-mmhj8vd7.js → cli-ag2yrnt5.js} +11 -2
- package/dist/{cli-n45mr7zh.js → cli-aj8djyqt.js} +5 -5
- package/dist/{cli-1fc85mvt.js → cli-art7c1zh.js} +5 -5
- package/dist/{cli-40jsnrjm.js → cli-az25fn5f.js} +10 -8
- package/dist/{cli-9s05422w.js → cli-bqztfyve.js} +1 -1
- package/dist/{cli-bn0rewsy.js → cli-c081bj3b.js} +2 -2
- package/dist/{cli-svrj71pg.js → cli-c2habvsf.js} +12 -12
- package/dist/{cli-s49hpn37.js → cli-ca6banwz.js} +85 -19
- package/dist/{cli-hhxjnjzs.js → cli-cz37jqss.js} +12 -10
- package/dist/{cli-6n8axjv1.js → cli-d2dpf95n.js} +2 -2
- package/dist/{cli-tx00c0h6.js → cli-dqygeeh5.js} +17 -1
- package/dist/{cli-z21whrrg.js → cli-emhjcj2y.js} +17 -17
- package/dist/{cli-e8jyq7d8.js → cli-esakngh8.js} +7 -3
- package/dist/{cli-ha9rmwgq.js → cli-fb8m699c.js} +2 -2
- package/dist/{cli-35gtk1p6.js → cli-ffvsj2qw.js} +44 -13
- package/dist/{cli-ce0ak9ms.js → cli-g20jjwt4.js} +26 -26
- package/dist/{cli-kxawjrxg.js → cli-g8ka5j4j.js} +772 -194
- package/dist/{cli-vwn81jbs.js → cli-gf95q3bm.js} +5 -5
- package/dist/{cli-s53vp709.js → cli-gnsb1zxa.js} +2 -2
- package/dist/{cli-nwyw3zhg.js → cli-gxee0bqa.js} +1 -1
- package/dist/{cli-gpv60278.js → cli-hfeb68z4.js} +7 -7
- package/dist/{cli-0ebey9hg.js → cli-j6rktc91.js} +1 -1
- package/dist/{cli-ewm3pwbq.js → cli-k21gx5ht.js} +46 -23
- package/dist/{cli-egjggehm.js → cli-kf4jree9.js} +2 -2
- package/dist/{cli-dabehxhp.js → cli-kt907da6.js} +1 -1
- package/dist/{cli-p0rzjkya.js → cli-m5a9m0ak.js} +32 -13
- package/dist/{cli-fzcn3d87.js → cli-m70bajzr.js} +3 -3
- package/dist/{cli-w1zwctj2.js → cli-mtnj4fwa.js} +11 -5
- package/dist/{cli-gpsz7g88.js → cli-mvjz5an3.js} +16 -12
- package/dist/{cli-hcpj2xqz.js → cli-n7asmce6.js} +225 -3
- package/dist/{cli-y561h5a9.js → cli-nn6vx2mq.js} +5 -5
- package/dist/cli-nq677csy.js +140 -0
- package/dist/{cli-a5ebc95n.js → cli-pfk92eqz.js} +18 -15
- package/dist/{cli-p6zs9h4y.js → cli-rr7zx19j.js} +767 -249
- package/dist/{cli-qgf8emrn.js → cli-sqma6vw1.js} +10 -7
- package/dist/{cli-0xk505e8.js → cli-sxgtf5fw.js} +1 -1
- package/dist/{cli-nzfnt2gs.js → cli-tf1n0r0b.js} +1 -1
- package/dist/{cli-qqzmjxkf.js → cli-v49fkghp.js} +11 -6
- package/dist/{cli-x77gen2p.js → cli-w2656ka1.js} +7 -7
- package/dist/{cli-5kqnemen.js → cli-yvy48785.js} +1 -1
- package/dist/{cli-8s5wx3nz.js → cli-zqne1qcj.js} +44 -17
- package/dist/cli.js +22 -22
- package/dist/{codex-adapter-n8ka66vf.js → codex-adapter-d95q4qsn.js} +7 -7
- package/dist/{codex-hook-e2he7aca.js → codex-hook-brpnycn5.js} +1 -1
- package/dist/{codex-login-rn7c5gxt.js → codex-login-8cg0vhf2.js} +1 -1
- package/dist/{codex-session-runner-fsebts37.js → codex-session-runner-gdwd8h0c.js} +8 -8
- package/dist/{commands-t04rt2pc.js → commands-jqmgk54b.js} +2 -2
- package/dist/{controller-rgna04r2.js → controller-z3jq589f.js} +30 -4
- package/dist/{controllers-connect-bqm1rtft.js → controllers-connect-r2za39ef.js} +23 -23
- package/dist/{cursor-adapter-swr2k95y.js → cursor-adapter-4mr4jgkw.js} +2 -3
- package/dist/{db-a4m7haw0.js → db-ppv2tze7.js} +3 -3
- package/dist/{db-24ck09xy.js → db-w36wwb5g.js} +4 -2
- package/dist/{devin-adapter-4ycy4vrf.js → devin-adapter-byen2cxt.js} +1 -1
- package/dist/{dispatcher-nwf9ss0q.js → dispatcher-pv5h77vf.js} +20 -20
- package/dist/{docker-nfy2gc8t.js → docker-fdzyewpz.js} +4 -4
- package/dist/{dsh-adapter-kpdnhjst.js → dsh-adapter-d4pdpb3r.js} +2 -3
- package/dist/{e2b-9gkdhm3c.js → e2b-222hsajc.js} +2 -2
- package/dist/{e2b-cjtf8k1z.js → e2b-fn3zacvt.js} +2 -2
- package/dist/{easter-egg-3d-e4qv8dxj.js → easter-egg-3d-4sp4dvmc.js} +1 -1
- package/dist/{event-bus-3z78ep5n.js → event-bus-pghg8hqy.js} +1 -1
- package/dist/{execute-0xpz8950.js → execute-jev839y1.js} +1 -1
- package/dist/{external-channel-j1e2p34p.js → external-channel-y6nkzhnn.js} +2 -2
- package/dist/{grok-adapter-qtjz0whk.js → grok-adapter-t08b9ntm.js} +10 -10
- package/dist/handlers-eqsnmv95.js +41 -0
- package/dist/{heartbeat-vtesda5d.js → heartbeat-vn31xwdk.js} +23 -23
- package/dist/{hook-b2hhj6rd.js → hook-6d0zbvvt.js} +6 -5
- package/dist/{hook-8wqaszda.js → hook-cpjs8q51.js} +13 -7
- package/dist/{http-mxcqhhcs.js → http-9c6medda.js} +1085 -136
- package/dist/{index-spwxjgay.js → index-38t35h0n.js} +20 -20
- package/dist/{index-1r8wfpzs.js → index-g6k9tctj.js} +1 -1
- package/dist/{index-srg522m6.js → index-k0yt1tvq.js} +20 -20
- package/dist/{index-31ceyf42.js → index-pkma1yf8.js} +1 -1
- package/dist/{index-n1vbvta9.js → index-qhjf2htm.js} +29 -24
- package/dist/index-yqgbfgaj.js +43 -0
- package/dist/{keepalive-dsd8rtgx.js → keepalive-em0117bp.js} +4 -4
- package/dist/lead-23e7z59t.js +79 -0
- package/dist/{maintenance-jqmqwnet.js → maintenance-kbme3qy9.js} +1 -1
- package/dist/{oauth-refresh-sweep-q2c3bnvm.js → oauth-refresh-sweep-xysj4yse.js} +3 -3
- package/dist/{onboard-w4yd7s8t.js → onboard-p6q0vz97.js} +3 -3
- package/dist/{opencode-adapter-9tppvxar.js → opencode-adapter-esv3k9yn.js} +7 -7
- package/dist/{otel-impl-f36byzbd.js → otel-impl-54qhqh1z.js} +2 -2
- package/dist/{pi-mono-adapter-tqsge1ay.js → pi-mono-adapter-mymbwhj0.js} +41 -14
- package/dist/{pricing-refresh-xvak5p4v.js → pricing-refresh-yb75wv33.js} +3 -3
- package/dist/{rbac-roles-gfn30fb8.js → rbac-roles-1vp2mw4p.js} +2 -2
- package/dist/{rbac-roles-682k2mt5.js → rbac-roles-dexhc9x8.js} +1 -1
- package/dist/render-v2-tjay5hhf.js +16 -0
- package/dist/{resume-2dvq348g.js → resume-8ayf37g5.js} +11 -9
- package/dist/{runtime-bt5pkpm1.js → runtime-hqe5cqcd.js} +1 -1
- package/dist/{session-access-7f21ekq9.js → session-access-fdhp987s.js} +4 -4
- package/dist/session-source-backfill-qgtc86z1.js +110 -0
- package/dist/{setup-epffxtbk.js → setup-4rrmqcq3.js} +1 -1
- package/dist/{virtual-modules-mnfbh5mr.js → virtual-modules-52km00d6.js} +2 -2
- package/dist/{work-objects-xz1a5rqk.js → work-objects-p28fgd70.js} +23 -23
- package/dist/worker-e3w7vye1.js +79 -0
- package/dist/{x-pbpezr0s.js → x-wxrzvzx8.js} +2 -2
- package/openapi.json +1323 -16
- package/package.json +5 -5
- package/plugin/commands/create-pr.md +2 -2
- package/plugin/pi-skills/create-pr/SKILL.md +2 -2
- package/src/assets/source-key.ts +95 -0
- package/src/be/db/api-keys.ts +80 -0
- package/src/be/db/approvals.ts +48 -0
- package/src/be/db/session-labels.ts +28 -0
- package/src/be/db/session-moves.ts +5 -6
- package/src/be/db/session-tree.ts +153 -14
- package/src/be/db/tasks/read.ts +11 -0
- package/src/be/db/tasks/write.ts +21 -6
- package/src/be/db/workflow-idempotency.ts +183 -0
- package/src/be/db/workflow-runs.ts +500 -7
- package/src/be/db-retention.ts +61 -6
- package/src/be/db.ts +126 -131
- package/src/be/memory/providers/openai-embedding.ts +5 -1
- package/src/be/migrations/242_workflow_idempotency_keys.sql +40 -0
- package/src/be/migrations/244_api_key_validation.sql +4 -0
- package/src/be/onboarding.ts +4 -0
- package/src/be/scripts/typecheck.ts +1 -1
- package/src/be/sealed-json.ts +1 -0
- package/src/be/seed-scripts/catalog/compound-insights.inline.ts +2 -2
- package/src/be/seed-scripts/catalog/compound-insights.ts +2 -2
- package/src/be/seed-skills/bundled-files.generated.json +1 -1
- package/src/be/session-source-backfill.ts +163 -0
- package/src/be/sql-connections.ts +7 -1
- package/src/be/swarm-config-guard.ts +3 -0
- package/src/be/users.ts +9 -0
- package/src/comb/review-batch.ts +28 -1
- package/src/comb/templates.ts +7 -2
- package/src/commands/claude-managed-setup.ts +7 -1
- package/src/commands/controller.ts +33 -0
- package/src/commands/credential-refresh.ts +76 -1
- package/src/commands/credential-wait.ts +2 -2
- package/src/commands/provider-credentials.ts +210 -170
- package/src/commands/runner.ts +31 -6
- package/src/extensions/apply-task-create.ts +64 -11
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/extensions/contract.ts +30 -0
- package/src/extensions/dispatcher.ts +4 -0
- package/src/extensions/post-bridge.ts +8 -0
- package/src/hooks/context-bound-note.ts +196 -0
- package/src/hooks/hook.ts +12 -0
- package/src/http/all-routes.ts +2 -0
- package/src/http/api-keys.ts +53 -0
- package/src/http/assets.ts +15 -0
- package/src/http/codex-oauth-accounts.ts +191 -0
- package/src/http/comb.ts +15 -2
- package/src/http/config.ts +49 -17
- package/src/http/core.ts +6 -0
- package/src/http/fleet-benchmark.ts +5 -2
- package/src/http/idempotency-key.ts +117 -0
- package/src/http/index.ts +11 -0
- package/src/http/integrations.ts +5 -1
- package/src/http/kv.ts +8 -3
- package/src/http/onboarding.ts +6 -1
- package/src/http/pool-keys.ts +354 -0
- package/src/http/sessions.ts +37 -12
- package/src/http/stats.ts +1 -0
- package/src/http/status.ts +26 -12
- package/src/http/tasks.ts +3 -0
- package/src/http/used-by.ts +7 -2
- package/src/http/workflows.ts +207 -33
- package/src/integrations/chat-sdk/inbound.ts +27 -0
- package/src/kv-reserved-namespaces.ts +19 -0
- package/src/prompts/context-bound-note.ts +48 -0
- package/src/prompts/session-templates.ts +25 -1
- package/src/providers/acp-targets.ts +1 -1
- package/src/providers/amp-adapter.ts +30 -8
- package/src/providers/claude-adapter.ts +34 -5
- package/src/providers/claude-managed-adapter.ts +42 -9
- package/src/providers/claude-sdk-session.ts +10 -0
- package/src/providers/claude-session-events.ts +13 -0
- package/src/providers/codex-adapter.ts +83 -11
- package/src/providers/opencode-adapter.ts +18 -0
- package/src/providers/pi-mono-adapter.ts +35 -0
- package/src/runtime-providers/docker.ts +6 -2
- package/src/scheduler/scheduler.ts +3 -2
- package/src/scripts-runtime/swarm-sdk.ts +7 -1
- package/src/scripts-runtime/types/stdlib.d.ts +1 -1
- package/src/scripts-runtime/types/swarm-extension.d.ts +52 -8
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -1
- package/src/slack/assistant.ts +7 -0
- package/src/slack/channel-labels.ts +74 -0
- package/src/slack/handlers.ts +8 -0
- package/src/slack/inbound-files.ts +5 -2
- package/src/slack/thread-buffer.ts +4 -0
- package/src/tasks/sibling-awareness.ts +12 -3
- package/src/telemetry-context.ts +5 -6
- package/src/telemetry-identity.ts +3 -3
- package/src/tests/amp-adapter.test.ts +97 -0
- package/src/tests/api-keys-validation.test.ts +170 -0
- package/src/tests/approval-requests.test.ts +10 -7
- package/src/tests/approval-sweeps.test.ts +12 -6
- package/src/tests/base-prompt.test.ts +1 -1
- package/src/tests/claude-hook-output.test.ts +79 -1
- package/src/tests/claude-managed-adapter.test.ts +321 -0
- package/src/tests/claude-routes-e2e.test.ts +7 -2
- package/src/tests/codex-adapter.test.ts +163 -0
- package/src/tests/codex-credential-pools.test.ts +120 -0
- package/src/tests/codex-gateway-route.test.ts +165 -0
- package/src/tests/codex-oauth-accounts.test.ts +357 -0
- package/src/tests/comb-review-batch.test.ts +63 -2
- package/src/tests/config-pool-keys.test.ts +533 -0
- package/src/tests/context-bound-note.test.ts +269 -0
- package/src/tests/credential-check.test.ts +290 -2
- package/src/tests/credential-refresh.test.ts +172 -1
- package/src/tests/db-retention.test.ts +9 -3
- package/src/tests/db-task-read-contract.test.ts +1 -0
- package/src/tests/db-task-write-contract.test.ts +1 -3
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/extensions-pre-task.test.ts +325 -0
- package/src/tests/fetch-resolved-env.test.ts +17 -0
- package/src/tests/fixtures/extensions/record-blocks/hooks.ts +10 -0
- package/src/tests/fixtures/extensions/record-blocks/manifest.json +7 -0
- package/src/tests/fixtures/extensions/record-task-create/hooks.ts +9 -0
- package/src/tests/fixtures/extensions/record-task-create/manifest.json +7 -0
- package/src/tests/fixtures/fake-amp.ts +22 -8
- package/src/tests/fixtures/held-template-render.ts +42 -0
- package/src/tests/fixtures/workflow-idempotency-trigger.child.ts +73 -0
- package/src/tests/fleet-benchmark.test.ts +8 -0
- package/src/tests/get-workflow-run-tool.test.ts +98 -0
- package/src/tests/integrations-http.test.ts +32 -2
- package/src/tests/internal-ai/complete-structured.test.ts +37 -1
- package/src/tests/internal-ai/credentials.test.ts +23 -0
- package/src/tests/kv-http.test.ts +32 -0
- package/src/tests/kv-tool.test.ts +25 -0
- package/src/tests/multi-runtime-registration.test.ts +12 -12
- package/src/tests/onboarding.test.ts +108 -1
- package/src/tests/openai-embedding-credentials.test.ts +35 -0
- package/src/tests/openapi-route-headers.test.ts +2 -0
- package/src/tests/opencode-adapter.test.ts +134 -0
- package/src/tests/openrouter-attribution-call-sites.test.ts +2 -2
- package/src/tests/org-website.test.ts +36 -0
- package/src/tests/pi-mono-adapter.test.ts +105 -0
- package/src/tests/prompt-template-session.test.ts +4 -3
- package/src/tests/provider-key-probes.test.ts +181 -0
- package/src/tests/rbac-e2e-helpers.test.ts +88 -1
- package/src/tests/rbac-e2e-helpers.ts +36 -11
- package/src/tests/runner-push-delivery.test.ts +25 -0
- package/src/tests/runtime-controller-liveness.test.ts +133 -0
- package/src/tests/runtime-providers-docker.test.ts +2 -0
- package/src/tests/script-connections.test.ts +5 -0
- package/src/tests/script-run-config-scope.test.ts +91 -3
- package/src/tests/script-runs-retention.test.ts +212 -0
- package/src/tests/sdk-allowlist.test.ts +39 -0
- package/src/tests/session-logs.test.ts +70 -0
- package/src/tests/session-source-backfill.test.ts +429 -0
- package/src/tests/session-source-keys.test.ts +236 -0
- package/src/tests/session-source-labels.test.ts +419 -0
- package/src/tests/sessions-detail-batch.test.ts +2 -0
- package/src/tests/sessions-move.test.ts +131 -0
- package/src/tests/sessions-tree.test.ts +336 -2
- package/src/tests/slack-inbound-files.test.ts +103 -23
- package/src/tests/status.test.ts +101 -18
- package/src/tests/tasks-workflow-run-filter.test.ts +146 -0
- package/src/tests/test-net.ts +31 -0
- package/src/tests/transcription.test.ts +8 -0
- package/src/tests/used-by-route.test.ts +11 -0
- package/src/tests/workflow-cascade-cancel.test.ts +1341 -0
- package/src/tests/workflow-foreach-supersede-retry.test.ts +488 -0
- package/src/tests/workflow-http-v2.test.ts +131 -0
- package/src/tests/workflow-idempotency.test.ts +915 -0
- package/src/tests/workflow-step-order.test.ts +92 -0
- package/src/tests/workflow-sub-workflow.test.ts +30 -0
- package/src/tools/get-tasks.ts +8 -0
- package/src/tools/kv/kv-read-auth.ts +4 -2
- package/src/tools/task-action.ts +1 -1
- package/src/tools/workflows/cancel-workflow-run.ts +1 -1
- package/src/tools/workflows/get-workflow-run.ts +14 -4
- package/src/types.ts +24 -0
- package/src/utils/company-profile.ts +51 -1
- package/src/utils/context-window.ts +8 -6
- package/src/utils/credentials.ts +5 -2
- package/src/utils/internal-ai/complete-structured.ts +5 -0
- package/src/utils/internal-ai/credentials.ts +4 -3
- package/src/utils/provider-key-probes.ts +328 -0
- package/src/utils/transcription.ts +4 -1
- package/src/workflows/approval-cancel.ts +15 -13
- package/src/workflows/approval-notifications.ts +5 -1
- package/src/workflows/checkpoint.ts +6 -3
- package/src/workflows/engine.ts +30 -8
- package/src/workflows/executors/foreach.ts +2 -2
- package/src/workflows/executors/sub-workflow.ts +8 -1
- package/src/workflows/foreach-driver.ts +10 -3
- package/src/workflows/foreach-join.ts +29 -6
- package/src/workflows/recovery.ts +6 -1
- package/src/workflows/resume.ts +168 -56
- package/src/workflows/retry-poller.ts +49 -3
- package/src/workflows/task-step-routing.ts +29 -7
- package/templates/ai-toolbox.manifest.json +8 -8
- package/templates/community/open-prompt-showreel/PLAYBOOK.md +5 -6
- package/templates/community/open-prompt-showreel/lead-prompt.md +1 -1
- package/templates/community/open-prompt-showreel/skills/open-prompt-showreel/SKILL.md +4 -4
- package/templates/skills/agent-browser/SKILL.md +4 -4
- package/templates/skills/agent-browser/content.md +4 -4
- package/templates/skills/code-quality/config.json +1 -1
- package/templates/skills/code-quality/content.md +2 -2
- package/templates/skills/delegate-work/content.md +29 -25
- package/templates/skills/delegate-work/files/scripts/codex-exec.sh +5 -5
- package/templates/skills/qa/content.md +2 -2
- package/templates/skills/researching/content.md +4 -0
- package/templates/skills/swarm-scripts/SKILL.md +1 -0
- package/templates/skills/swarm-scripts/content.md +1 -0
- package/templates/skills/work-on-task/SKILL.md +1 -1
- package/templates/skills/work-on-task/content.md +1 -1
- package/dist/cli-7421jzsw.js +0 -84
- package/dist/cli-e45e4m6b.js +0 -413
- package/dist/cli-zw88zjba.js +0 -307
- package/dist/handlers-19xr6dnz.js +0 -41
- package/dist/index-kw2mmat7.js +0 -43
- package/dist/lead-zyerk1x2.js +0 -79
- package/dist/render-v2-hgytz8nn.js +0 -12
- package/dist/worker-42t8emjt.js +0 -79
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { afterAll, afterEach, beforeAll, describe, expect, setSystemTime, test } from "bun:test";
|
|
2
|
+
import { unlink } from "node:fs/promises";
|
|
3
|
+
import {
|
|
4
|
+
closeDb,
|
|
5
|
+
createWorkflow,
|
|
6
|
+
createWorkflowRun,
|
|
7
|
+
createWorkflowRunStep,
|
|
8
|
+
getLatestStepForNode,
|
|
9
|
+
getWorkflowRunStepsByRunId,
|
|
10
|
+
initDb,
|
|
11
|
+
updateWorkflowRunStep,
|
|
12
|
+
} from "../be/db";
|
|
13
|
+
import { hasRunningStep } from "../workflows/engine";
|
|
14
|
+
|
|
15
|
+
const TEST_DB_PATH = "./test-workflow-step-order.sqlite";
|
|
16
|
+
|
|
17
|
+
// Steps inserted in the same millisecond share `startedAt`. Reads must still
|
|
18
|
+
// return them in insert order, because the engine treats the last row of a
|
|
19
|
+
// node as its latest step.
|
|
20
|
+
describe("workflow run step order with equal startedAt", () => {
|
|
21
|
+
beforeAll(async () => {
|
|
22
|
+
try {
|
|
23
|
+
await unlink(TEST_DB_PATH);
|
|
24
|
+
} catch {
|
|
25
|
+
// File doesn't exist
|
|
26
|
+
}
|
|
27
|
+
initDb(TEST_DB_PATH);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
setSystemTime();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterAll(async () => {
|
|
35
|
+
closeDb();
|
|
36
|
+
for (const suffix of ["", "-wal", "-shm"]) {
|
|
37
|
+
try {
|
|
38
|
+
await unlink(`${TEST_DB_PATH}${suffix}`);
|
|
39
|
+
} catch {
|
|
40
|
+
// File doesn't exist
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
async function createRun(): Promise<string> {
|
|
46
|
+
const workflow = await createWorkflow({
|
|
47
|
+
name: `step-order-${crypto.randomUUID()}`,
|
|
48
|
+
definition: { nodes: [{ id: "a", type: "echo", config: { message: "hi" } }] },
|
|
49
|
+
});
|
|
50
|
+
const runId = crypto.randomUUID();
|
|
51
|
+
await createWorkflowRun({ id: runId, workflowId: workflow.id });
|
|
52
|
+
return runId;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Ids sort opposite to insert order, so an id tiebreaker would also fail.
|
|
56
|
+
async function insertTwoSteps(runId: string): Promise<[string, string]> {
|
|
57
|
+
setSystemTime(new Date("2026-10-25T12:00:00.000Z"));
|
|
58
|
+
const first = `z-${crypto.randomUUID()}`;
|
|
59
|
+
const second = `a-${crypto.randomUUID()}`;
|
|
60
|
+
await createWorkflowRunStep({ id: first, runId, nodeId: "a", nodeType: "echo" });
|
|
61
|
+
await createWorkflowRunStep({ id: second, runId, nodeId: "a", nodeType: "echo" });
|
|
62
|
+
return [first, second];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
test("getWorkflowRunStepsByRunId returns steps in insert order", async () => {
|
|
66
|
+
const runId = await createRun();
|
|
67
|
+
const [first, second] = await insertTwoSteps(runId);
|
|
68
|
+
|
|
69
|
+
const steps = await getWorkflowRunStepsByRunId(runId);
|
|
70
|
+
expect(steps[0]?.startedAt).toBe(steps[1]?.startedAt);
|
|
71
|
+
expect(steps.map((s) => s.id)).toEqual([first, second]);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("getLatestStepForNode returns the step inserted last", async () => {
|
|
75
|
+
const runId = await createRun();
|
|
76
|
+
const [, second] = await insertTwoSteps(runId);
|
|
77
|
+
|
|
78
|
+
const latest = await getLatestStepForNode(runId, "a");
|
|
79
|
+
expect(latest?.id).toBe(second);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("hasRunningStep ignores a running step superseded at the same startedAt", async () => {
|
|
83
|
+
const runId = await createRun();
|
|
84
|
+
const [, second] = await insertTwoSteps(runId);
|
|
85
|
+
await updateWorkflowRunStep(second, {
|
|
86
|
+
status: "completed",
|
|
87
|
+
finishedAt: new Date().toISOString(),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
expect(hasRunningStep(await getWorkflowRunStepsByRunId(runId))).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -531,6 +531,36 @@ describe("sub-workflow crash recovery", () => {
|
|
|
531
531
|
for (const result of results) expect(result).toMatchObject({ correlationId: row!.id });
|
|
532
532
|
});
|
|
533
533
|
|
|
534
|
+
test("a child deleted before the step reads it back is not retried", async () => {
|
|
535
|
+
const child = await makeWorkflow(waitingChild);
|
|
536
|
+
const parent = await makeWorkflow(retryingParentOf(child.id));
|
|
537
|
+
const { runId, stepId } = await parentStepRow(parent);
|
|
538
|
+
// Deletes the child's workflow between the start and the read back, as a
|
|
539
|
+
// concurrent delete would.
|
|
540
|
+
const racing = new SubWorkflowExecutor(
|
|
541
|
+
{
|
|
542
|
+
...deps,
|
|
543
|
+
db: {
|
|
544
|
+
...db,
|
|
545
|
+
getWorkflowRun: async (id: string) => {
|
|
546
|
+
await db.deleteWorkflow(child.id);
|
|
547
|
+
return db.getWorkflowRun(id);
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
},
|
|
551
|
+
registry,
|
|
552
|
+
);
|
|
553
|
+
|
|
554
|
+
const result = await racing.run({
|
|
555
|
+
config: { workflowId: child.id, inputs: { n: 1 } },
|
|
556
|
+
context: {},
|
|
557
|
+
meta: { runId, stepId, nodeId: "child", workflowId: parent.id, dryRun: false },
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
expect(result).toMatchObject({ status: "failed", retryable: false });
|
|
561
|
+
expect((result as { error?: string }).error).toContain("not found");
|
|
562
|
+
});
|
|
563
|
+
|
|
534
564
|
test("a step that is no longer running starts no child", async () => {
|
|
535
565
|
const child = await makeWorkflow(waitingChild);
|
|
536
566
|
const parent = await makeWorkflow(parentOf(child.id));
|
package/src/tools/get-tasks.ts
CHANGED
|
@@ -50,6 +50,11 @@ export const getTasksInputSchema = z.object({
|
|
|
50
50
|
.uuid()
|
|
51
51
|
.optional()
|
|
52
52
|
.describe("Filter by schedule ID to find tasks created by a specific schedule."),
|
|
53
|
+
workflowRunId: z
|
|
54
|
+
.string()
|
|
55
|
+
.uuid()
|
|
56
|
+
.optional()
|
|
57
|
+
.describe("Filter by workflow run ID to find the tasks of a single run."),
|
|
53
58
|
key: AssetKeySchema.optional().describe("Filter by exact logical namespace."),
|
|
54
59
|
keyPrefix: AssetKeySchema.optional().describe("Filter by namespace subtree."),
|
|
55
60
|
includeHeartbeat: z
|
|
@@ -130,6 +135,7 @@ export async function getTasksHandler(
|
|
|
130
135
|
tags,
|
|
131
136
|
search,
|
|
132
137
|
scheduleId,
|
|
138
|
+
workflowRunId,
|
|
133
139
|
key,
|
|
134
140
|
keyPrefix,
|
|
135
141
|
includeHeartbeat,
|
|
@@ -151,6 +157,7 @@ export async function getTasksHandler(
|
|
|
151
157
|
tags,
|
|
152
158
|
search,
|
|
153
159
|
scheduleId,
|
|
160
|
+
workflowRunId,
|
|
154
161
|
key,
|
|
155
162
|
keyPrefix,
|
|
156
163
|
includeHeartbeat,
|
|
@@ -192,6 +199,7 @@ export async function getTasksHandler(
|
|
|
192
199
|
if (tags?.length) filters.push(`tags=[${tags.join(", ")}]`);
|
|
193
200
|
if (search) filters.push(`search='${search}'`);
|
|
194
201
|
if (scheduleId) filters.push(`scheduleId='${scheduleId}'`);
|
|
202
|
+
if (workflowRunId) filters.push(`workflowRunId='${workflowRunId}'`);
|
|
195
203
|
if (key) filters.push(`key='${key}'`);
|
|
196
204
|
if (keyPrefix) filters.push(`keyPrefix='${keyPrefix}'`);
|
|
197
205
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { mcpOverflowAuthError } from "@/kv-overflow";
|
|
2
|
+
import { privateNamespaceError } from "@/kv-reserved-namespaces";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Ordinary KV namespaces intentionally remain readable across agents. MCP
|
|
5
6
|
* overflow is different: it contains tool-result business data and is private
|
|
6
|
-
* to the authenticated agent whose finalizer created the spill.
|
|
7
|
+
* to the authenticated agent whose finalizer created the spill. Private
|
|
8
|
+
* reserved families (`session-labels`) are not readable here at all.
|
|
7
9
|
*/
|
|
8
10
|
export function kvReadAuthError(
|
|
9
11
|
namespace: string,
|
|
10
12
|
info: { agentId: string | undefined },
|
|
11
13
|
): string | null {
|
|
12
|
-
return mcpOverflowAuthError(namespace, info.agentId);
|
|
14
|
+
return privateNamespaceError(namespace) ?? mcpOverflowAuthError(namespace, info.agentId);
|
|
13
15
|
}
|
package/src/tools/task-action.ts
CHANGED
|
@@ -68,7 +68,7 @@ export const taskActionInputSchema = z.object({
|
|
|
68
68
|
// For 'create' action:
|
|
69
69
|
task: z.string().min(1).optional().describe("Task description (required for 'create')."),
|
|
70
70
|
key: AssetKeySchema.optional().describe(
|
|
71
|
-
"Logical namespace for a created task.
|
|
71
|
+
"Logical namespace for a created task. Default: the Slack or chat source key of the task (for example shared/slack/<channel>/thread:<ts>/), else shared/task:<id>/.",
|
|
72
72
|
),
|
|
73
73
|
taskType: z.string().max(50).optional().describe("Task type (e.g., 'bug', 'feature')."),
|
|
74
74
|
tags: z
|
|
@@ -10,7 +10,7 @@ export const registerCancelWorkflowRunTool = (server: McpServer) => {
|
|
|
10
10
|
title: "Cancel Workflow Run",
|
|
11
11
|
annotations: { destructiveHint: true },
|
|
12
12
|
description:
|
|
13
|
-
"Cancel a running or waiting workflow run. Cancels
|
|
13
|
+
"Cancel a running or waiting workflow run and every child run below it. Cancels their non-terminal steps, tasks, pending approvals and queued retries in one transaction; finished child runs keep their status. Repeating the cancel on a cancelled run finishes any child runs still open.",
|
|
14
14
|
inputSchema: z.object({
|
|
15
15
|
runId: z.string().uuid().describe("Workflow run ID to cancel"),
|
|
16
16
|
reason: z.string().optional().describe("Optional reason for cancellation"),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { getWorkflowRun, getWorkflowRunStepsByRunId } from "@/be/db";
|
|
4
|
+
import { getWorkflowRunStepsSlimByRunId, getWorkflowRunSummary } from "@/be/db/workflow-runs";
|
|
4
5
|
import { createToolRegistrar, swarmToolOutputSchema, toolErr, toolOk } from "@/tools/utils";
|
|
5
6
|
|
|
6
7
|
const STEP_VALUE_CAP = 400;
|
|
@@ -15,7 +16,7 @@ function stepValuePreview(value: unknown): string | undefined {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
function renderSteps(
|
|
18
|
-
steps: Awaited<ReturnType<typeof
|
|
19
|
+
steps: Awaited<ReturnType<typeof getWorkflowRunStepsSlimByRunId>>,
|
|
19
20
|
): string | undefined {
|
|
20
21
|
if (steps.length === 0) return undefined;
|
|
21
22
|
return steps
|
|
@@ -46,20 +47,29 @@ export const registerGetWorkflowRunTool = (server: McpServer) => {
|
|
|
46
47
|
description: "Get details of a workflow run by ID, including all steps and their statuses.",
|
|
47
48
|
inputSchema: z.object({
|
|
48
49
|
id: z.string().uuid().describe("Workflow run ID"),
|
|
50
|
+
fields: z
|
|
51
|
+
.enum(["full", "slim"])
|
|
52
|
+
.optional()
|
|
53
|
+
.describe(
|
|
54
|
+
"`slim` omits run.context and each step's input (a context snapshot per step, large in runs with loops). Outputs, errors and retry fields stay. Default: full.",
|
|
55
|
+
),
|
|
49
56
|
}),
|
|
50
57
|
outputSchema: swarmToolOutputSchema({
|
|
51
58
|
run: z.unknown().optional(),
|
|
52
59
|
steps: z.array(z.unknown()).optional(),
|
|
53
60
|
}),
|
|
54
61
|
},
|
|
55
|
-
async ({ id }) => {
|
|
62
|
+
async ({ id, fields }) => {
|
|
56
63
|
try {
|
|
57
64
|
// Display view: the scrubbed context and step outputs, never replay state.
|
|
58
|
-
const
|
|
65
|
+
const slim = fields === "slim";
|
|
66
|
+
const run = slim ? await getWorkflowRunSummary(id) : await getWorkflowRun(id, "display");
|
|
59
67
|
if (!run) {
|
|
60
68
|
return toolErr(`Workflow run not found: ${id}`, { data: { steps: [] } });
|
|
61
69
|
}
|
|
62
|
-
const steps =
|
|
70
|
+
const steps = slim
|
|
71
|
+
? await getWorkflowRunStepsSlimByRunId(id)
|
|
72
|
+
: await getWorkflowRunStepsByRunId(id, "display");
|
|
63
73
|
return toolOk(`Run ${id} status: ${run.status}.`, {
|
|
64
74
|
details: renderSteps(steps),
|
|
65
75
|
data: { run, steps },
|
package/src/types.ts
CHANGED
|
@@ -1341,12 +1341,27 @@ export const AgentSchema = z
|
|
|
1341
1341
|
//
|
|
1342
1342
|
// The cache-hit post-task path does NOT produce a new report; the row's
|
|
1343
1343
|
// `reportedAt` deliberately stays at the last actual check.
|
|
1344
|
+
/** One pool member's live test. `suffix` is its last 5 chars, as in `api_key_status`. */
|
|
1345
|
+
export const AgentCredStatusKeyResultSchema = z
|
|
1346
|
+
.object({
|
|
1347
|
+
keyType: z.string(),
|
|
1348
|
+
index: z.number(),
|
|
1349
|
+
suffix: z.string(),
|
|
1350
|
+
ok: z.boolean(),
|
|
1351
|
+
error: z.string().optional(),
|
|
1352
|
+
httpStatus: z.number().optional(),
|
|
1353
|
+
latency_ms: z.number(),
|
|
1354
|
+
})
|
|
1355
|
+
.openapi("AgentCredStatusKeyResult");
|
|
1356
|
+
|
|
1344
1357
|
export const AgentCredStatusLiveTestSchema = z
|
|
1345
1358
|
.object({
|
|
1346
1359
|
ok: z.boolean(),
|
|
1347
1360
|
error: z.string().nullable().default(null),
|
|
1348
1361
|
latency_ms: z.number(),
|
|
1349
1362
|
testedAt: z.number(), // unix ms
|
|
1363
|
+
warning: z.string().optional(),
|
|
1364
|
+
keys: z.array(AgentCredStatusKeyResultSchema).optional(),
|
|
1350
1365
|
})
|
|
1351
1366
|
.openapi("AgentCredStatusLiveTest");
|
|
1352
1367
|
export type AgentCredStatusLiveTest = z.infer<typeof AgentCredStatusLiveTestSchema>;
|
|
@@ -3090,6 +3105,15 @@ export const WorkflowRunStepSchema = z
|
|
|
3090
3105
|
.openapi("WorkflowRunStep");
|
|
3091
3106
|
export type WorkflowRunStep = z.infer<typeof WorkflowRunStepSchema>;
|
|
3092
3107
|
|
|
3108
|
+
/**
|
|
3109
|
+
* Step of `GET /api/workflow-runs/{id}?fields=slim`: no `input`, the context
|
|
3110
|
+
* snapshot taken when the step started. Loops repeat it once per iteration.
|
|
3111
|
+
*/
|
|
3112
|
+
export const WorkflowRunStepSlimSchema = WorkflowRunStepSchema.omit({ input: true }).openapi(
|
|
3113
|
+
"WorkflowRunStepSlim",
|
|
3114
|
+
);
|
|
3115
|
+
export type WorkflowRunStepSlim = z.infer<typeof WorkflowRunStepSlimSchema>;
|
|
3116
|
+
|
|
3093
3117
|
// --- Wait State (workflow `wait` node side table) ---
|
|
3094
3118
|
|
|
3095
3119
|
export const WaitModeSchema = z.enum(["time", "event"]);
|
|
@@ -1,6 +1,19 @@
|
|
|
1
|
+
import type { EventContext } from "../telemetry-contract";
|
|
2
|
+
|
|
1
3
|
export const COMPANY_TEAM_SIZES = ["1", "2-10", "11-50", "51+"] as const;
|
|
2
4
|
|
|
3
|
-
export const COMPANY_USE_CASES = [
|
|
5
|
+
export const COMPANY_USE_CASES = [
|
|
6
|
+
"features",
|
|
7
|
+
"bugs",
|
|
8
|
+
"review",
|
|
9
|
+
"ops",
|
|
10
|
+
"docs",
|
|
11
|
+
"data",
|
|
12
|
+
"content",
|
|
13
|
+
"research",
|
|
14
|
+
"seo",
|
|
15
|
+
"admin",
|
|
16
|
+
] as const;
|
|
4
17
|
|
|
5
18
|
export const COMPANY_ACQUISITION_SOURCES = [
|
|
6
19
|
"search",
|
|
@@ -19,6 +32,43 @@ export const USER_FUNCTIONS = [
|
|
|
19
32
|
"eng_lead",
|
|
20
33
|
"founder",
|
|
21
34
|
"product",
|
|
35
|
+
"marketing",
|
|
36
|
+
"sales",
|
|
37
|
+
"research",
|
|
22
38
|
"ops",
|
|
23
39
|
"other",
|
|
24
40
|
] as const;
|
|
41
|
+
|
|
42
|
+
// The values the vendored telemetry catalog (`src/telemetry-contract`) lists.
|
|
43
|
+
// The proxy rejects a whole event, feedback submission or benchmark request
|
|
44
|
+
// for one value it does not list. So a newer value stays out of telemetry, as
|
|
45
|
+
// if unset, until the proxy catalog adds it and `sync:telemetry-contract` runs.
|
|
46
|
+
const REPORTED_USE_CASES = [
|
|
47
|
+
"features",
|
|
48
|
+
"bugs",
|
|
49
|
+
"review",
|
|
50
|
+
"ops",
|
|
51
|
+
"docs",
|
|
52
|
+
"data",
|
|
53
|
+
] as const satisfies readonly NonNullable<EventContext["use_case"]>[];
|
|
54
|
+
|
|
55
|
+
const REPORTED_USER_FUNCTIONS = [
|
|
56
|
+
"engineer",
|
|
57
|
+
"eng_lead",
|
|
58
|
+
"founder",
|
|
59
|
+
"product",
|
|
60
|
+
"ops",
|
|
61
|
+
"other",
|
|
62
|
+
] as const satisfies readonly NonNullable<EventContext["user_function"]>[];
|
|
63
|
+
|
|
64
|
+
/** `value` when telemetry may report it as a use case, else undefined. */
|
|
65
|
+
export function reportedUseCase(value: unknown): (typeof REPORTED_USE_CASES)[number] | undefined {
|
|
66
|
+
return REPORTED_USE_CASES.find((reported) => reported === value);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** `value` when telemetry may report it as a job function, else undefined. */
|
|
70
|
+
export function reportedUserFunction(
|
|
71
|
+
value: unknown,
|
|
72
|
+
): (typeof REPORTED_USER_FUNCTIONS)[number] | undefined {
|
|
73
|
+
return REPORTED_USER_FUNCTIONS.find((reported) => reported === value);
|
|
74
|
+
}
|
|
@@ -67,7 +67,12 @@ function catalogContext(provider: string, model: string): number | undefined {
|
|
|
67
67
|
* Unknown models get a conservative 200k so percent math stays finite.
|
|
68
68
|
*/
|
|
69
69
|
export function getContextWindowSize(model: string): number {
|
|
70
|
-
|
|
70
|
+
return getKnownContextWindowSize(model) ?? DEFAULT_CONTEXT_WINDOW;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** {@link getContextWindowSize} without the fallback: undefined when the catalog has no window. */
|
|
74
|
+
export function getKnownContextWindowSize(model: string | undefined): number | undefined {
|
|
75
|
+
if (!model) return undefined;
|
|
71
76
|
const slash = model.indexOf("/");
|
|
72
77
|
if (slash > 0) {
|
|
73
78
|
const scoped = catalogContext(model.slice(0, slash), model.slice(slash + 1));
|
|
@@ -83,11 +88,8 @@ export function getContextWindowSize(model: string): number {
|
|
|
83
88
|
if (dated) return dated;
|
|
84
89
|
}
|
|
85
90
|
const shortname = resolveClaudeShortname(model);
|
|
86
|
-
if (shortname)
|
|
87
|
-
|
|
88
|
-
if (resolved) return resolved;
|
|
89
|
-
}
|
|
90
|
-
return DEFAULT_CONTEXT_WINDOW;
|
|
91
|
+
if (shortname) return catalogContext("anthropic", shortname);
|
|
92
|
+
return undefined;
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
/**
|
package/src/utils/credentials.ts
CHANGED
|
@@ -380,6 +380,7 @@ export function validateOpencodeCredentials(
|
|
|
380
380
|
/** Per-pool availability, including the model-scoped block breakdown when a model was requested. */
|
|
381
381
|
export interface AvailabilityInfo {
|
|
382
382
|
availableIndices: number[];
|
|
383
|
+
rejectedIndices?: number[];
|
|
383
384
|
modelBlockedIndices?: number[];
|
|
384
385
|
earliestModelResetAt?: string | null;
|
|
385
386
|
/** Indices excluded because the key's subscription plan cannot run the model. */
|
|
@@ -414,19 +415,21 @@ async function fetchAvailableIndices(
|
|
|
414
415
|
if (resp.ok) {
|
|
415
416
|
const data = (await resp.json()) as {
|
|
416
417
|
availableIndices: number[];
|
|
418
|
+
rejectedIndices?: number[];
|
|
417
419
|
modelBlockedIndices?: number[];
|
|
418
420
|
earliestModelResetAt?: string | null;
|
|
419
421
|
seatBlockedIndices?: number[];
|
|
420
422
|
};
|
|
421
423
|
availableIndicesMap[envVar] = {
|
|
422
424
|
availableIndices: data.availableIndices,
|
|
425
|
+
rejectedIndices: data.rejectedIndices,
|
|
423
426
|
modelBlockedIndices: data.modelBlockedIndices,
|
|
424
427
|
earliestModelResetAt: data.earliestModelResetAt,
|
|
425
428
|
seatBlockedIndices: data.seatBlockedIndices,
|
|
426
429
|
};
|
|
427
430
|
if (data.availableIndices.length < totalKeys) {
|
|
428
431
|
console.log(
|
|
429
|
-
`[credentials] ${envVar}: ${data.availableIndices.length}/${totalKeys} keys available (${totalKeys - data.availableIndices.length}
|
|
432
|
+
`[credentials] ${envVar}: ${data.availableIndices.length}/${totalKeys} keys available (${totalKeys - data.availableIndices.length} unavailable)`,
|
|
430
433
|
);
|
|
431
434
|
}
|
|
432
435
|
}
|
|
@@ -558,7 +561,7 @@ export async function resolveCredentialPools(
|
|
|
558
561
|
env[envVar] = result.selected;
|
|
559
562
|
const availInfo = available ? ` (${available.length} available of ${result.total})` : "";
|
|
560
563
|
console.log(
|
|
561
|
-
`[credentials] Selected ${envVar} credential ${result.index + 1}/${result.total}${availInfo} [...${result.keySuffix}]`,
|
|
564
|
+
`[credentials] Selected ${envVar} credential ${result.index + 1}/${result.total}${availInfo} [...${result.keySuffix}]${info?.rejectedIndices?.length ? ` (${info.rejectedIndices.length} rejected)` : ""}`,
|
|
562
565
|
);
|
|
563
566
|
selections.push({
|
|
564
567
|
...result,
|
|
@@ -20,6 +20,7 @@ import { complete } from "@earendil-works/pi-ai/compat";
|
|
|
20
20
|
import { getBuiltinModel as getModel } from "@earendil-works/pi-ai/providers/all";
|
|
21
21
|
import type { TSchema } from "typebox";
|
|
22
22
|
import { z } from "zod";
|
|
23
|
+
import { selectCredential } from "../credentials.js";
|
|
23
24
|
import {
|
|
24
25
|
DEFAULT_OPENROUTER_BASE_URL,
|
|
25
26
|
getOpenRouterAttributionHeaders,
|
|
@@ -134,6 +135,10 @@ export async function defaultSpawnClaudeCli(
|
|
|
134
135
|
if (!env.CLAUDE_CODE_OAUTH_TOKEN && env.AGENT_SWARM_CLAUDE_OAUTH_TOKEN) {
|
|
135
136
|
env.CLAUDE_CODE_OAUTH_TOKEN = env.AGENT_SWARM_CLAUDE_OAUTH_TOKEN;
|
|
136
137
|
}
|
|
138
|
+
// API calls and restarted workers can inherit raw pools.
|
|
139
|
+
for (const keyVar of ["CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_API_KEY"]) {
|
|
140
|
+
if (env[keyVar]) env[keyVar] = selectCredential(env[keyVar], undefined, keyVar).selected;
|
|
141
|
+
}
|
|
137
142
|
// Recursion guard: this shellout is itself a full claude session — on exit it
|
|
138
143
|
// fires the same global Stop hook, whose session-summary path would spawn
|
|
139
144
|
// another `claude -p`, recursively (each level holds a ~0.5-1GB node process;
|
|
@@ -25,6 +25,7 @@ import { registerBunOAuthFlows } from "@earendil-works/pi-ai/bun-oauth";
|
|
|
25
25
|
import { getEnvApiKey } from "@earendil-works/pi-ai/compat";
|
|
26
26
|
import { builtinModels } from "@earendil-works/pi-ai/providers/all";
|
|
27
27
|
import { getValidCodexOAuth, persistCodexOAuth } from "../../providers/codex-oauth/storage.js";
|
|
28
|
+
import { selectCredential } from "../credentials.js";
|
|
28
29
|
import { type CredentialKind, DEFAULT_MODEL, resolveRaterModelString } from "./models.js";
|
|
29
30
|
|
|
30
31
|
registerBunOAuthFlows();
|
|
@@ -135,7 +136,7 @@ export async function resolveCredential(
|
|
|
135
136
|
if (openrouterKey) {
|
|
136
137
|
return {
|
|
137
138
|
kind: "openrouter",
|
|
138
|
-
apiKey: openrouterKey,
|
|
139
|
+
apiKey: selectCredential(openrouterKey, undefined, "OPENROUTER_API_KEY").selected,
|
|
139
140
|
modelDefault: resolveRaterModelString("openrouter"),
|
|
140
141
|
};
|
|
141
142
|
}
|
|
@@ -151,7 +152,7 @@ export async function resolveCredential(
|
|
|
151
152
|
if (anthropicKey) {
|
|
152
153
|
return {
|
|
153
154
|
kind: "anthropic",
|
|
154
|
-
apiKey: anthropicKey,
|
|
155
|
+
apiKey: selectCredential(anthropicKey, undefined, "ANTHROPIC_API_KEY").selected,
|
|
155
156
|
modelDefault: resolveRaterModelString("anthropic"),
|
|
156
157
|
};
|
|
157
158
|
}
|
|
@@ -161,7 +162,7 @@ export async function resolveCredential(
|
|
|
161
162
|
if (openaiKey) {
|
|
162
163
|
return {
|
|
163
164
|
kind: "openai",
|
|
164
|
-
apiKey: openaiKey,
|
|
165
|
+
apiKey: selectCredential(openaiKey, undefined, "OPENAI_API_KEY").selected,
|
|
165
166
|
modelDefault: resolveRaterModelString("openai"),
|
|
166
167
|
};
|
|
167
168
|
}
|