@flamingo-stack/openframe-frontend-core 0.0.497 → 0.0.498-1506.4000.1

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 (285) hide show
  1. package/dist/chat-protocol/decode.d.ts +58 -0
  2. package/dist/chat-protocol/decode.d.ts.map +1 -0
  3. package/dist/chat-protocol/encode.d.ts +44 -0
  4. package/dist/chat-protocol/encode.d.ts.map +1 -0
  5. package/dist/chat-protocol/env-flag.d.ts +35 -0
  6. package/dist/chat-protocol/env-flag.d.ts.map +1 -0
  7. package/dist/chat-protocol/events.d.ts +207 -0
  8. package/dist/chat-protocol/events.d.ts.map +1 -0
  9. package/dist/chat-protocol/frames.d.ts +213 -0
  10. package/dist/chat-protocol/frames.d.ts.map +1 -0
  11. package/dist/chat-protocol/index.cjs +500 -0
  12. package/dist/chat-protocol/index.cjs.map +1 -0
  13. package/dist/chat-protocol/index.d.ts +18 -0
  14. package/dist/chat-protocol/index.d.ts.map +1 -0
  15. package/dist/chat-protocol/index.js +484 -0
  16. package/dist/chat-protocol/index.js.map +1 -0
  17. package/dist/chat-protocol/ip-normalize.d.ts +44 -0
  18. package/dist/chat-protocol/ip-normalize.d.ts.map +1 -0
  19. package/dist/chat-protocol/nats-decoder.d.ts +26 -0
  20. package/dist/chat-protocol/nats-decoder.d.ts.map +1 -0
  21. package/dist/{chunk-2DER2JSI.cjs → chunk-242K7LZY.cjs} +11 -11
  22. package/dist/{chunk-2DER2JSI.cjs.map → chunk-242K7LZY.cjs.map} +1 -1
  23. package/dist/{chunk-VBSS4TPV.cjs → chunk-2LYA3RBT.cjs} +37 -37
  24. package/dist/{chunk-VBSS4TPV.cjs.map → chunk-2LYA3RBT.cjs.map} +1 -1
  25. package/dist/{chunk-ZPUCCSYA.js → chunk-34C2JV2C.js} +2 -2
  26. package/dist/{chunk-GWVNRXJU.js → chunk-3VGRZ62V.js} +2 -2
  27. package/dist/{chunk-AAHAVML2.js → chunk-42NYDEHH.js} +2 -2
  28. package/dist/{chunk-ZEHA4IC7.js → chunk-42SMPKGY.js} +2 -2
  29. package/dist/{chunk-RTG5DJWM.cjs → chunk-44C23SSC.cjs} +5 -5
  30. package/dist/{chunk-RTG5DJWM.cjs.map → chunk-44C23SSC.cjs.map} +1 -1
  31. package/dist/{chunk-SL62IZ3I.cjs → chunk-4KKGHPNE.cjs} +9 -9
  32. package/dist/{chunk-SL62IZ3I.cjs.map → chunk-4KKGHPNE.cjs.map} +1 -1
  33. package/dist/{chunk-X2CYUCGL.cjs → chunk-5BQWVNRS.cjs} +62 -62
  34. package/dist/{chunk-X2CYUCGL.cjs.map → chunk-5BQWVNRS.cjs.map} +1 -1
  35. package/dist/{chunk-HRUXC3YN.js → chunk-5QWYIPMH.js} +2 -2
  36. package/dist/{chunk-NT3BKPEC.js → chunk-5ZY5JM4Z.js} +10 -10
  37. package/dist/chunk-5ZY5JM4Z.js.map +1 -0
  38. package/dist/{chunk-4C764VBX.cjs → chunk-62TM2RVZ.cjs} +26 -26
  39. package/dist/{chunk-4C764VBX.cjs.map → chunk-62TM2RVZ.cjs.map} +1 -1
  40. package/dist/{chunk-YBTYHIXA.js → chunk-632XJ2ZT.js} +6 -5
  41. package/dist/chunk-632XJ2ZT.js.map +1 -0
  42. package/dist/{chunk-DGDUOFNY.js → chunk-BUBQEZ5J.js} +2 -2
  43. package/dist/{chunk-ZAAIVSX6.js → chunk-D3LUKR2Y.js} +11964 -9714
  44. package/dist/chunk-D3LUKR2Y.js.map +1 -0
  45. package/dist/{chunk-5KSXMJXF.cjs → chunk-EO35UHFT.cjs} +60 -60
  46. package/dist/chunk-EO35UHFT.cjs.map +1 -0
  47. package/dist/{chunk-5YKUEZIA.cjs → chunk-EORFD5WB.cjs} +15 -15
  48. package/dist/{chunk-5YKUEZIA.cjs.map → chunk-EORFD5WB.cjs.map} +1 -1
  49. package/dist/{chunk-MEIMDHQ2.cjs → chunk-F7XPMG25.cjs} +28 -27
  50. package/dist/chunk-F7XPMG25.cjs.map +1 -0
  51. package/dist/{chunk-I74ADMZS.cjs → chunk-H6GFQ4AO.cjs} +7 -7
  52. package/dist/{chunk-I74ADMZS.cjs.map → chunk-H6GFQ4AO.cjs.map} +1 -1
  53. package/dist/{chunk-EOYFMWDT.cjs → chunk-J3NHQ4JB.cjs} +31 -31
  54. package/dist/{chunk-EOYFMWDT.cjs.map → chunk-J3NHQ4JB.cjs.map} +1 -1
  55. package/dist/{chunk-23QJPSZJ.cjs → chunk-SS3D3DHL.cjs} +7049 -4799
  56. package/dist/chunk-SS3D3DHL.cjs.map +1 -0
  57. package/dist/{chunk-6XQGPFIR.js → chunk-WNXIG6YY.js} +2 -2
  58. package/dist/{chunk-5INZDVGI.js → chunk-WZCQW4MW.js} +4 -4
  59. package/dist/{chunk-B3MRHZNZ.js → chunk-ZHC2BCXK.js} +4 -4
  60. package/dist/components/case-studies/index.cjs +8 -8
  61. package/dist/components/case-studies/index.js +2 -2
  62. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  63. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  64. package/dist/components/chat/hooks/index.d.ts +0 -1
  65. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  66. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  67. package/dist/components/chat/hooks/use-chunk-catchup.d.ts.map +1 -1
  68. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +15 -48
  69. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  70. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +10 -57
  71. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  72. package/dist/components/chat/index.cjs +10 -2
  73. package/dist/components/chat/index.cjs.map +1 -1
  74. package/dist/components/chat/index.d.ts +1 -0
  75. package/dist/components/chat/index.d.ts.map +1 -1
  76. package/dist/components/chat/index.js +21 -13
  77. package/dist/components/chat/stream/chat-dialog-store.d.ts +184 -0
  78. package/dist/components/chat/stream/chat-dialog-store.d.ts.map +1 -0
  79. package/dist/components/chat/stream/chat-stream-reducer.d.ts +367 -0
  80. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -0
  81. package/dist/components/chat/stream/delta-batcher.d.ts +51 -0
  82. package/dist/components/chat/stream/delta-batcher.d.ts.map +1 -0
  83. package/dist/components/chat/stream/index.d.ts +17 -0
  84. package/dist/components/chat/stream/index.d.ts.map +1 -0
  85. package/dist/components/chat/stream/message-mutations.d.ts +77 -0
  86. package/dist/components/chat/stream/message-mutations.d.ts.map +1 -0
  87. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +22 -0
  88. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +1 -0
  89. package/dist/components/chat/types/api.types.d.ts +1 -81
  90. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  91. package/dist/components/chat/types/processing.types.d.ts +2 -93
  92. package/dist/components/chat/types/processing.types.d.ts.map +1 -1
  93. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +34 -6
  94. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
  95. package/dist/components/chat/utils/index.d.ts +2 -3
  96. package/dist/components/chat/utils/index.d.ts.map +1 -1
  97. package/dist/components/chat/utils/process-historical-messages.d.ts +59 -11
  98. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  99. package/dist/components/contact/index.cjs +3 -3
  100. package/dist/components/contact/index.js +2 -2
  101. package/dist/components/docs/index.cjs +5 -5
  102. package/dist/components/docs/index.js +4 -4
  103. package/dist/components/embeds/index.cjs +3 -3
  104. package/dist/components/embeds/index.js +2 -2
  105. package/dist/components/faq/index.cjs +3 -3
  106. package/dist/components/faq/index.js +2 -2
  107. package/dist/components/features/index.cjs +2 -2
  108. package/dist/components/features/index.js +1 -1
  109. package/dist/components/help-center-pages/index.cjs +20 -20
  110. package/dist/components/help-center-pages/index.js +11 -11
  111. package/dist/components/index.cjs +172 -130
  112. package/dist/components/index.cjs.map +1 -1
  113. package/dist/components/index.js +63 -21
  114. package/dist/components/index.js.map +1 -1
  115. package/dist/components/navigation/index.cjs +2 -2
  116. package/dist/components/navigation/index.js +1 -1
  117. package/dist/components/onboarding-guides/index.cjs +5 -5
  118. package/dist/components/onboarding-guides/index.js +4 -4
  119. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  120. package/dist/components/related-content/index.cjs +3 -3
  121. package/dist/components/related-content/index.js +2 -2
  122. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  123. package/dist/components/tickets/index.cjs +5 -5
  124. package/dist/components/tickets/index.js +4 -4
  125. package/dist/components/ui/index.cjs +44 -2
  126. package/dist/components/ui/index.cjs.map +1 -1
  127. package/dist/components/ui/index.d.ts +1 -2
  128. package/dist/components/ui/index.d.ts.map +1 -1
  129. package/dist/components/ui/index.js +55 -13
  130. package/dist/components/ui/markdown/base-components.d.ts +51 -0
  131. package/dist/components/ui/markdown/base-components.d.ts.map +1 -0
  132. package/dist/components/ui/markdown/engine.d.ts +99 -0
  133. package/dist/components/ui/markdown/engine.d.ts.map +1 -0
  134. package/dist/components/ui/markdown/heading-ids.d.ts +65 -0
  135. package/dist/components/ui/markdown/heading-ids.d.ts.map +1 -0
  136. package/dist/components/ui/markdown/index.d.ts +18 -0
  137. package/dist/components/ui/markdown/index.d.ts.map +1 -0
  138. package/dist/components/ui/markdown/mermaid-diagram.d.ts +79 -0
  139. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +1 -0
  140. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +14 -0
  141. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +1 -0
  142. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +40 -0
  143. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -0
  144. package/dist/components/ui/markdown/rich/shortcodes.d.ts +8 -0
  145. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +1 -0
  146. package/dist/components/ui/markdown/sanitize.d.ts +153 -0
  147. package/dist/components/ui/markdown/sanitize.d.ts.map +1 -0
  148. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +23 -0
  149. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +1 -0
  150. package/dist/components/ui/markdown/streaming.d.ts +78 -0
  151. package/dist/components/ui/markdown/streaming.d.ts.map +1 -0
  152. package/dist/components/ui/markdown/text-size.d.ts +34 -0
  153. package/dist/components/ui/markdown/text-size.d.ts.map +1 -0
  154. package/dist/index.cjs +60 -2
  155. package/dist/index.cjs.map +1 -1
  156. package/dist/index.js +71 -13
  157. package/dist/utils/index.cjs +169 -40
  158. package/dist/utils/index.cjs.map +1 -1
  159. package/dist/utils/index.d.ts +1 -0
  160. package/dist/utils/index.d.ts.map +1 -1
  161. package/dist/utils/index.js +162 -41
  162. package/dist/utils/index.js.map +1 -1
  163. package/dist/utils/markdown-fences.d.ts +42 -0
  164. package/dist/utils/markdown-fences.d.ts.map +1 -0
  165. package/dist/utils/markdown-heading-id.d.ts +85 -0
  166. package/dist/utils/markdown-heading-id.d.ts.map +1 -0
  167. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  168. package/package.json +7 -1
  169. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +317 -0
  170. package/src/chat-protocol/__tests__/chat-protocol.test.ts +516 -0
  171. package/src/chat-protocol/__tests__/env-flag.test.ts +52 -0
  172. package/src/chat-protocol/__tests__/ip-normalize.test.ts +136 -0
  173. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +232 -0
  174. package/src/chat-protocol/decode.ts +278 -0
  175. package/src/chat-protocol/encode.ts +71 -0
  176. package/src/chat-protocol/env-flag.ts +39 -0
  177. package/src/chat-protocol/events.ts +245 -0
  178. package/src/chat-protocol/frames.ts +245 -0
  179. package/src/chat-protocol/index.ts +21 -0
  180. package/src/chat-protocol/ip-normalize.ts +146 -0
  181. package/src/chat-protocol/nats-decoder.ts +258 -0
  182. package/src/components/chat/__tests__/chat-message-list.test.tsx +381 -6
  183. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +207 -0
  184. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +250 -0
  185. package/src/components/chat/chat-message-enhanced.tsx +122 -20
  186. package/src/components/chat/chat-message-list.tsx +409 -132
  187. package/src/components/chat/embeddable-chat.tsx +6 -0
  188. package/src/components/chat/hooks/.index.md +30 -33
  189. package/src/components/chat/hooks/.use-nats-chat-adapter.md +36 -55
  190. package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +37 -0
  191. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  192. package/src/components/chat/hooks/__tests__/chunk-catchup-dialog-staleness.test.ts +92 -0
  193. package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +438 -0
  194. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +318 -0
  195. package/src/components/chat/hooks/index.ts +0 -1
  196. package/src/components/chat/hooks/use-chat.ts +8 -0
  197. package/src/components/chat/hooks/use-chunk-catchup.ts +26 -1
  198. package/src/components/chat/hooks/use-nats-chat-adapter.ts +254 -825
  199. package/src/components/chat/hooks/use-sse-chat-adapter.ts +380 -684
  200. package/src/components/chat/index.ts +5 -0
  201. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +940 -0
  202. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +806 -0
  203. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +467 -0
  204. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +1248 -0
  205. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +255 -0
  206. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +105 -0
  207. package/src/components/chat/stream/chat-dialog-store.ts +536 -0
  208. package/src/components/chat/stream/chat-stream-reducer.ts +1876 -0
  209. package/src/components/chat/stream/delta-batcher.ts +168 -0
  210. package/src/components/chat/stream/index.ts +55 -0
  211. package/src/components/chat/stream/message-mutations.ts +340 -0
  212. package/src/components/chat/stream/use-chat-stream-reducer.ts +126 -0
  213. package/src/components/chat/thinking-display.tsx +1 -1
  214. package/src/components/chat/types/.api.types.md +39 -49
  215. package/src/components/chat/types/.processing.types.md +29 -58
  216. package/src/components/chat/types/api.types.ts +6 -73
  217. package/src/components/chat/types/processing.types.ts +11 -53
  218. package/src/components/chat/utils/.index.md +31 -40
  219. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +420 -0
  220. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +605 -0
  221. package/src/components/chat/utils/__tests__/process-historical-messages-approvals.test.ts +61 -0
  222. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +394 -0
  223. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +270 -0
  224. package/src/components/chat/utils/extract-incomplete-message-state.ts +63 -5
  225. package/src/components/chat/utils/index.ts +5 -8
  226. package/src/components/chat/utils/process-historical-messages.ts +358 -386
  227. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +22 -4
  228. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  229. package/src/components/shared/product-release/release-detail-page.tsx +19 -4
  230. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +2420 -0
  231. package/src/components/ui/__tests__/markdown-parity.test.tsx +2540 -0
  232. package/src/components/ui/index.ts +1 -2
  233. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +176 -0
  234. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +151 -0
  235. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +354 -0
  236. package/src/components/ui/markdown/__tests__/sanitize-render.test.tsx +118 -0
  237. package/src/components/ui/markdown/__tests__/streaming.test.tsx +436 -0
  238. package/src/components/ui/markdown/base-components.tsx +360 -0
  239. package/src/components/ui/markdown/engine.tsx +315 -0
  240. package/src/components/ui/markdown/heading-ids.ts +239 -0
  241. package/src/components/ui/markdown/index.ts +49 -0
  242. package/src/components/ui/markdown/mermaid-diagram.tsx +323 -0
  243. package/src/components/ui/markdown/rich/embed-overrides.tsx +199 -0
  244. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +184 -0
  245. package/src/components/ui/markdown/rich/shortcodes.ts +170 -0
  246. package/src/components/ui/markdown/sanitize.ts +3584 -0
  247. package/src/components/ui/markdown/simple-markdown-renderer.tsx +28 -0
  248. package/src/components/ui/markdown/streaming.ts +390 -0
  249. package/src/components/ui/markdown/text-size.ts +106 -0
  250. package/src/components/ui/release-changelog-section.tsx +1 -1
  251. package/src/components/ui/ticket-info-section.tsx +1 -1
  252. package/src/utils/index.ts +1 -0
  253. package/src/utils/markdown-fences.ts +127 -0
  254. package/src/utils/markdown-heading-id.ts +348 -0
  255. package/src/utils/markdown-section-extractor.ts +41 -56
  256. package/dist/chunk-23QJPSZJ.cjs.map +0 -1
  257. package/dist/chunk-5KSXMJXF.cjs.map +0 -1
  258. package/dist/chunk-MEIMDHQ2.cjs.map +0 -1
  259. package/dist/chunk-NT3BKPEC.js.map +0 -1
  260. package/dist/chunk-YBTYHIXA.js.map +0 -1
  261. package/dist/chunk-ZAAIVSX6.js.map +0 -1
  262. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +0 -6
  263. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +0 -1
  264. package/dist/components/chat/utils/chunk-parser.d.ts +0 -25
  265. package/dist/components/chat/utils/chunk-parser.d.ts.map +0 -1
  266. package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
  267. package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
  268. package/dist/components/ui/simple-markdown-renderer.d.ts +0 -73
  269. package/dist/components/ui/simple-markdown-renderer.d.ts.map +0 -1
  270. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +0 -77
  271. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +0 -489
  272. package/src/components/chat/utils/.chunk-parser.md +0 -62
  273. package/src/components/chat/utils/chunk-parser.ts +0 -262
  274. package/src/components/ui/.simple-markdown-renderer.md +0 -52
  275. package/src/components/ui/rich-markdown-renderer.tsx +0 -1223
  276. package/src/components/ui/simple-markdown-renderer.tsx +0 -964
  277. /package/dist/{chunk-ZPUCCSYA.js.map → chunk-34C2JV2C.js.map} +0 -0
  278. /package/dist/{chunk-GWVNRXJU.js.map → chunk-3VGRZ62V.js.map} +0 -0
  279. /package/dist/{chunk-AAHAVML2.js.map → chunk-42NYDEHH.js.map} +0 -0
  280. /package/dist/{chunk-ZEHA4IC7.js.map → chunk-42SMPKGY.js.map} +0 -0
  281. /package/dist/{chunk-HRUXC3YN.js.map → chunk-5QWYIPMH.js.map} +0 -0
  282. /package/dist/{chunk-DGDUOFNY.js.map → chunk-BUBQEZ5J.js.map} +0 -0
  283. /package/dist/{chunk-6XQGPFIR.js.map → chunk-WNXIG6YY.js.map} +0 -0
  284. /package/dist/{chunk-5INZDVGI.js.map → chunk-WZCQW4MW.js.map} +0 -0
  285. /package/dist/{chunk-B3MRHZNZ.js.map → chunk-ZHC2BCXK.js.map} +0 -0
@@ -0,0 +1,605 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`MessageSegmentAccumulator — golden sequences > CHARACTERIZATION: a LATE standalone EXECUTING after its EXECUTED pushes a NEW executing segment (no in-place downgrade, but a duplicate card appears) 1`] = `
4
+ [
5
+ {
6
+ "data": {
7
+ "integratedToolType": "TACTICAL_RMM",
8
+ "parameters": {
9
+ "script": "cleanup.sh",
10
+ },
11
+ "result": "Freed 2.3 GB",
12
+ "success": true,
13
+ "toolExecutionRequestId": "exec-1",
14
+ "toolExplanation": undefined,
15
+ "toolFunction": "run_script",
16
+ "toolTitle": "Run cleanup script",
17
+ "type": "EXECUTED_TOOL",
18
+ },
19
+ "type": "tool_execution",
20
+ },
21
+ {
22
+ "data": {
23
+ "integratedToolType": "TACTICAL_RMM",
24
+ "parameters": {
25
+ "script": "cleanup.sh",
26
+ },
27
+ "toolExecutionRequestId": "exec-1",
28
+ "toolFunction": "run_script",
29
+ "toolTitle": "Run cleanup script",
30
+ "type": "EXECUTING_TOOL",
31
+ },
32
+ "type": "tool_execution",
33
+ },
34
+ ]
35
+ `;
36
+
37
+ exports[`MessageSegmentAccumulator — golden sequences > EXECUTED with no prior EXECUTING lands as a standalone completed segment 1`] = `
38
+ [
39
+ {
40
+ "data": {
41
+ "integratedToolType": "TACTICAL_RMM",
42
+ "parameters": undefined,
43
+ "result": "Freed 2.3 GB",
44
+ "success": true,
45
+ "toolExecutionRequestId": "exec-orphan",
46
+ "toolExplanation": undefined,
47
+ "toolFunction": "run_script",
48
+ "toolTitle": undefined,
49
+ "type": "EXECUTED_TOOL",
50
+ },
51
+ "type": "tool_execution",
52
+ },
53
+ ]
54
+ `;
55
+
56
+ exports[`MessageSegmentAccumulator — golden sequences > addApprovalBatch upserts by approvalRequestId (replay path produces ONE batch segment) 1`] = `
57
+ [
58
+ {
59
+ "data": {
60
+ "approvalRequestId": "batch-1",
61
+ "approvalType": "CLIENT",
62
+ "executions": {
63
+ "exec-a": {
64
+ "result": "ok",
65
+ "status": "done",
66
+ "success": true,
67
+ },
68
+ },
69
+ "toolCalls": [
70
+ {
71
+ "approvalType": "CLIENT",
72
+ "requiresApproval": true,
73
+ "toolCallArguments": {
74
+ "subject": "Printer down",
75
+ },
76
+ "toolExecutionRequestId": "exec-a",
77
+ "toolExplanation": "Opens a support ticket",
78
+ "toolName": "create_ticket",
79
+ "toolTitle": "Create ticket",
80
+ },
81
+ {
82
+ "approvalType": null,
83
+ "requiresApproval": false,
84
+ "toolCallArguments": null,
85
+ "toolExecutionRequestId": "exec-b",
86
+ "toolName": "read_kb",
87
+ },
88
+ ],
89
+ },
90
+ "onApprove": undefined,
91
+ "onReject": undefined,
92
+ "resolvedByName": "Jane Admin",
93
+ "status": "approved",
94
+ "type": "approval_batch",
95
+ },
96
+ ]
97
+ `;
98
+
99
+ exports[`MessageSegmentAccumulator — golden sequences > batch approval with per-tool executions merged into the batch (no standalone segments) 1`] = `
100
+ [
101
+ {
102
+ "data": {
103
+ "approvalRequestId": "batch-1",
104
+ "approvalType": "CLIENT",
105
+ "executions": {
106
+ "exec-a": {
107
+ "result": "Ticket #77 created",
108
+ "status": "done",
109
+ "success": true,
110
+ },
111
+ "exec-b": {
112
+ "result": undefined,
113
+ "status": "executing",
114
+ "success": undefined,
115
+ },
116
+ },
117
+ "toolCalls": [
118
+ {
119
+ "approvalType": "CLIENT",
120
+ "requiresApproval": true,
121
+ "toolCallArguments": {
122
+ "subject": "Printer down",
123
+ },
124
+ "toolExecutionRequestId": "exec-a",
125
+ "toolExplanation": "Opens a support ticket",
126
+ "toolName": "create_ticket",
127
+ "toolTitle": "Create ticket",
128
+ },
129
+ {
130
+ "approvalType": null,
131
+ "requiresApproval": false,
132
+ "toolCallArguments": null,
133
+ "toolExecutionRequestId": "exec-b",
134
+ "toolName": "read_kb",
135
+ },
136
+ ],
137
+ },
138
+ "onApprove": undefined,
139
+ "onReject": undefined,
140
+ "resolvedByName": "Jane Admin",
141
+ "status": "approved",
142
+ "type": "approval_batch",
143
+ },
144
+ ]
145
+ `;
146
+
147
+ exports[`MessageSegmentAccumulator — golden sequences > batch no-downgrade rule: a redelivered EXECUTING after EXECUTED keeps the done slot 1`] = `
148
+ [
149
+ {
150
+ "data": {
151
+ "approvalRequestId": "batch-1",
152
+ "approvalType": "CLIENT",
153
+ "executions": {
154
+ "exec-a": {
155
+ "result": "done!",
156
+ "status": "done",
157
+ "success": true,
158
+ },
159
+ },
160
+ "toolCalls": [
161
+ {
162
+ "approvalType": "CLIENT",
163
+ "requiresApproval": true,
164
+ "toolCallArguments": {
165
+ "subject": "Printer down",
166
+ },
167
+ "toolExecutionRequestId": "exec-a",
168
+ "toolExplanation": "Opens a support ticket",
169
+ "toolName": "create_ticket",
170
+ "toolTitle": "Create ticket",
171
+ },
172
+ {
173
+ "approvalType": null,
174
+ "requiresApproval": false,
175
+ "toolCallArguments": null,
176
+ "toolExecutionRequestId": "exec-b",
177
+ "toolName": "read_kb",
178
+ },
179
+ ],
180
+ },
181
+ "onApprove": undefined,
182
+ "onReject": undefined,
183
+ "resolvedByName": undefined,
184
+ "status": "approved",
185
+ "type": "approval_batch",
186
+ },
187
+ ]
188
+ `;
189
+
190
+ exports[`MessageSegmentAccumulator — golden sequences > coalesces consecutive text deltas into one text segment 1`] = `
191
+ [
192
+ {
193
+ "text": "Hello, world",
194
+ "type": "text",
195
+ },
196
+ ]
197
+ `;
198
+
199
+ exports[`MessageSegmentAccumulator — golden sequences > coalesces thinking deltas, and text after thinking starts a NEW segment 1`] = `
200
+ [
201
+ {
202
+ "text": "Let me think… ok.",
203
+ "type": "thinking",
204
+ },
205
+ {
206
+ "text": "Answer: 42",
207
+ "type": "text",
208
+ },
209
+ {
210
+ "text": "post-answer thought",
211
+ "type": "thinking",
212
+ },
213
+ ]
214
+ `;
215
+
216
+ exports[`MessageSegmentAccumulator — golden sequences > completeContextCompaction with no started segment pushes a completed one 1`] = `
217
+ [
218
+ {
219
+ "status": "completed",
220
+ "summary": undefined,
221
+ "type": "context_compaction",
222
+ },
223
+ ]
224
+ `;
225
+
226
+ exports[`MessageSegmentAccumulator — golden sequences > context compaction start → complete replaces the started segment in place 1`] = `
227
+ [
228
+ {
229
+ "text": "Before compaction",
230
+ "type": "text",
231
+ },
232
+ {
233
+ "status": "completed",
234
+ "summary": "Summarized 34 messages",
235
+ "type": "context_compaction",
236
+ },
237
+ {
238
+ "text": "After compaction",
239
+ "type": "text",
240
+ },
241
+ ]
242
+ `;
243
+
244
+ exports[`MessageSegmentAccumulator — golden sequences > error segments append verbatim 1`] = `
245
+ [
246
+ {
247
+ "text": "partial answer",
248
+ "type": "text",
249
+ },
250
+ {
251
+ "details": "boom",
252
+ "title": "Agent crashed",
253
+ "type": "error",
254
+ },
255
+ ]
256
+ `;
257
+
258
+ exports[`MessageSegmentAccumulator — golden sequences > flushPendingApprovals emits pending cards for every tracked-but-unresolved approval 1`] = `
259
+ [
260
+ {
261
+ "data": {
262
+ "approvalType": "CLIENT",
263
+ "command": "cmd-1",
264
+ "explanation": undefined,
265
+ "requestId": "req-1",
266
+ },
267
+ "onApprove": undefined,
268
+ "onReject": undefined,
269
+ "status": "pending",
270
+ "type": "approval_request",
271
+ },
272
+ {
273
+ "data": {
274
+ "approvalType": "ADMIN",
275
+ "command": "cmd-2",
276
+ "explanation": "why",
277
+ "requestId": "req-2",
278
+ },
279
+ "onApprove": undefined,
280
+ "onReject": undefined,
281
+ "status": "pending",
282
+ "type": "approval_request",
283
+ },
284
+ ]
285
+ `;
286
+
287
+ exports[`MessageSegmentAccumulator — golden sequences > implicit approval does NOT touch approval_batch segments (handled by applyExecutionToBatch only) 1`] = `
288
+ [
289
+ {
290
+ "data": {
291
+ "approvalRequestId": "batch-1",
292
+ "approvalType": "CLIENT",
293
+ "toolCalls": [
294
+ {
295
+ "approvalType": "CLIENT",
296
+ "requiresApproval": true,
297
+ "toolCallArguments": {
298
+ "subject": "Printer down",
299
+ },
300
+ "toolExecutionRequestId": "exec-a",
301
+ "toolExplanation": "Opens a support ticket",
302
+ "toolName": "create_ticket",
303
+ "toolTitle": "Create ticket",
304
+ },
305
+ {
306
+ "approvalType": null,
307
+ "requiresApproval": false,
308
+ "toolCallArguments": null,
309
+ "toolExecutionRequestId": "exec-b",
310
+ "toolName": "read_kb",
311
+ },
312
+ ],
313
+ },
314
+ "onApprove": undefined,
315
+ "onReject": undefined,
316
+ "resolvedByName": undefined,
317
+ "status": "pending",
318
+ "type": "approval_batch",
319
+ },
320
+ {
321
+ "data": {
322
+ "integratedToolType": "TACTICAL_RMM",
323
+ "parameters": {
324
+ "script": "cleanup.sh",
325
+ },
326
+ "toolExecutionRequestId": "exec-unrelated",
327
+ "toolFunction": "run_script",
328
+ "toolTitle": "Run cleanup script",
329
+ "type": "EXECUTING_TOOL",
330
+ },
331
+ "type": "tool_execution",
332
+ },
333
+ ]
334
+ `;
335
+
336
+ exports[`MessageSegmentAccumulator — golden sequences > implicit approval flips ONLY the latest pending gate, earlier pending gates stay pending 1`] = `
337
+ [
338
+ {
339
+ "data": {
340
+ "approvalType": "CLIENT",
341
+ "command": "first",
342
+ "explanation": undefined,
343
+ "requestId": "req-1",
344
+ },
345
+ "onApprove": undefined,
346
+ "onReject": undefined,
347
+ "status": "pending",
348
+ "type": "approval_request",
349
+ },
350
+ {
351
+ "data": {
352
+ "approvalType": "CLIENT",
353
+ "command": "second",
354
+ "explanation": undefined,
355
+ "requestId": "req-2",
356
+ },
357
+ "onApprove": undefined,
358
+ "onReject": undefined,
359
+ "status": "approved",
360
+ "type": "approval_request",
361
+ },
362
+ {
363
+ "data": {
364
+ "integratedToolType": "TACTICAL_RMM",
365
+ "parameters": {
366
+ "script": "cleanup.sh",
367
+ },
368
+ "toolExecutionRequestId": "exec-1",
369
+ "toolFunction": "run_script",
370
+ "toolTitle": "Run cleanup script",
371
+ "type": "EXECUTING_TOOL",
372
+ },
373
+ "type": "tool_execution",
374
+ },
375
+ ]
376
+ `;
377
+
378
+ exports[`MessageSegmentAccumulator — golden sequences > implicit resolvePendingApprovalForExecution: a tool execution flips the LATEST pending single approval (NATS-observer behavior) 1`] = `
379
+ [
380
+ {
381
+ "data": {
382
+ "approvalType": "CLIENT",
383
+ "command": "echo old",
384
+ "explanation": undefined,
385
+ "requestId": "req-old",
386
+ },
387
+ "onApprove": undefined,
388
+ "onReject": undefined,
389
+ "status": "rejected",
390
+ "type": "approval_request",
391
+ },
392
+ {
393
+ "data": {
394
+ "approvalType": "CLIENT",
395
+ "command": "systemctl restart nats",
396
+ "explanation": undefined,
397
+ "requestId": "req-1",
398
+ },
399
+ "onApprove": undefined,
400
+ "onReject": undefined,
401
+ "status": "approved",
402
+ "type": "approval_request",
403
+ },
404
+ {
405
+ "data": {
406
+ "integratedToolType": "TACTICAL_RMM",
407
+ "parameters": {
408
+ "script": "cleanup.sh",
409
+ },
410
+ "toolExecutionRequestId": "exec-9",
411
+ "toolFunction": "run_script",
412
+ "toolTitle": "Run cleanup script",
413
+ "type": "EXECUTING_TOOL",
414
+ },
415
+ "type": "tool_execution",
416
+ },
417
+ ]
418
+ `;
419
+
420
+ exports[`MessageSegmentAccumulator — golden sequences > initializeWithState continues an incomplete message across reconnect 1`] = `
421
+ [
422
+ {
423
+ "text": "partial ",
424
+ "type": "text",
425
+ },
426
+ {
427
+ "data": {
428
+ "integratedToolType": "TACTICAL_RMM",
429
+ "parameters": {
430
+ "script": "cleanup.sh",
431
+ },
432
+ "result": "Freed 2.3 GB",
433
+ "success": true,
434
+ "toolExecutionRequestId": "exec-1",
435
+ "toolExplanation": undefined,
436
+ "toolFunction": "run_script",
437
+ "toolTitle": "Run cleanup script",
438
+ "type": "EXECUTED_TOOL",
439
+ },
440
+ "type": "tool_execution",
441
+ },
442
+ {
443
+ "text": "and the rest.",
444
+ "type": "text",
445
+ },
446
+ ]
447
+ `;
448
+
449
+ exports[`MessageSegmentAccumulator — golden sequences > merges EXECUTING_TOOL → EXECUTED_TOOL in place by toolExecutionRequestId (title restored) 1`] = `
450
+ [
451
+ {
452
+ "text": "Running a cleanup now.",
453
+ "type": "text",
454
+ },
455
+ {
456
+ "data": {
457
+ "integratedToolType": "TACTICAL_RMM",
458
+ "parameters": {
459
+ "script": "cleanup.sh",
460
+ },
461
+ "result": "Freed 2.3 GB",
462
+ "success": true,
463
+ "toolExecutionRequestId": "exec-1",
464
+ "toolExplanation": undefined,
465
+ "toolFunction": "run_script",
466
+ "toolTitle": "Run cleanup script",
467
+ "type": "EXECUTED_TOOL",
468
+ },
469
+ "type": "tool_execution",
470
+ },
471
+ ]
472
+ `;
473
+
474
+ exports[`MessageSegmentAccumulator — golden sequences > pairs by (integratedToolType, toolFunction) when no exec id is present (older backends) 1`] = `
475
+ [
476
+ {
477
+ "data": {
478
+ "integratedToolType": "TACTICAL_RMM",
479
+ "parameters": {
480
+ "script": "cleanup.sh",
481
+ },
482
+ "result": "Freed 2.3 GB",
483
+ "success": true,
484
+ "toolExplanation": undefined,
485
+ "toolFunction": "run_script",
486
+ "toolTitle": "Run cleanup script",
487
+ "type": "EXECUTED_TOOL",
488
+ },
489
+ "type": "tool_execution",
490
+ },
491
+ ]
492
+ `;
493
+
494
+ exports[`MessageSegmentAccumulator — golden sequences > replaySegments reproduces a mixed recorded segment array (idempotent replay) 1`] = `
495
+ [
496
+ {
497
+ "text": "hmm",
498
+ "type": "thinking",
499
+ },
500
+ {
501
+ "text": "Sure — ",
502
+ "type": "text",
503
+ },
504
+ {
505
+ "data": {
506
+ "integratedToolType": "TACTICAL_RMM",
507
+ "parameters": {
508
+ "script": "cleanup.sh",
509
+ },
510
+ "result": "Freed 2.3 GB",
511
+ "success": true,
512
+ "toolExecutionRequestId": "exec-1",
513
+ "toolExplanation": undefined,
514
+ "toolFunction": "run_script",
515
+ "toolTitle": "Run cleanup script",
516
+ "type": "EXECUTED_TOOL",
517
+ },
518
+ "type": "tool_execution",
519
+ },
520
+ {
521
+ "data": {
522
+ "approvalRequestId": "batch-1",
523
+ "approvalType": "CLIENT",
524
+ "executions": {
525
+ "exec-a": {
526
+ "result": "ok",
527
+ "status": "done",
528
+ "success": true,
529
+ },
530
+ },
531
+ "toolCalls": [
532
+ {
533
+ "approvalType": "CLIENT",
534
+ "requiresApproval": true,
535
+ "toolCallArguments": {
536
+ "subject": "Printer down",
537
+ },
538
+ "toolExecutionRequestId": "exec-a",
539
+ "toolExplanation": "Opens a support ticket",
540
+ "toolName": "create_ticket",
541
+ "toolTitle": "Create ticket",
542
+ },
543
+ {
544
+ "approvalType": null,
545
+ "requiresApproval": false,
546
+ "toolCallArguments": null,
547
+ "toolExecutionRequestId": "exec-b",
548
+ "toolName": "read_kb",
549
+ },
550
+ ],
551
+ },
552
+ "onApprove": undefined,
553
+ "onReject": undefined,
554
+ "resolvedByName": undefined,
555
+ "status": "approved",
556
+ "type": "approval_batch",
557
+ },
558
+ {
559
+ "text": "done.",
560
+ "type": "text",
561
+ },
562
+ ]
563
+ `;
564
+
565
+ exports[`MessageSegmentAccumulator — golden sequences > single approval request → updateApprovalStatus flips status and stamps resolvedByName only on batches 1`] = `
566
+ [
567
+ {
568
+ "data": {
569
+ "approvalType": "CLIENT",
570
+ "command": "systemctl restart nats",
571
+ "explanation": "Restart broker",
572
+ "requestId": "req-1",
573
+ },
574
+ "onApprove": [Function],
575
+ "onReject": [Function],
576
+ "status": "approved",
577
+ "type": "approval_request",
578
+ },
579
+ ]
580
+ `;
581
+
582
+ exports[`MessageSegmentAccumulator — golden sequences > tracked (pending) approval + processApprovalResult appends a resolved segment 1`] = `
583
+ {
584
+ "hasPendingAfter": false,
585
+ "pendingData": {
586
+ "approvalType": "CLIENT",
587
+ "command": "rm -rf /tmp/cache",
588
+ "explanation": "Clear caches",
589
+ },
590
+ "segments": [
591
+ {
592
+ "data": {
593
+ "approvalType": "CLIENT",
594
+ "command": "rm -rf /tmp/cache",
595
+ "explanation": "Clear caches",
596
+ "requestId": "req-2",
597
+ },
598
+ "onApprove": undefined,
599
+ "onReject": undefined,
600
+ "status": "rejected",
601
+ "type": "approval_request",
602
+ },
603
+ ],
604
+ }
605
+ `;
@@ -10,6 +10,7 @@
10
10
 
11
11
  import { describe, it, expect } from 'vitest'
12
12
  import { processHistoricalMessagesWithErrors } from '../process-historical-messages'
13
+ import { createChatStreamReducer } from '../../stream/chat-stream-reducer'
13
14
  import type { HistoricalMessage, MessageSegment } from '../../types'
14
15
 
15
16
  const adminApprovalMessage = (id: string): HistoricalMessage => ({
@@ -95,3 +96,63 @@ describe('processHistoricalMessagesWithErrors — displayApprovalTypes', () => {
95
96
  expect(asst?.streamSeq).toBe(50)
96
97
  })
97
98
  })
99
+
100
+ /**
101
+ * PAIRED-PATH contract. The history processor and the realtime reducer are the
102
+ * two halves of one pipeline, and they DISAGREE by default: history renders
103
+ * every approval type (the deliberate behaviour this file's header argues for),
104
+ * the reducer defaults to `['CLIENT']`. Each half is pinned on its own — above
105
+ * for history, in the reducer's own suite for realtime — but NOTHING asserted
106
+ * the pair, so aligning one default "for consistency" (or a host wiring the
107
+ * option into one call site only) changed observable behaviour with every test
108
+ * still green.
109
+ *
110
+ * These two fixtures state the divergence and its remedy in one place: omitted
111
+ * → the SAME approval is an inline card after a reload and invisible live;
112
+ * explicit list → both paths agree. Read the header for why the asymmetric
113
+ * defaults are the intended trade-off (a `['CLIENT']` history default made
114
+ * pending ADMIN cards vanish on every refetch).
115
+ */
116
+ describe('displayApprovalTypes — history vs realtime default divergence', () => {
117
+ const liveApprovalSegments = (displayApprovalTypes?: string[]) => {
118
+ const effects: Array<{ name: string; args: unknown[] }> = []
119
+ const r = createChatStreamReducer({
120
+ transport: 'nats',
121
+ onEffect: (e) => effects.push(e),
122
+ ...(displayApprovalTypes ? { displayApprovalTypes } : {}),
123
+ })
124
+ r.apply({ type: 'turn-start' })
125
+ r.apply({
126
+ type: 'approval-request',
127
+ requestId: 'req-m1',
128
+ approvalType: 'ADMIN',
129
+ command: 'systemctl restart nats',
130
+ })
131
+ return {
132
+ rendered: r.state.messages.flatMap((m) => approvalSegments(m.segments)),
133
+ escalated: effects.filter((e) => e.name === 'onEscalatedApproval'),
134
+ }
135
+ }
136
+
137
+ it('OMITTED: history renders the ADMIN card inline, realtime escalates it', () => {
138
+ const history = processHistoricalMessagesWithErrors([adminApprovalMessage('m1')])
139
+ expect(history.messages.flatMap((m) => approvalSegments(m.content))).toHaveLength(1)
140
+ expect(history.escalatedApprovals.size).toBe(0)
141
+
142
+ const live = liveApprovalSegments()
143
+ expect(live.rendered).toHaveLength(0)
144
+ expect(live.escalated).toHaveLength(1)
145
+ })
146
+
147
+ it('EXPLICIT list: both paths render the same ADMIN card', () => {
148
+ const types = ['CLIENT', 'ADMIN']
149
+ const history = processHistoricalMessagesWithErrors([adminApprovalMessage('m1')], {
150
+ displayApprovalTypes: types,
151
+ })
152
+ expect(history.messages.flatMap((m) => approvalSegments(m.content))).toHaveLength(1)
153
+
154
+ const live = liveApprovalSegments(types)
155
+ expect(live.rendered).toHaveLength(1)
156
+ expect(live.escalated).toHaveLength(0)
157
+ })
158
+ })