@rudderhq/server 0.4.6-canary.8 → 0.5.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 (365) hide show
  1. package/dist/agent-runtimes/http/execute.d.ts.map +1 -1
  2. package/dist/agent-runtimes/http/execute.js +8 -2
  3. package/dist/agent-runtimes/http/execute.js.map +1 -1
  4. package/dist/agent-runtimes/process/execute.d.ts.map +1 -1
  5. package/dist/agent-runtimes/process/execute.js +3 -1
  6. package/dist/agent-runtimes/process/execute.js.map +1 -1
  7. package/dist/agent-runtimes/utils.d.ts +6 -1
  8. package/dist/agent-runtimes/utils.d.ts.map +1 -1
  9. package/dist/agent-runtimes/utils.js +1 -1
  10. package/dist/agent-runtimes/utils.js.map +1 -1
  11. package/dist/app.d.ts +3 -3
  12. package/dist/app.d.ts.map +1 -1
  13. package/dist/app.js +17 -8
  14. package/dist/app.js.map +1 -1
  15. package/dist/bootstrap/create-http-app.d.ts +6 -1
  16. package/dist/bootstrap/create-http-app.d.ts.map +1 -1
  17. package/dist/bootstrap/create-http-app.js +122 -46
  18. package/dist/bootstrap/create-http-app.js.map +1 -1
  19. package/dist/bootstrap/plugin-host-runtime.d.ts.map +1 -1
  20. package/dist/bootstrap/plugin-host-runtime.js +89 -31
  21. package/dist/bootstrap/plugin-host-runtime.js.map +1 -1
  22. package/dist/bootstrap/register-api-routes.d.ts +3 -1
  23. package/dist/bootstrap/register-api-routes.d.ts.map +1 -1
  24. package/dist/bootstrap/register-api-routes.js +3 -3
  25. package/dist/bootstrap/register-api-routes.js.map +1 -1
  26. package/dist/bootstrap/types.d.ts +1 -0
  27. package/dist/bootstrap/types.d.ts.map +1 -1
  28. package/dist/bundled-plugins/plugin-linear/dist/worker.js +351 -174
  29. package/dist/bundled-plugins/plugin-linear/dist/worker.js.map +3 -3
  30. package/dist/config.d.ts +2 -0
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +23 -0
  33. package/dist/config.js.map +1 -1
  34. package/dist/home-paths.d.ts.map +1 -1
  35. package/dist/home-paths.js +79 -7
  36. package/dist/home-paths.js.map +1 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +112 -119
  39. package/dist/index.js.map +1 -1
  40. package/dist/realtime/live-events-ws.d.ts +4 -20
  41. package/dist/realtime/live-events-ws.d.ts.map +1 -1
  42. package/dist/realtime/live-events-ws.js +68 -8
  43. package/dist/realtime/live-events-ws.js.map +1 -1
  44. package/dist/routes/access-onboarding.helpers.js +3 -3
  45. package/dist/routes/access-onboarding.helpers.js.map +1 -1
  46. package/dist/routes/access.helpers.d.ts.map +1 -1
  47. package/dist/routes/access.helpers.js +3 -2
  48. package/dist/routes/access.helpers.js.map +1 -1
  49. package/dist/routes/access.js +1 -1
  50. package/dist/routes/access.js.map +1 -1
  51. package/dist/routes/activity.d.ts.map +1 -1
  52. package/dist/routes/activity.js +5 -1
  53. package/dist/routes/activity.js.map +1 -1
  54. package/dist/routes/agents.management-routes.d.ts.map +1 -1
  55. package/dist/routes/agents.management-routes.js +15 -15
  56. package/dist/routes/agents.management-routes.js.map +1 -1
  57. package/dist/routes/assets.d.ts.map +1 -1
  58. package/dist/routes/assets.js +9 -2
  59. package/dist/routes/assets.js.map +1 -1
  60. package/dist/routes/chat-background-runtime.d.ts +19 -0
  61. package/dist/routes/chat-background-runtime.d.ts.map +1 -0
  62. package/dist/routes/chat-background-runtime.js +129 -0
  63. package/dist/routes/chat-background-runtime.js.map +1 -0
  64. package/dist/routes/chats.d.ts +2 -1
  65. package/dist/routes/chats.d.ts.map +1 -1
  66. package/dist/routes/chats.js +944 -24
  67. package/dist/routes/chats.js.map +1 -1
  68. package/dist/routes/chats.stream-routes.d.ts.map +1 -1
  69. package/dist/routes/chats.stream-routes.js +552 -76
  70. package/dist/routes/chats.stream-routes.js.map +1 -1
  71. package/dist/routes/issues.comments-attachments.d.ts.map +1 -1
  72. package/dist/routes/issues.comments-attachments.js +14 -31
  73. package/dist/routes/issues.comments-attachments.js.map +1 -1
  74. package/dist/routes/onboarding.js +1 -1
  75. package/dist/routes/onboarding.js.map +1 -1
  76. package/dist/routes/orgs.d.ts +2 -1
  77. package/dist/routes/orgs.d.ts.map +1 -1
  78. package/dist/routes/orgs.js +32 -3
  79. package/dist/routes/orgs.js.map +1 -1
  80. package/dist/routes/run-intelligence.d.ts.map +1 -1
  81. package/dist/routes/run-intelligence.js +109 -25
  82. package/dist/routes/run-intelligence.js.map +1 -1
  83. package/dist/runtime/runtime-supervisor.d.ts +21 -0
  84. package/dist/runtime/runtime-supervisor.d.ts.map +1 -0
  85. package/dist/runtime/runtime-supervisor.js +66 -0
  86. package/dist/runtime/runtime-supervisor.js.map +1 -0
  87. package/dist/services/activity-log.d.ts +4 -1
  88. package/dist/services/activity-log.d.ts.map +1 -1
  89. package/dist/services/activity-log.js +12 -4
  90. package/dist/services/activity-log.js.map +1 -1
  91. package/dist/services/activity.d.ts +11 -394
  92. package/dist/services/activity.d.ts.map +1 -1
  93. package/dist/services/activity.js +24 -18
  94. package/dist/services/activity.js.map +1 -1
  95. package/dist/services/agents.d.ts +799 -137
  96. package/dist/services/agents.d.ts.map +1 -1
  97. package/dist/services/approvals.d.ts +3 -3
  98. package/dist/services/automation-chat-output.d.ts.map +1 -1
  99. package/dist/services/automation-chat-output.js +115 -94
  100. package/dist/services/automation-chat-output.js.map +1 -1
  101. package/dist/services/budgets.d.ts.map +1 -1
  102. package/dist/services/budgets.js +38 -36
  103. package/dist/services/budgets.js.map +1 -1
  104. package/dist/services/chat-agent-runs.d.ts +3 -1
  105. package/dist/services/chat-agent-runs.d.ts.map +1 -1
  106. package/dist/services/chat-agent-runs.js +97 -34
  107. package/dist/services/chat-agent-runs.js.map +1 -1
  108. package/dist/services/chat-assistant.d.ts.map +1 -1
  109. package/dist/services/chat-assistant.helpers.d.ts +27 -4
  110. package/dist/services/chat-assistant.helpers.d.ts.map +1 -1
  111. package/dist/services/chat-assistant.helpers.js +66 -2
  112. package/dist/services/chat-assistant.helpers.js.map +1 -1
  113. package/dist/services/chat-assistant.inline-visuals.test.d.ts +2 -0
  114. package/dist/services/chat-assistant.inline-visuals.test.d.ts.map +1 -0
  115. package/dist/services/chat-assistant.inline-visuals.test.js +86 -0
  116. package/dist/services/chat-assistant.inline-visuals.test.js.map +1 -0
  117. package/dist/services/chat-assistant.js +115 -22
  118. package/dist/services/chat-assistant.js.map +1 -1
  119. package/dist/services/chat-generation-locks.d.ts +85 -0
  120. package/dist/services/chat-generation-locks.d.ts.map +1 -1
  121. package/dist/services/chat-generation-locks.js +371 -9
  122. package/dist/services/chat-generation-locks.js.map +1 -1
  123. package/dist/services/chat-generation-locks.test.d.ts +2 -0
  124. package/dist/services/chat-generation-locks.test.d.ts.map +1 -0
  125. package/dist/services/chat-generation-locks.test.js +324 -0
  126. package/dist/services/chat-generation-locks.test.js.map +1 -0
  127. package/dist/services/chat-generation-protocol.d.ts +674 -0
  128. package/dist/services/chat-generation-protocol.d.ts.map +1 -0
  129. package/dist/services/chat-generation-protocol.js +1571 -0
  130. package/dist/services/chat-generation-protocol.js.map +1 -0
  131. package/dist/services/chat-generation-protocol.test.d.ts +2 -0
  132. package/dist/services/chat-generation-protocol.test.d.ts.map +1 -0
  133. package/dist/services/chat-generation-protocol.test.js +1156 -0
  134. package/dist/services/chat-generation-protocol.test.js.map +1 -0
  135. package/dist/services/chat-title-generation.d.ts +0 -3
  136. package/dist/services/chat-title-generation.d.ts.map +1 -1
  137. package/dist/services/chat-title-generation.js +2 -32
  138. package/dist/services/chat-title-generation.js.map +1 -1
  139. package/dist/services/chat-work-manifest.d.ts.map +1 -1
  140. package/dist/services/chat-work-manifest.js +5 -1
  141. package/dist/services/chat-work-manifest.js.map +1 -1
  142. package/dist/services/chats.d.ts +1451 -272
  143. package/dist/services/chats.d.ts.map +1 -1
  144. package/dist/services/chats.js +1372 -35
  145. package/dist/services/chats.js.map +1 -1
  146. package/dist/services/costs.d.ts +34 -7
  147. package/dist/services/costs.d.ts.map +1 -1
  148. package/dist/services/costs.js +129 -61
  149. package/dist/services/costs.js.map +1 -1
  150. package/dist/services/finance.d.ts +3 -3
  151. package/dist/services/goals.d.ts +2 -2
  152. package/dist/services/heartbeat-run-summary.d.ts.map +1 -1
  153. package/dist/services/heartbeat-run-summary.js +16 -1
  154. package/dist/services/heartbeat-run-summary.js.map +1 -1
  155. package/dist/services/heartbeat.d.ts +1 -1
  156. package/dist/services/heartbeat.d.ts.map +1 -1
  157. package/dist/services/heartbeat.js +1 -1
  158. package/dist/services/heartbeat.js.map +1 -1
  159. package/dist/services/index.d.ts +1 -0
  160. package/dist/services/index.d.ts.map +1 -1
  161. package/dist/services/index.js +1 -0
  162. package/dist/services/index.js.map +1 -1
  163. package/dist/services/integrations/agent-integrations.d.ts +1 -1
  164. package/dist/services/integrations/custom-integrations.d.ts +1 -1
  165. package/dist/services/integrations/feishu/runtime.d.ts.map +1 -1
  166. package/dist/services/integrations/feishu/runtime.js +16 -0
  167. package/dist/services/integrations/feishu/runtime.js.map +1 -1
  168. package/dist/services/issues.comments-attachments.d.ts +111 -0
  169. package/dist/services/issues.comments-attachments.d.ts.map +1 -1
  170. package/dist/services/issues.comments-attachments.js +138 -66
  171. package/dist/services/issues.comments-attachments.js.map +1 -1
  172. package/dist/services/issues.d.ts +56 -0
  173. package/dist/services/issues.d.ts.map +1 -1
  174. package/dist/services/issues.helpers.d.ts.map +1 -1
  175. package/dist/services/issues.helpers.js +2 -2
  176. package/dist/services/issues.helpers.js.map +1 -1
  177. package/dist/services/issues.js +5 -2
  178. package/dist/services/issues.js.map +1 -1
  179. package/dist/services/knowledge-portability/organization-skills.catalog.d.ts.map +1 -1
  180. package/dist/services/knowledge-portability/organization-skills.catalog.js +7 -1
  181. package/dist/services/knowledge-portability/organization-skills.catalog.js.map +1 -1
  182. package/dist/services/messenger.d.ts.map +1 -1
  183. package/dist/services/messenger.js +11 -9
  184. package/dist/services/messenger.js.map +1 -1
  185. package/dist/services/organization-workspace-browser.d.ts +1 -1
  186. package/dist/services/organization-workspace-browser.d.ts.map +1 -1
  187. package/dist/services/organization-workspace-browser.js +49 -5
  188. package/dist/services/organization-workspace-browser.js.map +1 -1
  189. package/dist/services/orgs.d.ts.map +1 -1
  190. package/dist/services/orgs.js +36 -12
  191. package/dist/services/orgs.js.map +1 -1
  192. package/dist/services/plugin-dev-watcher.d.ts +19 -2
  193. package/dist/services/plugin-dev-watcher.d.ts.map +1 -1
  194. package/dist/services/plugin-dev-watcher.js +45 -11
  195. package/dist/services/plugin-dev-watcher.js.map +1 -1
  196. package/dist/services/plugin-registry.d.ts +28 -28
  197. package/dist/services/projects.d.ts +1 -1
  198. package/dist/services/run-events.d.ts +20 -0
  199. package/dist/services/run-events.d.ts.map +1 -0
  200. package/dist/services/run-events.js +34 -0
  201. package/dist/services/run-events.js.map +1 -0
  202. package/dist/services/run-intelligence.d.ts +66 -4
  203. package/dist/services/run-intelligence.d.ts.map +1 -1
  204. package/dist/services/run-intelligence.js +391 -42
  205. package/dist/services/run-intelligence.js.map +1 -1
  206. package/dist/services/run-log-store.d.ts.map +1 -1
  207. package/dist/services/run-log-store.js +26 -3
  208. package/dist/services/run-log-store.js.map +1 -1
  209. package/dist/services/runtime-kernel/heartbeat.core.d.ts +24 -1
  210. package/dist/services/runtime-kernel/heartbeat.core.d.ts.map +1 -1
  211. package/dist/services/runtime-kernel/heartbeat.core.js +2 -1
  212. package/dist/services/runtime-kernel/heartbeat.core.js.map +1 -1
  213. package/dist/services/runtime-kernel/heartbeat.d.ts +98 -37
  214. package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
  215. package/dist/services/runtime-kernel/heartbeat.execute.d.ts +3 -1
  216. package/dist/services/runtime-kernel/heartbeat.execute.d.ts.map +1 -1
  217. package/dist/services/runtime-kernel/heartbeat.execute.js +394 -219
  218. package/dist/services/runtime-kernel/heartbeat.execute.js.map +1 -1
  219. package/dist/services/runtime-kernel/heartbeat.js +603 -205
  220. package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
  221. package/dist/services/runtime-kernel/heartbeat.misc.d.ts.map +1 -1
  222. package/dist/services/runtime-kernel/heartbeat.misc.js +34 -24
  223. package/dist/services/runtime-kernel/heartbeat.misc.js.map +1 -1
  224. package/dist/services/runtime-kernel/heartbeat.recovery.d.ts.map +1 -1
  225. package/dist/services/runtime-kernel/heartbeat.recovery.js +56 -6
  226. package/dist/services/runtime-kernel/heartbeat.recovery.js.map +1 -1
  227. package/dist/services/runtime-kernel/heartbeat.release.d.ts +3 -1
  228. package/dist/services/runtime-kernel/heartbeat.release.d.ts.map +1 -1
  229. package/dist/services/runtime-kernel/heartbeat.release.js +276 -44
  230. package/dist/services/runtime-kernel/heartbeat.release.js.map +1 -1
  231. package/dist/services/runtime-kernel/heartbeat.sessions.d.ts +42 -1
  232. package/dist/services/runtime-kernel/heartbeat.sessions.d.ts.map +1 -1
  233. package/dist/services/runtime-kernel/heartbeat.sessions.js +110 -8
  234. package/dist/services/runtime-kernel/heartbeat.sessions.js.map +1 -1
  235. package/dist/services/runtime-kernel/heartbeat.terminal.d.ts +575 -0
  236. package/dist/services/runtime-kernel/heartbeat.terminal.d.ts.map +1 -0
  237. package/dist/services/runtime-kernel/heartbeat.terminal.js +589 -0
  238. package/dist/services/runtime-kernel/heartbeat.terminal.js.map +1 -0
  239. package/dist/services/runtime-kernel/heartbeat.wakeup.d.ts.map +1 -1
  240. package/dist/services/runtime-kernel/heartbeat.wakeup.js +238 -92
  241. package/dist/services/runtime-kernel/heartbeat.wakeup.js.map +1 -1
  242. package/dist/services/runtime-kernel/model-fallback.d.ts.map +1 -1
  243. package/dist/services/runtime-kernel/model-fallback.js +11 -0
  244. package/dist/services/runtime-kernel/model-fallback.js.map +1 -1
  245. package/dist/services/side-chats.d.ts +212 -0
  246. package/dist/services/side-chats.d.ts.map +1 -0
  247. package/dist/services/side-chats.js +379 -0
  248. package/dist/services/side-chats.js.map +1 -0
  249. package/dist/services/workspace-runtime.services.d.ts +1 -1
  250. package/dist/services/workspace-web-preview.d.ts +36 -0
  251. package/dist/services/workspace-web-preview.d.ts.map +1 -0
  252. package/dist/services/workspace-web-preview.js +566 -0
  253. package/dist/services/workspace-web-preview.js.map +1 -0
  254. package/package.json +13 -13
  255. package/resources/bundled-skills/rudder-docs/SKILL.md +161 -0
  256. package/resources/bundled-skills/rudder-docs/evals/trigger-evals.json +82 -0
  257. package/{skills/rudder → resources/bundled-skills/rudder-docs}/references/api-reference.md +17 -1
  258. package/{skills/rudder → resources/bundled-skills/rudder-docs}/references/cli-reference.md +52 -97
  259. package/resources/bundled-skills/rudder-docs/references/control-plane-practices.md +231 -0
  260. package/{skills/rudder → resources/bundled-skills/rudder-docs}/references/organization-skills.md +15 -1
  261. package/resources/bundled-skills/rudder-docs/references/source-map.md +138 -0
  262. package/resources/bundled-skills/visualize/SKILL.md +132 -0
  263. package/resources/bundled-skills/visualize/agents/openai.yaml +7 -0
  264. package/resources/bundled-skills/visualize/assets/example-chart.html +89 -0
  265. package/resources/bundled-skills/visualize/references/runtime-contract.md +114 -0
  266. package/skills/rudder-docs/SKILL.md +161 -0
  267. package/skills/rudder-docs/evals/trigger-evals.json +82 -0
  268. package/{resources/bundled-skills/rudder → skills/rudder-docs}/references/api-reference.md +17 -1
  269. package/{resources/bundled-skills/rudder → skills/rudder-docs}/references/cli-reference.md +52 -97
  270. package/skills/rudder-docs/references/control-plane-practices.md +231 -0
  271. package/{resources/bundled-skills/rudder → skills/rudder-docs}/references/organization-skills.md +15 -1
  272. package/skills/rudder-docs/references/source-map.md +138 -0
  273. package/skills/visualize/SKILL.md +132 -0
  274. package/skills/visualize/agents/openai.yaml +7 -0
  275. package/skills/visualize/assets/example-chart.html +89 -0
  276. package/skills/visualize/references/runtime-contract.md +114 -0
  277. package/ui-dist/assets/{abnfDiagram-VRR7QNED-C4e_AuJm.js → abnfDiagram-VRR7QNED-Dpnx79fp.js} +1 -1
  278. package/ui-dist/assets/{arc-3OG5_qjR.js → arc-Cpvh_rCf.js} +1 -1
  279. package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-CJz3inSs.js → architectureDiagram-ZJ3FMSHR-sDD_mBAI.js} +1 -1
  280. package/ui-dist/assets/{blockDiagram-677ZJIJ3-CpBIok39.js → blockDiagram-677ZJIJ3-4O4wWti1.js} +1 -1
  281. package/ui-dist/assets/{c4Diagram-LMCZKHZV-BbQrD6Fx.js → c4Diagram-LMCZKHZV-BkGODE4P.js} +1 -1
  282. package/ui-dist/assets/channel-CM4Myg_6.js +1 -0
  283. package/ui-dist/assets/{chunk-2Q5K7J3B-BkoT6fZL.js → chunk-2Q5K7J3B-DsDQQpID.js} +1 -1
  284. package/ui-dist/assets/{chunk-32BRIVSS-DecBtqTH.js → chunk-32BRIVSS-Bzx_VnIw.js} +1 -1
  285. package/ui-dist/assets/{chunk-5VM5RSS4-SFFAgh5q.js → chunk-5VM5RSS4-D4LoPCni.js} +1 -1
  286. package/ui-dist/assets/{chunk-EX3LRPZG-CxUndf0S.js → chunk-EX3LRPZG-BO0R-mS4.js} +3 -3
  287. package/ui-dist/assets/{chunk-JWPE2WC7-BbEXuDLm.js → chunk-JWPE2WC7-B4Nr8KRL.js} +1 -1
  288. package/ui-dist/assets/{chunk-MOJQB5TN-MOCGQpRH.js → chunk-MOJQB5TN--uaDDrYM.js} +1 -1
  289. package/ui-dist/assets/{chunk-RYQCIY6F-CUuwDB4L.js → chunk-RYQCIY6F-CyBY2w_j.js} +1 -1
  290. package/ui-dist/assets/{chunk-V7JOEXUC-D5H80ZpL.js → chunk-V7JOEXUC-BMid_x8S.js} +3 -3
  291. package/ui-dist/assets/{chunk-VR4S4FIN-Cg5d82yb.js → chunk-VR4S4FIN-DVqdPKuG.js} +1 -1
  292. package/ui-dist/assets/{chunk-XXDRQBXY-Bu7DXS_3.js → chunk-XXDRQBXY-vy03lLSS.js} +1 -1
  293. package/ui-dist/assets/classDiagram-OUVF2IWQ-CtlIEzTt.js +1 -0
  294. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CtlIEzTt.js +1 -0
  295. package/ui-dist/assets/{cose-bilkent-JH36ORCC-LCobsJkA.js → cose-bilkent-JH36ORCC-jQDZmrG3.js} +1 -1
  296. package/ui-dist/assets/{cynefin-VYW2F7L2-CxDfvhGJ.js → cynefin-VYW2F7L2-BxBj6aea.js} +1 -1
  297. package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-BbebJ96a.js → cynefinDiagram-TSTJHNR4-BuUubF5I.js} +1 -1
  298. package/ui-dist/assets/{dagre-VKFMJZFB-BNQ0fvpl.js → dagre-VKFMJZFB-B8HipJ3a.js} +1 -1
  299. package/ui-dist/assets/{diagram-FQU43EPY-B9vCEyLD.js → diagram-FQU43EPY-r7gkbKSt.js} +2 -2
  300. package/ui-dist/assets/{diagram-G47NLZAW-Z7Hg_sXF.js → diagram-G47NLZAW-CxClRsxD.js} +1 -1
  301. package/ui-dist/assets/{diagram-NH7WQ7WH-B_TZ5-gD.js → diagram-NH7WQ7WH-C8HYTLlq.js} +1 -1
  302. package/ui-dist/assets/{diagram-OA4YK3LP-qe-twEnv.js → diagram-OA4YK3LP-CjwqqLKz.js} +1 -1
  303. package/ui-dist/assets/{diagram-WEI45ONY-D8ufoJVE.js → diagram-WEI45ONY-2IWfCqZb.js} +1 -1
  304. package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-BXXAFqU6.js → ebnfDiagram-CCIWWBDH-DVGZkgjy.js} +1 -1
  305. package/ui-dist/assets/{erDiagram-Q63AITRT-uXmIG2c_.js → erDiagram-Q63AITRT-C_-u3Gmw.js} +1 -1
  306. package/ui-dist/assets/{flowDiagram-23GEKE2U-3eiT6gWx.js → flowDiagram-23GEKE2U-BvGg0NCq.js} +4 -4
  307. package/ui-dist/assets/{ganttDiagram-NO4QXBWP-CiVmqV02.js → ganttDiagram-NO4QXBWP-U3CZUUUR.js} +1 -1
  308. package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-DmIrlFHc.js → gitGraphDiagram-IHSO6WYX-CIWuEBIo.js} +1 -1
  309. package/ui-dist/assets/{graph-BpS6eOIF.js → graph-D3P5q-7m.js} +1 -1
  310. package/ui-dist/assets/index-B1rLBtZ1.js +1875 -0
  311. package/ui-dist/assets/{index-Dlx6uy7_.js → index-BAMXpiI5.js} +1 -1
  312. package/ui-dist/assets/{index-CUHGsSRd.js → index-BAgtKYR1.js} +1 -1
  313. package/ui-dist/assets/{index--YRaLrzl.js → index-CBOr9F6w.js} +1 -1
  314. package/ui-dist/assets/{index-cHC60zXl.js → index-CbHqnWUe.js} +1 -1
  315. package/ui-dist/assets/{index-DeWKDYpk.js → index-CjztBLJi.js} +1 -1
  316. package/ui-dist/assets/{index-T2PpfhXU.js → index-Cu1iMhjl.js} +1 -1
  317. package/ui-dist/assets/{index-Dgj1-Gzi.js → index-D7ycf1qU.js} +1 -1
  318. package/ui-dist/assets/{index-Dpvu2aoc.js → index-DAYlwxsg.js} +1 -1
  319. package/ui-dist/assets/{index-BAU4CU-l.js → index-DCFf9dps.js} +4 -4
  320. package/ui-dist/assets/{index-CWaZ_rS8.js → index-DOPIV8vd.js} +1 -1
  321. package/ui-dist/assets/{index-C-TZf854.js → index-DRxLJD40.js} +1 -1
  322. package/ui-dist/assets/{index-CUI9Uyvz.js → index-DYMtCDKT.js} +1 -1
  323. package/ui-dist/assets/index-DekHKOsL.css +1 -0
  324. package/ui-dist/assets/{index-BncN7e-4.js → index-DidCCw78.js} +1 -1
  325. package/ui-dist/assets/{index-Cl27pPic.js → index-Ds_qma4-.js} +1 -1
  326. package/ui-dist/assets/{index-CF3Fjm4r.js → index-HkQRx1D6.js} +1 -1
  327. package/ui-dist/assets/{index-Cp12taja.js → index-ikpL--zj.js} +1 -1
  328. package/ui-dist/assets/{index-BzDB5XYN.js → index-mnl55Stn.js} +1 -1
  329. package/ui-dist/assets/{infoDiagram-FWYZ7A6U-B_e34a6A.js → infoDiagram-FWYZ7A6U-Cx8Fa-I4.js} +1 -1
  330. package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-C_h8nqRS.js → ishikawaDiagram-FXEZZL3T-Cmuz1QUN.js} +1 -1
  331. package/ui-dist/assets/{journeyDiagram-5HDEW3XC-CrxAvEMf.js → journeyDiagram-5HDEW3XC-CJgkiVXG.js} +1 -1
  332. package/ui-dist/assets/{kanban-definition-HUTT4EX6-Zp6LAKss.js → kanban-definition-HUTT4EX6-RAWpefOB.js} +1 -1
  333. package/ui-dist/assets/layout-DyWQv0Rr.js +1 -0
  334. package/ui-dist/assets/{linear-_N4Odhfh.js → linear-D5pdgIf9.js} +1 -1
  335. package/ui-dist/assets/{map-CYGuJtD3.js → map-bVSzNLl2.js} +1 -1
  336. package/ui-dist/assets/mermaid.core-CeaXGD6B.js +312 -0
  337. package/ui-dist/assets/{mindmap-definition-LN4V7U3C-C-J9N_o_.js → mindmap-definition-LN4V7U3C-B8B8AX5C.js} +1 -1
  338. package/ui-dist/assets/{pegDiagram-2B236MQR-B9Mlsk91.js → pegDiagram-2B236MQR-C4Sv-ua6.js} +1 -1
  339. package/ui-dist/assets/{pieDiagram-ENE6RG2P-BY7DU2f8.js → pieDiagram-ENE6RG2P-CLARlOHx.js} +1 -1
  340. package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-CdCl_yc0.js → quadrantDiagram-ABIIQ3AL-DPCXQmeT.js} +1 -1
  341. package/ui-dist/assets/{railroadDiagram-RFXS5EU6-C5w2LKAD.js → railroadDiagram-RFXS5EU6-BpqRuKUQ.js} +1 -1
  342. package/ui-dist/assets/{requirementDiagram-TGXJPOKE-fRb_n-yH.js → requirementDiagram-TGXJPOKE-Dd-h62HZ.js} +1 -1
  343. package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-CYjb1HUH.js → sankeyDiagram-HTMAVEWB-DylT_pqq.js} +1 -1
  344. package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-CS95ySsI.js → sequenceDiagram-DBY2YBRQ-RiCF1REj.js} +1 -1
  345. package/ui-dist/assets/{sizeCapture-X5ZJPWSS-DPXTC0TI.js → sizeCapture-X5ZJPWSS-DXW4JQz2.js} +1 -1
  346. package/ui-dist/assets/{stateDiagram-2N3HPSRC-C4VFIMBR.js → stateDiagram-2N3HPSRC-6U3ESIGT.js} +1 -1
  347. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-KQTrcZvp.js +1 -0
  348. package/ui-dist/assets/{swimlanes-5IMT3BWC-UvxkQ8RD.js → swimlanes-5IMT3BWC-CeNHVNCi.js} +2 -2
  349. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-CcxS1c6r.js +8 -0
  350. package/ui-dist/assets/{timeline-definition-FHXFAJF6-BKotSwXW.js → timeline-definition-FHXFAJF6-Vlwoe_1b.js} +1 -1
  351. package/ui-dist/assets/{vennDiagram-L72KCM5P-TmXc-aFs.js → vennDiagram-L72KCM5P-DBP7D3HE.js} +6 -6
  352. package/ui-dist/assets/{wardleyDiagram-EHGQE667-aTINQKt9.js → wardleyDiagram-EHGQE667-DG-wzqpy.js} +1 -1
  353. package/ui-dist/assets/{xychartDiagram-FW5EYKEG-CZ86hWNQ.js → xychartDiagram-FW5EYKEG-BAq3mbha.js} +1 -1
  354. package/ui-dist/index.html +2 -2
  355. package/resources/bundled-skills/rudder/SKILL.md +0 -314
  356. package/skills/rudder/SKILL.md +0 -314
  357. package/ui-dist/assets/channel-roHkdL27.js +0 -1
  358. package/ui-dist/assets/classDiagram-OUVF2IWQ-CKZLREY1.js +0 -1
  359. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CKZLREY1.js +0 -1
  360. package/ui-dist/assets/index-BTW19O7e.js +0 -1808
  361. package/ui-dist/assets/index-DOlmbVZk.css +0 -1
  362. package/ui-dist/assets/layout-DlHAdVX4.js +0 -1
  363. package/ui-dist/assets/mermaid.core-B8dXcSSK.js +0 -314
  364. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-CF5IY4p0.js +0 -1
  365. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-BVLEg2fG.js +0 -8
@@ -1,13 +1,12 @@
1
- import { agents, heartbeatRuns, issues, projects } from "@rudderhq/db";
1
+ import { heartbeatRuns, issues, projects } from "@rudderhq/db";
2
2
  import { resolveAgentRunScene, } from "@rudderhq/shared";
3
- import { and, eq } from "drizzle-orm";
3
+ import { and, eq, sql } from "drizzle-orm";
4
4
  import { createLocalAgentJwt } from "../../agent-auth-jwt.js";
5
5
  import { findServerAdapter, getServerAdapter } from "../../agent-runtimes/index.js";
6
6
  import { parseObject } from "../../agent-runtimes/utils.js";
7
7
  import { resolveDefaultAgentWorkspaceDir, } from "../../home-paths.js";
8
8
  import { redactCurrentUserText } from "../../log-redaction.js";
9
9
  import { logger } from "../../middleware/logger.js";
10
- import { publishAutomationRunOutputToChat } from "../automation-chat-output.js";
11
10
  import { buildExecutionWorkspaceAdapterConfig, issueExecutionWorkspaceModeForPersistedWorkspace, parseIssueExecutionWorkspaceSettings, parseProjectExecutionWorkspacePolicy, resolveExecutionWorkspaceMode, } from "../execution-workspace-policy.js";
12
11
  import { summarizeHeartbeatRunResultJson } from "../heartbeat-run-summary.js";
13
12
  import { publishLiveEvent } from "../live-events.js";
@@ -18,10 +17,25 @@ export { prioritizeProjectWorkspaceCandidatesForRun } from "../agent-run-context
18
17
  import * as heartbeatCore from "./heartbeat.core.js";
19
18
  import * as heartbeatSessions from "./heartbeat.sessions.js";
20
19
  const { MAX_LIVE_LOG_CHUNK_BYTES, HEARTBEAT_MAX_CONCURRENT_RUNS_DEFAULT, HEARTBEAT_MAX_CONCURRENT_RUNS_MIN, HEARTBEAT_MAX_CONCURRENT_RUNS_MAX, DEFERRED_WAKE_CONTEXT_KEY, DETACHED_PROCESS_ERROR_CODE, ORPHANED_PROCESS_TERMINATION_GRACE_MS, ORPHANED_PROCESS_KILL_WAIT_MS, ORPHANED_PROCESS_POLL_INTERVAL_MS, startLocksByAgent, MAX_RECOVERY_CHAIN_DEPTH, ISSUE_PASSIVE_FOLLOWUP_REASON, ISSUE_PASSIVE_FOLLOWUP_WAKE_SOURCE, ISSUE_PASSIVE_FOLLOWUP_FAILURE_REASON, ISSUE_PASSIVE_FOLLOWUP_MAX_ATTEMPTS, ISSUE_REVIEW_CLOSEOUT_REASON, ISSUE_REVIEW_CLOSEOUT_FAILURE_REASON, ISSUE_REVIEW_CLOSEOUT_MAX_ATTEMPTS, ISSUE_PASSIVE_FOLLOWUP_COOLDOWN_MS_BY_ATTEMPT, ISSUE_PASSIVE_FOLLOWUP_TIMER_CONTINUITY_MAX_WINDOW_MS, SESSIONED_LOCAL_ADAPTERS, heartbeatRunListColumns, appendExcerpt, appendTranscriptEntriesFromChunk, normalizeMaxConcurrentRuns, withAgentStartLock, readNonEmptyString, buildHeartbeatAdapterInvokePayload, sanitizeStartupContextContextForPersistence, sanitizeStartupContextPromptForPersistence, buildRecentDateKeys, buildDateKeysBetween, fallbackSkillLabel, normalizeLoadedSkill, normalizeLoadedSkillForPayload, emptySkillEvidenceCounts, incrementSkillEvidenceCount, strongestSkillEvidence, resolveSkillEvidence, readSkillEvidenceFromPayload, extractSkillSlugFromPath, collectSkillPathsFromText, collectStringValues, normalizeSkillUseFromPath, dedupeSkillUses, collectSkillUsesFromText, readToolCommandInput, isCommandTranscriptTool, isReadTranscriptTool, inferUsedSkillsFromTranscript, normalizeSkillCandidate, addSkillCandidate, readSkillReferenceSlug, collectSkillReferences, inferUsedSkillsFromPrompt, resolveForbiddenRuntimeSkillMarkers, detectForbiddenRuntimeSkillMarker, normalizeLedgerBillingType, resolveLedgerBiller, normalizeBilledCostCents, resolveLedgerScopeForRun } = heartbeatCore;
21
- const { buildExplicitResumeSessionOverride, normalizeUsageTotals, readRawUsageTotals, deriveNormalizedUsageDelta, formatCount, parseSessionCompactionPolicy, resolveRuntimeSessionParamsForWorkspace, parseIssueAssigneeAgentRuntimeOverrides, deriveTaskKey, shouldResetTaskSessionForWake, formatRuntimeWorkspaceWarningLog, describeSessionResetReason, deriveCommentId, enrichWakeContextSnapshot, mergeCoalescedContextSnapshot, issueCommentAuthorKind, issueCommentAuthorLabel, buildDeferredWakePayload, readDeferredWakeContext, readDeferredWakePayload, deriveDeferredWakeTaskKey, hydrateWakeContextSnapshot, firstNonEmptyLine, deriveRecoveryFailureKind, deriveRecoveryFailureSummary, mergeMissingRecoveryContextFields, hydrateRecoveryBaseContextSnapshot, buildRecoveryContextSnapshot, normalizePassiveFollowupContext, normalizeReviewCloseoutContext, passiveFollowupCooldownMs, issueHasReviewer, isAgentEligibleForTimerContinuation, hasCredibleTimerContinuation, buildPassiveFollowupContextSnapshot, runTaskKey, isSameTaskScope, isTrackedLocalChildProcessAdapter, isProcessAlive, waitForProcessExit, terminateOrphanedProcess, truncateDisplayId, normalizeAgentNameKey, defaultSessionCodec, getAgentRuntimeSessionCodec, normalizeSessionParams, resolveNextSessionState } = heartbeatSessions;
20
+ const { buildExplicitResumeSessionOverride, selectRunSessionLineage, normalizeUsageTotals, readRawUsageTotals, deriveNormalizedUsageDelta, formatCount, parseSessionCompactionPolicy, resolveRuntimeSessionParamsForWorkspace, parseIssueAssigneeAgentRuntimeOverrides, deriveTaskKey, shouldResetTaskSessionForWake, formatRuntimeWorkspaceWarningLog, describeSessionResetReason, deriveCommentId, enrichWakeContextSnapshot, mergeCoalescedContextSnapshot, issueCommentAuthorKind, issueCommentAuthorLabel, buildDeferredWakePayload, readDeferredWakeContext, readDeferredWakePayload, deriveDeferredWakeTaskKey, hydrateWakeContextSnapshot, firstNonEmptyLine, deriveRecoveryFailureKind, deriveRecoveryFailureSummary, mergeMissingRecoveryContextFields, hydrateRecoveryBaseContextSnapshot, buildRecoveryContextSnapshot, normalizePassiveFollowupContext, normalizeReviewCloseoutContext, passiveFollowupCooldownMs, issueHasReviewer, isAgentEligibleForTimerContinuation, hasCredibleTimerContinuation, buildPassiveFollowupContextSnapshot, runTaskKey, isSameTaskScope, isTrackedLocalChildProcessAdapter, isProcessAlive, waitForProcessExit, terminateOrphanedProcess, truncateDisplayId, normalizeAgentNameKey, defaultSessionCodec, getAgentRuntimeSessionCodec, normalizeSessionParams, resolveNextSessionState } = heartbeatSessions;
22
21
  function buildPersistableHeartbeatContext(context) {
23
22
  return sanitizeStartupContextContextForPersistence(context) ?? {};
24
23
  }
24
+ const EXECUTOR_OWNED_CONTEXT_KEYS = [
25
+ "executionWorkspaceId",
26
+ "rudderGitIdentity",
27
+ "rudderScene",
28
+ "rudderWorkspace",
29
+ "rudderWorkspaces",
30
+ "rudderStartupContext",
31
+ "rudderStartupContextMetrics",
32
+ "rudderRuntimeServiceIntents",
33
+ "rudderSessionHandoffMarkdown",
34
+ "rudderSessionRotationReason",
35
+ "rudderPreviousSessionId",
36
+ "rudderRuntimeServices",
37
+ "rudderRuntimePrimaryUrl",
38
+ ];
25
39
  function resolveRuntimeSceneForRun(run) {
26
40
  return resolveAgentRunScene({
27
41
  ...run,
@@ -32,37 +46,114 @@ function resolveRuntimeSceneForRun(run) {
32
46
  });
33
47
  }
34
48
  export function createHeartbeatExecuteHandlers(context) {
35
- const { db, instanceSettings, getCurrentUserRedactionOptions, runLogStore, runContextSvc, issuesSvc, executionWorkspacesSvc, workspaceOperationsSvc, activeRunExecutions, budgetHooks, budgets, getAgent, getRun, getRuntimeState, getTaskSession, getLatestRunForSession, getOldestRunForSession, resolveNormalizedUsageForSession, evaluateSessionCompaction, resolveSessionBeforeForWakeup, resolveExplicitResumeSessionOverride, upsertTaskSession, clearTaskSessions, ensureRuntimeState, setRunStatus, setWakeupStatus, updateWakeupRequestRecord, insertWakeupRequestRecord, appendRunEvent, nextRunEventSeq, persistRunProcessMetadata, clearDetachedRunWarning, enqueueRecoveryRun, enqueueProcessLossRetry, parseHeartbeatPolicy, markAgentHeartbeatChecked, evaluateTimerPreflight, runHasIssueClosureComment, runHasIssueReviewDecision, issueHasDeferredWake, passiveFollowupAlreadyRecorded, reviewerCloseoutAlreadyRecorded, issueHasRecordedBlockedReviewerDecision, evaluatePassiveIssueClosureForLockedIssue, countRunningRunsForAgent, claimQueuedRun, finalizeAgentStatus, reapOrphanedRuns, resumeQueuedRuns, updateRuntimeState, startNextQueuedRunForAgent, releaseIssueExecutionAndPromote, enqueueWakeup, resumeDeferredWakeupsForAgent, listProjectScopedRunIds, listProjectScopedWakeupIds, cancelPendingWakeupsForBudgetScope, cancelRunInternal, cancelActiveForAgentInternal, cancelBudgetScopeWork, retryRunInternal, buildSkillAnalytics } = context;
36
- async function executeRun(runId) {
37
- let run = await getRun(runId);
38
- if (!run)
49
+ const { db, instanceSettings, getCurrentUserRedactionOptions, runLogStore, runContextSvc, issuesSvc, executionWorkspacesSvc, workspaceOperationsSvc, activeRunExecutions, runAbortControllers, budgetHooks, budgets, getAgent, getRun, getRuntimeState, getTaskSession, getLatestRunForSession, getOldestRunForSession, resolveNormalizedUsageForSession, evaluateSessionCompaction, resolveSessionBeforeForWakeup, resolveExplicitResumeSessionOverride, upsertTaskSession, clearTaskSessions, ensureRuntimeState, setRunStatus, transitionRunToTerminal, reconcileRunEvidence, reconcileTerminalEffectsIntent, setWakeupStatus, updateWakeupRequestRecord, insertWakeupRequestRecord, appendRunEvent, persistRunProcessMetadata, clearDetachedRunWarning, acknowledgeRunProcessExit, renewRunExecutionLease, enqueueRecoveryRun, enqueueProcessLossRetry, parseHeartbeatPolicy, markAgentHeartbeatChecked, evaluateTimerPreflight, runHasIssueClosureComment, runHasIssueReviewDecision, issueHasDeferredWake, passiveFollowupAlreadyRecorded, reviewerCloseoutAlreadyRecorded, issueHasRecordedBlockedReviewerDecision, evaluatePassiveIssueClosureForLockedIssue, countRunningRunsForAgent, claimQueuedRun, finalizeAgentStatus, completeTerminalControlEffects, reapOrphanedRuns, resumeQueuedRuns, updateRuntimeState, startNextQueuedRunForAgent, releaseIssueExecutionAndPromote, enqueueWakeup, resumeDeferredWakeupsForAgent, listProjectScopedRunIds, listProjectScopedWakeupIds, cancelPendingWakeupsForBudgetScope, cancelRunInternal, cancelActiveForAgentInternal, cancelBudgetScopeWork, retryRunInternal, buildSkillAnalytics } = context;
50
+ async function persistRunningExecutionContext(runId, desiredContext, patch = {}) {
51
+ return db.transaction(async (tx) => {
52
+ await tx.execute(sql `select id from heartbeat_runs where id = ${runId} for update`);
53
+ const currentRun = await tx
54
+ .select()
55
+ .from(heartbeatRuns)
56
+ .where(eq(heartbeatRuns.id, runId))
57
+ .then((rows) => rows[0] ?? null);
58
+ if (!currentRun || currentRun.status !== "running")
59
+ return null;
60
+ const persistableContext = buildPersistableHeartbeatContext(desiredContext);
61
+ const mergedContext = mergeCoalescedContextSnapshot(persistableContext, parseObject(currentRun.contextSnapshot));
62
+ for (const key of EXECUTOR_OWNED_CONTEXT_KEYS) {
63
+ if (Object.prototype.hasOwnProperty.call(persistableContext, key)) {
64
+ mergedContext[key] = persistableContext[key];
65
+ }
66
+ else {
67
+ delete mergedContext[key];
68
+ }
69
+ }
70
+ return tx
71
+ .update(heartbeatRuns)
72
+ .set({
73
+ ...patch,
74
+ contextSnapshot: mergedContext,
75
+ updatedAt: new Date(),
76
+ })
77
+ .where(and(eq(heartbeatRuns.id, runId), eq(heartbeatRuns.status, "running")))
78
+ .returning()
79
+ .then((rows) => rows[0] ?? null);
80
+ });
81
+ }
82
+ async function executeRun(runId, opts) {
83
+ const executionReserved = opts?.executionReserved === true;
84
+ if (executionReserved && !activeRunExecutions.has(runId))
39
85
  return;
40
- if (run.status !== "queued" && run.status !== "running")
86
+ let run;
87
+ let executionLeaseTimer = null;
88
+ let executionOwnerToken = null;
89
+ try {
90
+ run = await getRun(runId);
91
+ }
92
+ catch (error) {
93
+ if (executionReserved) {
94
+ runAbortControllers.delete(runId);
95
+ activeRunExecutions.delete(runId);
96
+ }
97
+ throw error;
98
+ }
99
+ if (!run || (run.status !== "queued" && run.status !== "running")) {
100
+ if (executionReserved) {
101
+ runAbortControllers.delete(runId);
102
+ activeRunExecutions.delete(runId);
103
+ if (run?.terminalEffectsPending) {
104
+ await acknowledgeRunProcessExit(run.id);
105
+ await completeTerminalControlEffects(run);
106
+ }
107
+ if (run)
108
+ await startNextQueuedRunForAgent(run.agentId);
109
+ }
41
110
  return;
42
- if (run.status === "queued") {
43
- const claimed = await claimQueuedRun(run);
44
- if (!claimed) {
45
- // Another worker has already claimed or finalized this run.
111
+ }
112
+ if (executionReserved) {
113
+ if (!activeRunExecutions.has(run.id))
46
114
  return;
47
- }
48
- run = claimed;
49
115
  }
50
- activeRunExecutions.add(run.id);
116
+ else {
117
+ if (activeRunExecutions.has(run.id))
118
+ return;
119
+ activeRunExecutions.add(run.id);
120
+ }
121
+ const executionAbortController = runAbortControllers.get(run.id) ?? new AbortController();
122
+ runAbortControllers.set(run.id, executionAbortController);
51
123
  try {
124
+ if (run.status === "queued") {
125
+ const claimed = await claimQueuedRun(run);
126
+ if (!claimed) {
127
+ // Another worker has already claimed or finalized this run.
128
+ return;
129
+ }
130
+ run = claimed;
131
+ }
132
+ executionOwnerToken = run.executionOwnerToken;
133
+ if (executionOwnerToken) {
134
+ await renewRunExecutionLease(run.id, executionOwnerToken);
135
+ executionLeaseTimer = setInterval(() => {
136
+ void renewRunExecutionLease(run.id, executionOwnerToken).catch(() => undefined);
137
+ }, 60_000);
138
+ executionLeaseTimer.unref?.();
139
+ }
52
140
  const agent = await getAgent(run.agentId);
53
141
  if (!agent) {
54
- await setRunStatus(runId, "failed", {
142
+ const failed = await transitionRunToTerminal(runId, "failed", {
55
143
  error: "Agent not found",
56
144
  errorCode: "agent_not_found",
57
145
  finishedAt: new Date(),
146
+ }, {
147
+ processExitedAt: new Date(),
148
+ expectedExecutionOwnerToken: executionOwnerToken,
58
149
  });
59
- await setWakeupStatus(run.wakeupRequestId, "failed", {
60
- finishedAt: new Date(),
61
- error: "Agent not found",
62
- });
63
- const failedRun = await getRun(runId);
64
- if (failedRun)
65
- await releaseIssueExecutionAndPromote(failedRun);
150
+ if (failed) {
151
+ await setWakeupStatus(run.wakeupRequestId, "failed", {
152
+ finishedAt: new Date(),
153
+ error: "Agent not found",
154
+ });
155
+ await completeTerminalControlEffects(failed);
156
+ }
66
157
  return;
67
158
  }
68
159
  const executionTranscript = [];
@@ -73,8 +164,26 @@ export function createHeartbeatExecuteHandlers(context) {
73
164
  let latestAdapterMeta = null;
74
165
  let adapterForbiddenMarkerObserved = false;
75
166
  let finalRunOutput = null;
76
- let finalRunStatus = run.status;
77
- const runtime = await ensureRuntimeState(agent);
167
+ let ownsTerminalState = false;
168
+ let shouldCompleteTerminalEffects = false;
169
+ const finalizeExecutionTranscript = () => {
170
+ stdoutTranscriptBuffer = appendTranscriptEntriesFromChunk({
171
+ buffer: stdoutTranscriptBuffer,
172
+ chunk: "",
173
+ transcript: executionTranscript,
174
+ parser: stdoutTranscriptParser,
175
+ finalize: true,
176
+ kind: "stdout",
177
+ });
178
+ stderrTranscriptBuffer = appendTranscriptEntriesFromChunk({
179
+ buffer: stderrTranscriptBuffer,
180
+ chunk: "",
181
+ transcript: executionTranscript,
182
+ finalize: true,
183
+ kind: "stderr",
184
+ });
185
+ };
186
+ await ensureRuntimeState(agent);
78
187
  const context = parseObject(run.contextSnapshot);
79
188
  delete context.rudderGitIdentity;
80
189
  const taskKey = deriveTaskKey(context, null);
@@ -115,16 +224,37 @@ export function createHeartbeatExecuteHandlers(context) {
115
224
  const taskSession = taskKey
116
225
  ? await getTaskSession(agent.orgId, agent.id, agent.agentRuntimeType, taskKey)
117
226
  : null;
118
- const resetTaskSession = shouldResetTaskSessionForWake(context);
227
+ const resetTaskSession = run.sessionReuseScope === "unknown"
228
+ ? shouldResetTaskSessionForWake(context)
229
+ : run.sessionReuseScope === "none" && shouldResetTaskSessionForWake(context);
119
230
  const sessionResetReason = describeSessionResetReason(context);
120
231
  const taskSessionForRun = resetTaskSession ? null : taskSession;
121
232
  const explicitResumeSessionParams = normalizeSessionParams(sessionCodec.deserialize(parseObject(context.resumeSessionParams)));
122
233
  const explicitResumeSessionDisplayId = truncateDisplayId(readNonEmptyString(context.resumeSessionDisplayId) ??
123
234
  (sessionCodec.getDisplayId ? sessionCodec.getDisplayId(explicitResumeSessionParams) : null) ??
124
235
  readNonEmptyString(explicitResumeSessionParams?.sessionId));
125
- const previousSessionParams = explicitResumeSessionParams ??
126
- (explicitResumeSessionDisplayId ? { sessionId: explicitResumeSessionDisplayId } : null) ??
127
- normalizeSessionParams(sessionCodec.deserialize(taskSessionForRun?.sessionParamsJson ?? null));
236
+ const taskSessionParams = normalizeSessionParams(sessionCodec.deserialize(taskSessionForRun?.sessionParamsJson ?? null));
237
+ const taskSessionDisplayId = truncateDisplayId(taskSessionForRun?.sessionDisplayId ??
238
+ (sessionCodec.getDisplayId ? sessionCodec.getDisplayId(taskSessionParams) : null) ??
239
+ readNonEmptyString(taskSessionParams?.sessionId));
240
+ const frozenSessionParams = normalizeSessionParams(sessionCodec.deserialize(run.sessionParamsBeforeJson ?? null));
241
+ const frozenSessionDisplayId = truncateDisplayId(run.sessionIdBefore ??
242
+ (sessionCodec.getDisplayId ? sessionCodec.getDisplayId(frozenSessionParams) : null) ??
243
+ readNonEmptyString(frozenSessionParams?.sessionId));
244
+ const sessionSelection = run.sessionReuseScope === "unknown"
245
+ ? selectRunSessionLineage({
246
+ forceFresh: Boolean(heartbeatSessions.readSessionReuseSuppression(context)),
247
+ explicitSessionParams: explicitResumeSessionParams,
248
+ explicitSessionDisplayId: explicitResumeSessionDisplayId,
249
+ taskSessionParams,
250
+ taskSessionDisplayId,
251
+ })
252
+ : {
253
+ reuseScope: run.sessionReuseScope,
254
+ sessionParams: run.sessionReuseScope === "none" ? null : frozenSessionParams,
255
+ sessionDisplayId: run.sessionReuseScope === "none" ? null : frozenSessionDisplayId,
256
+ };
257
+ const previousSessionParams = sessionSelection.sessionParams;
128
258
  const config = await runContextSvc.materializeManagedInstructionsForRun({
129
259
  ...agent,
130
260
  agentRuntimeConfig: parseObject(agent.agentRuntimeConfig),
@@ -313,13 +443,9 @@ export function createHeartbeatExecuteHandlers(context) {
313
443
  }
314
444
  if (persistedExecutionWorkspace) {
315
445
  context.executionWorkspaceId = persistedExecutionWorkspace.id;
316
- await db
317
- .update(heartbeatRuns)
318
- .set({
319
- contextSnapshot: buildPersistableHeartbeatContext(context),
320
- updatedAt: new Date(),
321
- })
322
- .where(eq(heartbeatRuns.id, run.id));
446
+ const workspaceContextRun = await persistRunningExecutionContext(run.id, context);
447
+ if (workspaceContextRun)
448
+ run = workspaceContextRun;
323
449
  }
324
450
  const runtimeSessionResolution = resolveRuntimeSessionParamsForWorkspace({
325
451
  orgId: agent.orgId,
@@ -378,13 +504,10 @@ export function createHeartbeatExecuteHandlers(context) {
378
504
  if (executionWorkspace.projectId && !readNonEmptyString(context.projectId)) {
379
505
  context.projectId = executionWorkspace.projectId;
380
506
  }
381
- const runtimeSessionFallback = taskKey || resetTaskSession ? null : runtime.sessionId;
382
- let previousSessionDisplayId = truncateDisplayId(explicitResumeSessionDisplayId ??
383
- taskSessionForRun?.sessionDisplayId ??
507
+ let previousSessionDisplayId = truncateDisplayId(sessionSelection.sessionDisplayId ??
384
508
  (sessionCodec.getDisplayId ? sessionCodec.getDisplayId(runtimeSessionParams) : null) ??
385
- readNonEmptyString(runtimeSessionParams?.sessionId) ??
386
- runtimeSessionFallback);
387
- let runtimeSessionIdForAdapter = readNonEmptyString(runtimeSessionParams?.sessionId) ?? runtimeSessionFallback;
509
+ readNonEmptyString(runtimeSessionParams?.sessionId));
510
+ let runtimeSessionIdForAdapter = readNonEmptyString(runtimeSessionParams?.sessionId);
388
511
  let runtimeSessionParamsForAdapter = runtimeSessionParams;
389
512
  const sessionCompaction = await evaluateSessionCompaction({
390
513
  agent,
@@ -407,13 +530,13 @@ export function createHeartbeatExecuteHandlers(context) {
407
530
  delete context.rudderSessionRotationReason;
408
531
  delete context.rudderPreviousSessionId;
409
532
  }
533
+ const sessionReuseScope = sessionCompaction.rotate ? "none" : sessionSelection.reuseScope;
410
534
  const runtimeForAdapter = {
411
535
  sessionId: runtimeSessionIdForAdapter,
412
536
  sessionParams: runtimeSessionParamsForAdapter,
413
537
  sessionDisplayId: previousSessionDisplayId,
414
538
  taskKey,
415
539
  };
416
- let seq = 1;
417
540
  let handle = null;
418
541
  let stdoutExcerpt = "";
419
542
  let stderrExcerpt = "";
@@ -429,7 +552,7 @@ export function createHeartbeatExecuteHandlers(context) {
429
552
  const appendForbiddenMarkerEvent = async (eventRun, scan) => {
430
553
  if (!scan.observed)
431
554
  return;
432
- await appendRunEvent(eventRun, seq++, {
555
+ await appendRunEvent(eventRun, {
433
556
  eventType: "adapter.forbidden_marker",
434
557
  stream: "system",
435
558
  level: "error",
@@ -451,38 +574,16 @@ export function createHeartbeatExecuteHandlers(context) {
451
574
  skillsDir: readNonEmptyString(runtimeSceneContext.rudderWorkspace.agentSkillsDir) ?? "",
452
575
  });
453
576
  const startedAt = run.startedAt ?? new Date();
454
- const runningWithSession = await db
455
- .update(heartbeatRuns)
456
- .set({
577
+ const runningWithSession = await persistRunningExecutionContext(run.id, context, {
457
578
  startedAt,
458
579
  sessionIdBefore: runtimeForAdapter.sessionDisplayId ?? runtimeForAdapter.sessionId,
459
- contextSnapshot: buildPersistableHeartbeatContext(context),
460
- updatedAt: new Date(),
461
- })
462
- .where(eq(heartbeatRuns.id, run.id))
463
- .returning()
464
- .then((rows) => rows[0] ?? null);
580
+ sessionParamsBeforeJson: runtimeForAdapter.sessionParams,
581
+ sessionReuseScope,
582
+ });
465
583
  if (runningWithSession)
466
584
  run = runningWithSession;
467
- const runningAgent = await db
468
- .update(agents)
469
- .set({ status: "running", updatedAt: new Date() })
470
- .where(eq(agents.id, agent.id))
471
- .returning()
472
- .then((rows) => rows[0] ?? null);
473
- if (runningAgent) {
474
- publishLiveEvent({
475
- orgId: runningAgent.orgId,
476
- type: "agent.status",
477
- payload: {
478
- agentId: runningAgent.id,
479
- status: runningAgent.status,
480
- outcome: "running",
481
- },
482
- });
483
- }
484
585
  const currentRun = run;
485
- await appendRunEvent(currentRun, seq++, {
586
+ await appendRunEvent(currentRun, {
486
587
  eventType: "lifecycle",
487
588
  stream: "system",
488
589
  level: "info",
@@ -524,7 +625,7 @@ export function createHeartbeatExecuteHandlers(context) {
524
625
  await db
525
626
  .update(heartbeatRuns)
526
627
  .set({ updatedAt: new Date(nowMs) })
527
- .where(eq(heartbeatRuns.id, run.id));
628
+ .where(and(eq(heartbeatRuns.id, run.id), eq(heartbeatRuns.status, "running")));
528
629
  }
529
630
  const payloadChunk = sanitizedChunk.length > MAX_LIVE_LOG_CHUNK_BYTES
530
631
  ? sanitizedChunk.slice(sanitizedChunk.length - MAX_LIVE_LOG_CHUNK_BYTES)
@@ -582,13 +683,7 @@ export function createHeartbeatExecuteHandlers(context) {
582
683
  context.rudderRuntimeServices = runtimeServices;
583
684
  context.rudderRuntimePrimaryUrl =
584
685
  runtimeServices.find((service) => readNonEmptyString(service.url))?.url ?? null;
585
- await db
586
- .update(heartbeatRuns)
587
- .set({
588
- contextSnapshot: buildPersistableHeartbeatContext(context),
589
- updatedAt: new Date(),
590
- })
591
- .where(eq(heartbeatRuns.id, run.id));
686
+ await persistRunningExecutionContext(run.id, context);
592
687
  }
593
688
  if (issueId && (executionWorkspace.created || runtimeServices.some((service) => !service.reused))) {
594
689
  try {
@@ -610,7 +705,7 @@ export function createHeartbeatExecuteHandlers(context) {
610
705
  meta.env[key] = "***REDACTED***";
611
706
  }
612
707
  }
613
- await appendRunEvent(currentRun, seq++, {
708
+ await appendRunEvent(currentRun, {
614
709
  eventType: "adapter.invoke",
615
710
  stream: "system",
616
711
  level: "info",
@@ -632,6 +727,10 @@ export function createHeartbeatExecuteHandlers(context) {
632
727
  agentRuntimeType: agent.agentRuntimeType,
633
728
  }, "local agent jwt secret missing or invalid; running without injected RUDDER_API_KEY");
634
729
  }
730
+ const runBeforeAdapter = await getRun(run.id);
731
+ if (runBeforeAdapter?.status !== "running") {
732
+ throw new Error("Run was finalized before adapter invocation");
733
+ }
635
734
  const adapterResult = await executeAdapterWithModelFallbacks(adapter, {
636
735
  runId: run.id,
637
736
  agent,
@@ -643,6 +742,7 @@ export function createHeartbeatExecuteHandlers(context) {
643
742
  onSpawn: async (meta) => {
644
743
  await persistRunProcessMetadata(run.id, meta);
645
744
  },
745
+ abortSignal: executionAbortController.signal,
646
746
  authToken: authToken ?? undefined,
647
747
  }, {
648
748
  resolveAdapter: findServerAdapter,
@@ -674,13 +774,7 @@ export function createHeartbeatExecuteHandlers(context) {
674
774
  context.rudderRuntimeServices = combinedRuntimeServices;
675
775
  context.rudderRuntimePrimaryUrl =
676
776
  combinedRuntimeServices.find((service) => readNonEmptyString(service.url))?.url ?? null;
677
- await db
678
- .update(heartbeatRuns)
679
- .set({
680
- contextSnapshot: buildPersistableHeartbeatContext(context),
681
- updatedAt: new Date(),
682
- })
683
- .where(eq(heartbeatRuns.id, run.id));
777
+ await persistRunningExecutionContext(run.id, context);
684
778
  if (issueId) {
685
779
  try {
686
780
  await issuesSvc.addComment(issueId, buildWorkspaceReadyComment({
@@ -742,8 +836,11 @@ export function createHeartbeatExecuteHandlers(context) {
742
836
  : outcome === "timed_out"
743
837
  ? "timed_out"
744
838
  : "failed";
745
- finalRunStatus = status;
746
839
  const adapterResultSummary = summarizeHeartbeatRunResultJson(adapterResult.resultJson);
840
+ const persistedResultSummary = summarizeHeartbeatRunResultJson({
841
+ ...(adapterResult.resultJson ?? {}),
842
+ ...(readNonEmptyString(adapterResult.summary) ? { summary: adapterResult.summary } : {}),
843
+ });
747
844
  transcriptFallbackResult = {
748
845
  ts: new Date().toISOString(),
749
846
  model: readNonEmptyString(adapterResult.model),
@@ -770,9 +867,10 @@ export function createHeartbeatExecuteHandlers(context) {
770
867
  ...((nextSessionState.displayId ?? nextSessionState.legacySessionId)
771
868
  ? { persistedSessionId: nextSessionState.displayId ?? nextSessionState.legacySessionId }
772
869
  : {}),
773
- sessionReused: runtimeForAdapter.sessionId != null || runtimeForAdapter.sessionDisplayId != null,
774
- taskSessionReused: taskSessionForRun != null,
775
- freshSession: runtimeForAdapter.sessionId == null && runtimeForAdapter.sessionDisplayId == null,
870
+ sessionReused: sessionReuseScope !== "none",
871
+ taskSessionReused: sessionReuseScope === "task",
872
+ freshSession: sessionReuseScope === "none",
873
+ sessionReuseScope,
776
874
  sessionRotated: sessionCompaction.rotate,
777
875
  sessionRotationReason: sessionCompaction.reason,
778
876
  provider: readNonEmptyString(adapterResult.provider) ?? "unknown",
@@ -782,7 +880,8 @@ export function createHeartbeatExecuteHandlers(context) {
782
880
  billingType: normalizeLedgerBillingType(adapterResult.billingType),
783
881
  }
784
882
  : null;
785
- await setRunStatus(run.id, status, {
883
+ finalizeExecutionTranscript();
884
+ const terminalEvidence = {
786
885
  finishedAt: new Date(),
787
886
  error: outcome === "succeeded"
788
887
  ? null
@@ -802,25 +901,87 @@ export function createHeartbeatExecuteHandlers(context) {
802
901
  signal: adapterResult.signal,
803
902
  usageJson,
804
903
  resultJson: adapterResult.resultJson ?? null,
904
+ resultSummaryJson: persistedResultSummary,
805
905
  sessionIdAfter: nextSessionState.displayId ?? nextSessionState.legacySessionId,
906
+ sessionParamsAfterJson: adapterResult.clearSession ? {} : nextSessionState.params,
806
907
  stdoutExcerpt,
807
908
  stderrExcerpt,
808
909
  logBytes: logSummary?.bytes,
809
910
  logSha256: logSummary?.sha256,
810
911
  logCompressed: logSummary?.compressed ?? false,
912
+ };
913
+ const terminalEffectsIntent = {
914
+ version: 1,
915
+ automation: {
916
+ output: transcriptFallbackResult?.output ?? terminalEvidence.error,
917
+ transcript: executionTranscript,
918
+ },
919
+ runtime: {
920
+ adapterResult: adapterResult,
921
+ legacySessionId: nextSessionState.legacySessionId,
922
+ normalizedUsage: normalizedUsage,
923
+ ownsTerminal: true,
924
+ },
925
+ ...(taskKey
926
+ ? {
927
+ taskSession: adapterResult.clearSession || (!nextSessionState.params && !nextSessionState.displayId)
928
+ ? {
929
+ operation: "clear",
930
+ orgId: agent.orgId,
931
+ agentId: agent.id,
932
+ agentRuntimeType: agent.agentRuntimeType,
933
+ taskKey,
934
+ lastRunId: run.id,
935
+ }
936
+ : {
937
+ operation: "upsert",
938
+ orgId: agent.orgId,
939
+ agentId: agent.id,
940
+ agentRuntimeType: agent.agentRuntimeType,
941
+ taskKey,
942
+ sessionParamsJson: nextSessionState.params,
943
+ sessionDisplayId: nextSessionState.displayId,
944
+ lastRunId: run.id,
945
+ lastError: outcome === "succeeded" ? null : (adapterResult.errorMessage ?? "run_failed"),
946
+ },
947
+ }
948
+ : {}),
949
+ };
950
+ const claimedTerminalRun = await transitionRunToTerminal(run.id, status, terminalEvidence, {
951
+ terminalEffectsIntent,
952
+ processExitedAt: new Date(),
953
+ expectedExecutionOwnerToken: executionOwnerToken,
811
954
  });
812
- await setWakeupStatus(run.wakeupRequestId, outcome === "succeeded" ? "completed" : status, {
813
- finishedAt: new Date(),
814
- error: failureCausedByForbiddenMarker
815
- ? "Forbidden runtime skill marker observed"
816
- : adapterResult.errorMessage ?? null,
817
- });
818
- const finalizedRun = await getRun(run.id);
955
+ ownsTerminalState = Boolean(claimedTerminalRun);
956
+ if (!claimedTerminalRun) {
957
+ await reconcileRunEvidence(run.id, terminalEvidence);
958
+ await reconcileTerminalEffectsIntent(run.id, {
959
+ version: 1,
960
+ automation: terminalEffectsIntent.automation,
961
+ runtime: {
962
+ adapterResult: adapterResult,
963
+ legacySessionId: null,
964
+ normalizedUsage: normalizedUsage,
965
+ ownsTerminal: false,
966
+ },
967
+ });
968
+ }
969
+ const finalizedRun = claimedTerminalRun ?? await getRun(run.id);
819
970
  if (finalizedRun) {
971
+ transcriptFallbackResult.subtype = finalizedRun.status;
972
+ transcriptFallbackResult.isError = finalizedRun.status !== "succeeded";
973
+ if (ownsTerminalState) {
974
+ await setWakeupStatus(run.wakeupRequestId, outcome === "succeeded" ? "completed" : status, {
975
+ finishedAt: new Date(),
976
+ error: failureCausedByForbiddenMarker
977
+ ? "Forbidden runtime skill marker observed"
978
+ : adapterResult.errorMessage ?? null,
979
+ });
980
+ }
820
981
  await appendForbiddenMarkerEvent(finalizedRun, forbiddenMarkerScan);
821
982
  const transcriptUsedSkills = inferUsedSkillsFromTranscript(executionTranscript);
822
983
  if (transcriptUsedSkills.length > 0) {
823
- await appendRunEvent(finalizedRun, seq++, {
984
+ await appendRunEvent(finalizedRun, {
824
985
  eventType: "adapter.skill_usage",
825
986
  stream: "system",
826
987
  level: "info",
@@ -837,50 +998,29 @@ export function createHeartbeatExecuteHandlers(context) {
837
998
  },
838
999
  });
839
1000
  }
840
- await appendRunEvent(finalizedRun, seq++, {
841
- eventType: "lifecycle",
842
- stream: "system",
843
- level: outcome === "succeeded" ? "info" : "error",
844
- message: `run ${outcome}`,
845
- payload: {
846
- status,
847
- exitCode: adapterResult.exitCode,
848
- },
849
- });
850
- await releaseIssueExecutionAndPromote(finalizedRun);
1001
+ if (ownsTerminalState) {
1002
+ await appendRunEvent(finalizedRun, {
1003
+ eventType: "lifecycle",
1004
+ stream: "system",
1005
+ level: outcome === "succeeded" ? "info" : "error",
1006
+ message: `run ${outcome}`,
1007
+ payload: {
1008
+ status,
1009
+ exitCode: adapterResult.exitCode,
1010
+ },
1011
+ });
1012
+ }
851
1013
  }
852
1014
  if (finalizedRun) {
853
- await updateRuntimeState(agent, finalizedRun, adapterResult, {
854
- legacySessionId: nextSessionState.legacySessionId,
855
- }, normalizedUsage);
856
- if (taskKey) {
857
- if (adapterResult.clearSession || (!nextSessionState.params && !nextSessionState.displayId)) {
858
- await clearTaskSessions(agent.orgId, agent.id, {
859
- taskKey,
860
- agentRuntimeType: agent.agentRuntimeType,
861
- });
862
- }
863
- else {
864
- await upsertTaskSession({
865
- orgId: agent.orgId,
866
- agentId: agent.id,
867
- agentRuntimeType: agent.agentRuntimeType,
868
- taskKey,
869
- sessionParamsJson: nextSessionState.params,
870
- sessionDisplayId: nextSessionState.displayId,
871
- lastRunId: finalizedRun.id,
872
- lastError: outcome === "succeeded" ? null : (adapterResult.errorMessage ?? "run_failed"),
873
- });
874
- }
1015
+ if (ownsTerminalState || finalizedRun.terminalEffectsPending) {
1016
+ shouldCompleteTerminalEffects = true;
875
1017
  }
876
1018
  }
877
- await finalizeAgentStatus(agent.id, outcome);
878
1019
  }
879
1020
  catch (err) {
880
1021
  const isWorkspacePreflightFailure = isWorkspacePermissionPreflightError(err) ||
881
1022
  isManagedWorkspaceConfigurationError(err);
882
1023
  const message = redactCurrentUserText(err instanceof Error ? err.message : "Unknown adapter failure", await getCurrentUserRedactionOptions());
883
- finalRunStatus = "failed";
884
1024
  transcriptFallbackResult = {
885
1025
  ts: new Date().toISOString(),
886
1026
  output: message,
@@ -890,17 +1030,32 @@ export function createHeartbeatExecuteHandlers(context) {
890
1030
  };
891
1031
  logger.error({ err, runId }, "heartbeat execution failed");
892
1032
  const latestRun = await getRun(run.id);
893
- if (latestRun?.status === "cancelled" || latestRun?.status === "timed_out") {
1033
+ if (latestRun?.status === "succeeded"
1034
+ || latestRun?.status === "failed"
1035
+ || latestRun?.status === "cancelled"
1036
+ || latestRun?.status === "timed_out") {
894
1037
  const terminalStatus = latestRun.status;
895
- finalRunStatus = terminalStatus;
896
1038
  transcriptFallbackResult = {
897
1039
  ts: new Date().toISOString(),
898
1040
  output: latestRun.error ?? message,
899
1041
  subtype: terminalStatus,
900
- isError: terminalStatus === "timed_out",
1042
+ isError: terminalStatus !== "succeeded",
901
1043
  errors: latestRun.error ? [latestRun.error] : [],
902
1044
  };
903
- await finalizeAgentStatus(agent.id, terminalStatus);
1045
+ let lateLogSummary = null;
1046
+ if (handle) {
1047
+ lateLogSummary = await runLogStore.finalize(handle).catch(() => null);
1048
+ }
1049
+ await reconcileRunEvidence(run.id, {
1050
+ stdoutExcerpt,
1051
+ stderrExcerpt,
1052
+ logBytes: lateLogSummary?.bytes,
1053
+ logSha256: lateLogSummary?.sha256,
1054
+ logCompressed: lateLogSummary?.compressed,
1055
+ });
1056
+ if (latestRun.terminalEffectsPending) {
1057
+ shouldCompleteTerminalEffects = true;
1058
+ }
904
1059
  return;
905
1060
  }
906
1061
  let logSummary = null;
@@ -912,7 +1067,7 @@ export function createHeartbeatExecuteHandlers(context) {
912
1067
  logger.warn({ err: finalizeErr, runId }, "failed to finalize run log after error");
913
1068
  }
914
1069
  }
915
- const failedRun = await setRunStatus(run.id, "failed", {
1070
+ const failureEvidence = {
916
1071
  error: message,
917
1072
  errorCode: isWorkspacePreflightFailure ? err.errorCode : "adapter_failed",
918
1073
  finishedAt: new Date(),
@@ -921,82 +1076,93 @@ export function createHeartbeatExecuteHandlers(context) {
921
1076
  logBytes: logSummary?.bytes,
922
1077
  logSha256: logSummary?.sha256,
923
1078
  logCompressed: logSummary?.compressed ?? false,
924
- });
925
- await setWakeupStatus(run.wakeupRequestId, "failed", {
926
- finishedAt: new Date(),
927
- error: message,
928
- });
929
- if (failedRun) {
930
- await appendForbiddenMarkerEvent(failedRun, buildForbiddenMarkerScan(null));
931
- await appendRunEvent(failedRun, seq++, {
932
- eventType: isWorkspacePreflightFailure ? "runtime.workspace_preflight_failed" : "error",
933
- stream: "system",
934
- level: "error",
935
- message,
936
- ...(isWorkspacePreflightFailure
937
- ? {
938
- payload: {
939
- errorCode: err.errorCode,
940
- failure: err.failure,
1079
+ };
1080
+ finalizeExecutionTranscript();
1081
+ const failureIntent = {
1082
+ version: 1,
1083
+ automation: { output: message, transcript: executionTranscript },
1084
+ ...(!isWorkspacePreflightFailure
1085
+ ? {
1086
+ runtime: {
1087
+ adapterResult: {
1088
+ exitCode: null,
1089
+ signal: null,
1090
+ timedOut: false,
1091
+ errorMessage: message,
941
1092
  },
942
- }
943
- : {}),
944
- });
945
- await releaseIssueExecutionAndPromote(failedRun);
946
- if (!isWorkspacePreflightFailure) {
947
- await updateRuntimeState(agent, failedRun, {
948
- exitCode: null,
949
- signal: null,
950
- timedOut: false,
951
- errorMessage: message,
952
- }, {
953
- legacySessionId: runtimeForAdapter.sessionId,
954
- });
955
- if (taskKey && (previousSessionParams || previousSessionDisplayId || taskSession)) {
956
- await upsertTaskSession({
1093
+ legacySessionId: runtimeForAdapter.sessionId,
1094
+ },
1095
+ }
1096
+ : {}),
1097
+ ...(taskKey && !isWorkspacePreflightFailure && (previousSessionParams || previousSessionDisplayId || taskSession)
1098
+ ? {
1099
+ taskSession: {
1100
+ operation: "upsert",
957
1101
  orgId: agent.orgId,
958
1102
  agentId: agent.id,
959
1103
  agentRuntimeType: agent.agentRuntimeType,
960
1104
  taskKey,
961
1105
  sessionParamsJson: previousSessionParams,
962
1106
  sessionDisplayId: previousSessionDisplayId,
963
- lastRunId: failedRun.id,
1107
+ lastRunId: run.id,
964
1108
  lastError: message,
965
- });
1109
+ },
966
1110
  }
1111
+ : {}),
1112
+ };
1113
+ const claimedFailedRun = await transitionRunToTerminal(run.id, "failed", failureEvidence, {
1114
+ terminalEffectsIntent: failureIntent,
1115
+ processExitedAt: new Date(),
1116
+ expectedExecutionOwnerToken: executionOwnerToken,
1117
+ });
1118
+ ownsTerminalState = Boolean(claimedFailedRun);
1119
+ if (!claimedFailedRun)
1120
+ await reconcileRunEvidence(run.id, failureEvidence);
1121
+ const failedRun = claimedFailedRun ?? await getRun(run.id);
1122
+ if (ownsTerminalState) {
1123
+ await setWakeupStatus(run.wakeupRequestId, "failed", {
1124
+ finishedAt: new Date(),
1125
+ error: message,
1126
+ });
1127
+ }
1128
+ if (failedRun) {
1129
+ if (ownsTerminalState) {
1130
+ await appendForbiddenMarkerEvent(failedRun, buildForbiddenMarkerScan(null));
1131
+ await appendRunEvent(failedRun, {
1132
+ eventType: isWorkspacePreflightFailure ? "runtime.workspace_preflight_failed" : "error",
1133
+ stream: "system",
1134
+ level: "error",
1135
+ message,
1136
+ ...(isWorkspacePreflightFailure
1137
+ ? {
1138
+ payload: {
1139
+ errorCode: err.errorCode,
1140
+ failure: err.failure,
1141
+ },
1142
+ }
1143
+ : {}),
1144
+ });
1145
+ }
1146
+ if (ownsTerminalState || failedRun.terminalEffectsPending) {
1147
+ shouldCompleteTerminalEffects = true;
967
1148
  }
968
1149
  }
969
- await finalizeAgentStatus(agent.id, "failed");
970
1150
  }
971
1151
  finally {
972
- stdoutTranscriptBuffer = appendTranscriptEntriesFromChunk({
973
- buffer: stdoutTranscriptBuffer,
974
- chunk: "",
975
- transcript: executionTranscript,
976
- parser: stdoutTranscriptParser,
977
- finalize: true,
978
- kind: "stdout",
979
- });
980
- stderrTranscriptBuffer = appendTranscriptEntriesFromChunk({
981
- buffer: stderrTranscriptBuffer,
982
- chunk: "",
983
- transcript: executionTranscript,
984
- finalize: true,
985
- kind: "stderr",
986
- });
1152
+ finalizeExecutionTranscript();
987
1153
  finalRunOutput = transcriptFallbackResult?.output ?? null;
988
- await publishAutomationRunOutputToChat(db, {
989
- issueId,
990
- output: finalRunOutput,
991
- status: finalRunStatus,
992
- transcript: executionTranscript,
993
- }).catch((error) => {
994
- logger.warn({
995
- runId: run.id,
996
- issueId,
997
- err: error instanceof Error ? error.message : String(error),
998
- }, "Failed to publish automation run output to chat");
999
- });
1154
+ if (ownsTerminalState || shouldCompleteTerminalEffects) {
1155
+ const terminalRun = await getRun(run.id).catch(() => null);
1156
+ if (terminalRun?.terminalEffectsPending) {
1157
+ await acknowledgeRunProcessExit(terminalRun.id);
1158
+ await completeTerminalControlEffects(terminalRun, ownsTerminalState
1159
+ ? {
1160
+ automationOutput: finalRunOutput,
1161
+ automationTranscript: executionTranscript,
1162
+ }
1163
+ : undefined);
1164
+ }
1165
+ }
1000
1166
  }
1001
1167
  }
1002
1168
  catch (outerErr) {
@@ -1004,33 +1170,42 @@ export function createHeartbeatExecuteHandlers(context) {
1004
1170
  // The inner catch did not fire, so we must record the failure here.
1005
1171
  const message = outerErr instanceof Error ? outerErr.message : "Unknown setup failure";
1006
1172
  logger.error({ err: outerErr, runId }, "heartbeat execution setup failed");
1007
- await setRunStatus(runId, "failed", {
1008
- error: message,
1009
- errorCode: "adapter_failed",
1010
- finishedAt: new Date(),
1011
- }).catch(() => undefined);
1012
- await setWakeupStatus(run.wakeupRequestId, "failed", {
1013
- finishedAt: new Date(),
1014
- error: message,
1015
- }).catch(() => undefined);
1016
- const failedRun = await getRun(runId).catch(() => null);
1017
- if (failedRun) {
1173
+ const latestRun = await getRun(runId).catch(() => null);
1174
+ const claimedFailedRun = latestRun?.status === "running"
1175
+ ? await transitionRunToTerminal(runId, "failed", {
1176
+ error: message,
1177
+ errorCode: "adapter_failed",
1178
+ finishedAt: new Date(),
1179
+ }, {
1180
+ processExitedAt: new Date(),
1181
+ expectedExecutionOwnerToken: executionOwnerToken,
1182
+ }).catch(() => undefined)
1183
+ : null;
1184
+ const terminalRun = claimedFailedRun ?? await getRun(runId).catch(() => latestRun);
1185
+ if (claimedFailedRun) {
1186
+ await setWakeupStatus(run.wakeupRequestId, "failed", {
1187
+ finishedAt: new Date(),
1188
+ error: message,
1189
+ }).catch(() => undefined);
1018
1190
  // Emit a run-log event so the failure is visible in the run timeline,
1019
1191
  // consistent with what the inner catch block does for adapter failures.
1020
- await appendRunEvent(failedRun, 1, {
1192
+ await appendRunEvent(claimedFailedRun, {
1021
1193
  eventType: "error",
1022
1194
  stream: "system",
1023
1195
  level: "error",
1024
1196
  message,
1025
1197
  }).catch(() => undefined);
1026
- await releaseIssueExecutionAndPromote(failedRun).catch(() => undefined);
1027
1198
  }
1028
- // Ensure the agent is not left stuck in "running" if the inner catch handler's
1029
- // DB calls threw (e.g. a transient DB error in finalizeAgentStatus).
1030
- await finalizeAgentStatus(run.agentId, "failed").catch(() => undefined);
1199
+ if (terminalRun?.terminalEffectsPending) {
1200
+ await acknowledgeRunProcessExit(terminalRun.id).catch(() => undefined);
1201
+ await completeTerminalControlEffects(terminalRun).catch(() => undefined);
1202
+ }
1031
1203
  }
1032
1204
  finally {
1205
+ if (executionLeaseTimer)
1206
+ clearInterval(executionLeaseTimer);
1033
1207
  await releaseRuntimeServicesForRun(run.id).catch(() => undefined);
1208
+ runAbortControllers.delete(run.id);
1034
1209
  activeRunExecutions.delete(run.id);
1035
1210
  await startNextQueuedRunForAgent(run.agentId);
1036
1211
  }