@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
@@ -4,46 +4,60 @@ import {
4
4
  executeComposioRequest
5
5
  } from "./cli-0z2v4nhw.js";
6
6
  import {
7
- DEFAULT_MODEL,
8
7
  LlmRater,
9
8
  REFERENCES_SOURCE_MAX_LENGTH,
10
9
  getMemoryRaterNames,
11
- resolveCredential,
12
10
  sanitizeReferencesSource
13
- } from "./cli-tt9k8r35.js";
11
+ } from "./cli-cpvsaqsw.js";
14
12
  import {
15
13
  isMultiRuntimeEnabled
16
14
  } from "./cli-re8z5p8p.js";
17
15
  import {
18
- getOpenRouterBaseUrl
19
- } from "./cli-3dpj7atn.js";
16
+ AgentFsProvider,
17
+ getFileStorageProvider,
18
+ providerPath
19
+ } from "./cli-jsp14b6c.js";
20
20
  import {
21
21
  ensurePricingSeeded,
22
22
  ensureRbacSeeded,
23
23
  getUserGrant
24
- } from "./cli-aky8tctm.js";
24
+ } from "./cli-z9x0sh1t.js";
25
25
  import {
26
26
  can,
27
27
  decideAdmission,
28
28
  grantLeadEquivalence,
29
29
  isRbacEnabled,
30
30
  revokeLeadEquivalence
31
- } from "./cli-g8djp6qe.js";
31
+ } from "./cli-9yg65c1j.js";
32
32
  import {
33
- startPricingRefreshLoop
34
- } from "./cli-ws6rqycm.js";
33
+ buildCatalogEntries,
34
+ getCatalogGeneration,
35
+ listModelCatalog,
36
+ listModelCatalogOverlay,
37
+ loadModelsCatalog,
38
+ requestModelCatalogRefresh,
39
+ startPricingRefreshLoop,
40
+ upsertModelCatalogOverlay
41
+ } from "./cli-cygyqj3b.js";
42
+ import {
43
+ loadModelsDevCache
44
+ } from "./cli-0n2e4x49.js";
35
45
  import {
36
46
  AppDefinitionSchema,
37
47
  AppElementsSchema,
38
48
  AppNameSchema,
49
+ BaseExecutor,
39
50
  ColumnKindSchema,
40
51
  ConnectionAuthInputSchema,
41
52
  DEFAULT_SCRIPT_RESOURCES,
53
+ HumanInTheLoopExecutor,
42
54
  MAX_SCRIPT_WALL_CLOCK_MS,
43
55
  MIN_SCRIPT_WALL_CLOCK_MS,
44
56
  SCRIPT_LONG_TIMEOUT_HINT_MS,
45
57
  SORTABLE_SYSTEM_DATE_COLUMNS,
46
58
  SYSTEM_COLUMN_KINDS,
59
+ SYSTEM_ONE_DECISION_NODE_TYPE,
60
+ SystemOneDecisionExecutor,
47
61
  appDefinitionNeedsRepair,
48
62
  applyAppDefinitionPatch,
49
63
  applyDefinitionPatch,
@@ -53,6 +67,7 @@ import {
53
67
  buildScriptCredentialBindingsWithFailures,
54
68
  connectionAuthInputFromFlat,
55
69
  createApp,
70
+ createApprovalFollowUpTask,
56
71
  createCappedStreamState,
57
72
  decodeAppDefinition,
58
73
  definitionNodeIds,
@@ -80,18 +95,22 @@ import {
80
95
  listRelationalCredentialBindings,
81
96
  listScriptConnections,
82
97
  parseAppDefinition,
98
+ postApprovalCancellationUpdates,
83
99
  publicEndpointSsrfOptions,
84
100
  readStreamCapped,
85
101
  refreshScriptConnection,
86
102
  require_dist as require_dist2,
87
103
  resolveSyncRunAs,
88
104
  resolveValidationPort,
105
+ resolveWorkflowLlmConfig,
89
106
  restoreScratchScriptLastUsedIfUnchanged,
90
107
  runSavedScriptAsAgent,
91
108
  runScript,
92
109
  sandboxSpawnEnv,
93
110
  setScriptConnectionEnabled,
94
111
  snapshotCapped,
112
+ systemOneRetryViolations,
113
+ systemOneUnresolvedError,
95
114
  touchScratchScriptLastUsed,
96
115
  typecheckScript,
97
116
  updateApp,
@@ -102,7 +121,7 @@ import {
102
121
  validateDefinition,
103
122
  validateScriptImports,
104
123
  writeBareImportShim
105
- } from "./cli-fgqxwrpv.js";
124
+ } from "./cli-fjtp3463.js";
106
125
  import {
107
126
  detachedProcessGroup,
108
127
  registerProcessGroup,
@@ -113,7 +132,7 @@ import {
113
132
  } from "./cli-f14fvzag.js";
114
133
  import {
115
134
  embedScript
116
- } from "./cli-987hg0aa.js";
135
+ } from "./cli-vwbbaecp.js";
117
136
  import {
118
137
  buildAuthorizationUrl,
119
138
  createOAuthApp,
@@ -128,12 +147,11 @@ import {
128
147
  listAuthorizationsForApp,
129
148
  onAuthorizationRefreshed,
130
149
  upsertOAuthApp
131
- } from "./cli-53sz8gkz.js";
150
+ } from "./cli-qv4jv8bx.js";
132
151
  import {
133
- AgentFsProvider,
134
- getFileStorageProvider,
135
- providerPath
136
- } from "./cli-jsp14b6c.js";
152
+ ZodFirstPartyTypeKind,
153
+ objectType
154
+ } from "./cli-fad8m16k.js";
137
155
  import {
138
156
  CANDIDATE_SET_MULTIPLIER,
139
157
  computeScore,
@@ -145,11 +163,7 @@ import {
145
163
  isGraphExpansionEnabled,
146
164
  rerank,
147
165
  rowToCandidate
148
- } from "./cli-65hjmev5.js";
149
- import {
150
- ZodFirstPartyTypeKind,
151
- objectType
152
- } from "./cli-fad8m16k.js";
166
+ } from "./cli-kc3dp84d.js";
153
167
  import {
154
168
  require_dist
155
169
  } from "./cli-51tf7ac3.js";
@@ -175,7 +189,7 @@ import {
175
189
  taskCitationWarnings,
176
190
  upsertTaskCitations,
177
191
  withSpan
178
- } from "./cli-j57qkrpq.js";
192
+ } from "./cli-wgjx0q33.js";
179
193
  import {
180
194
  init_task_attachment_links,
181
195
  taskAttachmentDisplayUrl,
@@ -198,10 +212,8 @@ import {
198
212
  cancelTask,
199
213
  checkDependencies,
200
214
  checkSlackRoutingCoherence,
201
- claimApprovalCancellationNotification,
202
215
  claimKv,
203
216
  claimTask,
204
- completeApprovalCancellationNotificationClaim,
205
217
  completeTask,
206
218
  computeContentHash,
207
219
  countKv,
@@ -357,6 +369,7 @@ import {
357
369
  init_date_utils,
358
370
  init_db,
359
371
  init_db_client,
372
+ init_model_tier_keys,
360
373
  init_request_auth_context,
361
374
  init_slack_routing,
362
375
  init_steering,
@@ -400,7 +413,6 @@ import {
400
413
  recordSlackMessage,
401
414
  refreshDraftTaskLease,
402
415
  rejectTask,
403
- releaseApprovalCancellationNotificationClaim,
404
416
  releaseMentionProcessing,
405
417
  releaseTask,
406
418
  requestSteering,
@@ -418,6 +430,7 @@ import {
418
430
  startTask,
419
431
  sweepExpiredKvPrefix,
420
432
  telemetry,
433
+ tierConfigKey,
421
434
  uninstallMcpServer,
422
435
  uninstallSkill,
423
436
  updateAgentMaxTasks,
@@ -445,7 +458,7 @@ import {
445
458
  upsertSwarmConfig,
446
459
  validateConfigValue,
447
460
  workflowContextKey
448
- } from "./cli-47m6dkd3.js";
461
+ } from "./cli-g9df2m37.js";
449
462
  import {
450
463
  $OpenAPIRegistry,
451
464
  $OpenApiGeneratorV31,
@@ -460,6 +473,7 @@ import {
460
473
  ChannelTypeSchema,
461
474
  CooldownConfigSchema,
462
475
  CreateTaskOptionsSchema,
476
+ DEFAULT_MODEL_TIER_MAP,
463
477
  ExtensionManifestSchema,
464
478
  ExtensionWorkflowFileSchema,
465
479
  FollowUpConfigSchema,
@@ -467,6 +481,7 @@ import {
467
481
  KvKeySchema,
468
482
  KvNamespaceSchema,
469
483
  KvValueTypeSchema,
484
+ MODEL_TIERS,
470
485
  MetricDefinitionSchema,
471
486
  ModelTierSchema,
472
487
  OnUnsupportedSchema,
@@ -485,7 +500,6 @@ import {
485
500
  SteerModeSchema,
486
501
  SteerOutcomeSchema,
487
502
  SwarmConfigScopeSchema,
488
- TERMINAL_TASK_STATUSES,
489
503
  TriggerConfigSchema,
490
504
  WorkflowDefinitionSchema,
491
505
  WorkflowNodePatchSchema,
@@ -500,14 +514,20 @@ import {
500
514
  isTerminalTaskStatus,
501
515
  normalizeAssetKey,
502
516
  parseAssetKey,
517
+ parseModelTier,
503
518
  splitLegacyModelAlias
504
- } from "./cli-4198qc9v.js";
519
+ } from "./cli-e4xnc0qp.js";
505
520
  import {
506
521
  generateDefaultClaudeMd,
507
522
  generateDefaultIdentityMd,
508
523
  generateDefaultSoulMd,
509
524
  init_defaults
510
- } from "./cli-3gmcwfyx.js";
525
+ } from "./cli-ardpzhjm.js";
526
+ import {
527
+ getSlackConfiguration,
528
+ init_config,
529
+ isSlackConfigured
530
+ } from "./cli-n7h1kqpf.js";
511
531
  import {
512
532
  deepInterpolate,
513
533
  findInterpolationTokens,
@@ -518,7 +538,7 @@ import {
518
538
  interpolate,
519
539
  registerTemplate,
520
540
  resolveTemplate
521
- } from "./cli-ggm92wcn.js";
541
+ } from "./cli-rgjprct3.js";
522
542
  import {
523
543
  MAX_PROFILE_FILE_LENGTH,
524
544
  getAppUrl,
@@ -526,16 +546,22 @@ import {
526
546
  getPublicMcpBaseUrl,
527
547
  init_constants
528
548
  } from "./cli-dv6cdjs2.js";
529
- import {
530
- getSlackConfiguration,
531
- init_config,
532
- isSlackConfigured
533
- } from "./cli-n7h1kqpf.js";
534
549
  import {
535
550
  init_env_flag,
536
551
  isEnvFlagEnabled,
537
552
  parseEnvFlag
538
553
  } from "./cli-ej6gbxfb.js";
554
+ import {
555
+ buildClaudeShortnameMap,
556
+ claudeCatalogModelId,
557
+ harnessCatalogSection,
558
+ harnessModelIds,
559
+ init_src,
560
+ isAlias,
561
+ modelFamilyKey,
562
+ parseAlias,
563
+ resolveAlias
564
+ } from "./cli-7zttzetj.js";
539
565
  import {
540
566
  exports_zod,
541
567
  init_zod
@@ -584,7 +610,7 @@ import {
584
610
  import {
585
611
  init_package,
586
612
  package_default
587
- } from "./cli-c07r9a2m.js";
613
+ } from "./cli-48527fpw.js";
588
614
  import {
589
615
  init_secret_scrubber,
590
616
  isSensitiveKey,
@@ -14323,7 +14349,7 @@ async function notifyAutomationPreflightFailure(preflight) {
14323
14349
  return;
14324
14350
  }
14325
14351
  try {
14326
- const { getSlackApp: getSlackApp2 } = await import("./app-g26wdcz6.js");
14352
+ const { getSlackApp: getSlackApp2 } = await import("./app-y1b9srva.js");
14327
14353
  const app = getSlackApp2();
14328
14354
  if (!app) {
14329
14355
  console.warn("[Automation Preflight] Slack not available, cannot send notification");
@@ -15011,6 +15037,52 @@ function getMaxWorkflowStepsPerRun() {
15011
15037
  return Number(process.env.WORKFLOW_MAX_STEPS_PER_RUN) || DEFAULT_MAX_STEPS_PER_RUN;
15012
15038
  }
15013
15039
 
15040
+ // src/workflows/readiness.ts
15041
+ async function findWorkflowReadinessProblems(definition, registry) {
15042
+ const nodesByType = new Map;
15043
+ for (const node of definition.nodes) {
15044
+ if (!registry.has(node.type))
15045
+ continue;
15046
+ const group = nodesByType.get(node.type) ?? [];
15047
+ group.push({ id: node.id, config: node.config });
15048
+ nodesByType.set(node.type, group);
15049
+ }
15050
+ const problems = [];
15051
+ for (const [type, nodes] of nodesByType) {
15052
+ try {
15053
+ for (const problem of await registry.get(type).checkReadiness(nodes)) {
15054
+ problems.push({ type, ...problem });
15055
+ }
15056
+ } catch {
15057
+ problems.push({
15058
+ type,
15059
+ nodeIds: nodes.map((node) => node.id),
15060
+ message: `Could not check whether "${type}" nodes are ready to run`
15061
+ });
15062
+ }
15063
+ }
15064
+ return problems;
15065
+ }
15066
+ function describeNodes(problem) {
15067
+ const noun = problem.nodeIds.length === 1 ? "node" : "nodes";
15068
+ return `${problem.type} ${noun} ${problem.nodeIds.map((id) => `"${id}"`).join(", ")}`;
15069
+ }
15070
+ function formatReadinessWarning(problem) {
15071
+ return `${problem.message} Affects ${describeNodes(problem)}. Runs of this workflow fail before any node executes until this is fixed.`;
15072
+ }
15073
+ function formatReadinessProblems(problems) {
15074
+ return problems.map((problem) => `${problem.message} Needed by ${describeNodes(problem)}.`).join(" ");
15075
+ }
15076
+ function formatReadinessRunError(problems) {
15077
+ return `Run not started, no node executed: ${formatReadinessProblems(problems)}`;
15078
+ }
15079
+ async function workflowSaveWarnings(definition, registry) {
15080
+ return (await findWorkflowReadinessProblems(definition, registry)).map(formatReadinessWarning);
15081
+ }
15082
+ function withSaveWarnings(text, warnings) {
15083
+ return warnings.length === 0 ? text : `${text} ${warnings.map((warning) => `Warning: ${warning}`).join(" ")}`;
15084
+ }
15085
+
15014
15086
  // src/workflows/template.ts
15015
15087
  init_template();
15016
15088
 
@@ -15153,6 +15225,15 @@ async function startWorkflowExecution(workflow, triggerData, registry, options =
15153
15225
  nodeCount: workflow.definition.nodes.length,
15154
15226
  triggerType: options.triggerType ?? "manual"
15155
15227
  });
15228
+ const notReady = await findWorkflowReadinessProblems(workflow.definition, registry);
15229
+ if (notReady.length > 0) {
15230
+ await updateWorkflowRun(runId, {
15231
+ status: "failed",
15232
+ error: formatReadinessRunError(notReady),
15233
+ finishedAt: new Date().toISOString()
15234
+ });
15235
+ return runId;
15236
+ }
15156
15237
  const ctx = { trigger: triggerData };
15157
15238
  if (options.requestedByUserId) {
15158
15239
  ctx.swarm = { requestedByUserId: options.requestedByUserId };
@@ -15479,6 +15560,11 @@ async function executeStep(def, runId, ctx, node, registry, workflowId, secretKe
15479
15560
  }
15480
15561
  async function runClaimedStep(def, runId, ctx, node, registry, existingStep, stepId, workflowId, options = {}) {
15481
15562
  const executor = registry.get(node.type);
15563
+ const systemOneRetryProblems = systemOneRetryViolations(node);
15564
+ if (systemOneRetryProblems.length > 0) {
15565
+ await checkpointStepFailure(runId, stepId, systemOneRetryProblems.join("; "), 0);
15566
+ return { outcome: "failed", successors: [] };
15567
+ }
15482
15568
  const interpolationCtx = buildNodeInterpolationCtx(node, ctx);
15483
15569
  if (node.inputSchema) {
15484
15570
  const inputErrors = validateJsonSchema(node.inputSchema, interpolationCtx);
@@ -15491,7 +15577,8 @@ async function runClaimedStep(def, runId, ctx, node, registry, existingStep, ste
15491
15577
  const {
15492
15578
  value: interpolatedValue,
15493
15579
  unresolved,
15494
- scriptBodyUnresolved
15580
+ scriptBodyUnresolved,
15581
+ strictUnresolved
15495
15582
  } = interpolateNodeConfig(node, interpolationCtx);
15496
15583
  const interpolatedConfig = interpolatedValue;
15497
15584
  const executionCtx = { ...ctx, ...interpolationCtx };
@@ -15500,6 +15587,10 @@ async function runClaimedStep(def, runId, ctx, node, registry, existingStep, ste
15500
15587
  await checkpointStepFailure(runId, stepId, errorMsg, 0);
15501
15588
  return { outcome: "failed", successors: [] };
15502
15589
  }
15590
+ if (strictUnresolved && strictUnresolved.length > 0) {
15591
+ await checkpointStepFailure(runId, stepId, systemOneUnresolvedError(node.id, strictUnresolved), 0);
15592
+ return { outcome: "failed", successors: [] };
15593
+ }
15503
15594
  if (unresolved.length > 0) {
15504
15595
  console.warn(`[workflow] Step ${node.id}: unresolved interpolation tokens: ${unresolved.join(", ")}`);
15505
15596
  await updateWorkflowRunStep(stepId, {
@@ -15663,6 +15754,25 @@ function buildScriptBodyCtx(node, interpolationCtx) {
15663
15754
  return safe;
15664
15755
  }
15665
15756
  function interpolateNodeConfig(node, interpolationCtx) {
15757
+ if (node.type === SYSTEM_ONE_DECISION_NODE_TYPE) {
15758
+ const { state, questions, ...rest } = node.config;
15759
+ const restResult = deepInterpolate(rest, interpolationCtx);
15760
+ const dynamic = {};
15761
+ if (Object.hasOwn(node.config, "state"))
15762
+ dynamic.state = state;
15763
+ if (Object.hasOwn(node.config, "questions"))
15764
+ dynamic.questions = questions;
15765
+ const dynamicResult = deepInterpolate(dynamic, interpolationCtx, { preserveRawTokens: true });
15766
+ const unresolved = [...restResult.unresolved, ...dynamicResult.unresolved];
15767
+ return {
15768
+ value: {
15769
+ ...restResult.value,
15770
+ ...dynamicResult.value
15771
+ },
15772
+ unresolved,
15773
+ strictUnresolved: unresolved
15774
+ };
15775
+ }
15666
15776
  if (node.type === "foreach" && Object.hasOwn(node.config, "over")) {
15667
15777
  const { over, body, ...configWithoutOverAndBody } = node.config;
15668
15778
  const configResult2 = deepInterpolate(configWithoutOverAndBody, interpolationCtx);
@@ -15733,106 +15843,30 @@ init_event_bus();
15733
15843
  // src/workflows/recovery.ts
15734
15844
  init_db();
15735
15845
 
15846
+ // src/workflows/approval-resolution.ts
15847
+ function shapeApprovalResolution(registry, definition, nodeId, parkedOutput, approval) {
15848
+ const node = definition.nodes.find((candidate) => candidate.id === nodeId);
15849
+ if (node && registry.has(node.type)) {
15850
+ const shaped = registry.get(node.type).resolveApproval(parkedOutput, approval);
15851
+ if (shaped)
15852
+ return shaped;
15853
+ }
15854
+ return {
15855
+ output: {
15856
+ requestId: approval.requestId,
15857
+ status: approval.status,
15858
+ responses: approval.responses
15859
+ },
15860
+ nextPort: approval.status === "timeout" ? "timeout" : approval.status === "rejected" ? "rejected" : "approved"
15861
+ };
15862
+ }
15863
+
15736
15864
  // src/workflows/constants.ts
15737
15865
  var FAILED_TASK_OUTPUT_PREFIX = "[FAILED:";
15738
15866
 
15739
15867
  // src/workflows/resume.ts
15740
15868
  init_db();
15741
15869
  init_secret_scrubber();
15742
-
15743
- // src/workflows/approval-notifications.ts
15744
- init_db();
15745
- init_resolver();
15746
- init_types();
15747
- init_secret_scrubber();
15748
- async function postApprovalCancellationUpdates(approvals, reason, client = getSlackApp()?.client) {
15749
- if (!client)
15750
- return;
15751
- const text = `This approval is no longer actionable: ${reason}`;
15752
- for (const approval of approvals) {
15753
- const channels = approval.notificationChannels;
15754
- const slackThreads = (channels ?? []).filter((notification) => notification.channel === "slack" && notification.messageTs);
15755
- if (slackThreads.length === 0)
15756
- continue;
15757
- for (const notification of slackThreads) {
15758
- if (notification.channel !== "slack" || !notification.messageTs)
15759
- continue;
15760
- const notificationKey = `${notification.target}:${notification.messageTs}`;
15761
- const claim = await claimApprovalCancellationNotification(approval.id, notificationKey);
15762
- if (!claim)
15763
- continue;
15764
- try {
15765
- await client.chat.postMessage({
15766
- channel: notification.target,
15767
- thread_ts: notification.messageTs,
15768
- text,
15769
- unfurl_links: false,
15770
- unfurl_media: false
15771
- });
15772
- await completeApprovalCancellationNotificationClaim(approval.id, notificationKey, claim.leaseToken);
15773
- } catch (error) {
15774
- await releaseApprovalCancellationNotificationClaim(approval.id, notificationKey, claim.leaseToken);
15775
- console.error(`[HITL] Failed to post cancellation update for approval ${approval.id}:`, scrubSecrets(error instanceof Error ? error.message : String(error)));
15776
- }
15777
- }
15778
- }
15779
- }
15780
- async function createApprovalFollowUpTask(request, templateEventType) {
15781
- if (request.workflowRunId || !request.sourceTaskId)
15782
- return false;
15783
- const sourceTask = await getTaskById(request.sourceTaskId);
15784
- if (!sourceTask)
15785
- return false;
15786
- if (templateEventType === "hitl.timeout" && TERMINAL_TASK_STATUSES.includes(sourceTask.status)) {
15787
- return false;
15788
- }
15789
- const { text: taskText } = templateEventType === "hitl.follow_up" ? resolveTemplate("hitl.follow_up", {
15790
- request_id: request.id,
15791
- title: request.title,
15792
- status: request.status,
15793
- responses: formatResponses(request.questions, request.responses ?? {})
15794
- }) : resolveTemplate("hitl.timeout", {
15795
- request_id: request.id,
15796
- title: request.title,
15797
- expires_at: request.expiresAt ?? "",
15798
- reason: request.resolutionReason ?? ""
15799
- });
15800
- await createTaskExtended(taskText, {
15801
- agentId: sourceTask.agentId,
15802
- routingReason: sourceTask.agentId ? "continuity" : undefined,
15803
- routingSource: sourceTask.agentId ? "engine_default" : undefined,
15804
- parentTaskId: request.sourceTaskId,
15805
- source: "system",
15806
- taskType: "hitl-follow-up",
15807
- tags: ["hitl", "follow-up"],
15808
- slackChannelId: sourceTask.slackChannelId ?? undefined,
15809
- slackThreadTs: sourceTask.slackThreadTs ?? undefined,
15810
- slackUserId: sourceTask.slackUserId ?? undefined
15811
- });
15812
- return true;
15813
- }
15814
- function formatResponses(questions, responses) {
15815
- return questions.map((q) => {
15816
- const answer = responses[q.id];
15817
- let answerText;
15818
- if (answer == null) {
15819
- answerText = "(no answer)";
15820
- } else if (q.type === "approval") {
15821
- const a = answer;
15822
- answerText = a.approved ? "Approved" : "Rejected";
15823
- if (a.comment)
15824
- answerText += ` — ${a.comment}`;
15825
- } else if (typeof answer === "object") {
15826
- answerText = JSON.stringify(answer);
15827
- } else {
15828
- answerText = String(answer);
15829
- }
15830
- return `- ${q.label}: ${answerText}`;
15831
- }).join(`
15832
- `);
15833
- }
15834
-
15835
- // src/workflows/resume.ts
15836
15870
  init_event_bus();
15837
15871
 
15838
15872
  // src/workflows/executors/wait.ts
@@ -16014,43 +16048,6 @@ async function matchesFilter(payload, filter) {
16014
16048
  return false;
16015
16049
  }
16016
16050
 
16017
- // src/workflows/executors/base.ts
16018
- class BaseExecutor {
16019
- deps;
16020
- retryPolicy;
16021
- constructor(deps) {
16022
- this.deps = deps;
16023
- }
16024
- async run(input) {
16025
- const configResult = this.configSchema.safeParse(input.config);
16026
- if (!configResult.success) {
16027
- return {
16028
- status: "failed",
16029
- error: `Input validation failed: ${configResult.error.message}`
16030
- };
16031
- }
16032
- let result;
16033
- try {
16034
- result = await this.execute(configResult.data, input.context, input.meta);
16035
- } catch (err) {
16036
- return {
16037
- status: "failed",
16038
- error: `Executor threw: ${err instanceof Error ? err.message : String(err)}`
16039
- };
16040
- }
16041
- if (result.status === "success" && result.output !== undefined) {
16042
- const outputResult = this.outputSchema.safeParse(result.output);
16043
- if (!outputResult.success) {
16044
- return {
16045
- status: "failed",
16046
- error: `Output validation failed: ${outputResult.error.message}`
16047
- };
16048
- }
16049
- }
16050
- return result;
16051
- }
16052
- }
16053
-
16054
16051
  // src/workflows/executors/wait.ts
16055
16052
  var WaitConfigSchema = exports_external.discriminatedUnion("mode", [
16056
16053
  exports_external.object({
@@ -16379,6 +16376,10 @@ async function retryFailedRun(runId, registry) {
16379
16376
  if (!failedStep)
16380
16377
  throw new Error("No failed step found");
16381
16378
  const completedNodeIds = new Set(await getCompletedStepNodeIds(runId));
16379
+ const notReady = await findWorkflowReadinessProblems({ nodes: workflow.definition.nodes.filter((node) => !completedNodeIds.has(node.id)) }, registry);
16380
+ if (notReady.length > 0) {
16381
+ throw new Error(`Retry not started, run left failed: ${formatReadinessProblems(notReady)}`);
16382
+ }
16382
16383
  const { activeEdges } = await loadCompletedStepRouting(workflow.definition, runId, completedNodeIds);
16383
16384
  const foreachParent = resolveForeachParent(workflow.definition, failedStep.nodeId);
16384
16385
  const failedNode = foreachParent ?? workflow.definition.nodes.find((n) => n.id === failedStep.nodeId);
@@ -16469,12 +16470,7 @@ async function resumeFromApprovalResolution(event, registry) {
16469
16470
  console.warn(`[workflows] approval ${event.requestId} is cancelled; step ${event.workflowRunStepId} stays waiting for the run cancel path`);
16470
16471
  return;
16471
16472
  }
16472
- const nextPort = event.status === "timeout" ? "timeout" : event.status === "rejected" ? "rejected" : "approved";
16473
- const stepOutput = {
16474
- requestId: event.requestId,
16475
- status: event.status,
16476
- responses: event.responses
16477
- };
16473
+ const { output: stepOutput, nextPort } = shapeApprovalResolution(registry, workflow.definition, step.nodeId, step.output, { requestId: event.requestId, status: event.status, responses: event.responses });
16478
16474
  const routing = await checkpointPortStepAndResolveSuccessors(workflow.definition, run.id, step.id, step.nodeId, stepOutput, nextPort, ctx);
16479
16475
  if (!routing.claimed)
16480
16476
  return;
@@ -16788,12 +16784,11 @@ async function recoverApprovalWaitingRuns(registry) {
16788
16784
  if (approvalStatus !== "approved" && approvalStatus !== "rejected" && approvalStatus !== "timeout") {
16789
16785
  return null;
16790
16786
  }
16791
- const nextPort = approvalStatus === "timeout" ? "timeout" : approvalStatus === "rejected" ? "rejected" : "approved";
16792
- const stepOutput = {
16787
+ const { output: stepOutput, nextPort } = shapeApprovalResolution(registry, workflow.definition, stuck.nodeId, (await getWorkflowRunStep(stuck.stepId))?.output, {
16793
16788
  requestId: stuck.approvalId,
16794
16789
  status: approvalStatus,
16795
16790
  responses: approval?.responses ?? null
16796
- };
16791
+ });
16797
16792
  return await checkpointPortStepAndResolveSuccessors(workflow.definition, stuck.runId, stuck.stepId, stuck.nodeId, stepOutput, nextPort, ctx);
16798
16793
  });
16799
16794
  if (!routing?.claimed)
@@ -17355,6 +17350,400 @@ init_zod();
17355
17350
  // src/workflows/executors/agent-task.ts
17356
17351
  init_zod();
17357
17352
 
17353
+ // src/be/model-validation.ts
17354
+ init_src();
17355
+ init_db();
17356
+
17357
+ // src/be/model-tier-resolution.ts
17358
+ init_src();
17359
+ init_zod();
17360
+ init_types();
17361
+ init_db();
17362
+
17363
+ // src/be/harness-model-support.ts
17364
+ init_src();
17365
+ init_secret_scrubber();
17366
+ init_db();
17367
+ var CLI_PINNED_HARNESSES = new Set(["claude", "codex"]);
17368
+ async function getHarnessModelSupport(harness, cliVersion, modelId) {
17369
+ const row = await getDbClient().get("SELECT status FROM harness_model_support WHERE harness = ? AND cliVersion = ? AND modelId = ?", [harness, cliVersion, modelId]);
17370
+ return row?.status ?? "unknown";
17371
+ }
17372
+ async function listHarnessModelSupport(filter) {
17373
+ const where = [];
17374
+ const params = [];
17375
+ if (filter?.harness) {
17376
+ where.push("harness = ?");
17377
+ params.push(filter.harness);
17378
+ }
17379
+ if (filter?.cliVersion) {
17380
+ where.push("cliVersion = ?");
17381
+ params.push(filter.cliVersion);
17382
+ }
17383
+ return await getDbClient().query(`SELECT harness, cliVersion, modelId, status, checkedAt, error FROM harness_model_support${where.length > 0 ? ` WHERE ${where.join(" AND ")}` : ""} ORDER BY checkedAt DESC`, params);
17384
+ }
17385
+ async function recordHarnessModelSupport(input) {
17386
+ const checkedAt = input.now ?? Date.now();
17387
+ const error = input.error ? scrubSecrets(input.error).slice(0, 2000) : null;
17388
+ await getDbClient().run(`INSERT INTO harness_model_support (harness, cliVersion, modelId, status, checkedAt, error)
17389
+ VALUES (?, ?, ?, ?, ?, ?)
17390
+ ON CONFLICT (harness, cliVersion, modelId) DO UPDATE SET
17391
+ status = CASE WHEN excluded.status = 'unknown' THEN harness_model_support.status ELSE excluded.status END,
17392
+ checkedAt = excluded.checkedAt,
17393
+ error = excluded.error`, [input.harness, input.cliVersion, input.modelId, input.status, checkedAt, error]);
17394
+ const row = await getDbClient().get("SELECT harness, cliVersion, modelId, status, checkedAt, error FROM harness_model_support WHERE harness = ? AND cliVersion = ? AND modelId = ?", [input.harness, input.cliVersion, input.modelId]);
17395
+ if (!row)
17396
+ throw new Error("harness_model_support upsert returned no row");
17397
+ return row;
17398
+ }
17399
+ async function agentRanModel(agentId, modelId) {
17400
+ const row = await getDbClient().get(`SELECT id FROM agent_tasks
17401
+ WHERE agentId = ? AND (resolvedModel = ? OR (resolvedModel IS NULL AND model = ?))
17402
+ LIMIT 1`, [agentId, modelId, modelId]);
17403
+ return row !== null && row !== undefined;
17404
+ }
17405
+ async function getAgentHarnessCliVersion(agentId) {
17406
+ const row = await getDbClient().get("SELECT harnessCliVersion FROM agents WHERE id = ?", [agentId]);
17407
+ return row?.harnessCliVersion ?? null;
17408
+ }
17409
+ async function setAgentHarnessCliVersion(agentId, cliVersion) {
17410
+ await getDbClient().run("UPDATE agents SET harnessCliVersion = ? WHERE id = ? AND harnessCliVersion IS NOT ?", [cliVersion, agentId, cliVersion]);
17411
+ }
17412
+ function unsupportedModelMessage(harness, cliVersion, model) {
17413
+ return `Model "${model}" is not supported by the ${harness} CLI ${cliVersion} on this worker. A CLI bump is needed before tasks can pin it.`;
17414
+ }
17415
+ async function fallbackForUnsupportedModel(harness, cliVersion, model, catalogSection) {
17416
+ if (!harnessCatalogSection(harness))
17417
+ return null;
17418
+ const family = modelFamilyKey(harness === "claude" ? claudeCatalogModelId(model, catalogSection) : model);
17419
+ const rejected = new Set((await listHarnessModelSupport({ harness, cliVersion })).filter((r) => r.status === "unsupported").map((r) => r.modelId));
17420
+ for (const id of harnessModelIds(harness, catalogSection)) {
17421
+ if (id === model || rejected.has(id))
17422
+ continue;
17423
+ if (modelFamilyKey(id) === family)
17424
+ return id;
17425
+ }
17426
+ return null;
17427
+ }
17428
+ var noticed = new Set;
17429
+ function noticeCliUnsupported(harness, cliVersion, model, fallback) {
17430
+ const key = `${harness}|${cliVersion}|${model}`;
17431
+ if (noticed.has(key))
17432
+ return;
17433
+ noticed.add(key);
17434
+ console.warn(`[model-tiers] ${model} is unsupported on ${harness} CLI ${cliVersion}; tier/alias tasks fall back to ${fallback} until the CLI is bumped`);
17435
+ }
17436
+
17437
+ // src/be/model-tier-resolution.ts
17438
+ init_model_tier_keys();
17439
+ init_model_tier_keys();
17440
+ var DEFAULT_MODEL_LATEST_SOAK_DAYS = 2;
17441
+ var OverridesSchema = exports_external.record(exports_external.string(), exports_external.record(exports_external.string(), exports_external.string()));
17442
+ function sanitizeModelTierOverrides(raw) {
17443
+ const parsed = OverridesSchema.safeParse(raw);
17444
+ if (!parsed.success)
17445
+ return {};
17446
+ const result = {};
17447
+ for (const [provider, tiers] of Object.entries(parsed.data)) {
17448
+ if (!ProviderNameSchema.safeParse(provider).success)
17449
+ continue;
17450
+ const clean = {};
17451
+ for (const [tier, value] of Object.entries(tiers)) {
17452
+ const t = parseModelTier(tier);
17453
+ const v = value.trim();
17454
+ if (t && t === tier && v && v.length <= 200 && !/\s/.test(v))
17455
+ clean[t] = v;
17456
+ }
17457
+ if (Object.keys(clean).length > 0)
17458
+ result[provider] = clean;
17459
+ }
17460
+ return result;
17461
+ }
17462
+ function parseModelTierOverridesHeader(header) {
17463
+ if (header === null || header === undefined || header === "")
17464
+ return;
17465
+ try {
17466
+ return sanitizeModelTierOverrides(JSON.parse(decodeURIComponent(header)));
17467
+ } catch {
17468
+ return;
17469
+ }
17470
+ }
17471
+ async function getAgentModelTierOverrides(agentId) {
17472
+ const row = await getDbClient().get("SELECT modelTierOverrides FROM agents WHERE id = ?", [agentId]);
17473
+ if (!row?.modelTierOverrides)
17474
+ return {};
17475
+ try {
17476
+ return sanitizeModelTierOverrides(JSON.parse(row.modelTierOverrides));
17477
+ } catch {
17478
+ return {};
17479
+ }
17480
+ }
17481
+ async function setAgentModelTierOverrides(agentId, overrides) {
17482
+ const next = Object.keys(overrides).length > 0 ? JSON.stringify(overrides) : null;
17483
+ await getDbClient().run("UPDATE agents SET modelTierOverrides = ? WHERE id = ? AND modelTierOverrides IS NOT ?", [next, agentId, next]);
17484
+ }
17485
+ var CATALOG_TTL_MS = 30000;
17486
+ var cachedCatalog = null;
17487
+ function mergeFacts(base, overlay) {
17488
+ const merged = { ...base };
17489
+ for (const [key, value] of Object.entries(overlay)) {
17490
+ if (value !== null && value !== undefined) {
17491
+ merged[key] = value;
17492
+ }
17493
+ }
17494
+ return merged;
17495
+ }
17496
+ async function loadResolutionCatalog() {
17497
+ const now = Date.now();
17498
+ const generation = getCatalogGeneration();
17499
+ if (cachedCatalog && cachedCatalog.generation === generation && now - cachedCatalog.at < CATALOG_TTL_MS) {
17500
+ return cachedCatalog;
17501
+ }
17502
+ let entries = await listModelCatalog();
17503
+ if (entries.length === 0) {
17504
+ const snapshot = loadModelsDevCache();
17505
+ entries = snapshot ? buildCatalogEntries(snapshot, 0) : [];
17506
+ }
17507
+ const facts = new Map;
17508
+ for (const entry of entries) {
17509
+ facts.set(`${entry.provider}/${entry.modelId}`, {
17510
+ provider: entry.provider,
17511
+ modelId: entry.modelId,
17512
+ facts: entry
17513
+ });
17514
+ }
17515
+ for (const overlay of await listModelCatalogOverlay()) {
17516
+ const key = `${overlay.provider}/${overlay.modelId}`;
17517
+ const existing = facts.get(key);
17518
+ facts.set(key, {
17519
+ provider: overlay.provider,
17520
+ modelId: overlay.modelId,
17521
+ facts: existing ? mergeFacts(existing.facts, overlay) : overlay
17522
+ });
17523
+ }
17524
+ const catalog = {};
17525
+ const priced = new Set;
17526
+ for (const { provider, modelId, facts: f } of facts.values()) {
17527
+ catalog[provider] ??= { id: provider, name: provider, models: {} };
17528
+ const model = {
17529
+ ...f.name ? { name: f.name } : {},
17530
+ ...f.releaseDate ? { release_date: f.releaseDate } : {},
17531
+ ...f.contextWindow ? { limit: { context: f.contextWindow } } : {},
17532
+ ...f.pricing ? { cost: f.pricing } : {}
17533
+ };
17534
+ catalog[provider].models[modelId] = model;
17535
+ const p = f.pricing;
17536
+ if (p && (typeof p.input === "number" || typeof p.output === "number")) {
17537
+ priced.add(`${provider}/${modelId}`);
17538
+ }
17539
+ }
17540
+ cachedCatalog = { at: now, generation, catalog, priced };
17541
+ return cachedCatalog;
17542
+ }
17543
+ function soakDays() {
17544
+ const raw = process.env.MODEL_LATEST_SOAK_DAYS?.trim();
17545
+ if (!raw)
17546
+ return DEFAULT_MODEL_LATEST_SOAK_DAYS;
17547
+ const n = Number(raw);
17548
+ return Number.isInteger(n) && n >= 0 ? n : DEFAULT_MODEL_LATEST_SOAK_DAYS;
17549
+ }
17550
+ function autoUpgradeEnabled() {
17551
+ const raw = process.env.MODEL_AUTO_UPGRADE?.trim().toLowerCase();
17552
+ return !(raw === "false" || raw === "0");
17553
+ }
17554
+ async function lastAliasResolution(alias) {
17555
+ const row = await getDbClient().get("SELECT newModel FROM model_alias_resolutions WHERE alias = ? ORDER BY id DESC LIMIT 1", [alias]);
17556
+ return row?.newModel ?? null;
17557
+ }
17558
+ async function resolveLatestAlias(alias, now = new Date, opts = {}) {
17559
+ const parsed = parseAlias(alias);
17560
+ if (!parsed)
17561
+ return null;
17562
+ const key = alias.trim().toLowerCase();
17563
+ const previous = await lastAliasResolution(key);
17564
+ if (previous && !autoUpgradeEnabled())
17565
+ return previous;
17566
+ const { catalog, priced } = await loadResolutionCatalog();
17567
+ const section = parsed.kind;
17568
+ const resolved = resolveAlias(key, catalog, {
17569
+ soakDays: soakDays(),
17570
+ now,
17571
+ isSupported: (id) => priced.has(`${section}/${id}`)
17572
+ });
17573
+ if (!resolved)
17574
+ return null;
17575
+ if (resolved !== previous && opts.record !== false) {
17576
+ await getDbClient().run("INSERT INTO model_alias_resolutions (alias, previousModel, newModel, changedAt) VALUES (?, ?, ?, ?)", [key, previous, resolved, now.getTime()]);
17577
+ getDbClient().afterCommit(() => {
17578
+ console.info(`[model-tiers] alias ${key} now resolves to ${resolved}${previous ? ` (was ${previous})` : ""}`);
17579
+ });
17580
+ }
17581
+ return resolved;
17582
+ }
17583
+ function taskModelCandidates(input) {
17584
+ const candidates = [];
17585
+ const model = input.model?.trim();
17586
+ if (model)
17587
+ candidates.push({ value: model, source: "model" });
17588
+ const tier = parseModelTier(input.modelTier);
17589
+ const provider = input.harnessProvider;
17590
+ if (tier && provider) {
17591
+ const worker = input.workerOverrides?.[provider]?.[tier]?.trim();
17592
+ if (worker)
17593
+ candidates.push({ value: worker, source: "worker-env" });
17594
+ const env = input.env ?? process.env;
17595
+ const configured = env[tierConfigKey(provider, tier)]?.trim();
17596
+ if (configured)
17597
+ candidates.push({ value: configured, source: "tier-config" });
17598
+ const fallback = DEFAULT_MODEL_TIER_MAP[provider]?.[tier];
17599
+ if (fallback)
17600
+ candidates.push({ value: fallback, source: "tier-default" });
17601
+ }
17602
+ return candidates;
17603
+ }
17604
+ async function resolveTaskModel(input) {
17605
+ for (const candidate of taskModelCandidates(input)) {
17606
+ if (!isAlias(candidate.value)) {
17607
+ return { resolvedModel: candidate.value, modelSource: candidate.source, modelAlias: null };
17608
+ }
17609
+ const resolved = await resolveLatestAlias(candidate.value, input.now, {
17610
+ record: input.record
17611
+ });
17612
+ if (resolved) {
17613
+ return {
17614
+ resolvedModel: resolved,
17615
+ modelSource: candidate.source,
17616
+ modelAlias: candidate.value.trim().toLowerCase()
17617
+ };
17618
+ }
17619
+ console.warn(`[model-tiers] ${candidate.source} alias ${candidate.value} resolved to nothing; trying next layer`);
17620
+ }
17621
+ return null;
17622
+ }
17623
+ async function previewModelTiers(opts = {}) {
17624
+ const env = opts.env ?? process.env;
17625
+ const rows = [];
17626
+ for (const provider of ProviderNameSchema.options) {
17627
+ if (MODEL_TIERS.every((tier) => !DEFAULT_MODEL_TIER_MAP[provider][tier]))
17628
+ continue;
17629
+ for (const tier of MODEL_TIERS) {
17630
+ const key = tierConfigKey(provider, tier);
17631
+ const configured = env[key]?.trim() || null;
17632
+ const resolution = await resolveTaskModel({
17633
+ modelTier: tier,
17634
+ harnessProvider: provider,
17635
+ env,
17636
+ now: opts.now,
17637
+ record: false
17638
+ });
17639
+ rows.push({
17640
+ provider,
17641
+ tier,
17642
+ key,
17643
+ defaultValue: DEFAULT_MODEL_TIER_MAP[provider][tier],
17644
+ configured,
17645
+ source: resolution?.modelSource === "tier-config" ? "tier-config" : "tier-default",
17646
+ resolvedModel: resolution?.resolvedModel ?? null,
17647
+ alias: resolution?.modelAlias ?? null
17648
+ });
17649
+ }
17650
+ }
17651
+ return rows;
17652
+ }
17653
+ async function applyCliSupport(resolution, harness, cliVersion) {
17654
+ if (!harness || !cliVersion || !CLI_PINNED_HARNESSES.has(harness))
17655
+ return resolution;
17656
+ const status = await getHarnessModelSupport(harness, cliVersion, resolution.resolvedModel);
17657
+ if (status !== "unsupported")
17658
+ return resolution;
17659
+ if (resolution.modelSource === "model" && !resolution.modelAlias) {
17660
+ return { unsupported: unsupportedModelMessage(harness, cliVersion, resolution.resolvedModel) };
17661
+ }
17662
+ const section = harnessCatalogSection(harness);
17663
+ const { catalog, priced } = await loadResolutionCatalog();
17664
+ const candidates = Object.fromEntries(Object.entries(section && catalog[section]?.models || {}).filter(([id]) => priced.has(`${section}/${id}`)));
17665
+ const fallback = await fallbackForUnsupportedModel(harness, cliVersion, resolution.resolvedModel, candidates);
17666
+ if (!fallback)
17667
+ return resolution;
17668
+ noticeCliUnsupported(harness, cliVersion, resolution.resolvedModel, fallback);
17669
+ return { ...resolution, resolvedModel: fallback, modelSource: "fallback:cli-unsupported" };
17670
+ }
17671
+ async function recordClaimModelResolution(task, agent) {
17672
+ const harnessProvider = agent.harnessProvider ?? agent.provider ?? null;
17673
+ const resolved = await resolveTaskModel({
17674
+ model: task.model,
17675
+ modelTier: task.modelTier,
17676
+ harnessProvider,
17677
+ workerOverrides: await getAgentModelTierOverrides(agent.id)
17678
+ });
17679
+ if (!resolved)
17680
+ return {};
17681
+ const checked = await applyCliSupport(resolved, harnessProvider, await getAgentHarnessCliVersion(agent.id));
17682
+ if ("unsupported" in checked) {
17683
+ return { modelUnsupported: checked.unsupported };
17684
+ }
17685
+ const resolution = checked;
17686
+ await getDbClient().run("UPDATE agent_tasks SET resolvedModel = ?, modelSource = ?, modelAlias = ? WHERE id = ?", [resolution.resolvedModel, resolution.modelSource, resolution.modelAlias, task.id]);
17687
+ return resolution.modelAlias ? resolution : { resolvedModel: resolution.resolvedModel, modelSource: resolution.modelSource };
17688
+ }
17689
+
17690
+ // src/be/model-validation.ts
17691
+ var FREE_FORM_HARNESSES = new Set(["acp", "devin", "dsh"]);
17692
+ var CONTEXT_SUFFIX_RE = /\[1m\]$/i;
17693
+ var BEDROCK_REGION_PREFIX_RE = /^(?:us|eu|apac|global|us-gov)\./;
17694
+ function hasModel(catalog, provider, modelId) {
17695
+ const models = catalog[provider]?.models;
17696
+ return Boolean(models && Object.hasOwn(models, modelId));
17697
+ }
17698
+ function isKnownCatalogModel(model, catalog) {
17699
+ const id = model.trim().replace(CONTEXT_SUFFIX_RE, "");
17700
+ if (!id)
17701
+ return false;
17702
+ const slash = id.indexOf("/");
17703
+ if (slash > 0) {
17704
+ const provider = id.slice(0, slash);
17705
+ const rest = id.slice(slash + 1);
17706
+ if (hasModel(catalog, provider, rest))
17707
+ return true;
17708
+ if (provider === "amazon-bedrock") {
17709
+ return hasModel(catalog, provider, rest.replace(BEDROCK_REGION_PREFIX_RE, ""));
17710
+ }
17711
+ }
17712
+ for (const provider of Object.keys(catalog)) {
17713
+ if (hasModel(catalog, provider, id))
17714
+ return true;
17715
+ }
17716
+ const anthropic = catalog.anthropic?.models;
17717
+ return Object.hasOwn(buildClaudeShortnameMap(anthropic), id);
17718
+ }
17719
+ async function explicitModelError(check) {
17720
+ const model = check.model?.trim();
17721
+ if (!model || check.allowCustomModel)
17722
+ return null;
17723
+ if (check.harnessProvider && FREE_FORM_HARNESSES.has(check.harnessProvider))
17724
+ return null;
17725
+ if (isAlias(model)) {
17726
+ if (!parseAlias(model)) {
17727
+ return `Invalid model alias "${model}". Use latest:<provider>/<family>[@stable|@any], e.g. latest:anthropic/opus.`;
17728
+ }
17729
+ const resolved = await resolveLatestAlias(model, new Date, { record: false });
17730
+ return resolved ? null : `Model alias "${model}" matches no model in the catalog. Check the provider and family, or use a concrete model id.`;
17731
+ }
17732
+ const { providers } = await loadModelsCatalog();
17733
+ const catalog = providers;
17734
+ if (Object.keys(catalog).length === 0)
17735
+ return null;
17736
+ if (isKnownCatalogModel(model, catalog))
17737
+ return null;
17738
+ return `Unknown model "${model}": it is not in the model catalog. Use a catalog model id, a Claude CLI shortname (opus, sonnet, haiku, fable), a latest:<provider>/<family> alias, or modelTier. To run a custom model id anyway, set allowCustomModel: true (allow_custom_model on the agent runtime).`;
17739
+ }
17740
+ async function explicitModelErrorForAgent(check) {
17741
+ if (!check.model?.trim() || check.allowCustomModel)
17742
+ return null;
17743
+ const agent = check.agentId ? await getAgentById(check.agentId) : null;
17744
+ return explicitModelError({ ...check, harnessProvider: agent?.harnessProvider ?? null });
17745
+ }
17746
+
17358
17747
  // src/extensions/apply-task-create.ts
17359
17748
  init_types();
17360
17749
  init_secret_scrubber();
@@ -27992,7 +28381,7 @@ async function notifySlack(text) {
27992
28381
  return;
27993
28382
  }
27994
28383
  try {
27995
- const { getSlackApp: getSlackApp2 } = await import("./app-g26wdcz6.js");
28384
+ const { getSlackApp: getSlackApp2 } = await import("./app-y1b9srva.js");
27996
28385
  const app = getSlackApp2();
27997
28386
  if (!app) {
27998
28387
  console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
@@ -28063,7 +28452,7 @@ async function deleteJiraWebhook(webhookId) {
28063
28452
  console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
28064
28453
  }
28065
28454
  async function overwriteWebhookIds(next) {
28066
- const { getDbClient: getDbClient2 } = await import("./db-03v9kzr2.js");
28455
+ const { getDbClient: getDbClient2 } = await import("./db-s3znhvbn.js");
28067
28456
  await getDbClient2().transaction(async (tx) => {
28068
28457
  const row = await tx.get("SELECT metadata FROM oauth_apps WHERE provider = 'jira'");
28069
28458
  if (!row) {
@@ -101795,7 +102184,7 @@ async function reloadGlobalConfigsAndIntegrations() {
101795
102184
  return runWithoutRequestAuth(() => reloadGlobalConfigsAndIntegrationsInner());
101796
102185
  }
101797
102186
  async function reloadGlobalConfigsAndIntegrationsInner() {
101798
- const { getEmbeddingProvider: getEmbeddingProvider2, resetEmbeddingProvider } = await import("./index-c6zsv1bd.js");
102187
+ const { getEmbeddingProvider: getEmbeddingProvider2, resetEmbeddingProvider } = await import("./index-bjmjh9h4.js");
101799
102188
  const wasEmbeddingsConfigured = getEmbeddingProvider2().isConfigured();
101800
102189
  const updated = await loadGlobalConfigsIntoEnv(true);
101801
102190
  await stopSlackApp();
@@ -101808,10 +102197,10 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
101808
102197
  integrations.push("embeddings");
101809
102198
  }
101810
102199
  if (!wasEmbeddingsConfigured && isEmbeddingsConfigured) {
101811
- import("./boot-reembed-se8zmdcp.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
102200
+ import("./boot-reembed-48d2qpkt.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
101812
102201
  console.error("[config-reload] memory backfill failed (non-fatal):", err);
101813
102202
  });
101814
- import("./boot-reembed-g5ckg9yb.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
102203
+ import("./boot-reembed-w0bryhkr.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
101815
102204
  console.error("[config-reload] script backfill failed (non-fatal):", err);
101816
102205
  });
101817
102206
  }
@@ -102624,7 +103013,7 @@ function setPreloadedTools(server, names) {
102624
103013
  async function applyPreToolCall(name, args, requestInfo, inputSchema) {
102625
103014
  if (requestInfo.callOrigin !== "mcp")
102626
103015
  return { args };
102627
- const dispatcher = await import("./dispatcher-nrmg8yht.js");
103016
+ const dispatcher = await import("./dispatcher-5xn0c7rf.js");
102628
103017
  const result = await dispatcher.dispatchPre("pre.tool.call", { tool: name, args, requestInfo }, inputSchema ? {
102629
103018
  validateModify: async (data) => {
102630
103019
  const schema = normalizeObjectSchema(inputSchema) ?? inputSchema;
@@ -113338,6 +113727,106 @@ var registerMemoryStoreTool = (server) => {
113338
113727
  });
113339
113728
  };
113340
113729
 
113730
+ // src/tools/model-catalog/index.ts
113731
+ init_zod();
113732
+ init_db();
113733
+ async function denyUnlessCatalogWriter(agentId) {
113734
+ const agent = await getAgentById(agentId);
113735
+ const decision = can({
113736
+ principal: { kind: "agent", agentId, isLead: agent?.isLead ?? false },
113737
+ verb: "models.catalog.write",
113738
+ resource: { kind: "none" },
113739
+ source: "mcp"
113740
+ });
113741
+ return decision.allow ? null : "Writing the model catalog requires the lead agent.";
113742
+ }
113743
+ var registerModelCatalogRefreshTool = (server) => {
113744
+ createToolRegistrar(server)("model-catalog-refresh", {
113745
+ title: "Refresh Model Catalog",
113746
+ description: "Refresh the swarm model catalog (and pricing rows) from models.dev, like `pi update --models`. Without force, skips the network when the last check is under 4h old. A forced refresh is accepted once per minute; a second one inside that window returns `skipped-cooldown` with `retryAfterMs`. Lead agent only. Returns the status, model count, and newly added provider/modelId keys.",
113747
+ annotations: { idempotentHint: true, openWorldHint: true },
113748
+ inputSchema: object({
113749
+ force: boolean().optional().describe("Fetch even if the last check is under 4h old (default false). Rate limited to one per minute.")
113750
+ }),
113751
+ outputSchema: swarmToolOutputSchema({
113752
+ status: string().optional(),
113753
+ models: number().optional(),
113754
+ added: array(string()).optional(),
113755
+ checkedAt: number().nullable().optional(),
113756
+ retryAfterMs: number().optional()
113757
+ })
113758
+ }, async ({ force }, requestInfo) => {
113759
+ if (!requestInfo.agentId) {
113760
+ return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
113761
+ }
113762
+ const denied = await denyUnlessCatalogWriter(requestInfo.agentId);
113763
+ if (denied)
113764
+ return toolErr(denied);
113765
+ const result = await requestModelCatalogRefresh({ force });
113766
+ const data = {
113767
+ status: result.status,
113768
+ models: result.models,
113769
+ added: result.added,
113770
+ checkedAt: result.checkedAt,
113771
+ retryAfterMs: result.retryAfterMs
113772
+ };
113773
+ if (result.status === "error") {
113774
+ return toolErr(`Model catalog refresh failed: ${result.error ?? "unknown error"}`, {
113775
+ data
113776
+ });
113777
+ }
113778
+ const addedText = result.added.length > 0 ? ` Added: ${result.added.join(", ")}.` : "";
113779
+ return toolOk(`Model catalog ${result.status}: ${result.models} model(s), ${result.added.length} new.`, {
113780
+ details: `status=${result.status}; models=${result.models}; added=${result.added.length}.${addedText}`,
113781
+ data
113782
+ });
113783
+ });
113784
+ };
113785
+ var registerModelCatalogOverlayUpsertTool = (server) => {
113786
+ createToolRegistrar(server)("model-catalog-overlay-upsert", {
113787
+ title: "Upsert Model Catalog Overlay",
113788
+ description: "Add or update hand-verified facts for one model (e.g. a launch models.dev has not listed yet). Overlay fields win over models.dev; overlay prices fill pricing-table gaps so cost recompute prices the model. The row auto-expires once models.dev matches every fact you set.",
113789
+ annotations: { idempotentHint: true },
113790
+ inputSchema: object({
113791
+ provider: string().min(1).describe("models.dev provider id: anthropic, openai, openrouter, amazon-bedrock, opencode."),
113792
+ modelId: string().min(1).describe("Model id as models.dev keys it (e.g. claude-opus-5-5)."),
113793
+ name: string().optional().describe("Display name."),
113794
+ releaseDate: string().optional().describe("Release date, YYYY-MM-DD."),
113795
+ contextWindow: number().int().positive().optional().describe("Context window, tokens."),
113796
+ maxOutput: number().int().positive().optional().describe("Max output tokens."),
113797
+ reasoningOptions: array(object({ type: string(), values: array(string()).optional() })).optional().describe("Reasoning options, models.dev shape: [{type, values?}]."),
113798
+ pricing: object({
113799
+ input: number().nonnegative().optional(),
113800
+ output: number().nonnegative().optional(),
113801
+ cache_read: number().nonnegative().optional(),
113802
+ cache_write: number().nonnegative().optional()
113803
+ }).optional().describe("USD per million tokens."),
113804
+ reason: string().min(1).describe("Why this overlay exists (source of the facts)."),
113805
+ verifiedBy: string().optional().describe("Who verified the facts (URL, person, agent).")
113806
+ }),
113807
+ outputSchema: swarmToolOutputSchema({
113808
+ overlay: looseObject({}).optional()
113809
+ })
113810
+ }, async (input, requestInfo) => {
113811
+ if (!requestInfo.agentId) {
113812
+ return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
113813
+ }
113814
+ const denied = await denyUnlessCatalogWriter(requestInfo.agentId);
113815
+ if (denied)
113816
+ return toolErr(denied);
113817
+ try {
113818
+ const overlay = await upsertModelCatalogOverlay(input);
113819
+ return toolOk(`Overlay for ${input.provider}/${input.modelId} saved.`, {
113820
+ details: `Overlay for ${input.provider}/${input.modelId} saved (reason: ${input.reason}). It expires when models.dev matches every fact set.`,
113821
+ data: { overlay }
113822
+ });
113823
+ } catch (error) {
113824
+ const message = error instanceof Error ? error.message : "Unknown error";
113825
+ return toolErr(`Failed to save overlay: ${message}`);
113826
+ }
113827
+ });
113828
+ };
113829
+
113341
113830
  // src/tools/my-agent-info.ts
113342
113831
  init_zod();
113343
113832
  init_db();
@@ -121355,7 +121844,8 @@ var createScheduleInputSchema = object({
121355
121844
  timezone: string().default("UTC").optional().describe("Timezone for cron schedules"),
121356
121845
  enabled: boolean().default(true).optional().describe("Whether the schedule is enabled (default: true)"),
121357
121846
  model: string().trim().min(1).optional().describe("Concrete model override for tasks created by this schedule. Interpreted by each assignee's harness/provider and does not switch providers. Prefer modelTier for portable intent."),
121358
- modelTier: ModelTierSchema.optional().describe("Portable model tier for tasks created by this schedule: 'smol', 'regular', 'smart', or 'ultra'. Resolved by each assignee's harness/provider at run time.")
121847
+ modelTier: ModelTierSchema.optional().describe("Portable model tier for tasks created by this schedule: 'smol', 'regular', 'smart', or 'ultra'. Resolved by each assignee's harness/provider at run time."),
121848
+ allowCustomModel: boolean().optional().describe("Accept a `model` the model catalog does not list. Without it an unknown model id is rejected. Only for ids the catalog cannot know yet.")
121359
121849
  });
121360
121850
  var scheduleDataShape = {
121361
121851
  id: string().optional(),
@@ -121416,7 +121906,8 @@ var registerCreateScheduleTool = (server) => {
121416
121906
  timezone,
121417
121907
  enabled: enabled2,
121418
121908
  model,
121419
- modelTier
121909
+ modelTier,
121910
+ allowCustomModel
121420
121911
  }, requestInfo, _meta) => {
121421
121912
  if (!requestInfo.agentId) {
121422
121913
  return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
@@ -121484,8 +121975,15 @@ var registerCreateScheduleTool = (server) => {
121484
121975
  return toolErr(`Script not found: ${scriptName}`);
121485
121976
  }
121486
121977
  }
121978
+ const normalizedModel = splitLegacyModelAlias({ model, modelTier });
121979
+ const modelError = await explicitModelErrorForAgent({
121980
+ model: normalizedModel.model,
121981
+ allowCustomModel,
121982
+ agentId: targetAgentId
121983
+ });
121984
+ if (modelError)
121985
+ return toolErr(modelError);
121487
121986
  try {
121488
- const normalizedModel = splitLegacyModelAlias({ model, modelTier });
121489
121987
  let nextRunAt;
121490
121988
  if (enabled2 === false) {
121491
121989
  nextRunAt = undefined;
@@ -121930,7 +122428,8 @@ var patchScheduleInputSchema = object({
121930
122428
  timezone: string().optional().describe("New timezone"),
121931
122429
  enabled: boolean().optional().describe("Enable or disable the schedule"),
121932
122430
  model: string().trim().min(1).nullable().optional().describe("Concrete model override for tasks created by this schedule. Set to null to clear."),
121933
- modelTier: ModelTierSchema.nullable().optional().describe("Portable model tier for tasks created by this schedule. Set to null to clear.")
122431
+ modelTier: ModelTierSchema.nullable().optional().describe("Portable model tier for tasks created by this schedule. Set to null to clear."),
122432
+ allowCustomModel: boolean().optional().describe("Accept a `model` the model catalog does not list. Without it an unknown model id is rejected. Only for ids the catalog cannot know yet.")
121934
122433
  });
121935
122434
  var scheduleDataShape2 = {
121936
122435
  id: string().optional(),
@@ -121990,7 +122489,8 @@ var registerPatchScheduleTool = (server) => {
121990
122489
  timezone,
121991
122490
  enabled: enabled2,
121992
122491
  model,
121993
- modelTier
122492
+ modelTier,
122493
+ allowCustomModel
121994
122494
  }, requestInfo, _meta) => {
121995
122495
  if (!requestInfo.agentId) {
121996
122496
  return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
@@ -122088,6 +122588,15 @@ var registerPatchScheduleTool = (server) => {
122088
122588
  updateData.enabled = enabled2;
122089
122589
  if (model !== undefined || modelTier !== undefined) {
122090
122590
  const normalizedModel = splitLegacyModelAlias({ model, modelTier });
122591
+ if (normalizedModel.model !== schedule.model) {
122592
+ const modelError = await explicitModelErrorForAgent({
122593
+ model: normalizedModel.model,
122594
+ allowCustomModel,
122595
+ agentId: targetAgentId ?? schedule.targetAgentId
122596
+ });
122597
+ if (modelError)
122598
+ return toolErr(modelError);
122599
+ }
122091
122600
  if (model !== undefined)
122092
122601
  updateData.model = normalizedModel.model ?? null;
122093
122602
  if (modelTier !== undefined || normalizedModel.modelTier) {
@@ -122220,7 +122729,8 @@ var updateScheduleInputSchema = object({
122220
122729
  timezone: string().optional().describe("New timezone"),
122221
122730
  enabled: boolean().optional().describe("Enable or disable the schedule"),
122222
122731
  model: string().trim().min(1).nullable().optional().describe("Concrete model override for tasks created by this schedule. Set to null to clear."),
122223
- modelTier: ModelTierSchema.nullable().optional().describe("Portable model tier for tasks created by this schedule. Set to null to clear.")
122732
+ modelTier: ModelTierSchema.nullable().optional().describe("Portable model tier for tasks created by this schedule. Set to null to clear."),
122733
+ allowCustomModel: boolean().optional().describe("Accept a `model` the model catalog does not list. Without it an unknown model id is rejected. Only for ids the catalog cannot know yet.")
122224
122734
  });
122225
122735
  var scheduleDataShape3 = {
122226
122736
  id: string().optional(),
@@ -122280,7 +122790,8 @@ var registerUpdateScheduleTool = (server) => {
122280
122790
  timezone,
122281
122791
  enabled: enabled2,
122282
122792
  model,
122283
- modelTier
122793
+ modelTier,
122794
+ allowCustomModel
122284
122795
  }, requestInfo, _meta) => {
122285
122796
  if (!requestInfo.agentId) {
122286
122797
  return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
@@ -122378,6 +122889,15 @@ var registerUpdateScheduleTool = (server) => {
122378
122889
  updateData.enabled = enabled2;
122379
122890
  if (model !== undefined || modelTier !== undefined) {
122380
122891
  const normalizedModel = splitLegacyModelAlias({ model, modelTier });
122892
+ if (normalizedModel.model !== schedule.model) {
122893
+ const modelError = await explicitModelErrorForAgent({
122894
+ model: normalizedModel.model,
122895
+ allowCustomModel,
122896
+ agentId: targetAgentId ?? schedule.targetAgentId
122897
+ });
122898
+ if (modelError)
122899
+ return toolErr(modelError);
122900
+ }
122381
122901
  if (model !== undefined)
122382
122902
  updateData.model = normalizedModel.model ?? null;
122383
122903
  if (modelTier !== undefined || normalizedModel.modelTier) {
@@ -123255,6 +123775,7 @@ var sendTaskInputSchema = object({
123255
123775
  vcsRepo: string().optional().describe("VCS repo identifier (e.g., 'desplega-ai/agent-swarm' for GitHub or 'group/project' for GitLab). Links the task to a registered repo for workspace context."),
123256
123776
  model: string().trim().min(1).optional().describe("Concrete model override for this task, interpreted by the assignee's harness/provider. This does not switch providers. Prefer modelTier for portable intent."),
123257
123777
  modelTier: ModelTierSchema.optional().describe("Portable model tier for this task: 'smol', 'regular', 'smart', or 'ultra'. Resolved at claim/run time using the assignee's harness/provider. Legacy model shortnames map as haiku→smol, sonnet→regular, opus→smart, fable→ultra."),
123778
+ allowCustomModel: boolean().optional().describe("Accept a `model` the model catalog does not list. Without it an unknown model id is rejected. Only for ids the catalog cannot know yet (a fresh launch, a private deployment)."),
123258
123779
  effort: ReasoningEffortSchema.optional().describe("Reasoning effort for this task: 'off', 'low', 'medium', 'high', 'xhigh', or 'max'. If omitted, the assignee's REASONING_EFFORT_OVERRIDE/default applies."),
123259
123780
  allowDuplicate: boolean().default(false).describe("If true, skip duplicate detection and create the task even if a similar one exists."),
123260
123781
  slackChannelId: string().optional().describe("Slack channel ID to post progress updates to. Use this to propagate Slack context when delegating from a Slack thread."),
@@ -123329,6 +123850,7 @@ async function sendTaskHandler(ctx, {
123329
123850
  vcsRepo,
123330
123851
  model,
123331
123852
  modelTier,
123853
+ allowCustomModel,
123332
123854
  effort,
123333
123855
  allowDuplicate,
123334
123856
  slackChannelId,
@@ -123365,6 +123887,13 @@ async function sendTaskHandler(ctx, {
123365
123887
  }
123366
123888
  const effectiveVcsRepo = vcsRepo;
123367
123889
  const normalizedModel = splitLegacyModelAlias({ model, modelTier });
123890
+ const modelError = await explicitModelErrorForAgent({
123891
+ model: normalizedModel.model,
123892
+ allowCustomModel,
123893
+ agentId
123894
+ });
123895
+ if (modelError)
123896
+ return toolErr(modelError, { data: { yourAgentId: creatorAgentId } });
123368
123897
  const effectiveParentTaskId = parentTaskId ?? sourceTaskId;
123369
123898
  const effectiveParentTask = effectiveParentTaskId ? await getTaskById(effectiveParentTaskId) : null;
123370
123899
  if (effectiveParentTask?.routingAffinityInvalid) {
@@ -124573,6 +125102,12 @@ function collectRichTextParts(node, parts) {
124573
125102
  }
124574
125103
  }
124575
125104
  }
125105
+ function decodeMrkdwn(text) {
125106
+ return text.replace(/<[^<>]*>/g, "").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&");
125107
+ }
125108
+ function normalizeForDedupe(text) {
125109
+ return text.replace(/:[a-z0-9_+'-]+:/gi, "").replace(/^[ \t]*(?:>|[•◦▪‣-]|\d+\.)[ \t]*/gm, "").replace(/[*_~`]/g, "").replace(/\s+/g, "");
125110
+ }
124576
125111
  function extractSlackMessageText(msg) {
124577
125112
  const topText = msg.text?.trim() ?? "";
124578
125113
  const attachmentParts = [];
@@ -124620,6 +125155,7 @@ function extractSlackMessageText(msg) {
124620
125155
  }
124621
125156
  }
124622
125157
  const blockParts = [];
125158
+ const richTextRanges = [];
124623
125159
  if (Array.isArray(msg.blocks) && msg.blocks.length > 0) {
124624
125160
  for (const rawBlock of msg.blocks) {
124625
125161
  if (rawBlock == null || typeof rawBlock !== "object")
@@ -124636,9 +125172,12 @@ function extractSlackMessageText(msg) {
124636
125172
  }
124637
125173
  }
124638
125174
  } else if (block.type === "rich_text" && Array.isArray(block.elements)) {
125175
+ const start = blockParts.length;
124639
125176
  for (const el of block.elements) {
124640
125177
  collectRichTextParts(el, blockParts);
124641
125178
  }
125179
+ if (blockParts.length > start)
125180
+ richTextRanges.push([start, blockParts.length]);
124642
125181
  } else if (block.type === "header") {
124643
125182
  if (block.text?.text)
124644
125183
  blockParts.push(block.text.text);
@@ -124667,7 +125206,21 @@ function extractSlackMessageText(msg) {
124667
125206
  }
124668
125207
  }
124669
125208
  }
124670
- const bodyText = [...attachmentParts, ...blockParts].filter(Boolean).join(`
125209
+ let bodyBlockParts = blockParts;
125210
+ if (topText && richTextRanges.length > 0) {
125211
+ const richText = richTextRanges.map(([start, end]) => blockParts.slice(start, end).join(`
125212
+ `)).join(`
125213
+ `);
125214
+ if (normalizeForDedupe(richText) === normalizeForDedupe(decodeMrkdwn(topText))) {
125215
+ const dropped = new Set;
125216
+ for (const [start, end] of richTextRanges) {
125217
+ for (let i = start;i < end; i++)
125218
+ dropped.add(i);
125219
+ }
125220
+ bodyBlockParts = blockParts.filter((_, i) => !dropped.has(i));
125221
+ }
125222
+ }
125223
+ const bodyText = [...attachmentParts, ...bodyBlockParts].filter(Boolean).join(`
124671
125224
  `);
124672
125225
  const bodyLines = new Set(bodyText.split(`
124673
125226
  `).map((l) => l.trim()).filter(Boolean));
@@ -127229,6 +127782,7 @@ var taskActionInputSchema = object({
127229
127782
  dir: string().min(1).startsWith("/").optional().describe("Working directory (absolute path) for the agent to start in. Only used with 'create' action."),
127230
127783
  model: string().trim().min(1).optional().describe("Concrete model override for the created task, interpreted by the claiming worker's harness/provider. This does not switch providers. Only used with 'create' action."),
127231
127784
  modelTier: ModelTierSchema.optional().describe("Portable model tier for the created task: 'smol', 'regular', 'smart', or 'ultra'. Resolved when a worker claims/runs the task. Only used with 'create' action."),
127785
+ allowCustomModel: boolean().optional().describe("Accept a `model` the model catalog does not list. Without it an unknown model id is rejected. Only used with 'create' action."),
127232
127786
  effort: ReasoningEffortSchema.optional().describe("Reasoning effort for the created task: 'off', 'low', 'medium', 'high', 'xhigh', or 'max'. Only used with 'create' action."),
127233
127787
  requiredCapabilities: array(string()).optional().describe("Capabilities required for pool routing."),
127234
127788
  leadOnly: boolean().default(false).describe("Structured authorization constraint: only Lead agents may claim this privileged task.")
@@ -127345,6 +127899,12 @@ async function taskActionHandler(ctx, input) {
127345
127899
  if (!task) {
127346
127900
  return taskActionResult({ success: false, message: "Task description is required for 'create' action." }, agentId);
127347
127901
  }
127902
+ const modelError = await explicitModelErrorForAgent({
127903
+ model: normalizedModel.model,
127904
+ allowCustomModel: input.allowCustomModel
127905
+ });
127906
+ if (modelError)
127907
+ return taskActionResult({ success: false, message: modelError }, agentId);
127348
127908
  try {
127349
127909
  assetKey = key ? await authorizeAssetKeyWrite(key, await resolveTaskAuditUserId(ctx.sourceTaskId, agentId)) : undefined;
127350
127910
  } catch (error) {
@@ -128316,7 +128876,8 @@ var registerCreateWorkflowTool = (server) => {
128316
128876
  }),
128317
128877
  outputSchema: swarmToolOutputSchema({
128318
128878
  yourAgentId: exports_external.string().optional(),
128319
- workflow: exports_external.unknown().optional()
128879
+ workflow: exports_external.unknown().optional(),
128880
+ warnings: exports_external.array(exports_external.string()).optional()
128320
128881
  })
128321
128882
  }, async ({
128322
128883
  name,
@@ -128355,11 +128916,13 @@ var registerCreateWorkflowTool = (server) => {
128355
128916
  createdBy
128356
128917
  }, "mcp");
128357
128918
  const longScriptTimeoutHint = findLongScriptTimeoutHint(definition.nodes);
128358
- return toolOk(`Created workflow "${workflow.name}".`, {
128359
- details: `Created workflow "${workflow.name}" (${workflow.id}).`,
128919
+ const warnings = await workflowSaveWarnings(workflow.definition, getExecutorRegistry());
128920
+ return toolOk(withSaveWarnings(`Created workflow "${workflow.name}".`, warnings), {
128921
+ details: withSaveWarnings(`Created workflow "${workflow.name}" (${workflow.id}).`, warnings),
128360
128922
  data: {
128361
128923
  yourAgentId: requestInfo.agentId,
128362
128924
  workflow,
128925
+ ...warnings.length > 0 ? { warnings } : {},
128363
128926
  ...longScriptTimeoutHint ? { longScriptTimeoutHint } : {}
128364
128927
  }
128365
128928
  });
@@ -128660,7 +129223,8 @@ var registerPatchWorkflowTool = (server) => {
128660
129223
  versionCreated: exports_external.number().optional(),
128661
129224
  nodesCreated: exports_external.number().optional(),
128662
129225
  nodesUpdated: exports_external.number().optional(),
128663
- nodesDeleted: exports_external.number().optional()
129226
+ nodesDeleted: exports_external.number().optional(),
129227
+ warnings: exports_external.array(exports_external.string()).optional()
128664
129228
  })
128665
129229
  }, async ({ id: id2, key, update, delete: del, create: create6, onNodeFailure, triggerSchema }, requestInfo) => {
128666
129230
  try {
@@ -128705,14 +129269,16 @@ var registerPatchWorkflowTool = (server) => {
128705
129269
  }
128706
129270
  const authoredFinalNodes = result.definition.nodes.filter((node) => timeoutAuthoredNodeIds.has(node.id));
128707
129271
  const longScriptTimeoutHint = findLongScriptTimeoutHint(authoredFinalNodes);
128708
- return toolOk(`Patched workflow "${workflow.name}".`, {
128709
- details: `Patched workflow "${workflow.name}" (${id2}). Version ${version} snapshot created.`,
129272
+ const warnings = await workflowSaveWarnings(result.definition, getExecutorRegistry());
129273
+ return toolOk(withSaveWarnings(`Patched workflow "${workflow.name}".`, warnings), {
129274
+ details: withSaveWarnings(`Patched workflow "${workflow.name}" (${id2}). Version ${version} snapshot created.`, warnings),
128710
129275
  data: {
128711
129276
  workflow,
128712
129277
  versionCreated: version ?? undefined,
128713
129278
  nodesCreated: create6?.length ?? 0,
128714
129279
  nodesUpdated: update?.length ?? 0,
128715
129280
  nodesDeleted: del?.length ?? 0,
129281
+ ...warnings.length > 0 ? { warnings } : {},
128716
129282
  ...longScriptTimeoutHint ? { longScriptTimeoutHint } : {}
128717
129283
  }
128718
129284
  });
@@ -128736,7 +129302,8 @@ var registerPatchWorkflowNodeTool = (server) => {
128736
129302
  }),
128737
129303
  outputSchema: swarmToolOutputSchema({
128738
129304
  workflow: exports_external.unknown().optional(),
128739
- versionCreated: exports_external.number().optional()
129305
+ versionCreated: exports_external.number().optional(),
129306
+ warnings: exports_external.array(exports_external.string()).optional()
128740
129307
  })
128741
129308
  }, async ({ id: id2, nodeId, ...nodeFields }, requestInfo) => {
128742
129309
  try {
@@ -128761,11 +129328,13 @@ var registerPatchWorkflowNodeTool = (server) => {
128761
129328
  const longScriptTimeoutHint = findLongScriptTimeoutHint([
128762
129329
  { id: nodeId, type: patchedNode?.type, config: nodeFields.config }
128763
129330
  ]);
128764
- return toolOk(`Patched node "${nodeId}" in workflow "${workflow.name}".`, {
128765
- details: `Patched node "${nodeId}" in workflow "${workflow.name}" (${id2}). Version ${version} snapshot created.`,
129331
+ const warnings = await workflowSaveWarnings(result.definition, getExecutorRegistry());
129332
+ return toolOk(withSaveWarnings(`Patched node "${nodeId}" in workflow "${workflow.name}".`, warnings), {
129333
+ details: withSaveWarnings(`Patched node "${nodeId}" in workflow "${workflow.name}" (${id2}). Version ${version} snapshot created.`, warnings),
128766
129334
  data: {
128767
129335
  workflow,
128768
129336
  versionCreated: version ?? undefined,
129337
+ ...warnings.length > 0 ? { warnings } : {},
128769
129338
  ...longScriptTimeoutHint ? { longScriptTimeoutHint } : {}
128770
129339
  }
128771
129340
  });
@@ -128886,7 +129455,8 @@ var registerUpdateWorkflowTool = (server) => {
128886
129455
  }),
128887
129456
  outputSchema: swarmToolOutputSchema({
128888
129457
  workflow: exports_external.unknown().optional(),
128889
- versionCreated: exports_external.number().optional()
129458
+ versionCreated: exports_external.number().optional(),
129459
+ warnings: exports_external.array(exports_external.string()).optional()
128890
129460
  })
128891
129461
  }, async ({
128892
129462
  id: id2,
@@ -128935,11 +129505,13 @@ var registerUpdateWorkflowTool = (server) => {
128935
129505
  return toolErr(`Workflow not found: ${id2}`);
128936
129506
  }
128937
129507
  const longScriptTimeoutHint = definition ? findLongScriptTimeoutHint(definition.nodes) : undefined;
128938
- return toolOk(`Updated workflow "${workflow.name}".`, {
128939
- details: `Updated workflow "${workflow.name}" (${id2}). Version ${version.version} snapshot created.`,
129508
+ const warnings = await workflowSaveWarnings(workflow.definition, getExecutorRegistry());
129509
+ return toolOk(withSaveWarnings(`Updated workflow "${workflow.name}".`, warnings), {
129510
+ details: withSaveWarnings(`Updated workflow "${workflow.name}" (${id2}). Version ${version.version} snapshot created.`, warnings),
128940
129511
  data: {
128941
129512
  workflow,
128942
129513
  versionCreated: version.version,
129514
+ ...warnings.length > 0 ? { warnings } : {},
128943
129515
  ...longScriptTimeoutHint ? { longScriptTimeoutHint } : {}
128944
129516
  }
128945
129517
  });
@@ -129083,6 +129655,8 @@ async function createServer(opts = {}) {
129083
129655
  registerListConfigTool(server);
129084
129656
  registerDeleteConfigTool(server);
129085
129657
  registerCredentialBindingsTool(server);
129658
+ registerModelCatalogRefreshTool(server);
129659
+ registerModelCatalogOverlayUpsertTool(server);
129086
129660
  }
129087
129661
  if (hasCapability2("scripts")) {
129088
129662
  registerScriptSearchTool(server);
@@ -129313,6 +129887,8 @@ var SDK_TOOL_NAME_MAP = {
129313
129887
  config_list: "list-config",
129314
129888
  config_set: "set-config",
129315
129889
  config_delete: "delete-config",
129890
+ modelCatalog_refresh: "model-catalog-refresh",
129891
+ modelCatalog_overlayUpsert: "model-catalog-overlay-upsert",
129316
129892
  slack_read: "slack-read",
129317
129893
  slack_listChannels: "slack-list-channels",
129318
129894
  slack_post: "slack-post",
@@ -131263,6 +131839,7 @@ var AgentTaskConfigSchema = exports_external.object({
131263
131839
  vcsRepo: exports_external.string().min(1).optional(),
131264
131840
  model: exports_external.string().min(1).optional(),
131265
131841
  modelTier: ModelTierSchema.optional(),
131842
+ allowCustomModel: exports_external.boolean().optional(),
131266
131843
  effort: ReasoningEffortSchema.optional(),
131267
131844
  parentTaskId: exports_external.string().uuid().optional(),
131268
131845
  requestedByUserId: exports_external.string().optional(),
@@ -131312,6 +131889,13 @@ class AgentTaskExecutor extends BaseExecutor {
131312
131889
  effectiveKey = workflow.key;
131313
131890
  }
131314
131891
  }
131892
+ const modelError = await explicitModelErrorForAgent({
131893
+ model: splitLegacyModelAlias({ model: config.model, modelTier: config.modelTier }).model,
131894
+ allowCustomModel: config.allowCustomModel,
131895
+ agentId: config.agentId
131896
+ });
131897
+ if (modelError)
131898
+ return { status: "failed", error: modelError };
131315
131899
  const preCreate = await applyPreTaskCreate({
131316
131900
  description: config.template,
131317
131901
  options: {
@@ -131561,340 +132145,6 @@ function normalizeExistingTaskOutput(output) {
131561
132145
  return output;
131562
132146
  }
131563
132147
 
131564
- // src/workflows/executors/human-in-the-loop.ts
131565
- init_zod();
131566
- init_constants();
131567
- init_secret_scrubber();
131568
- var SelectOptionSchema = exports_external.object({
131569
- value: exports_external.string(),
131570
- label: exports_external.string(),
131571
- description: exports_external.string().optional()
131572
- });
131573
- var QuestionSchema2 = exports_external.discriminatedUnion("type", [
131574
- exports_external.object({
131575
- id: exports_external.string(),
131576
- type: exports_external.literal("approval"),
131577
- label: exports_external.string(),
131578
- required: exports_external.boolean().default(true),
131579
- description: exports_external.string().optional()
131580
- }),
131581
- exports_external.object({
131582
- id: exports_external.string(),
131583
- type: exports_external.literal("text"),
131584
- label: exports_external.string(),
131585
- required: exports_external.boolean().default(true),
131586
- description: exports_external.string().optional(),
131587
- placeholder: exports_external.string().optional(),
131588
- multiline: exports_external.boolean().optional()
131589
- }),
131590
- exports_external.object({
131591
- id: exports_external.string(),
131592
- type: exports_external.literal("single-select"),
131593
- label: exports_external.string(),
131594
- required: exports_external.boolean().default(true),
131595
- description: exports_external.string().optional(),
131596
- options: exports_external.array(SelectOptionSchema)
131597
- }),
131598
- exports_external.object({
131599
- id: exports_external.string(),
131600
- type: exports_external.literal("multi-select"),
131601
- label: exports_external.string(),
131602
- required: exports_external.boolean().default(true),
131603
- description: exports_external.string().optional(),
131604
- options: exports_external.array(SelectOptionSchema),
131605
- minSelections: exports_external.number().int().min(0).optional(),
131606
- maxSelections: exports_external.number().int().min(1).optional()
131607
- }),
131608
- exports_external.object({
131609
- id: exports_external.string(),
131610
- type: exports_external.literal("boolean"),
131611
- label: exports_external.string(),
131612
- required: exports_external.boolean().default(true),
131613
- description: exports_external.string().optional(),
131614
- defaultValue: exports_external.boolean().optional()
131615
- })
131616
- ]);
131617
- var ApproverConfigSchema = exports_external.object({
131618
- users: exports_external.array(exports_external.string()).optional(),
131619
- roles: exports_external.array(exports_external.string()).optional(),
131620
- policy: exports_external.union([exports_external.literal("any"), exports_external.literal("all"), exports_external.object({ min: exports_external.number().int().min(1) })])
131621
- });
131622
- var NotificationConfigSchema = exports_external.object({
131623
- channel: exports_external.enum(["slack", "email"]),
131624
- target: exports_external.string()
131625
- });
131626
- var DYNAMIC_QUESTIONS_TOKEN_RE = /^\{\{[^}]+\}\}$/;
131627
- var MAX_HITL_QUESTIONS = 100;
131628
- var SLACK_SECTION_TEXT_LIMIT = 3000;
131629
- var MAX_REPORTED_ISSUES = 5;
131630
- var HITLConfigSchema = exports_external.object({
131631
- title: exports_external.string(),
131632
- questions: exports_external.union([
131633
- exports_external.array(QuestionSchema2).min(1),
131634
- exports_external.string().regex(DYNAMIC_QUESTIONS_TOKEN_RE, "questions must be an array or one exact {{interpolation}} token")
131635
- ]),
131636
- approvers: ApproverConfigSchema,
131637
- timeout: exports_external.object({
131638
- seconds: exports_external.number().int().min(1),
131639
- action: exports_external.literal("reject")
131640
- }).optional(),
131641
- notifications: exports_external.array(NotificationConfigSchema).optional()
131642
- });
131643
- var HITLOutputSchema = exports_external.object({
131644
- requestId: exports_external.string().uuid(),
131645
- status: exports_external.string(),
131646
- responses: exports_external.record(exports_external.string(), exports_external.unknown()).nullable()
131647
- });
131648
- function resolveHitlQuestions(value) {
131649
- const fail = (reason) => ({
131650
- ok: false,
131651
- error: `human-in-the-loop questions ${reason}`
131652
- });
131653
- if (typeof value === "string") {
131654
- return fail(value.trim() === "" ? "resolved to an empty value: the {{token}} did not resolve (check the node's inputs mapping and the upstream output)" : "resolved to a string; they must resolve to an array of question objects (use one exact {{token}} pointing at an array)");
131655
- }
131656
- if (!Array.isArray(value)) {
131657
- return fail(`must resolve to an array of question objects, got ${value === null ? "null" : typeof value}`);
131658
- }
131659
- if (value.length === 0) {
131660
- return fail("resolved to an empty array; refusing to create an approval card with no questions");
131661
- }
131662
- if (value.length > MAX_HITL_QUESTIONS) {
131663
- return fail(`resolved to ${value.length} questions, over the limit of ${MAX_HITL_QUESTIONS} per card; split or group them upstream`);
131664
- }
131665
- const issues = [];
131666
- const questions = [];
131667
- const seenIds = new Set;
131668
- value.forEach((raw, index) => {
131669
- const parsed = QuestionSchema2.safeParse(raw);
131670
- if (!parsed.success) {
131671
- for (const issue of parsed.error.issues) {
131672
- const path3 = issue.path.length > 0 ? `.${issue.path.map(String).join(".")}` : "";
131673
- issues.push(`[${index}]${path3}: ${issue.message}`);
131674
- }
131675
- return;
131676
- }
131677
- const question = parsed.data;
131678
- if (question.id.trim() === "") {
131679
- issues.push(`[${index}].id: must be a non-empty string`);
131680
- } else if (seenIds.has(question.id)) {
131681
- issues.push(`[${index}].id: duplicate id "${question.id}" (responses are keyed by id)`);
131682
- }
131683
- seenIds.add(question.id);
131684
- if ((question.type === "single-select" || question.type === "multi-select") && question.options.length === 0) {
131685
- issues.push(`[${index}].options: a ${question.type} question needs at least one option`);
131686
- }
131687
- questions.push(question);
131688
- });
131689
- if (issues.length > 0) {
131690
- const shown = issues.slice(0, MAX_REPORTED_ISSUES).join("; ");
131691
- const more = issues.length > MAX_REPORTED_ISSUES ? `; and ${issues.length - MAX_REPORTED_ISSUES} more issue(s)` : "";
131692
- return fail(`are invalid: ${shown}${more}`);
131693
- }
131694
- return { ok: true, questions };
131695
- }
131696
- function escapeSlackMrkdwn(text) {
131697
- return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
131698
- }
131699
- function buildSlackQuestionsSummary(questions, timeoutText = "") {
131700
- const header = `*Questions:*
131701
- `;
131702
- const lines = questions.map((q) => `• ${escapeSlackMrkdwn(q.label.replace(/\s+/g, " ").trim())}`);
131703
- const fits = (shown, omitted) => {
131704
- const tail = omitted > 0 ? `
131705
- _…and ${omitted} more. Answer all of them on the dashboard._` : "";
131706
- const text = `${header}${shown.join(`
131707
- `)}${tail}${timeoutText}`;
131708
- return text.length <= SLACK_SECTION_TEXT_LIMIT ? text : null;
131709
- };
131710
- const full = fits(lines, 0);
131711
- if (full)
131712
- return full;
131713
- for (let count = lines.length - 1;count >= 0; count--) {
131714
- const text = fits(lines.slice(0, count), lines.length - count);
131715
- if (text)
131716
- return text;
131717
- }
131718
- return `${header}_${questions.length} questions. Answer them on the dashboard._`;
131719
- }
131720
-
131721
- class HumanInTheLoopExecutor extends BaseExecutor {
131722
- type = "human-in-the-loop";
131723
- mode = "async";
131724
- configSchema = HITLConfigSchema;
131725
- outputSchema = HITLOutputSchema;
131726
- async run(input) {
131727
- const resolved = resolveHitlQuestions(input.config?.questions);
131728
- if (!resolved.ok)
131729
- return { status: "failed", error: resolved.error };
131730
- return super.run({ ...input, config: { ...input.config, questions: resolved.questions } });
131731
- }
131732
- async execute(config, _context, meta2) {
131733
- const { db } = this.deps;
131734
- const existing = await db.getApprovalRequestByStepId(meta2.stepId);
131735
- if (existing) {
131736
- if (existing.status !== "pending") {
131737
- if (existing.status === "cancelled") {
131738
- return {
131739
- status: "failed",
131740
- error: `Approval request was cancelled: ${existing.resolutionReason ?? "workflow run cancelled"}`
131741
- };
131742
- }
131743
- const nextPort = existing.status === "timeout" ? "timeout" : existing.status === "rejected" ? "rejected" : "approved";
131744
- return {
131745
- status: "success",
131746
- output: {
131747
- requestId: existing.id,
131748
- status: existing.status,
131749
- responses: existing.responses
131750
- },
131751
- nextPort
131752
- };
131753
- }
131754
- return {
131755
- status: "success",
131756
- async: true,
131757
- waitFor: "approval.resolved",
131758
- correlationId: existing.id
131759
- };
131760
- }
131761
- if (!Array.isArray(config.questions)) {
131762
- return { status: "failed", error: "human-in-the-loop questions did not resolve to an array" };
131763
- }
131764
- const requestId = crypto.randomUUID();
131765
- const created = await db.createApprovalRequest({
131766
- id: requestId,
131767
- title: config.title,
131768
- questions: config.questions,
131769
- approvers: config.approvers,
131770
- workflowRunId: meta2.runId,
131771
- workflowRunStepId: meta2.stepId,
131772
- timeoutSeconds: config.timeout?.seconds,
131773
- notificationChannels: config.notifications,
131774
- createdBy: meta2.requestedByUserId,
131775
- requireActionableWorkflow: true
131776
- });
131777
- if (created.status === "cancelled") {
131778
- return {
131779
- status: "success",
131780
- async: true,
131781
- waitFor: "approval.resolved",
131782
- correlationId: requestId
131783
- };
131784
- }
131785
- if (config.notifications?.length) {
131786
- this.dispatchNotifications(requestId, config, db).catch((err) => {
131787
- console.error("[HITL] Unexpected error dispatching notifications:", scrubSecrets(err instanceof Error ? err.message : String(err)));
131788
- });
131789
- }
131790
- return {
131791
- status: "success",
131792
- async: true,
131793
- waitFor: "approval.resolved",
131794
- correlationId: requestId
131795
- };
131796
- }
131797
- async dispatchNotifications(requestId, config, db) {
131798
- if (!config.notifications?.length)
131799
- return;
131800
- const approvalUrl = `${getAppUrl()}/approval-requests/${requestId}`;
131801
- const updatedChannels = [...config.notifications];
131802
- let updated = false;
131803
- for (let i = 0;i < config.notifications.length; i++) {
131804
- const notification = config.notifications[i];
131805
- if (notification.channel === "email") {
131806
- console.warn(`[HITL] Email notifications not yet supported (target: ${notification.target})`);
131807
- continue;
131808
- }
131809
- if (notification.channel === "slack") {
131810
- try {
131811
- const { getSlackApp: getSlackApp2 } = await import("./app-g26wdcz6.js");
131812
- const slackApp = getSlackApp2();
131813
- if (!slackApp) {
131814
- console.warn("[HITL] Slack not initialized — cannot send notification");
131815
- continue;
131816
- }
131817
- const questions = Array.isArray(config.questions) ? config.questions : [];
131818
- const questionsText = buildSlackQuestionsSummary(questions);
131819
- const timeoutCaption = config.timeout ? [
131820
- {
131821
- type: "context",
131822
- elements: [
131823
- {
131824
- type: "mrkdwn",
131825
- text: `⏱ Timeout: ${formatTimeout(config.timeout.seconds)} — times out if not responded`
131826
- }
131827
- ]
131828
- }
131829
- ] : [];
131830
- const blocks = [
131831
- {
131832
- type: "section",
131833
- text: {
131834
- type: "mrkdwn",
131835
- text: `\uD83D\uDD14 *Approval Required: ${config.title}*`
131836
- }
131837
- },
131838
- {
131839
- type: "section",
131840
- text: {
131841
- type: "mrkdwn",
131842
- text: questionsText
131843
- }
131844
- },
131845
- {
131846
- type: "actions",
131847
- elements: [
131848
- {
131849
- type: "button",
131850
- text: { type: "plain_text", text: "Review & Respond" },
131851
- url: approvalUrl,
131852
- style: "primary"
131853
- }
131854
- ]
131855
- },
131856
- ...timeoutCaption
131857
- ];
131858
- const result = await slackApp.client.chat.postMessage({
131859
- channel: notification.target,
131860
- text: `Approval Required: ${config.title} — ${approvalUrl}`,
131861
- unfurl_links: false,
131862
- unfurl_media: false,
131863
- blocks
131864
- });
131865
- if (result.ts) {
131866
- updatedChannels[i] = { ...notification, messageTs: result.ts };
131867
- updated = true;
131868
- }
131869
- console.log(`[HITL] Slack notification sent to ${notification.target} for request ${requestId}`);
131870
- } catch (err) {
131871
- console.error(`[HITL] Failed to send Slack notification to ${notification.target}:`, scrubSecrets(err instanceof Error ? err.message : String(err)));
131872
- }
131873
- }
131874
- }
131875
- if (updated) {
131876
- try {
131877
- await db.updateApprovalRequestNotifications(requestId, updatedChannels);
131878
- const latest = await db.getApprovalRequestById(requestId);
131879
- if (latest?.status === "cancelled") {
131880
- await postApprovalCancellationUpdates([latest], latest.resolutionReason ?? "Workflow run cancelled");
131881
- }
131882
- } catch (err) {
131883
- console.error("[HITL] Failed to update notification channels in DB:", scrubSecrets(err instanceof Error ? err.message : String(err)));
131884
- }
131885
- }
131886
- }
131887
- }
131888
- function formatTimeout(seconds) {
131889
- if (seconds < 60)
131890
- return `${seconds}s`;
131891
- if (seconds < 3600)
131892
- return `${Math.round(seconds / 60)}m`;
131893
- const hours = Math.floor(seconds / 3600);
131894
- const mins = Math.round(seconds % 3600 / 60);
131895
- return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
131896
- }
131897
-
131898
132148
  // src/workflows/executors/notify.ts
131899
132149
  init_zod();
131900
132150
  var NotifyConfigSchema = exports_external.object({
@@ -131937,7 +132187,7 @@ class NotifyExecutor extends BaseExecutor {
131937
132187
  }
131938
132188
  }
131939
132189
  case "slack": {
131940
- const { getSlackApp: getSlackApp2 } = await import("./app-g26wdcz6.js");
132190
+ const { getSlackApp: getSlackApp2 } = await import("./app-y1b9srva.js");
131941
132191
  const app = getSlackApp2();
131942
132192
  if (!app) {
131943
132193
  return {
@@ -132049,26 +132299,6 @@ function evaluateCondition(op, actual, expected) {
132049
132299
 
132050
132300
  // src/workflows/executors/raw-llm.ts
132051
132301
  init_zod();
132052
-
132053
- // src/workflows/executors/workflow-llm.ts
132054
- async function resolveWorkflowLlmConfig(requestedModel, env = process.env) {
132055
- const credential = await resolveCredential({ env });
132056
- if (!credential) {
132057
- throw new Error("No workflow LLM credential found. Set OPENROUTER_API_KEY or OPENAI_API_KEY.");
132058
- }
132059
- if (credential.kind !== "openrouter" && credential.kind !== "openai") {
132060
- throw new Error(`Workflow LLM nodes do not support the resolved ${credential.kind} credential yet. Set OPENROUTER_API_KEY or OPENAI_API_KEY.`);
132061
- }
132062
- const providerPrefix = `${credential.kind}/`;
132063
- const model = requestedModel ?? DEFAULT_MODEL[credential.kind];
132064
- return {
132065
- apiKey: credential.apiKey,
132066
- baseURL: credential.kind === "openrouter" ? getOpenRouterBaseUrl(env) : undefined,
132067
- model: model.startsWith(providerPrefix) ? model.slice(providerPrefix.length) : model
132068
- };
132069
- }
132070
-
132071
- // src/workflows/executors/raw-llm.ts
132072
132302
  var RawLlmConfigSchema = exports_external.object({
132073
132303
  prompt: exports_external.string(),
132074
132304
  model: exports_external.string().optional(),
@@ -132091,7 +132321,7 @@ async function executeRawLlm(config) {
132091
132321
  });
132092
132322
  const model = provider(llmConfig.model);
132093
132323
  if (config.schema) {
132094
- const { generateObject, jsonSchema } = await import("./index-f24115ge.js");
132324
+ const { generateObject, jsonSchema } = await import("./index-2wsdsnmm.js");
132095
132325
  const { object: object4 } = await generateObject({
132096
132326
  model,
132097
132327
  schema: jsonSchema(config.schema),
@@ -132105,7 +132335,7 @@ async function executeRawLlm(config) {
132105
132335
  output: { result: object4, model: modelName }
132106
132336
  };
132107
132337
  }
132108
- const { generateText } = await import("./index-f24115ge.js");
132338
+ const { generateText } = await import("./index-2wsdsnmm.js");
132109
132339
  const { text } = await generateText({
132110
132340
  model,
132111
132341
  prompt: config.prompt
@@ -132543,7 +132773,7 @@ class ValidateExecutor extends BaseExecutor {
132543
132773
  const outputStr = typeof targetOutput === "string" ? targetOutput : JSON.stringify(targetOutput);
132544
132774
  try {
132545
132775
  const { createOpenAI } = await import("./index-n5t1gzfb.js");
132546
- const { generateObject, jsonSchema } = await import("./index-f24115ge.js");
132776
+ const { generateObject, jsonSchema } = await import("./index-2wsdsnmm.js");
132547
132777
  const llmConfig = await resolveWorkflowLlmConfig();
132548
132778
  const provider = createOpenAI({
132549
132779
  baseURL: llmConfig.baseURL,
@@ -132713,6 +132943,7 @@ function createExecutorRegistry(deps) {
132713
132943
  registry3.register(new CodeMatchExecutor(deps));
132714
132944
  registry3.register(new NotifyExecutor(deps));
132715
132945
  registry3.register(new RawLlmExecutor(deps));
132946
+ registry3.register(new SystemOneDecisionExecutor(deps));
132716
132947
  registry3.register(new ScriptExecutor(deps));
132717
132948
  registry3.register(new SwarmScriptExecutor(deps));
132718
132949
  registry3.register(new VcsExecutor(deps));
@@ -132761,4 +132992,4 @@ async function initWorkflows() {
132761
132992
  logOpenWebhookTriggers();
132762
132993
  }
132763
132994
 
132764
- export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, findUserById, findUserByExternalId, getUserIdentities, listUserEvents, listUserTokens, recordIdentityEvent, findOrCreateUserByEmail, linkIdentity, unlinkIdentity, mintToken, revokeToken, resolveUserByToken, mintSessionToken, revokeSessionToken, fingerprintApiKey, resolveIdentity, renderIdentity, createAdditiveBuffer, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, automationIntegrationFixUrl, preflightAutomation, getAutomationSetupStates, listEnabledAutomationPreflightInputs, validateJsonSchema, TriggerSchemaError, startWorkflowExecution, createApprovalFollowUpTask, setupWorkflowResumeListener, retryFailedRun, cancelWorkflowRun, resumeWaitState, initWaitBusSubscriptions, subscribeWaitToBus, recoverIncompleteRuns, startRetryPoller, stopRetryPoller, validateTemplateVariables, instantiateTemplate, handleWebhookTrigger, logOpenWebhookTriggers, handleEventTrigger, handleScheduleTrigger, verifyHmacSignature, WebhookError, snapshotWorkflow, snapshotAndUpdateWorkflow, startWaitPoller, stopWaitPoller, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry, initWorkflows, dispatchScheduleTarget, calculateNextRun, startScheduler, stopScheduler, runScheduleNow, parseSkillContent, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, toolErr, createToolRegistrar, warnIfCorsAllowsAnyOrigin, isOriginAllowedForCredentials, allowedCredentialRedirect, setCorsHeaders, parseQueryParams, getPathSegments, wireHttpSpanLifecycle, safeRequestUrlForLog, agentWithCapacity, parseBody, BODY_TOO_LARGE, enforceContentLengthCap, json, jsonError, triggerSchemaErrorResponse, deriveApiBaseUrl, httpServerSemconvAttributes, runtimeInstanceHeader, describeRequestRoute, route, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError, isRegistered, isExtensionAgentId, getExtensionBridgeToken, resolveBridgeCallOrigin, extensionIdForAgent, runContext, registerLoaded, unregister, listRegistered, dispatchPre, dispatchPost, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2 as handleIssue1, handleNote, handlePipeline, repointTrackerSyncBySwarmId, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, parseCookieHeader, extractAndVerifyCookie, issuePageSessionCookie, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, userCtx, resolveTaskAuditUserId, resolveHttpAuditUserId, resolveHttpFavoriteOwner, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, refreshLinks, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, indexMemoryContent, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, taskActionInputSchema, taskActionOutputSchema, taskActionHandler, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };
132995
+ export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, findUserById, findUserByExternalId, getUserIdentities, listUserEvents, listUserTokens, recordIdentityEvent, findOrCreateUserByEmail, linkIdentity, unlinkIdentity, mintToken, revokeToken, resolveUserByToken, mintSessionToken, revokeSessionToken, fingerprintApiKey, resolveIdentity, renderIdentity, createAdditiveBuffer, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, automationIntegrationFixUrl, preflightAutomation, getAutomationSetupStates, listEnabledAutomationPreflightInputs, validateJsonSchema, workflowSaveWarnings, TriggerSchemaError, startWorkflowExecution, setupWorkflowResumeListener, retryFailedRun, cancelWorkflowRun, resumeWaitState, initWaitBusSubscriptions, subscribeWaitToBus, recoverIncompleteRuns, startRetryPoller, stopRetryPoller, validateTemplateVariables, instantiateTemplate, handleWebhookTrigger, logOpenWebhookTriggers, handleEventTrigger, handleScheduleTrigger, verifyHmacSignature, WebhookError, snapshotWorkflow, snapshotAndUpdateWorkflow, startWaitPoller, stopWaitPoller, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, explicitModelError, explicitModelErrorForAgent, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry, initWorkflows, dispatchScheduleTarget, calculateNextRun, startScheduler, stopScheduler, runScheduleNow, parseSkillContent, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, toolErr, createToolRegistrar, warnIfCorsAllowsAnyOrigin, isOriginAllowedForCredentials, allowedCredentialRedirect, setCorsHeaders, parseQueryParams, getPathSegments, wireHttpSpanLifecycle, safeRequestUrlForLog, agentWithCapacity, parseBody, BODY_TOO_LARGE, enforceContentLengthCap, json, jsonError, triggerSchemaErrorResponse, deriveApiBaseUrl, httpServerSemconvAttributes, runtimeInstanceHeader, describeRequestRoute, route, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError, isRegistered, isExtensionAgentId, getExtensionBridgeToken, resolveBridgeCallOrigin, extensionIdForAgent, runContext, registerLoaded, unregister, listRegistered, dispatchPre, dispatchPost, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2 as handleIssue1, handleNote, handlePipeline, repointTrackerSyncBySwarmId, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, parseCookieHeader, extractAndVerifyCookie, issuePageSessionCookie, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, userCtx, resolveTaskAuditUserId, resolveHttpAuditUserId, resolveHttpFavoriteOwner, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, refreshLinks, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, indexMemoryContent, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, taskActionInputSchema, taskActionOutputSchema, taskActionHandler, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };