@desplega.ai/agent-swarm 1.131.1 → 1.134.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 (360) hide show
  1. package/README.md +3 -3
  2. package/dist/{actions-jgcy477k.js → actions-7kast243.js} +20 -18
  3. package/dist/{anthropic-messages-rjmd2e7n.js → anthropic-messages-706yad38.js} +33 -17
  4. package/dist/app-0g84t8wf.js +28 -0
  5. package/dist/{artifact-jysj3wrg.js → artifact-dje5ke4h.js} +37 -131
  6. package/dist/{assistant-f2vkk1hj.js → assistant-ac4htcky.js} +25 -22
  7. package/dist/{azure-openai-responses-c0yjmbfd.js → azure-openai-responses-be59fbsz.js} +13 -13
  8. package/dist/{boot-reembed-q7mp8hcr.js → boot-reembed-b1rcqn85.js} +13 -11
  9. package/dist/{boot-reembed-xmw8wcx6.js → boot-reembed-kw2541c4.js} +14 -12
  10. package/dist/{boot-scrub-logs-dsqrv79n.js → boot-scrub-logs-ja29t92g.js} +11 -9
  11. package/dist/{claude-adapter-q6x7yspx.js → claude-adapter-5cg1fv8s.js} +33 -29
  12. package/dist/{claude-managed-adapter-wsg37bt8.js → claude-managed-adapter-9z9sdytx.js} +9 -9
  13. package/dist/{claude-managed-setup-52z4mq9w.js → claude-managed-setup-3zqp51cr.js} +5 -5
  14. package/dist/{claude-1ex232fc.js → claude-wqn3dtca.js} +1 -1
  15. package/dist/{cli-4wgngmwv.js → cli-00w4hbam.js} +1 -1
  16. package/dist/{cli-er3a4bb0.js → cli-15429qdw.js} +6 -1
  17. package/dist/{cli-e5dabkx0.js → cli-1cwhyvta.js} +4 -4
  18. package/dist/{cli-zsspvvm2.js → cli-1ybr6vw2.js} +237 -237
  19. package/dist/{cli-xpxde7rm.js → cli-2wv4kj0e.js} +60 -31
  20. package/dist/cli-34w2584r.js +530 -0
  21. package/dist/{cli-se2p6rkb.js → cli-38taxznr.js} +6 -6
  22. package/dist/{cli-9sbhdpvb.js → cli-3cgfyfzm.js} +14 -14
  23. package/dist/{cli-5n6e5yfn.js → cli-3zmdzfjf.js} +79 -74
  24. package/dist/{cli-3ty0t082.js → cli-43x36mty.js} +197 -8
  25. package/dist/{cli-ycrnynpw.js → cli-480nehnh.js} +29 -22
  26. package/dist/{cli-0258203w.js → cli-492e7ap5.js} +140 -20
  27. package/dist/{cli-3fj60etf.js → cli-497b685t.js} +3 -3
  28. package/dist/{cli-pxfxkx5m.js → cli-4bap00k0.js} +1 -1
  29. package/dist/{cli-w2wxd56v.js → cli-4bc8vmhm.js} +848 -770
  30. package/dist/{cli-aca5pz9f.js → cli-589599p9.js} +1 -1
  31. package/dist/{cli-t930g0xh.js → cli-5tnr64pm.js} +1 -1
  32. package/dist/{cli-jxg3s9ey.js → cli-65d93ves.js} +7 -7
  33. package/dist/{cli-6dpytdr2.js → cli-6x363v1z.js} +2 -2
  34. package/dist/{cli-dxak0fqd.js → cli-787ph852.js} +11 -11
  35. package/dist/{cli-793jvbsh.js → cli-7bv8nckk.js} +16 -11
  36. package/dist/{cli-zyxs93y9.js → cli-7jcc9y1r.js} +3 -3
  37. package/dist/{cli-f1am9szv.js → cli-87t2gstf.js} +1 -1
  38. package/dist/{cli-9aryf9tv.js → cli-95m51ztz.js} +1 -1
  39. package/dist/{cli-4w4fmq9x.js → cli-9w49enmh.js} +2 -2
  40. package/dist/{cli-v69vk5h0.js → cli-9y5b02vr.js} +13 -13
  41. package/dist/{cli-x23me2mg.js → cli-a1rrkrb4.js} +1 -1
  42. package/dist/{cli-psrqtw2m.js → cli-a3pkfpqs.js} +2 -2
  43. package/dist/{cli-h0rgxd24.js → cli-a4ajmfvp.js} +6 -6
  44. package/dist/{cli-ygrbmjja.js → cli-aw8bb6sf.js} +6 -6
  45. package/dist/{cli-g74vpjp2.js → cli-brm3et47.js} +55 -22
  46. package/dist/{cli-czkae1fp.js → cli-c5ddbdfj.js} +9 -9
  47. package/dist/{cli-114fvtmj.js → cli-c79a9zrc.js} +1 -1
  48. package/dist/{cli-49n9f49x.js → cli-dx3dz0ms.js} +3 -3
  49. package/dist/{cli-6dp3ydxa.js → cli-e07exmsb.js} +18 -14
  50. package/dist/cli-et1bbwqf.js +13 -0
  51. package/dist/{cli-yazx6hap.js → cli-f3s9dry0.js} +14 -14
  52. package/dist/{cli-t8d349cy.js → cli-f4wj0s3m.js} +3 -3
  53. package/dist/{cli-d6n0thxw.js → cli-f64gdfxc.js} +1 -1
  54. package/dist/{cli-pwfsqc2x.js → cli-fyd58xgb.js} +55 -55
  55. package/dist/{cli-7dm2zqy2.js → cli-g0j14czv.js} +2 -2
  56. package/dist/{cli-b0p7rfnd.js → cli-g2p9bd1z.js} +14 -14
  57. package/dist/{cli-z905tvmm.js → cli-g814jbst.js} +2 -2
  58. package/dist/{cli-5dsbcjjw.js → cli-ghexzd2d.js} +970 -970
  59. package/dist/{cli-jvv0g8bh.js → cli-gpt9kf01.js} +15 -15
  60. package/dist/{cli-rgrfzg8z.js → cli-grt6qv91.js} +380 -380
  61. package/dist/{cli-wz9115x0.js → cli-gtafvdy0.js} +8 -8
  62. package/dist/{cli-q5dzzak0.js → cli-gy07xk4s.js} +2 -2
  63. package/dist/{cli-sy7jk3tx.js → cli-h0djenzm.js} +2 -2
  64. package/dist/{cli-nrkkknat.js → cli-h37gbjbf.js} +2 -281
  65. package/dist/{cli-jevgrb4w.js → cli-h39xxnq6.js} +1200 -491
  66. package/dist/{cli-gz9sbyk3.js → cli-jepmgn7r.js} +1 -1
  67. package/dist/{cli-ccf9vy7q.js → cli-jmvk6et8.js} +7 -7
  68. package/dist/{cli-2rk0cx7s.js → cli-jxj92gkt.js} +51 -41
  69. package/dist/{cli-bqw0mt1n.js → cli-k46t4664.js} +18 -3
  70. package/dist/{cli-50vbt00w.js → cli-m07313tr.js} +1153 -696
  71. package/dist/{cli-4j2mrzag.js → cli-mkq1rk7b.js} +1 -1
  72. package/dist/{cli-1z7048dy.js → cli-mnm7w46e.js} +1 -1
  73. package/dist/{cli-kd1ck4rx.js → cli-mp9sg4cg.js} +14 -8
  74. package/dist/{cli-jbcva0xj.js → cli-mrammd8c.js} +60 -35
  75. package/dist/cli-nanaxrz6.js +27 -0
  76. package/dist/{cli-p9swy5t3.js → cli-pq2ee5ja.js} +8 -6
  77. package/dist/{cli-2wadx7p2.js → cli-pt43pdp1.js} +2 -2
  78. package/dist/{cli-7sgrxg9a.js → cli-q6d0vvey.js} +4 -4
  79. package/dist/{cli-k9qkf1hw.js → cli-qf9kpsve.js} +9 -9
  80. package/dist/cli-qh4sqfws.js +15 -0
  81. package/dist/{cli-e15jhafb.js → cli-qntkxysp.js} +14 -14
  82. package/dist/{cli-sajgpkqg.js → cli-qs9hhsvb.js} +1723 -325
  83. package/dist/{cli-z2zcxes1.js → cli-qt5bt3vk.js} +1 -1
  84. package/dist/{cli-wx82tw1k.js → cli-qtekrty1.js} +3 -3
  85. package/dist/{cli-g1re8r05.js → cli-rh6f3s9n.js} +3 -3
  86. package/dist/{cli-n0krnc6d.js → cli-rzhcrw2p.js} +2 -2
  87. package/dist/{cli-gecy3z2s.js → cli-snw62ze5.js} +4 -4
  88. package/dist/{cli-n6h8qt8n.js → cli-snz3p4yf.js} +15 -10
  89. package/dist/{cli-r6kqqbj0.js → cli-tkf8n6cw.js} +11 -11
  90. package/dist/{cli-4rkfg1wx.js → cli-tkrr24mz.js} +14 -9
  91. package/dist/{cli-9dr5qzc0.js → cli-tv9f1kyb.js} +54 -43
  92. package/dist/{cli-gm9cbhbq.js → cli-vtz6yj3v.js} +28 -9
  93. package/dist/{cli-2f07m0xr.js → cli-wf86d5t7.js} +1 -1
  94. package/dist/{cli-7zd05xb4.js → cli-whrvct19.js} +45 -45
  95. package/dist/{cli-ap1czx8f.js → cli-wrrea8xm.js} +3 -3
  96. package/dist/{cli-57khth04.js → cli-xmyqv00z.js} +120 -4
  97. package/dist/{cli-cwy5hqbq.js → cli-yjmk7tzc.js} +1 -1
  98. package/dist/{cli-6pcz9h15.js → cli-zykjrwcx.js} +180 -394
  99. package/dist/cli.js +45 -45
  100. package/dist/{codex-adapter-htjkn22b.js → codex-adapter-hsq6mz3m.js} +21 -19
  101. package/dist/{codex-hook-hq54t9ft.js → codex-hook-8c500gq8.js} +8 -7
  102. package/dist/{codex-login-z6yhbkmk.js → codex-login-x7603481.js} +3 -3
  103. package/dist/{codex-session-runner-wjfc7smz.js → codex-session-runner-c1x3x143.js} +15 -13
  104. package/dist/{commands-xhrfwqsk.js → commands-rwtddtst.js} +11 -9
  105. package/dist/{db-anvwb22f.js → db-j2b355vz.js} +458 -444
  106. package/dist/{devin-adapter-v1sarqtw.js → devin-adapter-8qmhqpy3.js} +3 -3
  107. package/dist/{devtools-2y1r7yqk.js → devtools-j2rnj8w7.js} +4 -4
  108. package/dist/{e2b-jdkwemv2.js → e2b-znpx78eg.js} +16 -16
  109. package/dist/{es5-vjgtkgp6.js → es5-fmqrjzy3.js} +2 -2
  110. package/dist/{event-bus-axn823e9.js → event-bus-n8sb35pw.js} +4 -4
  111. package/dist/{getMachineId-bsd-6tc9wxdj.js → getMachineId-bsd-wpzbhkm6.js} +4 -4
  112. package/dist/{getMachineId-darwin-sjt9sgnc.js → getMachineId-darwin-45zabjy0.js} +4 -4
  113. package/dist/{getMachineId-linux-v5n18y9p.js → getMachineId-linux-warnp5pd.js} +3 -3
  114. package/dist/{getMachineId-unsupported-yrjyqw3d.js → getMachineId-unsupported-5spent2a.js} +3 -3
  115. package/dist/{getMachineId-win-w3r8063c.js → getMachineId-win-v4bvcw7a.js} +4 -4
  116. package/dist/{google-generative-ai-hysrd8qx.js → google-generative-ai-b0wzss55.js} +17 -14
  117. package/dist/{google-vertex-p5arrga0.js → google-vertex-e8q4dpya.js} +18 -15
  118. package/dist/{handlers-b9kbc621.js → handlers-hchgrxkh.js} +32 -29
  119. package/dist/{hook-xkvn6c5h.js → hook-p49egqc0.js} +66 -52
  120. package/dist/hook-spb00w76.js +34 -0
  121. package/dist/{http-9xh6ta4r.js → http-nh14kkms.js} +663 -181
  122. package/dist/index-1qthq7vc.js +6 -0
  123. package/dist/{index-0g68f0p6.js → index-20xqmn3v.js} +3 -3
  124. package/dist/{index-vdkr5z2w.js → index-3e03k6e4.js} +114 -114
  125. package/dist/{index-ywds4812.js → index-4cbyhq2g.js} +43 -41
  126. package/dist/index-67pzqfrb.js +36 -0
  127. package/dist/{index-bccrkdkn.js → index-7m8yxkw5.js} +16 -16
  128. package/dist/{index-eaxyqcmj.js → index-dvsk64sm.js} +163 -83
  129. package/dist/{index-dqkpnmqm.js → index-e19s2m8k.js} +18 -18
  130. package/dist/{index-j30k5zxn.js → index-emvxcy98.js} +16 -16
  131. package/dist/{index-7ndw6ecy.js → index-gqnmr60d.js} +9 -9
  132. package/dist/{index-9znhar3x.js → index-j02xvjtd.js} +184 -185
  133. package/dist/{index-1s2442yw.js → index-ns5kksc1.js} +7 -7
  134. package/dist/{index-dpy2hth8.js → index-pdxc8kfh.js} +71 -71
  135. package/dist/{index-z1m7pw0v.js → index-ptcqm8bc.js} +107 -107
  136. package/dist/{index-070v4eyb.js → index-pyp7rexm.js} +5 -6
  137. package/dist/{index-86znjz1p.js → index-shne41sd.js} +13 -13
  138. package/dist/{index-2qn2qndv.js → index-t36q2v4t.js} +183 -183
  139. package/dist/index-tcnvv8w6.js +7 -0
  140. package/dist/index-w91qbfv1.js +7 -0
  141. package/dist/{index-fzc0mwvj.js → index-yqweff5n.js} +32 -32
  142. package/dist/index-yrfphye1.js +39 -0
  143. package/dist/{keepalive-vc7s2aa6.js → keepalive-9k51nqhc.js} +21 -15
  144. package/dist/lead-2xq3dxbz.js +88 -0
  145. package/dist/maintenance-0c0g6nym.js +28 -0
  146. package/dist/mistral-conversations-2njwdwhj.js +717 -0
  147. package/dist/{multipart-parser-qaktc7p8.js → multipart-parser-6gftesw0.js} +2 -2
  148. package/dist/{oauth-refresh-sweep-yecgjpk4.js → oauth-refresh-sweep-273a64r2.js} +14 -12
  149. package/dist/{onboard-xj0f73f9.js → onboard-tsv9wwhz.js} +12 -12
  150. package/dist/{openai-codex-responses-5g27pd6f.js → openai-codex-responses-kt84eq86.js} +26 -26
  151. package/dist/{openai-completions-3vkmfz2a.js → openai-completions-mrypq7qp.js} +17 -16
  152. package/dist/{openai-responses-dg4t7j7a.js → openai-responses-qhrk21ez.js} +20 -17
  153. package/dist/{opencode-adapter-1gm38aba.js → opencode-adapter-rar9676j.js} +13 -11
  154. package/dist/{openrouter-images-g3gm8931.js → openrouter-images-684fysx9.js} +5 -5
  155. package/dist/{otel-impl-nxg0n0b3.js → otel-impl-wp1mfzd2.js} +752 -537
  156. package/dist/{photon_rs-ky7dj5qw.js → photon_rs-8dwt2pzy.js} +581 -581
  157. package/dist/{pi-messages-tqj8q6b9.js → pi-messages-txp9f97r.js} +7 -7
  158. package/dist/{pi-mono-adapter-4g5kby31.js → pi-mono-adapter-yz47kk8e.js} +1910 -1180
  159. package/dist/pricing-refresh-jw1yw2fn.js +22 -0
  160. package/dist/rbac-roles-dg964c8p.js +32 -0
  161. package/dist/{rbac-roles-1hcxdtg7.js → rbac-roles-p53cg5cv.js} +19 -17
  162. package/dist/{registry-02cy9z5z.js → registry-mh12y17v.js} +4 -4
  163. package/dist/render-v2-56vn2rk9.js +36 -0
  164. package/dist/seed-pricing-52xx6z63.js +19 -0
  165. package/dist/{setup-46xtgq3c.js → setup-e8gp79sy.js} +7 -7
  166. package/dist/token-util-zy908s1a.js +6 -0
  167. package/dist/{token-fxkn2zf2.js → token-xg5711x5.js} +4 -4
  168. package/dist/worker-s17f1g46.js +88 -0
  169. package/dist/{x-6mg4kfpe.js → x-xkfh0w0v.js} +5 -5
  170. package/openapi.json +566 -22
  171. package/package.json +6 -6
  172. package/src/be/budget-refusal-notify.ts +14 -7
  173. package/src/be/db-queries/task-artifacts.ts +182 -0
  174. package/src/be/db.ts +834 -171
  175. package/src/be/events.ts +5 -0
  176. package/src/be/migrations/131_session_logs_created_at_index.sql +2 -0
  177. package/src/be/migrations/132_multi_runtime_instances.sql +44 -0
  178. package/src/be/migrations/133_workflow_run_trigger_type.sql +12 -0
  179. package/src/be/migrations/135_backfill_task_pull_request_attachments.sql +228 -0
  180. package/src/be/migrations/136_task_requester_provenance.sql +37 -0
  181. package/src/be/migrations/137_memory_retrieval_composite_index.sql +1 -0
  182. package/src/be/migrations/runner.ts +17 -11
  183. package/src/be/multi-runtime.ts +430 -0
  184. package/src/be/scripts/extract-schema.ts +3 -1
  185. package/src/be/scripts/typecheck.ts +6 -2
  186. package/src/be/seed-prompt-templates.ts +25 -2
  187. package/src/be/seed-skills/index.ts +7 -0
  188. package/src/be/steering.ts +1 -1
  189. package/src/be/swarm-config-guard.ts +18 -0
  190. package/src/commands/credential-wait.ts +54 -0
  191. package/src/commands/onboard/steps/core-credentials.tsx +1 -1
  192. package/src/commands/onboard/steps/custom-templates.tsx +1 -1
  193. package/src/commands/onboard/steps/harness-credentials.tsx +1 -1
  194. package/src/commands/onboard/steps/health-check.tsx +1 -1
  195. package/src/commands/onboard/steps/start.tsx +1 -1
  196. package/src/commands/profile-sync-audit.ts +56 -0
  197. package/src/commands/profile-sync.ts +287 -15
  198. package/src/commands/provider-credentials.ts +46 -19
  199. package/src/commands/runner.ts +199 -33
  200. package/src/commands/templates.ts +22 -0
  201. package/src/github/handlers.ts +55 -9
  202. package/src/heartbeat/heartbeat.ts +109 -17
  203. package/src/hooks/hook.ts +49 -33
  204. package/src/http/active-sessions.ts +11 -1
  205. package/src/http/agents.ts +261 -30
  206. package/src/http/all-routes.ts +1 -0
  207. package/src/http/config.ts +13 -2
  208. package/src/http/core.ts +102 -4
  209. package/src/http/db-query-bounded.ts +313 -0
  210. package/src/http/db-query-shared.ts +249 -0
  211. package/src/http/db-query.ts +54 -42
  212. package/src/http/events.ts +2 -0
  213. package/src/http/index.ts +23 -2
  214. package/src/http/mcp-bridge.ts +37 -3
  215. package/src/http/mcp.ts +12 -0
  216. package/src/http/memory.ts +13 -2
  217. package/src/http/openapi.ts +1 -0
  218. package/src/http/poll.ts +70 -27
  219. package/src/http/prompt-templates.ts +36 -13
  220. package/src/http/route-def.ts +43 -9
  221. package/src/http/schedules.ts +2 -2
  222. package/src/http/scripts.ts +10 -1
  223. package/src/http/session-data.ts +44 -0
  224. package/src/http/tasks.ts +2 -2
  225. package/src/http/users.ts +74 -52
  226. package/src/http/webhooks.ts +5 -2
  227. package/src/http/workflows.ts +1 -4
  228. package/src/integrations/kapso/inbound.ts +1 -1
  229. package/src/jira/outbound.ts +39 -8
  230. package/src/jira/webhook-lifecycle.ts +13 -2
  231. package/src/linear/outbound.ts +43 -10
  232. package/src/oauth/keepalive.ts +13 -2
  233. package/src/prompts/base-prompt.ts +1 -1
  234. package/src/prompts/default-drift.ts +21 -0
  235. package/src/prompts/session-templates.ts +56 -7
  236. package/src/providers/claude-adapter.ts +6 -0
  237. package/src/providers/codex-adapter.ts +6 -0
  238. package/src/providers/opencode-adapter.ts +6 -0
  239. package/src/providers/pi-mono-adapter.ts +8 -0
  240. package/src/providers/pricing-sources.md +24 -0
  241. package/src/queue-stall-alarm.ts +216 -0
  242. package/src/rbac/legacy-policy.ts +3 -0
  243. package/src/rbac/permissions.ts +12 -0
  244. package/src/scheduler/scheduler.ts +7 -0
  245. package/src/script-workflows/executor.ts +2 -1
  246. package/src/scripts-runtime/executors/native.ts +2 -1
  247. package/src/scripts-runtime/executors/types.ts +5 -0
  248. package/src/scripts-runtime/loader.ts +5 -0
  249. package/src/scripts-runtime/sdk-allowlist.ts +3 -0
  250. package/src/scripts-runtime/swarm-config.ts +8 -0
  251. package/src/scripts-runtime/swarm-sdk.ts +7 -0
  252. package/src/scripts-runtime/types/stdlib.d.ts +4 -0
  253. package/src/scripts-runtime/types/swarm-sdk.d.ts +4 -0
  254. package/src/server.ts +6 -0
  255. package/src/slack/channel-join.ts +22 -3
  256. package/src/slack/channel-lifecycle.ts +114 -0
  257. package/src/tests/budget-claim-gate.test.ts +20 -0
  258. package/src/tests/claude-adapter.test.ts +32 -0
  259. package/src/tests/codex-adapter.test.ts +30 -0
  260. package/src/tests/create-task-validation.test.ts +128 -0
  261. package/src/tests/credential-wait.test.ts +67 -1
  262. package/src/tests/db-query.test.ts +711 -2
  263. package/src/tests/heartbeat-checklist.test.ts +28 -0
  264. package/src/tests/http-api-integration.test.ts +81 -0
  265. package/src/tests/http-users.test.ts +166 -1
  266. package/src/tests/identity-field-budget.test.ts +176 -0
  267. package/src/tests/mcp-tools-user.test.ts +34 -0
  268. package/src/tests/mcp-user-route.test.ts +17 -0
  269. package/src/tests/metrics-http.test.ts +44 -0
  270. package/src/tests/migration-failure.test.ts +86 -0
  271. package/src/tests/multi-runtime-registration.test.ts +2810 -0
  272. package/src/tests/openapi-response-contract.test.ts +24 -0
  273. package/src/tests/openapi-route-headers.test.ts +83 -0
  274. package/src/tests/opencode-adapter.test.ts +40 -0
  275. package/src/tests/outbound-listener-rejection.test.ts +138 -0
  276. package/src/tests/pi-mono-adapter.test.ts +98 -0
  277. package/src/tests/preload.ts +2 -0
  278. package/src/tests/profile-sync-warning.test.ts +277 -0
  279. package/src/tests/profile-sync.test.ts +232 -6
  280. package/src/tests/prompt-template-resolver.test.ts +177 -6
  281. package/src/tests/prompt-template-session.test.ts +39 -3
  282. package/src/tests/queue-stall-alarm.test.ts +226 -0
  283. package/src/tests/rbac-charact-slack.test.ts +29 -0
  284. package/src/tests/rbac-engine.test.ts +3 -0
  285. package/src/tests/requester-comms.test.ts +32 -0
  286. package/src/tests/runner-requester-profile.test.ts +38 -0
  287. package/src/tests/schedule-target-type.test.ts +38 -0
  288. package/src/tests/script-connections.test.ts +13 -1
  289. package/src/tests/scripts-runtime-identity.test.ts +375 -0
  290. package/src/tests/scripts-runtime.test.ts +4 -3
  291. package/src/tests/sdk-allowlist.test.ts +47 -0
  292. package/src/tests/send-task-requested-by.test.ts +9 -0
  293. package/src/tests/session-costs.test.ts +506 -1
  294. package/src/tests/shutdown-error-scrubbing.test.ts +92 -0
  295. package/src/tests/slack-channel-lifecycle.test.ts +241 -0
  296. package/src/tests/slack-render-v2.test.ts +43 -0
  297. package/src/tests/steering-core.test.ts +28 -0
  298. package/src/tests/swarm-config-reserved-keys.test.ts +22 -0
  299. package/src/tests/task-artifacts.test.ts +386 -0
  300. package/src/tests/task-attachments-schema.test.ts +17 -1
  301. package/src/tests/task-completion-idempotency.test.ts +57 -0
  302. package/src/tests/task-pull-request-backfill-migration.test.ts +321 -0
  303. package/src/tests/tool-annotations.test.ts +4 -0
  304. package/src/tests/update-profile-api.test.ts +67 -39
  305. package/src/tests/update-profile-auth.test.ts +48 -4
  306. package/src/tests/user-attribution-migration.test.ts +54 -0
  307. package/src/tests/user-identity.test.ts +72 -0
  308. package/src/tests/workflow-async-v2.test.ts +39 -1
  309. package/src/tests/workflow-http-v2.test.ts +3 -2
  310. package/src/tests/workflow-mcp-trigger-schema.test.ts +52 -3
  311. package/src/tests/workflow-retry-v2.test.ts +45 -1
  312. package/src/tools/db-query.ts +18 -8
  313. package/src/tools/get-task-details.ts +24 -3
  314. package/src/tools/manage-user.ts +36 -3
  315. package/src/tools/poll-task.ts +93 -14
  316. package/src/tools/script-common.ts +5 -0
  317. package/src/tools/send-task.ts +1 -4
  318. package/src/tools/slack-archive-channel.ts +70 -0
  319. package/src/tools/slack-create-channel.ts +74 -0
  320. package/src/tools/slack-invite-to-channel.ts +78 -0
  321. package/src/tools/store-progress.ts +13 -2
  322. package/src/tools/swarm-config/delete-config.ts +9 -0
  323. package/src/tools/swarm-config/set-config.ts +3 -2
  324. package/src/tools/task-action.ts +30 -0
  325. package/src/tools/task-tool-ctx.ts +8 -1
  326. package/src/tools/tool-config.ts +4 -1
  327. package/src/tools/update-profile.ts +16 -21
  328. package/src/tools/utils.ts +5 -0
  329. package/src/tools/workflows/trigger-workflow.ts +7 -1
  330. package/src/types.ts +165 -1
  331. package/src/utils/github-pull-request.ts +76 -0
  332. package/src/utils/identity-field-budget.ts +73 -0
  333. package/src/utils/multi-runtime.ts +20 -0
  334. package/src/utils/requester-comms.ts +24 -0
  335. package/src/workflows/engine.ts +22 -2
  336. package/src/workflows/resume.ts +19 -11
  337. package/src/workflows/retry-poller.ts +1 -0
  338. package/src/workflows/triggers.ts +4 -0
  339. package/templates/skills/db-query-guidance/config.json +14 -0
  340. package/templates/skills/db-query-guidance/content.md +57 -0
  341. package/dist/app-5da78bd4.js +0 -26
  342. package/dist/cli-3te4jdkm.js +0 -225
  343. package/dist/cli-bmze986d.js +0 -7
  344. package/dist/cli-kh3ba2zf.js +0 -607
  345. package/dist/hook-cgk4wxmx.js +0 -31
  346. package/dist/index-25wjsdv2.js +0 -34
  347. package/dist/index-76at2ymp.js +0 -7
  348. package/dist/index-hase6zbe.js +0 -6
  349. package/dist/index-vg4snay4.js +0 -36
  350. package/dist/index-vy8edt27.js +0 -7
  351. package/dist/lead-r2yqfmx7.js +0 -85
  352. package/dist/maintenance-mw70k468.js +0 -26
  353. package/dist/mistral-conversations-81fwav0j.js +0 -30578
  354. package/dist/otel-nqa12wf3.js +0 -3149
  355. package/dist/pricing-refresh-2cn6effr.js +0 -20
  356. package/dist/rbac-roles-vynday5g.js +0 -30
  357. package/dist/render-v2-tc0bh8kk.js +0 -34
  358. package/dist/seed-pricing-8kceb43f.js +0 -17
  359. package/dist/token-util-pqyc8kng.js +0 -6
  360. package/dist/worker-qrbz6hmv.js +0 -85
@@ -45,6 +45,7 @@ import {
45
45
  getKapsoNumberMapping,
46
46
  getLinksForMemory,
47
47
  getOAuthPreset,
48
+ getParseErrorMessage,
48
49
  getPathSegments,
49
50
  getTaskDetailsHandler,
50
51
  getTaskDetailsInputSchema,
@@ -52,6 +53,7 @@ import {
52
53
  getTasksHandler,
53
54
  getTasksInputSchema,
54
55
  getTasksOutputSchema,
56
+ getUserCommsPrefs,
55
57
  guardTerminalTaskResultWrite,
56
58
  handleAgentSessionEvent,
57
59
  handleAgentSessionPrompted,
@@ -104,6 +106,7 @@ import {
104
106
  markScriptSdkRequestOrigin,
105
107
  mcpOverflowAuthError,
106
108
  mergeScheduleTiming,
109
+ normalizeObjectSchema,
107
110
  parseBody,
108
111
  parseQueryParams,
109
112
  parseSkillContent,
@@ -119,6 +122,8 @@ import {
119
122
  resolveScriptsOnlyMode,
120
123
  resolveTaskAuditUserId,
121
124
  route,
125
+ runtimeInstanceHeader,
126
+ safeParseAsync,
122
127
  safeRequestUrlForLog,
123
128
  scheduleIntegrationsReload,
124
129
  scopedResourceScopeIdSchema,
@@ -152,15 +157,15 @@ import {
152
157
  withRemoteContext,
153
158
  withSpanContext,
154
159
  writeSkillsToFilesystem
155
- } from "./cli-jevgrb4w.js";
156
- import"./cli-1z7048dy.js";
160
+ } from "./cli-h39xxnq6.js";
161
+ import"./cli-mnm7w46e.js";
157
162
  import {
158
163
  Anthropic
159
- } from "./cli-gz9sbyk3.js";
164
+ } from "./cli-jepmgn7r.js";
160
165
  import {
161
166
  REFERENCES_SOURCE_MAX_LENGTH,
162
167
  sanitizeReferencesSource
163
- } from "./cli-2wadx7p2.js";
168
+ } from "./cli-pt43pdp1.js";
164
169
  import {
165
170
  deriveCodexKeySuffix,
166
171
  getValidCodexOAuth,
@@ -173,34 +178,48 @@ import {
173
178
  checkHeartbeatChecklist,
174
179
  runHeartbeatSweep,
175
180
  stopHeartbeat
176
- } from "./cli-g74vpjp2.js";
181
+ } from "./cli-brm3et47.js";
177
182
  import {
183
+ AGENT_MAX_TASKS_CONFIG_KEY,
178
184
  createResumeFollowUp,
179
- createWorkerTaskFollowUp
180
- } from "./cli-3ty0t082.js";
185
+ createWorkerTaskFollowUp,
186
+ getRuntimeInstanceById,
187
+ listRuntimeInstancesForAgent,
188
+ reconcileAgentMaxTasksPolicy,
189
+ reconcileAgentStatusFromRuntimes,
190
+ resetAgentMaxTasksMirror,
191
+ runtimeStaleThresholdMinutes,
192
+ setRuntimeCredentialReady,
193
+ touchRuntimeInstance,
194
+ upsertRuntimeInstance,
195
+ upsertSwarmConfigWithPolicyMirror
196
+ } from "./cli-43x36mty.js";
197
+ import {
198
+ isMultiRuntimeEnabled
199
+ } from "./cli-qh4sqfws.js";
181
200
  import {
182
201
  calculateNextRun,
183
202
  dispatchScheduleTarget,
184
203
  ensure,
185
204
  initialize,
186
205
  require_dist
187
- } from "./cli-ycrnynpw.js";
206
+ } from "./cli-480nehnh.js";
188
207
  import {
189
208
  getModelsCatalog
190
- } from "./cli-t8d349cy.js";
209
+ } from "./cli-f4wj0s3m.js";
191
210
  import {
192
211
  normalizeModelKey
193
- } from "./cli-114fvtmj.js";
212
+ } from "./cli-c79a9zrc.js";
194
213
  import {
195
214
  getUserGrant
196
- } from "./cli-sy7jk3tx.js";
215
+ } from "./cli-h0djenzm.js";
197
216
  import {
198
217
  can,
199
218
  clearAuditSink,
200
219
  decideToolAdmission,
201
220
  isRbacEnabled,
202
221
  setAuditSink
203
- } from "./cli-bqw0mt1n.js";
222
+ } from "./cli-k46t4664.js";
204
223
  import {
205
224
  ensureAgentFsCredentialsForAgent,
206
225
  extractArgsJsonSchema,
@@ -210,12 +229,12 @@ import {
210
229
  scriptSdkTypesWithGeneratedApis,
211
230
  scriptStdlibTypesWithGeneratedApis,
212
231
  typecheckScript
213
- } from "./cli-4rkfg1wx.js";
232
+ } from "./cli-tkrr24mz.js";
214
233
  import {
215
234
  collectScriptReferences,
216
235
  getApp,
217
236
  listAppRecords
218
- } from "./cli-gecy3z2s.js";
237
+ } from "./cli-snw62ze5.js";
219
238
  import {
220
239
  RawLlmConfigSchema,
221
240
  RawLlmOutputSchema,
@@ -235,7 +254,7 @@ import {
235
254
  validateDefinition,
236
255
  validateJsonSchema,
237
256
  verifyHmacSignature
238
- } from "./cli-jbcva0xj.js";
257
+ } from "./cli-mrammd8c.js";
239
258
  import"./cli-3dpj7atn.js";
240
259
  import {
241
260
  ConnectionAuthInputSchema,
@@ -307,14 +326,14 @@ import {
307
326
  upsertMcpOAuthToken,
308
327
  upsertScriptByName,
309
328
  upsertScriptConnection
310
- } from "./cli-6dp3ydxa.js";
311
- import"./cli-epan13p1.js";
329
+ } from "./cli-e07exmsb.js";
312
330
  import {
313
331
  getApiKey
314
332
  } from "./cli-f14fvzag.js";
333
+ import"./cli-epan13p1.js";
315
334
  import {
316
335
  searchScripts
317
- } from "./cli-g1re8r05.js";
336
+ } from "./cli-rh6f3s9n.js";
318
337
  import {
319
338
  CANDIDATE_SET_MULTIPLIER,
320
339
  getEmbeddingProvider,
@@ -322,8 +341,8 @@ import {
322
341
  init_constants as init_constants2,
323
342
  init_reranker,
324
343
  rerank
325
- } from "./cli-se2p6rkb.js";
326
- import"./cli-0258203w.js";
344
+ } from "./cli-38taxznr.js";
345
+ import"./cli-492e7ap5.js";
327
346
  import {
328
347
  acquireOAuthRefreshLock,
329
348
  buildAuthorizationUrl,
@@ -347,14 +366,14 @@ import {
347
366
  updateAuthorizationIdentity,
348
367
  updateOAuthAppById,
349
368
  upsertAuthorization
350
- } from "./cli-nrkkknat.js";
369
+ } from "./cli-h37gbjbf.js";
351
370
  import"./cli-fad8m16k.js";
352
371
  import {
353
372
  FilesError,
354
373
  getFileStorageProvider,
355
374
  normalizeFilesError
356
375
  } from "./cli-bnx54kxv.js";
357
- import"./cli-6dpytdr2.js";
376
+ import"./cli-6x363v1z.js";
358
377
  import {
359
378
  findUserById,
360
379
  fingerprintApiKey,
@@ -370,18 +389,18 @@ import {
370
389
  resolveUserByToken,
371
390
  revokeToken,
372
391
  unlinkIdentity
373
- } from "./cli-aca5pz9f.js";
392
+ } from "./cli-589599p9.js";
374
393
  import {
375
394
  createTaskWithSiblingAwareness
376
- } from "./cli-2f07m0xr.js";
395
+ } from "./cli-wf86d5t7.js";
377
396
  import {
378
397
  getSlackApp,
379
398
  startSlackApp,
380
399
  stopSlackApp
381
- } from "./cli-rgrfzg8z.js";
382
- import"./cli-k9qkf1hw.js";
383
- import"./cli-b0p7rfnd.js";
384
- import"./cli-t930g0xh.js";
400
+ } from "./cli-grt6qv91.js";
401
+ import"./cli-qf9kpsve.js";
402
+ import"./cli-g2p9bd1z.js";
403
+ import"./cli-5tnr64pm.js";
385
404
  import {
386
405
  ActiveSessionSchema,
387
406
  AgentAvatarSchema,
@@ -449,6 +468,7 @@ import {
449
468
  RepoGuidelinesSchema,
450
469
  RepoHooksSchema,
451
470
  ResumeReasonSchema,
471
+ RuntimeInstanceSchema,
452
472
  ScheduledTaskSchema,
453
473
  ScheduledTaskTargetTypeSchema,
454
474
  ScriptApiAuthModeSchema,
@@ -481,6 +501,7 @@ import {
481
501
  TaskTemplateKindSchema,
482
502
  TaskTemplateSchema,
483
503
  TriggerConfigSchema,
504
+ UserCommsPrefsSchema,
484
505
  UserFavoriteSchema,
485
506
  UserSchema,
486
507
  WorkflowDefinitionSchema,
@@ -505,6 +526,7 @@ import {
505
526
  clearKeyRateLimit,
506
527
  closeDb,
507
528
  completeTask,
529
+ computeContentHash,
508
530
  countActiveScriptRuns,
509
531
  countAllMetrics,
510
532
  countAllPages,
@@ -567,6 +589,7 @@ import {
567
589
  getAllTasks,
568
590
  getAllUsers,
569
591
  getApprovalRequestById,
592
+ getAttributionByPerson,
570
593
  getAvailableKeyIndices,
571
594
  getBudget,
572
595
  getBudgets,
@@ -602,6 +625,7 @@ import {
602
625
  getPendingTaskForAgent,
603
626
  getPricingRows,
604
627
  getPromptTemplateById,
628
+ getPromptTemplateDefaultDrift,
605
629
  getPromptTemplateHistory,
606
630
  getPromptTemplates,
607
631
  getRecentBudgetRefusalNotifications,
@@ -655,11 +679,12 @@ import {
655
679
  init_credential_broker,
656
680
  init_date_utils,
657
681
  init_db,
682
+ init_default_drift,
658
683
  init_request_auth_context,
659
684
  init_steering,
660
685
  init_swarm_config_guard,
661
686
  init_telemetry,
662
- init_templates1 as init_templates,
687
+ init_templates,
663
688
  init_types,
664
689
  insertActiveSession,
665
690
  insertPricingRow,
@@ -724,6 +749,7 @@ import {
724
749
  updateActiveSessionProviderSessionId,
725
750
  updateAgentActivity,
726
751
  updateAgentCredStatus,
752
+ updateAgentCredentialMissing,
727
753
  updateAgentCredentialState,
728
754
  updateAgentMaxTasks,
729
755
  updateAgentName,
@@ -756,20 +782,23 @@ import {
756
782
  upsertSwarmConfig,
757
783
  validateConfigValue,
758
784
  withFavoriteFlags
759
- } from "./cli-50vbt00w.js";
785
+ } from "./cli-m07313tr.js";
786
+ import {
787
+ IDENTITY_FIELD_BUDGETS,
788
+ IdentityFieldBudgetError,
789
+ init_identity_field_budget
790
+ } from "./cli-34w2584r.js";
760
791
  import {
761
792
  getAllTemplateDefinitions,
762
793
  getTemplateDefinition,
763
- init_env_flag,
764
794
  init_registry,
765
795
  init_resolver,
766
796
  init_steering_enabled,
767
797
  init_template,
768
798
  interpolate,
769
- isEnvFlagEnabled,
770
799
  isSteeringEnabled,
771
800
  resolveTemplate
772
- } from "./cli-xpxde7rm.js";
801
+ } from "./cli-2wv4kj0e.js";
773
802
  import {
774
803
  MAX_PROFILE_FILE_LENGTH,
775
804
  getAppUrl,
@@ -777,62 +806,66 @@ import {
777
806
  getMcpBaseUrl,
778
807
  getPublicMcpBaseUrl,
779
808
  init_constants
780
- } from "./cli-x23me2mg.js";
781
- import"./cli-z2zcxes1.js";
809
+ } from "./cli-a1rrkrb4.js";
810
+ import"./cli-qt5bt3vk.js";
811
+ import {
812
+ init_env_flag,
813
+ isEnvFlagEnabled
814
+ } from "./cli-nanaxrz6.js";
782
815
  import {
783
816
  init_zod
784
- } from "./cli-zsspvvm2.js";
817
+ } from "./cli-1ybr6vw2.js";
818
+ import {
819
+ init_package,
820
+ package_default
821
+ } from "./cli-jmvk6et8.js";
785
822
  import {
786
823
  init_secret_scrubber,
787
824
  registerVolatileSecret,
788
825
  scrubObject,
789
826
  scrubSecrets
790
- } from "./cli-4j2mrzag.js";
791
- import {
792
- init_package,
793
- package_default
794
- } from "./cli-ccf9vy7q.js";
827
+ } from "./cli-mkq1rk7b.js";
795
828
  import {
796
829
  array,
797
830
  exports_external,
798
831
  number,
799
832
  object,
800
833
  string
801
- } from "./cli-5dsbcjjw.js";
802
- import"./cli-e15jhafb.js";
834
+ } from "./cli-ghexzd2d.js";
835
+ import"./cli-qntkxysp.js";
803
836
  import {
804
837
  init_event_bus,
805
838
  workflowEventBus
806
- } from "./cli-9aryf9tv.js";
839
+ } from "./cli-95m51ztz.js";
807
840
  import {
808
841
  bedrockProviderModule
809
- } from "./cli-9dr5qzc0.js";
810
- import"./cli-cwy5hqbq.js";
842
+ } from "./cli-tv9f1kyb.js";
843
+ import"./cli-gpt9kf01.js";
811
844
  import {
812
845
  setBedrockProviderModule
813
846
  } from "./cli-darcwax3.js";
814
- import"./cli-jvv0g8bh.js";
815
- import"./cli-r6kqqbj0.js";
847
+ import"./cli-tkf8n6cw.js";
848
+ import"./cli-yjmk7tzc.js";
816
849
  import"./cli-6map995v.js";
817
- import"./cli-4wgngmwv.js";
818
- import"./cli-vapyk8sw.js";
819
- import"./cli-zyxs93y9.js";
820
- import"./cli-57khth04.js";
850
+ import"./cli-00w4hbam.js";
851
+ import"./cli-7jcc9y1r.js";
852
+ import"./cli-xmyqv00z.js";
821
853
  import"./cli-y2apkfe2.js";
854
+ import"./cli-vapyk8sw.js";
822
855
  import"./cli-akdvwc9v.js";
823
856
  import"./cli-8wrympd7.js";
824
- import"./cli-7sgrxg9a.js";
825
- import"./cli-3fj60etf.js";
826
- import"./cli-9sbhdpvb.js";
827
- import"./cli-z905tvmm.js";
828
- import"./cli-dxak0fqd.js";
829
- import"./cli-49n9f49x.js";
830
- import"./cli-jxg3s9ey.js";
831
- import"./cli-czkae1fp.js";
857
+ import"./cli-q6d0vvey.js";
858
+ import"./cli-497b685t.js";
859
+ import"./cli-3cgfyfzm.js";
860
+ import"./cli-g814jbst.js";
861
+ import"./cli-787ph852.js";
862
+ import"./cli-dx3dz0ms.js";
863
+ import"./cli-65d93ves.js";
864
+ import"./cli-c5ddbdfj.js";
832
865
  import {
833
866
  __require,
834
867
  __toESM
835
- } from "./cli-p9swy5t3.js";
868
+ } from "./cli-pq2ee5ja.js";
836
869
 
837
870
  // src/utils/internal-ai/register-bedrock.ts
838
871
  setBedrockProviderModule(bedrockProviderModule);
@@ -979,6 +1012,162 @@ function seedLegacyCapabilitiesConfig() {
979
1012
  return { seeded: true, added: [...added] };
980
1013
  }
981
1014
 
1015
+ // src/queue-stall-alarm.ts
1016
+ init_db();
1017
+ init_secret_scrubber();
1018
+ var QUEUE_STALL_THRESHOLD_MS = 30 * 60 * 1000;
1019
+ var QUEUE_STALL_CHECK_INTERVAL_MS = 5 * 60 * 1000;
1020
+ var QUEUE_STALL_STARTUP_DELAY_MS = 1e4;
1021
+ var alarmInterval = null;
1022
+ var startupTimeout = null;
1023
+ var checkInFlight = false;
1024
+ var alarmActive = false;
1025
+ function getQueueStallSnapshot(now = new Date) {
1026
+ const oldest = getDb().prepare(`WITH queued AS (
1027
+ SELECT
1028
+ t.id,
1029
+ t.dependsOn,
1030
+ COALESCE(
1031
+ (
1032
+ SELECT MAX(entry.createdAt)
1033
+ FROM agent_log entry
1034
+ WHERE entry.taskId = t.id
1035
+ AND entry.newValue = t.status
1036
+ AND entry.eventType IN (
1037
+ 'task_created',
1038
+ 'task_status_change',
1039
+ 'task_released',
1040
+ 'task_accepted',
1041
+ 'task_rejected'
1042
+ )
1043
+ ),
1044
+ t.createdAt
1045
+ ) AS queueEnteredAt
1046
+ FROM agent_tasks t
1047
+ WHERE t.status IN ('pending', 'unassigned')
1048
+ ),
1049
+ claimable AS (
1050
+ SELECT
1051
+ queued.id,
1052
+ MAX(
1053
+ queued.queueEnteredAt,
1054
+ COALESCE(
1055
+ (
1056
+ SELECT MAX(COALESCE(prerequisite.finishedAt, prerequisite.createdAt))
1057
+ FROM json_each(COALESCE(queued.dependsOn, '[]')) dep
1058
+ JOIN agent_tasks prerequisite ON prerequisite.id = dep.value
1059
+ ),
1060
+ queued.queueEnteredAt
1061
+ )
1062
+ ) AS claimableAt
1063
+ FROM queued
1064
+ WHERE NOT EXISTS (
1065
+ SELECT 1
1066
+ FROM json_each(COALESCE(queued.dependsOn, '[]')) dep
1067
+ LEFT JOIN agent_tasks prerequisite ON prerequisite.id = dep.value
1068
+ WHERE prerequisite.id IS NULL OR prerequisite.status != 'completed'
1069
+ )
1070
+ ),
1071
+ oldest AS (
1072
+ SELECT id, claimableAt FROM claimable ORDER BY claimableAt ASC LIMIT 1
1073
+ )
1074
+ SELECT
1075
+ (SELECT COUNT(*) FROM claimable) AS claimableCount,
1076
+ (SELECT id FROM oldest) AS oldestTaskId,
1077
+ (SELECT claimableAt FROM oldest) AS oldestClaimableAt`).get();
1078
+ const pickupCutoff = new Date(now.getTime() - QUEUE_STALL_THRESHOLD_MS).toISOString();
1079
+ const recentPickupCount = getDb().prepare(`SELECT COUNT(*) AS count
1080
+ FROM agent_log
1081
+ WHERE eventType IN ('task_status_change', 'task_claimed')
1082
+ AND oldValue IN ('pending', 'unassigned')
1083
+ AND newValue = 'in_progress'
1084
+ AND createdAt >= ?`).get(pickupCutoff)?.count ?? 0;
1085
+ const oldestClaimableAt = oldest?.oldestClaimableAt ?? null;
1086
+ return {
1087
+ claimableCount: oldest?.claimableCount ?? 0,
1088
+ oldestTaskId: oldest?.oldestTaskId ?? null,
1089
+ oldestClaimableAt,
1090
+ oldestAgeMs: oldestClaimableAt ? Math.max(0, now.getTime() - new Date(oldestClaimableAt).getTime()) : 0,
1091
+ recentPickupCount
1092
+ };
1093
+ }
1094
+ function isQueueStalled(snapshot) {
1095
+ return snapshot.claimableCount > 0 && snapshot.oldestAgeMs >= QUEUE_STALL_THRESHOLD_MS;
1096
+ }
1097
+ function formatAge(ageMs) {
1098
+ return `${Math.floor(ageMs / 60000)}m`;
1099
+ }
1100
+ function formatCheckFailure(error) {
1101
+ const message = error instanceof Error ? error.message : String(error);
1102
+ return `[Queue Stall Alarm] Check or notification failed: ${scrubSecrets(message)}`;
1103
+ }
1104
+ async function notifySlack(message) {
1105
+ const channel = process.env.SLACK_ALERTS_CHANNEL?.trim();
1106
+ if (!channel)
1107
+ throw new Error("SLACK_ALERTS_CHANNEL is not configured");
1108
+ const app = getSlackApp();
1109
+ if (!app)
1110
+ throw new Error("Slack is not connected");
1111
+ await app.client.chat.postMessage({
1112
+ channel,
1113
+ text: message,
1114
+ unfurl_links: false,
1115
+ unfurl_media: false
1116
+ });
1117
+ }
1118
+ async function checkQueueStall(now = new Date, notify = notifySlack) {
1119
+ const snapshot = getQueueStallSnapshot(now);
1120
+ const stalled = isQueueStalled(snapshot);
1121
+ if (stalled && !alarmActive) {
1122
+ await notify(`\uD83D\uDEA8 *Agent Swarm queue pickup stalled*
1123
+ ` + `Claimable tasks: *${snapshot.claimableCount}*
1124
+ ` + `Oldest wait: *${formatAge(snapshot.oldestAgeMs)}* (task \`${snapshot.oldestTaskId}\`)
1125
+ ` + `Pickups in the last 30m: *${snapshot.recentPickupCount}*
1126
+
1127
+ ` + "This alarm runs in the API process and does not require an agent to claim a task.");
1128
+ alarmActive = true;
1129
+ console.error(`[Queue Stall Alarm] Fired: claimable=${snapshot.claimableCount}, oldest=${snapshot.oldestTaskId}, age=${formatAge(snapshot.oldestAgeMs)}, recent_pickups=${snapshot.recentPickupCount}`);
1130
+ } else if (!stalled && alarmActive) {
1131
+ await notify(`✅ *Agent Swarm queue pickup recovered*
1132
+ Claimable tasks: *${snapshot.claimableCount}*
1133
+ Pickups in the last 30m: *${snapshot.recentPickupCount}*`);
1134
+ alarmActive = false;
1135
+ console.log("[Queue Stall Alarm] Recovery notification sent");
1136
+ }
1137
+ return snapshot;
1138
+ }
1139
+ function scheduleCheck() {
1140
+ if (checkInFlight)
1141
+ return;
1142
+ checkInFlight = true;
1143
+ checkQueueStall().catch((error) => {
1144
+ console.error(formatCheckFailure(error));
1145
+ }).finally(() => {
1146
+ checkInFlight = false;
1147
+ });
1148
+ }
1149
+ function startQueueStallAlarm() {
1150
+ if (alarmInterval || startupTimeout)
1151
+ return;
1152
+ console.log(`[Queue Stall Alarm] Starting (threshold ${formatAge(QUEUE_STALL_THRESHOLD_MS)}, interval ${formatAge(QUEUE_STALL_CHECK_INTERVAL_MS)})`);
1153
+ startupTimeout = setTimeout(() => {
1154
+ startupTimeout = null;
1155
+ scheduleCheck();
1156
+ }, QUEUE_STALL_STARTUP_DELAY_MS);
1157
+ alarmInterval = setInterval(scheduleCheck, QUEUE_STALL_CHECK_INTERVAL_MS);
1158
+ }
1159
+ function stopQueueStallAlarm() {
1160
+ if (startupTimeout) {
1161
+ clearTimeout(startupTimeout);
1162
+ startupTimeout = null;
1163
+ }
1164
+ if (alarmInterval) {
1165
+ clearInterval(alarmInterval);
1166
+ alarmInterval = null;
1167
+ }
1168
+ checkInFlight = false;
1169
+ }
1170
+
982
1171
  // src/script-workflows/supervisor.ts
983
1172
  init_db();
984
1173
 
@@ -986,6 +1175,7 @@ init_db();
986
1175
  import { existsSync } from "node:fs";
987
1176
  import { mkdir, rm } from "node:fs/promises";
988
1177
  import { resolve } from "node:path";
1178
+ import { fileURLToPath } from "node:url";
989
1179
 
990
1180
  // src/script-workflows/limits.ts
991
1181
  var DEFAULT_MAX_STEPS = 1000;
@@ -1013,7 +1203,7 @@ var MAX_STDERR_BYTES = 1048576;
1013
1203
  function getScriptWorkflowHarnessPath() {
1014
1204
  const runtimeDir = process.env.SCRIPT_WORKFLOW_RUNTIME_DIR;
1015
1205
  if (!runtimeDir)
1016
- return new URL("./harness.ts", import.meta.url).pathname;
1206
+ return fileURLToPath(new URL("./harness.ts", import.meta.url));
1017
1207
  const bundledHarness = `${resolve(runtimeDir)}/harness.bundle.js`;
1018
1208
  if (!existsSync(bundledHarness)) {
1019
1209
  throw new Error(`Script workflow harness bundle not found at ${bundledHarness}. ` + "Build/copy harness.bundle.js and set SCRIPT_WORKFLOW_RUNTIME_DIR to its directory.");
@@ -1237,7 +1427,8 @@ var createActiveSession = route({
1237
1427
  triggerType: exports_external.string().min(1),
1238
1428
  inboxMessageId: exports_external.string().optional(),
1239
1429
  taskDescription: exports_external.string().optional(),
1240
- runnerSessionId: exports_external.string().optional()
1430
+ runnerSessionId: exports_external.string().optional(),
1431
+ runtimeInstanceId: exports_external.string().optional()
1241
1432
  }),
1242
1433
  responses: {
1243
1434
  201: { description: "Session created", schema: exports_external.object({ session: ActiveSessionSchema }) },
@@ -1340,7 +1531,8 @@ async function handleActiveSessions(req, res, pathSegments, queryParams, myAgent
1340
1531
  triggerType: parsed.body.triggerType,
1341
1532
  inboxMessageId: parsed.body.inboxMessageId,
1342
1533
  taskDescription: parsed.body.taskDescription,
1343
- runnerSessionId: parsed.body.runnerSessionId
1534
+ runnerSessionId: parsed.body.runnerSessionId,
1535
+ runtimeInstanceId: parsed.body.runtimeInstanceId
1344
1536
  });
1345
1537
  createActiveSession.respond(res, 201, { session });
1346
1538
  return true;
@@ -1383,7 +1575,7 @@ async function handleActiveSessions(req, res, pathSegments, queryParams, myAgent
1383
1575
  return true;
1384
1576
  let cleaned = 0;
1385
1577
  if (parsed.body?.agentId) {
1386
- cleaned = cleanupAgentSessions(parsed.body.agentId);
1578
+ cleaned = isMultiRuntimeEnabled() ? 0 : cleanupAgentSessions(parsed.body.agentId);
1387
1579
  } else {
1388
1580
  cleaned = cleanupStaleSessions(parsed.body?.maxAgeMinutes ?? 30);
1389
1581
  }
@@ -1411,6 +1603,12 @@ init_db();
1411
1603
  init_telemetry();
1412
1604
  init_types();
1413
1605
  init_constants();
1606
+ init_identity_field_budget();
1607
+ init_secret_scrubber();
1608
+ function singleHeaderValue(req, name) {
1609
+ const raw = req.headers[name];
1610
+ return Array.isArray(raw) ? raw[0] : raw;
1611
+ }
1414
1612
  var CapabilitySchema = exports_external.enum(ALL_CAPABILITIES);
1415
1613
  var AgentCapacitySchema = exports_external.object({
1416
1614
  current: exports_external.number().int(),
@@ -1450,7 +1648,8 @@ var registerAgent = route({
1450
1648
  capabilities: exports_external.array(exports_external.string()).optional(),
1451
1649
  maxTasks: exports_external.number().int().optional(),
1452
1650
  provider: ProviderNameSchema.optional(),
1453
- harness_provider: ProviderNameSchema.optional()
1651
+ harness_provider: ProviderNameSchema.optional(),
1652
+ runtimeInstanceId: exports_external.string().min(1).optional()
1454
1653
  }),
1455
1654
  responses: {
1456
1655
  200: {
@@ -1552,6 +1751,36 @@ var getAgentSetupScript = route({
1552
1751
  404: { description: "Agent not found" }
1553
1752
  }
1554
1753
  });
1754
+ var AgentRuntimeInstanceSchema = RuntimeInstanceSchema.omit({ metadata: true }).extend({
1755
+ isLive: exports_external.boolean()
1756
+ });
1757
+ var listAgentRuntimeInstances = route({
1758
+ method: "get",
1759
+ path: "/api/agents/{id}/runtime-instances",
1760
+ pattern: ["api", "agents", null, "runtime-instances"],
1761
+ summary: "List runtime instances serving an agent",
1762
+ description: "Read-only view of the worker processes currently registered for a logical agent. Rows exist only for multi-runtime registrations (MULTI_RUNTIME_ENABLED), so the list is empty in the default configuration. `isLive` combines `status` with `lastSeenAt` freshness against the server's staleness cutoff (`staleThresholdMinutes`); `reportedSlots` is each process's self-reported capacity, distinct from the agent's logical `maxTasks` policy.",
1763
+ tags: ["Agents"],
1764
+ params: exports_external.object({ id: exports_external.string() }),
1765
+ responses: {
1766
+ 200: {
1767
+ description: "Runtime instances for the agent (empty when none are registered)",
1768
+ schema: exports_external.object({
1769
+ runtimeInstances: exports_external.array(AgentRuntimeInstanceSchema),
1770
+ staleThresholdMinutes: exports_external.number().int()
1771
+ })
1772
+ },
1773
+ 404: { description: "Agent not found" }
1774
+ }
1775
+ });
1776
+ var ProfileSyncRejectionSchema = exports_external.object({
1777
+ field: exports_external.enum(["soulMd", "identityMd", "claudeMd", "toolsMd"]),
1778
+ diskSize: exports_external.number().int(),
1779
+ dbSize: exports_external.number().int(),
1780
+ budget: exports_external.number().int(),
1781
+ delta: exports_external.number().int(),
1782
+ reason: exports_external.string()
1783
+ });
1555
1784
  var updateAgentProfileRoute = route({
1556
1785
  method: "put",
1557
1786
  path: "/api/agents/{id}/profile",
@@ -1563,11 +1792,11 @@ var updateAgentProfileRoute = route({
1563
1792
  role: exports_external.string().max(100).optional(),
1564
1793
  description: exports_external.string().optional(),
1565
1794
  capabilities: exports_external.array(exports_external.string()).optional(),
1566
- claudeMd: exports_external.string().max(MAX_PROFILE_FILE_LENGTH).optional(),
1567
- soulMd: exports_external.string().max(MAX_PROFILE_FILE_LENGTH).optional(),
1568
- identityMd: exports_external.string().max(MAX_PROFILE_FILE_LENGTH).optional(),
1795
+ claudeMd: exports_external.string().optional(),
1796
+ soulMd: exports_external.string().optional(),
1797
+ identityMd: exports_external.string().optional(),
1569
1798
  setupScript: exports_external.string().max(MAX_PROFILE_FILE_LENGTH).optional(),
1570
- toolsMd: exports_external.string().max(MAX_PROFILE_FILE_LENGTH).optional(),
1799
+ toolsMd: exports_external.string().optional(),
1571
1800
  heartbeatMd: exports_external.string().max(MAX_PROFILE_FILE_LENGTH).optional(),
1572
1801
  avatar: AgentAvatarSchema.nullable().optional(),
1573
1802
  changeSource: exports_external.string().optional(),
@@ -1576,7 +1805,13 @@ var updateAgentProfileRoute = route({
1576
1805
  }),
1577
1806
  responses: {
1578
1807
  200: { description: "Profile updated", schema: AgentWithCapacitySchema },
1579
- 400: { description: "Validation error" },
1808
+ 400: {
1809
+ description: "Validation or identity-field budget error",
1810
+ schema: exports_external.object({
1811
+ error: exports_external.string(),
1812
+ profileSyncRejection: ProfileSyncRejectionSchema.optional()
1813
+ })
1814
+ },
1580
1815
  404: { description: "Agent not found" }
1581
1816
  }
1582
1817
  });
@@ -1619,12 +1854,14 @@ var updateAgentCredentialStatusRoute = route({
1619
1854
  summary: "Worker self-report of credential readiness (Phase 3 boot loop)",
1620
1855
  tags: ["Agents"],
1621
1856
  params: exports_external.object({ id: exports_external.string() }),
1857
+ headers: runtimeInstanceHeader("report credential readiness"),
1622
1858
  body: credentialStatusBody,
1623
1859
  responses: {
1624
1860
  200: {
1625
1861
  description: "State updated; returns the agent row.",
1626
1862
  schema: AgentWithCapacitySchema
1627
1863
  },
1864
+ 400: { description: "Missing X-Runtime-Instance-ID in multi-runtime mode" },
1628
1865
  404: { description: "Agent not found" }
1629
1866
  }
1630
1867
  });
@@ -1662,13 +1899,26 @@ async function handleAgentRegister(req, res, pathSegments, myAgentId) {
1662
1899
  if (!parsed)
1663
1900
  return true;
1664
1901
  const agentId = myAgentId || crypto.randomUUID();
1902
+ const multiRuntime = isMultiRuntimeEnabled();
1903
+ if (multiRuntime && parsed.body.runtimeInstanceId) {
1904
+ const existingRuntime = getRuntimeInstanceById(parsed.body.runtimeInstanceId);
1905
+ if (existingRuntime && existingRuntime.agentId !== agentId) {
1906
+ jsonError(res, "runtimeInstanceId is already registered to another agent", 400);
1907
+ return true;
1908
+ }
1909
+ } else if (multiRuntime) {
1910
+ jsonError(res, "runtimeInstanceId is required when multi-runtime mode is enabled", 400);
1911
+ return true;
1912
+ }
1665
1913
  const result = getDb().transaction(() => {
1666
1914
  const existingAgent = getAgentById(agentId);
1667
1915
  if (existingAgent) {
1668
1916
  if (existingAgent.status === "offline") {
1669
1917
  updateAgentStatus(existingAgent.id, "idle");
1670
1918
  }
1671
- if (parsed.body.maxTasks !== undefined && parsed.body.maxTasks !== existingAgent.maxTasks) {
1919
+ if (multiRuntime) {
1920
+ reconcileAgentMaxTasksPolicy(existingAgent.id);
1921
+ } else if (parsed.body.maxTasks !== undefined && parsed.body.maxTasks !== existingAgent.maxTasks) {
1672
1922
  updateAgentMaxTasks(existingAgent.id, parsed.body.maxTasks);
1673
1923
  }
1674
1924
  if (parsed.body.provider && parsed.body.provider !== existingAgent.provider) {
@@ -1678,6 +1928,14 @@ async function handleAgentRegister(req, res, pathSegments, myAgentId) {
1678
1928
  setAgentHarnessProvider(existingAgent.id, parsed.body.harness_provider);
1679
1929
  }
1680
1930
  resetEmptyPollCount(existingAgent.id);
1931
+ if (multiRuntime && parsed.body.runtimeInstanceId) {
1932
+ upsertRuntimeInstance({
1933
+ id: parsed.body.runtimeInstanceId,
1934
+ agentId: existingAgent.id,
1935
+ reportedSlots: parsed.body.maxTasks ?? 1
1936
+ });
1937
+ reconcileAgentStatusFromRuntimes(existingAgent.id);
1938
+ }
1681
1939
  return { agent: getAgentById(agentId), created: false };
1682
1940
  }
1683
1941
  const agent = createAgent({
@@ -1692,6 +1950,18 @@ async function handleAgentRegister(req, res, pathSegments, myAgentId) {
1692
1950
  provider: parsed.body.provider,
1693
1951
  harnessProvider: parsed.body.harness_provider ?? null
1694
1952
  });
1953
+ if (multiRuntime) {
1954
+ reconcileAgentMaxTasksPolicy(agent.id);
1955
+ if (parsed.body.runtimeInstanceId) {
1956
+ upsertRuntimeInstance({
1957
+ id: parsed.body.runtimeInstanceId,
1958
+ agentId: agent.id,
1959
+ reportedSlots: parsed.body.maxTasks ?? 1
1960
+ });
1961
+ reconcileAgentStatusFromRuntimes(agent.id);
1962
+ }
1963
+ return { agent: getAgentById(agent.id), created: true };
1964
+ }
1695
1965
  return { agent, created: true };
1696
1966
  })();
1697
1967
  telemetry.agent("registered", {
@@ -1780,6 +2050,20 @@ async function handleAgentsRest(req, res, pathSegments, queryParams, _myAgentId)
1780
2050
  });
1781
2051
  return true;
1782
2052
  }
2053
+ if (listAgentRuntimeInstances.match(req.method, pathSegments)) {
2054
+ const parsed = await listAgentRuntimeInstances.parse(req, res, pathSegments, queryParams);
2055
+ if (!parsed)
2056
+ return true;
2057
+ if (!getAgentById(parsed.params.id)) {
2058
+ jsonError(res, "Agent not found", 404);
2059
+ return true;
2060
+ }
2061
+ listAgentRuntimeInstances.respond(res, 200, {
2062
+ runtimeInstances: listRuntimeInstancesForAgent(parsed.params.id).map(({ metadata: _metadata, ...instance }) => instance),
2063
+ staleThresholdMinutes: runtimeStaleThresholdMinutes()
2064
+ });
2065
+ return true;
2066
+ }
1783
2067
  if (updateAgentProfileRoute.match(req.method, pathSegments)) {
1784
2068
  const parsed = await updateAgentProfileRoute.parse(req, res, pathSegments, queryParams);
1785
2069
  if (!parsed)
@@ -1795,22 +2079,77 @@ async function handleAgentsRest(req, res, pathSegments, queryParams, _myAgentId)
1795
2079
  changedByAgentId: body.changedByAgentId ?? null,
1796
2080
  changeReason: body.changeReason ?? null
1797
2081
  } : undefined;
1798
- const agent = updateAgentProfile(parsed.params.id, {
1799
- role: body.role,
1800
- description: body.description,
1801
- capabilities: body.capabilities,
1802
- claudeMd: body.claudeMd,
1803
- soulMd: body.soulMd,
1804
- identityMd: body.identityMd,
1805
- setupScript: body.setupScript,
1806
- toolsMd: body.toolsMd,
1807
- heartbeatMd: body.heartbeatMd,
1808
- ...body.avatar !== undefined ? { avatar: body.avatar } : {}
1809
- }, versionMeta);
2082
+ let agent;
2083
+ try {
2084
+ agent = updateAgentProfile(parsed.params.id, {
2085
+ role: body.role,
2086
+ description: body.description,
2087
+ capabilities: body.capabilities,
2088
+ claudeMd: body.claudeMd,
2089
+ soulMd: body.soulMd,
2090
+ identityMd: body.identityMd,
2091
+ setupScript: body.setupScript,
2092
+ toolsMd: body.toolsMd,
2093
+ heartbeatMd: body.heartbeatMd,
2094
+ ...body.avatar !== undefined ? { avatar: body.avatar } : {}
2095
+ }, versionMeta);
2096
+ } catch (error) {
2097
+ if (error instanceof IdentityFieldBudgetError) {
2098
+ if (versionMeta?.changeSource === "self_edit" || versionMeta?.changeSource === "session_sync") {
2099
+ try {
2100
+ createEvent({
2101
+ category: "system",
2102
+ event: "system.profile_sync_rejected",
2103
+ status: "error",
2104
+ source: "api",
2105
+ agentId: parsed.params.id,
2106
+ data: {
2107
+ ...error.rejection,
2108
+ dbHash: error.dbHash,
2109
+ diskHash: error.diskHash,
2110
+ changeSource: versionMeta.changeSource
2111
+ }
2112
+ });
2113
+ } catch (eventError) {
2114
+ const message = eventError instanceof Error ? eventError.message : String(eventError);
2115
+ console.error(scrubSecrets(`[profile-sync] Failed to persist budget rejection event: ${message}`));
2116
+ }
2117
+ }
2118
+ updateAgentProfileRoute.respond(res, 400, {
2119
+ error: error.message,
2120
+ profileSyncRejection: error.rejection
2121
+ });
2122
+ return true;
2123
+ }
2124
+ throw error;
2125
+ }
1810
2126
  if (!agent) {
1811
2127
  jsonError(res, "Agent not found", 404);
1812
2128
  return true;
1813
2129
  }
2130
+ if (versionMeta?.changeSource === "self_edit" || versionMeta?.changeSource === "session_sync") {
2131
+ try {
2132
+ for (const field of Object.keys(IDENTITY_FIELD_BUDGETS)) {
2133
+ if (body[field] === undefined)
2134
+ continue;
2135
+ createEvent({
2136
+ category: "system",
2137
+ event: "system.profile_sync_reconciled",
2138
+ status: "ok",
2139
+ source: "api",
2140
+ agentId: parsed.params.id,
2141
+ data: {
2142
+ field,
2143
+ dbHash: computeContentHash(agent[field] ?? ""),
2144
+ changeSource: versionMeta.changeSource
2145
+ }
2146
+ });
2147
+ }
2148
+ } catch (eventError) {
2149
+ const message = eventError instanceof Error ? eventError.message : String(eventError);
2150
+ console.error(scrubSecrets(`[profile-sync] Failed to persist reconciliation event: ${message}`));
2151
+ }
2152
+ }
1814
2153
  updateAgentProfileRoute.respond(res, 200, agentWithCapacity(agent));
1815
2154
  return true;
1816
2155
  }
@@ -1934,7 +2273,24 @@ async function handleAgentsRest(req, res, pathSegments, queryParams, _myAgentId)
1934
2273
  jsonError(res, "Agent not found", 404);
1935
2274
  return true;
1936
2275
  }
1937
- const agent = parsed.body.ready !== undefined ? updateAgentCredentialState(parsed.params.id, parsed.body.ready, parsed.body.missing ?? null) ?? existing : existing;
2276
+ const runtimeInstanceId = singleHeaderValue(req, "x-runtime-instance-id");
2277
+ const multiRuntime = isMultiRuntimeEnabled();
2278
+ if (multiRuntime && parsed.body.ready !== undefined && !runtimeInstanceId) {
2279
+ jsonError(res, "X-Runtime-Instance-ID is required when multi-runtime mode is enabled", 400);
2280
+ return true;
2281
+ }
2282
+ let agent = existing;
2283
+ if (parsed.body.ready !== undefined) {
2284
+ if (multiRuntime && runtimeInstanceId) {
2285
+ if (setRuntimeCredentialReady(runtimeInstanceId, parsed.params.id, parsed.body.ready)) {
2286
+ updateAgentCredentialMissing(parsed.params.id, parsed.body.missing ?? null);
2287
+ reconcileAgentStatusFromRuntimes(parsed.params.id);
2288
+ }
2289
+ agent = getAgentById(parsed.params.id) ?? existing;
2290
+ } else {
2291
+ agent = updateAgentCredentialState(parsed.params.id, parsed.body.ready, parsed.body.missing ?? null) ?? existing;
2292
+ }
2293
+ }
1938
2294
  if (!agent) {
1939
2295
  jsonError(res, "Agent not found", 404);
1940
2296
  return true;
@@ -3526,7 +3882,7 @@ async function handleConfig(req, res, pathSegments, queryParams) {
3526
3882
  }
3527
3883
  try {
3528
3884
  const includeSecrets = queryParams.get("includeSecrets") === "true";
3529
- const config = upsertSwarmConfig({
3885
+ const config = upsertSwarmConfigWithPolicyMirror({
3530
3886
  scope,
3531
3887
  scopeId: scopeId || null,
3532
3888
  key,
@@ -3564,6 +3920,9 @@ async function handleConfig(req, res, pathSegments, queryParams) {
3564
3920
  if (existing.scope === "global") {
3565
3921
  scheduleIntegrationsReload();
3566
3922
  }
3923
+ if (existing.scope === "agent" && existing.scopeId && existing.key === AGENT_MAX_TASKS_CONFIG_KEY) {
3924
+ resetAgentMaxTasksMirror(existing.scopeId);
3925
+ }
3567
3926
  deleteConfig.respond(res, 200, { success: true });
3568
3927
  return true;
3569
3928
  }
@@ -3801,6 +4160,7 @@ var getEventsRoute = route({
3801
4160
  agentId: exports_external.string().optional(),
3802
4161
  taskId: exports_external.string().optional(),
3803
4162
  sessionId: exports_external.string().optional(),
4163
+ dataField: exports_external.string().optional(),
3804
4164
  since: exports_external.string().optional(),
3805
4165
  until: exports_external.string().optional(),
3806
4166
  limit: exports_external.coerce.number().int().min(1).max(1000).optional()
@@ -3893,6 +4253,7 @@ async function handleEvents(req, res, pathSegments, queryParams, _myAgentId) {
3893
4253
  agentId: parsed.query.agentId || undefined,
3894
4254
  taskId: parsed.query.taskId || undefined,
3895
4255
  sessionId: parsed.query.sessionId || undefined,
4256
+ dataField: parsed.query.dataField || undefined,
3896
4257
  since: parsed.query.since || undefined,
3897
4258
  until: parsed.query.until || undefined,
3898
4259
  limit: parsed.query.limit ?? 100
@@ -6455,6 +6816,15 @@ async function handleMcp(req, res, transports, sessionActivity = {}, sessionAgen
6455
6816
  chunks.push(chunk);
6456
6817
  }
6457
6818
  const body = JSON.parse(Buffer.concat(chunks).toString());
6819
+ if (!sessionId && body.method === "server/discover") {
6820
+ res.writeHead(200, { "Content-Type": "application/json" });
6821
+ res.end(JSON.stringify({
6822
+ jsonrpc: "2.0",
6823
+ error: { code: -32601, message: "Method not found" },
6824
+ id: body.id ?? null
6825
+ }));
6826
+ return true;
6827
+ }
6458
6828
  let transport;
6459
6829
  if (sessionId && transports[sessionId]) {
6460
6830
  transport = transports[sessionId];
@@ -6577,6 +6947,9 @@ var SDK_TOOL_NAME_MAP = {
6577
6947
  slack_post: "slack-post",
6578
6948
  slack_reply: "slack-reply",
6579
6949
  slack_startThread: "slack-start-thread",
6950
+ slack_createChannel: "slack-create-channel",
6951
+ slack_inviteToChannel: "slack-invite-to-channel",
6952
+ slack_archiveChannel: "slack-archive-channel",
6580
6953
  slack_uploadFile: "slack-upload-file",
6581
6954
  slack_downloadFile: "slack-download-file",
6582
6955
  slack_delete: "slack-delete",
@@ -6663,6 +7036,7 @@ var mcpBridgeRoute = route({
6663
7036
  pattern: ["api", "mcp-bridge"],
6664
7037
  summary: "Generic MCP tool proxy for the scripts SDK bridge",
6665
7038
  tags: ["Scripts"],
7039
+ headers: runtimeInstanceHeader("acquire work through bridged tools"),
6666
7040
  body: exports_external.object({
6667
7041
  tool: exports_external.string().min(1).max(200),
6668
7042
  args: exports_external.record(exports_external.string(), exports_external.unknown()).default({})
@@ -6700,17 +7074,30 @@ async function handleMcpBridge(req, res, pathSegments, _queryParams, myAgentId)
6700
7074
  return true;
6701
7075
  }
6702
7076
  const sourceTaskId = Array.isArray(req.headers["x-source-task-id"]) ? req.headers["x-source-task-id"][0] : req.headers["x-source-task-id"];
7077
+ const runtimeInstanceId = Array.isArray(req.headers["x-runtime-instance-id"]) ? req.headers["x-runtime-instance-id"][0] : req.headers["x-runtime-instance-id"];
6703
7078
  const extra = markScriptSdkRequestOrigin({
6704
7079
  sessionId: "mcp-bridge",
6705
7080
  requestInfo: {
6706
7081
  headers: {
6707
7082
  "x-agent-id": myAgentId ?? "",
6708
- ...sourceTaskId ? { "x-source-task-id": sourceTaskId } : {}
7083
+ ...sourceTaskId ? { "x-source-task-id": sourceTaskId } : {},
7084
+ ...runtimeInstanceId ? { "x-runtime-instance-id": runtimeInstanceId } : {}
6709
7085
  }
6710
7086
  }
6711
7087
  });
7088
+ let handlerArgs = args;
7089
+ if (tool.inputSchema) {
7090
+ const inputObj = normalizeObjectSchema(tool.inputSchema);
7091
+ const parseResult = await safeParseAsync(inputObj ?? tool.inputSchema, args);
7092
+ if (!parseResult.success) {
7093
+ const parseError = "error" in parseResult ? parseResult.error : "Unknown error";
7094
+ jsonError(res, `Invalid arguments for tool '${toolName}': ${getParseErrorMessage(parseError)}`, 400);
7095
+ return true;
7096
+ }
7097
+ handlerArgs = parseResult.data;
7098
+ }
6712
7099
  try {
6713
- const result = tool.inputSchema ? await Promise.resolve(tool.handler(args, extra)) : await Promise.resolve(tool.handler(extra));
7100
+ const result = tool.inputSchema ? await Promise.resolve(tool.handler(handlerArgs, extra)) : await Promise.resolve(tool.handler(extra));
6714
7101
  if (result && typeof result === "object" && "structuredContent" in result) {
6715
7102
  json(res, result.structuredContent);
6716
7103
  } else if (result && typeof result === "object" && "content" in result) {
@@ -8495,6 +8882,7 @@ function getUsefulnessStats(options = {}) {
8495
8882
 
8496
8883
  // src/http/memory.ts
8497
8884
  init_types();
8885
+ init_secret_scrubber();
8498
8886
  var MemoryRetrievalSourceSchema = exports_external.enum(["vec", "fts", "hybrid", "fallback", "graph"]);
8499
8887
  var IndexMemoryResponseSchema = exports_external.object({
8500
8888
  queued: exports_external.boolean(),
@@ -9037,7 +9425,7 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
9037
9425
  } catch (err) {
9038
9426
  console.error("[memory] Batch embedding failed:", err.message);
9039
9427
  }
9040
- })();
9428
+ })().catch((err) => console.error("[memory] batch embed failed:", scrubSecrets(err instanceof Error ? err.message : String(err))));
9041
9429
  indexMemory.respond(res, 202, { queued: true, memoryIds: memories.map((m) => m.id) });
9042
9430
  return true;
9043
9431
  }
@@ -9308,7 +9696,7 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
9308
9696
  }
9309
9697
  }
9310
9698
  console.log(`[memory] Re-embedding complete: ${memories.length} memories`);
9311
- })();
9699
+ })().catch((err) => console.error("[memory] re-embed batch failed:", scrubSecrets(err instanceof Error ? err.message : String(err))));
9312
9700
  return true;
9313
9701
  }
9314
9702
  if (rateMemory.match(req.method, pathSegments)) {
@@ -11945,11 +12333,14 @@ var PollRequestedBySchema = UserSchema.pick({
11945
12333
  email: true,
11946
12334
  role: true,
11947
12335
  notes: true
12336
+ }).extend({
12337
+ comms: UserCommsPrefsSchema.optional()
11948
12338
  });
11949
12339
  var PollTaskOfferedTriggerSchema = exports_external.object({
11950
12340
  type: exports_external.literal("task_offered"),
11951
12341
  taskId: exports_external.string(),
11952
- task: AgentTaskSchema
12342
+ task: AgentTaskSchema,
12343
+ requestedBy: PollRequestedBySchema.optional()
11953
12344
  });
11954
12345
  var PollTaskAssignedTriggerSchema = exports_external.object({
11955
12346
  type: exports_external.literal("task_assigned"),
@@ -11993,6 +12384,7 @@ var pollTriggers = route({
11993
12384
  summary: "Poll for triggers (tasks, mentions)",
11994
12385
  tags: ["Poll"],
11995
12386
  auth: { apiKey: true, agentId: true },
12387
+ headers: runtimeInstanceHeader("poll for work"),
11996
12388
  responses: {
11997
12389
  200: { description: "Trigger data or null", schema: pollResponseSchema },
11998
12390
  400: { description: "Missing X-Agent-ID" },
@@ -12004,6 +12396,22 @@ var lastChannelActivityCheckAt = 0;
12004
12396
  function getRequesterNotes(notes) {
12005
12397
  return typeof notes === "string" && notes.trim().length > 0 ? notes : undefined;
12006
12398
  }
12399
+ function buildTriggerRequestedBy(task) {
12400
+ const user = task.requestedByUserId ? getUserById(task.requestedByUserId) : undefined;
12401
+ if (user) {
12402
+ return {
12403
+ name: user.name,
12404
+ email: user.email,
12405
+ role: user.role,
12406
+ notes: getRequesterNotes(user.notes),
12407
+ comms: getUserCommsPrefs(user)
12408
+ };
12409
+ }
12410
+ if (task.slackUserId) {
12411
+ return { name: renderIdentity(resolveIdentity("slack", task.slackUserId)) };
12412
+ }
12413
+ return;
12414
+ }
12007
12415
  function attachmentsForTrigger(taskId) {
12008
12416
  return getTaskAttachments(taskId).map((a) => ({
12009
12417
  id: a.id,
@@ -12034,6 +12442,7 @@ var commitCursorsRoute = route({
12034
12442
  }
12035
12443
  });
12036
12444
  async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
12445
+ const runtimeInstanceId = ((h) => Array.isArray(h) ? h[0] : h)(req.headers["x-runtime-instance-id"]);
12037
12446
  if (commitCursorsRoute.match(req.method, pathSegments)) {
12038
12447
  const parsed = await commitCursorsRoute.parse(req, res, pathSegments, queryParams);
12039
12448
  if (!parsed)
@@ -12061,16 +12470,21 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
12061
12470
  if (!agent) {
12062
12471
  return { error: "Agent not found", status: 404 };
12063
12472
  }
12064
- const offeredTasks = getOfferedTasksForAgent(myAgentId);
12473
+ if (isMultiRuntimeEnabled() && !(runtimeInstanceId && touchRuntimeInstance(runtimeInstanceId, agent.id))) {
12474
+ return { trigger: null };
12475
+ }
12476
+ const offeredTasks = hasCapacity(myAgentId) ? getOfferedTasksForAgent(myAgentId) : [];
12065
12477
  const firstOfferedTask = offeredTasks[0];
12066
12478
  if (firstOfferedTask) {
12067
12479
  const claimedTask = claimOfferedTask(firstOfferedTask.id, myAgentId);
12068
12480
  if (claimedTask) {
12481
+ const offeredRequestedBy = buildTriggerRequestedBy(claimedTask);
12069
12482
  return {
12070
12483
  trigger: {
12071
12484
  type: "task_offered",
12072
12485
  taskId: claimedTask.id,
12073
- task: claimedTask
12486
+ task: claimedTask,
12487
+ ...offeredRequestedBy && { requestedBy: offeredRequestedBy }
12074
12488
  }
12075
12489
  };
12076
12490
  }
@@ -12121,6 +12535,7 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
12121
12535
  };
12122
12536
  }
12123
12537
  startTask(pendingTask.id);
12538
+ updateAgentStatusFromCapacity(myAgentId);
12124
12539
  ensure({
12125
12540
  id: "started",
12126
12541
  flow: "task",
@@ -12140,9 +12555,7 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
12140
12555
  source: pendingTask.source,
12141
12556
  agentId: myAgentId
12142
12557
  });
12143
- const requestedByUser = pendingTask.requestedByUserId ? getUserById(pendingTask.requestedByUserId) : undefined;
12144
- const requestedByNotes = getRequesterNotes(requestedByUser?.notes);
12145
- const requestedByUnknownName = !requestedByUser && pendingTask.slackUserId ? renderIdentity(resolveIdentity("slack", pendingTask.slackUserId)) : undefined;
12558
+ const assignedRequestedBy = buildTriggerRequestedBy(pendingTask);
12146
12559
  return {
12147
12560
  trigger: {
12148
12561
  type: "task_assigned",
@@ -12152,17 +12565,7 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
12152
12565
  status: "in_progress",
12153
12566
  attachments: attachmentsForTrigger(pendingTask.id)
12154
12567
  },
12155
- ...requestedByUser && {
12156
- requestedBy: {
12157
- name: requestedByUser.name,
12158
- email: requestedByUser.email,
12159
- role: requestedByUser.role,
12160
- notes: requestedByNotes
12161
- }
12162
- },
12163
- ...requestedByUnknownName && {
12164
- requestedBy: { name: requestedByUnknownName }
12165
- }
12568
+ ...assignedRequestedBy && { requestedBy: assignedRequestedBy }
12166
12569
  }
12167
12570
  };
12168
12571
  }
@@ -12230,16 +12633,19 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
12230
12633
  for (const candidateId of unassignedIds) {
12231
12634
  const claimed = claimTask(candidateId, myAgentId);
12232
12635
  if (claimed) {
12636
+ updateAgentStatusFromCapacity(myAgentId);
12233
12637
  telemetry.taskEvent("claimed", {
12234
12638
  taskId: claimed.id,
12235
12639
  source: claimed.source,
12236
12640
  agentId: myAgentId
12237
12641
  });
12642
+ const claimedRequestedBy = buildTriggerRequestedBy(claimed);
12238
12643
  return {
12239
12644
  trigger: {
12240
12645
  type: "task_assigned",
12241
12646
  taskId: claimed.id,
12242
- task: { ...claimed, attachments: attachmentsForTrigger(claimed.id) }
12647
+ task: { ...claimed, attachments: attachmentsForTrigger(claimed.id) },
12648
+ ...claimedRequestedBy && { requestedBy: claimedRequestedBy }
12243
12649
  }
12244
12650
  };
12245
12651
  }
@@ -12489,6 +12895,7 @@ async function handlePricing(req, res, pathSegments, queryParams, _myAgentId) {
12489
12895
  // src/http/prompt-templates.ts
12490
12896
  init_zod();
12491
12897
  init_db();
12898
+ init_default_drift();
12492
12899
  init_registry();
12493
12900
  init_resolver();
12494
12901
  init_types();
@@ -12505,6 +12912,14 @@ var EventTemplateDefinitionResponseSchema = exports_external.object({
12505
12912
  variables: exports_external.array(VariableDefinitionSchema),
12506
12913
  category: exports_external.enum(["event", "system", "common", "task_lifecycle", "session"])
12507
12914
  });
12915
+ var PromptTemplateResponseSchema = PromptTemplateSchema.extend({
12916
+ defaultDrifted: exports_external.boolean()
12917
+ }).openapi("PromptTemplateResponse");
12918
+ function toPromptTemplateResponse(template) {
12919
+ const definition = getTemplateDefinition(template.eventType);
12920
+ const defaultDrifted = definition ? getPromptTemplateDefaultDrift(template, definition.defaultBody).defaultDrifted : false;
12921
+ return { ...template, defaultDrifted };
12922
+ }
12508
12923
  var ResolveResultSchema = exports_external.object({
12509
12924
  text: exports_external.string(),
12510
12925
  templateId: exports_external.string().optional(),
@@ -12512,7 +12927,10 @@ var ResolveResultSchema = exports_external.object({
12512
12927
  skipped: exports_external.boolean(),
12513
12928
  unresolved: exports_external.array(exports_external.string())
12514
12929
  });
12515
- var DbResolveResultSchema = exports_external.union([exports_external.object({ template: PromptTemplateSchema }), exports_external.object({ skip: exports_external.literal(true) })]).nullable();
12930
+ var DbResolveResultSchema = exports_external.union([
12931
+ exports_external.object({ template: PromptTemplateResponseSchema }),
12932
+ exports_external.object({ skip: exports_external.literal(true) })
12933
+ ]).nullable();
12516
12934
  var resolvedRoute = route({
12517
12935
  method: "get",
12518
12936
  path: "/api/prompt-templates/resolved",
@@ -12600,7 +13018,7 @@ var checkoutRoute = route({
12600
13018
  responses: {
12601
13019
  200: {
12602
13020
  description: "Checked-out template",
12603
- schema: exports_external.object({ template: PromptTemplateSchema })
13021
+ schema: exports_external.object({ template: PromptTemplateResponseSchema })
12604
13022
  },
12605
13023
  400: { description: "Validation error" },
12606
13024
  404: { description: "Template or version not found" }
@@ -12615,7 +13033,10 @@ var resetRoute = route({
12615
13033
  tags: ["PromptTemplates"],
12616
13034
  params: exports_external.object({ id: exports_external.string() }),
12617
13035
  responses: {
12618
- 200: { description: "Reset template", schema: exports_external.object({ template: PromptTemplateSchema }) },
13036
+ 200: {
13037
+ description: "Reset template",
13038
+ schema: exports_external.object({ template: PromptTemplateResponseSchema })
13039
+ },
12619
13040
  404: { description: "Template not found or no code default available" }
12620
13041
  },
12621
13042
  auth: { apiKey: true }
@@ -12631,7 +13052,7 @@ var getByIdRoute2 = route({
12631
13052
  200: {
12632
13053
  description: "Template with history",
12633
13054
  schema: exports_external.object({
12634
- template: PromptTemplateSchema,
13055
+ template: PromptTemplateResponseSchema,
12635
13056
  history: exports_external.array(PromptTemplateHistorySchema)
12636
13057
  })
12637
13058
  },
@@ -12671,7 +13092,7 @@ var listRoute2 = route({
12671
13092
  responses: {
12672
13093
  200: {
12673
13094
  description: "List of prompt templates",
12674
- schema: exports_external.object({ templates: exports_external.array(PromptTemplateSchema) })
13095
+ schema: exports_external.object({ templates: exports_external.array(PromptTemplateResponseSchema) })
12675
13096
  }
12676
13097
  },
12677
13098
  auth: { apiKey: true }
@@ -12694,7 +13115,7 @@ var upsertRoute = route({
12694
13115
  responses: {
12695
13116
  200: {
12696
13117
  description: "Upserted template",
12697
- schema: exports_external.object({ template: PromptTemplateSchema })
13118
+ schema: exports_external.object({ template: PromptTemplateResponseSchema })
12698
13119
  },
12699
13120
  400: { description: "Validation error" }
12700
13121
  },
@@ -12715,7 +13136,7 @@ async function handlePromptTemplates(req, res, pathSegments, queryParams) {
12715
13136
  const definition = getTemplateDefinition(eventType);
12716
13137
  resolvedRoute.respond(res, 200, {
12717
13138
  resolution: result,
12718
- dbResult,
13139
+ dbResult: dbResult && "template" in dbResult ? { template: toPromptTemplateResponse(dbResult.template) } : dbResult,
12719
13140
  definition: definition ? {
12720
13141
  eventType: definition.eventType,
12721
13142
  header: definition.header,
@@ -12772,7 +13193,7 @@ ${templateBody}` : templateBody;
12772
13193
  return true;
12773
13194
  try {
12774
13195
  const template = checkoutPromptTemplate(parsed.params.id, parsed.body.version);
12775
- checkoutRoute.respond(res, 200, { template });
13196
+ checkoutRoute.respond(res, 200, { template: toPromptTemplateResponse(template) });
12776
13197
  } catch (error) {
12777
13198
  const message = error instanceof Error ? error.message : "Unknown error";
12778
13199
  if (message.includes("not found")) {
@@ -12799,7 +13220,7 @@ ${templateBody}` : templateBody;
12799
13220
  }
12800
13221
  try {
12801
13222
  const template = resetPromptTemplateToDefault(parsed.params.id, definition.defaultBody);
12802
- resetRoute.respond(res, 200, { template });
13223
+ resetRoute.respond(res, 200, { template: toPromptTemplateResponse(template) });
12803
13224
  } catch (error) {
12804
13225
  const message = error instanceof Error ? error.message : "Unknown error";
12805
13226
  jsonError(res, message, 400);
@@ -12816,7 +13237,7 @@ ${templateBody}` : templateBody;
12816
13237
  return true;
12817
13238
  }
12818
13239
  const history = getPromptTemplateHistory(parsed.params.id);
12819
- getByIdRoute2.respond(res, 200, { template, history });
13240
+ getByIdRoute2.respond(res, 200, { template: toPromptTemplateResponse(template), history });
12820
13241
  return true;
12821
13242
  }
12822
13243
  if (deleteByIdRoute.match(req.method, pathSegments)) {
@@ -12846,7 +13267,7 @@ ${templateBody}` : templateBody;
12846
13267
  scopeId: parsed.query.scopeId || undefined,
12847
13268
  isDefault: parsed.query.isDefault ? parsed.query.isDefault === "true" : undefined
12848
13269
  });
12849
- listRoute2.respond(res, 200, { templates });
13270
+ listRoute2.respond(res, 200, { templates: templates.map(toPromptTemplateResponse) });
12850
13271
  return true;
12851
13272
  }
12852
13273
  if (upsertRoute.match(req.method, pathSegments)) {
@@ -12881,7 +13302,7 @@ ${templateBody}` : templateBody;
12881
13302
  changedBy,
12882
13303
  changeReason
12883
13304
  });
12884
- upsertRoute.respond(res, 200, { template });
13305
+ upsertRoute.respond(res, 200, { template: toPromptTemplateResponse(template) });
12885
13306
  } catch (error) {
12886
13307
  const message = error instanceof Error ? error.message : "Unknown error";
12887
13308
  jsonError(res, message, 500);
@@ -13085,7 +13506,7 @@ var scheduleUpdateBodySchema = exports_external.object({
13085
13506
  taskTemplate: exports_external.string().optional(),
13086
13507
  taskType: exports_external.string().optional(),
13087
13508
  tags: exports_external.array(exports_external.string()).optional(),
13088
- priority: exports_external.number().int().optional(),
13509
+ priority: exports_external.number().int().min(0).max(100).optional(),
13089
13510
  targetAgentId: exports_external.string().nullable().optional(),
13090
13511
  enabled: exports_external.boolean().optional(),
13091
13512
  timezone: exports_external.string().optional(),
@@ -13122,7 +13543,7 @@ var createSchedule = route({
13122
13543
  taskTemplate: exports_external.string().min(1).optional(),
13123
13544
  taskType: exports_external.string().optional(),
13124
13545
  tags: exports_external.array(exports_external.string()).optional(),
13125
- priority: exports_external.number().int().optional(),
13546
+ priority: exports_external.number().int().min(0).max(100).optional(),
13126
13547
  targetAgentId: exports_external.string().optional(),
13127
13548
  enabled: exports_external.boolean().optional(),
13128
13549
  timezone: exports_external.string().optional(),
@@ -16296,6 +16717,7 @@ var runRoute = route({
16296
16717
  summary: "Run a reusable or inline script",
16297
16718
  description: "Inline source skips typecheck and is auto-saved as a scratch script only on success.",
16298
16719
  tags: ["Scripts"],
16720
+ headers: runtimeInstanceHeader("acquire work through the script SDK"),
16299
16721
  body: runBodySchema,
16300
16722
  responses: {
16301
16723
  200: { description: "Script run completed", schema: scriptRunResponseSchema },
@@ -16657,6 +17079,7 @@ async function handleScripts(req, res, pathSegments, queryParams, agentId) {
16657
17079
  const agent = requireAgent2(res, agentId);
16658
17080
  if (!agent)
16659
17081
  return true;
17082
+ const runtimeInstanceId = ((h) => Array.isArray(h) ? h[0] : h)(req.headers["x-runtime-instance-id"]);
16660
17083
  let source = parsed.body.source;
16661
17084
  let fsMode = parsed.body.fsMode;
16662
17085
  let namedScript = null;
@@ -16682,6 +17105,7 @@ async function handleScripts(req, res, pathSegments, queryParams, agentId) {
16682
17105
  args: parsed.body.args,
16683
17106
  fsMode,
16684
17107
  agentId: agent.id,
17108
+ runtimeInstanceId,
16685
17109
  egressSecrets: credentials.egressSecrets,
16686
17110
  failedBindings: credentials.failedBindings,
16687
17111
  apiConnections: getScriptApiConnectionDescriptors({ agentId: agent.id }),
@@ -17120,7 +17544,10 @@ var SessionCostSummaryTotalsSchema = exports_external.object({
17120
17544
  totalDurationMs: exports_external.number().int(),
17121
17545
  totalSessions: exports_external.number().int(),
17122
17546
  avgCostPerSession: exports_external.number(),
17123
- attributedCostUsd: exports_external.number()
17547
+ attributedCostUsd: exports_external.number(),
17548
+ attributableCostUsd: exports_external.number(),
17549
+ excludedCostUsd: exports_external.number(),
17550
+ excludedTaskCount: exports_external.number().int()
17124
17551
  });
17125
17552
  var SessionCostDailyRowSchema = exports_external.object({
17126
17553
  date: exports_external.string(),
@@ -17155,6 +17582,15 @@ var DashboardCostSummarySchema = exports_external.object({
17155
17582
  costToday: exports_external.number(),
17156
17583
  costMtd: exports_external.number()
17157
17584
  });
17585
+ var AttributionByPersonRowSchema = exports_external.object({
17586
+ userId: exports_external.string(),
17587
+ problemsInitiated: exports_external.number().int(),
17588
+ problemsShipped: exports_external.number().int(),
17589
+ agentsReached: exports_external.number().int(),
17590
+ reposReached: exports_external.number().int(),
17591
+ surfacesReached: exports_external.number().int(),
17592
+ firstPassYield: exports_external.null()
17593
+ });
17158
17594
  var createSessionLogsRoute = route({
17159
17595
  method: "post",
17160
17596
  path: "/api/session-logs",
@@ -17247,6 +17683,23 @@ var getSessionCostSummaryRoute = route({
17247
17683
  400: { description: "Invalid groupBy" }
17248
17684
  }
17249
17685
  });
17686
+ var getAttributionByPersonRoute = route({
17687
+ method: "get",
17688
+ path: "/api/attribution/by-person",
17689
+ pattern: ["api", "attribution", "by-person"],
17690
+ summary: "Four-metric per-person attribution (problems initiated/shipped, reach)",
17691
+ tags: ["Session Data"],
17692
+ query: exports_external.object({
17693
+ startDate: exports_external.string().optional(),
17694
+ endDate: exports_external.string().optional()
17695
+ }),
17696
+ responses: {
17697
+ 200: {
17698
+ description: "Per-person attribution rows",
17699
+ schema: exports_external.object({ rows: exports_external.array(AttributionByPersonRowSchema) })
17700
+ }
17701
+ }
17702
+ });
17250
17703
  var getDashboardCosts = route({
17251
17704
  method: "get",
17252
17705
  path: "/api/session-costs/dashboard",
@@ -17408,6 +17861,17 @@ async function handleSessionData(req, res, pathSegments, queryParams, _myAgentId
17408
17861
  getDashboardCosts.respond(res, 200, dashboardCosts);
17409
17862
  return true;
17410
17863
  }
17864
+ if (getAttributionByPersonRoute.match(req.method, pathSegments)) {
17865
+ const parsed = await getAttributionByPersonRoute.parse(req, res, pathSegments, queryParams);
17866
+ if (!parsed)
17867
+ return true;
17868
+ const rows = getAttributionByPerson({
17869
+ startDate: parsed.query.startDate || undefined,
17870
+ endDate: parsed.query.endDate || undefined
17871
+ });
17872
+ getAttributionByPersonRoute.respond(res, 200, { rows });
17873
+ return true;
17874
+ }
17411
17875
  if (listSessionCosts.match(req.method, pathSegments)) {
17412
17876
  const parsed = await listSessionCosts.parse(req, res, pathSegments, queryParams);
17413
17877
  if (!parsed)
@@ -19183,7 +19647,7 @@ var createTask = route({
19183
19647
  agentId: exports_external.string().optional(),
19184
19648
  taskType: exports_external.string().optional(),
19185
19649
  tags: exports_external.array(exports_external.string()).optional(),
19186
- priority: exports_external.number().int().optional(),
19650
+ priority: exports_external.number().int().min(0).max(100).optional(),
19187
19651
  dependsOn: exports_external.array(exports_external.string()).optional(),
19188
19652
  offeredTo: exports_external.string().optional(),
19189
19653
  dir: exports_external.string().optional(),
@@ -19643,7 +20107,7 @@ async function handleTasks(req, res, pathSegments, queryParams, myAgentId) {
19643
20107
  creatorAgentId: myAgentId || undefined,
19644
20108
  taskType: parsed.body.taskType || undefined,
19645
20109
  tags: parsed.body.tags || undefined,
19646
- priority: parsed.body.priority || 50,
20110
+ priority: parsed.body.priority,
19647
20111
  dependsOn: parsed.body.dependsOn || undefined,
19648
20112
  offeredTo: parsed.body.offeredTo || undefined,
19649
20113
  dir: parsed.body.dir || undefined,
@@ -21202,6 +21666,7 @@ var updateUserRoute = route({
21202
21666
  preferredChannel: exports_external.string().optional(),
21203
21667
  timezone: exports_external.string().optional(),
21204
21668
  metadata: exports_external.record(exports_external.string(), exports_external.unknown()).nullable().optional(),
21669
+ comms: UserCommsPrefsSchema.nullable().optional().describe("Merges into metadata.comms without touching sibling metadata keys; null removes only the comms key. When metadata is also provided, it is applied first and replaces the whole blob."),
21205
21670
  dailyBudgetUsd: exports_external.number().nullable().optional(),
21206
21671
  status: exports_external.enum(["invited", "active", "suspended"]).optional(),
21207
21672
  identities: exports_external.array(exports_external.object({ kind: exports_external.string().min(1), externalId: exports_external.string().min(1) })).optional()
@@ -21620,43 +22085,46 @@ async function handleUsers(req, res, pathSegments, queryParams) {
21620
22085
  return true;
21621
22086
  }
21622
22087
  try {
21623
- for (const ident of sourceBefore.identities) {
21624
- unlinkIdentity(sourceId, ident.kind, ident.externalId, actor);
21625
- linkIdentity(targetId, ident.kind, ident.externalId, actor);
21626
- }
21627
- const targetAliases = new Set(targetBefore.emailAliases ?? []);
21628
- const targetPrimary = (targetBefore.email ?? "").toLowerCase();
21629
- const newAliases = [];
21630
- const candidates = [
21631
- ...sourceBefore.email ? [sourceBefore.email] : [],
21632
- ...sourceBefore.emailAliases ?? []
21633
- ];
21634
- for (const candidate of candidates) {
21635
- const lower = candidate.toLowerCase();
21636
- if (!lower || lower === targetPrimary)
21637
- continue;
21638
- if (![...targetAliases].some((a) => a.toLowerCase() === lower) && !newAliases.some((a) => a.toLowerCase() === lower)) {
21639
- newAliases.push(candidate);
22088
+ const mergedUser = getDb().transaction(() => {
22089
+ for (const ident of sourceBefore.identities) {
22090
+ unlinkIdentity(sourceId, ident.kind, ident.externalId, actor);
22091
+ linkIdentity(targetId, ident.kind, ident.externalId, actor);
21640
22092
  }
21641
- }
21642
- if (newAliases.length > 0) {
21643
- const merged = [...targetBefore.emailAliases ?? [], ...newAliases];
21644
- updateUser(targetId, { emailAliases: merged });
21645
- for (const alias of newAliases) {
21646
- recordIdentityEvent(targetId, "email_added", actor, null, { email: alias });
22093
+ const targetAliases = new Set(targetBefore.emailAliases ?? []);
22094
+ const targetPrimary = (targetBefore.email ?? "").toLowerCase();
22095
+ const newAliases = [];
22096
+ const candidates = [
22097
+ ...sourceBefore.email ? [sourceBefore.email] : [],
22098
+ ...sourceBefore.emailAliases ?? []
22099
+ ];
22100
+ for (const candidate of candidates) {
22101
+ const lower = candidate.toLowerCase();
22102
+ if (!lower || lower === targetPrimary)
22103
+ continue;
22104
+ if (![...targetAliases].some((a) => a.toLowerCase() === lower) && !newAliases.some((a) => a.toLowerCase() === lower)) {
22105
+ newAliases.push(candidate);
22106
+ }
21647
22107
  }
21648
- }
21649
- deleteUser(sourceId);
21650
- const targetAfter = composeUser(targetId);
21651
- recordIdentityEvent(targetId, "manual_merge", actor, targetBefore, {
21652
- ...targetAfter,
21653
- source: {
21654
- id: sourceBefore.id,
21655
- name: sourceBefore.name,
21656
- email: sourceBefore.email
22108
+ if (newAliases.length > 0) {
22109
+ const merged = [...targetBefore.emailAliases ?? [], ...newAliases];
22110
+ updateUser(targetId, { emailAliases: merged });
22111
+ for (const alias of newAliases) {
22112
+ recordIdentityEvent(targetId, "email_added", actor, null, { email: alias });
22113
+ }
21657
22114
  }
21658
- });
21659
- mergeUsersRoute.respond(res, 200, { user: composeUser(targetId) });
22115
+ deleteUser(sourceId, targetId);
22116
+ const targetAfter = composeUser(targetId);
22117
+ recordIdentityEvent(targetId, "manual_merge", actor, targetBefore, {
22118
+ ...targetAfter,
22119
+ source: {
22120
+ id: sourceBefore.id,
22121
+ name: sourceBefore.name,
22122
+ email: sourceBefore.email
22123
+ }
22124
+ });
22125
+ return composeUser(targetId);
22126
+ })();
22127
+ mergeUsersRoute.respond(res, 200, { user: mergedUser });
21660
22128
  } catch (err) {
21661
22129
  jsonError(res, err instanceof Error ? err.message : "Failed to merge users", 500);
21662
22130
  }
@@ -21687,9 +22155,19 @@ async function handleUsers(req, res, pathSegments, queryParams) {
21687
22155
  return true;
21688
22156
  }
21689
22157
  try {
21690
- const { identities, metadata, ...rest } = parsed.body;
22158
+ const { identities, metadata, comms, ...rest } = parsed.body;
21691
22159
  const update = { ...rest };
21692
- if (metadata !== undefined) {
22160
+ if (comms !== undefined) {
22161
+ const base = {
22162
+ ...metadata !== undefined ? metadata ?? {} : before.metadata ?? {}
22163
+ };
22164
+ if (comms === null) {
22165
+ delete base.comms;
22166
+ } else {
22167
+ base.comms = comms;
22168
+ }
22169
+ update.metadata = Object.keys(base).length > 0 ? base : null;
22170
+ } else if (metadata !== undefined) {
21693
22171
  update.metadata = metadata;
21694
22172
  }
21695
22173
  const updated = updateUser(parsed.params.id, update);
@@ -22301,7 +22779,10 @@ async function handleWebhooks(req, res, pathSegments) {
22301
22779
  const routing = routeKapsoInbound(payload);
22302
22780
  switch (routing.kind) {
22303
22781
  case "workflow":
22304
- await handleWebhookTrigger(routing.workflowId, rawBody, req.headers, getExecutorRegistry(), { alreadyAuthenticated: true });
22782
+ await handleWebhookTrigger(routing.workflowId, rawBody, req.headers, getExecutorRegistry(), {
22783
+ alreadyAuthenticated: true,
22784
+ requestedByUserId: resolveKapsoRequestedByUserId(payload)
22785
+ });
22305
22786
  break;
22306
22787
  case "no_mapping":
22307
22788
  console.warn(`[Kapso] No native mapping for phone_number_id "${routing.phoneNumberId}" — ignoring (register it with register-kapso-number)`);
@@ -22418,7 +22899,6 @@ async function handleWorkflowEvents(req, res, pathSegments, queryParams) {
22418
22899
  init_zod();
22419
22900
  init_db();
22420
22901
  init_types();
22421
- init_request_auth_context();
22422
22902
  var WorkflowWithFavoriteSchema = WorkflowSchema.extend({ favorite: exports_external.boolean() });
22423
22903
  var WorkflowSummarySchema = WorkflowSchema.omit({
22424
22904
  definition: true,
@@ -23085,12 +23565,11 @@ async function handleWorkflows(req, res, pathSegments, queryParams, myAgentId) {
23085
23565
  return true;
23086
23566
  }
23087
23567
  const body = await parseBody(req);
23088
- const auth = getRequestAuth(req);
23089
23568
  let runId;
23090
23569
  try {
23091
23570
  runId = await startWorkflowExecution(workflow, body, getExecutorRegistry(), {
23092
23571
  triggerType: "api",
23093
- requestedByUserId: auth?.kind === "user" ? auth.userId : workflow.createdBy
23572
+ requestedByUserId: resolveHttpAuditUserId(req, myAgentId) ?? undefined
23094
23573
  });
23095
23574
  } catch (err) {
23096
23575
  if (err instanceof TriggerSchemaError) {
@@ -23585,14 +24064,15 @@ async function shutdown() {
23585
24064
  sessionsProcessed: getServerSessionsProcessed()
23586
24065
  });
23587
24066
  if (hasCapability("scheduling")) {
23588
- const { stopScheduler } = await import("./index-25wjsdv2.js");
24067
+ const { stopScheduler } = await import("./index-67pzqfrb.js");
23589
24068
  stopScheduler();
23590
24069
  }
23591
24070
  stopHeartbeat();
24071
+ stopQueueStallAlarm();
23592
24072
  stopScriptRunSupervisor();
23593
24073
  await stopSlackApp();
23594
24074
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
23595
- const { stopOAuthKeepalive } = await import("./keepalive-vc7s2aa6.js");
24075
+ const { stopOAuthKeepalive } = await import("./keepalive-9k51nqhc.js");
23596
24076
  await stopOAuthKeepalive();
23597
24077
  }
23598
24078
  stopOAuthPendingGc();
@@ -23631,11 +24111,11 @@ if (!globalState.__sigintRegistered) {
23631
24111
  globalState.__sigintRegistered = true;
23632
24112
  process.on("SIGINT", () => {
23633
24113
  shutdownSignal = "SIGINT";
23634
- shutdown();
24114
+ shutdown().catch((err) => console.error("[shutdown] SIGINT shutdown failed:", scrubSecrets(err instanceof Error ? err.message : String(err))));
23635
24115
  });
23636
24116
  process.on("SIGTERM", () => {
23637
24117
  shutdownSignal = "SIGTERM";
23638
- shutdown();
24118
+ shutdown().catch((err) => console.error("[shutdown] SIGTERM shutdown failed:", scrubSecrets(err instanceof Error ? err.message : String(err))));
23639
24119
  });
23640
24120
  }
23641
24121
  if (!globalState.__runId) {
@@ -23647,6 +24127,7 @@ try {
23647
24127
  startupConfigsInjected = loadGlobalConfigsIntoEnv(false);
23648
24128
  } catch (err) {
23649
24129
  console.error("[startup] Failed to load global swarm configs before listen:", err);
24130
+ process.exitCode = 1;
23650
24131
  throw err;
23651
24132
  }
23652
24133
  try {
@@ -23655,15 +24136,15 @@ try {
23655
24136
  console.warn("[startup] CAPABILITIES upgrade seed failed (non-fatal):", err);
23656
24137
  }
23657
24138
  try {
23658
- const { seedPricingFromModelsDev } = await import("./seed-pricing-8kceb43f.js");
24139
+ const { seedPricingFromModelsDev } = await import("./seed-pricing-52xx6z63.js");
23659
24140
  seedPricingFromModelsDev();
23660
- const { startPricingRefreshLoop } = await import("./pricing-refresh-2cn6effr.js");
24141
+ const { startPricingRefreshLoop } = await import("./pricing-refresh-jw1yw2fn.js");
23661
24142
  startPricingRefreshLoop();
23662
24143
  } catch (err) {
23663
24144
  console.error("[startup] Failed to seed pricing rows:", err);
23664
24145
  }
23665
24146
  try {
23666
- const { ensureRbacSeedsSynced } = await import("./rbac-roles-vynday5g.js");
24147
+ const { ensureRbacSeedsSynced } = await import("./rbac-roles-dg964c8p.js");
23667
24148
  ensureRbacSeedsSynced();
23668
24149
  } catch (err) {
23669
24150
  console.error("[startup] Failed to sync RBAC seed rows:", err);
@@ -23671,7 +24152,7 @@ try {
23671
24152
  throw err;
23672
24153
  }
23673
24154
  try {
23674
- const { runAllSeeders } = await import("./index-eaxyqcmj.js");
24155
+ const { runAllSeeders } = await import("./index-dvsk64sm.js");
23675
24156
  await runAllSeeders({ scriptEmbeddingMode: "skip" });
23676
24157
  } catch (err) {
23677
24158
  console.error("[startup] Failed to seed built-in entities:", err);
@@ -23700,6 +24181,7 @@ httpServer.listen(port, async () => {
23700
24181
  }, { generateIfMissing: true });
23701
24182
  telemetry.server("started", { port });
23702
24183
  await startSlackApp();
24184
+ startQueueStallAlarm();
23703
24185
  initGitHub();
23704
24186
  initGitLab();
23705
24187
  initAgentMail();
@@ -23708,35 +24190,35 @@ httpServer.listen(port, async () => {
23708
24190
  initWorkflows();
23709
24191
  startScriptRunSupervisor(getMcpBaseUrl());
23710
24192
  if (hasCapability("scheduling")) {
23711
- const { startScheduler } = await import("./index-25wjsdv2.js");
23712
- const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-ywds4812.js");
24193
+ const { startScheduler } = await import("./index-67pzqfrb.js");
24194
+ const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-4cbyhq2g.js");
23713
24195
  const intervalMs = Number(process.env.SCHEDULER_INTERVAL_MS) || 1e4;
23714
24196
  startScheduler(getExecutorRegistry2(), intervalMs, {
23715
24197
  runId: globalState.__runId
23716
24198
  });
23717
24199
  }
23718
24200
  if (!isEnvFlagEnabled("HEARTBEAT_DISABLE", false)) {
23719
- const { startHeartbeat } = await import("./index-vg4snay4.js");
24201
+ const { startHeartbeat } = await import("./index-yrfphye1.js");
23720
24202
  const heartbeatMs = Number(process.env.HEARTBEAT_INTERVAL_MS) || 90000;
23721
24203
  startHeartbeat(heartbeatMs);
23722
24204
  }
23723
24205
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
23724
- const { startOAuthKeepalive } = await import("./keepalive-vc7s2aa6.js");
24206
+ const { startOAuthKeepalive } = await import("./keepalive-9k51nqhc.js");
23725
24207
  startOAuthKeepalive();
23726
24208
  }
23727
24209
  if (process.env.OAUTH_REFRESH_SWEEP_DISABLE !== "true") {
23728
- const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-yecgjpk4.js");
24210
+ const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-273a64r2.js");
23729
24211
  startOAuthRefreshSweep();
23730
24212
  }
23731
24213
  startOAuthPendingGc();
23732
24214
  startMemoryGc();
23733
- import("./boot-reembed-q7mp8hcr.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
24215
+ import("./boot-reembed-b1rcqn85.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
23734
24216
  console.error("[boot-reembed] startup backfill failed (non-fatal):", err);
23735
24217
  });
23736
- import("./boot-reembed-xmw8wcx6.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
24218
+ import("./boot-reembed-kw2541c4.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
23737
24219
  console.error("[boot-reembed-scripts] startup backfill failed (non-fatal):", err);
23738
24220
  });
23739
- import("./boot-scrub-logs-dsqrv79n.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
24221
+ import("./boot-scrub-logs-ja29t92g.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
23740
24222
  console.error("[boot-scrub-logs] startup scrub failed (non-fatal):", err);
23741
24223
  });
23742
24224
  }).on("error", (err) => {