@rudderhq/server 0.7.15 → 0.7.18

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 (247) hide show
  1. package/dist/agent-runtimes/http/execute.test.d.ts +2 -0
  2. package/dist/agent-runtimes/http/execute.test.d.ts.map +1 -0
  3. package/dist/agent-runtimes/http/execute.test.js +43 -0
  4. package/dist/agent-runtimes/http/execute.test.js.map +1 -0
  5. package/dist/agent-runtimes/process/execute.d.ts.map +1 -1
  6. package/dist/agent-runtimes/process/execute.js +20 -3
  7. package/dist/agent-runtimes/process/execute.js.map +1 -1
  8. package/dist/agent-runtimes/process/execute.test.d.ts +2 -0
  9. package/dist/agent-runtimes/process/execute.test.d.ts.map +1 -0
  10. package/dist/agent-runtimes/process/execute.test.js +57 -0
  11. package/dist/agent-runtimes/process/execute.test.js.map +1 -0
  12. package/dist/agent-runtimes/registry.d.ts.map +1 -1
  13. package/dist/agent-runtimes/registry.js +3 -1
  14. package/dist/agent-runtimes/registry.js.map +1 -1
  15. package/dist/config.js +4 -4
  16. package/dist/config.js.map +1 -1
  17. package/dist/index.js +2 -2
  18. package/dist/index.js.map +1 -1
  19. package/dist/routes/agents.management-routes.d.ts.map +1 -1
  20. package/dist/routes/agents.management-routes.js +51 -1
  21. package/dist/routes/agents.management-routes.js.map +1 -1
  22. package/dist/routes/chats.annotation-routes.d.ts +6 -1
  23. package/dist/routes/chats.annotation-routes.d.ts.map +1 -1
  24. package/dist/routes/chats.annotation-routes.js +40 -7
  25. package/dist/routes/chats.annotation-routes.js.map +1 -1
  26. package/dist/routes/chats.d.ts.map +1 -1
  27. package/dist/routes/chats.js +28 -40
  28. package/dist/routes/chats.js.map +1 -1
  29. package/dist/routes/chats.message-query-routes.d.ts +9 -0
  30. package/dist/routes/chats.message-query-routes.d.ts.map +1 -0
  31. package/dist/routes/chats.message-query-routes.js +43 -0
  32. package/dist/routes/chats.message-query-routes.js.map +1 -0
  33. package/dist/routes/chats.stop-route.d.ts +3 -0
  34. package/dist/routes/chats.stop-route.d.ts.map +1 -0
  35. package/dist/routes/chats.stop-route.js +240 -0
  36. package/dist/routes/chats.stop-route.js.map +1 -0
  37. package/dist/routes/chats.stream-routes.d.ts.map +1 -1
  38. package/dist/routes/chats.stream-routes.js +110 -302
  39. package/dist/routes/chats.stream-routes.js.map +1 -1
  40. package/dist/routes/chats.stream-support.d.ts +41 -0
  41. package/dist/routes/chats.stream-support.d.ts.map +1 -1
  42. package/dist/routes/chats.stream-support.js +58 -0
  43. package/dist/routes/chats.stream-support.js.map +1 -1
  44. package/dist/routes/issues.mutations.d.ts.map +1 -1
  45. package/dist/routes/issues.mutations.js +99 -1
  46. package/dist/routes/issues.mutations.js.map +1 -1
  47. package/dist/routes/run-intelligence.d.ts.map +1 -1
  48. package/dist/routes/run-intelligence.js +11 -1
  49. package/dist/routes/run-intelligence.js.map +1 -1
  50. package/dist/services/agent-issue-creation.d.ts +1 -0
  51. package/dist/services/agent-issue-creation.d.ts.map +1 -1
  52. package/dist/services/agent-run-context.d.ts +1 -1
  53. package/dist/services/agent-run-context.d.ts.map +1 -1
  54. package/dist/services/agents.d.ts +35 -0
  55. package/dist/services/agents.d.ts.map +1 -1
  56. package/dist/services/automation-chat-output.d.ts +2 -0
  57. package/dist/services/automation-chat-output.d.ts.map +1 -1
  58. package/dist/services/automations.d.ts.map +1 -1
  59. package/dist/services/automations.js +1 -1
  60. package/dist/services/automations.js.map +1 -1
  61. package/dist/services/chat-agent-runs.d.ts +3 -0
  62. package/dist/services/chat-agent-runs.d.ts.map +1 -1
  63. package/dist/services/chat-annotation-copy-lineage.d.ts +2 -0
  64. package/dist/services/chat-annotation-copy-lineage.d.ts.map +1 -1
  65. package/dist/services/chat-generation-locks.d.ts +3 -1
  66. package/dist/services/chat-generation-locks.d.ts.map +1 -1
  67. package/dist/services/chat-generation-locks.js +3 -1
  68. package/dist/services/chat-generation-locks.js.map +1 -1
  69. package/dist/services/chat-generation-protocol.d.ts +2 -0
  70. package/dist/services/chat-generation-protocol.d.ts.map +1 -1
  71. package/dist/services/chat-inline-annotations.test.js +34 -0
  72. package/dist/services/chat-inline-annotations.test.js.map +1 -1
  73. package/dist/services/chat-message-mutation-fingerprint.d.ts +46 -0
  74. package/dist/services/chat-message-mutation-fingerprint.d.ts.map +1 -0
  75. package/dist/services/chat-message-mutation-fingerprint.js +77 -0
  76. package/dist/services/chat-message-mutation-fingerprint.js.map +1 -0
  77. package/dist/services/chat-queued-message-materialization.d.ts +2 -2
  78. package/dist/services/chat-queued-message-materialization.d.ts.map +1 -1
  79. package/dist/services/chat-queued-message-materialization.js +2 -2
  80. package/dist/services/chat-queued-message-materialization.js.map +1 -1
  81. package/dist/services/chats.annotation-persistence.d.ts +8 -0
  82. package/dist/services/chats.annotation-persistence.d.ts.map +1 -1
  83. package/dist/services/chats.annotation-persistence.js +101 -5
  84. package/dist/services/chats.annotation-persistence.js.map +1 -1
  85. package/dist/services/chats.d.ts +8 -10
  86. package/dist/services/chats.d.ts.map +1 -1
  87. package/dist/services/chats.js +5 -2
  88. package/dist/services/chats.js.map +1 -1
  89. package/dist/services/chats.queued-message-create.d.ts +1 -0
  90. package/dist/services/chats.queued-message-create.d.ts.map +1 -1
  91. package/dist/services/chats.queued-message-create.js +2 -2
  92. package/dist/services/chats.queued-message-create.js.map +1 -1
  93. package/dist/services/chats.types.d.ts +3 -1
  94. package/dist/services/chats.types.d.ts.map +1 -1
  95. package/dist/services/delegation-runs.d.ts +41 -0
  96. package/dist/services/delegation-runs.d.ts.map +1 -0
  97. package/dist/services/delegation-runs.js +229 -0
  98. package/dist/services/delegation-runs.js.map +1 -0
  99. package/dist/services/delegation-runs.test.d.ts +2 -0
  100. package/dist/services/delegation-runs.test.d.ts.map +1 -0
  101. package/dist/services/delegation-runs.test.js +373 -0
  102. package/dist/services/delegation-runs.test.js.map +1 -0
  103. package/dist/services/issues.d.ts.map +1 -1
  104. package/dist/services/issues.helpers.d.ts +5 -0
  105. package/dist/services/issues.helpers.d.ts.map +1 -1
  106. package/dist/services/issues.helpers.js +11 -0
  107. package/dist/services/issues.helpers.js.map +1 -1
  108. package/dist/services/issues.js +6 -9
  109. package/dist/services/issues.js.map +1 -1
  110. package/dist/services/knowledge-portability/organization-skills.catalog.d.ts +1 -1
  111. package/dist/services/knowledge-portability/organization-skills.catalog.d.ts.map +1 -1
  112. package/dist/services/knowledge-portability/organization-skills.catalog.js +7 -0
  113. package/dist/services/knowledge-portability/organization-skills.catalog.js.map +1 -1
  114. package/dist/services/messenger-run-origin.d.ts +1 -0
  115. package/dist/services/messenger-run-origin.d.ts.map +1 -1
  116. package/dist/services/messenger-run-origin.js +1 -0
  117. package/dist/services/messenger-run-origin.js.map +1 -1
  118. package/dist/services/messenger.d.ts.map +1 -1
  119. package/dist/services/messenger.js +1 -0
  120. package/dist/services/messenger.js.map +1 -1
  121. package/dist/services/product-analytics-collector.test.js +5 -1
  122. package/dist/services/product-analytics-collector.test.js.map +1 -1
  123. package/dist/services/run-intelligence.d.ts.map +1 -1
  124. package/dist/services/run-intelligence.js +15 -1
  125. package/dist/services/run-intelligence.js.map +1 -1
  126. package/dist/services/runtime-kernel/assignment-run-guardrail.d.ts +12 -3
  127. package/dist/services/runtime-kernel/assignment-run-guardrail.d.ts.map +1 -1
  128. package/dist/services/runtime-kernel/assignment-run-guardrail.js +104 -7
  129. package/dist/services/runtime-kernel/assignment-run-guardrail.js.map +1 -1
  130. package/dist/services/runtime-kernel/assignment-run-guardrail.test.js +119 -3
  131. package/dist/services/runtime-kernel/assignment-run-guardrail.test.js.map +1 -1
  132. package/dist/services/runtime-kernel/heartbeat.core.d.ts +24 -2
  133. package/dist/services/runtime-kernel/heartbeat.core.d.ts.map +1 -1
  134. package/dist/services/runtime-kernel/heartbeat.core.js +12 -0
  135. package/dist/services/runtime-kernel/heartbeat.core.js.map +1 -1
  136. package/dist/services/runtime-kernel/heartbeat.d.ts +10 -0
  137. package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
  138. package/dist/services/runtime-kernel/heartbeat.execute.d.ts.map +1 -1
  139. package/dist/services/runtime-kernel/heartbeat.execute.js +97 -26
  140. package/dist/services/runtime-kernel/heartbeat.execute.js.map +1 -1
  141. package/dist/services/runtime-kernel/heartbeat.js +25 -19
  142. package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
  143. package/dist/services/runtime-kernel/heartbeat.misc.js +1 -1
  144. package/dist/services/runtime-kernel/heartbeat.misc.js.map +1 -1
  145. package/dist/services/runtime-kernel/heartbeat.recovery.d.ts +8 -0
  146. package/dist/services/runtime-kernel/heartbeat.recovery.d.ts.map +1 -1
  147. package/dist/services/runtime-kernel/heartbeat.recovery.js +124 -5
  148. package/dist/services/runtime-kernel/heartbeat.recovery.js.map +1 -1
  149. package/dist/services/runtime-kernel/heartbeat.release.d.ts.map +1 -1
  150. package/dist/services/runtime-kernel/heartbeat.release.js +1 -0
  151. package/dist/services/runtime-kernel/heartbeat.release.js.map +1 -1
  152. package/dist/services/runtime-kernel/heartbeat.sessions.d.ts.map +1 -1
  153. package/dist/services/runtime-kernel/heartbeat.sessions.js +2 -0
  154. package/dist/services/runtime-kernel/heartbeat.sessions.js.map +1 -1
  155. package/dist/services/runtime-kernel/heartbeat.terminal.d.ts +10 -1
  156. package/dist/services/runtime-kernel/heartbeat.terminal.d.ts.map +1 -1
  157. package/dist/services/runtime-kernel/heartbeat.terminal.js.map +1 -1
  158. package/dist/services/runtime-kernel/heartbeat.wakeup.d.ts.map +1 -1
  159. package/dist/services/runtime-kernel/heartbeat.wakeup.js +14 -1
  160. package/dist/services/runtime-kernel/heartbeat.wakeup.js.map +1 -1
  161. package/package.json +14 -14
  162. package/resources/bundled-skills/rudder-docs/references/cli-reference.md +1 -0
  163. package/skills/rudder-docs/references/cli-reference.md +1 -0
  164. package/ui-dist/assets/{LibraryLiveSurface-CbD9B2Jg.js → LibraryLiveSurface-BHneB__U.js} +1 -1
  165. package/ui-dist/assets/{abnfDiagram-VRR7QNED-BGfRZrl0.js → abnfDiagram-VRR7QNED-GUoY9rTt.js} +1 -1
  166. package/ui-dist/assets/{addon-fit--ip0m1eF.js → addon-fit-CqXXE0-1.js} +1 -1
  167. package/ui-dist/assets/{arc-BtiiHzBd.js → arc-BD7m_r6l.js} +1 -1
  168. package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-CblysKA0.js → architectureDiagram-ZJ3FMSHR-nEufXAY_.js} +1 -1
  169. package/ui-dist/assets/{blockDiagram-677ZJIJ3-DZUzthvF.js → blockDiagram-677ZJIJ3-D3qUEbL5.js} +1 -1
  170. package/ui-dist/assets/{c4Diagram-LMCZKHZV-Durmr5OS.js → c4Diagram-LMCZKHZV-7SPUxKgx.js} +1 -1
  171. package/ui-dist/assets/channel-Czz1OwXA.js +1 -0
  172. package/ui-dist/assets/{chunk-2Q5K7J3B-CzC-fYbH.js → chunk-2Q5K7J3B-6o3ETzOY.js} +1 -1
  173. package/ui-dist/assets/{chunk-32BRIVSS-D4A3SSYA.js → chunk-32BRIVSS-Efd566e8.js} +1 -1
  174. package/ui-dist/assets/{chunk-5VM5RSS4-IPYYyHit.js → chunk-5VM5RSS4-BA4X4gzU.js} +1 -1
  175. package/ui-dist/assets/{chunk-EX3LRPZG-CGdhATIq.js → chunk-EX3LRPZG-BD7K-mPD.js} +1 -1
  176. package/ui-dist/assets/{chunk-JWPE2WC7-CY08geUj.js → chunk-JWPE2WC7-DXv6iHxr.js} +1 -1
  177. package/ui-dist/assets/{chunk-MOJQB5TN-B0VR-_eb.js → chunk-MOJQB5TN-dQ6gk-_u.js} +1 -1
  178. package/ui-dist/assets/{chunk-RYQCIY6F-CwiPcDLW.js → chunk-RYQCIY6F-xEk6bTb7.js} +1 -1
  179. package/ui-dist/assets/{chunk-V7JOEXUC-CC4xQqDn.js → chunk-V7JOEXUC-zlvz5Y5q.js} +1 -1
  180. package/ui-dist/assets/{chunk-VR4S4FIN-fa3cKPyb.js → chunk-VR4S4FIN--zCSWk5F.js} +1 -1
  181. package/ui-dist/assets/{chunk-XXDRQBXY-B_uFpawt.js → chunk-XXDRQBXY-CZ2QWPRe.js} +1 -1
  182. package/ui-dist/assets/classDiagram-OUVF2IWQ-C_ooAkuA.js +1 -0
  183. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-C_ooAkuA.js +1 -0
  184. package/ui-dist/assets/{cose-bilkent-JH36ORCC-DfOcZUvm.js → cose-bilkent-JH36ORCC-DrRNgFzR.js} +1 -1
  185. package/ui-dist/assets/{cynefin-VYW2F7L2-BID948i0.js → cynefin-VYW2F7L2-T9PONuTh.js} +1 -1
  186. package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-BqvF2qjZ.js → cynefinDiagram-TSTJHNR4-Dkop4mS3.js} +1 -1
  187. package/ui-dist/assets/{dagre-VKFMJZFB-C5W_FyuW.js → dagre-VKFMJZFB-Chc8Imxx.js} +1 -1
  188. package/ui-dist/assets/{diagram-FQU43EPY-CutgooHd.js → diagram-FQU43EPY-n4pgnJYP.js} +1 -1
  189. package/ui-dist/assets/{diagram-G47NLZAW-CM16AG4F.js → diagram-G47NLZAW-DnjvVsj5.js} +1 -1
  190. package/ui-dist/assets/{diagram-NH7WQ7WH-CbXAmz5f.js → diagram-NH7WQ7WH-kHZ9astC.js} +1 -1
  191. package/ui-dist/assets/{diagram-OA4YK3LP-B_zLEkuk.js → diagram-OA4YK3LP-BAMly3yv.js} +1 -1
  192. package/ui-dist/assets/{diagram-WEI45ONY-s5JKRJa5.js → diagram-WEI45ONY-BTFQhBrp.js} +1 -1
  193. package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-B8MHJ46l.js → ebnfDiagram-CCIWWBDH-c2T4DORg.js} +1 -1
  194. package/ui-dist/assets/{erDiagram-Q63AITRT-dlFN6klQ.js → erDiagram-Q63AITRT-BXLi1JHT.js} +1 -1
  195. package/ui-dist/assets/{flowDiagram-23GEKE2U-CMEEUfRl.js → flowDiagram-23GEKE2U-CHzX7naH.js} +1 -1
  196. package/ui-dist/assets/{ganttDiagram-NO4QXBWP-RYdUNmeQ.js → ganttDiagram-NO4QXBWP-BqUKeoDF.js} +1 -1
  197. package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-BB5uby_3.js → gitGraphDiagram-IHSO6WYX-DM4K-DoE.js} +1 -1
  198. package/ui-dist/assets/{graph-CHqsk9a0.js → graph-BDejhZe_.js} +1 -1
  199. package/ui-dist/assets/{index-Dyal9gL0.js → index-B4zWD5-i.js} +1 -1
  200. package/ui-dist/assets/{index-DAVSGjLA.js → index-BJ-hTdyx.js} +1 -1
  201. package/ui-dist/assets/{index-Y7wKGA2n.js → index-BN90mN5Z.js} +1 -1
  202. package/ui-dist/assets/{index-C7bvI53l.js → index-Bni14R_J.js} +1 -1
  203. package/ui-dist/assets/index-BsB7Sc7m.css +32 -0
  204. package/ui-dist/assets/{index-CFQElZYx.js → index-BuCCxdIU.js} +1 -1
  205. package/ui-dist/assets/{index-DmawwuDA.js → index-CH8tOJZ9.js} +1 -1
  206. package/ui-dist/assets/{index-Io44HJHg.js → index-CIbvFYbV.js} +1 -1
  207. package/ui-dist/assets/{index-0b2QvaiP.js → index-CV0k_zvK.js} +1 -1
  208. package/ui-dist/assets/{index-CkCTdyQB.js → index-DAM3EGbv.js} +1 -1
  209. package/ui-dist/assets/{index-CQfL7Zs4.js → index-DHzaZSPM.js} +634 -633
  210. package/ui-dist/assets/{index-F9rBxffQ.js → index-DSAl1a-M.js} +1 -1
  211. package/ui-dist/assets/{index-CMRNQHWA.js → index-DVDu5Nwd.js} +1 -1
  212. package/ui-dist/assets/{index-D6KvRwFm.js → index-DZBZIqJI.js} +1 -1
  213. package/ui-dist/assets/{index-Cv41zOKL.js → index-WbyFmgaS.js} +1 -1
  214. package/ui-dist/assets/{index-jiYIDst0.js → index-XnCv8P5f.js} +1 -1
  215. package/ui-dist/assets/{infoDiagram-FWYZ7A6U-DTjJ4G6b.js → infoDiagram-FWYZ7A6U-PcFBrZTu.js} +1 -1
  216. package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-CYEQju_T.js → ishikawaDiagram-FXEZZL3T-BF2qBweH.js} +1 -1
  217. package/ui-dist/assets/{journeyDiagram-5HDEW3XC-CjAZvQIh.js → journeyDiagram-5HDEW3XC-D3TqAoEB.js} +1 -1
  218. package/ui-dist/assets/{kanban-definition-HUTT4EX6-DpopB0pg.js → kanban-definition-HUTT4EX6-CUiHrckR.js} +1 -1
  219. package/ui-dist/assets/{layout-zLRJSNuB.js → layout-DMKAzTyC.js} +1 -1
  220. package/ui-dist/assets/{linear-DvemTimo.js → linear-D8C0WdTA.js} +1 -1
  221. package/ui-dist/assets/{map-Bls8mI9F.js → map-DUCHGq8e.js} +1 -1
  222. package/ui-dist/assets/{mermaid.core-Cr_nLldI.js → mermaid.core-C-eoqr77.js} +4 -4
  223. package/ui-dist/assets/{mindmap-definition-LN4V7U3C-CYQI0O1_.js → mindmap-definition-LN4V7U3C-B54nV_Hu.js} +1 -1
  224. package/ui-dist/assets/{pegDiagram-2B236MQR-D4ZufqLz.js → pegDiagram-2B236MQR-CcIDNzTo.js} +1 -1
  225. package/ui-dist/assets/{pieDiagram-ENE6RG2P-Cp9_BLOv.js → pieDiagram-ENE6RG2P-BU4swrSE.js} +1 -1
  226. package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-D3vG5dG8.js → quadrantDiagram-ABIIQ3AL-CnniDL18.js} +1 -1
  227. package/ui-dist/assets/{railroadDiagram-RFXS5EU6-ajkkn6FI.js → railroadDiagram-RFXS5EU6-CiBY7wpV.js} +1 -1
  228. package/ui-dist/assets/{requirementDiagram-TGXJPOKE-ClXp9KU7.js → requirementDiagram-TGXJPOKE-C7c_tTqS.js} +1 -1
  229. package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-DZgfcF8o.js → sankeyDiagram-HTMAVEWB-DJuTS99d.js} +1 -1
  230. package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-_zoarL3b.js → sequenceDiagram-DBY2YBRQ-BxhtY70W.js} +1 -1
  231. package/ui-dist/assets/{sizeCapture-X5ZJPWSS-Bf9ESdZs.js → sizeCapture-X5ZJPWSS-0A0Kww03.js} +1 -1
  232. package/ui-dist/assets/{stateDiagram-2N3HPSRC-C3CX2N_K.js → stateDiagram-2N3HPSRC-DPw4bytW.js} +1 -1
  233. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-ANI7JZ72.js +1 -0
  234. package/ui-dist/assets/{swimlanes-5IMT3BWC-DBx4Yd1a.js → swimlanes-5IMT3BWC-D6MMDWrs.js} +2 -2
  235. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-CxjGCcz5.js +8 -0
  236. package/ui-dist/assets/{timeline-definition-FHXFAJF6-BQd4WmPY.js → timeline-definition-FHXFAJF6-gNKDUxQx.js} +1 -1
  237. package/ui-dist/assets/{vennDiagram-L72KCM5P-C52MuYHI.js → vennDiagram-L72KCM5P-BpZCM-ST.js} +1 -1
  238. package/ui-dist/assets/{wardleyDiagram-EHGQE667-Cb_8DNud.js → wardleyDiagram-EHGQE667-CvR0dYqn.js} +1 -1
  239. package/ui-dist/assets/{xterm-FmL4hGL4.js → xterm-CEksOm0P.js} +1 -1
  240. package/ui-dist/assets/{xychartDiagram-FW5EYKEG-BT_-q9dc.js → xychartDiagram-FW5EYKEG-C6_4sxeI.js} +1 -1
  241. package/ui-dist/index.html +11 -7
  242. package/ui-dist/assets/channel-DtMg64x5.js +0 -1
  243. package/ui-dist/assets/classDiagram-OUVF2IWQ-Dhm6vJZV.js +0 -1
  244. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-Dhm6vJZV.js +0 -1
  245. package/ui-dist/assets/index-CYaeM_68.css +0 -32
  246. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-Dk-0Ax2u.js +0 -1
  247. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-BPKbu0D2.js +0 -8
@@ -1,4 +1,4 @@
1
- import { addChatMessageSchema, chatClientCheckpointSchema, chatInlineAnnotationsFromStructuredPayload, convertChatToIssueSchema, createChatAttachmentMetadataSchema, createChatContextLinkSchema, createChatFirstTurnSchema, resolveChatOperationProposalSchema, setChatProjectContextSchema, stopChatGenerationSchema, } from "@rudderhq/shared";
1
+ import { addChatMessageSchema, chatClientCheckpointSchema, chatInlineAnnotationsFromStructuredPayload, convertChatToIssueSchema, createChatAttachmentMetadataSchema, createChatContextLinkSchema, createChatFirstTurnSchema, resolveChatOperationProposalSchema, setChatProjectContextSchema, } from "@rudderhq/shared";
2
2
  import { coalesceChatTranscriptTextEntries, withChatTranscriptGenerationProvenance, } from "@rudderhq/shared/chat-transcript-provenance";
3
3
  import multer from "multer";
4
4
  import { randomUUID } from "node:crypto";
@@ -8,13 +8,15 @@ import { logger } from "../middleware/logger.js";
8
8
  import { validate } from "../middleware/validate.js";
9
9
  import { chatAssistantErrorForLog } from "../services/chat-assistant.helpers.js";
10
10
  import { CHAT_ASSISTANT_USER_ERROR_MESSAGE, ChatAssistantStreamError, userVisiblePartialBodyFromError } from "../services/chat-assistant.js";
11
- import { cancelActiveChatGeneration, claimChatGeneration, createChatRuntimeControlCoordinator, getActiveChatGeneration, setActiveChatGenerationId, } from "../services/chat-generation-locks.js";
11
+ import { claimChatGeneration, createChatRuntimeControlCoordinator, getActiveChatGeneration, setActiveChatGenerationId, } from "../services/chat-generation-locks.js";
12
12
  import { hashChatGenerationBody } from "../services/chat-generation-protocol.js";
13
+ import { replayChatStreamMessage } from "../services/chat-message-mutation-fingerprint.js";
13
14
  import { logActivity } from "../services/index.js";
14
15
  import { assertCompanyAccess, getActorInfo } from "./authz.js";
15
16
  import { wakeIssueAssigneeAfterChatConversion } from "./chat-issue-assignment-wakeup.js";
16
17
  import { chatRuntimeSnapshot } from "./chats.runtime-controls.js";
17
- import { CHAT_ASSISTANT_RECOVERABLE_FAILURE_FALLBACK_MESSAGE, CHAT_ASSISTANT_STOPPED_FALLBACK_MESSAGE, createChatStreamFileStaging, createStartingChatGenerationGate, normalizeMultipartFirstTurnBody, normalizeMultipartMessageBody, outputAdmissionClosed, resolveStoppedAssistantState, startingChatGenerationGates, withMergedChatMessageAttachments, } from "./chats.stream-support.js";
18
+ import { registerChatStopRoute } from "./chats.stop-route.js";
19
+ import { CHAT_ASSISTANT_RECOVERABLE_FAILURE_FALLBACK_MESSAGE, CHAT_ASSISTANT_STOPPED_FALLBACK_MESSAGE, createChatStreamFileStaging, createStartingChatGenerationGate, normalizeMultipartFirstTurnBody, normalizeMultipartMessageBody, outputAdmissionClosed, persistChatStreamUserMessageBeforeGeneration, resolveStoppedAssistantState, startingChatGenerationGates, withMergedChatMessageAttachments, } from "./chats.stream-support.js";
18
20
  import { registerChatUserStateRoutes } from "./chats.user-state-routes.js";
19
21
  export function registerChatStreamRoutes(ctx) {
20
22
  const { router, db, storage, svc, assistantSvc, agentsSvc, issuesSvc, projectsSvc, goalsSvc, access, operatorProfiles, heartbeat, assertConversationAccess, assertChatLocalMutationAllowed, assertSideChatMutationAllowed, touchSideChat, boardUserId, assertCanAssignTasks, runSingleFileUpload, runMessageFileUpload, isMultipartRequest, uploadedMessageFiles, validateUploadedMessageFiles, preflightChatDraft, logChatMessagesAdded, assertContextLinksBelongToCompany, turnContextFromUserMessage, addUserMessage, inlineAnnotations, storeUserMessageFiles, cleanupStoredUserMessageFiles, storeQueuedAnnotationFiles, cleanupUncommittedQueuedAnnotationFiles, startChatTitleGeneration, attachFilesToUserMessage, loadAssistantInput, chatReplyingAgentId, assertCanConvertIssueProposal, persistAssistantReply, linkChatRunMessages, attachGeneratedFilesToPartialMessage, persistPartialAssistantMessage, recoverableFailurePayload, recoverableFailureBody, writeStreamEvent, queueRequestActor, wakeServerQueue, wakeTerminalProjector, } = ctx;
@@ -75,6 +77,25 @@ export function registerChatStreamRoutes(ctx) {
75
77
  });
76
78
  return;
77
79
  }
80
+ const clientMutationId = parsedBody.data.clientMutationId ?? null;
81
+ const clientMutationFingerprint = await replayChatStreamMessage({
82
+ atomicFirstTurn: Boolean(atomicFirstTurn),
83
+ clientMutationId,
84
+ body: parsedBody.data.body,
85
+ editUserMessageId: parsedBody.data.editUserMessageId,
86
+ inlineAnnotationsProvided,
87
+ inlineAnnotations: parsedBody.data.inlineAnnotations,
88
+ modelOverride: parsedBody.data.modelOverride,
89
+ effortOverride: parsedBody.data.effortOverride,
90
+ files: messageFiles,
91
+ orgId: conversation.orgId,
92
+ conversationId: conversation.id,
93
+ lookup: svc.getUserMessageMutationByClientMutationId,
94
+ response: res,
95
+ writeStreamEvent,
96
+ });
97
+ if (clientMutationFingerprint === undefined)
98
+ return;
78
99
  const preparedAnnotations = !atomicFirstTurn && inlineAnnotationsProvided
79
100
  ? await inlineAnnotations.prepare({
80
101
  orgId: conversation.orgId,
@@ -107,7 +128,7 @@ export function registerChatStreamRoutes(ctx) {
107
128
  if (!runtimeSnapshot)
108
129
  throw new Error("Chat runtime snapshot is unavailable");
109
130
  const abortController = new AbortController();
110
- const releaseGeneration = claimChatGeneration(conversation.id, abortController, null);
131
+ const releaseGeneration = claimChatGeneration(conversation.id, abortController, null, clientMutationId);
111
132
  if (!releaseGeneration) {
112
133
  if (parsedBody.data.editUserMessageId) {
113
134
  res.status(409).json({ error: "Stop the current response before editing this message" });
@@ -117,14 +138,22 @@ export function registerChatStreamRoutes(ctx) {
117
138
  res.status(409).json({ error: "A chat reply is already being generated for this conversation" });
118
139
  return;
119
140
  }
120
- const clientMutationId = `stream:${randomUUID()}`;
141
+ const activeGeneration = getActiveChatGeneration(conversation.id);
142
+ if (clientMutationId && activeGeneration?.clientMutationId === clientMutationId) {
143
+ throw conflict("This message is already being sent. Try again shortly.", {
144
+ code: "chat_send_in_progress",
145
+ phase: "message_acceptance",
146
+ });
147
+ }
148
+ const queueClientMutationId = clientMutationId ?? `stream:${randomUUID()}`;
121
149
  const storedQueueFiles = await storeQueuedAnnotationFiles(conversation, messageFiles);
122
150
  let queuedResult;
123
151
  try {
124
152
  queuedResult = await svc.createQueuedMessageWithStagedAttachments({
125
153
  orgId: conversation.orgId,
126
154
  conversationId: conversation.id,
127
- clientMutationId,
155
+ clientMutationId: queueClientMutationId,
156
+ mutationFingerprint: clientMutationFingerprint ?? undefined,
128
157
  runtimeSnapshotVersion: 1,
129
158
  expectedGenerationId: getActiveChatGeneration(conversation.id)?.generationId ?? null,
130
159
  requestActor: queueRequestActor(req),
@@ -152,10 +181,10 @@ export function registerChatStreamRoutes(ctx) {
152
181
  });
153
182
  }
154
183
  catch (error) {
155
- await cleanupUncommittedQueuedAnnotationFiles(conversation.orgId, clientMutationId, storedQueueFiles);
184
+ await cleanupUncommittedQueuedAnnotationFiles(conversation.orgId, queueClientMutationId, storedQueueFiles);
156
185
  throw error;
157
186
  }
158
- await cleanupUncommittedQueuedAnnotationFiles(conversation.orgId, clientMutationId, queuedResult.cleanupAttachments);
187
+ await cleanupUncommittedQueuedAnnotationFiles(conversation.orgId, queueClientMutationId, queuedResult.cleanupAttachments);
159
188
  const item = queuedResult.item;
160
189
  const queuedAnnotations = (item.payload.inlineAnnotations ?? []);
161
190
  await logActivity(db, {
@@ -209,22 +238,45 @@ export function registerChatStreamRoutes(ctx) {
209
238
  }
210
239
  const startupGate = createStartingChatGenerationGate();
211
240
  startingChatGenerationGates.set(conversation.id, startupGate);
212
- if (queuedMessageId) {
213
- try {
214
- await svc.assertQueuedMessageClaimedForDelivery({
215
- conversationId: conversation.id,
216
- itemId: queuedMessageId,
217
- body: parsedBody.data.body,
218
- });
219
- }
220
- catch (error) {
221
- startupGate.resolveGeneration(null);
222
- startingChatGenerationGates.delete(conversation.id);
223
- releaseGeneration();
224
- await stagedMessageFiles.cleanup();
225
- throw error;
226
- }
241
+ const messagePersistence = await persistChatStreamUserMessageBeforeGeneration({
242
+ atomicFirstTurn,
243
+ queuedMessageId,
244
+ conversation: conversation,
245
+ body: parsedBody.data.body,
246
+ editUserMessageId: parsedBody.data.editUserMessageId ?? null,
247
+ preparedAnnotations,
248
+ inlineAnnotationsProvided,
249
+ clientMutationId,
250
+ clientMutationFingerprint,
251
+ svc,
252
+ addUserMessage,
253
+ actor,
254
+ startupGate,
255
+ releaseGeneration,
256
+ stagedMessageFiles,
257
+ });
258
+ if (messagePersistence.kind === "error") {
259
+ logger.warn({ err: chatAssistantErrorForLog(messagePersistence.error), conversationId: conversation.id }, "chat user-message persistence failed before generation");
260
+ res.status(201);
261
+ res.setHeader("Content-Type", "application/x-ndjson; charset=utf-8");
262
+ res.setHeader("Cache-Control", "no-cache, no-transform");
263
+ res.setHeader("X-Accel-Buffering", "no");
264
+ writeStreamEvent(res, { type: "error", error: CHAT_ASSISTANT_USER_ERROR_MESSAGE, messageId: messagePersistence.messageId });
265
+ res.end();
266
+ return;
267
+ }
268
+ if (messagePersistence.kind === "replayed") {
269
+ res.status(200);
270
+ res.setHeader("Content-Type", "application/x-ndjson; charset=utf-8");
271
+ res.setHeader("Cache-Control", "no-cache, no-transform");
272
+ res.setHeader("X-Accel-Buffering", "no");
273
+ writeStreamEvent(res, { type: "ack", userMessage: messagePersistence.message });
274
+ writeStreamEvent(res, { type: "final", messages: [] });
275
+ res.end();
276
+ return;
227
277
  }
278
+ let { userMessagePersisted, committedUserMessageId } = messagePersistence;
279
+ const persistedUserMessage = messagePersistence.userMessage;
228
280
  let generation = null;
229
281
  try {
230
282
  const createdGeneration = await svc.createGeneration(conversation.orgId, conversation.id);
@@ -237,42 +289,39 @@ export function registerChatStreamRoutes(ctx) {
237
289
  startingChatGenerationGates.delete(conversation.id);
238
290
  releaseGeneration();
239
291
  await stagedMessageFiles.cleanup();
240
- if (atomicFirstTurn) {
241
- const failurePayload = recoverableFailurePayload(error, null);
242
- const failureBody = recoverableFailureBody(failurePayload) || CHAT_ASSISTANT_RECOVERABLE_FAILURE_FALLBACK_MESSAGE;
243
- const failedMessage = await svc.addMessage(conversation.id, {
244
- orgId: conversation.orgId,
245
- role: "assistant",
246
- kind: "message",
247
- status: "failed",
248
- body: failureBody,
249
- structuredPayload: failurePayload,
250
- replyingAgentId: conversation.preferredAgentId,
251
- chatTurnId: atomicFirstTurn.userMessage.chatTurnId,
252
- });
253
- await logChatMessagesAdded(conversation, [failedMessage], {
254
- actorType: "system",
255
- actorId: "chat-assistant",
256
- agentId: conversation.preferredAgentId,
257
- });
258
- res.status(201);
259
- res.setHeader("Content-Type", "application/x-ndjson; charset=utf-8");
260
- res.setHeader("Cache-Control", "no-cache, no-transform");
261
- res.setHeader("X-Accel-Buffering", "no");
262
- writeStreamEvent(res, {
263
- type: "ack",
264
- conversation: atomicFirstTurn.conversation,
265
- userMessage: atomicFirstTurn.userMessage,
266
- });
267
- writeStreamEvent(res, {
268
- type: "error",
269
- error: failureBody,
270
- messageId: failedMessage.id,
271
- });
272
- res.end();
273
- return;
274
- }
275
- throw error;
292
+ const failurePayload = recoverableFailurePayload(error, null);
293
+ const failureBody = recoverableFailureBody(failurePayload) || CHAT_ASSISTANT_RECOVERABLE_FAILURE_FALLBACK_MESSAGE;
294
+ const failedMessage = await svc.addMessage(conversation.id, {
295
+ orgId: conversation.orgId,
296
+ role: "assistant",
297
+ kind: "message",
298
+ status: "failed",
299
+ body: failureBody,
300
+ structuredPayload: failurePayload,
301
+ replyingAgentId: conversation.preferredAgentId,
302
+ chatTurnId: persistedUserMessage.chatTurnId,
303
+ });
304
+ await logChatMessagesAdded(conversation, [failedMessage], {
305
+ actorType: "system",
306
+ actorId: "chat-assistant",
307
+ agentId: conversation.preferredAgentId,
308
+ });
309
+ res.status(201);
310
+ res.setHeader("Content-Type", "application/x-ndjson; charset=utf-8");
311
+ res.setHeader("Cache-Control", "no-cache, no-transform");
312
+ res.setHeader("X-Accel-Buffering", "no");
313
+ writeStreamEvent(res, {
314
+ type: "ack",
315
+ ...(atomicFirstTurn ? { conversation: atomicFirstTurn.conversation } : {}),
316
+ userMessage: persistedUserMessage,
317
+ });
318
+ writeStreamEvent(res, {
319
+ type: "error",
320
+ error: failureBody,
321
+ messageId: failedMessage.id,
322
+ });
323
+ res.end();
324
+ return;
276
325
  }
277
326
  if (abortController.signal.aborted && startupGate.stopRequested) {
278
327
  await startupGate.stopApplied;
@@ -282,8 +331,6 @@ export function registerChatStreamRoutes(ctx) {
282
331
  const transcript = [];
283
332
  let assistantProgressMessageId = null;
284
333
  let activeChatRunId = null;
285
- let userMessagePersisted = Boolean(atomicFirstTurn);
286
- let committedUserMessageId = atomicFirstTurn?.userMessage.id ?? null;
287
334
  let generationTerminalStatus = "failed";
288
335
  let generationWaitingForNetwork = false;
289
336
  let admittedAssistantBody = "";
@@ -382,16 +429,7 @@ export function registerChatStreamRoutes(ctx) {
382
429
  res.setHeader("X-Accel-Buffering", "no");
383
430
  res.flushHeaders();
384
431
  try {
385
- let userMessage = atomicFirstTurn?.userMessage ?? await addUserMessage(conversation, parsedBody.data.body, actor, parsedBody.data.editUserMessageId ?? null, {
386
- provided: inlineAnnotationsProvided,
387
- prepared: preparedAnnotations,
388
- storedAttachments: stagedMessageFiles.files,
389
- onPersisted: (messageId) => {
390
- userMessagePersisted = true;
391
- committedUserMessageId = messageId;
392
- stagedMessageFiles.markCommitted();
393
- },
394
- });
432
+ let userMessage = persistedUserMessage;
395
433
  userMessagePersisted = true;
396
434
  committedUserMessageId = userMessage.id;
397
435
  stagedMessageFiles.markCommitted();
@@ -957,237 +995,7 @@ export function registerChatStreamRoutes(ctx) {
957
995
  advanced: checkpoint.advanced,
958
996
  });
959
997
  });
960
- router.post("/chats/:id/messages/stream/stop", async (req, res) => {
961
- const parsed = stopChatGenerationSchema.safeParse(req.body ?? {});
962
- if (!parsed.success) {
963
- res.status(400).json({ error: "Invalid chat Stop request", details: parsed.error.issues });
964
- return;
965
- }
966
- const conversation = await assertConversationAccess(req, req.params.id);
967
- if (!conversation) {
968
- res.status(404).json({ error: "Chat conversation not found" });
969
- return;
970
- }
971
- assertChatLocalMutationAllowed(conversation);
972
- await assertSideChatMutationAllowed(req, conversation);
973
- const controlActionId = parsed.data.controlActionId ?? randomUUID();
974
- const startupGate = startingChatGenerationGates.get(conversation.id) ?? null;
975
- let startupStopRequested = false;
976
- let startupInterruptRequested = false;
977
- try {
978
- let active = getActiveChatGeneration(conversation.id);
979
- if (active && !active.generationId && startupGate) {
980
- startupStopRequested = true;
981
- startupGate.stopRequested = true;
982
- startupInterruptRequested = cancelActiveChatGeneration(conversation.id);
983
- const startupGenerationId = await startupGate.generationReady;
984
- active = startupGenerationId ? getActiveChatGeneration(conversation.id) : null;
985
- if (!startupGenerationId) {
986
- res.json({
987
- stopped: startupInterruptRequested,
988
- controlActionId,
989
- generationId: null,
990
- disposition: startupInterruptRequested ? "startup_cancelled" : "interrupted_unverified",
991
- });
992
- return;
993
- }
994
- }
995
- const latestActiveGeneration = active?.generationId
996
- ? null
997
- : await svc.getLatestActiveGeneration(conversation.id);
998
- const generationId = parsed.data.expectedGenerationId
999
- ?? active?.generationId
1000
- ?? latestActiveGeneration?.id
1001
- ?? null;
1002
- if (!generationId) {
1003
- res.json({
1004
- stopped: false,
1005
- controlActionId,
1006
- generationId: null,
1007
- disposition: "no_active_generation",
1008
- });
1009
- return;
1010
- }
1011
- let durableCheckpoint = await svc.generationProtocol.getLatestVisibleCheckpoint({
1012
- orgId: conversation.orgId,
1013
- conversationId: conversation.id,
1014
- generationId,
1015
- });
1016
- if (durableCheckpoint.generation.runtimeTerminalAt && !parsed.data.controlActionId) {
1017
- wakeTerminalProjector();
1018
- res.json({
1019
- stopped: false,
1020
- controlActionId,
1021
- generationId,
1022
- disposition: "no_active_generation",
1023
- });
1024
- return;
1025
- }
1026
- const expectedAttemptEpoch = parsed.data.expectedAttemptEpoch
1027
- ?? durableCheckpoint.generation.attemptEpoch;
1028
- const requestedControlVersion = parsed.data.expectedControlVersion
1029
- ?? durableCheckpoint.generation.controlVersion;
1030
- const requestedRenderSeq = parsed.data.lastCommittedRenderSeq
1031
- ?? durableCheckpoint.generationSeq;
1032
- const requestedBodyHash = parsed.data.renderedBodyHash
1033
- ?? durableCheckpoint.bodyHash;
1034
- let stop = null;
1035
- for (let attempt = 0; attempt < 2 && !stop; attempt += 1) {
1036
- try {
1037
- stop = await svc.generationProtocol.beginStopAction({
1038
- orgId: conversation.orgId,
1039
- conversationId: conversation.id,
1040
- controlActionId,
1041
- expectedGenerationId: generationId,
1042
- expectedAttemptEpoch,
1043
- expectedControlVersion: requestedControlVersion,
1044
- admissionControlVersion: attempt === 0
1045
- ? requestedControlVersion
1046
- : durableCheckpoint.generation.controlVersion,
1047
- requestedRenderSeq,
1048
- requestedBodyHash,
1049
- });
1050
- }
1051
- catch (error) {
1052
- const status = error && typeof error === "object" && "status" in error
1053
- ? Number(error.status)
1054
- : null;
1055
- if (attempt > 0 || status !== 409)
1056
- throw error;
1057
- durableCheckpoint = await svc.generationProtocol.getLatestVisibleCheckpoint({
1058
- orgId: conversation.orgId,
1059
- conversationId: conversation.id,
1060
- generationId,
1061
- });
1062
- if (durableCheckpoint.generation.runtimeTerminalAt && !parsed.data.controlActionId) {
1063
- wakeTerminalProjector();
1064
- res.json({
1065
- stopped: false,
1066
- controlActionId,
1067
- generationId,
1068
- disposition: "no_active_generation",
1069
- });
1070
- return;
1071
- }
1072
- if (durableCheckpoint.generation.attemptEpoch !== expectedAttemptEpoch)
1073
- throw error;
1074
- }
1075
- }
1076
- if (!stop)
1077
- throw new Error("Failed to establish the chat Stop cutoff");
1078
- const wasWaitingForNetwork = durableCheckpoint.generation.status === "waiting_for_network";
1079
- if (stop.idempotent
1080
- && parsed.data.expectedControlVersion !== undefined
1081
- && stop.action.expectedControlVersion !== parsed.data.expectedControlVersion) {
1082
- throw conflict("Control action id was already used for a different Stop request");
1083
- }
1084
- if (stop.outcome === "completion_committed") {
1085
- res.json({
1086
- stopped: false,
1087
- controlActionId,
1088
- generationId,
1089
- disposition: "completion_committed",
1090
- });
1091
- return;
1092
- }
1093
- if (stop.outcome === "already_terminal") {
1094
- const alreadyStopped = stop.generation.status === "stopped"
1095
- || stop.action.localDisposition === "stopped";
1096
- wakeTerminalProjector();
1097
- res.json({
1098
- stopped: alreadyStopped,
1099
- controlActionId,
1100
- generationId,
1101
- disposition: alreadyStopped ? "stopped" : "no_active_generation",
1102
- acceptedThroughSeq: stop.action.acceptedThroughSeq,
1103
- frozenBodyHash: stop.action.frozenBodyHash,
1104
- });
1105
- return;
1106
- }
1107
- if (stop.outcome === "stop_in_progress" && !stop.generation.runtimeTerminalAt) {
1108
- const localInterruptRequested = startupInterruptRequested || cancelActiveChatGeneration(conversation.id);
1109
- res.json({
1110
- stopped: Boolean(localInterruptRequested),
1111
- controlActionId,
1112
- generationId,
1113
- disposition: "stopping",
1114
- acceptedThroughSeq: stop.action.acceptedThroughSeq,
1115
- frozenBodyHash: stop.action.frozenBodyHash,
1116
- });
1117
- return;
1118
- }
1119
- if (stop.idempotent && stop.generation.runtimeTerminalAt) {
1120
- const terminalDisposition = stop.generation.status === "stopped"
1121
- || stop.action.localDisposition === "stopped"
1122
- ? "stopped"
1123
- : "stopping";
1124
- wakeTerminalProjector();
1125
- res.json({
1126
- stopped: true,
1127
- controlActionId,
1128
- generationId,
1129
- disposition: terminalDisposition,
1130
- acceptedThroughSeq: stop.action.acceptedThroughSeq,
1131
- frozenBodyHash: stop.action.frozenBodyHash,
1132
- });
1133
- return;
1134
- }
1135
- const localInterruptRequested = startupInterruptRequested || cancelActiveChatGeneration(conversation.id);
1136
- let stopped = Boolean(localInterruptRequested);
1137
- let disposition = "stopping";
1138
- if (startupStopRequested) {
1139
- await svc.generationProtocol.recordRuntimeTerminal({
1140
- orgId: conversation.orgId,
1141
- conversationId: conversation.id,
1142
- generationId,
1143
- expectedAttemptEpoch: stop.generation.attemptEpoch,
1144
- finalStatus: "stopped",
1145
- terminalReason: "operator_stop",
1146
- controlActionId,
1147
- });
1148
- wakeTerminalProjector();
1149
- }
1150
- else if (wasWaitingForNetwork) {
1151
- stopped = true;
1152
- disposition = "stopped";
1153
- await svc.generationProtocol.recordRuntimeTerminal({
1154
- orgId: conversation.orgId,
1155
- conversationId: conversation.id,
1156
- generationId,
1157
- expectedAttemptEpoch: stop.generation.attemptEpoch,
1158
- finalStatus: "stopped",
1159
- terminalReason: "operator_stop",
1160
- controlActionId,
1161
- });
1162
- wakeTerminalProjector();
1163
- }
1164
- else if (!localInterruptRequested) {
1165
- disposition = "interrupted_unverified";
1166
- await svc.generationProtocol.recordRuntimeTerminal({
1167
- orgId: conversation.orgId,
1168
- conversationId: conversation.id,
1169
- generationId,
1170
- expectedAttemptEpoch: stop.generation.attemptEpoch,
1171
- finalStatus: "interrupted_unverified",
1172
- terminalReason: "stop_without_local_runtime_owner",
1173
- controlActionId,
1174
- });
1175
- wakeTerminalProjector();
1176
- }
1177
- res.json({
1178
- stopped,
1179
- controlActionId,
1180
- generationId,
1181
- disposition,
1182
- acceptedThroughSeq: stop.action.acceptedThroughSeq,
1183
- frozenBodyHash: stop.action.frozenBodyHash,
1184
- });
1185
- }
1186
- finally {
1187
- if (startupStopRequested)
1188
- startupGate?.resolveStopApplied();
1189
- }
1190
- });
998
+ registerChatStopRoute(ctx);
1191
999
  router.post("/orgs/:orgId/chats/:chatId/attachments", async (req, res) => {
1192
1000
  const orgId = req.params.orgId;
1193
1001
  const chatId = req.params.chatId;