@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.
Files changed (349) hide show
  1. package/README.md +2 -2
  2. package/dist/{acp-adapter-gr2fcyyj.js → acp-adapter-dgfakfpw.js} +9 -9
  3. package/dist/{actions-wv766ghf.js → actions-fbqma8aa.js} +21 -21
  4. package/dist/{amp-adapter-speb906t.js → amp-adapter-en0jy6hs.js} +4 -4
  5. package/dist/{app-ag29n14f.js → app-k8a5cgpp.js} +3 -3
  6. package/dist/{assistant-3x8bz3eg.js → assistant-a16433gr.js} +30 -26
  7. package/dist/{boot-reembed-jsmfrpzf.js → boot-reembed-6c1sjfnr.js} +1 -1
  8. package/dist/{boot-reembed-5b3d2eea.js → boot-reembed-f4nn561n.js} +1 -1
  9. package/dist/{boot-scrub-sweep-s73gerxy.js → boot-scrub-sweep-d4w9gajf.js} +4 -4
  10. package/dist/{boot-seeds-5zmax2wr.js → boot-seeds-9bmkspyw.js} +4 -4
  11. package/dist/{claude-adapter-hswdnm3t.js → claude-adapter-nys1kjxa.js} +9 -9
  12. package/dist/{claude-managed-adapter-cvbzj1h6.js → claude-managed-adapter-55207973.js} +3 -3
  13. package/dist/{claude-managed-setup-3k8m3hhc.js → claude-managed-setup-3cm35gey.js} +11 -4
  14. package/dist/{claude-sdk-session-fkbyk66x.js → claude-sdk-session-nw5yd8cp.js} +9313 -9260
  15. package/dist/{cli-210xd1f4.js → cli-03gg9pd1.js} +4 -4
  16. package/dist/{cli-kxpfx2xr.js → cli-0z1xjzwa.js} +2 -2
  17. package/dist/cli-1tem6ns9.js +894 -0
  18. package/dist/{cli-25j01dpj.js → cli-24j1jeeb.js} +3 -3
  19. package/dist/{cli-ta8bd7th.js → cli-2sjhpsns.js} +2 -2
  20. package/dist/{cli-p859hcc8.js → cli-39aet655.js} +2 -2
  21. package/dist/{cli-g1cw7xtt.js → cli-39rrw8yp.js} +1 -1
  22. package/dist/{cli-e2ar4bp1.js → cli-3aqd4jaa.js} +121 -47
  23. package/dist/{cli-jjznk3f7.js → cli-3fwqy71j.js} +69 -35
  24. package/dist/{cli-p9rafdrb.js → cli-3gfvmzht.js} +7 -7
  25. package/dist/{cli-03vpq45j.js → cli-3ndmpxxv.js} +2 -2
  26. package/dist/{cli-aecdcr77.js → cli-4hxrf0p4.js} +228 -74
  27. package/dist/{cli-mz9afxxf.js → cli-4rf0f5vg.js} +15 -3
  28. package/dist/{cli-qzme5949.js → cli-5rj83bam.js} +284 -202
  29. package/dist/{cli-fsdprwrg.js → cli-5sckpqcx.js} +2 -2
  30. package/dist/{cli-cz5nmdxt.js → cli-683y0b3a.js} +2 -2
  31. package/dist/{cli-3ngdk5te.js → cli-6y51ryva.js} +2 -2
  32. package/dist/{cli-n4c8e3s5.js → cli-708wdy32.js} +1 -1
  33. package/dist/{cli-pasyvjmm.js → cli-737pyqxr.js} +1 -1
  34. package/dist/{cli-gx4rm0qx.js → cli-7enjwya9.js} +1 -1
  35. package/dist/{cli-6x9ma5w5.js → cli-803188pb.js} +1 -1
  36. package/dist/{cli-avdvgcay.js → cli-9abdgn5t.js} +28 -9
  37. package/dist/{cli-99xgw26r.js → cli-a2rr0fmg.js} +1 -1
  38. package/dist/{cli-e5bxnjps.js → cli-a34pr3w1.js} +7 -7
  39. package/dist/{cli-502eqv93.js → cli-abkm71vr.js} +1 -1
  40. package/dist/{cli-mmhj8vd7.js → cli-ag2yrnt5.js} +11 -2
  41. package/dist/{cli-n45mr7zh.js → cli-aj8djyqt.js} +5 -5
  42. package/dist/{cli-1fc85mvt.js → cli-art7c1zh.js} +5 -5
  43. package/dist/{cli-40jsnrjm.js → cli-az25fn5f.js} +10 -8
  44. package/dist/{cli-9s05422w.js → cli-bqztfyve.js} +1 -1
  45. package/dist/{cli-bn0rewsy.js → cli-c081bj3b.js} +2 -2
  46. package/dist/{cli-svrj71pg.js → cli-c2habvsf.js} +12 -12
  47. package/dist/{cli-s49hpn37.js → cli-ca6banwz.js} +85 -19
  48. package/dist/{cli-hhxjnjzs.js → cli-cz37jqss.js} +12 -10
  49. package/dist/{cli-6n8axjv1.js → cli-d2dpf95n.js} +2 -2
  50. package/dist/{cli-tx00c0h6.js → cli-dqygeeh5.js} +17 -1
  51. package/dist/{cli-z21whrrg.js → cli-emhjcj2y.js} +17 -17
  52. package/dist/{cli-e8jyq7d8.js → cli-esakngh8.js} +7 -3
  53. package/dist/{cli-ha9rmwgq.js → cli-fb8m699c.js} +2 -2
  54. package/dist/{cli-35gtk1p6.js → cli-ffvsj2qw.js} +44 -13
  55. package/dist/{cli-ce0ak9ms.js → cli-g20jjwt4.js} +26 -26
  56. package/dist/{cli-kxawjrxg.js → cli-g8ka5j4j.js} +772 -194
  57. package/dist/{cli-vwn81jbs.js → cli-gf95q3bm.js} +5 -5
  58. package/dist/{cli-s53vp709.js → cli-gnsb1zxa.js} +2 -2
  59. package/dist/{cli-nwyw3zhg.js → cli-gxee0bqa.js} +1 -1
  60. package/dist/{cli-gpv60278.js → cli-hfeb68z4.js} +7 -7
  61. package/dist/{cli-0ebey9hg.js → cli-j6rktc91.js} +1 -1
  62. package/dist/{cli-ewm3pwbq.js → cli-k21gx5ht.js} +46 -23
  63. package/dist/{cli-egjggehm.js → cli-kf4jree9.js} +2 -2
  64. package/dist/{cli-dabehxhp.js → cli-kt907da6.js} +1 -1
  65. package/dist/{cli-p0rzjkya.js → cli-m5a9m0ak.js} +32 -13
  66. package/dist/{cli-fzcn3d87.js → cli-m70bajzr.js} +3 -3
  67. package/dist/{cli-w1zwctj2.js → cli-mtnj4fwa.js} +11 -5
  68. package/dist/{cli-gpsz7g88.js → cli-mvjz5an3.js} +16 -12
  69. package/dist/{cli-hcpj2xqz.js → cli-n7asmce6.js} +225 -3
  70. package/dist/{cli-y561h5a9.js → cli-nn6vx2mq.js} +5 -5
  71. package/dist/cli-nq677csy.js +140 -0
  72. package/dist/{cli-a5ebc95n.js → cli-pfk92eqz.js} +18 -15
  73. package/dist/{cli-p6zs9h4y.js → cli-rr7zx19j.js} +767 -249
  74. package/dist/{cli-qgf8emrn.js → cli-sqma6vw1.js} +10 -7
  75. package/dist/{cli-0xk505e8.js → cli-sxgtf5fw.js} +1 -1
  76. package/dist/{cli-nzfnt2gs.js → cli-tf1n0r0b.js} +1 -1
  77. package/dist/{cli-qqzmjxkf.js → cli-v49fkghp.js} +11 -6
  78. package/dist/{cli-x77gen2p.js → cli-w2656ka1.js} +7 -7
  79. package/dist/{cli-5kqnemen.js → cli-yvy48785.js} +1 -1
  80. package/dist/{cli-8s5wx3nz.js → cli-zqne1qcj.js} +44 -17
  81. package/dist/cli.js +22 -22
  82. package/dist/{codex-adapter-n8ka66vf.js → codex-adapter-d95q4qsn.js} +7 -7
  83. package/dist/{codex-hook-e2he7aca.js → codex-hook-brpnycn5.js} +1 -1
  84. package/dist/{codex-login-rn7c5gxt.js → codex-login-8cg0vhf2.js} +1 -1
  85. package/dist/{codex-session-runner-fsebts37.js → codex-session-runner-gdwd8h0c.js} +8 -8
  86. package/dist/{commands-t04rt2pc.js → commands-jqmgk54b.js} +2 -2
  87. package/dist/{controller-rgna04r2.js → controller-z3jq589f.js} +30 -4
  88. package/dist/{controllers-connect-bqm1rtft.js → controllers-connect-r2za39ef.js} +23 -23
  89. package/dist/{cursor-adapter-swr2k95y.js → cursor-adapter-4mr4jgkw.js} +2 -3
  90. package/dist/{db-a4m7haw0.js → db-ppv2tze7.js} +3 -3
  91. package/dist/{db-24ck09xy.js → db-w36wwb5g.js} +4 -2
  92. package/dist/{devin-adapter-4ycy4vrf.js → devin-adapter-byen2cxt.js} +1 -1
  93. package/dist/{dispatcher-nwf9ss0q.js → dispatcher-pv5h77vf.js} +20 -20
  94. package/dist/{docker-nfy2gc8t.js → docker-fdzyewpz.js} +4 -4
  95. package/dist/{dsh-adapter-kpdnhjst.js → dsh-adapter-d4pdpb3r.js} +2 -3
  96. package/dist/{e2b-9gkdhm3c.js → e2b-222hsajc.js} +2 -2
  97. package/dist/{e2b-cjtf8k1z.js → e2b-fn3zacvt.js} +2 -2
  98. package/dist/{easter-egg-3d-e4qv8dxj.js → easter-egg-3d-4sp4dvmc.js} +1 -1
  99. package/dist/{event-bus-3z78ep5n.js → event-bus-pghg8hqy.js} +1 -1
  100. package/dist/{execute-0xpz8950.js → execute-jev839y1.js} +1 -1
  101. package/dist/{external-channel-j1e2p34p.js → external-channel-y6nkzhnn.js} +2 -2
  102. package/dist/{grok-adapter-qtjz0whk.js → grok-adapter-t08b9ntm.js} +10 -10
  103. package/dist/handlers-eqsnmv95.js +41 -0
  104. package/dist/{heartbeat-vtesda5d.js → heartbeat-vn31xwdk.js} +23 -23
  105. package/dist/{hook-b2hhj6rd.js → hook-6d0zbvvt.js} +6 -5
  106. package/dist/{hook-8wqaszda.js → hook-cpjs8q51.js} +13 -7
  107. package/dist/{http-mxcqhhcs.js → http-9c6medda.js} +1085 -136
  108. package/dist/{index-spwxjgay.js → index-38t35h0n.js} +20 -20
  109. package/dist/{index-1r8wfpzs.js → index-g6k9tctj.js} +1 -1
  110. package/dist/{index-srg522m6.js → index-k0yt1tvq.js} +20 -20
  111. package/dist/{index-31ceyf42.js → index-pkma1yf8.js} +1 -1
  112. package/dist/{index-n1vbvta9.js → index-qhjf2htm.js} +29 -24
  113. package/dist/index-yqgbfgaj.js +43 -0
  114. package/dist/{keepalive-dsd8rtgx.js → keepalive-em0117bp.js} +4 -4
  115. package/dist/lead-23e7z59t.js +79 -0
  116. package/dist/{maintenance-jqmqwnet.js → maintenance-kbme3qy9.js} +1 -1
  117. package/dist/{oauth-refresh-sweep-q2c3bnvm.js → oauth-refresh-sweep-xysj4yse.js} +3 -3
  118. package/dist/{onboard-w4yd7s8t.js → onboard-p6q0vz97.js} +3 -3
  119. package/dist/{opencode-adapter-9tppvxar.js → opencode-adapter-esv3k9yn.js} +7 -7
  120. package/dist/{otel-impl-f36byzbd.js → otel-impl-54qhqh1z.js} +2 -2
  121. package/dist/{pi-mono-adapter-tqsge1ay.js → pi-mono-adapter-mymbwhj0.js} +41 -14
  122. package/dist/{pricing-refresh-xvak5p4v.js → pricing-refresh-yb75wv33.js} +3 -3
  123. package/dist/{rbac-roles-gfn30fb8.js → rbac-roles-1vp2mw4p.js} +2 -2
  124. package/dist/{rbac-roles-682k2mt5.js → rbac-roles-dexhc9x8.js} +1 -1
  125. package/dist/render-v2-tjay5hhf.js +16 -0
  126. package/dist/{resume-2dvq348g.js → resume-8ayf37g5.js} +11 -9
  127. package/dist/{runtime-bt5pkpm1.js → runtime-hqe5cqcd.js} +1 -1
  128. package/dist/{session-access-7f21ekq9.js → session-access-fdhp987s.js} +4 -4
  129. package/dist/session-source-backfill-qgtc86z1.js +110 -0
  130. package/dist/{setup-epffxtbk.js → setup-4rrmqcq3.js} +1 -1
  131. package/dist/{virtual-modules-mnfbh5mr.js → virtual-modules-52km00d6.js} +2 -2
  132. package/dist/{work-objects-xz1a5rqk.js → work-objects-p28fgd70.js} +23 -23
  133. package/dist/worker-e3w7vye1.js +79 -0
  134. package/dist/{x-pbpezr0s.js → x-wxrzvzx8.js} +2 -2
  135. package/openapi.json +1323 -16
  136. package/package.json +5 -5
  137. package/plugin/commands/create-pr.md +2 -2
  138. package/plugin/pi-skills/create-pr/SKILL.md +2 -2
  139. package/src/assets/source-key.ts +95 -0
  140. package/src/be/db/api-keys.ts +80 -0
  141. package/src/be/db/approvals.ts +48 -0
  142. package/src/be/db/session-labels.ts +28 -0
  143. package/src/be/db/session-moves.ts +5 -6
  144. package/src/be/db/session-tree.ts +153 -14
  145. package/src/be/db/tasks/read.ts +11 -0
  146. package/src/be/db/tasks/write.ts +21 -6
  147. package/src/be/db/workflow-idempotency.ts +183 -0
  148. package/src/be/db/workflow-runs.ts +500 -7
  149. package/src/be/db-retention.ts +61 -6
  150. package/src/be/db.ts +126 -131
  151. package/src/be/memory/providers/openai-embedding.ts +5 -1
  152. package/src/be/migrations/242_workflow_idempotency_keys.sql +40 -0
  153. package/src/be/migrations/244_api_key_validation.sql +4 -0
  154. package/src/be/onboarding.ts +4 -0
  155. package/src/be/scripts/typecheck.ts +1 -1
  156. package/src/be/sealed-json.ts +1 -0
  157. package/src/be/seed-scripts/catalog/compound-insights.inline.ts +2 -2
  158. package/src/be/seed-scripts/catalog/compound-insights.ts +2 -2
  159. package/src/be/seed-skills/bundled-files.generated.json +1 -1
  160. package/src/be/session-source-backfill.ts +163 -0
  161. package/src/be/sql-connections.ts +7 -1
  162. package/src/be/swarm-config-guard.ts +3 -0
  163. package/src/be/users.ts +9 -0
  164. package/src/comb/review-batch.ts +28 -1
  165. package/src/comb/templates.ts +7 -2
  166. package/src/commands/claude-managed-setup.ts +7 -1
  167. package/src/commands/controller.ts +33 -0
  168. package/src/commands/credential-refresh.ts +76 -1
  169. package/src/commands/credential-wait.ts +2 -2
  170. package/src/commands/provider-credentials.ts +210 -170
  171. package/src/commands/runner.ts +31 -6
  172. package/src/extensions/apply-task-create.ts +64 -11
  173. package/src/extensions/contract-types.generated.ts +1 -1
  174. package/src/extensions/contract.ts +30 -0
  175. package/src/extensions/dispatcher.ts +4 -0
  176. package/src/extensions/post-bridge.ts +8 -0
  177. package/src/hooks/context-bound-note.ts +196 -0
  178. package/src/hooks/hook.ts +12 -0
  179. package/src/http/all-routes.ts +2 -0
  180. package/src/http/api-keys.ts +53 -0
  181. package/src/http/assets.ts +15 -0
  182. package/src/http/codex-oauth-accounts.ts +191 -0
  183. package/src/http/comb.ts +15 -2
  184. package/src/http/config.ts +49 -17
  185. package/src/http/core.ts +6 -0
  186. package/src/http/fleet-benchmark.ts +5 -2
  187. package/src/http/idempotency-key.ts +117 -0
  188. package/src/http/index.ts +11 -0
  189. package/src/http/integrations.ts +5 -1
  190. package/src/http/kv.ts +8 -3
  191. package/src/http/onboarding.ts +6 -1
  192. package/src/http/pool-keys.ts +354 -0
  193. package/src/http/sessions.ts +37 -12
  194. package/src/http/stats.ts +1 -0
  195. package/src/http/status.ts +26 -12
  196. package/src/http/tasks.ts +3 -0
  197. package/src/http/used-by.ts +7 -2
  198. package/src/http/workflows.ts +207 -33
  199. package/src/integrations/chat-sdk/inbound.ts +27 -0
  200. package/src/kv-reserved-namespaces.ts +19 -0
  201. package/src/prompts/context-bound-note.ts +48 -0
  202. package/src/prompts/session-templates.ts +25 -1
  203. package/src/providers/acp-targets.ts +1 -1
  204. package/src/providers/amp-adapter.ts +30 -8
  205. package/src/providers/claude-adapter.ts +34 -5
  206. package/src/providers/claude-managed-adapter.ts +42 -9
  207. package/src/providers/claude-sdk-session.ts +10 -0
  208. package/src/providers/claude-session-events.ts +13 -0
  209. package/src/providers/codex-adapter.ts +83 -11
  210. package/src/providers/opencode-adapter.ts +18 -0
  211. package/src/providers/pi-mono-adapter.ts +35 -0
  212. package/src/runtime-providers/docker.ts +6 -2
  213. package/src/scheduler/scheduler.ts +3 -2
  214. package/src/scripts-runtime/swarm-sdk.ts +7 -1
  215. package/src/scripts-runtime/types/stdlib.d.ts +1 -1
  216. package/src/scripts-runtime/types/swarm-extension.d.ts +52 -8
  217. package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -1
  218. package/src/slack/assistant.ts +7 -0
  219. package/src/slack/channel-labels.ts +74 -0
  220. package/src/slack/handlers.ts +8 -0
  221. package/src/slack/inbound-files.ts +5 -2
  222. package/src/slack/thread-buffer.ts +4 -0
  223. package/src/tasks/sibling-awareness.ts +12 -3
  224. package/src/telemetry-context.ts +5 -6
  225. package/src/telemetry-identity.ts +3 -3
  226. package/src/tests/amp-adapter.test.ts +97 -0
  227. package/src/tests/api-keys-validation.test.ts +170 -0
  228. package/src/tests/approval-requests.test.ts +10 -7
  229. package/src/tests/approval-sweeps.test.ts +12 -6
  230. package/src/tests/base-prompt.test.ts +1 -1
  231. package/src/tests/claude-hook-output.test.ts +79 -1
  232. package/src/tests/claude-managed-adapter.test.ts +321 -0
  233. package/src/tests/claude-routes-e2e.test.ts +7 -2
  234. package/src/tests/codex-adapter.test.ts +163 -0
  235. package/src/tests/codex-credential-pools.test.ts +120 -0
  236. package/src/tests/codex-gateway-route.test.ts +165 -0
  237. package/src/tests/codex-oauth-accounts.test.ts +357 -0
  238. package/src/tests/comb-review-batch.test.ts +63 -2
  239. package/src/tests/config-pool-keys.test.ts +533 -0
  240. package/src/tests/context-bound-note.test.ts +269 -0
  241. package/src/tests/credential-check.test.ts +290 -2
  242. package/src/tests/credential-refresh.test.ts +172 -1
  243. package/src/tests/db-retention.test.ts +9 -3
  244. package/src/tests/db-task-read-contract.test.ts +1 -0
  245. package/src/tests/db-task-write-contract.test.ts +1 -3
  246. package/src/tests/docs-index-footprint.test.js +3 -3
  247. package/src/tests/extensions-pre-task.test.ts +325 -0
  248. package/src/tests/fetch-resolved-env.test.ts +17 -0
  249. package/src/tests/fixtures/extensions/record-blocks/hooks.ts +10 -0
  250. package/src/tests/fixtures/extensions/record-blocks/manifest.json +7 -0
  251. package/src/tests/fixtures/extensions/record-task-create/hooks.ts +9 -0
  252. package/src/tests/fixtures/extensions/record-task-create/manifest.json +7 -0
  253. package/src/tests/fixtures/fake-amp.ts +22 -8
  254. package/src/tests/fixtures/held-template-render.ts +42 -0
  255. package/src/tests/fixtures/workflow-idempotency-trigger.child.ts +73 -0
  256. package/src/tests/fleet-benchmark.test.ts +8 -0
  257. package/src/tests/get-workflow-run-tool.test.ts +98 -0
  258. package/src/tests/integrations-http.test.ts +32 -2
  259. package/src/tests/internal-ai/complete-structured.test.ts +37 -1
  260. package/src/tests/internal-ai/credentials.test.ts +23 -0
  261. package/src/tests/kv-http.test.ts +32 -0
  262. package/src/tests/kv-tool.test.ts +25 -0
  263. package/src/tests/multi-runtime-registration.test.ts +12 -12
  264. package/src/tests/onboarding.test.ts +108 -1
  265. package/src/tests/openai-embedding-credentials.test.ts +35 -0
  266. package/src/tests/openapi-route-headers.test.ts +2 -0
  267. package/src/tests/opencode-adapter.test.ts +134 -0
  268. package/src/tests/openrouter-attribution-call-sites.test.ts +2 -2
  269. package/src/tests/org-website.test.ts +36 -0
  270. package/src/tests/pi-mono-adapter.test.ts +105 -0
  271. package/src/tests/prompt-template-session.test.ts +4 -3
  272. package/src/tests/provider-key-probes.test.ts +181 -0
  273. package/src/tests/rbac-e2e-helpers.test.ts +88 -1
  274. package/src/tests/rbac-e2e-helpers.ts +36 -11
  275. package/src/tests/runner-push-delivery.test.ts +25 -0
  276. package/src/tests/runtime-controller-liveness.test.ts +133 -0
  277. package/src/tests/runtime-providers-docker.test.ts +2 -0
  278. package/src/tests/script-connections.test.ts +5 -0
  279. package/src/tests/script-run-config-scope.test.ts +91 -3
  280. package/src/tests/script-runs-retention.test.ts +212 -0
  281. package/src/tests/sdk-allowlist.test.ts +39 -0
  282. package/src/tests/session-logs.test.ts +70 -0
  283. package/src/tests/session-source-backfill.test.ts +429 -0
  284. package/src/tests/session-source-keys.test.ts +236 -0
  285. package/src/tests/session-source-labels.test.ts +419 -0
  286. package/src/tests/sessions-detail-batch.test.ts +2 -0
  287. package/src/tests/sessions-move.test.ts +131 -0
  288. package/src/tests/sessions-tree.test.ts +336 -2
  289. package/src/tests/slack-inbound-files.test.ts +103 -23
  290. package/src/tests/status.test.ts +101 -18
  291. package/src/tests/tasks-workflow-run-filter.test.ts +146 -0
  292. package/src/tests/test-net.ts +31 -0
  293. package/src/tests/transcription.test.ts +8 -0
  294. package/src/tests/used-by-route.test.ts +11 -0
  295. package/src/tests/workflow-cascade-cancel.test.ts +1341 -0
  296. package/src/tests/workflow-foreach-supersede-retry.test.ts +488 -0
  297. package/src/tests/workflow-http-v2.test.ts +131 -0
  298. package/src/tests/workflow-idempotency.test.ts +915 -0
  299. package/src/tests/workflow-step-order.test.ts +92 -0
  300. package/src/tests/workflow-sub-workflow.test.ts +30 -0
  301. package/src/tools/get-tasks.ts +8 -0
  302. package/src/tools/kv/kv-read-auth.ts +4 -2
  303. package/src/tools/task-action.ts +1 -1
  304. package/src/tools/workflows/cancel-workflow-run.ts +1 -1
  305. package/src/tools/workflows/get-workflow-run.ts +14 -4
  306. package/src/types.ts +24 -0
  307. package/src/utils/company-profile.ts +51 -1
  308. package/src/utils/context-window.ts +8 -6
  309. package/src/utils/credentials.ts +5 -2
  310. package/src/utils/internal-ai/complete-structured.ts +5 -0
  311. package/src/utils/internal-ai/credentials.ts +4 -3
  312. package/src/utils/provider-key-probes.ts +328 -0
  313. package/src/utils/transcription.ts +4 -1
  314. package/src/workflows/approval-cancel.ts +15 -13
  315. package/src/workflows/approval-notifications.ts +5 -1
  316. package/src/workflows/checkpoint.ts +6 -3
  317. package/src/workflows/engine.ts +30 -8
  318. package/src/workflows/executors/foreach.ts +2 -2
  319. package/src/workflows/executors/sub-workflow.ts +8 -1
  320. package/src/workflows/foreach-driver.ts +10 -3
  321. package/src/workflows/foreach-join.ts +29 -6
  322. package/src/workflows/recovery.ts +6 -1
  323. package/src/workflows/resume.ts +168 -56
  324. package/src/workflows/retry-poller.ts +49 -3
  325. package/src/workflows/task-step-routing.ts +29 -7
  326. package/templates/ai-toolbox.manifest.json +8 -8
  327. package/templates/community/open-prompt-showreel/PLAYBOOK.md +5 -6
  328. package/templates/community/open-prompt-showreel/lead-prompt.md +1 -1
  329. package/templates/community/open-prompt-showreel/skills/open-prompt-showreel/SKILL.md +4 -4
  330. package/templates/skills/agent-browser/SKILL.md +4 -4
  331. package/templates/skills/agent-browser/content.md +4 -4
  332. package/templates/skills/code-quality/config.json +1 -1
  333. package/templates/skills/code-quality/content.md +2 -2
  334. package/templates/skills/delegate-work/content.md +29 -25
  335. package/templates/skills/delegate-work/files/scripts/codex-exec.sh +5 -5
  336. package/templates/skills/qa/content.md +2 -2
  337. package/templates/skills/researching/content.md +4 -0
  338. package/templates/skills/swarm-scripts/SKILL.md +1 -0
  339. package/templates/skills/swarm-scripts/content.md +1 -0
  340. package/templates/skills/work-on-task/SKILL.md +1 -1
  341. package/templates/skills/work-on-task/content.md +1 -1
  342. package/dist/cli-7421jzsw.js +0 -84
  343. package/dist/cli-e45e4m6b.js +0 -413
  344. package/dist/cli-zw88zjba.js +0 -307
  345. package/dist/handlers-19xr6dnz.js +0 -41
  346. package/dist/index-kw2mmat7.js +0 -43
  347. package/dist/lead-zyerk1x2.js +0 -79
  348. package/dist/render-v2-hgytz8nn.js +0 -12
  349. 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));
@@ -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
  }
@@ -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. Defaults to a shared/task:<id>/ resource key.",
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 all non-terminal steps and their associated tasks.",
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 getWorkflowRunStepsByRunId>>,
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 run = await getWorkflowRun(id, "display");
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 = await getWorkflowRunStepsByRunId(id, "display");
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 = ["features", "bugs", "review", "ops", "docs", "data"] as const;
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
- if (!model) return DEFAULT_CONTEXT_WINDOW;
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
- const resolved = catalogContext("anthropic", shortname);
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
  /**
@@ -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} rate-limited)`,
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
  }