@desplega.ai/agent-swarm 1.158.0 → 1.160.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 (378) hide show
  1. package/README.md +1 -1
  2. package/dist/{acp-adapter-xaq4n6pc.js → acp-adapter-2mjwcsfh.js} +124 -27
  3. package/dist/{actions-p9hz5yat.js → actions-e43rxskr.js} +35 -30
  4. package/dist/{anthropic-messages-51pz26qe.js → anthropic-messages-5qx80j9k.js} +106 -16
  5. package/dist/{app-g26wdcz6.js → app-mc7xfagn.js} +12 -10
  6. package/dist/{assistant-wydfqkb3.js → assistant-sedkzv3b.js} +42 -31
  7. package/dist/{azure-openai-responses-8gksqtmz.js → azure-openai-responses-nfb21z9a.js} +13 -14
  8. package/dist/{boot-reembed-se8zmdcp.js → boot-reembed-cqz9swn5.js} +13 -12
  9. package/dist/{boot-reembed-g5ckg9yb.js → boot-reembed-m3656j2n.js} +14 -13
  10. package/dist/{boot-scrub-logs-wfxqan61.js → boot-scrub-logs-xbxf5d7w.js} +11 -9
  11. package/dist/boot-seeds-gsetbs5y.js +28 -0
  12. package/dist/{claude-adapter-tv2x4f36.js → claude-adapter-dc6289mc.js} +28 -23
  13. package/dist/{claude-managed-adapter-41b2s7fd.js → claude-managed-adapter-naaw51me.js} +4 -3
  14. package/dist/{claude-managed-setup-60g8aazx.js → claude-managed-setup-eacvchx0.js} +12 -3
  15. package/dist/claude-sdk-session-bqp2xvym.js +29722 -0
  16. package/dist/{cli-987hg0aa.js → cli-0jwe9034.js} +2 -2
  17. package/dist/{cli-vj6h9kc2.js → cli-0m7wct0d.js} +59 -1
  18. package/dist/{cli-c07r9a2m.js → cli-0q3avq3s.js} +12 -11
  19. package/dist/{cli-19jenss3.js → cli-0wgxmwf6.js} +31 -10
  20. package/dist/cli-0x01kwrd.js +491 -0
  21. package/dist/cli-0xqde53b.js +176 -0
  22. package/dist/cli-10nhj6xq.js +8355 -0
  23. package/dist/{cli-tt9k8r35.js → cli-12tszpk9.js} +479 -910
  24. package/dist/{cli-5b6b62tz.js → cli-13hw4z91.js} +1 -1
  25. package/dist/{cli-cqt19wg6.js → cli-1a2j50m0.js} +11 -2
  26. package/dist/{cli-xberxa1r.js → cli-25fcq4b4.js} +2 -2
  27. package/dist/{cli-npssxgaz.js → cli-2pdaysab.js} +52 -2
  28. package/dist/cli-3qhyh31j.js +166 -0
  29. package/dist/cli-447dt1h3.js +3828 -0
  30. package/dist/cli-4derpgyk.js +115 -0
  31. package/dist/{cli-00w2c66p.js → cli-523679eh.js} +13 -2
  32. package/dist/{cli-y95wp3tg.js → cli-58e8yr0d.js} +1 -1
  33. package/dist/{cli-24k806sc.js → cli-5nbmpy8w.js} +3 -3
  34. package/dist/{cli-53sz8gkz.js → cli-6cs6wzxt.js} +1 -1
  35. package/dist/cli-741yb0xx.js +1027 -0
  36. package/dist/cli-74h9hscv.js +69 -0
  37. package/dist/cli-7cxw8b60.js +14910 -0
  38. package/dist/{cli-xhaeg2nc.js → cli-7e398j1h.js} +1 -1
  39. package/dist/cli-7kyk9jr3.js +22 -0
  40. package/dist/cli-89s4ngw3.js +183 -0
  41. package/dist/{cli-9b13ggd1.js → cli-89v6kyq7.js} +1 -0
  42. package/dist/{cli-ftfvggzx.js → cli-9hsgwz4w.js} +1045 -581
  43. package/dist/{cli-rqz8qbw7.js → cli-a8dvhzrt.js} +59 -20
  44. package/dist/{cli-j57qkrpq.js → cli-azhgzetg.js} +395 -56
  45. package/dist/cli-br0qdrnp.js +2150 -0
  46. package/dist/{cli-rj19hc34.js → cli-btfv8y88.js} +1 -1
  47. package/dist/{cli-8qmme6vd.js → cli-c8a36vcc.js} +2 -2
  48. package/dist/cli-cpvsaqsw.js +333 -0
  49. package/dist/cli-d5czme6m.js +17805 -0
  50. package/dist/{cli-h38x0qhg.js → cli-et8m9xsv.js} +4 -3
  51. package/dist/{cli-x24pshtq.js → cli-evvtk35y.js} +6 -6
  52. package/dist/{cli-7s3syk22.js → cli-f8gy6r2r.js} +5 -5
  53. package/dist/{cli-zt1227k1.js → cli-fkqhbg8g.js} +5 -3
  54. package/dist/{cli-9httdpyq.js → cli-g2whhdrf.js} +1 -1
  55. package/dist/cli-gt4hxb8p.js +99 -0
  56. package/dist/{cli-s8eet254.js → cli-jajnsm8q.js} +37184 -53838
  57. package/dist/{cli-7gtvvpbh.js → cli-jayjpjmb.js} +21 -12
  58. package/dist/{cli-68w09sjw.js → cli-jyk0ynw2.js} +27 -89
  59. package/dist/{cli-aehm1rbq.js → cli-jz4w45qt.js} +1152 -61
  60. package/dist/cli-kmcpfwn2.js +333856 -0
  61. package/dist/{cli-4198qc9v.js → cli-ktmyrtpn.js} +19 -3
  62. package/dist/{cli-j55n64b6.js → cli-mfe5btp9.js} +505 -189
  63. package/dist/{cli-q67y4wzm.js → cli-phsaj4xq.js} +24 -2
  64. package/dist/{cli-1hkrch3k.js → cli-pm1rst0h.js} +46 -7
  65. package/dist/{cli-pw9rj5t9.js → cli-pqetb83f.js} +1 -176
  66. package/dist/{cli-ggm92wcn.js → cli-ptr8h7kp.js} +20 -1
  67. package/dist/{cli-s8s499xy.js → cli-qbksc292.js} +3 -2
  68. package/dist/{cli-47m6dkd3.js → cli-qydf22qq.js} +597 -346
  69. package/dist/{cli-3gmcwfyx.js → cli-r1mxd1xh.js} +13 -6
  70. package/dist/cli-rb9m6rpe.js +4980 -0
  71. package/dist/cli-rykfmgwg.js +102 -0
  72. package/dist/{cli-5d10vd2m.js → cli-shkxm1vn.js} +6 -5
  73. package/dist/{cli-eetrvv91.js → cli-t3p77qk1.js} +1 -1
  74. package/dist/cli-tfky2838.js +756 -0
  75. package/dist/{cli-g8djp6qe.js → cli-tmqt7dpj.js} +40 -0
  76. package/dist/{cli-fgqxwrpv.js → cli-tpq83z89.js} +1631 -127
  77. package/dist/cli-trc24wk2.js +143 -0
  78. package/dist/{cli-aky8tctm.js → cli-tzx2ke1v.js} +3 -3
  79. package/dist/cli-v7fn5gms.js +1425 -0
  80. package/dist/{cli-wscdvcqz.js → cli-vctdqs5h.js} +1 -1
  81. package/dist/{cli-cw9zck8j.js → cli-xjcywfsf.js} +8 -4
  82. package/dist/{cli-k0g1sjzm.js → cli-ybgv4kw2.js} +18 -11
  83. package/dist/{cli-rjehvrts.js → cli-ydmcgve1.js} +8 -8
  84. package/dist/{cli-vhjwh6cz.js → cli-ygwm91nt.js} +1 -1
  85. package/dist/{cli-mcnhgnn1.js → cli-ykk5jaax.js} +184 -26
  86. package/dist/{cli-de1396j2.js → cli-ywybs5as.js} +7 -1
  87. package/dist/cli-zpep9q5e.js +491 -0
  88. package/dist/cli.js +41 -32
  89. package/dist/cloudflare-workers-ai-system-one-k6fbxw9d.js +46 -0
  90. package/dist/{codex-adapter-cnm8wk11.js → codex-adapter-nmxcatww.js} +26 -17
  91. package/dist/{codex-hook-9hptmdhj.js → codex-hook-20me6byw.js} +2 -2
  92. package/dist/{codex-login-x3jk4etn.js → codex-login-w6fz4xbz.js} +50 -5
  93. package/dist/{codex-session-runner-gfg547zj.js → codex-session-runner-90aa80ev.js} +24 -17
  94. package/dist/{commands-e3bn0p75.js → commands-8wcq1kn7.js} +11 -9
  95. package/dist/{db-03v9kzr2.js → db-j40kc4se.js} +25 -11
  96. package/dist/{devin-adapter-8vgkwh29.js → devin-adapter-dpsv6hd9.js} +1 -1
  97. package/dist/{dispatcher-nrmg8yht.js → dispatcher-4zqy768d.js} +34 -29
  98. package/dist/{dsh-adapter-k03nfqa6.js → dsh-adapter-mpnzgztj.js} +3 -3
  99. package/dist/{e2b-93x1k0j5.js → e2b-ez07znam.js} +4 -3
  100. package/dist/execute-6e7qeyk4.js +1017 -0
  101. package/dist/{google-generative-ai-bxmv50nc.js → google-generative-ai-k6n5nbpp.js} +6 -5
  102. package/dist/{google-vertex-809af514.js → google-vertex-44xxtcvp.js} +6 -5
  103. package/dist/{handlers-aqcedbyb.js → handlers-kjdce1w5.js} +37 -32
  104. package/dist/{hook-ybvmrmhq.js → hook-czx13n12.js} +19 -15
  105. package/dist/{hook-7vkskkre.js → hook-r2t4bqfg.js} +18 -14
  106. package/dist/{http-2eqa8t24.js → http-3bbb19be.js} +900 -145
  107. package/dist/{index-f6cryxwe.js → index-4a5njnm1.js} +2 -59
  108. package/dist/{index-x71bvq0p.js → index-668me3f0.js} +35 -30
  109. package/dist/{index-c6zsv1bd.js → index-7aj368tw.js} +13 -12
  110. package/dist/{index-1yks3qcr.js → index-fg0dsp6c.js} +34 -29
  111. package/dist/{index-chgdkq36.js → index-kkv84jq9.js} +34 -29
  112. package/dist/{index-a3vn96n8.js → index-zg7vp46x.js} +198 -54
  113. package/dist/{keepalive-vtkf5n99.js → keepalive-yra8dy57.js} +13 -11
  114. package/dist/{lead-h3sp357x.js → lead-va0pad2c.js} +54 -49
  115. package/dist/llama-cpp-classify-tgj35k8d.js +335 -0
  116. package/dist/{maintenance-jzeqtk3q.js → maintenance-hqewtmyg.js} +14 -13
  117. package/dist/{mistral-conversations-zx0kn554.js → mistral-conversations-pc3ntnxt.js} +14 -17
  118. package/dist/{oauth-refresh-sweep-qp3dzmdp.js → oauth-refresh-sweep-7rdt1m9n.js} +12 -10
  119. package/dist/{onboard-tmsp0qbz.js → onboard-j6ms6d0x.js} +6 -5
  120. package/dist/{openai-codex-responses-4vjqzvjp.js → openai-codex-responses-bbancrr0.js} +21 -8
  121. package/dist/{openai-completions-9hjrqbw8.js → openai-completions-jpaj5g2b.js} +9 -12
  122. package/dist/{openai-responses-7b1pn0xt.js → openai-responses-200k1wx4.js} +23 -18
  123. package/dist/{opencode-adapter-x6x2da1z.js → opencode-adapter-89rabkw2.js} +8 -7
  124. package/dist/{openrouter-images-9f9ek4rw.js → openrouter-images-8yx3487g.js} +5 -7
  125. package/dist/{otel-impl-9mz73q65.js → otel-impl-a792rjz0.js} +1 -1
  126. package/dist/{pi-messages-txpjj39q.js → pi-messages-vxdt8v7j.js} +2 -1
  127. package/dist/{pi-mono-adapter-m6dvv0dz.js → pi-mono-adapter-g7qzvr3v.js} +295 -70
  128. package/dist/pricing-refresh-wx0tp7cb.js +39 -0
  129. package/dist/quickjs-r1pq2107.wasm +0 -0
  130. package/dist/{rbac-roles-c9wqz83x.js → rbac-roles-8tzawacv.js} +12 -10
  131. package/dist/{render-v2-gryrh9h8.js → render-v2-mm7zswb8.js} +12 -10
  132. package/dist/runtime-zyssgse0.js +24 -0
  133. package/dist/{setup-q9720bt6.js → setup-8y70ys6t.js} +6 -5
  134. package/dist/typesafe-system-one-2ef30pec.js +27 -0
  135. package/dist/{virtual-modules-3htpgn8x.js → virtual-modules-6nmk7h3n.js} +22 -13
  136. package/dist/{work-objects-b76x7deb.js → work-objects-fg6xkb0n.js} +37 -32
  137. package/dist/{worker-6vrxbv41.js → worker-wmwhxsph.js} +54 -49
  138. package/openapi.json +1314 -91
  139. package/package.json +12 -11
  140. package/src/be/db/agents.ts +20 -0
  141. package/src/be/db/api-keys.ts +70 -0
  142. package/src/be/db/tasks/human-free.ts +442 -0
  143. package/src/be/db/tasks/read.ts +56 -1
  144. package/src/be/db/tasks/write.ts +107 -11
  145. package/src/be/db.ts +274 -188
  146. package/src/be/harness-model-support.ts +182 -0
  147. package/src/be/human-free-drain.ts +67 -0
  148. package/src/be/memory/providers/sqlite-store.ts +51 -15
  149. package/src/be/migrations/182_task_human_free_flag.sql +63 -0
  150. package/src/be/migrations/183_human_free_reclassify_queue.sql +25 -0
  151. package/src/be/migrations/184_model_catalog.sql +120 -0
  152. package/src/be/migrations/185_api_key_auth_failures.sql +6 -0
  153. package/src/be/migrations/186_api_key_seat_mismatch.sql +8 -0
  154. package/src/be/model-catalog-store.ts +644 -0
  155. package/src/be/model-tier-keys.ts +46 -0
  156. package/src/be/model-tier-resolution.ts +534 -0
  157. package/src/be/model-validation.ts +188 -0
  158. package/src/be/models-catalog.ts +61 -7
  159. package/src/be/modelsdev-cache.json +82 -0
  160. package/src/be/modelsdev-cache.ts +2 -0
  161. package/src/be/pricing-refresh.ts +154 -12
  162. package/src/be/scripts/typecheck.ts +15 -0
  163. package/src/be/seed/runner.ts +18 -12
  164. package/src/be/seed/types.ts +1 -0
  165. package/src/be/seed-scripts/catalog/task-failure-audit.ts +61 -9
  166. package/src/be/swarm-config-guard.ts +8 -0
  167. package/src/cli.tsx +10 -0
  168. package/src/commands/claude-managed-setup.ts +3 -1
  169. package/src/commands/codex-login.ts +67 -0
  170. package/src/commands/credential-outcome-report.ts +191 -0
  171. package/src/commands/rate-limit-outcome.ts +34 -4
  172. package/src/commands/runner.ts +357 -186
  173. package/src/commands/seat-mismatch-report.ts +46 -0
  174. package/src/extensions/apply-task-create.ts +27 -1
  175. package/src/extensions/contract-types.generated.ts +1 -1
  176. package/src/heartbeat/heartbeat.ts +79 -17
  177. package/src/heartbeat/templates.ts +2 -2
  178. package/src/http/agents.ts +62 -1
  179. package/src/http/api-keys.ts +140 -2
  180. package/src/http/codex-oauth-keep-warm.ts +3 -5
  181. package/src/http/index.ts +8 -0
  182. package/src/http/memory.ts +12 -5
  183. package/src/http/models-catalog.ts +357 -8
  184. package/src/http/poll.ts +54 -3
  185. package/src/http/schedules.ts +51 -6
  186. package/src/http/script-runs.ts +12 -0
  187. package/src/http/session-data.ts +2 -5
  188. package/src/http/stats.ts +6 -8
  189. package/src/http/status.ts +15 -1
  190. package/src/http/tasks.ts +90 -7
  191. package/src/http/usage-cache.ts +56 -15
  192. package/src/http/workflows.ts +46 -8
  193. package/src/mcp-client/http-client.ts +5 -0
  194. package/src/memory/recall-query.ts +74 -0
  195. package/src/prompts/base-prompt.ts +15 -4
  196. package/src/prompts/session-templates.ts +23 -1
  197. package/src/providers/acp-adapter.ts +1 -0
  198. package/src/providers/claude-adapter.ts +14 -5
  199. package/src/providers/claude-managed-adapter.ts +1 -0
  200. package/src/providers/claude-managed-models.ts +47 -161
  201. package/src/providers/claude-sdk-session.ts +3 -1
  202. package/src/providers/codex-adapter.ts +14 -14
  203. package/src/providers/codex-models.ts +65 -198
  204. package/src/providers/devin-adapter.ts +1 -0
  205. package/src/providers/dsh-adapter.ts +2 -1
  206. package/src/providers/harness-version.ts +83 -7
  207. package/src/providers/opencode-adapter.ts +53 -1
  208. package/src/providers/pi-binary-root/src/extensions/codemode/worker.ts +11 -0
  209. package/src/providers/pi-codemode-runtime.ts +17 -0
  210. package/src/providers/pi-mono-adapter.ts +361 -83
  211. package/src/providers/pi-mono-extension.ts +16 -1
  212. package/src/providers/reasoning-effort.ts +44 -140
  213. package/src/providers/types.ts +8 -0
  214. package/src/rbac/legacy-policy.ts +43 -0
  215. package/src/rbac/permissions.ts +15 -0
  216. package/src/scripts-runtime/sdk-allowlist.ts +4 -0
  217. package/src/scripts-runtime/types/stdlib.d.ts +15 -0
  218. package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
  219. package/src/scripts-runtime/types/swarm-sdk.d.ts +15 -0
  220. package/src/server.ts +6 -0
  221. package/src/slack/assistant.ts +13 -0
  222. package/src/slack/message-text.ts +56 -2
  223. package/src/slack/render-v2.ts +87 -37
  224. package/src/slack/session-status.ts +541 -0
  225. package/src/slack/thread-buffer.ts +10 -2
  226. package/src/tasks/sibling-awareness.ts +3 -2
  227. package/src/telemetry.ts +5 -4
  228. package/src/templates.d.ts +6 -0
  229. package/src/tests/agents-list-model-display.test.ts +4 -6
  230. package/src/tests/api-key-auth-failure-route.test.ts +142 -0
  231. package/src/tests/api-key-tracking.test.ts +368 -1
  232. package/src/tests/base-prompt.test.ts +43 -2
  233. package/src/tests/claude-adapter.test.ts +68 -0
  234. package/src/tests/claude-managed-adapter.test.ts +12 -18
  235. package/src/tests/codex-adapter.test.ts +2 -1
  236. package/src/tests/codex-auth-failure.test.ts +52 -0
  237. package/src/tests/codex-gpt6-release.test.ts +66 -5
  238. package/src/tests/codex-login.test.ts +116 -0
  239. package/src/tests/context-window.test.ts +7 -5
  240. package/src/tests/credential-exhaustion-policy.test.ts +118 -3
  241. package/src/tests/credential-outcome-report.test.ts +171 -0
  242. package/src/tests/credential-status-api.test.ts +103 -2
  243. package/src/tests/db-extraction-contract.test.ts +1 -0
  244. package/src/tests/db-task-read-contract.test.ts +10 -1
  245. package/src/tests/db-task-write-contract.test.ts +535 -2
  246. package/src/tests/docs-index-footprint.test.js +3 -3
  247. package/src/tests/dokploy-deploy.test.ts +315 -0
  248. package/src/tests/dsh-adapter.test.ts +1 -1
  249. package/src/tests/explicit-model-validation.test.ts +583 -0
  250. package/src/tests/extensions-pre-task.test.ts +73 -0
  251. package/src/tests/fetch-resolved-env.test.ts +46 -0
  252. package/src/tests/hang-watchdog-worker.ts +47 -0
  253. package/src/tests/hang-watchdog.test.ts +45 -0
  254. package/src/tests/hang-watchdog.ts +30 -0
  255. package/src/tests/harness-model-guard.test.ts +123 -0
  256. package/src/tests/harness-model-support.test.ts +374 -0
  257. package/src/tests/harness-version.test.ts +70 -3
  258. package/src/tests/heartbeat-checklist-config.test.ts +71 -0
  259. package/src/tests/heartbeat-checklist.test.ts +4 -2
  260. package/src/tests/heartbeat-orphan-resume.test.ts +48 -0
  261. package/src/tests/http-task-write-ownership.test.ts +172 -0
  262. package/src/tests/human-free-flag.test.ts +279 -0
  263. package/src/tests/human-free-oracle.ts +57 -0
  264. package/src/tests/human-free-reclassify.test.ts +669 -0
  265. package/src/tests/memory-fts-populate.test.ts +139 -0
  266. package/src/tests/memory-http-recall-gating.test.ts +125 -1
  267. package/src/tests/migration-046-budgets.test.ts +3 -3
  268. package/src/tests/model-catalog-migration.test.ts +134 -0
  269. package/src/tests/model-catalog-table.test.ts +249 -0
  270. package/src/tests/model-catalog-write-access.test.ts +387 -0
  271. package/src/tests/model-rate-limit-windows.test.ts +19 -0
  272. package/src/tests/model-tier-resolution.test.ts +611 -0
  273. package/src/tests/models-catalog.test.ts +1 -1
  274. package/src/tests/multi-runtime-enabled-stats.test.ts +65 -1
  275. package/src/tests/opencode-adapter.test.ts +157 -2
  276. package/src/tests/package-publish.test.ts +137 -36
  277. package/src/tests/pi-codemode.test.ts +246 -0
  278. package/src/tests/pi-mono-adapter.test.ts +3 -0
  279. package/src/tests/pi-native-mcp.test.ts +193 -0
  280. package/src/tests/pi-tool-exposure.test.ts +374 -0
  281. package/src/tests/preload.ts +3 -0
  282. package/src/tests/pricing-routes.test.ts +2 -2
  283. package/src/tests/prompt-template-session.test.ts +5 -3
  284. package/src/tests/rate-limit-event.test.ts +65 -0
  285. package/src/tests/rate-limit-outcome.test.ts +90 -0
  286. package/src/tests/rbac-engine.test.ts +77 -3
  287. package/src/tests/reasoning-effort.test.ts +109 -0
  288. package/src/tests/refresh-modelsdev-carryforward.test.ts +5 -5
  289. package/src/tests/runner-key-completion-outcome.test.ts +112 -0
  290. package/src/tests/runner-key-outcome-late-reset.test.ts +224 -0
  291. package/src/tests/runner-registration-retry.test.ts +149 -0
  292. package/src/tests/runtime-model-catalog.test.ts +86 -0
  293. package/src/tests/script-connections.test.ts +9 -0
  294. package/src/tests/seat-mismatch-report.test.ts +85 -0
  295. package/src/tests/seed-scripts.test.ts +138 -0
  296. package/src/tests/seed.test.ts +25 -0
  297. package/src/tests/session-costs.test.ts +14 -11
  298. package/src/tests/slack-message-text.test.ts +101 -0
  299. package/src/tests/slack-render-v2.test.ts +96 -0
  300. package/src/tests/slack-session-status.test.ts +626 -0
  301. package/src/tests/slack-thread-buffer-context.test.ts +93 -0
  302. package/src/tests/status.test.ts +29 -0
  303. package/src/tests/steering-promotion.test.ts +51 -0
  304. package/src/tests/store-progress-ownership.test.ts +136 -0
  305. package/src/tests/subscription-plans.test.ts +28 -0
  306. package/src/tests/task-cascade-fail.test.ts +148 -2
  307. package/src/tests/task-citations.test.ts +3 -2
  308. package/src/tests/tool-annotations.test.ts +1 -1
  309. package/src/tests/usage-cache.test.ts +166 -0
  310. package/src/tests/workflow-agent-task.test.ts +30 -0
  311. package/src/tests/workflow-executors.test.ts +5 -2
  312. package/src/tests/workflow-system-one-decision-review.test.ts +1021 -0
  313. package/src/tests/workflow-system-one-decision-save-warnings.test.ts +365 -0
  314. package/src/tests/workflow-system-one-decision.test.ts +2063 -0
  315. package/src/tests/workflow-triggers-v2.test.ts +320 -0
  316. package/src/tools/model-catalog/index.ts +137 -0
  317. package/src/tools/schedules/create-schedule.ts +17 -2
  318. package/src/tools/schedules/patch-schedule.ts +31 -1
  319. package/src/tools/schedules/update-schedule.ts +31 -1
  320. package/src/tools/send-task.ts +18 -1
  321. package/src/tools/store-progress.ts +49 -4
  322. package/src/tools/task-action.ts +14 -1
  323. package/src/tools/tool-config.ts +3 -1
  324. package/src/tools/workflows/create-workflow.ts +17 -4
  325. package/src/tools/workflows/patch-workflow-node.ts +17 -7
  326. package/src/tools/workflows/patch-workflow.ts +9 -2
  327. package/src/tools/workflows/update-workflow.ts +17 -4
  328. package/src/types.ts +41 -1
  329. package/src/utils/codex-auth-failure.ts +34 -0
  330. package/src/utils/context-window.ts +47 -53
  331. package/src/utils/credentials.ts +72 -30
  332. package/src/utils/error-tracker.ts +80 -0
  333. package/src/utils/harness-cli-version.ts +115 -0
  334. package/src/utils/harness-model-error.ts +33 -0
  335. package/src/utils/model-rate-limit-windows.ts +12 -0
  336. package/src/utils/runtime-model-catalog.ts +152 -0
  337. package/src/utils/spawn-model-guard.ts +43 -0
  338. package/src/utils/subscription-plans.ts +22 -0
  339. package/src/workflows/approval-resolution.ts +39 -0
  340. package/src/workflows/definition.ts +7 -0
  341. package/src/workflows/engine.ts +69 -1
  342. package/src/workflows/executors/agent-task.ts +16 -6
  343. package/src/workflows/executors/base.ts +53 -0
  344. package/src/workflows/executors/human-in-the-loop.ts +8 -8
  345. package/src/workflows/executors/index.ts +1 -0
  346. package/src/workflows/executors/registry.ts +2 -0
  347. package/src/workflows/executors/system-one-decision.ts +1232 -0
  348. package/src/workflows/executors/system-one-providers.ts +301 -0
  349. package/src/workflows/executors/workflow-llm.ts +13 -1
  350. package/src/workflows/model-validation.ts +45 -0
  351. package/src/workflows/patch-definition.ts +5 -0
  352. package/src/workflows/readiness.ts +86 -0
  353. package/src/workflows/recovery.ts +12 -12
  354. package/src/workflows/resume.ts +23 -9
  355. package/src/workflows/triggers.ts +85 -0
  356. package/templates/schedules/daily-blocker-digest/content.md +4 -5
  357. package/templates/skills/agent-browser/SKILL.md +6 -5
  358. package/templates/skills/agent-browser/content.md +6 -5
  359. package/templates/skills/heartbeat-runbook/config.json +1 -1
  360. package/templates/skills/heartbeat-runbook/content.md +2 -2
  361. package/templates/skills/swarm-scripts/SKILL.md +1 -1
  362. package/templates/skills/swarm-scripts/content.md +1 -1
  363. package/templates/skills/workflow-iterate/content.md +82 -1
  364. package/templates/workflows/claude-code-changelog-watch/content.md +2 -0
  365. package/templates/workflows/pr-review-status-sweep/content.md +2 -0
  366. package/dist/boot-seeds-s3q01xj3.js +0 -26
  367. package/dist/claude-sdk-session-t442qz6f.js +0 -39108
  368. package/dist/cli-0xjkj1j7.js +0 -61
  369. package/dist/cli-20cj37vt.js +0 -335561
  370. package/dist/cli-2djtr51b.js +0 -48
  371. package/dist/cli-65hjmev5.js +0 -1141
  372. package/dist/cli-aw1jwp1r.js +0 -14075
  373. package/dist/cli-h967nb6r.js +0 -6603
  374. package/dist/cli-vapyk8sw.js +0 -20
  375. package/dist/cli-ws6rqycm.js +0 -247
  376. package/dist/pricing-refresh-v1cbr9te.js +0 -27
  377. package/src/providers/modelsdev-reasoning.json +0 -6453
  378. package/dist/{index-f24115ge.js → index-2wsdsnmm.js} +3 -3
@@ -45,6 +45,8 @@ import {
45
45
  init_reaction_shortcode,
46
46
  isPendingSlackMessage,
47
47
  isSettledSlackMessage,
48
+ isSlackThreadAwaitingHuman,
49
+ listSlackThreadsAwaitingHuman,
48
50
  markFinalizedSlackRelaysDelivered,
49
51
  markSlackDeferralResolved,
50
52
  markSlackRelayAttempted,
@@ -57,19 +59,19 @@ import {
57
59
  setSlackMessageTracking,
58
60
  slackContextKey,
59
61
  updateSlackMessageRecord
60
- } from "./cli-47m6dkd3.js";
62
+ } from "./cli-qydf22qq.js";
61
63
  import {
62
64
  init_types,
63
65
  isTerminalTaskStatus
64
- } from "./cli-4198qc9v.js";
65
- import {
66
- getAppUrl,
67
- init_constants
68
- } from "./cli-dv6cdjs2.js";
66
+ } from "./cli-ktmyrtpn.js";
69
67
  import {
70
68
  getSlackConfiguration,
71
69
  init_config
72
70
  } from "./cli-n7h1kqpf.js";
71
+ import {
72
+ getAppUrl,
73
+ init_constants
74
+ } from "./cli-dv6cdjs2.js";
73
75
  import {
74
76
  init_env_flag,
75
77
  isEnvFlagEnabled
@@ -52904,7 +52906,7 @@ async function initOtel(serviceRole = process.env.AGENT_ROLE || "api") {
52904
52906
  return;
52905
52907
  initialized = true;
52906
52908
  try {
52907
- const impl = await import("./otel-impl-9mz73q65.js");
52909
+ const impl = await import("./otel-impl-a792rjz0.js");
52908
52910
  await impl.boot(serviceRole, {
52909
52911
  exportConsoleLogs: serviceRole === "api" && isApiLogExportEnabled()
52910
52912
  });
@@ -54341,15 +54343,15 @@ async function initSlackApp() {
54341
54343
  ...clientOptions ? { clientOptions } : {}
54342
54344
  });
54343
54345
  initialized2 = true;
54344
- const { registerMessageHandler } = await import("./handlers-aqcedbyb.js");
54345
- const { registerCommandHandler } = await import("./commands-e3bn0p75.js");
54346
- const { registerActionHandlers } = await import("./actions-p9hz5yat.js");
54347
- const { registerWorkObjectHandlers } = await import("./work-objects-b76x7deb.js");
54346
+ const { registerMessageHandler } = await import("./handlers-kjdce1w5.js");
54347
+ const { registerCommandHandler } = await import("./commands-8wcq1kn7.js");
54348
+ const { registerActionHandlers } = await import("./actions-e43rxskr.js");
54349
+ const { registerWorkObjectHandlers } = await import("./work-objects-fg6xkb0n.js");
54348
54350
  registerMessageHandler(app);
54349
54351
  registerCommandHandler(app);
54350
54352
  registerActionHandlers(app);
54351
54353
  registerWorkObjectHandlers(app);
54352
- const { createAssistant } = await import("./assistant-wydfqkb3.js");
54354
+ const { createAssistant } = await import("./assistant-sedkzv3b.js");
54353
54355
  app.assistant(createAssistant());
54354
54356
  return app;
54355
54357
  }
@@ -54358,7 +54360,7 @@ async function startSlackApp() {
54358
54360
  await initSlackApp();
54359
54361
  }
54360
54362
  if (app) {
54361
- const { isSlackRenderV2Enabled: isSlackRenderV2Enabled2 } = await import("./render-v2-gryrh9h8.js");
54363
+ const { isSlackRenderV2Enabled: isSlackRenderV2Enabled2 } = await import("./render-v2-mm7zswb8.js");
54362
54364
  if (isSlackRenderV2Enabled2())
54363
54365
  await ensureSlackRenderV2Activation();
54364
54366
  await app.start();
@@ -54540,6 +54542,334 @@ function closureState(ask, closure, now, settleSec, timeoutMin) {
54540
54542
 
54541
54543
  // src/slack/render-v2.ts
54542
54544
  init_reaction_shortcode();
54545
+
54546
+ // src/slack/session-status.ts
54547
+ init_db();
54548
+ init_types();
54549
+ init_secret_scrubber();
54550
+ var import_bolt2 = __toESM(require_dist7(), 1);
54551
+ var REFRESH_MS = 30 * 60000;
54552
+ var DEFAULT_CALL_TIMEOUT_MS = 8000;
54553
+ var TRANSPORT_MARGIN_MS = 500;
54554
+ var callTimeoutMs = DEFAULT_CALL_TIMEOUT_MS;
54555
+ var RETRY_BASE_MS = 30000;
54556
+ var RETRY_MAX_MS = 10 * 60000;
54557
+ var UNAVAILABLE_COOLDOWN_MS = 60 * 60000;
54558
+ var CALLS_PER_TICK = 8;
54559
+ var ORPHAN_GRACE_MS = 2 * 60000;
54560
+ var WORKSPACE_ERRORS = new Set([
54561
+ "missing_scope",
54562
+ "not_allowed_token_type",
54563
+ "feature_disabled",
54564
+ "not_authed",
54565
+ "invalid_auth",
54566
+ "account_inactive",
54567
+ "token_revoked",
54568
+ "token_expired",
54569
+ "access_denied",
54570
+ "no_permission",
54571
+ "accesslimited",
54572
+ "enterprise_is_restricted",
54573
+ "ekm_access_denied",
54574
+ "org_login_required",
54575
+ "method_deprecated",
54576
+ "deprecated_endpoint",
54577
+ "unknown_method"
54578
+ ]);
54579
+ var TRANSIENT_ERRORS = new Set([
54580
+ "ratelimited",
54581
+ "rate_limited",
54582
+ "internal_error",
54583
+ "service_unavailable",
54584
+ "fatal_error",
54585
+ "request_timeout"
54586
+ ]);
54587
+ var threads = new Map;
54588
+ var keyTails = new Map;
54589
+ var warned = new Set;
54590
+ var unavailableUntil = 0;
54591
+ function threadKey(channelId, threadTs) {
54592
+ return `${channelId}:${threadTs}`;
54593
+ }
54594
+ function splitKey(key) {
54595
+ const at = key.indexOf(":");
54596
+ return { channelId: key.slice(0, at), threadTs: key.slice(at + 1) };
54597
+ }
54598
+ function errorCode(error) {
54599
+ const code = error?.data?.error;
54600
+ return typeof code === "string" && code.length > 0 ? code : undefined;
54601
+ }
54602
+ function warnOnce(key, message) {
54603
+ if (warned.has(key))
54604
+ return;
54605
+ warned.add(key);
54606
+ console.warn(scrubSecrets(`[Slack] ${message}`));
54607
+ }
54608
+
54609
+ class CallTimeoutError extends Error {
54610
+ constructor(ms) {
54611
+ super(`timed out after ${ms}ms`);
54612
+ this.name = "CallTimeoutError";
54613
+ }
54614
+ }
54615
+ function withTimeout(promise, ms) {
54616
+ let timer;
54617
+ const timeout = new Promise((_, reject) => {
54618
+ timer = setTimeout(() => reject(new CallTimeoutError(ms)), ms);
54619
+ });
54620
+ return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
54621
+ }
54622
+ var transports = new WeakMap;
54623
+ function statusTransport(client) {
54624
+ if (!(client instanceof import_bolt2.webApi.WebClient))
54625
+ return client;
54626
+ let transport = transports.get(client);
54627
+ if (!transport) {
54628
+ const timeout = Math.max(callTimeoutMs - TRANSPORT_MARGIN_MS, 1);
54629
+ transport = new import_bolt2.webApi.WebClient(client.token ?? process.env.SLACK_BOT_TOKEN, {
54630
+ slackApiUrl: client.slackApiUrl,
54631
+ retryConfig: { retries: 0 },
54632
+ rejectRateLimitedCalls: true,
54633
+ timeout,
54634
+ requestInterceptor: (config) => ({ ...config, signal: AbortSignal.timeout(timeout) })
54635
+ });
54636
+ transports.set(client, transport);
54637
+ }
54638
+ return transport;
54639
+ }
54640
+ function withThreadLock(key, fn) {
54641
+ const run = (keyTails.get(key) ?? Promise.resolve()).then(fn);
54642
+ const tail = run.catch(() => {
54643
+ return;
54644
+ });
54645
+ keyTails.set(key, tail);
54646
+ tail.then(() => {
54647
+ if (keyTails.get(key) === tail)
54648
+ keyTails.delete(key);
54649
+ });
54650
+ return run;
54651
+ }
54652
+ function decideSlackSessionStatus(tasks, awaitingHuman) {
54653
+ if (tasks.some((task) => !isTerminalTaskStatus(task.status)))
54654
+ return "processing";
54655
+ return awaitingHuman ? "suspended" : "active";
54656
+ }
54657
+ async function desiredStatus(channelId, threadTs) {
54658
+ const tasks = await getSlackTasksInThread(channelId, threadTs);
54659
+ const running = tasks.some((task) => !isTerminalTaskStatus(task.status));
54660
+ const awaitingHuman = running ? false : await isSlackThreadAwaitingHuman(channelId, threadTs);
54661
+ return decideSlackSessionStatus(tasks, awaitingHuman);
54662
+ }
54663
+ function classify(error) {
54664
+ const code = errorCode(error);
54665
+ if (!code)
54666
+ return { kind: "transient", code: "no_slack_verdict" };
54667
+ if (WORKSPACE_ERRORS.has(code))
54668
+ return { kind: "unavailable", code };
54669
+ if (TRANSIENT_ERRORS.has(code))
54670
+ return { kind: "transient", code };
54671
+ return { kind: "refused", code };
54672
+ }
54673
+ function retryAfterMs(error) {
54674
+ const seconds = error?.retryAfter;
54675
+ return typeof seconds === "number" && seconds > 0 ? seconds * 1000 : undefined;
54676
+ }
54677
+ async function applyStatus(client, channelId, threadTs, desired, budget) {
54678
+ const key = threadKey(channelId, threadTs);
54679
+ const now = Date.now();
54680
+ const entry = threads.get(key);
54681
+ if (now < unavailableUntil || entry?.refused) {
54682
+ if (desired === "active")
54683
+ threads.delete(key);
54684
+ return "unavailable";
54685
+ }
54686
+ if (desired === "active") {
54687
+ if (!entry || entry.status === "active" && !entry.uncertain) {
54688
+ threads.delete(key);
54689
+ return "idle";
54690
+ }
54691
+ } else if (entry && entry.status === desired && !entry.uncertain && now - entry.setAt < REFRESH_MS) {
54692
+ return "current";
54693
+ }
54694
+ if (entry && now < entry.retryAt)
54695
+ return "unavailable";
54696
+ if (budget) {
54697
+ if (budget.remaining <= 0) {
54698
+ if (entry)
54699
+ threads.set(key, { ...entry, deferred: true });
54700
+ return "unavailable";
54701
+ }
54702
+ budget.remaining--;
54703
+ }
54704
+ const pending = statusTransport(client).apiCall("agents.sessions.setStatus", {
54705
+ channel_id: channelId,
54706
+ thread_ts: threadTs,
54707
+ status: desired
54708
+ });
54709
+ try {
54710
+ const result = await withTimeout(pending, callTimeoutMs);
54711
+ if (result?.ok === false)
54712
+ throw { data: { error: result.error ?? "unknown_error" } };
54713
+ } catch (error) {
54714
+ if (error instanceof CallTimeoutError) {
54715
+ pending.then((late) => {
54716
+ if (late?.ok !== false) {
54717
+ noteLateWrite(client, channelId, threadTs, desired);
54718
+ }
54719
+ }, () => {});
54720
+ }
54721
+ const failure = classify(error);
54722
+ if (failure.kind === "unavailable") {
54723
+ unavailableUntil = now + UNAVAILABLE_COOLDOWN_MS;
54724
+ warnOnce(`unavailable:${failure.code}`, `Native session status is unavailable (${failure.code}). Keeping the reaction and tree message${failure.code === "missing_scope" ? "; the bot token needs the chat:write scope" : ""}. Will probe again in ${UNAVAILABLE_COOLDOWN_MS / 60000} min.`);
54725
+ } else if (failure.kind === "refused") {
54726
+ threads.set(key, {
54727
+ status: entry?.status ?? "active",
54728
+ setAt: entry?.setAt ?? 0,
54729
+ failures: 0,
54730
+ retryAt: 0,
54731
+ refused: true,
54732
+ uncertain: false
54733
+ });
54734
+ warnOnce(`refused:${failure.code}`, `Slack refused a session status for ${channelId}/${threadTs} (${failure.code}). Leaving that thread on the reaction and tree message.`);
54735
+ } else {
54736
+ const failures = (entry?.failures ?? 0) + 1;
54737
+ const backoff = Math.min(RETRY_BASE_MS * 2 ** (failures - 1), RETRY_MAX_MS);
54738
+ threads.set(key, {
54739
+ status: entry?.status ?? "active",
54740
+ setAt: entry?.setAt ?? 0,
54741
+ failures,
54742
+ retryAt: now + Math.max(backoff, retryAfterMs(error) ?? 0),
54743
+ refused: false,
54744
+ uncertain: true
54745
+ });
54746
+ warnOnce(`transient:${failure.code}`, `Setting the session status failed (${failure.code}); retrying with backoff.`);
54747
+ }
54748
+ return "unavailable";
54749
+ }
54750
+ if (desired === "active")
54751
+ threads.delete(key);
54752
+ else {
54753
+ threads.set(key, {
54754
+ status: desired,
54755
+ setAt: now,
54756
+ failures: 0,
54757
+ retryAt: 0,
54758
+ refused: false,
54759
+ uncertain: false
54760
+ });
54761
+ }
54762
+ return "applied";
54763
+ }
54764
+ async function noteLateWrite(client, channelId, threadTs, landed) {
54765
+ try {
54766
+ const key = threadKey(channelId, threadTs);
54767
+ await withThreadLock(key, async () => {
54768
+ if (landed === "active")
54769
+ threads.delete(key);
54770
+ else {
54771
+ threads.set(key, {
54772
+ status: landed,
54773
+ setAt: Date.now(),
54774
+ failures: 0,
54775
+ retryAt: 0,
54776
+ refused: false,
54777
+ uncertain: false
54778
+ });
54779
+ }
54780
+ });
54781
+ await reconcileSlackSessionStatus({ channelId, threadTs, client });
54782
+ } catch (error) {
54783
+ warnOnce("late-write", `Reconciling a late session status write failed: ${error instanceof Error ? error.message : String(error)}`);
54784
+ }
54785
+ }
54786
+ async function clearLegacyDmStatus(client, channelId, threadTs) {
54787
+ if (!channelId.startsWith("D"))
54788
+ return;
54789
+ try {
54790
+ await client.apiCall("assistant.threads.setStatus", {
54791
+ channel_id: channelId,
54792
+ thread_ts: threadTs,
54793
+ status: ""
54794
+ });
54795
+ } catch (error) {
54796
+ warnOnce("legacy-clear", `Failed to clear the assistant status for ${channelId}/${threadTs}: ${error instanceof Error ? error.message : String(error)}`);
54797
+ }
54798
+ }
54799
+ async function reconcileSlackSessionStatus(input) {
54800
+ try {
54801
+ const client = input.client ?? getSlackApp()?.client;
54802
+ if (!client)
54803
+ return;
54804
+ const { channelId, threadTs } = input;
54805
+ await withThreadLock(threadKey(channelId, threadTs), async () => {
54806
+ const desired = await desiredStatus(channelId, threadTs);
54807
+ const result = await applyStatus(client, channelId, threadTs, desired, input.budget);
54808
+ if (input.outcomeDelivered && result === "unavailable") {
54809
+ await clearLegacyDmStatus(client, channelId, threadTs);
54810
+ }
54811
+ });
54812
+ } catch (error) {
54813
+ warnOnce("reconcile", `Session status sync failed: ${error instanceof Error ? error.message : String(error)}`);
54814
+ }
54815
+ }
54816
+ async function markSlackSessionProcessing(input) {
54817
+ try {
54818
+ const client = input.client ?? getSlackApp()?.client;
54819
+ if (!client)
54820
+ return false;
54821
+ const { channelId, threadTs } = input;
54822
+ return await withThreadLock(threadKey(channelId, threadTs), async () => {
54823
+ const result = await applyStatus(client, channelId, threadTs, "processing");
54824
+ return result === "applied" || result === "current";
54825
+ });
54826
+ } catch {
54827
+ return false;
54828
+ }
54829
+ }
54830
+ function beginSlackStatusTick() {
54831
+ const budget = { remaining: CALLS_PER_TICK };
54832
+ const visited = new Set;
54833
+ return {
54834
+ budget,
54835
+ reconcile: async (channelId, threadTs) => {
54836
+ visited.add(threadKey(channelId, threadTs));
54837
+ await reconcileSlackSessionStatus({ channelId, threadTs, budget });
54838
+ },
54839
+ finish: async () => {
54840
+ try {
54841
+ const targets = new Map;
54842
+ const now = Date.now();
54843
+ for (const [key, entry] of threads) {
54844
+ const inGrace = entry.status === "processing" && !entry.uncertain && !entry.deferred && now - entry.setAt < ORPHAN_GRACE_MS;
54845
+ if (inGrace)
54846
+ continue;
54847
+ targets.set(key, splitKey(key));
54848
+ }
54849
+ for (const thread of await listSlackThreadsAwaitingHuman()) {
54850
+ targets.set(threadKey(thread.channelId, thread.threadTs), thread);
54851
+ }
54852
+ for (const [key, thread] of targets) {
54853
+ if (visited.has(key))
54854
+ continue;
54855
+ await reconcileSlackSessionStatus({ ...thread, budget });
54856
+ }
54857
+ } catch (error) {
54858
+ warnOnce("tick-finish", `Session status sweep failed: ${error instanceof Error ? error.message : String(error)}`);
54859
+ }
54860
+ }
54861
+ };
54862
+ }
54863
+ function _resetSlackSessionStatusForTests() {
54864
+ callTimeoutMs = DEFAULT_CALL_TIMEOUT_MS;
54865
+ transports = new WeakMap;
54866
+ threads.clear();
54867
+ keyTails.clear();
54868
+ warned.clear();
54869
+ unavailableUntil = 0;
54870
+ }
54871
+
54872
+ // src/slack/render-v2.ts
54543
54873
  var TREE_UPDATE_DEBOUNCE_MS = 500;
54544
54874
  var TREE_UPDATE_MIN_INTERVAL_MS = 3000;
54545
54875
  var MAX_SLACK_RETRIES = 3;
@@ -54603,7 +54933,7 @@ function outcomeDeliveryGate(taskId, card) {
54603
54933
  return false;
54604
54934
  return Date.now() >= (outcomeDeliveryNextAttemptAt.get(taskId) ?? 0);
54605
54935
  }
54606
- async function reconcileStuckOutcomeDelivery(task, card) {
54936
+ async function reconcileStuckOutcomeDelivery(task, card, statusBudget) {
54607
54937
  if (!card || card.deliveryAbandonedAt)
54608
54938
  return;
54609
54939
  if (card.deliveryAttempts < OUTCOME_DELIVERY_MAX_ATTEMPTS)
@@ -54614,16 +54944,16 @@ async function reconcileStuckOutcomeDelivery(task, card) {
54614
54944
  if (!abandoned)
54615
54945
  return;
54616
54946
  console.error(`[Slack] Recovered a stuck outcome delivery for task ${task.id} left at ` + `${card.deliveryAttempts} attempt(s) without a give-up; surfacing failure and clearing the working indicator`);
54617
- await surfaceOutcomeDeliveryGiveUp(task, lastError, card.deliveryAttempts);
54947
+ await surfaceOutcomeDeliveryGiveUp(task, lastError, card.deliveryAttempts, statusBudget);
54618
54948
  }
54619
- async function checkOutcomeDeliveryGate(task, card) {
54620
- await reconcileStuckOutcomeDelivery(task, card);
54949
+ async function checkOutcomeDeliveryGate(task, card, statusBudget) {
54950
+ await reconcileStuckOutcomeDelivery(task, card, statusBudget);
54621
54951
  return outcomeDeliveryGate(task.id, card);
54622
54952
  }
54623
54953
  function noteOutcomeDeliverySuccess(taskId) {
54624
54954
  outcomeDeliveryNextAttemptAt.delete(taskId);
54625
54955
  }
54626
- async function noteOutcomeDeliveryFailure(task, tree, error) {
54956
+ async function noteOutcomeDeliveryFailure(task, tree, error, statusBudget) {
54627
54957
  const detail = describeSlackError(error);
54628
54958
  const summary = scrubSecrets(slackErrorSummary(error));
54629
54959
  if (!task.slackChannelId || !task.slackThreadTs) {
@@ -54654,9 +54984,9 @@ async function noteOutcomeDeliveryFailure(task, tree, error) {
54654
54984
  if (!abandoned)
54655
54985
  return;
54656
54986
  console.error(`[Slack] Giving up on outcome delivery for task ${task.id} after ${attempts} attempt(s)` + `${terminal ? " (Slack refused the delivery)" : ""}; surfacing failure and clearing the working indicator`);
54657
- await surfaceOutcomeDeliveryGiveUp(task, summary, attempts);
54987
+ await surfaceOutcomeDeliveryGiveUp(task, summary, attempts, statusBudget);
54658
54988
  }
54659
- async function surfaceOutcomeDeliveryGiveUp(task, summary, attempts) {
54989
+ async function surfaceOutcomeDeliveryGiveUp(task, summary, attempts, statusBudget) {
54660
54990
  const app2 = getSlackApp();
54661
54991
  if (!app2 || !task.slackChannelId || !task.slackThreadTs)
54662
54992
  return;
@@ -54669,20 +54999,16 @@ async function surfaceOutcomeDeliveryGiveUp(task, summary, attempts) {
54669
54999
  } catch (postError) {
54670
55000
  console.error(`[Slack] Give-up notice failed to post for task ${task.id}:`, scrubSecrets(postError instanceof Error ? postError.message : String(postError)));
54671
55001
  }
54672
- await clearAssistantStatus(app2.client, task.slackChannelId, task.slackThreadTs);
55002
+ await clearAssistantStatus(app2.client, task.slackChannelId, task.slackThreadTs, statusBudget);
54673
55003
  }
54674
- async function clearAssistantStatus(client, channelId, threadTs) {
54675
- if (!channelId.startsWith("D"))
54676
- return;
54677
- try {
54678
- await client.apiCall("assistant.threads.setStatus", {
54679
- channel_id: channelId,
54680
- thread_ts: threadTs,
54681
- status: ""
54682
- });
54683
- } catch (error) {
54684
- console.warn(`[Slack] Failed to clear assistant status for ${channelId}/${threadTs}:`, error);
54685
- }
55004
+ async function clearAssistantStatus(client, channelId, threadTs, statusBudget) {
55005
+ await reconcileSlackSessionStatus({
55006
+ client,
55007
+ channelId,
55008
+ threadTs,
55009
+ budget: statusBudget,
55010
+ outcomeDelivered: true
55011
+ });
54686
55012
  }
54687
55013
  function slackTreeStallMinutes() {
54688
55014
  return Number(process.env.SLACK_TREE_STALL_MIN) || 15;
@@ -54996,10 +55322,15 @@ async function createThreadTree(task) {
54996
55322
  lastTreeUpdateAt.set(record.id, Date.now());
54997
55323
  return record;
54998
55324
  }
54999
- async function ensureSlackThreadTree(taskIds) {
55325
+ async function ensureSlackThreadTree(taskIds, statusBudget) {
55000
55326
  const task = (await Promise.all(taskIds.map(getTaskById))).find((candidate) => !!candidate);
55001
55327
  if (!task?.slackChannelId || !task.slackThreadTs)
55002
55328
  return null;
55329
+ await reconcileSlackSessionStatus({
55330
+ channelId: task.slackChannelId,
55331
+ threadTs: task.slackThreadTs,
55332
+ budget: statusBudget
55333
+ });
55003
55334
  const contextKey = task.contextKey ?? slackContextKey({
55004
55335
  channelId: task.slackChannelId,
55005
55336
  threadTs: task.slackThreadTs
@@ -55015,7 +55346,7 @@ async function ensureSlackThreadTree(taskIds) {
55015
55346
  if (!isSlackMessageNotFound(error))
55016
55347
  throw error;
55017
55348
  await discardTreeRecord(existing);
55018
- return ensureSlackThreadTree(taskIds);
55349
+ return ensureSlackThreadTree(taskIds, statusBudget);
55019
55350
  }
55020
55351
  }
55021
55352
  const creationKey = physicalThreadKey(task.slackChannelId, task.slackThreadTs);
@@ -55050,12 +55381,12 @@ async function withTreeUpdateLock(channelId, threadTs, work) {
55050
55381
  treeUpdateTails.delete(key);
55051
55382
  }
55052
55383
  }
55053
- async function replaceMissingTree(tree) {
55384
+ async function replaceMissingTree(tree, statusBudget) {
55054
55385
  await discardTreeRecord(tree);
55055
55386
  const taskIds = (await getSlackTasksInThread(tree.channelId, tree.threadTs)).map((task) => task.id);
55056
- return taskIds.length > 0 ? ensureSlackThreadTree(taskIds) : null;
55387
+ return taskIds.length > 0 ? ensureSlackThreadTree(taskIds, statusBudget) : null;
55057
55388
  }
55058
- async function updateThreadTree(tree, bypassThrottle = false) {
55389
+ async function updateThreadTree(tree, bypassThrottle = false, statusBudget) {
55059
55390
  const result = await withTreeUpdateLock(tree.channelId, tree.threadTs, async () => {
55060
55391
  const app2 = getSlackApp();
55061
55392
  if (!app2)
@@ -55101,7 +55432,7 @@ async function updateThreadTree(tree, bypassThrottle = false) {
55101
55432
  return "updated";
55102
55433
  });
55103
55434
  if (result === "missing") {
55104
- await replaceMissingTree(tree);
55435
+ await replaceMissingTree(tree, statusBudget);
55105
55436
  return false;
55106
55437
  }
55107
55438
  return result === "updated";
@@ -55454,7 +55785,7 @@ async function streamOutcomeCard(task, tree, options) {
55454
55785
  });
55455
55786
  }
55456
55787
  }
55457
- await clearAssistantStatus(app2.client, task.slackChannelId, task.slackThreadTs);
55788
+ await clearAssistantStatus(app2.client, task.slackChannelId, task.slackThreadTs, options?.statusBudget);
55458
55789
  const permalink = await resolvePermalink(app2.client, task.slackChannelId, outcome.ts);
55459
55790
  return await updateSlackMessageRecord(outcome.id, {
55460
55791
  permalink,
@@ -55553,13 +55884,14 @@ async function processSlackRenderV2() {
55553
55884
  const activatedAt = await ensureSlackRenderV2Activation();
55554
55885
  const delegationEnabled = isSlackDelegationEnabled();
55555
55886
  const delegationActivatedAt = delegationEnabled ? await ensureSlackDelegationActivation() : null;
55887
+ const statusTick = beginSlackStatusTick();
55556
55888
  for (const task of await getSlackTasksMissingTree()) {
55557
55889
  if (!isSlackRenderV2Enabled())
55558
55890
  return;
55559
55891
  if (!task.slackChannelId || !task.slackThreadTs)
55560
55892
  continue;
55561
55893
  try {
55562
- await ensureSlackThreadTree([task.id]);
55894
+ await ensureSlackThreadTree([task.id], statusTick.budget);
55563
55895
  } catch (error) {
55564
55896
  console.error(`[Slack] Failed to create v2 tree for task ${task.id}:`, error);
55565
55897
  }
@@ -55571,7 +55903,7 @@ async function processSlackRenderV2() {
55571
55903
  const initialTasks = await getSlackTasksInThread(tree.channelId, tree.threadTs);
55572
55904
  if (isPendingSlackMessage(tree)) {
55573
55905
  try {
55574
- const recovered = await ensureSlackThreadTree(initialTasks.map((task) => task.id));
55906
+ const recovered = await ensureSlackThreadTree(initialTasks.map((task) => task.id), statusTick.budget);
55575
55907
  if (!recovered)
55576
55908
  continue;
55577
55909
  tree = recovered;
@@ -55587,7 +55919,7 @@ async function processSlackRenderV2() {
55587
55919
  } catch (error) {
55588
55920
  if (isSlackMessageNotFound(error)) {
55589
55921
  try {
55590
- await replaceMissingTree(tree);
55922
+ await replaceMissingTree(tree, statusTick.budget);
55591
55923
  } catch (replacementError) {
55592
55924
  console.error(`[Slack] Failed to replace missing v2 tree ${tree.id}:`, replacementError);
55593
55925
  }
@@ -55619,7 +55951,7 @@ async function processSlackRenderV2() {
55619
55951
  continue;
55620
55952
  }
55621
55953
  try {
55622
- const replacement = await replaceMissingTree(tree);
55954
+ const replacement = await replaceMissingTree(tree, statusTick.budget);
55623
55955
  if (!replacement)
55624
55956
  continue;
55625
55957
  tree = replacement;
@@ -55680,10 +56012,13 @@ async function processSlackRenderV2() {
55680
56012
  continue;
55681
56013
  if (askId && await childCardCountFor(askId) >= CHILD_CARDS_PER_ASK)
55682
56014
  continue;
55683
- if (!await checkOutcomeDeliveryGate(task, card))
56015
+ if (!await checkOutcomeDeliveryGate(task, card, statusTick.budget))
55684
56016
  continue;
55685
56017
  try {
55686
- const outcome = await streamOutcomeCard(task, tree, { buildContent: childOutcomeContent });
56018
+ const outcome = await streamOutcomeCard(task, tree, {
56019
+ buildContent: childOutcomeContent,
56020
+ statusBudget: statusTick.budget
56021
+ });
55687
56022
  if (outcome) {
55688
56023
  noteOutcomeDeliverySuccess(task.id);
55689
56024
  childCardsThisTick++;
@@ -55693,7 +56028,7 @@ async function processSlackRenderV2() {
55693
56028
  }
55694
56029
  outcomeCreated ||= !!outcome;
55695
56030
  } catch (error) {
55696
- await noteOutcomeDeliveryFailure(task, tree, error);
56031
+ await noteOutcomeDeliveryFailure(task, tree, error, statusTick.budget);
55697
56032
  }
55698
56033
  }
55699
56034
  for (const task of tasks) {
@@ -55708,17 +56043,17 @@ async function processSlackRenderV2() {
55708
56043
  continue;
55709
56044
  const deferByClosure = task.source === "slack" && delegationEnabled && delegationActivatedAt !== null && task.createdAt >= delegationActivatedAt;
55710
56045
  if (!deferByClosure) {
55711
- if (!await checkOutcomeDeliveryGate(task, card))
56046
+ if (!await checkOutcomeDeliveryGate(task, card, statusTick.budget))
55712
56047
  continue;
55713
56048
  try {
55714
- const outcome = await streamOutcomeCard(task, tree);
56049
+ const outcome = await streamOutcomeCard(task, tree, { statusBudget: statusTick.budget });
55715
56050
  if (outcome) {
55716
56051
  noteOutcomeDeliverySuccess(task.id);
55717
56052
  await finalizeTerminalSlackReactions([task]);
55718
56053
  }
55719
56054
  outcomeCreated ||= !!outcome;
55720
56055
  } catch (error) {
55721
- await noteOutcomeDeliveryFailure(task, tree, error);
56056
+ await noteOutcomeDeliveryFailure(task, tree, error, statusTick.budget);
55722
56057
  }
55723
56058
  continue;
55724
56059
  }
@@ -55741,12 +56076,13 @@ async function processSlackRenderV2() {
55741
56076
  const state2 = closureState(task, closure, new Date, settleSec, timeoutMin);
55742
56077
  if (state2 === "open")
55743
56078
  continue;
55744
- if (!await checkOutcomeDeliveryGate(task, card))
56079
+ if (!await checkOutcomeDeliveryGate(task, card, statusTick.budget))
55745
56080
  continue;
55746
56081
  try {
55747
56082
  const outcome = await streamOutcomeCard(task, tree, {
55748
56083
  buildContent: (_t, slackReplySent) => askConclusionContent(task, closure, state2, slackReplySent),
55749
- conclusionKind: state2 === "timedOut" ? "timeout" : "complete"
56084
+ conclusionKind: state2 === "timedOut" ? "timeout" : "complete",
56085
+ statusBudget: statusTick.budget
55750
56086
  });
55751
56087
  if (outcome) {
55752
56088
  noteOutcomeDeliverySuccess(task.id);
@@ -55760,16 +56096,18 @@ async function processSlackRenderV2() {
55760
56096
  }
55761
56097
  outcomeCreated ||= !!outcome;
55762
56098
  } catch (error) {
55763
- await noteOutcomeDeliveryFailure(task, tree, error);
56099
+ await noteOutcomeDeliveryFailure(task, tree, error, statusTick.budget);
55764
56100
  }
55765
56101
  }
55766
56102
  try {
55767
- await updateThreadTree(tree, outcomeCreated);
56103
+ await updateThreadTree(tree, outcomeCreated, statusTick.budget);
55768
56104
  } catch (error) {
55769
56105
  console.error(`[Slack] Failed to update v2 tree ${tree.id}:`, error);
55770
56106
  }
56107
+ await statusTick.reconcile(tree.channelId, tree.threadTs);
55771
56108
  }
55772
56109
  await refreshResolvedDeferralCards();
56110
+ await statusTick.finish();
55773
56111
  }
55774
56112
  function _resetSlackRenderV2ForTests() {
55775
56113
  for (const timer of pendingTreeUpdates.values())
@@ -55782,7 +56120,8 @@ function _resetSlackRenderV2ForTests() {
55782
56120
  cachedTeamId = undefined;
55783
56121
  outcomeDeliveryNextAttemptAt.clear();
55784
56122
  outcomeReservedWithoutAttempt.clear();
56123
+ _resetSlackSessionStatusForTests();
55785
56124
  }
55786
- var _noteOutcomeDeliveryFailureForTests = noteOutcomeDeliveryFailure;
56125
+ var _noteOutcomeDeliveryFailureForTests = (task, tree, error) => noteOutcomeDeliveryFailure(task, tree, error, undefined);
55787
56126
 
55788
- export { initialize, ensure, require_dist7 as require_dist, getSlackConnectionState, isPollTracingEnabled, initOtel, withSpan, startSpan, withSpanContext, withRemoteContext, injectTraceContext, recordSessionCost, recordDbRetentionSweep, recordDbRetentionStatement, slackTaskOutput, ackSlackMessage, getTaskLink, getTaskUrl, markdownToSlack, buildCaptionBlock, buildCancelledBlocks, buildBufferFlushBlocks, buildTreeBlocks, taskCitationIssues, stripInvalidTaskCitations, taskCitationSourceGroups, renderTaskCitations, taskCitationWarnings, MAX_TASK_CITATIONS, CitationInputSchema, TaskCitationSchema, upsertTaskCitations, getTaskCitations, getTaskCitationsForTasks, hasTaskCitationCheckRefusal, getAgentDisplayName, getAgentEmoji, isSlackRenderV2Enabled, isSlackDelegationEnabled, callSlackWithRetry, formatV2Duration, renderThreadTree, ensureSlackThreadTree, withStatusLead, childOutcomeContent, streamOutcomeCard, slackErrorCode2 as slackErrorCode, isTerminalSlackError, describeSlackError, slackErrorSummary, refreshResolvedDeferralCards, processSlackRenderV2, _resetSlackRenderV2ForTests, _noteOutcomeDeliveryFailureForTests, registerTreeMessage, getSlackApp, initSlackApp, startSlackApp, stopSlackApp };
56127
+ export { initialize, ensure, require_dist7 as require_dist, getSlackConnectionState, isPollTracingEnabled, initOtel, withSpan, startSpan, withSpanContext, withRemoteContext, injectTraceContext, recordSessionCost, recordDbRetentionSweep, recordDbRetentionStatement, slackTaskOutput, ackSlackMessage, getTaskLink, getTaskUrl, markdownToSlack, buildCaptionBlock, buildCancelledBlocks, buildBufferFlushBlocks, buildTreeBlocks, taskCitationIssues, stripInvalidTaskCitations, taskCitationSourceGroups, renderTaskCitations, taskCitationWarnings, MAX_TASK_CITATIONS, CitationInputSchema, TaskCitationSchema, upsertTaskCitations, getTaskCitations, getTaskCitationsForTasks, hasTaskCitationCheckRefusal, getAgentDisplayName, getAgentEmoji, markSlackSessionProcessing, isSlackRenderV2Enabled, isSlackDelegationEnabled, callSlackWithRetry, formatV2Duration, renderThreadTree, ensureSlackThreadTree, withStatusLead, childOutcomeContent, streamOutcomeCard, slackErrorCode2 as slackErrorCode, isTerminalSlackError, describeSlackError, slackErrorSummary, refreshResolvedDeferralCards, processSlackRenderV2, _resetSlackRenderV2ForTests, _noteOutcomeDeliveryFailureForTests, registerTreeMessage, getSlackApp, initSlackApp, startSlackApp, stopSlackApp };