@desplega.ai/agent-swarm 1.158.0 → 1.159.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 (272) hide show
  1. package/dist/{acp-adapter-xaq4n6pc.js → acp-adapter-qhch0n2v.js} +1 -1
  2. package/dist/{actions-p9hz5yat.js → actions-dtsh1mfb.js} +33 -29
  3. package/dist/{anthropic-messages-51pz26qe.js → anthropic-messages-f2h06k64.js} +8 -3
  4. package/dist/{app-g26wdcz6.js → app-y1b9srva.js} +10 -9
  5. package/dist/{assistant-wydfqkb3.js → assistant-31hwy5xj.js} +34 -30
  6. package/dist/{azure-openai-responses-8gksqtmz.js → azure-openai-responses-0k1mfax5.js} +12 -13
  7. package/dist/{boot-reembed-se8zmdcp.js → boot-reembed-48d2qpkt.js} +11 -11
  8. package/dist/{boot-reembed-g5ckg9yb.js → boot-reembed-w0bryhkr.js} +12 -12
  9. package/dist/{boot-scrub-logs-wfxqan61.js → boot-scrub-logs-t65wbrn7.js} +9 -8
  10. package/dist/{boot-seeds-s3q01xj3.js → boot-seeds-h7c32hvm.js} +12 -11
  11. package/dist/{claude-adapter-tv2x4f36.js → claude-adapter-1t6611ne.js} +26 -21
  12. package/dist/{claude-managed-adapter-41b2s7fd.js → claude-managed-adapter-werp659j.js} +4 -2
  13. package/dist/{claude-managed-setup-60g8aazx.js → claude-managed-setup-y6rdgbc1.js} +11 -2
  14. package/dist/claude-sdk-session-zhkyk8yw.js +29319 -0
  15. package/dist/{cli-vj6h9kc2.js → cli-0m7wct0d.js} +59 -1
  16. package/dist/{cli-wscdvcqz.js → cli-0n2e4x49.js} +1 -1
  17. package/dist/cli-0xqde53b.js +176 -0
  18. package/dist/{cli-xberxa1r.js → cli-10ym38qc.js} +2 -2
  19. package/dist/{cli-5b6b62tz.js → cli-13hw4z91.js} +1 -1
  20. package/dist/{cli-rqz8qbw7.js → cli-20035trh.js} +50 -18
  21. package/dist/{cli-k0g1sjzm.js → cli-31nkw3g3.js} +3 -3
  22. package/dist/cli-3gvrr8vj.js +1422 -0
  23. package/dist/{cli-c07r9a2m.js → cli-48527fpw.js} +9 -8
  24. package/dist/{cli-24k806sc.js → cli-4aj25szq.js} +2 -2
  25. package/dist/{cli-7gtvvpbh.js → cli-4tvgz99m.js} +7 -7
  26. package/dist/cli-503ya656.js +455 -0
  27. package/dist/{cli-cw9zck8j.js → cli-5f2hq128.js} +8 -4
  28. package/dist/{cli-s8eet254.js → cli-68bmme5p.js} +11078 -27833
  29. package/dist/{cli-ftfvggzx.js → cli-79aq9cgb.js} +794 -563
  30. package/dist/cli-7cxw8b60.js +14910 -0
  31. package/dist/cli-7kyk9jr3.js +22 -0
  32. package/dist/cli-7zttzetj.js +324 -0
  33. package/dist/{cli-y95wp3tg.js → cli-96qd5psa.js} +1 -1
  34. package/dist/{cli-g8djp6qe.js → cli-9yg65c1j.js} +22 -0
  35. package/dist/{cli-3gmcwfyx.js → cli-ardpzhjm.js} +5 -5
  36. package/dist/{cli-7s3syk22.js → cli-b6thtzac.js} +5 -5
  37. package/dist/{cli-00w2c66p.js → cli-bgv70kym.js} +13 -2
  38. package/dist/{cli-j55n64b6.js → cli-bv0a38v9.js} +163 -44
  39. package/dist/cli-ca2w7zv7.js +115 -0
  40. package/dist/cli-cpvsaqsw.js +333 -0
  41. package/dist/cli-cygyqj3b.js +754 -0
  42. package/dist/{cli-x24pshtq.js → cli-dvjpkkjd.js} +6 -6
  43. package/dist/{cli-5d10vd2m.js → cli-e0ndxhtk.js} +4 -4
  44. package/dist/{cli-4198qc9v.js → cli-e4xnc0qp.js} +15 -3
  45. package/dist/{cli-rjehvrts.js → cli-eg7cdg68.js} +8 -8
  46. package/dist/cli-ejpygnqz.js +3815 -0
  47. package/dist/{cli-fgqxwrpv.js → cli-fjtp3463.js} +1631 -127
  48. package/dist/{cli-zt1227k1.js → cli-fkqhbg8g.js} +5 -3
  49. package/dist/{cli-47m6dkd3.js → cli-g9df2m37.js} +409 -168
  50. package/dist/cli-gzyh0j0g.js +8455 -0
  51. package/dist/cli-hgqfttfc.js +183 -0
  52. package/dist/cli-hj65wsts.js +17755 -0
  53. package/dist/cli-j9z8mfx3.js +476 -0
  54. package/dist/{cli-aehm1rbq.js → cli-kc3dp84d.js} +1135 -61
  55. package/dist/{cli-h38x0qhg.js → cli-kdnehe0t.js} +4 -3
  56. package/dist/{cli-20cj37vt.js → cli-m4excttz.js} +136 -2216
  57. package/dist/{cli-8qmme6vd.js → cli-mg24hkt4.js} +2 -2
  58. package/dist/{cli-xhaeg2nc.js → cli-mzkqpxee.js} +1 -1
  59. package/dist/{cli-q67y4wzm.js → cli-phsaj4xq.js} +24 -2
  60. package/dist/{cli-pw9rj5t9.js → cli-pqetb83f.js} +1 -176
  61. package/dist/{cli-rj19hc34.js → cli-qjxy52w7.js} +1 -1
  62. package/dist/{cli-53sz8gkz.js → cli-qv4jv8bx.js} +1 -1
  63. package/dist/cli-qvnnx4ct.js +1051 -0
  64. package/dist/cli-rb9m6rpe.js +4980 -0
  65. package/dist/{cli-tt9k8r35.js → cli-rfezr056.js} +476 -909
  66. package/dist/{cli-ggm92wcn.js → cli-rgjprct3.js} +1 -0
  67. package/dist/{cli-9httdpyq.js → cli-rrqmqr1s.js} +1 -1
  68. package/dist/cli-rykfmgwg.js +102 -0
  69. package/dist/{cli-eetrvv91.js → cli-t3p77qk1.js} +1 -1
  70. package/dist/{cli-68w09sjw.js → cli-vn0qv9cj.js} +25 -88
  71. package/dist/{cli-987hg0aa.js → cli-vwbbaecp.js} +2 -2
  72. package/dist/cli-wd9hz40d.js +69 -0
  73. package/dist/{cli-j57qkrpq.js → cli-wgjx0q33.js} +13 -13
  74. package/dist/cli-xgpf00sk.js +2149 -0
  75. package/dist/{cli-mcnhgnn1.js → cli-ykk5jaax.js} +184 -26
  76. package/dist/{cli-aky8tctm.js → cli-z9x0sh1t.js} +3 -3
  77. package/dist/{cli-1hkrch3k.js → cli-zw65mab6.js} +5 -5
  78. package/dist/cli.js +38 -29
  79. package/dist/cloudflare-workers-ai-system-one-1sg586qv.js +46 -0
  80. package/dist/{codex-adapter-cnm8wk11.js → codex-adapter-jqfqqa21.js} +21 -14
  81. package/dist/{codex-hook-9hptmdhj.js → codex-hook-5eys3dya.js} +2 -2
  82. package/dist/{codex-session-runner-gfg547zj.js → codex-session-runner-zd341dsm.js} +21 -14
  83. package/dist/{commands-e3bn0p75.js → commands-vfsysz4s.js} +9 -8
  84. package/dist/{db-03v9kzr2.js → db-s3znhvbn.js} +15 -10
  85. package/dist/{dispatcher-nrmg8yht.js → dispatcher-5xn0c7rf.js} +32 -28
  86. package/dist/{dsh-adapter-k03nfqa6.js → dsh-adapter-894mgfvs.js} +3 -3
  87. package/dist/{e2b-93x1k0j5.js → e2b-ez07znam.js} +4 -3
  88. package/dist/execute-71ysgv35.js +965 -0
  89. package/dist/{google-generative-ai-bxmv50nc.js → google-generative-ai-1nfcdphp.js} +5 -4
  90. package/dist/{google-vertex-809af514.js → google-vertex-1tqcd7b1.js} +5 -4
  91. package/dist/{handlers-aqcedbyb.js → handlers-5w4jwycr.js} +35 -31
  92. package/dist/{hook-7vkskkre.js → hook-853bxrr6.js} +16 -13
  93. package/dist/{hook-ybvmrmhq.js → hook-z0hbxj85.js} +16 -13
  94. package/dist/{http-2eqa8t24.js → http-akc3wy3m.js} +600 -123
  95. package/dist/{index-f6cryxwe.js → index-4a5njnm1.js} +2 -59
  96. package/dist/{index-a3vn96n8.js → index-5sz16ksh.js} +187 -47
  97. package/dist/{index-c6zsv1bd.js → index-bjmjh9h4.js} +11 -11
  98. package/dist/{index-chgdkq36.js → index-cd151qkq.js} +32 -28
  99. package/dist/{index-x71bvq0p.js → index-k661dzzr.js} +33 -29
  100. package/dist/{index-1yks3qcr.js → index-ttpbhnjg.js} +32 -28
  101. package/dist/{keepalive-vtkf5n99.js → keepalive-8p9rpvz5.js} +11 -10
  102. package/dist/{lead-h3sp357x.js → lead-jp69z5h3.js} +49 -45
  103. package/dist/llama-cpp-classify-t2tccams.js +335 -0
  104. package/dist/{maintenance-jzeqtk3q.js → maintenance-fwx4ev0k.js} +12 -12
  105. package/dist/{mistral-conversations-zx0kn554.js → mistral-conversations-bhvwqcnk.js} +14 -17
  106. package/dist/{oauth-refresh-sweep-qp3dzmdp.js → oauth-refresh-sweep-cwcq1ctx.js} +10 -9
  107. package/dist/{onboard-tmsp0qbz.js → onboard-2b4q0t84.js} +6 -5
  108. package/dist/{openai-codex-responses-4vjqzvjp.js → openai-codex-responses-nekthgks.js} +21 -8
  109. package/dist/{openai-completions-9hjrqbw8.js → openai-completions-hxtzwj0s.js} +8 -11
  110. package/dist/{openai-responses-7b1pn0xt.js → openai-responses-w4r118w7.js} +22 -17
  111. package/dist/{opencode-adapter-x6x2da1z.js → opencode-adapter-zz7xvjj6.js} +6 -4
  112. package/dist/{openrouter-images-9f9ek4rw.js → openrouter-images-b6sqqjgn.js} +4 -6
  113. package/dist/{otel-impl-9mz73q65.js → otel-impl-g8rs4vwr.js} +1 -1
  114. package/dist/{pi-messages-txpjj39q.js → pi-messages-vxdt8v7j.js} +2 -1
  115. package/dist/{pi-mono-adapter-m6dvv0dz.js → pi-mono-adapter-n0me28wt.js} +29 -17
  116. package/dist/pricing-refresh-0v77385v.js +39 -0
  117. package/dist/{rbac-roles-c9wqz83x.js → rbac-roles-krjyazbj.js} +10 -9
  118. package/dist/{render-v2-gryrh9h8.js → render-v2-3wjsp9aw.js} +10 -9
  119. package/dist/runtime-ktjysacx.js +24 -0
  120. package/dist/{setup-q9720bt6.js → setup-yeqryke6.js} +6 -5
  121. package/dist/typesafe-system-one-96960jxp.js +27 -0
  122. package/dist/{virtual-modules-3htpgn8x.js → virtual-modules-dzdeq1sf.js} +21 -13
  123. package/dist/{work-objects-b76x7deb.js → work-objects-3pakpkw0.js} +35 -31
  124. package/dist/{worker-6vrxbv41.js → worker-85testgj.js} +49 -45
  125. package/openapi.json +863 -14
  126. package/package.json +9 -8
  127. package/src/be/db/agents.ts +20 -0
  128. package/src/be/db/tasks/human-free.ts +442 -0
  129. package/src/be/db/tasks/read.ts +56 -1
  130. package/src/be/db/tasks/write.ts +107 -11
  131. package/src/be/db.ts +89 -165
  132. package/src/be/harness-model-support.ts +182 -0
  133. package/src/be/human-free-drain.ts +67 -0
  134. package/src/be/migrations/182_task_human_free_flag.sql +63 -0
  135. package/src/be/migrations/183_human_free_reclassify_queue.sql +25 -0
  136. package/src/be/migrations/184_model_catalog.sql +120 -0
  137. package/src/be/model-catalog-store.ts +644 -0
  138. package/src/be/model-tier-keys.ts +31 -0
  139. package/src/be/model-tier-resolution.ts +489 -0
  140. package/src/be/model-validation.ts +112 -0
  141. package/src/be/models-catalog.ts +61 -7
  142. package/src/be/modelsdev-cache.json +82 -0
  143. package/src/be/modelsdev-cache.ts +2 -0
  144. package/src/be/pricing-refresh.ts +154 -12
  145. package/src/be/scripts/typecheck.ts +15 -0
  146. package/src/be/seed-scripts/catalog/task-failure-audit.ts +61 -9
  147. package/src/be/swarm-config-guard.ts +6 -0
  148. package/src/cli.tsx +10 -0
  149. package/src/commands/claude-managed-setup.ts +3 -1
  150. package/src/commands/runner.ts +76 -2
  151. package/src/extensions/contract-types.generated.ts +1 -1
  152. package/src/heartbeat/heartbeat.ts +64 -15
  153. package/src/heartbeat/templates.ts +2 -2
  154. package/src/http/agents.ts +49 -1
  155. package/src/http/index.ts +8 -0
  156. package/src/http/models-catalog.ts +357 -8
  157. package/src/http/poll.ts +45 -2
  158. package/src/http/schedules.ts +36 -6
  159. package/src/http/session-data.ts +2 -5
  160. package/src/http/stats.ts +6 -8
  161. package/src/http/tasks.ts +26 -1
  162. package/src/http/usage-cache.ts +56 -15
  163. package/src/http/workflows.ts +35 -8
  164. package/src/prompts/session-templates.ts +1 -0
  165. package/src/providers/claude-managed-models.ts +47 -161
  166. package/src/providers/codex-adapter.ts +4 -4
  167. package/src/providers/codex-models.ts +65 -198
  168. package/src/providers/reasoning-effort.ts +44 -140
  169. package/src/rbac/legacy-policy.ts +25 -0
  170. package/src/rbac/permissions.ts +10 -0
  171. package/src/scripts-runtime/sdk-allowlist.ts +4 -0
  172. package/src/scripts-runtime/types/stdlib.d.ts +15 -0
  173. package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
  174. package/src/scripts-runtime/types/swarm-sdk.d.ts +15 -0
  175. package/src/server.ts +6 -0
  176. package/src/slack/message-text.ts +56 -2
  177. package/src/slack/thread-buffer.ts +10 -2
  178. package/src/tests/agents-list-model-display.test.ts +4 -6
  179. package/src/tests/base-prompt.test.ts +3 -0
  180. package/src/tests/claude-adapter.test.ts +10 -0
  181. package/src/tests/claude-managed-adapter.test.ts +12 -18
  182. package/src/tests/codex-adapter.test.ts +2 -1
  183. package/src/tests/codex-gpt6-release.test.ts +66 -5
  184. package/src/tests/context-window.test.ts +7 -5
  185. package/src/tests/db-extraction-contract.test.ts +1 -0
  186. package/src/tests/db-task-read-contract.test.ts +5 -1
  187. package/src/tests/db-task-write-contract.test.ts +4 -1
  188. package/src/tests/docs-index-footprint.test.js +3 -3
  189. package/src/tests/explicit-model-validation.test.ts +332 -0
  190. package/src/tests/harness-model-support.test.ts +374 -0
  191. package/src/tests/heartbeat-checklist-config.test.ts +71 -0
  192. package/src/tests/heartbeat-checklist.test.ts +4 -2
  193. package/src/tests/heartbeat-orphan-resume.test.ts +48 -0
  194. package/src/tests/human-free-flag.test.ts +279 -0
  195. package/src/tests/human-free-oracle.ts +57 -0
  196. package/src/tests/human-free-reclassify.test.ts +669 -0
  197. package/src/tests/migration-046-budgets.test.ts +3 -3
  198. package/src/tests/model-catalog-migration.test.ts +134 -0
  199. package/src/tests/model-catalog-table.test.ts +249 -0
  200. package/src/tests/model-catalog-write-access.test.ts +387 -0
  201. package/src/tests/model-tier-resolution.test.ts +519 -0
  202. package/src/tests/models-catalog.test.ts +1 -1
  203. package/src/tests/multi-runtime-enabled-stats.test.ts +65 -1
  204. package/src/tests/package-publish.test.ts +137 -36
  205. package/src/tests/pricing-routes.test.ts +2 -2
  206. package/src/tests/rbac-engine.test.ts +42 -2
  207. package/src/tests/reasoning-effort.test.ts +109 -0
  208. package/src/tests/refresh-modelsdev-carryforward.test.ts +5 -5
  209. package/src/tests/runtime-model-catalog.test.ts +86 -0
  210. package/src/tests/script-connections.test.ts +5 -0
  211. package/src/tests/seed-scripts.test.ts +89 -0
  212. package/src/tests/session-costs.test.ts +14 -11
  213. package/src/tests/slack-message-text.test.ts +101 -0
  214. package/src/tests/slack-thread-buffer-context.test.ts +93 -0
  215. package/src/tests/task-cascade-fail.test.ts +148 -2
  216. package/src/tests/tool-annotations.test.ts +1 -1
  217. package/src/tests/usage-cache.test.ts +166 -0
  218. package/src/tests/workflow-executors.test.ts +5 -2
  219. package/src/tests/workflow-system-one-decision-review.test.ts +1021 -0
  220. package/src/tests/workflow-system-one-decision-save-warnings.test.ts +365 -0
  221. package/src/tests/workflow-system-one-decision.test.ts +2063 -0
  222. package/src/tools/model-catalog/index.ts +137 -0
  223. package/src/tools/schedules/create-schedule.ts +16 -1
  224. package/src/tools/schedules/patch-schedule.ts +17 -0
  225. package/src/tools/schedules/update-schedule.ts +17 -0
  226. package/src/tools/send-task.ts +14 -0
  227. package/src/tools/task-action.ts +12 -0
  228. package/src/tools/tool-config.ts +3 -1
  229. package/src/tools/workflows/create-workflow.ts +9 -2
  230. package/src/tools/workflows/patch-workflow-node.ts +17 -7
  231. package/src/tools/workflows/patch-workflow.ts +9 -2
  232. package/src/tools/workflows/update-workflow.ts +9 -2
  233. package/src/types.ts +30 -1
  234. package/src/utils/context-window.ts +47 -53
  235. package/src/utils/harness-cli-version.ts +115 -0
  236. package/src/utils/harness-model-error.ts +33 -0
  237. package/src/utils/runtime-model-catalog.ts +137 -0
  238. package/src/workflows/approval-resolution.ts +39 -0
  239. package/src/workflows/definition.ts +7 -0
  240. package/src/workflows/engine.ts +69 -1
  241. package/src/workflows/executors/agent-task.ts +9 -0
  242. package/src/workflows/executors/base.ts +53 -0
  243. package/src/workflows/executors/human-in-the-loop.ts +8 -8
  244. package/src/workflows/executors/index.ts +1 -0
  245. package/src/workflows/executors/registry.ts +2 -0
  246. package/src/workflows/executors/system-one-decision.ts +1232 -0
  247. package/src/workflows/executors/system-one-providers.ts +301 -0
  248. package/src/workflows/executors/workflow-llm.ts +13 -1
  249. package/src/workflows/readiness.ts +86 -0
  250. package/src/workflows/recovery.ts +12 -12
  251. package/src/workflows/resume.ts +23 -9
  252. package/templates/schedules/daily-blocker-digest/content.md +4 -5
  253. package/templates/skills/agent-browser/SKILL.md +6 -5
  254. package/templates/skills/agent-browser/content.md +6 -5
  255. package/templates/skills/heartbeat-runbook/config.json +1 -1
  256. package/templates/skills/heartbeat-runbook/content.md +2 -2
  257. package/templates/skills/swarm-scripts/SKILL.md +1 -1
  258. package/templates/skills/swarm-scripts/content.md +1 -1
  259. package/templates/skills/workflow-iterate/content.md +81 -1
  260. package/templates/workflows/claude-code-changelog-watch/content.md +2 -0
  261. package/templates/workflows/pr-review-status-sweep/content.md +2 -0
  262. package/dist/claude-sdk-session-t442qz6f.js +0 -39108
  263. package/dist/cli-0xjkj1j7.js +0 -61
  264. package/dist/cli-65hjmev5.js +0 -1141
  265. package/dist/cli-aw1jwp1r.js +0 -14075
  266. package/dist/cli-h967nb6r.js +0 -6603
  267. package/dist/cli-vapyk8sw.js +0 -20
  268. package/dist/cli-ws6rqycm.js +0 -247
  269. package/dist/pricing-refresh-v1cbr9te.js +0 -27
  270. package/src/providers/modelsdev-reasoning.json +0 -6453
  271. package/dist/{codex-login-x3jk4etn.js → codex-login-he9vrn90.js} +3 -3
  272. package/dist/{index-f24115ge.js → index-2wsdsnmm.js} +3 -3
@@ -7,12 +7,18 @@ import {
7
7
  } from "./cli-dgnj0zcc.js";
8
8
  import {
9
9
  SIMILARITY_THRESHOLD,
10
+ isUnknownModelError,
10
11
  memoryRelevance,
11
12
  writeSkillsToFilesystem
12
- } from "./cli-q67y4wzm.js";
13
+ } from "./cli-phsaj4xq.js";
13
14
  import {
14
15
  Anthropic
15
16
  } from "./cli-j490egb5.js";
17
+ import {
18
+ checkHeartbeatChecklist,
19
+ runHeartbeatSweep,
20
+ stopHeartbeat
21
+ } from "./cli-20035trh.js";
16
22
  import {
17
23
  isClaudeBridgeEffective,
18
24
  resolveClaudeTransport
@@ -22,16 +28,11 @@ import {
22
28
  } from "./cli-npssxgaz.js";
23
29
  import {
24
30
  reasoningCapability
25
- } from "./cli-h967nb6r.js";
31
+ } from "./cli-ca2w7zv7.js";
26
32
  import {
27
33
  ensureAgentFsCredentialsForAgent,
28
34
  inviteEmailToSharedOrg
29
- } from "./cli-xhaeg2nc.js";
30
- import {
31
- checkHeartbeatChecklist,
32
- runHeartbeatSweep,
33
- stopHeartbeat
34
- } from "./cli-rqz8qbw7.js";
35
+ } from "./cli-mzkqpxee.js";
35
36
  import {
36
37
  AGENT_MAX_TASKS_CONFIG_KEY,
37
38
  ALL_CAPABILITIES,
@@ -58,6 +59,7 @@ import {
58
59
  TriggerSchemaError,
59
60
  WebhookError,
60
61
  activateVersion,
62
+ agentRanModel,
61
63
  agentWithCapacity,
62
64
  allowedCredentialRedirect,
63
65
  applyRating,
@@ -80,7 +82,6 @@ import {
80
82
  checkOutputSchemaShape,
81
83
  clearJiraMetadata,
82
84
  closeRooms,
83
- createApprovalFollowUpTask,
84
85
  createEvent,
85
86
  createEventsBatch,
86
87
  createResumeFollowUp,
@@ -103,10 +104,13 @@ import {
103
104
  executeRawLlm,
104
105
  executeReadOnlyQuery,
105
106
  expandCandidatesWithGraph,
107
+ explicitModelError,
108
+ explicitModelErrorForAgent,
106
109
  extractAndVerifyCookie,
107
110
  findUserById,
108
111
  fingerprintApiKey,
109
112
  flushAuditBuffer,
113
+ getAgentHarnessCliVersion,
110
114
  getAutomationSetupStates,
111
115
  getEnabledCapabilities,
112
116
  getEventCountsFiltered,
@@ -185,6 +189,7 @@ import {
185
189
  listExtensionRuns,
186
190
  listExtensionVersions,
187
191
  listExtensions,
192
+ listHarnessModelSupport,
188
193
  listOAuthPresetIds,
189
194
  listOAuthPresets,
190
195
  listRuntimeInstancesForAgent,
@@ -201,13 +206,17 @@ import {
201
206
  mintToken,
202
207
  parseBody,
203
208
  parseCookieHeader,
209
+ parseModelTierOverridesHeader,
204
210
  parseQueryParams,
205
211
  parseSkillContent,
206
212
  patchWorkflowDefinition,
207
213
  preflightAutomation,
214
+ previewModelTiers,
208
215
  readScriptSdkJsonResponse,
209
216
  reconcileAgentMaxTasksPolicy,
210
217
  reconcileAgentStatusFromRuntimes,
218
+ recordClaimModelResolution,
219
+ recordHarnessModelSupport,
211
220
  recordIdentityEvent,
212
221
  recordMemoryAccesses,
213
222
  recordRetrievals,
@@ -244,11 +253,14 @@ import {
244
253
  runtimeInstanceHeader,
245
254
  runtimeStaleThresholdMinutes,
246
255
  safeRequestUrlForLog,
256
+ sanitizeModelTierOverrides,
247
257
  scheduleIntegrationsReload,
248
258
  scopedResourceScopeIdSchema,
249
259
  sendKapsoReaction,
250
260
  sendTaskHandler,
251
261
  sendTaskOutputSchema,
262
+ setAgentHarnessCliVersion,
263
+ setAgentModelTierOverrides,
252
264
  setCorsHeaders,
253
265
  setExtensionLoopbackBaseUrl,
254
266
  setRuntimeCredentialReady,
@@ -287,32 +299,25 @@ import {
287
299
  verifyHmacSignature,
288
300
  verifyWebhookSignature,
289
301
  warnIfCorsAllowsAnyOrigin,
290
- wireHttpSpanLifecycle
291
- } from "./cli-ftfvggzx.js";
302
+ wireHttpSpanLifecycle,
303
+ workflowSaveWarnings
304
+ } from "./cli-79aq9cgb.js";
292
305
  import"./cli-0z2v4nhw.js";
293
306
  import {
294
307
  REFERENCES_SOURCE_MAX_LENGTH,
295
308
  sanitizeReferencesSource
296
- } from "./cli-tt9k8r35.js";
297
- import {
298
- CLIENT_ID,
299
- MAX_CODEX_OAUTH_SLOT,
300
- _fetchHolder,
301
- codexOAuthKeyForSlot,
302
- deriveCodexKeySuffix,
303
- exchangeAuthorizationCode as exchangeAuthorizationCode2,
304
- getAccountId,
305
- getValidCodexOAuth,
306
- loadAllCodexOAuthSlots
307
- } from "./cli-vhjwh6cz.js";
309
+ } from "./cli-cpvsaqsw.js";
308
310
  import {
309
311
  isMultiRuntimeEnabled
310
312
  } from "./cli-re8z5p8p.js";
311
- import"./cli-3dpj7atn.js";
312
- import"./cli-aw1jwp1r.js";
313
+ import {
314
+ FilesError,
315
+ getFileStorageProvider,
316
+ normalizeFilesError
317
+ } from "./cli-jsp14b6c.js";
313
318
  import {
314
319
  getUserGrant
315
- } from "./cli-aky8tctm.js";
320
+ } from "./cli-z9x0sh1t.js";
316
321
  import {
317
322
  LEGACY_RULES,
318
323
  can,
@@ -320,13 +325,17 @@ import {
320
325
  decideToolAdmission,
321
326
  isRbacEnabled,
322
327
  setAuditSink
323
- } from "./cli-g8djp6qe.js";
328
+ } from "./cli-9yg65c1j.js";
324
329
  import {
325
- getModelsCatalog
326
- } from "./cli-ws6rqycm.js";
330
+ deleteModelCatalogOverlay,
331
+ loadModelsCatalog,
332
+ requestModelCatalogRefresh,
333
+ upsertModelCatalogOverlay
334
+ } from "./cli-cygyqj3b.js";
335
+ import"./cli-m4excttz.js";
327
336
  import {
328
337
  normalizeModelKey
329
- } from "./cli-wscdvcqz.js";
338
+ } from "./cli-0n2e4x49.js";
330
339
  import {
331
340
  ConnectionAuthInputSchema,
332
341
  MAX_SCRIPT_WALL_CLOCK_MS,
@@ -347,6 +356,7 @@ import {
347
356
  connectionAuthInputFromFlat,
348
357
  connectionAuthSummary,
349
358
  consumeMcpOAuthPending,
359
+ createApprovalFollowUpTask,
350
360
  createScriptApi,
351
361
  definitionNodeIds,
352
362
  deleteMcpOAuthToken,
@@ -418,7 +428,7 @@ import {
418
428
  upsertScriptByName,
419
429
  upsertScriptConnection,
420
430
  validateDefinition
421
- } from "./cli-fgqxwrpv.js";
431
+ } from "./cli-fjtp3463.js";
422
432
  import"./cli-epan13p1.js";
423
433
  import {
424
434
  detachedProcessGroup,
@@ -430,9 +440,25 @@ import {
430
440
  import {
431
441
  getApiKey
432
442
  } from "./cli-f14fvzag.js";
443
+ import"./cli-rfezr056.js";
444
+ import {
445
+ CLIENT_ID,
446
+ MAX_CODEX_OAUTH_SLOT,
447
+ _fetchHolder,
448
+ codexOAuthKeyForSlot,
449
+ deriveCodexKeySuffix,
450
+ exchangeAuthorizationCode as exchangeAuthorizationCode2,
451
+ getAccountId,
452
+ getValidCodexOAuth,
453
+ loadAllCodexOAuthSlots
454
+ } from "./cli-vhjwh6cz.js";
455
+ import"./cli-3dpj7atn.js";
456
+ import"./cli-gzyh0j0g.js";
457
+ import"./cli-rb9m6rpe.js";
458
+ import"./cli-rykfmgwg.js";
433
459
  import {
434
460
  searchScripts
435
- } from "./cli-987hg0aa.js";
461
+ } from "./cli-vwbbaecp.js";
436
462
  import {
437
463
  acquireOAuthRefreshLock,
438
464
  buildAuthorizationUrl,
@@ -456,29 +482,22 @@ import {
456
482
  updateAuthorizationIdentity,
457
483
  updateOAuthAppById,
458
484
  upsertAuthorization
459
- } from "./cli-53sz8gkz.js";
460
- import {
461
- FilesError,
462
- getFileStorageProvider,
463
- normalizeFilesError
464
- } from "./cli-jsp14b6c.js";
485
+ } from "./cli-qv4jv8bx.js";
486
+ import"./cli-fad8m16k.js";
465
487
  import {
466
488
  CANDIDATE_SET_MULTIPLIER,
467
489
  EMBEDDING_DIMENSIONS,
490
+ OpenAI,
468
491
  getEmbeddingProvider,
469
492
  getMemoryStore,
470
493
  init_constants as init_constants2,
494
+ init_openai,
471
495
  init_reranker,
472
496
  rerank
473
- } from "./cli-65hjmev5.js";
474
- import"./cli-xberxa1r.js";
497
+ } from "./cli-kc3dp84d.js";
498
+ import"./cli-10ym38qc.js";
475
499
  import"./cli-bsakbbkm.js";
476
- import"./cli-fad8m16k.js";
477
500
  import"./cli-51tf7ac3.js";
478
- import {
479
- OpenAI,
480
- init_openai
481
- } from "./cli-aehm1rbq.js";
482
501
  import {
483
502
  TaskCitationSchema,
484
503
  ensure,
@@ -498,7 +517,7 @@ import {
498
517
  withRemoteContext,
499
518
  withSpan,
500
519
  withSpanContext
501
- } from "./cli-j57qkrpq.js";
520
+ } from "./cli-wgjx0q33.js";
502
521
  import"./cli-q51yprfq.js";
503
522
  import"./cli-3er6gcsn.js";
504
523
  import"./cli-2658f6at.js";
@@ -576,6 +595,7 @@ import {
576
595
  deleteTaskAttachment,
577
596
  deleteUser,
578
597
  deleteWorkflow,
598
+ drainHumanFreeReclassifyQueue,
579
599
  emitBuiltInIntegrationConnectedOnce,
580
600
  emitIntegrationConnected,
581
601
  emitMcpServerConnectedTelemetry,
@@ -589,6 +609,7 @@ import {
589
609
  getAgentHarnessProviders,
590
610
  getAgentMcpServers,
591
611
  getAgentSkills,
612
+ getAgentStatusCounts,
592
613
  getAgentWithTasks,
593
614
  getAllAgents,
594
615
  getAllAgentsWithTasks,
@@ -677,7 +698,6 @@ import {
677
698
  getTaskSteeringFieldsForTasks,
678
699
  getTasksCount,
679
700
  getUnassignedTaskIdsForAgent,
680
- getUsageDataVersion,
681
701
  getUserById,
682
702
  getWorkflow,
683
703
  getWorkflowRun,
@@ -699,6 +719,7 @@ import {
699
719
  init_db,
700
720
  init_default_drift,
701
721
  init_heartbeat_expiry,
722
+ init_human_free,
702
723
  init_request_auth_context,
703
724
  init_steering,
704
725
  init_swarm_config_guard,
@@ -764,7 +785,9 @@ import {
764
785
  setApiKeyName,
765
786
  setApiKeyPlan,
766
787
  setFavorite,
788
+ setHumanFreeQueueListener,
767
789
  setRequestAuth,
790
+ settleSupersededTaskDependents,
768
791
  startTask,
769
792
  supersedeTask,
770
793
  sweepExpiredKv,
@@ -808,7 +831,7 @@ import {
808
831
  upsertSwarmConfig,
809
832
  validateConfigValue,
810
833
  withFavoriteFlags
811
- } from "./cli-47m6dkd3.js";
834
+ } from "./cli-g9df2m37.js";
812
835
  import {
813
836
  ActiveSessionSchema,
814
837
  AgentAcpStatusSchema,
@@ -858,6 +881,7 @@ import {
858
881
  KvKeySchema,
859
882
  KvNamespaceSchema,
860
883
  KvValueTypeSchema,
884
+ MODEL_TIERS,
861
885
  McpAuthMethodSchema,
862
886
  McpServerSchema,
863
887
  McpServerWithInstallInfoSchema,
@@ -934,12 +958,16 @@ import {
934
958
  isSafeBundlePath,
935
959
  isTerminalTaskStatus,
936
960
  splitLegacyModelAlias
937
- } from "./cli-4198qc9v.js";
961
+ } from "./cli-e4xnc0qp.js";
938
962
  import {
939
963
  IDENTITY_FIELD_BUDGETS,
940
964
  IdentityFieldBudgetError,
941
965
  init_identity_field_budget
942
- } from "./cli-3gmcwfyx.js";
966
+ } from "./cli-ardpzhjm.js";
967
+ import {
968
+ getSlackConfiguration,
969
+ init_config
970
+ } from "./cli-n7h1kqpf.js";
943
971
  import {
944
972
  getAllTemplateDefinitions,
945
973
  getTemplateDefinition,
@@ -950,8 +978,7 @@ import {
950
978
  interpolate,
951
979
  isSteeringEnabled,
952
980
  resolveTemplate
953
- } from "./cli-ggm92wcn.js";
954
- import"./cli-19jenss3.js";
981
+ } from "./cli-rgjprct3.js";
955
982
  import {
956
983
  MAX_PROFILE_FILE_LENGTH,
957
984
  getAppUrl,
@@ -960,26 +987,27 @@ import {
960
987
  getPublicMcpBaseUrl,
961
988
  init_constants
962
989
  } from "./cli-dv6cdjs2.js";
963
- import {
964
- getSlackConfiguration,
965
- init_config
966
- } from "./cli-n7h1kqpf.js";
967
- import {
968
- MODEL_SCOPED_WINDOWS,
969
- activeModelBlocks,
970
- init_model_rate_limit_windows
971
- } from "./cli-de1396j2.js";
972
990
  import {
973
991
  SUBSCRIPTION_PLANS,
974
992
  SUBSCRIPTION_PLANS_CHECKED_AT,
975
993
  init_subscription_plans,
976
994
  isSubscriptionPlanId
977
995
  } from "./cli-cqt19wg6.js";
996
+ import"./cli-19jenss3.js";
997
+ import {
998
+ MODEL_SCOPED_WINDOWS,
999
+ activeModelBlocks,
1000
+ init_model_rate_limit_windows
1001
+ } from "./cli-de1396j2.js";
978
1002
  import {
979
1003
  init_env_flag,
980
1004
  isEnvFlagEnabled,
981
1005
  parseEnvFlag
982
1006
  } from "./cli-ej6gbxfb.js";
1007
+ import {
1008
+ init_src,
1009
+ isAlias
1010
+ } from "./cli-7zttzetj.js";
983
1011
  import {
984
1012
  exports_zod,
985
1013
  init_zod
@@ -996,7 +1024,7 @@ import {
996
1024
  import {
997
1025
  init_package,
998
1026
  package_default
999
- } from "./cli-c07r9a2m.js";
1027
+ } from "./cli-48527fpw.js";
1000
1028
  import {
1001
1029
  init_secret_scrubber,
1002
1030
  registerVolatileSecret,
@@ -1005,20 +1033,20 @@ import {
1005
1033
  } from "./cli-r2ap2czm.js";
1006
1034
  import {
1007
1035
  bedrockProviderModule
1008
- } from "./cli-h38x0qhg.js";
1036
+ } from "./cli-kdnehe0t.js";
1009
1037
  import"./cli-yn0a417a.js";
1010
1038
  import"./cli-cgj4hc12.js";
1011
1039
  import"./cli-txgcknmy.js";
1012
1040
  import"./cli-6map995v.js";
1013
- import"./cli-k0g1sjzm.js";
1041
+ import"./cli-31nkw3g3.js";
1014
1042
  import"./cli-y2apkfe2.js";
1015
- import"./cli-vapyk8sw.js";
1043
+ import"./cli-7kyk9jr3.js";
1016
1044
  import {
1017
1045
  setBedrockProviderModule
1018
- } from "./cli-5b6b62tz.js";
1046
+ } from "./cli-13hw4z91.js";
1019
1047
  import"./cli-btbzvq95.js";
1020
1048
  import"./cli-1m2e086m.js";
1021
- import"./cli-mcnhgnn1.js";
1049
+ import"./cli-ykk5jaax.js";
1022
1050
  import"./cli-bzr0ftht.js";
1023
1051
  import"./cli-bd957dgb.js";
1024
1052
  import {
@@ -1509,6 +1537,62 @@ async function stopDbRetention() {
1509
1537
  await retentionTickPromise;
1510
1538
  }
1511
1539
 
1540
+ // src/be/human-free-drain.ts
1541
+ init_human_free();
1542
+ var YIELD_MS2 = 25;
1543
+ var IDLE_INTERVAL_MS = 60000;
1544
+ var running = false;
1545
+ var idleTimer = null;
1546
+ var passTimer = null;
1547
+ function scheduleIdle() {
1548
+ if (!running)
1549
+ return;
1550
+ if (idleTimer)
1551
+ clearTimeout(idleTimer);
1552
+ idleTimer = setTimeout(() => schedulePass(0), IDLE_INTERVAL_MS);
1553
+ idleTimer.unref?.();
1554
+ }
1555
+ function schedulePass(delayMs) {
1556
+ if (!running || passTimer)
1557
+ return;
1558
+ passTimer = setTimeout(() => {
1559
+ passTimer = null;
1560
+ runPass();
1561
+ }, delayMs);
1562
+ passTimer.unref?.();
1563
+ }
1564
+ async function runPass() {
1565
+ if (!running)
1566
+ return;
1567
+ try {
1568
+ const { batches, remaining } = await drainHumanFreeReclassifyQueue({ maxBatches: 1 });
1569
+ if (batches > 0 && remaining > 0) {
1570
+ schedulePass(YIELD_MS2);
1571
+ return;
1572
+ }
1573
+ } catch (err) {
1574
+ console.error("[human-free-drain] batch failed, retrying later:", err instanceof Error ? err.message : String(err));
1575
+ }
1576
+ scheduleIdle();
1577
+ }
1578
+ function startHumanFreeDrain() {
1579
+ if (running)
1580
+ return;
1581
+ running = true;
1582
+ setHumanFreeQueueListener(() => schedulePass(0));
1583
+ schedulePass(0);
1584
+ }
1585
+ function stopHumanFreeDrain() {
1586
+ running = false;
1587
+ setHumanFreeQueueListener(undefined);
1588
+ if (idleTimer)
1589
+ clearTimeout(idleTimer);
1590
+ if (passTimer)
1591
+ clearTimeout(passTimer);
1592
+ idleTimer = null;
1593
+ passTimer = null;
1594
+ }
1595
+
1512
1596
  // src/be/scripts/retention.ts
1513
1597
  init_db();
1514
1598
  var SCRATCH_RETENTION_DAYS = 14;
@@ -3326,6 +3410,7 @@ async function handleActiveSessions(req, res, pathSegments, queryParams, myAgent
3326
3410
  }
3327
3411
 
3328
3412
  // src/http/agents.ts
3413
+ init_src();
3329
3414
  init_zod();
3330
3415
  init_db();
3331
3416
  init_telemetry();
@@ -3378,7 +3463,9 @@ var registerAgent = route({
3378
3463
  maxTasks: exports_external.number().int().optional(),
3379
3464
  provider: ProviderNameSchema.optional(),
3380
3465
  harness_provider: ProviderNameSchema.optional(),
3381
- runtimeInstanceId: exports_external.string().min(1).optional()
3466
+ runtimeInstanceId: exports_external.string().min(1).optional(),
3467
+ modelTierOverrides: exports_external.record(exports_external.string(), exports_external.record(exports_external.string(), exports_external.string())).optional(),
3468
+ harnessCliVersion: exports_external.string().max(64).optional()
3382
3469
  }),
3383
3470
  responses: {
3384
3471
  200: {
@@ -3458,7 +3545,7 @@ var updateAgentRuntimeRoute = route({
3458
3545
  path: "/api/agents/{id}/runtime",
3459
3546
  pattern: ["api", "agents", null, "runtime"],
3460
3547
  summary: "Update an agent's runtime harness and default model",
3461
- description: "Updates `agents.harness_provider` and agent-scoped runtime config. The settings apply to future provider sessions. For `model`, `reasoning_effort`, and `claude.transport`: omit the field to leave it unchanged, send `null` to clear the corresponding override, or send a value to set it.",
3548
+ description: "Updates `agents.harness_provider` and agent-scoped runtime config. The settings apply to future provider sessions. For `model`, `reasoning_effort`, and `claude.transport`: omit the field to leave it unchanged, send `null` to clear the corresponding override, or send a value to set it. A `model` the model catalog does not list is a 400 unless `allow_custom_model` is true. A `latest:` alias is not accepted here (aliases resolve for a task's model and for `MODEL_TIER_*` values); `reasoning_effort` must be one the harness and model support.",
3462
3549
  tags: ["Agents"],
3463
3550
  params: exports_external.object({ id: exports_external.string() }),
3464
3551
  query: exports_external.object({ repoId: exports_external.string().optional() }),
@@ -3809,6 +3896,12 @@ async function handleAgentRegister(req, res, pathSegments, myAgentId) {
3809
3896
  }
3810
3897
  return { agent, created: true };
3811
3898
  });
3899
+ if (parsed.body.harnessCliVersion !== undefined) {
3900
+ await setAgentHarnessCliVersion(agentId, parsed.body.harnessCliVersion.trim() || null);
3901
+ }
3902
+ if (parsed.body.modelTierOverrides) {
3903
+ await setAgentModelTierOverrides(agentId, sanitizeModelTierOverrides(parsed.body.modelTierOverrides));
3904
+ }
3812
3905
  telemetry.agent("registered", {
3813
3906
  role: parsed.body.role,
3814
3907
  capabilities: parsed.body.capabilities ?? [],
@@ -4114,6 +4207,21 @@ async function handleAgentsRest(req, res, pathSegments, queryParams, _myAgentId)
4114
4207
  return true;
4115
4208
  }
4116
4209
  }
4210
+ if (typeof model === "string" && isAlias(model)) {
4211
+ jsonError(res, `A latest: alias cannot be an agent's default model ("${model}"). Set the alias on a task, or as a MODEL_TIER_<PROVIDER>_<TIER> value.`, 400);
4212
+ return true;
4213
+ }
4214
+ if (typeof model === "string") {
4215
+ const modelError = await explicitModelError({
4216
+ model,
4217
+ allowCustomModel: allow_custom_model,
4218
+ harnessProvider: harness_provider
4219
+ });
4220
+ if (modelError) {
4221
+ jsonError(res, modelError, 400);
4222
+ return true;
4223
+ }
4224
+ }
4117
4225
  let agent;
4118
4226
  try {
4119
4227
  agent = await getDbClient().transaction(async () => {
@@ -4373,22 +4481,50 @@ init_subscription_plans();
4373
4481
 
4374
4482
  // src/http/usage-cache.ts
4375
4483
  var USAGE_CACHE_TTL_MS = 30000;
4484
+ var USAGE_CACHE_MAX_STALE_MS = 120000;
4376
4485
  var MAX_ENTRIES = 100;
4377
4486
  var entries = new Map;
4378
- async function cachedUsageReport(key, load) {
4379
- const now = Date.now();
4487
+ var loading = new Map;
4488
+ var generation = 0;
4489
+ function load(key, loader) {
4490
+ const running2 = loading.get(key);
4491
+ if (running2)
4492
+ return running2;
4493
+ const startedIn = generation;
4494
+ const promise = Promise.resolve().then(loader).then((value) => {
4495
+ if (startedIn === generation) {
4496
+ entries.delete(key);
4497
+ if (entries.size >= MAX_ENTRIES)
4498
+ entries.delete(entries.keys().next().value);
4499
+ entries.set(key, { fetchedAt: Date.now(), value });
4500
+ }
4501
+ return value;
4502
+ }).finally(() => {
4503
+ if (loading.get(key) === promise)
4504
+ loading.delete(key);
4505
+ });
4506
+ loading.set(key, promise);
4507
+ return promise;
4508
+ }
4509
+ async function cachedUsageReport(key, loader) {
4380
4510
  const hit = entries.get(key);
4381
- if (hit && hit.expiresAt > now)
4382
- return hit.value;
4383
- const value = await load();
4384
- entries.delete(key);
4385
- if (entries.size >= MAX_ENTRIES)
4386
- entries.delete(entries.keys().next().value);
4387
- entries.set(key, { expiresAt: now + USAGE_CACHE_TTL_MS, value });
4388
- return value;
4511
+ if (hit) {
4512
+ const age = Date.now() - hit.fetchedAt;
4513
+ if (age < USAGE_CACHE_TTL_MS)
4514
+ return hit.value;
4515
+ if (age < USAGE_CACHE_MAX_STALE_MS) {
4516
+ load(key, loader).catch((error) => {
4517
+ console.error(`[usage-cache] background refresh failed for ${key.split(":")[0]}:`, error);
4518
+ });
4519
+ return hit.value;
4520
+ }
4521
+ }
4522
+ return load(key, loader);
4389
4523
  }
4390
4524
  function clearUsageCache() {
4525
+ generation++;
4391
4526
  entries.clear();
4527
+ loading.clear();
4392
4528
  }
4393
4529
 
4394
4530
  // src/http/api-keys.ts
@@ -7671,6 +7807,9 @@ declare module "swarm-extension" {
7671
7807
  model?: string | undefined;
7672
7808
  modelTier?: "smol" | "regular" | "smart" | "ultra" | undefined;
7673
7809
  effort?: "off" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
7810
+ resolvedModel?: string | undefined;
7811
+ modelSource?: string | undefined;
7812
+ modelAlias?: string | undefined;
7674
7813
  scheduleId?: string | undefined;
7675
7814
  workflowRunId?: string | null | undefined;
7676
7815
  workflowRunStepId?: string | null | undefined;
@@ -15173,11 +15312,21 @@ async function handleMetrics(req, res, pathSegments, queryParams, myAgentId) {
15173
15312
 
15174
15313
  // src/http/models-catalog.ts
15175
15314
  init_zod();
15315
+ init_db();
15316
+ init_types();
15317
+ init_request_auth_context();
15176
15318
  var CatalogModelSchema = exports_external.object({
15177
15319
  id: exports_external.string(),
15178
15320
  name: exports_external.string().optional(),
15179
- cost: exports_external.object({ input: exports_external.number().optional(), output: exports_external.number().optional() }).optional(),
15321
+ cost: exports_external.object({
15322
+ input: exports_external.number().optional(),
15323
+ output: exports_external.number().optional(),
15324
+ cache_read: exports_external.number().optional(),
15325
+ cache_write: exports_external.number().optional()
15326
+ }).optional(),
15180
15327
  limit: exports_external.object({ context: exports_external.number().optional() }).optional(),
15328
+ release_date: exports_external.string().optional(),
15329
+ status: exports_external.string().optional(),
15181
15330
  reasoning: exports_external.boolean().optional(),
15182
15331
  reasoning_options: exports_external.array(exports_external.object({ type: exports_external.string(), values: exports_external.array(exports_external.string()).optional() })).optional()
15183
15332
  });
@@ -15186,6 +15335,55 @@ var CatalogProviderSchema = exports_external.object({
15186
15335
  name: exports_external.string().optional(),
15187
15336
  models: exports_external.record(exports_external.string(), CatalogModelSchema)
15188
15337
  });
15338
+ var ReasoningOptionSchema = exports_external.object({
15339
+ type: exports_external.string(),
15340
+ values: exports_external.array(exports_external.string()).optional()
15341
+ });
15342
+ var OverlayPricingSchema = exports_external.object({
15343
+ input: exports_external.number().nonnegative().optional(),
15344
+ output: exports_external.number().nonnegative().optional(),
15345
+ cache_read: exports_external.number().nonnegative().optional(),
15346
+ cache_write: exports_external.number().nonnegative().optional()
15347
+ });
15348
+ var ModelCatalogRefreshResultSchema = exports_external.object({
15349
+ status: exports_external.enum(["updated", "not-modified", "skipped-fresh", "skipped-cooldown", "error"]),
15350
+ models: exports_external.number(),
15351
+ added: exports_external.array(exports_external.string()),
15352
+ checkedAt: exports_external.number().nullable(),
15353
+ retryAfterMs: exports_external.number().optional(),
15354
+ error: exports_external.string().optional()
15355
+ });
15356
+ var ModelCatalogOverlayBodySchema = exports_external.object({
15357
+ provider: exports_external.string().min(1),
15358
+ modelId: exports_external.string().min(1),
15359
+ name: exports_external.string().optional(),
15360
+ family: exports_external.string().optional(),
15361
+ releaseDate: exports_external.string().optional(),
15362
+ contextWindow: exports_external.number().int().positive().optional(),
15363
+ maxOutput: exports_external.number().int().positive().optional(),
15364
+ reasoning: exports_external.boolean().optional(),
15365
+ reasoningOptions: exports_external.array(ReasoningOptionSchema).optional(),
15366
+ pricing: OverlayPricingSchema.optional(),
15367
+ status: exports_external.string().optional(),
15368
+ reason: exports_external.string().min(1),
15369
+ verifiedBy: exports_external.string().optional(),
15370
+ expiresWhenUpstreamMatches: exports_external.boolean().optional()
15371
+ });
15372
+ var OverlayEntrySchema = ModelCatalogOverlayBodySchema.extend({
15373
+ name: exports_external.string().nullish(),
15374
+ family: exports_external.string().nullish(),
15375
+ releaseDate: exports_external.string().nullish(),
15376
+ contextWindow: exports_external.number().nullish(),
15377
+ maxOutput: exports_external.number().nullish(),
15378
+ reasoning: exports_external.boolean().nullish(),
15379
+ reasoningOptions: exports_external.array(ReasoningOptionSchema).nullish(),
15380
+ pricing: OverlayPricingSchema.nullish(),
15381
+ status: exports_external.string().nullish(),
15382
+ verifiedBy: exports_external.string().nullish(),
15383
+ expiresWhenUpstreamMatches: exports_external.boolean(),
15384
+ createdAt: exports_external.number(),
15385
+ updatedAt: exports_external.number()
15386
+ });
15189
15387
  var getCatalog = route({
15190
15388
  method: "get",
15191
15389
  path: "/api/models-catalog",
@@ -15204,12 +15402,218 @@ var getCatalog = route({
15204
15402
  }
15205
15403
  }
15206
15404
  });
15405
+ var ModelTierPreviewSchema = exports_external.object({
15406
+ provider: ProviderNameSchema,
15407
+ tier: exports_external.enum(MODEL_TIERS),
15408
+ key: exports_external.string(),
15409
+ defaultValue: exports_external.string(),
15410
+ configured: exports_external.string().nullable(),
15411
+ source: exports_external.enum(["tier-config", "tier-default"]),
15412
+ resolvedModel: exports_external.string().nullable(),
15413
+ alias: exports_external.string().nullable()
15414
+ });
15415
+ var getTiers = route({
15416
+ method: "get",
15417
+ path: "/api/models-catalog/tiers",
15418
+ pattern: ["api", "models-catalog", "tiers"],
15419
+ summary: "Preview what each model tier resolves to per harness provider",
15420
+ description: "One row per provider and tier: the built-in default, the `MODEL_TIER_<PROVIDER>_<TIER>` value stored in swarm config (if any), which layer wins, and the concrete model it resolves to against the current catalog (`latest:` aliases resolved with the same soak and auto-upgrade rules as claim time, without recording a resolution). Ignores per-worker `MODEL_TIER_*` overrides and per-task models.",
15421
+ tags: ["Pricing"],
15422
+ responses: {
15423
+ 200: {
15424
+ description: "Tier previews",
15425
+ schema: exports_external.object({ tiers: exports_external.array(ModelTierPreviewSchema) })
15426
+ }
15427
+ }
15428
+ });
15429
+ var refreshCatalog = route({
15430
+ method: "post",
15431
+ path: "/api/models-catalog/refresh",
15432
+ pattern: ["api", "models-catalog", "refresh"],
15433
+ summary: "Refresh the model catalog from models.dev",
15434
+ description: "Unforced calls skip the network when the last models.dev check is younger than 4h (`skipped-fresh`). `force: true` always fetches, still conditional on the stored ETag (`not-modified` on 304), but a forced call within a minute of the previous one returns `skipped-cooldown` with `retryAfterMs`. Concurrent refreshes share one fetch. Lead agent or operator only. `added` lists provider/modelId keys new since the previous fetch.",
15435
+ tags: ["Pricing"],
15436
+ rbac: { permission: "models.catalog.write" },
15437
+ body: exports_external.object({ force: exports_external.boolean().optional() }),
15438
+ responses: {
15439
+ 200: { description: "Refresh outcome", schema: ModelCatalogRefreshResultSchema },
15440
+ 403: { description: "Forbidden" }
15441
+ }
15442
+ });
15443
+ var upsertOverlay = route({
15444
+ method: "put",
15445
+ path: "/api/models-catalog/overlay",
15446
+ pattern: ["api", "models-catalog", "overlay"],
15447
+ summary: "Upsert one model-catalog overlay row",
15448
+ description: "Overlay facts win per non-null field over the models.dev row; overlay-only models are served too. Overlay prices fill pricing-table gaps (never override an active price). With `expiresWhenUpstreamMatches` (default true) the row is deleted once upstream matches every non-null fact.",
15449
+ tags: ["Pricing"],
15450
+ rbac: { permission: "models.catalog.write" },
15451
+ body: ModelCatalogOverlayBodySchema,
15452
+ responses: {
15453
+ 200: { description: "Overlay row upserted", schema: OverlayEntrySchema },
15454
+ 403: { description: "Forbidden" }
15455
+ }
15456
+ });
15457
+ var deleteOverlay = route({
15458
+ method: "delete",
15459
+ path: "/api/models-catalog/overlay",
15460
+ pattern: ["api", "models-catalog", "overlay"],
15461
+ summary: "Delete one model-catalog overlay row",
15462
+ tags: ["Pricing"],
15463
+ rbac: { permission: "models.catalog.write" },
15464
+ body: exports_external.object({ provider: exports_external.string().min(1), modelId: exports_external.string().min(1) }),
15465
+ responses: {
15466
+ 200: { description: "Overlay row deleted", schema: exports_external.object({ deleted: exports_external.boolean() }) },
15467
+ 403: { description: "Forbidden" }
15468
+ }
15469
+ });
15470
+ var HarnessSupportRowSchema = exports_external.object({
15471
+ harness: exports_external.string(),
15472
+ cliVersion: exports_external.string(),
15473
+ modelId: exports_external.string(),
15474
+ status: exports_external.enum(["ok", "unsupported", "unknown"]),
15475
+ checkedAt: exports_external.number(),
15476
+ error: exports_external.string().nullable()
15477
+ });
15478
+ var listHarnessSupport = route({
15479
+ method: "get",
15480
+ path: "/api/models-catalog/harness-support",
15481
+ pattern: ["api", "models-catalog", "harness-support"],
15482
+ summary: "List harness CLI model support rows",
15483
+ description: "Whether a catalog model runs on a given `claude` / `codex` CLI version, as recorded by workers after a model's first run. No row means unknown (allowed at claim).",
15484
+ tags: ["Pricing"],
15485
+ query: exports_external.object({ harness: exports_external.string().optional(), cliVersion: exports_external.string().optional() }),
15486
+ responses: {
15487
+ 200: {
15488
+ description: "Support rows, newest first",
15489
+ schema: exports_external.object({ rows: exports_external.array(HarnessSupportRowSchema) })
15490
+ }
15491
+ }
15492
+ });
15493
+ var recordHarnessSupport = route({
15494
+ method: "put",
15495
+ path: "/api/models-catalog/harness-support",
15496
+ pattern: ["api", "models-catalog", "harness-support"],
15497
+ summary: "Record whether a harness CLI version accepts a model",
15498
+ description: "Written by workers: `ok` after a model's first successful run, `unsupported` when the CLI rejects the model id. Claim-time resolution falls back (alias/tier) or fails fast (explicit model) on `unsupported`.",
15499
+ tags: ["Pricing"],
15500
+ rbac: { permission: "models.harness-support.write" },
15501
+ body: exports_external.object({
15502
+ harness: exports_external.string().min(1).max(32),
15503
+ cliVersion: exports_external.string().min(1).max(64),
15504
+ modelId: exports_external.string().min(1).max(200),
15505
+ status: exports_external.enum(["ok", "unsupported", "unknown"]),
15506
+ error: exports_external.string().max(4000).optional()
15507
+ }),
15508
+ responses: {
15509
+ 200: { description: "Support row upserted", schema: HarnessSupportRowSchema },
15510
+ 403: { description: "Forbidden" }
15511
+ }
15512
+ });
15513
+ async function ensureCatalogWriter(req, res, verb = "models.catalog.write") {
15514
+ const auth = getRequestAuth(req);
15515
+ const header2 = req.headers["x-agent-id"];
15516
+ const agentId = auth?.kind === "agent" ? auth.agentId : Array.isArray(header2) ? header2[0] : header2;
15517
+ let principal;
15518
+ if (auth?.kind === "user") {
15519
+ principal = { kind: "user", userId: auth.userId };
15520
+ } else if (agentId) {
15521
+ const agent = await getAgentById(agentId);
15522
+ principal = { kind: "agent", agentId, isLead: agent?.isLead ?? false };
15523
+ } else if (auth?.kind === "operator") {
15524
+ principal = { kind: "operator" };
15525
+ } else {
15526
+ principal = { kind: "agent", agentId: "", isLead: false };
15527
+ }
15528
+ const decision = can({
15529
+ principal,
15530
+ verb,
15531
+ resource: { kind: "none" },
15532
+ source: "http"
15533
+ });
15534
+ if (!decision.allow) {
15535
+ jsonError(res, verb === "models.catalog.write" ? "Writing the model catalog requires the lead agent or an operator" : "Recording harness model support requires a registered agent or an operator", 403);
15536
+ return null;
15537
+ }
15538
+ return {
15539
+ userId: auth?.kind === "user" ? auth.userId : null,
15540
+ agentId: principal.kind === "agent" && principal.agentId ? principal.agentId : null
15541
+ };
15542
+ }
15543
+ async function callerOwnsSupportRow(agentId, body) {
15544
+ const agent = await getAgentById(agentId);
15545
+ if (!agent || agent.harnessProvider !== body.harness)
15546
+ return false;
15547
+ return await getAgentHarnessCliVersion(agentId) === body.cliVersion;
15548
+ }
15207
15549
  async function handleModelsCatalog(req, res, pathSegments, queryParams) {
15208
15550
  if (getCatalog.match(req.method, pathSegments)) {
15209
15551
  const parsed = await getCatalog.parse(req, res, pathSegments, queryParams);
15210
15552
  if (!parsed)
15211
15553
  return true;
15212
- json(res, getModelsCatalog());
15554
+ getCatalog.respond(res, 200, await loadModelsCatalog());
15555
+ return true;
15556
+ }
15557
+ if (getTiers.match(req.method, pathSegments)) {
15558
+ const parsed = await getTiers.parse(req, res, pathSegments, queryParams);
15559
+ if (!parsed)
15560
+ return true;
15561
+ getTiers.respond(res, 200, { tiers: await previewModelTiers() });
15562
+ return true;
15563
+ }
15564
+ if (refreshCatalog.match(req.method, pathSegments)) {
15565
+ const parsed = await refreshCatalog.parse(req, res, pathSegments, queryParams);
15566
+ if (!parsed)
15567
+ return true;
15568
+ if (!await ensureCatalogWriter(req, res))
15569
+ return true;
15570
+ refreshCatalog.respond(res, 200, await requestModelCatalogRefresh({ force: parsed.body.force }));
15571
+ return true;
15572
+ }
15573
+ if (upsertOverlay.match(req.method, pathSegments)) {
15574
+ const parsed = await upsertOverlay.parse(req, res, pathSegments, queryParams);
15575
+ if (!parsed)
15576
+ return true;
15577
+ const writer = await ensureCatalogWriter(req, res);
15578
+ if (!writer)
15579
+ return true;
15580
+ const entry = await upsertModelCatalogOverlay(parsed.body, { userId: writer.userId });
15581
+ upsertOverlay.respond(res, 200, entry);
15582
+ return true;
15583
+ }
15584
+ if (deleteOverlay.match(req.method, pathSegments)) {
15585
+ const parsed = await deleteOverlay.parse(req, res, pathSegments, queryParams);
15586
+ if (!parsed)
15587
+ return true;
15588
+ if (!await ensureCatalogWriter(req, res))
15589
+ return true;
15590
+ const deleted = await deleteModelCatalogOverlay(parsed.body.provider, parsed.body.modelId);
15591
+ deleteOverlay.respond(res, 200, { deleted });
15592
+ return true;
15593
+ }
15594
+ if (listHarnessSupport.match(req.method, pathSegments)) {
15595
+ const parsed = await listHarnessSupport.parse(req, res, pathSegments, queryParams);
15596
+ if (!parsed)
15597
+ return true;
15598
+ listHarnessSupport.respond(res, 200, { rows: await listHarnessModelSupport(parsed.query) });
15599
+ return true;
15600
+ }
15601
+ if (recordHarnessSupport.match(req.method, pathSegments)) {
15602
+ const parsed = await recordHarnessSupport.parse(req, res, pathSegments, queryParams);
15603
+ if (!parsed)
15604
+ return true;
15605
+ const writer = await ensureCatalogWriter(req, res, "models.harness-support.write");
15606
+ if (!writer)
15607
+ return true;
15608
+ if (writer.agentId && !await callerOwnsSupportRow(writer.agentId, parsed.body)) {
15609
+ jsonError(res, "Harness support can only be recorded for the calling agent's own harness and registered CLI version", 403);
15610
+ return true;
15611
+ }
15612
+ if (writer.agentId && parsed.body.status === "unsupported" && !(isUnknownModelError(parsed.body.error, parsed.body.modelId) && await agentRanModel(writer.agentId, parsed.body.modelId))) {
15613
+ jsonError(res, "An unsupported report needs a model the calling agent ran and the CLI's model-rejection error", 403);
15614
+ return true;
15615
+ }
15616
+ recordHarnessSupport.respond(res, 200, await recordHarnessModelSupport(parsed.body));
15213
15617
  return true;
15214
15618
  }
15215
15619
  return false;
@@ -17868,7 +18272,9 @@ var pollTriggers = route({
17868
18272
  summary: "Poll for triggers (tasks, mentions)",
17869
18273
  tags: ["Poll"],
17870
18274
  auth: { apiKey: true, agentId: true },
17871
- headers: runtimeInstanceHeader("poll for work"),
18275
+ headers: runtimeInstanceHeader("poll for work").extend({
18276
+ "X-Model-Tier-Overrides": exports_external.string().optional().describe("URL-encoded JSON {provider: {tier: model}} of the worker's MODEL_TIER_* env overrides. " + "Stored on the agent row and applied at claim time (modelSource=worker-env).")
18277
+ }),
17872
18278
  responses: {
17873
18279
  200: { description: "Trigger data or null", schema: pollResponseSchema },
17874
18280
  400: { description: "Missing X-Agent-ID" },
@@ -17905,6 +18311,14 @@ async function attachmentsForTrigger(taskId) {
17905
18311
  sizeBytes: a.sizeBytes
17906
18312
  }));
17907
18313
  }
18314
+ async function claimModelFields(task, agent) {
18315
+ try {
18316
+ return await recordClaimModelResolution(task, agent);
18317
+ } catch (error) {
18318
+ console.warn(`[/api/poll] model resolution failed for task ${task.id}:`, error);
18319
+ return {};
18320
+ }
18321
+ }
17908
18322
  var commitCursorsRoute = route({
17909
18323
  method: "post",
17910
18324
  path: "/api/channel-activity/commit-cursors",
@@ -17928,6 +18342,7 @@ var commitCursorsRoute = route({
17928
18342
  });
17929
18343
  async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
17930
18344
  const runtimeInstanceId = ((h) => Array.isArray(h) ? h[0] : h)(req.headers["x-runtime-instance-id"]);
18345
+ const modelTierOverrides = parseModelTierOverridesHeader(((h) => Array.isArray(h) ? h[0] : h)(req.headers["x-model-tier-overrides"]));
17931
18346
  if (commitCursorsRoute.match(req.method, pathSegments)) {
17932
18347
  const parsed = await commitCursorsRoute.parse(req, res, pathSegments, queryParams);
17933
18348
  if (!parsed)
@@ -17955,6 +18370,9 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
17955
18370
  if (!agent) {
17956
18371
  return { error: "Agent not found", status: 404 };
17957
18372
  }
18373
+ if (modelTierOverrides) {
18374
+ await setAgentModelTierOverrides(agent.id, modelTierOverrides);
18375
+ }
17958
18376
  if (isExtensionAgent(agent)) {
17959
18377
  return { trigger: null };
17960
18378
  }
@@ -18052,6 +18470,7 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
18052
18470
  taskId: pendingTask.id,
18053
18471
  task: {
18054
18472
  ...pendingTask,
18473
+ ...await claimModelFields(pendingTask, agent),
18055
18474
  status: "in_progress",
18056
18475
  attachments: await attachmentsForTrigger(pendingTask.id)
18057
18476
  },
@@ -18136,7 +18555,11 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
18136
18555
  trigger: {
18137
18556
  type: "task_assigned",
18138
18557
  taskId: claimed.id,
18139
- task: { ...claimed, attachments: await attachmentsForTrigger(claimed.id) },
18558
+ task: {
18559
+ ...claimed,
18560
+ ...await claimModelFields(claimed, agent),
18561
+ attachments: await attachmentsForTrigger(claimed.id)
18562
+ },
18140
18563
  ...claimedRequestedBy && { requestedBy: claimedRequestedBy }
18141
18564
  }
18142
18565
  };
@@ -19298,6 +19721,7 @@ var scheduleUpdateBodySchema = exports_external.object({
19298
19721
  timezone: exports_external.string().optional(),
19299
19722
  model: exports_external.string().nullable().optional(),
19300
19723
  modelTier: ModelTierSchema.nullable().optional(),
19724
+ allowCustomModel: exports_external.boolean().optional(),
19301
19725
  nextRunAt: exports_external.string().nullable().optional(),
19302
19726
  targetType: ScheduledTaskTargetTypeSchema.optional(),
19303
19727
  workflowId: exports_external.string().uuid().nullable().optional(),
@@ -19338,6 +19762,7 @@ var createSchedule = route({
19338
19762
  timezone: exports_external.string().optional(),
19339
19763
  model: exports_external.string().optional(),
19340
19764
  modelTier: ModelTierSchema.optional(),
19765
+ allowCustomModel: exports_external.boolean().optional(),
19341
19766
  scheduleType: exports_external.enum(["recurring", "one_time"]).optional(),
19342
19767
  targetType: ScheduledTaskTargetTypeSchema.optional(),
19343
19768
  workflowId: exports_external.string().uuid().optional(),
@@ -19575,6 +20000,15 @@ async function handleSchedules(req, res, pathSegments, queryParams, myAgentId) {
19575
20000
  return true;
19576
20001
  }
19577
20002
  }
20003
+ const modelError = await explicitModelErrorForAgent({
20004
+ model: splitLegacyModelAlias({ model: body.model, modelTier: body.modelTier }).model,
20005
+ allowCustomModel: body.allowCustomModel,
20006
+ agentId: body.targetAgentId
20007
+ });
20008
+ if (modelError) {
20009
+ jsonError(res, modelError, 400);
20010
+ return true;
20011
+ }
19578
20012
  try {
19579
20013
  const trustedUserId = await resolveHttpAuditUserId(req, myAgentId);
19580
20014
  let key;
@@ -19703,22 +20137,35 @@ async function handleSchedules(req, res, pathSegments, queryParams, myAgentId) {
19703
20137
  throw error;
19704
20138
  }
19705
20139
  }
20140
+ const allowCustomModel = parsed.body.allowCustomModel;
20141
+ delete body.allowCustomModel;
20142
+ const existing = await getScheduledTaskById(parsed.params.id);
20143
+ if (!existing) {
20144
+ jsonError(res, "Schedule not found", 404);
20145
+ return true;
20146
+ }
19706
20147
  if (parsed.body.model !== undefined || parsed.body.modelTier !== undefined) {
19707
20148
  const normalizedModel = splitLegacyModelAlias({
19708
20149
  model: parsed.body.model,
19709
20150
  modelTier: parsed.body.modelTier
19710
20151
  });
20152
+ if (normalizedModel.model !== existing.model) {
20153
+ const modelError = await explicitModelErrorForAgent({
20154
+ model: normalizedModel.model,
20155
+ allowCustomModel,
20156
+ agentId: parsed.body.targetAgentId ?? existing.targetAgentId
20157
+ });
20158
+ if (modelError) {
20159
+ jsonError(res, modelError, 400);
20160
+ return true;
20161
+ }
20162
+ }
19711
20163
  if (parsed.body.model !== undefined)
19712
20164
  body.model = normalizedModel.model ?? null;
19713
20165
  if (parsed.body.modelTier !== undefined || normalizedModel.modelTier) {
19714
20166
  body.modelTier = normalizedModel.modelTier ?? null;
19715
20167
  }
19716
20168
  }
19717
- const existing = await getScheduledTaskById(parsed.params.id);
19718
- if (!existing) {
19719
- jsonError(res, "Schedule not found", 404);
19720
- return true;
19721
- }
19722
20169
  if (existing.scheduleType === "one_time" && !existing.enabled && existing.lastRunAt) {
19723
20170
  jsonError(res, "One-time schedule has already executed. Create a new one instead.", 400);
19724
20171
  return true;
@@ -23752,8 +24199,7 @@ async function handleSessionData(req, res, pathSegments, queryParams, _myAgentId
23752
24199
  userId: parsed.query.userId || undefined,
23753
24200
  groupBy: parsed.query.groupBy || "both"
23754
24201
  };
23755
- const version = await getUsageDataVersion();
23756
- const summary = await cachedUsageReport(`summary:${version}:${JSON.stringify(opts)}`, () => getSessionCostSummary(opts));
24202
+ const summary = await cachedUsageReport(`summary:${JSON.stringify(opts)}`, () => getSessionCostSummary(opts));
23757
24203
  getSessionCostSummaryRoute.respond(res, 200, summary);
23758
24204
  return true;
23759
24205
  }
@@ -23770,8 +24216,7 @@ async function handleSessionData(req, res, pathSegments, queryParams, _myAgentId
23770
24216
  startDate: parsed.query.startDate || undefined,
23771
24217
  endDate: parsed.query.endDate || undefined
23772
24218
  };
23773
- const version = await getUsageDataVersion();
23774
- const rows = await cachedUsageReport(`attribution:${version}:${JSON.stringify(opts)}`, () => getAttributionByPerson(opts));
24219
+ const rows = await cachedUsageReport(`attribution:${JSON.stringify(opts)}`, () => getAttributionByPerson(opts));
23775
24220
  getAttributionByPersonRoute.respond(res, 200, { rows });
23776
24221
  return true;
23777
24222
  }
@@ -24804,6 +25249,7 @@ init_zod();
24804
25249
  init_db();
24805
25250
  init_steering();
24806
25251
  init_types();
25252
+ init_env_flag();
24807
25253
  var AgentCountsSchema = exports_external.object({
24808
25254
  total: exports_external.number(),
24809
25255
  idle: exports_external.number(),
@@ -24825,7 +25271,8 @@ var DashboardStatsSchema = exports_external.object({
24825
25271
  agents: AgentCountsSchema,
24826
25272
  tasks: TaskCountsSchema,
24827
25273
  steeringEnabled: exports_external.boolean(),
24828
- multiRuntimeEnabled: exports_external.boolean()
25274
+ multiRuntimeEnabled: exports_external.boolean(),
25275
+ devMode: exports_external.boolean()
24829
25276
  });
24830
25277
  var RetentionTableStatsSchema = exports_external.object({
24831
25278
  at: exports_external.string(),
@@ -24990,15 +25437,10 @@ async function handleStats(req, res, pathSegments, queryParams, myAgentId) {
24990
25437
  return true;
24991
25438
  }
24992
25439
  if (getStats.match(req.method, pathSegments)) {
24993
- const agents = await getAllAgents();
25440
+ const agents = await getAgentStatusCounts();
24994
25441
  const taskStats = await getTaskStats();
24995
25442
  const stats = {
24996
- agents: {
24997
- total: agents.length,
24998
- idle: agents.filter((a) => a.status === "idle").length,
24999
- busy: agents.filter((a) => a.status === "busy").length,
25000
- offline: agents.filter((a) => a.status === "offline").length
25001
- },
25443
+ agents,
25002
25444
  tasks: {
25003
25445
  total: taskStats.total,
25004
25446
  unassigned: taskStats.unassigned,
@@ -25011,6 +25453,7 @@ async function handleStats(req, res, pathSegments, queryParams, myAgentId) {
25011
25453
  failed: taskStats.failed
25012
25454
  },
25013
25455
  steeringEnabled: isSteeringEnabled2(),
25456
+ devMode: isEnvFlagEnabled("SWARM_DEV_MODE", false),
25014
25457
  multiRuntimeEnabled: isMultiRuntimeEnabled()
25015
25458
  };
25016
25459
  getStats.respond(res, 200, stats);
@@ -25129,6 +25572,9 @@ var AgentTaskSummarySchema2 = AgentTaskSchema.pick({
25129
25572
  scheduleId: true,
25130
25573
  model: true,
25131
25574
  modelTier: true,
25575
+ resolvedModel: true,
25576
+ modelSource: true,
25577
+ modelAlias: true,
25132
25578
  effort: true,
25133
25579
  provider: true,
25134
25580
  requestedByUserId: true,
@@ -25256,6 +25702,7 @@ var createTask = route({
25256
25702
  requestedByUserId: exports_external.string().optional(),
25257
25703
  model: exports_external.string().optional(),
25258
25704
  modelTier: ModelTierSchema.optional(),
25705
+ allowCustomModel: exports_external.boolean().optional(),
25259
25706
  effort: ReasoningEffortSchema.optional(),
25260
25707
  draft: exports_external.boolean().optional()
25261
25708
  }).superRefine((body, ctx) => {
@@ -25269,7 +25716,9 @@ var createTask = route({
25269
25716
  }),
25270
25717
  responses: {
25271
25718
  201: { description: "Task created", schema: AgentTaskSchema },
25272
- 400: { description: "Validation error, or agentId/offeredTo targets an extension identity" },
25719
+ 400: {
25720
+ description: "Validation error, an unknown `model` (set `allowCustomModel` to store a custom id), or agentId/offeredTo targets an extension identity"
25721
+ },
25273
25722
  422: {
25274
25723
  description: "Task creation blocked by an extension",
25275
25724
  schema: exports_external.object({
@@ -25746,6 +26195,15 @@ async function handleTasks(req, res, pathSegments, queryParams, myAgentId) {
25746
26195
  if (lead)
25747
26196
  defaultAgentId = lead.id;
25748
26197
  }
26198
+ const modelError = await explicitModelErrorForAgent({
26199
+ model: splitLegacyModelAlias({ model: parsed.body.model, modelTier: parsed.body.modelTier }).model,
26200
+ allowCustomModel: parsed.body.allowCustomModel,
26201
+ agentId: defaultAgentId
26202
+ });
26203
+ if (modelError) {
26204
+ jsonError(res, modelError, 400);
26205
+ return true;
26206
+ }
25749
26207
  const parentTask = parsed.body.parentTaskId ? await getTaskById(parsed.body.parentTaskId) : null;
25750
26208
  let assetKey;
25751
26209
  try {
@@ -26423,6 +26881,7 @@ async function handleTasks(req, res, pathSegments, queryParams, myAgentId) {
26423
26881
  reason: parsed.body.reason
26424
26882
  });
26425
26883
  if (followUp.kind !== "created") {
26884
+ await settleSupersededTaskDependents(parsed.params.id, null);
26426
26885
  console.warn(`[Supersede] Task ${parsed.params.id.slice(0, 8)} superseded but resume creation skipped (${followUp.kind === "skipped" ? followUp.reason : followUp.kind})`);
26427
26886
  supersedeTaskRoute.respond(res, 200, {
26428
26887
  success: true,
@@ -28691,6 +29150,9 @@ init_zod();
28691
29150
  init_db();
28692
29151
  init_types();
28693
29152
  var WorkflowWithFavoriteSchema = WorkflowSchema.extend({ favorite: exports_external.boolean() });
29153
+ var WorkflowSaveResponseSchema = WorkflowSchema.extend({
29154
+ warnings: exports_external.array(exports_external.string()).optional()
29155
+ });
28694
29156
  var WorkflowSummarySchema = WorkflowSchema.omit({
28695
29157
  definition: true,
28696
29158
  triggers: true,
@@ -28716,6 +29178,10 @@ var WorkflowRunPageSchema = exports_external.object({
28716
29178
  })
28717
29179
  });
28718
29180
  var SuccessResponseSchema = exports_external.object({ success: exports_external.literal(true) });
29181
+ async function withSaveWarnings(workflow) {
29182
+ const warnings = await workflowSaveWarnings(workflow.definition, getExecutorRegistry());
29183
+ return warnings.length > 0 ? { ...workflow, warnings } : workflow;
29184
+ }
28719
29185
  var listWorkflowsRoute = route({
28720
29186
  method: "get",
28721
29187
  path: "/api/workflows",
@@ -28760,7 +29226,7 @@ var createWorkflowRoute = route({
28760
29226
  vcsRepo: exports_external.string().min(1).optional()
28761
29227
  }),
28762
29228
  responses: {
28763
- 201: { description: "Workflow created", schema: WorkflowSchema },
29229
+ 201: { description: "Workflow created", schema: WorkflowSaveResponseSchema },
28764
29230
  400: { description: "Invalid definition" }
28765
29231
  }
28766
29232
  });
@@ -28806,7 +29272,10 @@ var updateWorkflowRoute = route({
28806
29272
  enabled: exports_external.boolean().optional()
28807
29273
  }),
28808
29274
  responses: {
28809
- 200: { description: "Workflow updated (version snapshot created)", schema: WorkflowSchema },
29275
+ 200: {
29276
+ description: "Workflow updated (version snapshot created)",
29277
+ schema: WorkflowSaveResponseSchema
29278
+ },
28810
29279
  400: { description: "Invalid definition" },
28811
29280
  404: { description: "Workflow not found" }
28812
29281
  }
@@ -28820,7 +29289,10 @@ var patchWorkflowRoute = route({
28820
29289
  params: exports_external.object({ id: exports_external.string() }),
28821
29290
  body: WorkflowPatchSchema.extend({ key: AssetKeySchema.optional() }),
28822
29291
  responses: {
28823
- 200: { description: "Workflow patched (version snapshot created)", schema: WorkflowSchema },
29292
+ 200: {
29293
+ description: "Workflow patched (version snapshot created)",
29294
+ schema: WorkflowSaveResponseSchema
29295
+ },
28824
29296
  400: { description: "Invalid patch or resulting definition" },
28825
29297
  404: { description: "Workflow not found" }
28826
29298
  }
@@ -28834,7 +29306,10 @@ var patchWorkflowNodeRoute = route({
28834
29306
  params: exports_external.object({ id: exports_external.string(), nodeId: exports_external.string() }),
28835
29307
  body: WorkflowNodePatchSchema,
28836
29308
  responses: {
28837
- 200: { description: "Node patched (version snapshot created)", schema: WorkflowSchema },
29309
+ 200: {
29310
+ description: "Node patched (version snapshot created)",
29311
+ schema: WorkflowSaveResponseSchema
29312
+ },
28838
29313
  400: { description: "Invalid patch or resulting definition" },
28839
29314
  404: { description: "Workflow or node not found" }
28840
29315
  }
@@ -29142,7 +29617,7 @@ async function handleWorkflows(req, res, pathSegments, queryParams, myAgentId) {
29142
29617
  createdByAgentId: myAgentId ?? undefined,
29143
29618
  createdBy: await resolveHttpAuditUserId(req, myAgentId) ?? undefined
29144
29619
  }, "api");
29145
- createWorkflowRoute.respond(res, 201, workflow);
29620
+ createWorkflowRoute.respond(res, 201, await withSaveWarnings(workflow));
29146
29621
  return true;
29147
29622
  }
29148
29623
  if (getWorkflowRoute.match(req.method, pathSegments)) {
@@ -29187,7 +29662,7 @@ async function handleWorkflows(req, res, pathSegments, queryParams, myAgentId) {
29187
29662
  jsonError(res, result.reason === "patch" ? result.errors.join("; ") : `Invalid definition: ${result.errors.join("; ")}`, 400);
29188
29663
  return true;
29189
29664
  }
29190
- patchWorkflowNodeRoute.respond(res, 200, result.workflow);
29665
+ patchWorkflowNodeRoute.respond(res, 200, await withSaveWarnings(result.workflow));
29191
29666
  return true;
29192
29667
  }
29193
29668
  if (patchWorkflowRoute.match(req.method, pathSegments)) {
@@ -29238,7 +29713,7 @@ async function handleWorkflows(req, res, pathSegments, queryParams, myAgentId) {
29238
29713
  jsonError(res, result.reason === "patch" ? result.errors.join("; ") : `Invalid definition: ${result.errors.join("; ")}`, 400);
29239
29714
  return true;
29240
29715
  }
29241
- patchWorkflowRoute.respond(res, 200, result.workflow);
29716
+ patchWorkflowRoute.respond(res, 200, await withSaveWarnings(result.workflow));
29242
29717
  return true;
29243
29718
  }
29244
29719
  if (updateWorkflowRoute.match(req.method, pathSegments)) {
@@ -29297,7 +29772,7 @@ async function handleWorkflows(req, res, pathSegments, queryParams, myAgentId) {
29297
29772
  res.end();
29298
29773
  return true;
29299
29774
  }
29300
- updateWorkflowRoute.respond(res, 200, workflow);
29775
+ updateWorkflowRoute.respond(res, 200, await withSaveWarnings(workflow));
29301
29776
  return true;
29302
29777
  }
29303
29778
  if (deleteWorkflowRoute.match(req.method, pathSegments)) {
@@ -29850,7 +30325,7 @@ async function shutdown() {
29850
30325
  sessionsProcessed: getServerSessionsProcessed()
29851
30326
  });
29852
30327
  if (hasCapability("scheduling")) {
29853
- const { stopScheduler } = await import("./index-chgdkq36.js");
30328
+ const { stopScheduler } = await import("./index-cd151qkq.js");
29854
30329
  stopScheduler();
29855
30330
  }
29856
30331
  stopHeartbeat();
@@ -29858,12 +30333,13 @@ async function shutdown() {
29858
30333
  await stopScriptRunSupervisor();
29859
30334
  await stopSlackApp();
29860
30335
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
29861
- const { stopOAuthKeepalive } = await import("./keepalive-vtkf5n99.js");
30336
+ const { stopOAuthKeepalive } = await import("./keepalive-8p9rpvz5.js");
29862
30337
  await stopOAuthKeepalive();
29863
30338
  }
29864
30339
  stopOAuthPendingGc();
29865
30340
  stopMemoryGc();
29866
30341
  await stopDbRetention();
30342
+ stopHumanFreeDrain();
29867
30343
  stopScratchScriptGc();
29868
30344
  await stopExtensionRuntime();
29869
30345
  stopAuditGc();
@@ -29926,15 +30402,15 @@ try {
29926
30402
  console.warn("[startup] CAPABILITIES upgrade seed failed (non-fatal):", err);
29927
30403
  }
29928
30404
  try {
29929
- const { ensurePricingSeeded } = await import("./boot-seeds-s3q01xj3.js");
30405
+ const { ensurePricingSeeded } = await import("./boot-seeds-h7c32hvm.js");
29930
30406
  ensurePricingSeeded();
29931
- const { startPricingRefreshLoop } = await import("./pricing-refresh-v1cbr9te.js");
30407
+ const { startPricingRefreshLoop } = await import("./pricing-refresh-0v77385v.js");
29932
30408
  startPricingRefreshLoop();
29933
30409
  } catch (err) {
29934
30410
  console.error("[startup] Failed to seed pricing rows:", err);
29935
30411
  }
29936
30412
  try {
29937
- const { ensureRbacSeeded } = await import("./boot-seeds-s3q01xj3.js");
30413
+ const { ensureRbacSeeded } = await import("./boot-seeds-h7c32hvm.js");
29938
30414
  ensureRbacSeeded();
29939
30415
  } catch (err) {
29940
30416
  console.error("[startup] Failed to sync RBAC seed rows:", err);
@@ -29942,7 +30418,7 @@ try {
29942
30418
  throw err;
29943
30419
  }
29944
30420
  try {
29945
- const { runAllSeeders } = await import("./index-a3vn96n8.js");
30421
+ const { runAllSeeders } = await import("./index-5sz16ksh.js");
29946
30422
  await runAllSeeders({ scriptEmbeddingMode: "skip" });
29947
30423
  } catch (err) {
29948
30424
  console.error("[startup] Failed to seed built-in entities:", err);
@@ -29996,36 +30472,37 @@ httpServer.listen(port, async () => {
29996
30472
  await initWorkflows();
29997
30473
  await startScriptRunSupervisor(getMcpBaseUrl());
29998
30474
  if (hasCapability("scheduling")) {
29999
- const { startScheduler } = await import("./index-chgdkq36.js");
30000
- const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-1yks3qcr.js");
30475
+ const { startScheduler } = await import("./index-cd151qkq.js");
30476
+ const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-ttpbhnjg.js");
30001
30477
  const intervalMs = Number(process.env.SCHEDULER_INTERVAL_MS) || 1e4;
30002
30478
  startScheduler(getExecutorRegistry2(), intervalMs, {
30003
30479
  runId: globalState.__runId
30004
30480
  });
30005
30481
  }
30006
30482
  if (!isEnvFlagEnabled("HEARTBEAT_DISABLE", false)) {
30007
- const { startHeartbeat } = await import("./index-x71bvq0p.js");
30483
+ const { startHeartbeat } = await import("./index-k661dzzr.js");
30008
30484
  const heartbeatMs = Number(process.env.HEARTBEAT_INTERVAL_MS) || 90000;
30009
30485
  startHeartbeat(heartbeatMs);
30010
30486
  }
30011
30487
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
30012
- const { startOAuthKeepalive } = await import("./keepalive-vtkf5n99.js");
30488
+ const { startOAuthKeepalive } = await import("./keepalive-8p9rpvz5.js");
30013
30489
  startOAuthKeepalive();
30014
30490
  }
30015
30491
  if (process.env.OAUTH_REFRESH_SWEEP_DISABLE !== "true") {
30016
- const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-qp3dzmdp.js");
30492
+ const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-cwcq1ctx.js");
30017
30493
  startOAuthRefreshSweep();
30018
30494
  }
30019
30495
  startOAuthPendingGc();
30020
30496
  await startMemoryGc();
30021
30497
  await startDbRetention();
30022
- import("./boot-reembed-se8zmdcp.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
30498
+ startHumanFreeDrain();
30499
+ import("./boot-reembed-48d2qpkt.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
30023
30500
  console.error("[boot-reembed] startup backfill failed (non-fatal):", err);
30024
30501
  });
30025
- import("./boot-reembed-g5ckg9yb.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
30502
+ import("./boot-reembed-w0bryhkr.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
30026
30503
  console.error("[boot-reembed-scripts] startup backfill failed (non-fatal):", err);
30027
30504
  });
30028
- import("./boot-scrub-logs-wfxqan61.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
30505
+ import("./boot-scrub-logs-t65wbrn7.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
30029
30506
  console.error("[boot-scrub-logs] startup scrub failed (non-fatal):", err);
30030
30507
  });
30031
30508
  }).on("error", (err) => {