@desplega.ai/agent-swarm 1.157.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 (403) hide show
  1. package/dist/{acp-adapter-qhqrk4q0.js → acp-adapter-qhch0n2v.js} +1 -1
  2. package/dist/{actions-9rrg0zxm.js → actions-dtsh1mfb.js} +33 -29
  3. package/dist/{anthropic-messages-51pz26qe.js → anthropic-messages-f2h06k64.js} +8 -3
  4. package/dist/{app-enysy1zd.js → app-y1b9srva.js} +10 -9
  5. package/dist/{artifact-td4q4dch.js → artifact-3v5t9jtg.js} +1 -1
  6. package/dist/{assistant-zegamy48.js → assistant-31hwy5xj.js} +34 -30
  7. package/dist/{azure-openai-responses-8gksqtmz.js → azure-openai-responses-0k1mfax5.js} +12 -13
  8. package/dist/{boot-reembed-zfxb937k.js → boot-reembed-48d2qpkt.js} +11 -11
  9. package/dist/{boot-reembed-r6shx5qx.js → boot-reembed-w0bryhkr.js} +12 -12
  10. package/dist/{boot-scrub-logs-k5y0se6r.js → boot-scrub-logs-t65wbrn7.js} +9 -8
  11. package/dist/boot-seeds-h7c32hvm.js +27 -0
  12. package/dist/{claude-adapter-5yc7hxwv.js → claude-adapter-1t6611ne.js} +26 -21
  13. package/dist/{claude-managed-adapter-ea2aga6w.js → claude-managed-adapter-werp659j.js} +4 -2
  14. package/dist/{claude-managed-setup-60g8aazx.js → claude-managed-setup-y6rdgbc1.js} +11 -2
  15. package/dist/claude-sdk-session-zhkyk8yw.js +29319 -0
  16. package/dist/{cli-vj6h9kc2.js → cli-0m7wct0d.js} +59 -1
  17. package/dist/{cli-xf5b7y1f.js → cli-0n2e4x49.js} +13 -5
  18. package/dist/cli-0xqde53b.js +176 -0
  19. package/dist/{cli-nbp6m6gp.js → cli-10ym38qc.js} +53 -28
  20. package/dist/{cli-5b6b62tz.js → cli-13hw4z91.js} +1 -1
  21. package/dist/{cli-tpv97m71.js → cli-20035trh.js} +286 -84
  22. package/dist/{cli-k0g1sjzm.js → cli-31nkw3g3.js} +3 -3
  23. package/dist/cli-3gvrr8vj.js +1422 -0
  24. package/dist/{cli-sgyqyyxe.js → cli-48527fpw.js} +10 -8
  25. package/dist/{cli-24k806sc.js → cli-4aj25szq.js} +2 -2
  26. package/dist/{cli-s98skd5r.js → cli-4tvgz99m.js} +7 -7
  27. package/dist/cli-503ya656.js +455 -0
  28. package/dist/{cli-cw9zck8j.js → cli-5f2hq128.js} +8 -4
  29. package/dist/{cli-p37sg0a9.js → cli-68bmme5p.js} +11078 -27833
  30. package/dist/{cli-01vfmq8c.js → cli-79aq9cgb.js} +1318 -644
  31. package/dist/cli-7cxw8b60.js +14910 -0
  32. package/dist/cli-7kyk9jr3.js +22 -0
  33. package/dist/cli-7zttzetj.js +324 -0
  34. package/dist/{cli-y95wp3tg.js → cli-96qd5psa.js} +1 -1
  35. package/dist/{cli-ytxs7mn1.js → cli-9yg65c1j.js} +39 -0
  36. package/dist/{cli-3gmcwfyx.js → cli-ardpzhjm.js} +5 -5
  37. package/dist/{cli-y3nxwx0t.js → cli-b6thtzac.js} +20 -13
  38. package/dist/{cli-00w2c66p.js → cli-bgv70kym.js} +13 -2
  39. package/dist/{cli-r9ee9c4w.js → cli-bv0a38v9.js} +162 -42
  40. package/dist/cli-ca2w7zv7.js +115 -0
  41. package/dist/cli-cpvsaqsw.js +333 -0
  42. package/dist/cli-cygyqj3b.js +754 -0
  43. package/dist/{cli-5j7bm4tb.js → cli-dvjpkkjd.js} +6 -6
  44. package/dist/{cli-005pze6s.js → cli-e0ndxhtk.js} +4 -4
  45. package/dist/{cli-h0wdadsx.js → cli-e4xnc0qp.js} +21 -5
  46. package/dist/{cli-jytrw2na.js → cli-eg7cdg68.js} +8 -8
  47. package/dist/cli-ejpygnqz.js +3815 -0
  48. package/dist/{cli-c41wjx0r.js → cli-fjtp3463.js} +1917 -134
  49. package/dist/{cli-zt1227k1.js → cli-fkqhbg8g.js} +5 -3
  50. package/dist/{cli-awwphhcs.js → cli-g9df2m37.js} +765 -288
  51. package/dist/cli-gzyh0j0g.js +8455 -0
  52. package/dist/cli-hgqfttfc.js +183 -0
  53. package/dist/cli-hj65wsts.js +17755 -0
  54. package/dist/cli-j9z8mfx3.js +476 -0
  55. package/dist/{cli-aehm1rbq.js → cli-kc3dp84d.js} +1135 -61
  56. package/dist/{cli-h38x0qhg.js → cli-kdnehe0t.js} +4 -3
  57. package/dist/{cli-yscm6cv8.js → cli-m4excttz.js} +1993 -2216
  58. package/dist/{cli-74h6f2bp.js → cli-mg24hkt4.js} +2 -2
  59. package/dist/{cli-vx9p3qdt.js → cli-mzkqpxee.js} +1 -1
  60. package/dist/{cli-tjmghmm5.js → cli-phsaj4xq.js} +29 -4
  61. package/dist/{cli-pw9rj5t9.js → cli-pqetb83f.js} +1 -176
  62. package/dist/{cli-n6zq3kbd.js → cli-qjxy52w7.js} +1 -1
  63. package/dist/{cli-wb2zvbfg.js → cli-qv4jv8bx.js} +1 -1
  64. package/dist/cli-qvnnx4ct.js +1051 -0
  65. package/dist/cli-rb9m6rpe.js +4980 -0
  66. package/dist/{cli-tt9k8r35.js → cli-rfezr056.js} +476 -909
  67. package/dist/{cli-ggm92wcn.js → cli-rgjprct3.js} +1 -0
  68. package/dist/{cli-9n76jszt.js → cli-rrqmqr1s.js} +1 -1
  69. package/dist/cli-rykfmgwg.js +102 -0
  70. package/dist/cli-t1ze64h3.js +811 -0
  71. package/dist/{cli-eetrvv91.js → cli-t3p77qk1.js} +1 -1
  72. package/dist/{cli-scwq51gn.js → cli-vn0qv9cj.js} +25 -82
  73. package/dist/{cli-wsed24mk.js → cli-vwbbaecp.js} +2 -2
  74. package/dist/cli-wd9hz40d.js +69 -0
  75. package/dist/{cli-9p33cz9h.js → cli-wgjx0q33.js} +90 -32
  76. package/dist/cli-xgpf00sk.js +2149 -0
  77. package/dist/{cli-mcnhgnn1.js → cli-ykk5jaax.js} +184 -26
  78. package/dist/{cli-f3va018d.js → cli-z9x0sh1t.js} +26 -93
  79. package/dist/{cli-58rgvkt4.js → cli-zw65mab6.js} +5 -5
  80. package/dist/cli.js +56 -33
  81. package/dist/cloudflare-workers-ai-system-one-1sg586qv.js +46 -0
  82. package/dist/{codex-adapter-gns3s6c3.js → codex-adapter-jqfqqa21.js} +20 -13
  83. package/dist/{codex-hook-9hptmdhj.js → codex-hook-5eys3dya.js} +2 -2
  84. package/dist/{codex-session-runner-gqnxys5w.js → codex-session-runner-zd341dsm.js} +20 -13
  85. package/dist/{commands-hxy2y2sp.js → commands-vfsysz4s.js} +9 -8
  86. package/dist/{db-w8ghhsgf.js → db-s3znhvbn.js} +29 -10
  87. package/dist/{dispatcher-cp1rknjz.js → dispatcher-5xn0c7rf.js} +32 -28
  88. package/dist/{dsh-adapter-1dwg97zv.js → dsh-adapter-894mgfvs.js} +3 -3
  89. package/dist/{e2b-93x1k0j5.js → e2b-ez07znam.js} +4 -3
  90. package/dist/execute-71ysgv35.js +965 -0
  91. package/dist/{google-generative-ai-bxmv50nc.js → google-generative-ai-1nfcdphp.js} +5 -4
  92. package/dist/{google-vertex-809af514.js → google-vertex-1tqcd7b1.js} +5 -4
  93. package/dist/{handlers-egfhr351.js → handlers-5w4jwycr.js} +35 -31
  94. package/dist/{hook-x4kftwzt.js → hook-853bxrr6.js} +32 -21
  95. package/dist/{hook-fbxjqfjz.js → hook-z0hbxj85.js} +16 -13
  96. package/dist/{http-c7jfx990.js → http-akc3wy3m.js} +989 -275
  97. package/dist/{index-f6cryxwe.js → index-4a5njnm1.js} +2 -59
  98. package/dist/{index-jtvpgb8f.js → index-5sz16ksh.js} +208 -65
  99. package/dist/{index-dc2ek6bw.js → index-bjmjh9h4.js} +11 -11
  100. package/dist/{index-yy07ef2s.js → index-cd151qkq.js} +32 -28
  101. package/dist/{index-r6bty6tb.js → index-k661dzzr.js} +33 -29
  102. package/dist/{index-4k9hct21.js → index-ttpbhnjg.js} +32 -28
  103. package/dist/{keepalive-f7ekefyc.js → keepalive-8p9rpvz5.js} +11 -10
  104. package/dist/{lead-h053syts.js → lead-jp69z5h3.js} +49 -45
  105. package/dist/llama-cpp-classify-t2tccams.js +335 -0
  106. package/dist/{maintenance-a3w6zs54.js → maintenance-fwx4ev0k.js} +12 -12
  107. package/dist/{mistral-conversations-zx0kn554.js → mistral-conversations-bhvwqcnk.js} +14 -17
  108. package/dist/{oauth-refresh-sweep-vra1dhkd.js → oauth-refresh-sweep-cwcq1ctx.js} +10 -9
  109. package/dist/{onboard-mfgzeqxs.js → onboard-2b4q0t84.js} +282 -84
  110. package/dist/{openai-codex-responses-4vjqzvjp.js → openai-codex-responses-nekthgks.js} +21 -8
  111. package/dist/{openai-completions-9hjrqbw8.js → openai-completions-hxtzwj0s.js} +8 -11
  112. package/dist/{openai-responses-7b1pn0xt.js → openai-responses-w4r118w7.js} +22 -17
  113. package/dist/{opencode-adapter-z64xjzec.js → opencode-adapter-zz7xvjj6.js} +6 -4
  114. package/dist/{openrouter-images-9f9ek4rw.js → openrouter-images-b6sqqjgn.js} +4 -6
  115. package/dist/{otel-impl-2ez6xk57.js → otel-impl-g8rs4vwr.js} +416 -301
  116. package/dist/{pi-messages-txpjj39q.js → pi-messages-vxdt8v7j.js} +2 -1
  117. package/dist/{pi-mono-adapter-2b7mw16r.js → pi-mono-adapter-n0me28wt.js} +29 -17
  118. package/dist/pricing-refresh-0v77385v.js +39 -0
  119. package/dist/{rbac-roles-nm6924sy.js → rbac-roles-krjyazbj.js} +10 -9
  120. package/dist/{render-v2-f026j6c4.js → render-v2-3wjsp9aw.js} +10 -9
  121. package/dist/runtime-ktjysacx.js +24 -0
  122. package/dist/{setup-w606fr1q.js → setup-yeqryke6.js} +6 -5
  123. package/dist/typesafe-system-one-96960jxp.js +27 -0
  124. package/dist/{virtual-modules-8qheft18.js → virtual-modules-dzdeq1sf.js} +21 -13
  125. package/dist/{work-objects-ezmggdne.js → work-objects-3pakpkw0.js} +35 -31
  126. package/dist/{worker-1mbyv29k.js → worker-85testgj.js} +49 -45
  127. package/openapi.json +3288 -1442
  128. package/package.json +10 -8
  129. package/src/apps/catalog.generated.json +229 -0
  130. package/src/apps/page-validator.ts +71 -16
  131. package/src/apps/row-store.ts +66 -11
  132. package/src/apps/sync.ts +59 -17
  133. package/src/artifact-sdk/browser-sdk.ts +436 -2
  134. package/src/be/approval-sweeps.ts +109 -0
  135. package/src/be/boot-seeds.ts +40 -0
  136. package/src/be/chunking.ts +1 -1
  137. package/src/be/db/agents.ts +40 -0
  138. package/src/be/db/approvals.ts +78 -0
  139. package/src/be/db/tasks/human-free.ts +442 -0
  140. package/src/be/db/tasks/read.ts +252 -39
  141. package/src/be/db/tasks/write.ts +148 -20
  142. package/src/be/db-client.ts +107 -48
  143. package/src/be/db.ts +308 -241
  144. package/src/be/events.ts +33 -1
  145. package/src/be/harness-model-support.ts +182 -0
  146. package/src/be/human-free-drain.ts +67 -0
  147. package/src/be/memory/graph-expansion.ts +10 -3
  148. package/src/be/memory/providers/sqlite-store.ts +55 -13
  149. package/src/be/memory/raters/retrieval.ts +5 -2
  150. package/src/be/memory/reranker.ts +26 -2
  151. package/src/be/memory/types.ts +2 -0
  152. package/src/be/migrations/166_approval_request_auto_cancellation.sql +9 -0
  153. package/src/be/migrations/171_memory_retrieval_relevance.sql +8 -0
  154. package/src/be/migrations/175_workflow_runs_list_index.sql +11 -0
  155. package/src/be/migrations/177_events_event_agent_created_index.sql +11 -0
  156. package/src/be/migrations/182_task_human_free_flag.sql +63 -0
  157. package/src/be/migrations/183_human_free_reclassify_queue.sql +25 -0
  158. package/src/be/migrations/184_model_catalog.sql +120 -0
  159. package/src/be/model-catalog-store.ts +644 -0
  160. package/src/be/model-tier-keys.ts +31 -0
  161. package/src/be/model-tier-resolution.ts +489 -0
  162. package/src/be/model-validation.ts +112 -0
  163. package/src/be/models-catalog.ts +63 -7
  164. package/src/be/modelsdev-cache.json +1939 -0
  165. package/src/be/modelsdev-cache.ts +16 -1
  166. package/src/be/pricing-normalize.ts +2 -0
  167. package/src/be/pricing-refresh.ts +154 -12
  168. package/src/be/scripts/typecheck.ts +16 -0
  169. package/src/be/seed-pricing.ts +3 -1
  170. package/src/be/seed-scripts/catalog/task-failure-audit.ts +61 -9
  171. package/src/be/seed-skills/bundled-files.generated.json +1 -1
  172. package/src/be/steering.ts +53 -3
  173. package/src/be/swarm-config-guard.ts +9 -0
  174. package/src/be/task-citations.ts +29 -0
  175. package/src/cli.tsx +24 -1
  176. package/src/commands/claude-managed-setup.ts +3 -1
  177. package/src/commands/onboard/compose-generator.ts +8 -3
  178. package/src/commands/onboard/container-engine.ts +220 -0
  179. package/src/commands/onboard/manifest.ts +1 -0
  180. package/src/commands/onboard/steps/health-check.tsx +4 -1
  181. package/src/commands/onboard/steps/prereq-check.tsx +50 -54
  182. package/src/commands/onboard/steps/start.tsx +31 -16
  183. package/src/commands/onboard/types.ts +7 -2
  184. package/src/commands/onboard.tsx +39 -4
  185. package/src/commands/profile-sync.ts +79 -26
  186. package/src/commands/runner.ts +84 -3
  187. package/src/extensions/catalog.generated.json +17 -0
  188. package/src/extensions/contract-types.generated.ts +1 -1
  189. package/src/heartbeat/heartbeat.ts +323 -114
  190. package/src/heartbeat/templates.ts +2 -2
  191. package/src/hooks/hook.ts +21 -12
  192. package/src/http/agents.ts +84 -1
  193. package/src/http/approval-requests.ts +136 -64
  194. package/src/http/apps.ts +14 -3
  195. package/src/http/config.ts +15 -1
  196. package/src/http/events.ts +62 -2
  197. package/src/http/index.ts +14 -4
  198. package/src/http/memory.ts +21 -7
  199. package/src/http/models-catalog.ts +357 -8
  200. package/src/http/poll.ts +45 -2
  201. package/src/http/schedules.ts +37 -7
  202. package/src/http/session-data.ts +11 -9
  203. package/src/http/sessions.ts +25 -18
  204. package/src/http/stats.ts +25 -15
  205. package/src/http/status.ts +11 -1
  206. package/src/http/tasks.ts +66 -9
  207. package/src/http/usage-cache.ts +56 -15
  208. package/src/http/webhooks.ts +67 -46
  209. package/src/http/workflows.ts +50 -28
  210. package/src/linear/outbound.ts +37 -15
  211. package/src/otel-impl.ts +151 -1
  212. package/src/otel.ts +14 -3
  213. package/src/prompts/memories.ts +19 -2
  214. package/src/prompts/session-templates.ts +1 -0
  215. package/src/providers/claude-managed-models.ts +47 -153
  216. package/src/providers/codex-adapter.ts +4 -4
  217. package/src/providers/codex-models.ts +65 -198
  218. package/src/providers/reasoning-effort.ts +44 -140
  219. package/src/rbac/legacy-policy.ts +41 -0
  220. package/src/rbac/permissions.ts +14 -0
  221. package/src/scheduler/schedule-task.ts +3 -0
  222. package/src/scripts-runtime/sdk-allowlist.ts +5 -0
  223. package/src/scripts-runtime/swarm-sdk.ts +9 -0
  224. package/src/scripts-runtime/types/stdlib.d.ts +16 -0
  225. package/src/scripts-runtime/types/swarm-extension.d.ts +4 -0
  226. package/src/scripts-runtime/types/swarm-sdk.d.ts +16 -0
  227. package/src/server.ts +18 -7
  228. package/src/slack/app.ts +35 -4
  229. package/src/slack/connection-state.ts +17 -0
  230. package/src/slack/message-text.ts +56 -2
  231. package/src/slack/thread-buffer.ts +10 -2
  232. package/src/tasks/context-key.ts +1 -0
  233. package/src/tasks/worker-follow-up.ts +6 -2
  234. package/src/tests/agent-task-activity.test.ts +74 -0
  235. package/src/tests/agents-list-model-display.test.ts +9 -6
  236. package/src/tests/approval-auto-cancellation-migration.test.ts +104 -0
  237. package/src/tests/approval-requests.test.ts +395 -0
  238. package/src/tests/approval-sweeps-config.test.ts +47 -0
  239. package/src/tests/approval-sweeps.test.ts +508 -0
  240. package/src/tests/apps-kibo-blocks.test.ts +77 -0
  241. package/src/tests/apps-spike.test.ts +56 -1
  242. package/src/tests/apps-sync-engine.test.ts +20 -9
  243. package/src/tests/base-prompt.test.ts +3 -0
  244. package/src/tests/boot-seeds.test.ts +170 -0
  245. package/src/tests/cancel-approval-request-tool.test.ts +115 -0
  246. package/src/tests/claude-adapter.test.ts +10 -0
  247. package/src/tests/claude-managed-adapter.test.ts +17 -17
  248. package/src/tests/codex-adapter.test.ts +2 -1
  249. package/src/tests/codex-gpt6-release.test.ts +66 -5
  250. package/src/tests/config-key-filter.test.ts +80 -0
  251. package/src/tests/context-window.test.ts +8 -5
  252. package/src/tests/db-client-busy-retry.test.ts +96 -0
  253. package/src/tests/db-client.test.ts +60 -1
  254. package/src/tests/db-extraction-contract.test.ts +1 -0
  255. package/src/tests/db-task-read-contract.test.ts +15 -1
  256. package/src/tests/db-task-write-contract.test.ts +13 -1
  257. package/src/tests/docs-index-footprint.test.js +3 -3
  258. package/src/tests/events-http.test.ts +103 -0
  259. package/src/tests/explicit-model-validation.test.ts +332 -0
  260. package/src/tests/extensions-catalog.test.ts +22 -17
  261. package/src/tests/extensions-pre-task.test.ts +107 -0
  262. package/src/tests/fixtures/kibo-blocks-definition.json.txt +105 -0
  263. package/src/tests/follow-up-config-inheritance.test.ts +260 -0
  264. package/src/tests/harness-model-support.test.ts +374 -0
  265. package/src/tests/heartbeat-checklist-config.test.ts +71 -0
  266. package/src/tests/heartbeat-checklist.test.ts +4 -2
  267. package/src/tests/heartbeat-orphan-resume.test.ts +132 -0
  268. package/src/tests/heartbeat-reboot-live.test.ts +95 -0
  269. package/src/tests/heartbeat-stall-cas.test.ts +80 -0
  270. package/src/tests/heartbeat.test.ts +99 -3
  271. package/src/tests/hook-mcp-config.test.ts +29 -0
  272. package/src/tests/http-api-integration.test.ts +16 -2
  273. package/src/tests/human-free-flag.test.ts +279 -0
  274. package/src/tests/human-free-oracle.ts +57 -0
  275. package/src/tests/human-free-reclassify.test.ts +669 -0
  276. package/src/tests/kv-storage.test.ts +62 -0
  277. package/src/tests/linear-outbound-sync.test.ts +120 -5
  278. package/src/tests/list-endpoint-slimming.test.ts +91 -0
  279. package/src/tests/memory-graph-organic-route.test.ts +155 -0
  280. package/src/tests/memory-http-recall-gating.test.ts +14 -4
  281. package/src/tests/memory-hybrid.test.ts +161 -1
  282. package/src/tests/memory-prompt-recall-crowdout.test.ts +297 -0
  283. package/src/tests/memory.test.ts +22 -0
  284. package/src/tests/migration-046-budgets.test.ts +3 -3
  285. package/src/tests/model-catalog-migration.test.ts +134 -0
  286. package/src/tests/model-catalog-table.test.ts +249 -0
  287. package/src/tests/model-catalog-write-access.test.ts +387 -0
  288. package/src/tests/model-tier-resolution.test.ts +519 -0
  289. package/src/tests/models-catalog.test.ts +1 -1
  290. package/src/tests/multi-runtime-enabled-stats.test.ts +65 -1
  291. package/src/tests/onboard-container-engine.test.ts +240 -0
  292. package/src/tests/otel-event-loop-and-logs.test.ts +99 -0
  293. package/src/tests/package-publish.test.ts +137 -36
  294. package/src/tests/pricing-routes.test.ts +16 -2
  295. package/src/tests/profile-sync-warning.test.ts +8 -4
  296. package/src/tests/promote-draft-task-route.test.ts +19 -0
  297. package/src/tests/provider-registration.test.ts +296 -42
  298. package/src/tests/rbac-engine.test.ts +72 -2
  299. package/src/tests/reasoning-effort.test.ts +117 -0
  300. package/src/tests/refresh-modelsdev-carryforward.test.ts +5 -5
  301. package/src/tests/runtime-model-catalog.test.ts +86 -0
  302. package/src/tests/script-connections.test.ts +12 -0
  303. package/src/tests/sdk-allowlist.test.ts +39 -0
  304. package/src/tests/seed-scripts.test.ts +89 -0
  305. package/src/tests/session-costs-model-key-normalize.test.ts +1 -0
  306. package/src/tests/session-costs.test.ts +14 -11
  307. package/src/tests/sessions-detail-batch.test.ts +250 -0
  308. package/src/tests/sessions.test.ts +118 -0
  309. package/src/tests/slack-config.test.ts +22 -0
  310. package/src/tests/slack-message-text.test.ts +101 -0
  311. package/src/tests/slack-thread-buffer-context.test.ts +93 -0
  312. package/src/tests/sonnet-5-5-registry.test.ts +44 -0
  313. package/src/tests/status.test.ts +36 -1
  314. package/src/tests/swarm-diff.test.ts +316 -10
  315. package/src/tests/task-cascade-fail.test.ts +148 -2
  316. package/src/tests/task-completion-idempotency.test.ts +2 -1
  317. package/src/tests/tasks-requested-by-filter.test.ts +3 -1
  318. package/src/tests/tool-annotations.test.ts +1 -1
  319. package/src/tests/ui-list-slim-projections.test.ts +158 -0
  320. package/src/tests/usage-cache.test.ts +166 -0
  321. package/src/tests/webhooks-task-blocked.test.ts +127 -0
  322. package/src/tests/workflow-approval-recovery.test.ts +203 -0
  323. package/src/tests/workflow-executors.test.ts +5 -2
  324. package/src/tests/workflow-hitl-routing.test.ts +22 -1
  325. package/src/tests/workflow-hitl-slack-card.test.ts +52 -0
  326. package/src/tests/workflow-http-v2.test.ts +99 -8
  327. package/src/tests/workflow-retry-validation.test.ts +56 -0
  328. package/src/tests/workflow-system-one-decision-review.test.ts +1021 -0
  329. package/src/tests/workflow-system-one-decision-save-warnings.test.ts +365 -0
  330. package/src/tests/workflow-system-one-decision.test.ts +2063 -0
  331. package/src/tests/workflow-tla-races.test.ts +389 -0
  332. package/src/tests/workflow-validation-port-routing.test.ts +113 -1
  333. package/src/tools/cancel-approval-request.ts +57 -0
  334. package/src/tools/memory-search.ts +1 -0
  335. package/src/tools/model-catalog/index.ts +137 -0
  336. package/src/tools/request-human-input.ts +4 -2
  337. package/src/tools/schedules/create-schedule.ts +16 -1
  338. package/src/tools/schedules/patch-schedule.ts +17 -0
  339. package/src/tools/schedules/update-schedule.ts +17 -0
  340. package/src/tools/send-task.ts +18 -0
  341. package/src/tools/task-action.ts +12 -0
  342. package/src/tools/templates.ts +19 -0
  343. package/src/tools/tool-config.ts +5 -2
  344. package/src/tools/workflows/create-workflow.ts +9 -2
  345. package/src/tools/workflows/list-workflow-runs.ts +1 -0
  346. package/src/tools/workflows/patch-workflow-node.ts +17 -7
  347. package/src/tools/workflows/patch-workflow.ts +9 -2
  348. package/src/tools/workflows/update-workflow.ts +9 -2
  349. package/src/types.ts +68 -1
  350. package/src/utils/context-window.ts +47 -52
  351. package/src/utils/harness-cli-version.ts +115 -0
  352. package/src/utils/harness-model-error.ts +33 -0
  353. package/src/utils/runtime-model-catalog.ts +137 -0
  354. package/src/workflows/approval-cancel.ts +152 -0
  355. package/src/workflows/approval-notifications.ts +84 -0
  356. package/src/workflows/approval-resolution.ts +39 -0
  357. package/src/workflows/checkpoint.ts +10 -5
  358. package/src/workflows/definition.ts +28 -0
  359. package/src/workflows/engine.ts +221 -22
  360. package/src/workflows/executors/agent-task.ts +9 -0
  361. package/src/workflows/executors/base.ts +53 -0
  362. package/src/workflows/executors/human-in-the-loop.ts +9 -9
  363. package/src/workflows/executors/index.ts +1 -0
  364. package/src/workflows/executors/registry.ts +2 -0
  365. package/src/workflows/executors/system-one-decision.ts +1232 -0
  366. package/src/workflows/executors/system-one-providers.ts +301 -0
  367. package/src/workflows/executors/workflow-llm.ts +13 -1
  368. package/src/workflows/readiness.ts +86 -0
  369. package/src/workflows/recovery.ts +100 -45
  370. package/src/workflows/resume.ts +71 -26
  371. package/src/workflows/retry-poller.ts +71 -21
  372. package/templates/extensions/README.md +1 -0
  373. package/templates/extensions/github-sender-allowlist/README.md +18 -0
  374. package/templates/extensions/github-sender-allowlist/hooks.ts +55 -0
  375. package/templates/extensions/github-sender-allowlist/manifest.json +8 -0
  376. package/templates/schedules/daily-blocker-digest/content.md +4 -5
  377. package/templates/skills/agent-browser/SKILL.md +6 -5
  378. package/templates/skills/agent-browser/content.md +6 -5
  379. package/templates/skills/apps/content.md +20 -1
  380. package/templates/skills/code-quality/content.md +26 -1
  381. package/templates/skills/heartbeat-runbook/config.json +1 -1
  382. package/templates/skills/heartbeat-runbook/content.md +2 -2
  383. package/templates/skills/pages/content.md +16 -4
  384. package/templates/skills/pages/files/examples/multiplayer-board.html +3 -12
  385. package/templates/skills/swarm-scripts/SKILL.md +1 -1
  386. package/templates/skills/swarm-scripts/content.md +1 -1
  387. package/templates/skills/workflow-iterate/content.md +81 -1
  388. package/templates/workflows/claude-code-changelog-watch/content.md +2 -0
  389. package/templates/workflows/pr-review-status-sweep/content.md +2 -0
  390. package/dist/claude-sdk-session-j4ywn3xf.js +0 -39108
  391. package/dist/cli-2daksqps.js +0 -378
  392. package/dist/cli-6jjzxv3b.js +0 -246
  393. package/dist/cli-avkd6mqv.js +0 -6052
  394. package/dist/cli-aw1jwp1r.js +0 -14075
  395. package/dist/cli-e781c6f9.js +0 -60
  396. package/dist/cli-v53rbqp3.js +0 -1101
  397. package/dist/cli-vapyk8sw.js +0 -20
  398. package/dist/pricing-refresh-6sw65tck.js +0 -27
  399. package/dist/rbac-roles-3gxmnb20.js +0 -37
  400. package/dist/seed-pricing-vqxa06qf.js +0 -26
  401. package/src/providers/modelsdev-reasoning.json +0 -5902
  402. package/dist/{codex-login-x3jk4etn.js → codex-login-he9vrn90.js} +3 -3
  403. package/dist/{index-f24115ge.js → index-2wsdsnmm.js} +3 -3
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  REBOOT_RETRY_PIN_TAG,
3
3
  agentsWithLiveRuntime,
4
+ cancelApprovalRequestAndRun,
4
5
  countActiveRuntimeInstancesForAgent,
5
6
  createPoolStarvationDecisionTask,
6
7
  createRerouteDecisionTask,
@@ -15,15 +16,19 @@ import {
15
16
  recoverIncompleteRuns,
16
17
  repointTrackerSyncBySwarmId,
17
18
  resolveLeadOnlyRecoveryAssignment
18
- } from "./cli-01vfmq8c.js";
19
+ } from "./cli-79aq9cgb.js";
19
20
  import {
20
21
  isMultiRuntimeEnabled
21
22
  } from "./cli-re8z5p8p.js";
23
+ import {
24
+ createApprovalFollowUpTask
25
+ } from "./cli-fjtp3463.js";
22
26
  import {
23
27
  MAX_EMPTY_POLLS,
24
28
  assignUnassignedTaskPending,
25
29
  backfillSupersedeTaskResumeTaskId,
26
30
  buildRoutingAffinityFromAgent,
31
+ cascadeFailDependents,
27
32
  cleanupStaleSessions,
28
33
  createLogEntry,
29
34
  createTaskExtended,
@@ -34,15 +39,20 @@ import {
34
39
  getActiveTaskCount,
35
40
  getAllAgents,
36
41
  getDbClient,
42
+ getDependentTasks,
43
+ getExpiredPendingApprovals,
37
44
  getIdleWorkersWithCapacity,
38
45
  getLeadAgent,
39
46
  getPendingSteeringForTask,
40
47
  getRecentCompletedCount,
41
48
  getRecentFailedCount,
42
49
  getRecentFailedTasks,
50
+ getStaleApprovalRequests,
43
51
  getStalePinnedResumes,
44
52
  getStaleUnassignedAffinityTasks,
45
53
  getStalledInProgressTasks,
54
+ getSupersededTasksWithUnsettledDependents,
55
+ getSupersededTasksWithoutResume,
46
56
  getTaskById,
47
57
  getTaskStats,
48
58
  getTasksByStatus,
@@ -59,24 +69,98 @@ import {
59
69
  releaseStaleOfferedTasksForOfflineAgents,
60
70
  releaseStaleProcessingInbox,
61
71
  releaseStaleReviewingTasks,
72
+ resolveApprovalRequest,
73
+ settleSupersededTaskDependents,
62
74
  supersedeTask,
63
75
  updateAgentStatus
64
- } from "./cli-awwphhcs.js";
76
+ } from "./cli-g9df2m37.js";
65
77
  import {
66
78
  init_registry,
67
79
  init_resolver,
68
80
  registerTemplate,
69
81
  resolveTemplate
70
- } from "./cli-ggm92wcn.js";
82
+ } from "./cli-rgjprct3.js";
83
+ import {
84
+ init_env_flag,
85
+ isEnvFlagEnabled
86
+ } from "./cli-ej6gbxfb.js";
71
87
  import {
72
88
  init_secret_scrubber,
73
89
  scrubSecrets
74
90
  } from "./cli-r2ap2czm.js";
75
91
 
92
+ // src/be/approval-sweeps.ts
93
+ init_db();
94
+ var DEFAULT_APPROVAL_REQUEST_AUTO_CANCELLATION_DAYS = 7;
95
+ function approvalRequestAutoCancellationDays() {
96
+ const raw = process.env.APPROVAL_REQUEST_AUTO_CANCELLATION_DAYS;
97
+ if (raw != null && /^\d+$/.test(raw.trim())) {
98
+ return Number.parseInt(raw.trim(), 10);
99
+ }
100
+ return DEFAULT_APPROVAL_REQUEST_AUTO_CANCELLATION_DAYS;
101
+ }
102
+ async function autoCancelStaleApprovalRequests(now = new Date) {
103
+ const days = approvalRequestAutoCancellationDays();
104
+ if (days === 0)
105
+ return { cancelled: [], runsCancelled: [] };
106
+ const cutoff = new Date(now.getTime() - days * 86400000).toISOString();
107
+ const stale = await getStaleApprovalRequests({ cutoff });
108
+ const reason = `Auto-cancelled by the approval sweep after ${days} days with no response`;
109
+ const cancelled = [];
110
+ const runsCancelled = [];
111
+ for (const row of stale) {
112
+ try {
113
+ const result = await cancelApprovalRequestAndRun(row.id, {
114
+ reason,
115
+ resolvedBy: null,
116
+ slackReason: "auto-cancelled with no response"
117
+ });
118
+ if (!result || "timedOut" in result)
119
+ continue;
120
+ cancelled.push(result.request);
121
+ if (result.runCancelled && result.request.workflowRunId) {
122
+ runsCancelled.push(result.request.workflowRunId);
123
+ }
124
+ } catch (err) {
125
+ console.error(`[approval-sweep] could not cancel approval request ${row.id}: ${err instanceof Error ? err.message : String(err)}`);
126
+ }
127
+ }
128
+ if (cancelled.length > 0) {
129
+ console.log(`[approval-sweep] auto-cancelled ${cancelled.length} stale approval requests and ${runsCancelled.length} workflow runs`);
130
+ }
131
+ return { cancelled, runsCancelled };
132
+ }
133
+ async function timeoutExpiredApprovalRequests(now = new Date) {
134
+ const expired = await getExpiredPendingApprovals({ now: now.toISOString() });
135
+ const timedOut = [];
136
+ for (const row of expired) {
137
+ try {
138
+ const updated = await getDbClient().transaction(async () => {
139
+ const request = await resolveApprovalRequest(row.id, {
140
+ status: "timeout",
141
+ resolutionReason: `Timed out by the approval sweep: no answer before ${row.expiresAt}`
142
+ });
143
+ if (request)
144
+ await createApprovalFollowUpTask(request, "hitl.timeout");
145
+ return request;
146
+ });
147
+ if (updated)
148
+ timedOut.push(updated);
149
+ } catch (err) {
150
+ console.error(`[approval-sweep] could not time out approval request ${row.id}: ${err instanceof Error ? err.message : String(err)}`);
151
+ }
152
+ }
153
+ if (timedOut.length > 0) {
154
+ console.log(`[approval-sweep] timed out ${timedOut.length} expired approval requests`);
155
+ }
156
+ return { timedOut };
157
+ }
158
+
76
159
  // src/heartbeat/heartbeat.ts
77
160
  init_db();
78
161
  init_steering();
79
162
  init_resolver();
163
+ init_env_flag();
80
164
  init_secret_scrubber();
81
165
 
82
166
  // src/heartbeat/templates.ts
@@ -98,8 +182,8 @@ Goal: Review system status and your standing orders, take action if needed.
98
182
  ## Instructions
99
183
  1. **Read your HEARTBEAT.md** — run \`read /workspace/HEARTBEAT.md\` to get the latest standing orders (the snapshot above may be slightly stale).
100
184
  2. **Prune tracked HEARTBEAT items FIRST.** Active Blockers + Watch Items + Open Discussion combined must stay at ≤10 items; 20 is the absolute max only when genuinely super busy. This cap does not apply to evergreen Standing Orders / Governance / Playbook-index reference sections. Before adding anything, re-check every tracked item against its lift trigger and remove anything resolved, stale, or past its trigger date. Lift incident detail to memory; never keep it inline in HEARTBEAT.md. Every new tracked item must include an explicit lift trigger + date; if it has no removal condition, do not add it. If the tracked list is already at/over cap, prune before (or instead of) adding — the cap is binding.
101
- 3. **Run seeded heartbeat data-gathering.** Use \`script-run\` with global script \`Heartbeat Audit\` and pass the current HEARTBEAT.md text as \`heartbeatMarkdown\`. It covers Rules #10/#13/#15/#16/#17: resolved stale PRs, pool-target risk schedules, schedule/provider failure clusters, and whether daily-blocker-digest ran today. The Slack thread-reply check (Rule #11) stays Lead-side; the script runtime has no Slack token.
102
- 4. Review the system status above plus the \`Heartbeat Audit\` result for anything that needs attention (stalled tasks, idle workers with available work, anomalies).
185
+ 3. **Run seeded heartbeat data-gathering.** Use \`script-run\` with the global scripts \`schedule-health\` and \`task-failure-audit\`, both with args \`{ "days": 1, "publishPage": false }\`. They report failing schedules and failure clusters. Check any other standing order in HEARTBEAT.md yourself. Scripts can read Slack too (\`ctx.swarm.slack_read\` or the seeded \`slack-thread-flatten\` script), so a recurring Slack check can be scripted.
186
+ 4. Review the system status above plus the script results for anything that needs attention (stalled tasks, idle workers with available work, anomalies).
103
187
  5. **CRITICAL — Reboot failure triage:** Failures with reason "worker session not found" or "worker session heartbeat is stale" indicate tasks that were INTERRUPTED by a server restart. These are NOT "expected auto-cleanup" — they represent work that was lost mid-execution. For each such failure:
104
188
  - Check what the task was (via \`get-task-details\` with the task ID from the failure)
105
189
  - If a retry task was auto-created (tagged \`reboot-retry\`), verify it is progressing
@@ -215,10 +299,22 @@ var HEARTBEAT_RESUME_PIN_GRACE_MIN = (() => {
215
299
  return Number.isFinite(parsed) ? parsed : 10;
216
300
  })();
217
301
  var POOL_AFFINITY_ESCALATION_MIN = Number(process.env.POOL_AFFINITY_ESCALATION_MIN) || 15;
218
- var HEARTBEAT_CHECKLIST_INTERVAL_MS = Number(process.env.HEARTBEAT_CHECKLIST_INTERVAL_MS) || 30 * 60 * 1000;
219
- var HEARTBEAT_CHECKLIST_DISABLE = Boolean(process.env.HEARTBEAT_CHECKLIST_DISABLE);
302
+ var DEFAULT_HEARTBEAT_CHECKLIST_INTERVAL_MS = 30 * 60 * 1000;
303
+ function heartbeatChecklistIntervalMs() {
304
+ const raw = process.env.HEARTBEAT_CHECKLIST_INTERVAL_MS?.trim();
305
+ if (!raw)
306
+ return DEFAULT_HEARTBEAT_CHECKLIST_INTERVAL_MS;
307
+ const parsed = Number(raw);
308
+ if (!Number.isFinite(parsed))
309
+ return DEFAULT_HEARTBEAT_CHECKLIST_INTERVAL_MS;
310
+ return Math.max(0, parsed);
311
+ }
312
+ function isHeartbeatChecklistDisabled() {
313
+ return isEnvFlagEnabled("HEARTBEAT_CHECKLIST_DISABLE", false);
314
+ }
220
315
  var heartbeatInterval = null;
221
316
  var checklistInterval = null;
317
+ var bootTriageTimeout = null;
222
318
  var isSweeping = false;
223
319
  var beforeHeartbeatSupersedeForTests = null;
224
320
  var rebootAffectedTasks = [];
@@ -260,12 +356,15 @@ async function codeLevelTriage() {
260
356
  workflowRuns: 0,
261
357
  staleRuntimes: 0,
262
358
  staleOfferedTasks: 0,
263
- abandonedDraftTasks: 0
359
+ abandonedDraftTasks: 0,
360
+ approvalAutoCancelled: 0,
361
+ approvalTimedOut: 0
264
362
  }
265
363
  };
266
364
  findings.staleCleanup.staleRuntimes = (await expireStaleRuntimeInstances()).expired;
267
365
  findings.staleCleanup.staleOfferedTasks = await releaseStaleOfferedTasksForOfflineAgents();
268
366
  await detectAndRemediateStalledTasks(findings);
367
+ await repairSupersededWithoutResume(findings);
269
368
  await checkWorkerHealth(findings);
270
369
  await autoAssignPoolTasks(findings);
271
370
  await cleanupStaleResources(findings);
@@ -361,6 +460,31 @@ async function detectAndRemediateStalledTasks(findings) {
361
460
  await remediateCrashedWorkerTask(findings, task, remediationOpts, proposed);
362
461
  }
363
462
  }
463
+ var ORPHAN_SUPERSEDE_MIN_AGE_MS = 60 * 1000;
464
+ var ORPHAN_SUPERSEDE_MAX_AGE_MS = 24 * 60 * 60 * 1000;
465
+ async function repairSupersededWithoutResume(findings) {
466
+ const now = Date.now();
467
+ const orphans = await getSupersededTasksWithoutResume(new Date(now - ORPHAN_SUPERSEDE_MIN_AGE_MS).toISOString(), new Date(now - ORPHAN_SUPERSEDE_MAX_AGE_MS).toISOString());
468
+ for (const task of orphans) {
469
+ const resume = task.agentId && getNextResumeGeneration(task) <= maxResumeGenerations() ? await createResumeFollowUp({ parentId: task.id, reason: "crash_recovery" }) : null;
470
+ if (resume?.kind !== "created" || !task.agentId) {
471
+ await settleSupersededTaskDependents(task.id, null);
472
+ continue;
473
+ }
474
+ await backfillSupersedeTaskResumeTaskId(task.id, resume.task.id);
475
+ findings.autoResumedTasks.push({
476
+ taskId: task.id,
477
+ resumeTaskId: resume.task.id,
478
+ agentId: task.agentId,
479
+ reason: "repaired superseded task without resume"
480
+ });
481
+ console.log(`[Heartbeat] Created missing resume ${resume.task.id.slice(0, 8)} for superseded task ${task.id.slice(0, 8)}`);
482
+ }
483
+ const unsettled = await getSupersededTasksWithUnsettledDependents(new Date(now - ORPHAN_SUPERSEDE_MIN_AGE_MS).toISOString(), new Date(now - ORPHAN_SUPERSEDE_MAX_AGE_MS).toISOString());
484
+ for (const { taskId, resumeTaskId } of unsettled) {
485
+ await settleSupersededTaskDependents(taskId, resumeTaskId);
486
+ }
487
+ }
364
488
  function isRemediationAction(value) {
365
489
  return typeof value === "string" && REMEDIATION_ACTIONS.has(value);
366
490
  }
@@ -393,7 +517,9 @@ async function remediateCrashedWorkerTask(findings, task, opts, decision) {
393
517
  if (!task.agentId)
394
518
  return;
395
519
  if (decision.action === "fail") {
396
- const failed = await failTask(task.id, decision.reason);
520
+ const failed = await failTask(task.id, decision.reason, {
521
+ expectedLastUpdatedAt: task.lastUpdatedAt
522
+ });
397
523
  if (failed) {
398
524
  findings.autoFailedTasks.push({
399
525
  taskId: task.id,
@@ -416,7 +542,8 @@ async function remediateCrashedWorkerTask(findings, task, opts, decision) {
416
542
  await beforeHeartbeatSupersedeForTests?.(task);
417
543
  const superseded = await supersedeTask(task.id, {
418
544
  reason: decision.reason,
419
- resumeTaskId: null
545
+ resumeTaskId: null,
546
+ expectedLastUpdatedAt: task.lastUpdatedAt
420
547
  });
421
548
  if (!superseded) {
422
549
  return;
@@ -443,6 +570,7 @@ async function remediateCrashedWorkerTask(findings, task, opts, decision) {
443
570
  }
444
571
  } else {
445
572
  const reason = resume.kind === "skipped" ? `resume_creation_skipped_${resume.reason}` : "resume_creation_skipped_workflow";
573
+ await settleSupersededTaskDependents(task.id, null);
446
574
  const failed = await failTask(task.id, reason);
447
575
  if (failed) {
448
576
  findings.autoFailedTasks.push({
@@ -510,94 +638,144 @@ async function runRebootSweep() {
510
638
  if (sessionLastSeen >= bootEpoch - BOOT_EPOCH_SKEW_MS) {
511
639
  continue;
512
640
  }
641
+ if (Date.now() - sessionLastSeen < stallThresholdStaleHeartbeatMin() * 60 * 1000) {
642
+ continue;
643
+ }
513
644
  }
514
645
  if (session)
515
646
  await deleteActiveSession(task.id);
516
- const failed = await failTask(task.id, reason);
647
+ const failed = await failTask(task.id, reason, { cascadeDependents: false });
517
648
  if (!failed)
518
649
  continue;
519
- if (await getActiveTaskCount(task.agentId) === 0) {
520
- await restoreAgentIdleAfterRemediation(task.agentId);
521
- }
522
- if (SKIP_AUTO_RESUME_TYPES.has(task.taskType ?? "")) {
523
- rebootAffectedTasks.push({ original: failed, retryTaskId: null });
524
- continue;
525
- }
526
650
  let retryTaskId = null;
527
- if (task.routingAffinityInvalid) {
528
- console.error(`[Heartbeat] Reboot retry suppressed for ${task.id.slice(0, 8)}: invalid routing affinity`);
529
- rebootAffectedTasks.push({ original: failed, retryTaskId: null });
530
- continue;
531
- }
532
- const existingRetry = await getDbClient().get(`SELECT id FROM agent_tasks
651
+ try {
652
+ if (await getActiveTaskCount(task.agentId) === 0) {
653
+ await restoreAgentIdleAfterRemediation(task.agentId);
654
+ }
655
+ if (SKIP_AUTO_RESUME_TYPES.has(task.taskType ?? "")) {
656
+ rebootAffectedTasks.push({ original: failed, retryTaskId: null });
657
+ continue;
658
+ }
659
+ if (task.routingAffinityInvalid) {
660
+ console.error(`[Heartbeat] Reboot retry suppressed for ${task.id.slice(0, 8)}: invalid routing affinity`);
661
+ rebootAffectedTasks.push({ original: failed, retryTaskId: null });
662
+ continue;
663
+ }
664
+ const existingRetry = await getDbClient().get(`SELECT id FROM agent_tasks
533
665
  WHERE parentTaskId = ?
534
666
  AND status NOT IN ('completed', 'failed', 'cancelled')
535
667
  LIMIT 1`, [task.id]);
536
- if (!existingRetry) {
537
- try {
538
- let preferredAgentId;
539
- let sourceCandidate = await getPinCandidateAgent(task.agentId);
540
- if (sourceCandidate) {
541
- const activeCount = await getActiveTaskCount(sourceCandidate.id);
542
- const maxTasks = sourceCandidate.maxTasks ?? 1;
543
- const hasCap = activeCount < maxTasks;
544
- if (hasCap) {
545
- preferredAgentId = sourceCandidate.id;
546
- } else {
547
- sourceCandidate = null;
548
- console.warn(`[Heartbeat] Reboot retry for task ${task.id.slice(0, 8)} NOT pinned: agent ${task.agentId.slice(0, 8)} at capacity (${activeCount}/${maxTasks}); falling back to affinity-gated pool`);
668
+ if (!existingRetry) {
669
+ try {
670
+ let preferredAgentId;
671
+ let sourceCandidate = await getPinCandidateAgent(task.agentId);
672
+ if (sourceCandidate) {
673
+ const activeCount = await getActiveTaskCount(sourceCandidate.id);
674
+ const maxTasks = sourceCandidate.maxTasks ?? 1;
675
+ const hasCap = activeCount < maxTasks;
676
+ if (hasCap) {
677
+ preferredAgentId = sourceCandidate.id;
678
+ } else {
679
+ sourceCandidate = null;
680
+ console.warn(`[Heartbeat] Reboot retry for task ${task.id.slice(0, 8)} NOT pinned: agent ${task.agentId.slice(0, 8)} at capacity (${activeCount}/${maxTasks}); falling back to affinity-gated pool`);
681
+ }
549
682
  }
550
- }
551
- const leadOnly = task.routingAffinity?.leadOnly === true;
552
- const authorization = await resolveLeadOnlyRecoveryAssignment(task, sourceCandidate);
553
- if (leadOnly)
554
- preferredAgentId = authorization.agentId;
555
- const tags = ["reboot-retry", "auto-generated"];
556
- if (preferredAgentId !== undefined)
557
- tags.push(REBOOT_RETRY_PIN_TAG);
558
- const sourceAffinity = await buildRoutingAffinityFromAgent(task.agentId) ?? undefined;
559
- const routingAffinity = leadOnly ? {
560
- ...sourceAffinity ?? task.routingAffinity,
561
- capabilities: task.routingAffinity?.capabilities ?? sourceAffinity?.capabilities ?? [],
562
- leadOnly: true
563
- } : sourceAffinity;
564
- const retryTask = await createTaskExtended(task.task, {
565
- parentTaskId: task.id,
566
- agentId: preferredAgentId,
567
- routingReason: preferredAgentId === undefined ? undefined : preferredAgentId === task.agentId ? "continuity" : "reroute_fault",
568
- routingSource: preferredAgentId === undefined ? undefined : "engine_default",
569
- tags,
570
- priority: task.priority,
571
- source: task.source,
572
- taskType: task.taskType ?? undefined,
573
- routingAffinity
574
- });
575
- if (authorization.decision) {
576
- await createLogEntry({
577
- eventType: "task_recovery_authorization",
578
- taskId: retryTask.id,
683
+ const leadOnly = task.routingAffinity?.leadOnly === true;
684
+ const authorization = await resolveLeadOnlyRecoveryAssignment(task, sourceCandidate);
685
+ if (leadOnly)
686
+ preferredAgentId = authorization.agentId;
687
+ const tags = ["reboot-retry", "auto-generated"];
688
+ if (preferredAgentId !== undefined)
689
+ tags.push(REBOOT_RETRY_PIN_TAG);
690
+ const sourceAffinity = await buildRoutingAffinityFromAgent(task.agentId) ?? undefined;
691
+ const routingAffinity = leadOnly ? {
692
+ ...sourceAffinity ?? task.routingAffinity,
693
+ capabilities: task.routingAffinity?.capabilities ?? sourceAffinity?.capabilities ?? [],
694
+ leadOnly: true
695
+ } : sourceAffinity;
696
+ const retryTask = await createTaskExtended(task.task, {
697
+ parentTaskId: task.id,
579
698
  agentId: preferredAgentId,
580
- metadata: {
581
- leadOnly: true,
582
- parentTaskId: task.id,
583
- sourceAgentId: task.agentId,
584
- decision: authorization.decision
585
- }
699
+ routingReason: preferredAgentId === undefined ? undefined : preferredAgentId === task.agentId ? "continuity" : "reroute_fault",
700
+ routingSource: preferredAgentId === undefined ? undefined : "engine_default",
701
+ tags,
702
+ priority: task.priority,
703
+ source: task.source,
704
+ taskType: task.taskType ?? undefined,
705
+ inheritParentFollowUpConfig: true,
706
+ routingAffinity
586
707
  });
708
+ if (authorization.decision) {
709
+ await createLogEntry({
710
+ eventType: "task_recovery_authorization",
711
+ taskId: retryTask.id,
712
+ agentId: preferredAgentId,
713
+ metadata: {
714
+ leadOnly: true,
715
+ parentTaskId: task.id,
716
+ sourceAgentId: task.agentId,
717
+ decision: authorization.decision
718
+ }
719
+ });
720
+ }
721
+ retryTaskId = retryTask.id;
722
+ console.log(`[Heartbeat] Reboot retry created: ${retryTaskId} (parent: ${task.id})`);
723
+ } catch (err) {
724
+ console.error(`[Heartbeat] Failed to create retry task for ${task.id}:`, err);
587
725
  }
588
- retryTaskId = retryTask.id;
589
- console.log(`[Heartbeat] Reboot retry created: ${retryTaskId} (parent: ${task.id})`);
590
- } catch (err) {
591
- console.error(`[Heartbeat] Failed to create retry task for ${task.id}:`, err);
592
726
  }
727
+ rebootAffectedTasks.push({ original: failed, retryTaskId });
728
+ } finally {
729
+ await settleRebootSweptDependents(task.id, retryTaskId);
593
730
  }
594
- rebootAffectedTasks.push({ original: failed, retryTaskId });
595
731
  }
596
732
  console.log(`[Heartbeat] Reboot sweep complete: ${rebootAffectedTasks.length} task(s) auto-failed and retried`);
597
733
  } finally {
598
734
  isSweeping = false;
599
735
  }
600
736
  }
737
+ var NEVER_STARTED_STATUSES = new Set([
738
+ "draft",
739
+ "backlog",
740
+ "unassigned",
741
+ "offered",
742
+ "reviewing",
743
+ "pending"
744
+ ]);
745
+ async function settleRebootSweptDependents(sweptId, retryTaskId) {
746
+ try {
747
+ if (retryTaskId) {
748
+ for (const dep of await getDependentTasks(sweptId)) {
749
+ if (!NEVER_STARTED_STATUSES.has(dep.status))
750
+ continue;
751
+ const dependsOn = [
752
+ ...new Set(dep.dependsOn.map((id) => id === sweptId ? retryTaskId : id))
753
+ ];
754
+ const row = await getDbClient().get(`UPDATE agent_tasks
755
+ SET dependsOn = ?, lastUpdatedAt = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
756
+ WHERE id = ? AND status = ?
757
+ AND EXISTS (SELECT 1 FROM json_each(agent_tasks.dependsOn) WHERE value = ?)
758
+ RETURNING id`, [JSON.stringify(dependsOn), dep.id, dep.status, sweptId]);
759
+ if (!row)
760
+ continue;
761
+ try {
762
+ await createLogEntry({
763
+ eventType: "task_dependency_repointed",
764
+ taskId: dep.id,
765
+ agentId: dep.agentId ?? undefined,
766
+ oldValue: sweptId,
767
+ newValue: retryTaskId,
768
+ metadata: { reason: "reboot_retry" }
769
+ });
770
+ } catch {}
771
+ console.log(`[Heartbeat] Reboot sweep: dependent ${dep.id.slice(0, 8)} re-pointed from ${sweptId.slice(0, 8)} to retry ${retryTaskId.slice(0, 8)}`);
772
+ }
773
+ }
774
+ await cascadeFailDependents(sweptId, "failed");
775
+ } catch (err) {
776
+ console.error(`[Heartbeat] Reboot sweep: settling dependents of ${sweptId} failed:`, err);
777
+ }
778
+ }
601
779
  function getRebootAffectedTasks() {
602
780
  return rebootAffectedTasks;
603
781
  }
@@ -764,6 +942,18 @@ async function cleanupStaleResources(findings) {
764
942
  } catch {
765
943
  findings.staleCleanup.workflowRuns = 0;
766
944
  }
945
+ try {
946
+ findings.staleCleanup.approvalTimedOut = (await timeoutExpiredApprovalRequests()).timedOut.length;
947
+ } catch (err) {
948
+ console.error("[heartbeat] approval timeout sweep failed:", err);
949
+ findings.staleCleanup.approvalTimedOut = 0;
950
+ }
951
+ try {
952
+ findings.staleCleanup.approvalAutoCancelled = (await autoCancelStaleApprovalRequests()).cancelled.length;
953
+ } catch (err) {
954
+ console.error("[heartbeat] approval auto-cancel sweep failed:", err);
955
+ findings.staleCleanup.approvalAutoCancelled = 0;
956
+ }
767
957
  }
768
958
  function isEffectivelyEmpty(content) {
769
959
  const lines = content.split(`
@@ -970,7 +1160,9 @@ async function runHeartbeatSweep() {
970
1160
  workflowRuns: 0,
971
1161
  staleRuntimes: 0,
972
1162
  staleOfferedTasks: 0,
973
- abandonedDraftTasks: 0
1163
+ abandonedDraftTasks: 0,
1164
+ approvalAutoCancelled: 0,
1165
+ approvalTimedOut: 0
974
1166
  }
975
1167
  };
976
1168
  cleanupOnlyFindings.staleCleanup.staleRuntimes = (await expireStaleRuntimeInstances()).expired;
@@ -1018,9 +1210,11 @@ function logFindings(findings) {
1018
1210
  inboxProcessing,
1019
1211
  workflowRuns,
1020
1212
  staleOfferedTasks,
1021
- abandonedDraftTasks
1213
+ abandonedDraftTasks,
1214
+ approvalAutoCancelled,
1215
+ approvalTimedOut
1022
1216
  } = findings.staleCleanup;
1023
- const totalCleanup = sessions + reviewingTasks + mentionProcessing + inboxProcessing + workflowRuns;
1217
+ const totalCleanup = sessions + reviewingTasks + mentionProcessing + inboxProcessing + workflowRuns + approvalAutoCancelled + approvalTimedOut;
1024
1218
  if (totalCleanup > 0) {
1025
1219
  parts.push(`stale_cleanup=${totalCleanup}`);
1026
1220
  }
@@ -1086,21 +1280,29 @@ async function createBootTriageTask() {
1086
1280
  });
1087
1281
  console.log(`[Heartbeat] Boot triage task created for lead ${lead.name}`);
1088
1282
  }
1089
- function startHeartbeatChecklist(intervalMs = HEARTBEAT_CHECKLIST_INTERVAL_MS) {
1090
- if (HEARTBEAT_CHECKLIST_DISABLE) {
1283
+ function startHeartbeatChecklist(intervalMs = heartbeatChecklistIntervalMs()) {
1284
+ if (isHeartbeatChecklistDisabled()) {
1091
1285
  console.log("[Heartbeat] Checklist disabled via HEARTBEAT_CHECKLIST_DISABLE");
1092
1286
  return;
1093
1287
  }
1094
- if (checklistInterval) {
1288
+ if (checklistInterval || bootTriageTimeout) {
1289
+ return;
1290
+ }
1291
+ bootTriageTimeout = setTimeout(() => createBootTriageTask(), 90000);
1292
+ if (intervalMs <= 0) {
1293
+ console.log("[Heartbeat] Recurring checklist off (HEARTBEAT_CHECKLIST_INTERVAL_MS=0); boot triage still scheduled");
1095
1294
  return;
1096
1295
  }
1097
1296
  console.log(`[Heartbeat] Checklist starting with ${intervalMs}ms interval`);
1098
- setTimeout(() => createBootTriageTask(), 90000);
1099
1297
  checklistInterval = setInterval(() => {
1100
1298
  checkHeartbeatChecklist().catch((err) => console.error("[Heartbeat] checklist check failed:", scrubSecrets(err instanceof Error ? err.message : String(err))));
1101
1299
  }, intervalMs);
1102
1300
  }
1103
1301
  function stopHeartbeatChecklist() {
1302
+ if (bootTriageTimeout) {
1303
+ clearTimeout(bootTriageTimeout);
1304
+ bootTriageTimeout = null;
1305
+ }
1104
1306
  if (checklistInterval) {
1105
1307
  clearInterval(checklistInterval);
1106
1308
  checklistInterval = null;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getSystemMessageText
3
- } from "./cli-mcnhgnn1.js";
3
+ } from "./cli-ykk5jaax.js";
4
4
 
5
5
  // node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.js
6
6
  class UnsupportedStrictJsonSchemaError extends Error {
@@ -313,10 +313,9 @@ function clampMaxTokensToContext(model, context, maxTokens) {
313
313
  return Math.min(maxTokens, Math.max(MIN_MAX_TOKENS, available));
314
314
  }
315
315
  function buildBaseOptions(model, context, options, apiKey) {
316
- const samplingParams = model.samplingParams || options?.samplingParams ? { ...model.samplingParams, ...options?.samplingParams } : undefined;
317
316
  return {
318
317
  temperature: options?.temperature,
319
- samplingParams,
318
+ samplingParams: options?.samplingParams,
320
319
  maxTokens: clampMaxTokensToContext(model, context, options?.maxTokens ?? model.maxTokens),
321
320
  signal: options?.signal,
322
321
  telemetryContext: options?.telemetryContext,
@@ -328,6 +327,7 @@ function buildBaseOptions(model, context, options, apiKey) {
328
327
  headers: options?.headers,
329
328
  onPayload: options?.onPayload,
330
329
  onResponse: options?.onResponse,
330
+ onProviderStreamEvent: options?.onProviderStreamEvent,
331
331
  timeoutMs: options?.timeoutMs,
332
332
  websocketConnectTimeoutMs: options?.websocketConnectTimeoutMs,
333
333
  maxRetries: options?.maxRetries,