@rudderhq/server 0.4.6-canary.9 → 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 (350) 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 +348 -172
  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 +31 -54
  39. package/dist/index.js.map +1 -1
  40. package/dist/routes/access-onboarding.helpers.js +3 -3
  41. package/dist/routes/access-onboarding.helpers.js.map +1 -1
  42. package/dist/routes/access.helpers.d.ts.map +1 -1
  43. package/dist/routes/access.helpers.js +3 -2
  44. package/dist/routes/access.helpers.js.map +1 -1
  45. package/dist/routes/access.js +1 -1
  46. package/dist/routes/access.js.map +1 -1
  47. package/dist/routes/activity.d.ts.map +1 -1
  48. package/dist/routes/activity.js +5 -1
  49. package/dist/routes/activity.js.map +1 -1
  50. package/dist/routes/agents.management-routes.d.ts.map +1 -1
  51. package/dist/routes/agents.management-routes.js +13 -13
  52. package/dist/routes/agents.management-routes.js.map +1 -1
  53. package/dist/routes/assets.d.ts.map +1 -1
  54. package/dist/routes/assets.js +9 -2
  55. package/dist/routes/assets.js.map +1 -1
  56. package/dist/routes/chat-background-runtime.d.ts +19 -0
  57. package/dist/routes/chat-background-runtime.d.ts.map +1 -0
  58. package/dist/routes/chat-background-runtime.js +129 -0
  59. package/dist/routes/chat-background-runtime.js.map +1 -0
  60. package/dist/routes/chats.d.ts +2 -1
  61. package/dist/routes/chats.d.ts.map +1 -1
  62. package/dist/routes/chats.js +944 -24
  63. package/dist/routes/chats.js.map +1 -1
  64. package/dist/routes/chats.stream-routes.d.ts.map +1 -1
  65. package/dist/routes/chats.stream-routes.js +552 -76
  66. package/dist/routes/chats.stream-routes.js.map +1 -1
  67. package/dist/routes/issues.comments-attachments.d.ts.map +1 -1
  68. package/dist/routes/issues.comments-attachments.js +14 -31
  69. package/dist/routes/issues.comments-attachments.js.map +1 -1
  70. package/dist/routes/onboarding.js +1 -1
  71. package/dist/routes/onboarding.js.map +1 -1
  72. package/dist/routes/orgs.d.ts +2 -1
  73. package/dist/routes/orgs.d.ts.map +1 -1
  74. package/dist/routes/orgs.js +31 -2
  75. package/dist/routes/orgs.js.map +1 -1
  76. package/dist/routes/run-intelligence.d.ts.map +1 -1
  77. package/dist/routes/run-intelligence.js +76 -16
  78. package/dist/routes/run-intelligence.js.map +1 -1
  79. package/dist/services/activity-log.d.ts +4 -1
  80. package/dist/services/activity-log.d.ts.map +1 -1
  81. package/dist/services/activity-log.js +12 -4
  82. package/dist/services/activity-log.js.map +1 -1
  83. package/dist/services/activity.d.ts +11 -394
  84. package/dist/services/activity.d.ts.map +1 -1
  85. package/dist/services/activity.js +24 -18
  86. package/dist/services/activity.js.map +1 -1
  87. package/dist/services/agents.d.ts +741 -118
  88. package/dist/services/agents.d.ts.map +1 -1
  89. package/dist/services/approvals.d.ts +3 -3
  90. package/dist/services/automation-chat-output.d.ts.map +1 -1
  91. package/dist/services/automation-chat-output.js +115 -94
  92. package/dist/services/automation-chat-output.js.map +1 -1
  93. package/dist/services/budgets.d.ts.map +1 -1
  94. package/dist/services/budgets.js +38 -36
  95. package/dist/services/budgets.js.map +1 -1
  96. package/dist/services/chat-agent-runs.d.ts +3 -1
  97. package/dist/services/chat-agent-runs.d.ts.map +1 -1
  98. package/dist/services/chat-agent-runs.js +95 -34
  99. package/dist/services/chat-agent-runs.js.map +1 -1
  100. package/dist/services/chat-assistant.d.ts.map +1 -1
  101. package/dist/services/chat-assistant.helpers.d.ts +27 -4
  102. package/dist/services/chat-assistant.helpers.d.ts.map +1 -1
  103. package/dist/services/chat-assistant.helpers.js +66 -2
  104. package/dist/services/chat-assistant.helpers.js.map +1 -1
  105. package/dist/services/chat-assistant.inline-visuals.test.d.ts +2 -0
  106. package/dist/services/chat-assistant.inline-visuals.test.d.ts.map +1 -0
  107. package/dist/services/chat-assistant.inline-visuals.test.js +86 -0
  108. package/dist/services/chat-assistant.inline-visuals.test.js.map +1 -0
  109. package/dist/services/chat-assistant.js +115 -22
  110. package/dist/services/chat-assistant.js.map +1 -1
  111. package/dist/services/chat-generation-locks.d.ts +85 -0
  112. package/dist/services/chat-generation-locks.d.ts.map +1 -1
  113. package/dist/services/chat-generation-locks.js +371 -9
  114. package/dist/services/chat-generation-locks.js.map +1 -1
  115. package/dist/services/chat-generation-locks.test.d.ts +2 -0
  116. package/dist/services/chat-generation-locks.test.d.ts.map +1 -0
  117. package/dist/services/chat-generation-locks.test.js +324 -0
  118. package/dist/services/chat-generation-locks.test.js.map +1 -0
  119. package/dist/services/chat-generation-protocol.d.ts +674 -0
  120. package/dist/services/chat-generation-protocol.d.ts.map +1 -0
  121. package/dist/services/chat-generation-protocol.js +1571 -0
  122. package/dist/services/chat-generation-protocol.js.map +1 -0
  123. package/dist/services/chat-generation-protocol.test.d.ts +2 -0
  124. package/dist/services/chat-generation-protocol.test.d.ts.map +1 -0
  125. package/dist/services/chat-generation-protocol.test.js +1156 -0
  126. package/dist/services/chat-generation-protocol.test.js.map +1 -0
  127. package/dist/services/chat-title-generation.d.ts +0 -3
  128. package/dist/services/chat-title-generation.d.ts.map +1 -1
  129. package/dist/services/chat-title-generation.js +2 -32
  130. package/dist/services/chat-title-generation.js.map +1 -1
  131. package/dist/services/chat-work-manifest.d.ts.map +1 -1
  132. package/dist/services/chat-work-manifest.js +5 -1
  133. package/dist/services/chat-work-manifest.js.map +1 -1
  134. package/dist/services/chats.d.ts +1451 -272
  135. package/dist/services/chats.d.ts.map +1 -1
  136. package/dist/services/chats.js +1372 -35
  137. package/dist/services/chats.js.map +1 -1
  138. package/dist/services/costs.d.ts +34 -7
  139. package/dist/services/costs.d.ts.map +1 -1
  140. package/dist/services/costs.js +129 -61
  141. package/dist/services/costs.js.map +1 -1
  142. package/dist/services/finance.d.ts +3 -3
  143. package/dist/services/goals.d.ts +2 -2
  144. package/dist/services/heartbeat.d.ts +1 -1
  145. package/dist/services/heartbeat.d.ts.map +1 -1
  146. package/dist/services/heartbeat.js +1 -1
  147. package/dist/services/heartbeat.js.map +1 -1
  148. package/dist/services/index.d.ts +1 -0
  149. package/dist/services/index.d.ts.map +1 -1
  150. package/dist/services/index.js +1 -0
  151. package/dist/services/index.js.map +1 -1
  152. package/dist/services/integrations/agent-integrations.d.ts +1 -1
  153. package/dist/services/integrations/custom-integrations.d.ts +1 -1
  154. package/dist/services/integrations/feishu/runtime.d.ts.map +1 -1
  155. package/dist/services/integrations/feishu/runtime.js +16 -0
  156. package/dist/services/integrations/feishu/runtime.js.map +1 -1
  157. package/dist/services/issues.comments-attachments.d.ts +111 -0
  158. package/dist/services/issues.comments-attachments.d.ts.map +1 -1
  159. package/dist/services/issues.comments-attachments.js +138 -66
  160. package/dist/services/issues.comments-attachments.js.map +1 -1
  161. package/dist/services/issues.d.ts +56 -0
  162. package/dist/services/issues.d.ts.map +1 -1
  163. package/dist/services/issues.helpers.d.ts.map +1 -1
  164. package/dist/services/issues.helpers.js +2 -2
  165. package/dist/services/issues.helpers.js.map +1 -1
  166. package/dist/services/issues.js +5 -2
  167. package/dist/services/issues.js.map +1 -1
  168. package/dist/services/knowledge-portability/organization-skills.catalog.d.ts.map +1 -1
  169. package/dist/services/knowledge-portability/organization-skills.catalog.js +7 -1
  170. package/dist/services/knowledge-portability/organization-skills.catalog.js.map +1 -1
  171. package/dist/services/messenger.d.ts.map +1 -1
  172. package/dist/services/messenger.js +11 -9
  173. package/dist/services/messenger.js.map +1 -1
  174. package/dist/services/organization-workspace-browser.d.ts.map +1 -1
  175. package/dist/services/organization-workspace-browser.js +19 -3
  176. package/dist/services/organization-workspace-browser.js.map +1 -1
  177. package/dist/services/orgs.d.ts.map +1 -1
  178. package/dist/services/orgs.js +36 -12
  179. package/dist/services/orgs.js.map +1 -1
  180. package/dist/services/plugin-dev-watcher.d.ts +19 -2
  181. package/dist/services/plugin-dev-watcher.d.ts.map +1 -1
  182. package/dist/services/plugin-dev-watcher.js +45 -11
  183. package/dist/services/plugin-dev-watcher.js.map +1 -1
  184. package/dist/services/plugin-registry.d.ts +28 -28
  185. package/dist/services/projects.d.ts +1 -1
  186. package/dist/services/run-events.d.ts +20 -0
  187. package/dist/services/run-events.d.ts.map +1 -0
  188. package/dist/services/run-events.js +34 -0
  189. package/dist/services/run-events.js.map +1 -0
  190. package/dist/services/run-intelligence.d.ts +16 -4
  191. package/dist/services/run-intelligence.d.ts.map +1 -1
  192. package/dist/services/run-intelligence.js +90 -15
  193. package/dist/services/run-intelligence.js.map +1 -1
  194. package/dist/services/runtime-kernel/heartbeat.core.d.ts +23 -0
  195. package/dist/services/runtime-kernel/heartbeat.core.d.ts.map +1 -1
  196. package/dist/services/runtime-kernel/heartbeat.core.js +1 -0
  197. package/dist/services/runtime-kernel/heartbeat.core.js.map +1 -1
  198. package/dist/services/runtime-kernel/heartbeat.d.ts +95 -37
  199. package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
  200. package/dist/services/runtime-kernel/heartbeat.execute.d.ts +3 -1
  201. package/dist/services/runtime-kernel/heartbeat.execute.d.ts.map +1 -1
  202. package/dist/services/runtime-kernel/heartbeat.execute.js +389 -219
  203. package/dist/services/runtime-kernel/heartbeat.execute.js.map +1 -1
  204. package/dist/services/runtime-kernel/heartbeat.js +594 -204
  205. package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
  206. package/dist/services/runtime-kernel/heartbeat.misc.d.ts.map +1 -1
  207. package/dist/services/runtime-kernel/heartbeat.misc.js +34 -24
  208. package/dist/services/runtime-kernel/heartbeat.misc.js.map +1 -1
  209. package/dist/services/runtime-kernel/heartbeat.recovery.d.ts.map +1 -1
  210. package/dist/services/runtime-kernel/heartbeat.recovery.js +56 -6
  211. package/dist/services/runtime-kernel/heartbeat.recovery.js.map +1 -1
  212. package/dist/services/runtime-kernel/heartbeat.release.d.ts +3 -1
  213. package/dist/services/runtime-kernel/heartbeat.release.d.ts.map +1 -1
  214. package/dist/services/runtime-kernel/heartbeat.release.js +276 -44
  215. package/dist/services/runtime-kernel/heartbeat.release.js.map +1 -1
  216. package/dist/services/runtime-kernel/heartbeat.sessions.d.ts +42 -1
  217. package/dist/services/runtime-kernel/heartbeat.sessions.d.ts.map +1 -1
  218. package/dist/services/runtime-kernel/heartbeat.sessions.js +110 -8
  219. package/dist/services/runtime-kernel/heartbeat.sessions.js.map +1 -1
  220. package/dist/services/runtime-kernel/heartbeat.terminal.d.ts +575 -0
  221. package/dist/services/runtime-kernel/heartbeat.terminal.d.ts.map +1 -0
  222. package/dist/services/runtime-kernel/heartbeat.terminal.js +589 -0
  223. package/dist/services/runtime-kernel/heartbeat.terminal.js.map +1 -0
  224. package/dist/services/runtime-kernel/heartbeat.wakeup.d.ts.map +1 -1
  225. package/dist/services/runtime-kernel/heartbeat.wakeup.js +238 -92
  226. package/dist/services/runtime-kernel/heartbeat.wakeup.js.map +1 -1
  227. package/dist/services/runtime-kernel/model-fallback.d.ts.map +1 -1
  228. package/dist/services/runtime-kernel/model-fallback.js +11 -0
  229. package/dist/services/runtime-kernel/model-fallback.js.map +1 -1
  230. package/dist/services/side-chats.d.ts +212 -0
  231. package/dist/services/side-chats.d.ts.map +1 -0
  232. package/dist/services/side-chats.js +379 -0
  233. package/dist/services/side-chats.js.map +1 -0
  234. package/dist/services/workspace-runtime.services.d.ts +1 -1
  235. package/dist/services/workspace-web-preview.d.ts +36 -0
  236. package/dist/services/workspace-web-preview.d.ts.map +1 -0
  237. package/dist/services/workspace-web-preview.js +566 -0
  238. package/dist/services/workspace-web-preview.js.map +1 -0
  239. package/package.json +13 -13
  240. package/resources/bundled-skills/rudder-docs/SKILL.md +161 -0
  241. package/resources/bundled-skills/rudder-docs/evals/trigger-evals.json +82 -0
  242. package/{skills/rudder → resources/bundled-skills/rudder-docs}/references/api-reference.md +17 -1
  243. package/{skills/rudder → resources/bundled-skills/rudder-docs}/references/cli-reference.md +49 -94
  244. package/resources/bundled-skills/rudder-docs/references/control-plane-practices.md +231 -0
  245. package/{skills/rudder → resources/bundled-skills/rudder-docs}/references/organization-skills.md +15 -1
  246. package/resources/bundled-skills/rudder-docs/references/source-map.md +138 -0
  247. package/resources/bundled-skills/visualize/SKILL.md +132 -0
  248. package/resources/bundled-skills/visualize/agents/openai.yaml +7 -0
  249. package/resources/bundled-skills/visualize/assets/example-chart.html +89 -0
  250. package/resources/bundled-skills/visualize/references/runtime-contract.md +114 -0
  251. package/skills/rudder-docs/SKILL.md +161 -0
  252. package/skills/rudder-docs/evals/trigger-evals.json +82 -0
  253. package/{resources/bundled-skills/rudder → skills/rudder-docs}/references/api-reference.md +17 -1
  254. package/{resources/bundled-skills/rudder → skills/rudder-docs}/references/cli-reference.md +49 -94
  255. package/skills/rudder-docs/references/control-plane-practices.md +231 -0
  256. package/{resources/bundled-skills/rudder → skills/rudder-docs}/references/organization-skills.md +15 -1
  257. package/skills/rudder-docs/references/source-map.md +138 -0
  258. package/skills/visualize/SKILL.md +132 -0
  259. package/skills/visualize/agents/openai.yaml +7 -0
  260. package/skills/visualize/assets/example-chart.html +89 -0
  261. package/skills/visualize/references/runtime-contract.md +114 -0
  262. package/ui-dist/assets/{abnfDiagram-VRR7QNED-CKLAbEpH.js → abnfDiagram-VRR7QNED-Dpnx79fp.js} +1 -1
  263. package/ui-dist/assets/{arc-CS20WjB1.js → arc-Cpvh_rCf.js} +1 -1
  264. package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-BY4lounK.js → architectureDiagram-ZJ3FMSHR-sDD_mBAI.js} +1 -1
  265. package/ui-dist/assets/{blockDiagram-677ZJIJ3-BHtHl-hm.js → blockDiagram-677ZJIJ3-4O4wWti1.js} +1 -1
  266. package/ui-dist/assets/{c4Diagram-LMCZKHZV-DgOJp7yn.js → c4Diagram-LMCZKHZV-BkGODE4P.js} +1 -1
  267. package/ui-dist/assets/channel-CM4Myg_6.js +1 -0
  268. package/ui-dist/assets/{chunk-2Q5K7J3B-Uin6HTPH.js → chunk-2Q5K7J3B-DsDQQpID.js} +1 -1
  269. package/ui-dist/assets/{chunk-32BRIVSS-BxAI7yMx.js → chunk-32BRIVSS-Bzx_VnIw.js} +1 -1
  270. package/ui-dist/assets/{chunk-5VM5RSS4-Ce6AR6Sg.js → chunk-5VM5RSS4-D4LoPCni.js} +1 -1
  271. package/ui-dist/assets/{chunk-EX3LRPZG-DgxPO59e.js → chunk-EX3LRPZG-BO0R-mS4.js} +3 -3
  272. package/ui-dist/assets/{chunk-JWPE2WC7-Bn3BYmxA.js → chunk-JWPE2WC7-B4Nr8KRL.js} +1 -1
  273. package/ui-dist/assets/{chunk-MOJQB5TN-BlTdGU58.js → chunk-MOJQB5TN--uaDDrYM.js} +1 -1
  274. package/ui-dist/assets/{chunk-RYQCIY6F-C0V6evNH.js → chunk-RYQCIY6F-CyBY2w_j.js} +1 -1
  275. package/ui-dist/assets/{chunk-V7JOEXUC-DjvZ40fp.js → chunk-V7JOEXUC-BMid_x8S.js} +3 -3
  276. package/ui-dist/assets/{chunk-VR4S4FIN-CejmQVxi.js → chunk-VR4S4FIN-DVqdPKuG.js} +1 -1
  277. package/ui-dist/assets/{chunk-XXDRQBXY-tj-vHLHN.js → chunk-XXDRQBXY-vy03lLSS.js} +1 -1
  278. package/ui-dist/assets/classDiagram-OUVF2IWQ-CtlIEzTt.js +1 -0
  279. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CtlIEzTt.js +1 -0
  280. package/ui-dist/assets/{cose-bilkent-JH36ORCC-Ci7DAkTj.js → cose-bilkent-JH36ORCC-jQDZmrG3.js} +1 -1
  281. package/ui-dist/assets/{cynefin-VYW2F7L2-CHU2plsQ.js → cynefin-VYW2F7L2-BxBj6aea.js} +1 -1
  282. package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-pqqNoczb.js → cynefinDiagram-TSTJHNR4-BuUubF5I.js} +1 -1
  283. package/ui-dist/assets/{dagre-VKFMJZFB-Bk8Y_kGf.js → dagre-VKFMJZFB-B8HipJ3a.js} +1 -1
  284. package/ui-dist/assets/{diagram-FQU43EPY-CiSxIS2M.js → diagram-FQU43EPY-r7gkbKSt.js} +2 -2
  285. package/ui-dist/assets/{diagram-G47NLZAW-qpVsOLnz.js → diagram-G47NLZAW-CxClRsxD.js} +1 -1
  286. package/ui-dist/assets/{diagram-NH7WQ7WH-Cda5JA3K.js → diagram-NH7WQ7WH-C8HYTLlq.js} +1 -1
  287. package/ui-dist/assets/{diagram-OA4YK3LP-Dh_DdE2d.js → diagram-OA4YK3LP-CjwqqLKz.js} +1 -1
  288. package/ui-dist/assets/{diagram-WEI45ONY-r5ouUhNZ.js → diagram-WEI45ONY-2IWfCqZb.js} +1 -1
  289. package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-C6lDAmmi.js → ebnfDiagram-CCIWWBDH-DVGZkgjy.js} +1 -1
  290. package/ui-dist/assets/{erDiagram-Q63AITRT-BznPfnRu.js → erDiagram-Q63AITRT-C_-u3Gmw.js} +1 -1
  291. package/ui-dist/assets/{flowDiagram-23GEKE2U-bCaogpDj.js → flowDiagram-23GEKE2U-BvGg0NCq.js} +4 -4
  292. package/ui-dist/assets/{ganttDiagram-NO4QXBWP-Bn-e5kP6.js → ganttDiagram-NO4QXBWP-U3CZUUUR.js} +1 -1
  293. package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-D7E-RLhl.js → gitGraphDiagram-IHSO6WYX-CIWuEBIo.js} +1 -1
  294. package/ui-dist/assets/{graph-3haZvvEy.js → graph-D3P5q-7m.js} +1 -1
  295. package/ui-dist/assets/index-B1rLBtZ1.js +1875 -0
  296. package/ui-dist/assets/{index-BUneV0z1.js → index-BAMXpiI5.js} +1 -1
  297. package/ui-dist/assets/{index-CheuLaX8.js → index-BAgtKYR1.js} +1 -1
  298. package/ui-dist/assets/{index-BDji4WI2.js → index-CBOr9F6w.js} +1 -1
  299. package/ui-dist/assets/{index-DlcNrNku.js → index-CbHqnWUe.js} +1 -1
  300. package/ui-dist/assets/{index-C1NcizE3.js → index-CjztBLJi.js} +1 -1
  301. package/ui-dist/assets/{index-JqztCnnf.js → index-Cu1iMhjl.js} +1 -1
  302. package/ui-dist/assets/{index-BFnwTV9t.js → index-D7ycf1qU.js} +1 -1
  303. package/ui-dist/assets/{index-JLGi6sfB.js → index-DAYlwxsg.js} +1 -1
  304. package/ui-dist/assets/{index-Bje1DqHh.js → index-DCFf9dps.js} +4 -4
  305. package/ui-dist/assets/{index-zyCQr__a.js → index-DOPIV8vd.js} +1 -1
  306. package/ui-dist/assets/{index-JEy5ZJbE.js → index-DRxLJD40.js} +1 -1
  307. package/ui-dist/assets/{index-Doc88zxN.js → index-DYMtCDKT.js} +1 -1
  308. package/ui-dist/assets/index-DekHKOsL.css +1 -0
  309. package/ui-dist/assets/{index-BN3GMGqN.js → index-DidCCw78.js} +1 -1
  310. package/ui-dist/assets/{index-DKRH0hjR.js → index-Ds_qma4-.js} +1 -1
  311. package/ui-dist/assets/{index-B2bHoMTu.js → index-HkQRx1D6.js} +1 -1
  312. package/ui-dist/assets/{index-DLxzQvPB.js → index-ikpL--zj.js} +1 -1
  313. package/ui-dist/assets/{index-mE0kmjy0.js → index-mnl55Stn.js} +1 -1
  314. package/ui-dist/assets/{infoDiagram-FWYZ7A6U-NSQ6saR1.js → infoDiagram-FWYZ7A6U-Cx8Fa-I4.js} +1 -1
  315. package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-XhGk3DMM.js → ishikawaDiagram-FXEZZL3T-Cmuz1QUN.js} +1 -1
  316. package/ui-dist/assets/{journeyDiagram-5HDEW3XC-CUyh1IKu.js → journeyDiagram-5HDEW3XC-CJgkiVXG.js} +1 -1
  317. package/ui-dist/assets/{kanban-definition-HUTT4EX6-P_0zllUc.js → kanban-definition-HUTT4EX6-RAWpefOB.js} +1 -1
  318. package/ui-dist/assets/layout-DyWQv0Rr.js +1 -0
  319. package/ui-dist/assets/{linear-DWu-hp7y.js → linear-D5pdgIf9.js} +1 -1
  320. package/ui-dist/assets/{map-B2IiHu-a.js → map-bVSzNLl2.js} +1 -1
  321. package/ui-dist/assets/mermaid.core-CeaXGD6B.js +312 -0
  322. package/ui-dist/assets/{mindmap-definition-LN4V7U3C-DpKo7DKc.js → mindmap-definition-LN4V7U3C-B8B8AX5C.js} +1 -1
  323. package/ui-dist/assets/{pegDiagram-2B236MQR-DzDDMRRX.js → pegDiagram-2B236MQR-C4Sv-ua6.js} +1 -1
  324. package/ui-dist/assets/{pieDiagram-ENE6RG2P-Dr7ZCi_a.js → pieDiagram-ENE6RG2P-CLARlOHx.js} +1 -1
  325. package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-BB_gv9s9.js → quadrantDiagram-ABIIQ3AL-DPCXQmeT.js} +1 -1
  326. package/ui-dist/assets/{railroadDiagram-RFXS5EU6-C2ji_jMN.js → railroadDiagram-RFXS5EU6-BpqRuKUQ.js} +1 -1
  327. package/ui-dist/assets/{requirementDiagram-TGXJPOKE-BJg8vYwc.js → requirementDiagram-TGXJPOKE-Dd-h62HZ.js} +1 -1
  328. package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-msvrlvO_.js → sankeyDiagram-HTMAVEWB-DylT_pqq.js} +1 -1
  329. package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-B_B68qK5.js → sequenceDiagram-DBY2YBRQ-RiCF1REj.js} +1 -1
  330. package/ui-dist/assets/{sizeCapture-X5ZJPWSS-D0VdKiQi.js → sizeCapture-X5ZJPWSS-DXW4JQz2.js} +1 -1
  331. package/ui-dist/assets/{stateDiagram-2N3HPSRC-B4V-owEQ.js → stateDiagram-2N3HPSRC-6U3ESIGT.js} +1 -1
  332. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-KQTrcZvp.js +1 -0
  333. package/ui-dist/assets/{swimlanes-5IMT3BWC-B1JTwGb7.js → swimlanes-5IMT3BWC-CeNHVNCi.js} +2 -2
  334. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-CcxS1c6r.js +8 -0
  335. package/ui-dist/assets/{timeline-definition-FHXFAJF6-C-8YlQA9.js → timeline-definition-FHXFAJF6-Vlwoe_1b.js} +1 -1
  336. package/ui-dist/assets/{vennDiagram-L72KCM5P-DP13xuPX.js → vennDiagram-L72KCM5P-DBP7D3HE.js} +6 -6
  337. package/ui-dist/assets/{wardleyDiagram-EHGQE667-D6BNPJwb.js → wardleyDiagram-EHGQE667-DG-wzqpy.js} +1 -1
  338. package/ui-dist/assets/{xychartDiagram-FW5EYKEG-my7CwP2H.js → xychartDiagram-FW5EYKEG-BAq3mbha.js} +1 -1
  339. package/ui-dist/index.html +2 -2
  340. package/resources/bundled-skills/rudder/SKILL.md +0 -314
  341. package/skills/rudder/SKILL.md +0 -314
  342. package/ui-dist/assets/channel-D-nDuwao.js +0 -1
  343. package/ui-dist/assets/classDiagram-OUVF2IWQ-Ds2nJ2Kt.js +0 -1
  344. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-Ds2nJ2Kt.js +0 -1
  345. package/ui-dist/assets/index-BA7XbHmf.css +0 -1
  346. package/ui-dist/assets/index-hE0ZX3Ud.js +0 -1820
  347. package/ui-dist/assets/layout-C-tMX-j8.js +0 -1
  348. package/ui-dist/assets/mermaid.core-WA5rvr0F.js +0 -314
  349. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-DAB9Vdyb.js +0 -1
  350. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-DRt36f68.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,7 +836,6 @@ 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);
747
840
  const persistedResultSummary = summarizeHeartbeatRunResultJson({
748
841
  ...(adapterResult.resultJson ?? {}),
@@ -774,9 +867,10 @@ export function createHeartbeatExecuteHandlers(context) {
774
867
  ...((nextSessionState.displayId ?? nextSessionState.legacySessionId)
775
868
  ? { persistedSessionId: nextSessionState.displayId ?? nextSessionState.legacySessionId }
776
869
  : {}),
777
- sessionReused: runtimeForAdapter.sessionId != null || runtimeForAdapter.sessionDisplayId != null,
778
- taskSessionReused: taskSessionForRun != null,
779
- freshSession: runtimeForAdapter.sessionId == null && runtimeForAdapter.sessionDisplayId == null,
870
+ sessionReused: sessionReuseScope !== "none",
871
+ taskSessionReused: sessionReuseScope === "task",
872
+ freshSession: sessionReuseScope === "none",
873
+ sessionReuseScope,
780
874
  sessionRotated: sessionCompaction.rotate,
781
875
  sessionRotationReason: sessionCompaction.reason,
782
876
  provider: readNonEmptyString(adapterResult.provider) ?? "unknown",
@@ -786,7 +880,8 @@ export function createHeartbeatExecuteHandlers(context) {
786
880
  billingType: normalizeLedgerBillingType(adapterResult.billingType),
787
881
  }
788
882
  : null;
789
- await setRunStatus(run.id, status, {
883
+ finalizeExecutionTranscript();
884
+ const terminalEvidence = {
790
885
  finishedAt: new Date(),
791
886
  error: outcome === "succeeded"
792
887
  ? null
@@ -808,24 +903,85 @@ export function createHeartbeatExecuteHandlers(context) {
808
903
  resultJson: adapterResult.resultJson ?? null,
809
904
  resultSummaryJson: persistedResultSummary,
810
905
  sessionIdAfter: nextSessionState.displayId ?? nextSessionState.legacySessionId,
906
+ sessionParamsAfterJson: adapterResult.clearSession ? {} : nextSessionState.params,
811
907
  stdoutExcerpt,
812
908
  stderrExcerpt,
813
909
  logBytes: logSummary?.bytes,
814
910
  logSha256: logSummary?.sha256,
815
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,
816
954
  });
817
- await setWakeupStatus(run.wakeupRequestId, outcome === "succeeded" ? "completed" : status, {
818
- finishedAt: new Date(),
819
- error: failureCausedByForbiddenMarker
820
- ? "Forbidden runtime skill marker observed"
821
- : adapterResult.errorMessage ?? null,
822
- });
823
- 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);
824
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
+ }
825
981
  await appendForbiddenMarkerEvent(finalizedRun, forbiddenMarkerScan);
826
982
  const transcriptUsedSkills = inferUsedSkillsFromTranscript(executionTranscript);
827
983
  if (transcriptUsedSkills.length > 0) {
828
- await appendRunEvent(finalizedRun, seq++, {
984
+ await appendRunEvent(finalizedRun, {
829
985
  eventType: "adapter.skill_usage",
830
986
  stream: "system",
831
987
  level: "info",
@@ -842,50 +998,29 @@ export function createHeartbeatExecuteHandlers(context) {
842
998
  },
843
999
  });
844
1000
  }
845
- await appendRunEvent(finalizedRun, seq++, {
846
- eventType: "lifecycle",
847
- stream: "system",
848
- level: outcome === "succeeded" ? "info" : "error",
849
- message: `run ${outcome}`,
850
- payload: {
851
- status,
852
- exitCode: adapterResult.exitCode,
853
- },
854
- });
855
- 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
+ }
856
1013
  }
857
1014
  if (finalizedRun) {
858
- await updateRuntimeState(agent, finalizedRun, adapterResult, {
859
- legacySessionId: nextSessionState.legacySessionId,
860
- }, normalizedUsage);
861
- if (taskKey) {
862
- if (adapterResult.clearSession || (!nextSessionState.params && !nextSessionState.displayId)) {
863
- await clearTaskSessions(agent.orgId, agent.id, {
864
- taskKey,
865
- agentRuntimeType: agent.agentRuntimeType,
866
- });
867
- }
868
- else {
869
- await upsertTaskSession({
870
- orgId: agent.orgId,
871
- agentId: agent.id,
872
- agentRuntimeType: agent.agentRuntimeType,
873
- taskKey,
874
- sessionParamsJson: nextSessionState.params,
875
- sessionDisplayId: nextSessionState.displayId,
876
- lastRunId: finalizedRun.id,
877
- lastError: outcome === "succeeded" ? null : (adapterResult.errorMessage ?? "run_failed"),
878
- });
879
- }
1015
+ if (ownsTerminalState || finalizedRun.terminalEffectsPending) {
1016
+ shouldCompleteTerminalEffects = true;
880
1017
  }
881
1018
  }
882
- await finalizeAgentStatus(agent.id, outcome);
883
1019
  }
884
1020
  catch (err) {
885
1021
  const isWorkspacePreflightFailure = isWorkspacePermissionPreflightError(err) ||
886
1022
  isManagedWorkspaceConfigurationError(err);
887
1023
  const message = redactCurrentUserText(err instanceof Error ? err.message : "Unknown adapter failure", await getCurrentUserRedactionOptions());
888
- finalRunStatus = "failed";
889
1024
  transcriptFallbackResult = {
890
1025
  ts: new Date().toISOString(),
891
1026
  output: message,
@@ -895,17 +1030,32 @@ export function createHeartbeatExecuteHandlers(context) {
895
1030
  };
896
1031
  logger.error({ err, runId }, "heartbeat execution failed");
897
1032
  const latestRun = await getRun(run.id);
898
- 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") {
899
1037
  const terminalStatus = latestRun.status;
900
- finalRunStatus = terminalStatus;
901
1038
  transcriptFallbackResult = {
902
1039
  ts: new Date().toISOString(),
903
1040
  output: latestRun.error ?? message,
904
1041
  subtype: terminalStatus,
905
- isError: terminalStatus === "timed_out",
1042
+ isError: terminalStatus !== "succeeded",
906
1043
  errors: latestRun.error ? [latestRun.error] : [],
907
1044
  };
908
- 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
+ }
909
1059
  return;
910
1060
  }
911
1061
  let logSummary = null;
@@ -917,7 +1067,7 @@ export function createHeartbeatExecuteHandlers(context) {
917
1067
  logger.warn({ err: finalizeErr, runId }, "failed to finalize run log after error");
918
1068
  }
919
1069
  }
920
- const failedRun = await setRunStatus(run.id, "failed", {
1070
+ const failureEvidence = {
921
1071
  error: message,
922
1072
  errorCode: isWorkspacePreflightFailure ? err.errorCode : "adapter_failed",
923
1073
  finishedAt: new Date(),
@@ -926,82 +1076,93 @@ export function createHeartbeatExecuteHandlers(context) {
926
1076
  logBytes: logSummary?.bytes,
927
1077
  logSha256: logSummary?.sha256,
928
1078
  logCompressed: logSummary?.compressed ?? false,
929
- });
930
- await setWakeupStatus(run.wakeupRequestId, "failed", {
931
- finishedAt: new Date(),
932
- error: message,
933
- });
934
- if (failedRun) {
935
- await appendForbiddenMarkerEvent(failedRun, buildForbiddenMarkerScan(null));
936
- await appendRunEvent(failedRun, seq++, {
937
- eventType: isWorkspacePreflightFailure ? "runtime.workspace_preflight_failed" : "error",
938
- stream: "system",
939
- level: "error",
940
- message,
941
- ...(isWorkspacePreflightFailure
942
- ? {
943
- payload: {
944
- errorCode: err.errorCode,
945
- 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,
946
1092
  },
947
- }
948
- : {}),
949
- });
950
- await releaseIssueExecutionAndPromote(failedRun);
951
- if (!isWorkspacePreflightFailure) {
952
- await updateRuntimeState(agent, failedRun, {
953
- exitCode: null,
954
- signal: null,
955
- timedOut: false,
956
- errorMessage: message,
957
- }, {
958
- legacySessionId: runtimeForAdapter.sessionId,
959
- });
960
- if (taskKey && (previousSessionParams || previousSessionDisplayId || taskSession)) {
961
- await upsertTaskSession({
1093
+ legacySessionId: runtimeForAdapter.sessionId,
1094
+ },
1095
+ }
1096
+ : {}),
1097
+ ...(taskKey && !isWorkspacePreflightFailure && (previousSessionParams || previousSessionDisplayId || taskSession)
1098
+ ? {
1099
+ taskSession: {
1100
+ operation: "upsert",
962
1101
  orgId: agent.orgId,
963
1102
  agentId: agent.id,
964
1103
  agentRuntimeType: agent.agentRuntimeType,
965
1104
  taskKey,
966
1105
  sessionParamsJson: previousSessionParams,
967
1106
  sessionDisplayId: previousSessionDisplayId,
968
- lastRunId: failedRun.id,
1107
+ lastRunId: run.id,
969
1108
  lastError: message,
970
- });
1109
+ },
971
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;
972
1148
  }
973
1149
  }
974
- await finalizeAgentStatus(agent.id, "failed");
975
1150
  }
976
1151
  finally {
977
- stdoutTranscriptBuffer = appendTranscriptEntriesFromChunk({
978
- buffer: stdoutTranscriptBuffer,
979
- chunk: "",
980
- transcript: executionTranscript,
981
- parser: stdoutTranscriptParser,
982
- finalize: true,
983
- kind: "stdout",
984
- });
985
- stderrTranscriptBuffer = appendTranscriptEntriesFromChunk({
986
- buffer: stderrTranscriptBuffer,
987
- chunk: "",
988
- transcript: executionTranscript,
989
- finalize: true,
990
- kind: "stderr",
991
- });
1152
+ finalizeExecutionTranscript();
992
1153
  finalRunOutput = transcriptFallbackResult?.output ?? null;
993
- await publishAutomationRunOutputToChat(db, {
994
- issueId,
995
- output: finalRunOutput,
996
- status: finalRunStatus,
997
- transcript: executionTranscript,
998
- }).catch((error) => {
999
- logger.warn({
1000
- runId: run.id,
1001
- issueId,
1002
- err: error instanceof Error ? error.message : String(error),
1003
- }, "Failed to publish automation run output to chat");
1004
- });
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
+ }
1005
1166
  }
1006
1167
  }
1007
1168
  catch (outerErr) {
@@ -1009,33 +1170,42 @@ export function createHeartbeatExecuteHandlers(context) {
1009
1170
  // The inner catch did not fire, so we must record the failure here.
1010
1171
  const message = outerErr instanceof Error ? outerErr.message : "Unknown setup failure";
1011
1172
  logger.error({ err: outerErr, runId }, "heartbeat execution setup failed");
1012
- await setRunStatus(runId, "failed", {
1013
- error: message,
1014
- errorCode: "adapter_failed",
1015
- finishedAt: new Date(),
1016
- }).catch(() => undefined);
1017
- await setWakeupStatus(run.wakeupRequestId, "failed", {
1018
- finishedAt: new Date(),
1019
- error: message,
1020
- }).catch(() => undefined);
1021
- const failedRun = await getRun(runId).catch(() => null);
1022
- 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);
1023
1190
  // Emit a run-log event so the failure is visible in the run timeline,
1024
1191
  // consistent with what the inner catch block does for adapter failures.
1025
- await appendRunEvent(failedRun, 1, {
1192
+ await appendRunEvent(claimedFailedRun, {
1026
1193
  eventType: "error",
1027
1194
  stream: "system",
1028
1195
  level: "error",
1029
1196
  message,
1030
1197
  }).catch(() => undefined);
1031
- await releaseIssueExecutionAndPromote(failedRun).catch(() => undefined);
1032
1198
  }
1033
- // Ensure the agent is not left stuck in "running" if the inner catch handler's
1034
- // DB calls threw (e.g. a transient DB error in finalizeAgentStatus).
1035
- 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
+ }
1036
1203
  }
1037
1204
  finally {
1205
+ if (executionLeaseTimer)
1206
+ clearInterval(executionLeaseTimer);
1038
1207
  await releaseRuntimeServicesForRun(run.id).catch(() => undefined);
1208
+ runAbortControllers.delete(run.id);
1039
1209
  activeRunExecutions.delete(run.id);
1040
1210
  await startNextQueuedRunForAgent(run.agentId);
1041
1211
  }