@flamingo-stack/openframe-frontend-core 0.0.457 → 0.0.458-snapshot.20260720215024

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 (290) 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 +192 -0
  8. package/dist/chat-protocol/events.d.ts.map +1 -0
  9. package/dist/chat-protocol/frames.d.ts +206 -0
  10. package/dist/chat-protocol/frames.d.ts.map +1 -0
  11. package/dist/chat-protocol/index.cjs +493 -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 +477 -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-SQ3CP2IV.cjs → chunk-3N3TMZ62.cjs} +7 -7
  22. package/dist/{chunk-SQ3CP2IV.cjs.map → chunk-3N3TMZ62.cjs.map} +1 -1
  23. package/dist/{chunk-I7M6KCCS.js → chunk-4R6H2U77.js} +4 -4
  24. package/dist/{chunk-CCT5VCRP.cjs → chunk-4XDWNAZW.cjs} +9 -9
  25. package/dist/{chunk-CCT5VCRP.cjs.map → chunk-4XDWNAZW.cjs.map} +1 -1
  26. package/dist/{chunk-KQ36EHE4.cjs → chunk-7KSEINAE.cjs} +15 -15
  27. package/dist/{chunk-KQ36EHE4.cjs.map → chunk-7KSEINAE.cjs.map} +1 -1
  28. package/dist/{chunk-FM5DTJPA.cjs → chunk-ADD3FPDG.cjs} +6851 -4713
  29. package/dist/chunk-ADD3FPDG.cjs.map +1 -0
  30. package/dist/{chunk-RSW42GTZ.js → chunk-APF5QBAU.js} +2 -2
  31. package/dist/{chunk-YCIVMKRS.cjs → chunk-BLZZXZNM.cjs} +26 -26
  32. package/dist/{chunk-YCIVMKRS.cjs.map → chunk-BLZZXZNM.cjs.map} +1 -1
  33. package/dist/{chunk-YHB4MNUX.cjs → chunk-BQ7PMWLM.cjs} +28 -27
  34. package/dist/chunk-BQ7PMWLM.cjs.map +1 -0
  35. package/dist/{chunk-GJ7BN4MI.js → chunk-CGNDAJ7V.js} +4 -4
  36. package/dist/{chunk-R5IQJXA3.js → chunk-F2NMWV44.js} +2 -2
  37. package/dist/{chunk-EOVQVVDJ.cjs → chunk-F7F43U7Q.cjs} +11 -11
  38. package/dist/{chunk-EOVQVVDJ.cjs.map → chunk-F7F43U7Q.cjs.map} +1 -1
  39. package/dist/{chunk-2ZW2ZPDW.js → chunk-LAOO7XHO.js} +2 -2
  40. package/dist/{chunk-O7F7RZFN.js → chunk-LJKZIIK4.js} +6 -5
  41. package/dist/chunk-LJKZIIK4.js.map +1 -0
  42. package/dist/{chunk-AJGZ3YSR.js → chunk-OR5AMXYN.js} +2 -2
  43. package/dist/{chunk-5XFJG3TC.cjs → chunk-P5JQDFRM.cjs} +60 -60
  44. package/dist/chunk-P5JQDFRM.cjs.map +1 -0
  45. package/dist/{chunk-U4APSAAR.cjs → chunk-PXZ7YQ5V.cjs} +5 -5
  46. package/dist/{chunk-U4APSAAR.cjs.map → chunk-PXZ7YQ5V.cjs.map} +1 -1
  47. package/dist/{chunk-WXDEMTLD.js → chunk-QO2XD3FR.js} +2 -2
  48. package/dist/{chunk-C2TDHJBO.cjs → chunk-QSGZE6AZ.cjs} +37 -37
  49. package/dist/{chunk-C2TDHJBO.cjs.map → chunk-QSGZE6AZ.cjs.map} +1 -1
  50. package/dist/{chunk-NSL5MNS4.js → chunk-REWRUV3K.js} +11644 -9506
  51. package/dist/chunk-REWRUV3K.js.map +1 -0
  52. package/dist/{chunk-BDTQIIJR.cjs → chunk-TA7MFVUS.cjs} +31 -31
  53. package/dist/{chunk-BDTQIIJR.cjs.map → chunk-TA7MFVUS.cjs.map} +1 -1
  54. package/dist/{chunk-4423DHRX.js → chunk-UI7CIUAR.js} +2 -2
  55. package/dist/{chunk-5BKBG653.js → chunk-VXJH5TDN.js} +10 -10
  56. package/dist/chunk-VXJH5TDN.js.map +1 -0
  57. package/dist/{chunk-AB65PWU2.cjs → chunk-WCE66C2Z.cjs} +62 -62
  58. package/dist/{chunk-AB65PWU2.cjs.map → chunk-WCE66C2Z.cjs.map} +1 -1
  59. package/dist/{chunk-KXIIUE75.js → chunk-XF5ROTMQ.js} +2 -2
  60. package/dist/components/case-studies/index.cjs +8 -8
  61. package/dist/components/case-studies/index.js +2 -2
  62. package/dist/components/chart.d.ts +1 -1
  63. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  64. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  65. package/dist/components/chat/hooks/index.d.ts +0 -1
  66. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  67. package/dist/components/chat/hooks/use-chat.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 +3 -47
  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 -90
  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/features/time-tracker/time-tracker-panel.d.ts.map +1 -1
  110. package/dist/components/help-center-pages/index.cjs +20 -20
  111. package/dist/components/help-center-pages/index.js +11 -11
  112. package/dist/components/index.cjs +171 -129
  113. package/dist/components/index.cjs.map +1 -1
  114. package/dist/components/index.js +63 -21
  115. package/dist/components/index.js.map +1 -1
  116. package/dist/components/layout/page-container.d.ts.map +1 -1
  117. package/dist/components/navigation/index.cjs +2 -2
  118. package/dist/components/navigation/index.js +1 -1
  119. package/dist/components/onboarding-guides/index.cjs +5 -5
  120. package/dist/components/onboarding-guides/index.js +4 -4
  121. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  122. package/dist/components/related-content/index.cjs +3 -3
  123. package/dist/components/related-content/index.js +2 -2
  124. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  125. package/dist/components/tickets/index.cjs +5 -5
  126. package/dist/components/tickets/index.js +4 -4
  127. package/dist/components/ui/index.cjs +44 -2
  128. package/dist/components/ui/index.cjs.map +1 -1
  129. package/dist/components/ui/index.d.ts +1 -2
  130. package/dist/components/ui/index.d.ts.map +1 -1
  131. package/dist/components/ui/index.js +55 -13
  132. package/dist/components/ui/markdown/base-components.d.ts +56 -0
  133. package/dist/components/ui/markdown/base-components.d.ts.map +1 -0
  134. package/dist/components/ui/markdown/engine.d.ts +99 -0
  135. package/dist/components/ui/markdown/engine.d.ts.map +1 -0
  136. package/dist/components/ui/markdown/heading-ids.d.ts +65 -0
  137. package/dist/components/ui/markdown/heading-ids.d.ts.map +1 -0
  138. package/dist/components/ui/markdown/index.d.ts +18 -0
  139. package/dist/components/ui/markdown/index.d.ts.map +1 -0
  140. package/dist/components/ui/markdown/mermaid-diagram.d.ts +79 -0
  141. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +1 -0
  142. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +14 -0
  143. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +1 -0
  144. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +40 -0
  145. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -0
  146. package/dist/components/ui/markdown/rich/shortcodes.d.ts +8 -0
  147. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +1 -0
  148. package/dist/components/ui/markdown/sanitize.d.ts +153 -0
  149. package/dist/components/ui/markdown/sanitize.d.ts.map +1 -0
  150. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +23 -0
  151. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +1 -0
  152. package/dist/components/ui/markdown/streaming.d.ts +78 -0
  153. package/dist/components/ui/markdown/streaming.d.ts.map +1 -0
  154. package/dist/components/ui/markdown/text-size.d.ts +34 -0
  155. package/dist/components/ui/markdown/text-size.d.ts.map +1 -0
  156. package/dist/components/ui/modal-v2.d.ts.map +1 -1
  157. package/dist/components/ui/modal.d.ts.map +1 -1
  158. package/dist/index.cjs +60 -2
  159. package/dist/index.cjs.map +1 -1
  160. package/dist/index.js +71 -13
  161. package/dist/utils/index.cjs +169 -40
  162. package/dist/utils/index.cjs.map +1 -1
  163. package/dist/utils/index.d.ts +1 -0
  164. package/dist/utils/index.d.ts.map +1 -1
  165. package/dist/utils/index.js +162 -41
  166. package/dist/utils/index.js.map +1 -1
  167. package/dist/utils/markdown-fences.d.ts +42 -0
  168. package/dist/utils/markdown-fences.d.ts.map +1 -0
  169. package/dist/utils/markdown-heading-id.d.ts +85 -0
  170. package/dist/utils/markdown-heading-id.d.ts.map +1 -0
  171. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  172. package/package.json +7 -1
  173. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +307 -0
  174. package/src/chat-protocol/__tests__/chat-protocol.test.ts +515 -0
  175. package/src/chat-protocol/__tests__/env-flag.test.ts +52 -0
  176. package/src/chat-protocol/__tests__/ip-normalize.test.ts +136 -0
  177. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +228 -0
  178. package/src/chat-protocol/decode.ts +277 -0
  179. package/src/chat-protocol/encode.ts +71 -0
  180. package/src/chat-protocol/env-flag.ts +39 -0
  181. package/src/chat-protocol/events.ts +228 -0
  182. package/src/chat-protocol/frames.ts +238 -0
  183. package/src/chat-protocol/index.ts +21 -0
  184. package/src/chat-protocol/ip-normalize.ts +146 -0
  185. package/src/chat-protocol/nats-decoder.ts +252 -0
  186. package/src/components/chat/__tests__/chat-message-list.test.tsx +293 -5
  187. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +207 -0
  188. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +209 -0
  189. package/src/components/chat/chat-message-enhanced.tsx +111 -17
  190. package/src/components/chat/chat-message-list.tsx +367 -113
  191. package/src/components/chat/embeddable-chat.tsx +6 -0
  192. package/src/components/chat/hooks/.index.md +1 -1
  193. package/src/components/chat/hooks/.use-nats-chat-adapter.md +1 -1
  194. package/src/components/chat/hooks/__tests__/__snapshots__/persisted-state-v1-golden.test.ts.snap +297 -0
  195. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  196. package/src/components/chat/hooks/__tests__/persisted-state-v1-golden.test.ts +272 -0
  197. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +318 -0
  198. package/src/components/chat/hooks/index.ts +0 -1
  199. package/src/components/chat/hooks/use-chat.ts +8 -0
  200. package/src/components/chat/hooks/use-nats-chat-adapter.ts +243 -822
  201. package/src/components/chat/hooks/use-sse-chat-adapter.ts +318 -666
  202. package/src/components/chat/index.ts +5 -0
  203. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +937 -0
  204. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +756 -0
  205. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +460 -0
  206. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +894 -0
  207. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +255 -0
  208. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +98 -0
  209. package/src/components/chat/stream/chat-dialog-store.ts +536 -0
  210. package/src/components/chat/stream/chat-stream-reducer.ts +1796 -0
  211. package/src/components/chat/stream/delta-batcher.ts +159 -0
  212. package/src/components/chat/stream/index.ts +55 -0
  213. package/src/components/chat/stream/message-mutations.ts +338 -0
  214. package/src/components/chat/stream/use-chat-stream-reducer.ts +126 -0
  215. package/src/components/chat/thinking-display.tsx +1 -1
  216. package/src/components/chat/types/.api.types.md +1 -3
  217. package/src/components/chat/types/.processing.types.md +6 -23
  218. package/src/components/chat/types/api.types.ts +6 -73
  219. package/src/components/chat/types/processing.types.ts +11 -52
  220. package/src/components/chat/utils/.index.md +0 -5
  221. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +418 -0
  222. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +599 -0
  223. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +317 -0
  224. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +270 -0
  225. package/src/components/chat/utils/extract-incomplete-message-state.ts +63 -5
  226. package/src/components/chat/utils/index.ts +5 -8
  227. package/src/components/chat/utils/process-historical-messages.ts +352 -383
  228. package/src/components/features/notifications/notification-drawer.tsx +4 -2
  229. package/src/components/features/time-tracker/time-tracker-panel.tsx +8 -2
  230. package/src/components/layout/page-container.tsx +5 -1
  231. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +22 -4
  232. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  233. package/src/components/shared/product-release/release-detail-page.tsx +19 -4
  234. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +2420 -0
  235. package/src/components/ui/__tests__/markdown-parity.test.tsx +2528 -0
  236. package/src/components/ui/index.ts +1 -2
  237. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +115 -0
  238. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +95 -0
  239. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +309 -0
  240. package/src/components/ui/markdown/__tests__/streaming.test.tsx +388 -0
  241. package/src/components/ui/markdown/base-components.tsx +341 -0
  242. package/src/components/ui/markdown/engine.tsx +315 -0
  243. package/src/components/ui/markdown/heading-ids.ts +239 -0
  244. package/src/components/ui/markdown/index.ts +49 -0
  245. package/src/components/ui/markdown/mermaid-diagram.tsx +291 -0
  246. package/src/components/ui/markdown/rich/embed-overrides.tsx +199 -0
  247. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +184 -0
  248. package/src/components/ui/markdown/rich/shortcodes.ts +170 -0
  249. package/src/components/ui/markdown/sanitize.ts +3499 -0
  250. package/src/components/ui/markdown/simple-markdown-renderer.tsx +28 -0
  251. package/src/components/ui/markdown/streaming.ts +362 -0
  252. package/src/components/ui/markdown/text-size.ts +106 -0
  253. package/src/components/ui/modal-v2.tsx +6 -0
  254. package/src/components/ui/modal.tsx +3 -0
  255. package/src/components/ui/release-changelog-section.tsx +1 -1
  256. package/src/components/ui/ticket-info-section.tsx +1 -1
  257. package/src/utils/index.ts +1 -0
  258. package/src/utils/markdown-fences.ts +127 -0
  259. package/src/utils/markdown-heading-id.ts +348 -0
  260. package/src/utils/markdown-section-extractor.ts +41 -56
  261. package/dist/chunk-5BKBG653.js.map +0 -1
  262. package/dist/chunk-5XFJG3TC.cjs.map +0 -1
  263. package/dist/chunk-FM5DTJPA.cjs.map +0 -1
  264. package/dist/chunk-NSL5MNS4.js.map +0 -1
  265. package/dist/chunk-O7F7RZFN.js.map +0 -1
  266. package/dist/chunk-YHB4MNUX.cjs.map +0 -1
  267. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +0 -6
  268. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +0 -1
  269. package/dist/components/chat/utils/chunk-parser.d.ts +0 -25
  270. package/dist/components/chat/utils/chunk-parser.d.ts.map +0 -1
  271. package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
  272. package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
  273. package/dist/components/ui/simple-markdown-renderer.d.ts +0 -73
  274. package/dist/components/ui/simple-markdown-renderer.d.ts.map +0 -1
  275. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +0 -50
  276. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +0 -479
  277. package/src/components/chat/utils/.chunk-parser.md +0 -51
  278. package/src/components/chat/utils/chunk-parser.ts +0 -255
  279. package/src/components/ui/.simple-markdown-renderer.md +0 -40
  280. package/src/components/ui/rich-markdown-renderer.tsx +0 -1223
  281. package/src/components/ui/simple-markdown-renderer.tsx +0 -965
  282. /package/dist/{chunk-I7M6KCCS.js.map → chunk-4R6H2U77.js.map} +0 -0
  283. /package/dist/{chunk-RSW42GTZ.js.map → chunk-APF5QBAU.js.map} +0 -0
  284. /package/dist/{chunk-GJ7BN4MI.js.map → chunk-CGNDAJ7V.js.map} +0 -0
  285. /package/dist/{chunk-R5IQJXA3.js.map → chunk-F2NMWV44.js.map} +0 -0
  286. /package/dist/{chunk-2ZW2ZPDW.js.map → chunk-LAOO7XHO.js.map} +0 -0
  287. /package/dist/{chunk-AJGZ3YSR.js.map → chunk-OR5AMXYN.js.map} +0 -0
  288. /package/dist/{chunk-WXDEMTLD.js.map → chunk-QO2XD3FR.js.map} +0 -0
  289. /package/dist/{chunk-4423DHRX.js.map → chunk-UI7CIUAR.js.map} +0 -0
  290. /package/dist/{chunk-KXIIUE75.js.map → chunk-XF5ROTMQ.js.map} +0 -0
@@ -9,7 +9,6 @@ Defines TypeScript interfaces for API interactions and React hook contracts used
9
9
  | `UseChunkCatchupOptions` | Configure chunk catch-up replay with optional custom fetch function |
10
10
  | `UseNatsDialogSubscriptionOptions` | Core NATS WebSocket subscription config with reconnection backoff tuning |
11
11
  | `UseJetStreamDialogSubscriptionOptions` | JetStream-based subscription with sequence-based resume support |
12
- | `UseRealtimeChunkProcessorOptions` | Controls how streaming chunks are parsed, including approval routing and batch mode |
13
12
 
14
13
  ### Hook Return Types
15
14
  | Interface | Purpose |
@@ -17,7 +16,6 @@ Defines TypeScript interfaces for API interactions and React hook contracts used
17
16
  | `UseChunkCatchupReturn` | Exposes catchup, processing, and buffering controls |
18
17
  | `UseNatsDialogSubscriptionReturn` | Connection state and reconnection counter |
19
18
  | `UseJetStreamDialogSubscriptionReturn` | Connection state plus current stream sequence |
20
- | `UseRealtimeChunkProcessorReturn` | Chunk processing, segment access, and approval status management |
21
19
 
22
20
  ### Callbacks
23
21
  - **`RealtimeChunkCallbacks`** — Rich event callback map for streaming events: `onStreamStart`, `onStreamEnd`, `onSegmentsUpdate`, `onTokenUsage`, `onApprove`, `onReject`, `onEscalatedApproval`, `onApprovalResolved`, `onToolExecuted`, `onDialogClosed`, and more.
@@ -31,7 +29,7 @@ Defines TypeScript interfaces for API interactions and React hook contracts used
31
29
  ## Usage Example
32
30
 
33
31
  ```typescript
34
- const options: UseRealtimeChunkProcessorOptions = {
32
+ const options: ChatStreamReducerOptions = {
35
33
  callbacks: {
36
34
  onSegmentsUpdate: (segments, meta) => {
37
35
  if (meta?.append) appendToLastMessage(segments)
@@ -5,13 +5,9 @@ Defines TypeScript types for message processing pipeline operations, including c
5
5
 
6
6
  | Export | Type | Description |
7
7
  |--------|------|-------------|
8
- | `ParsedChunkAction` | Union type | Discriminated union of all possible chunk parse results (text, tool execution, approvals, metadata, etc.) |
9
8
  | `AccumulatorState` | Interface | Stateful container tracking message segments, pending approvals, and executing tools during stream processing |
10
9
  | `PendingApproval` | Interface | Represents an approval request awaiting user action (command, explanation, type) |
11
10
  | `MessageProcessingOptions` | Interface | Configuration for assistant rendering, approval callbacks, chat filtering, and batch approval UI |
12
- | `ChunkProcessor` | Interface | Contract for processing raw `ChunkData` into `ParsedChunkAction` results |
13
- | `ChunkProcessorOptions` | Interface | Lifecycle callbacks for chunk processing events |
14
- | `MessageTransformer` | Interface | Contract for transforming raw inputs into `ProcessedMessage` objects |
15
11
  | `StreamProcessor` | Interface | Full lifecycle control (start/stop/pause/resume/reset) for stream consumers |
16
12
  | `StreamState` | Interface | Snapshot of stream health: active status, buffered chunks, error log, and last activity timestamp |
17
13
  | `BufferManager` | Interface | CRUD-style contract for managing `ChunkData` buffers |
@@ -21,29 +17,11 @@ Defines TypeScript types for message processing pipeline operations, including c
21
17
 
22
18
  ```typescript
23
19
  import type {
24
- ParsedChunkAction,
25
20
  AccumulatorState,
26
21
  MessageProcessingOptions,
27
22
  StreamState
28
23
  } from './processing.types'
29
24
 
30
- // Handling a parsed chunk action via discriminated union
31
- function handleChunkAction(action: ParsedChunkAction): void {
32
- switch (action.action) {
33
- case 'text':
34
- console.log('Received text:', action.text)
35
- break
36
- case 'tool_execution':
37
- console.log('Tool executing:', action.segment)
38
- break
39
- case 'approval_batch':
40
- console.log('Batch approval request:', action.requestId, action.toolCalls)
41
- break
42
- case 'error':
43
- console.error('Processing error:', action.error, action.details)
44
- break
45
- }
46
- }
47
25
 
48
26
  // Initializing accumulator state
49
27
  const state: AccumulatorState = {
@@ -65,4 +43,9 @@ const options: MessageProcessingOptions = {
65
43
  logRejection(requestId)
66
44
  }
67
45
  }
68
- ```
46
+ ```
47
+
48
+ > NOTE: the wire-chunk vocabulary now lives in `src/chat-protocol/events.ts`
49
+ > (`ChatStreamEvent`, produced by `decodeNatsChunk`). The old
50
+ > `ParsedChunkAction` union and the `ChunkProcessor` contract were deleted
51
+ > together with the legacy `chunk-parser`.
@@ -213,79 +213,12 @@ export interface RealtimeChunkCallbacks {
213
213
  onDialogClosed?: () => void
214
214
  }
215
215
 
216
- export interface UseRealtimeChunkProcessorOptions {
217
- callbacks: RealtimeChunkCallbacks
218
- /**
219
- * Filter approval types that should be displayed directly
220
- * Others will trigger onEscalatedApproval
221
- * Default: ['CLIENT']
222
- */
223
- displayApprovalTypes?: string[]
224
- /**
225
- * Map of existing approval statuses
226
- */
227
- approvalStatuses?: Record<string, ChatApprovalStatus>
228
- /**
229
- * Initialize accumulator with existing state from incomplete historical message
230
- * Used to continue building messages across page refreshes or reconnections
231
- */
232
- initialState?: {
233
- /** Existing segments to continue building upon */
234
- existingSegments?: MessageSegment[]
235
- /** Pending approvals that haven't been resolved */
236
- pendingApprovals?: Map<string, { command: string; explanation?: string; approvalType: string }>
237
- /** Executing tools waiting for completion */
238
- executingTools?: Map<string, ExecutingToolState>
239
- /** Escalated approvals */
240
- escalatedApprovals?: Map<
241
- string,
242
- { command: string; explanation?: string; approvalType: string; toolCalls?: PendingToolCallData[] }
243
- >
244
- }
245
- /**
246
- * Consumer-owned (e.g. set in `openframe-oss-tenant` chat client via the
247
- * `'batch-approvals'` feature flag and forwarded here). The lib does NOT
248
- * default this to a batch-on behavior — when omitted it falls back to the
249
- * legacy single-card rendering.
250
- *
251
- * When true: `APPROVAL_REQUEST` chunks containing `toolCalls[]` are rendered
252
- * as a single batch card. When false / omitted: the batch is split into N
253
- * legacy approval cards (one per tool that requires approval), all sharing
254
- * the same `approvalRequestId`. Tools with `requiresApproval=false` are
255
- * dropped from the UI in the unfolded mode.
256
- */
257
- batchApprovalsEnabled?: boolean
258
- /**
259
- * Engages the direct-mode barrier optimistically: once true, all AI-assistant
260
- * chunks (text, thinking, tool executions, approvals, metadata, errors, etc.)
261
- * are dropped and any open stream is torn down, leaving only human/control
262
- * messages. A `DIRECT_MESSAGE` chunk engages the same barrier automatically
263
- * regardless of this flag. Pass this from a host that already knows the dialog
264
- * switched to direct mode (e.g. an optimistic mode toggle) to close the race
265
- * window before the server emits the first `DIRECT_MESSAGE`.
266
- *
267
- * Do NOT set this when the host reconstructs history by replaying chunks
268
- * through `processChunk` — a static flag would drop legitimate pre-switch AI
269
- * history. Rely on the in-order `DIRECT_MESSAGE` detection instead.
270
- */
271
- isDirectMode?: boolean
272
- }
273
-
274
- export interface UseRealtimeChunkProcessorReturn {
275
- /** Process a single chunk */
276
- processChunk: (chunk: unknown) => void
277
- /** Get current segments */
278
- getSegments: () => MessageSegment[]
279
- /** Reset the accumulator */
280
- reset: () => void
281
- /** Update approval status for a request */
282
- updateApprovalStatus: (requestId: string, status: ChatApprovalStatus, resolvedByName?: string | null) => MessageSegment[]
283
- /** Get pending approval requests */
284
- getPendingApprovals: () => Map<
285
- string,
286
- { command: string; explanation?: string; approvalType: string; toolCalls?: PendingToolCallData[] }
287
- >
288
- }
216
+ // NOTE: `UseRealtimeChunkProcessorOptions` / `UseRealtimeChunkProcessorReturn`
217
+ // were DELETED along with the `useRealtimeChunkProcessor` compat hook. The
218
+ // equivalents are `ChatStreamReducerOptions` + `ChatStreamReducer` in
219
+ // `../stream/chat-stream-reducer`. `RealtimeChunkCallbacks` above SURVIVES:
220
+ // it is still the canonical description of the effect names/args the reducer
221
+ // emits via `ChatReducerEffect`.
289
222
 
290
223
  // ========== API Request Types ==========
291
224
 
@@ -3,37 +3,14 @@
3
3
  * Contains types for message parsing, accumulation, and processing
4
4
  */
5
5
 
6
- import type { MessageSegment, ProcessedMessage, ToolExecutionSegment, TokenUsageData, PendingToolCallData, ExecutingToolState } from './message.types'
6
+ import type { MessageSegment, PendingToolCallData, ExecutingToolState } from './message.types'
7
7
  import type { ChatApprovalStatus, AssistantType } from './chat.types'
8
- import type { ChunkData, NatsMessageType } from './network.types'
9
-
10
- // ========== Parsed Chunk Result Types ==========
11
-
12
- export type ParsedChunkAction =
13
- | { action: 'message_start' }
14
- | { action: 'message_end' }
15
- | { action: 'error'; error: string; details?: string }
16
- | { action: 'metadata'; modelDisplayName: string; modelName: string; providerName: string; contextWindow: number }
17
- | { action: 'text'; text: string }
18
- | { action: 'thinking'; text: string }
19
- | { action: 'tool_execution'; segment: ToolExecutionSegment }
20
- | { action: 'approval_request'; requestId: string; command: string; explanation?: string; approvalType: string }
21
- | { action: 'approval_batch'; requestId: string; approvalType: string; toolCalls: PendingToolCallData[] }
22
- | { action: 'approval_result'; requestId: string; approved: boolean; approvalType: string; resolvedByName?: string | null }
23
- | {
24
- action: 'message_request'
25
- text: string
26
- ownerType?: string
27
- displayName?: string
28
- userId?: string
29
- contextItems?: Array<{ type: string; id: string }>
30
- }
31
- | { action: 'token_usage'; data: TokenUsageData }
32
- | { action: 'direct_message'; text: string; ownerType?: string; displayName?: string; userId?: string }
33
- | { action: 'system'; text: string }
34
- | { action: 'context_compaction_start' }
35
- | { action: 'context_compaction_end'; summary?: string }
36
- | { action: 'dialog_closed' }
8
+ import type { ChunkData } from './network.types'
9
+
10
+ // NOTE: the `ParsedChunkAction` union that used to live here was DELETED
11
+ // alongside the legacy `chunk-parser`. The wire → normalized-event
12
+ // vocabulary is now `ChatStreamEvent` in `src/chat-protocol/events.ts`,
13
+ // produced by `decodeNatsChunk`.
37
14
 
38
15
  // ========== Accumulator State ==========
39
16
 
@@ -81,31 +58,13 @@ export interface MessageProcessingOptions {
81
58
  batchApprovalsEnabled?: boolean
82
59
  }
83
60
 
84
- // ========== Chunk Processing Types ==========
85
-
86
- export interface ChunkProcessor {
87
- processChunk: (chunk: ChunkData, messageType: NatsMessageType) => ParsedChunkAction | null
88
- reset: () => void
89
- }
90
-
91
- export interface ChunkProcessorOptions {
92
- onMessageStart?: () => void
93
- onMessageEnd?: () => void
94
- onError?: (error: string, details?: string) => void
95
- onText?: (text: string) => void
96
- onToolExecution?: (segment: MessageSegment) => void
97
- onApprovalRequest?: (data: any) => void
98
- onApprovalResult?: (data: any) => void
99
- onMetadata?: (data: any) => void
100
- }
61
+ // NOTE: `ChunkProcessorOptions` (the options bag of the deleted
62
+ // `ChunkProcessor`) and `MessageTransformer` were DELETED — both were left
63
+ // behind by the chunk-processor removal with zero references in lib, hub, or
64
+ // app.
101
65
 
102
66
  // ========== Message Transformation Types ==========
103
67
 
104
- export interface MessageTransformer {
105
- transform: (input: any) => ProcessedMessage | null
106
- batch: (inputs: any[]) => ProcessedMessage[]
107
- }
108
-
109
68
  export interface TransformationOptions {
110
69
  preserveOriginal?: boolean
111
70
  mergeSegments?: boolean
@@ -5,7 +5,6 @@ Barrel export module that consolidates and re-exports all message processing, ch
5
5
 
6
6
  | Category | Exports |
7
7
  |----------|---------|
8
- | **Chunk Parsing** | `parseChunkToAction`, `isControlChunk`, `isErrorChunk`, `isMetadataChunk`, `extractTextFromChunk` |
9
8
  | **Message Accumulation** | `MessageSegmentAccumulator`, `createMessageSegmentAccumulator`, `AccumulatorCallbacks` |
10
9
  | **Historical Messages** | `processHistoricalMessages`, `extractErrorMessages`, `processHistoricalMessagesWithErrors` |
11
10
  | **Chat Navigation** | `handleChatNavClick`, `resolveExternalNavigation`, `decideNewTab`, `computeIsNewTab`, `buildAnchorProps` |
@@ -20,7 +19,6 @@ Barrel export module that consolidates and re-exports all message processing, ch
20
19
 
21
20
  ```typescript
22
21
  import {
23
- parseChunkToAction,
24
22
  createMessageSegmentAccumulator,
25
23
  handleChatNavClick,
26
24
  getChatProxyAuth,
@@ -30,9 +28,6 @@ import {
30
28
  getStatusColorScheme,
31
29
  } from '@flamingo/chat-utils'
32
30
 
33
- // Parse a streaming chunk from the AI response
34
- const action = parseChunkToAction(rawChunk)
35
-
36
31
  // Accumulate streamed message segments
37
32
  const accumulator = createMessageSegmentAccumulator({
38
33
  onSegmentComplete: (segment) => console.log('Segment:', segment),
@@ -0,0 +1,418 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`extractErrorMessages / processHistoricalMessagesWithErrors — golden > extractErrorMessages surfaces ERROR rows as standalone error-role messages 1`] = `
4
+ [
5
+ {
6
+ "assistantType": "mingo",
7
+ "avatar": undefined,
8
+ "content": "Agent crashed",
9
+ "id": "a5-error",
10
+ "name": "Mingo AI",
11
+ "role": "error",
12
+ "timestamp": 2026-07-19T09:04:00.000Z,
13
+ },
14
+ ]
15
+ `;
16
+
17
+ exports[`extractErrorMessages / processHistoricalMessagesWithErrors — golden > processHistoricalMessagesWithErrors output parity on the same corpus (snapshot) 1`] = `
18
+ {
19
+ "escalatedApprovals": [],
20
+ "messages": [
21
+ {
22
+ "authorType": "user",
23
+ "avatar": undefined,
24
+ "content": "diagnose this device please",
25
+ "contextItems": [
26
+ {
27
+ "id": "dev-1",
28
+ "label": "dev-1",
29
+ "type": "device",
30
+ },
31
+ ],
32
+ "id": "u1",
33
+ "name": "You",
34
+ "role": "user",
35
+ "streamSeq": 10,
36
+ "timestamp": 2026-07-19T09:00:00.000Z,
37
+ },
38
+ {
39
+ "assistantType": "mingo",
40
+ "authorType": "mingo",
41
+ "avatar": "/avatars/mingo.png",
42
+ "content": [
43
+ {
44
+ "text": "Checking device state… looks like disk pressure.",
45
+ "type": "thinking",
46
+ },
47
+ {
48
+ "text": "The device is low on disk. ",
49
+ "type": "text",
50
+ },
51
+ {
52
+ "data": {
53
+ "integratedToolType": "TACTICAL_RMM",
54
+ "parameters": {
55
+ "script": "cleanup.sh",
56
+ },
57
+ "result": "Freed 2.3 GB",
58
+ "success": true,
59
+ "toolExecutionRequestId": "exec-1",
60
+ "toolFunction": "run_script",
61
+ "toolTitle": "Run cleanup script",
62
+ "type": "EXECUTED_TOOL",
63
+ },
64
+ "type": "tool_execution",
65
+ },
66
+ {
67
+ "text": "Cleanup done.",
68
+ "type": "text",
69
+ },
70
+ ],
71
+ "id": "a2",
72
+ "name": "Mingo AI",
73
+ "role": "assistant",
74
+ "streamSeq": 20,
75
+ "timestamp": 2026-07-19T09:00:05.000Z,
76
+ },
77
+ {
78
+ "authorType": "admin",
79
+ "avatar": "/avatars/jane.png",
80
+ "content": "please restart the broker",
81
+ "id": "u2",
82
+ "name": "Jane Admin",
83
+ "role": "user",
84
+ "timestamp": 2026-07-19T09:01:00.000Z,
85
+ },
86
+ {
87
+ "assistantType": "mingo",
88
+ "authorType": "mingo",
89
+ "avatar": "/avatars/mingo.png",
90
+ "content": [
91
+ {
92
+ "text": "I need approval to restart it.",
93
+ "type": "text",
94
+ },
95
+ {
96
+ "data": {
97
+ "approvalType": "CLIENT",
98
+ "command": "systemctl restart nats",
99
+ "explanation": "Restart the message broker",
100
+ "requestId": "req-1",
101
+ },
102
+ "onApprove": undefined,
103
+ "onReject": undefined,
104
+ "status": "approved",
105
+ "type": "approval_request",
106
+ },
107
+ {
108
+ "data": {
109
+ "approvalRequestId": "batch-1",
110
+ "approvalType": "CLIENT",
111
+ "executions": {
112
+ "exec-a": {
113
+ "result": "Ticket #77 created",
114
+ "status": "done",
115
+ "success": true,
116
+ },
117
+ },
118
+ "toolCalls": [
119
+ {
120
+ "approvalType": "CLIENT",
121
+ "requiresApproval": true,
122
+ "toolCallArguments": {
123
+ "subject": "Printer down",
124
+ },
125
+ "toolExecutionRequestId": "exec-a",
126
+ "toolName": "create_ticket",
127
+ "toolTitle": "Create ticket",
128
+ },
129
+ {
130
+ "requiresApproval": false,
131
+ "toolExecutionRequestId": "exec-b",
132
+ "toolName": "read_kb",
133
+ },
134
+ ],
135
+ },
136
+ "onApprove": undefined,
137
+ "onReject": undefined,
138
+ "resolvedByName": "Alice Client",
139
+ "status": "approved",
140
+ "type": "approval_batch",
141
+ },
142
+ ],
143
+ "id": "a4",
144
+ "name": "Mingo AI",
145
+ "role": "assistant",
146
+ "streamSeq": 30,
147
+ "timestamp": 2026-07-19T09:01:05.000Z,
148
+ },
149
+ {
150
+ "authorType": "system",
151
+ "content": "",
152
+ "id": "s1",
153
+ "name": "Technician joined the chat",
154
+ "role": "user",
155
+ "streamSeq": 40,
156
+ "timestamp": 2026-07-19T09:03:00.000Z,
157
+ },
158
+ {
159
+ "assistantType": "mingo",
160
+ "authorType": "mingo",
161
+ "avatar": "/avatars/mingo.png",
162
+ "content": [
163
+ {
164
+ "text": "Attempting one more thing… ",
165
+ "type": "text",
166
+ },
167
+ {
168
+ "details": "boom",
169
+ "title": "Agent crashed",
170
+ "type": "error",
171
+ },
172
+ ],
173
+ "id": "a5",
174
+ "name": "Mingo AI",
175
+ "role": "assistant",
176
+ "timestamp": 2026-07-19T09:04:00.000Z,
177
+ },
178
+ ],
179
+ }
180
+ `;
181
+
182
+ exports[`processHistoricalMessages — golden corpus > chatTypeFilter drops rows of other chat types 1`] = `
183
+ [
184
+ {
185
+ "authorType": "user",
186
+ "avatar": undefined,
187
+ "content": "visible",
188
+ "id": "u1",
189
+ "name": "You",
190
+ "role": "user",
191
+ "timestamp": 2026-07-19T09:00:00.000Z,
192
+ },
193
+ ]
194
+ `;
195
+
196
+ exports[`processHistoricalMessages — golden corpus > owner-type author resolution: CLIENT vs ADMIN vs ADMIN-without-name display names/avatars 1`] = `
197
+ [
198
+ {
199
+ "authorType": "user",
200
+ "avatar": undefined,
201
+ "content": "from client",
202
+ "id": "u-client",
203
+ "name": "You",
204
+ "role": "user",
205
+ "timestamp": 2026-07-19T09:00:00.000Z,
206
+ },
207
+ {
208
+ "authorType": "admin",
209
+ "avatar": "/a.png",
210
+ "content": "from named admin",
211
+ "id": "u-admin-named",
212
+ "name": "Jane Admin",
213
+ "role": "user",
214
+ "timestamp": 2026-07-19T09:00:01.000Z,
215
+ },
216
+ {
217
+ "authorType": "admin",
218
+ "avatar": undefined,
219
+ "content": "from anonymous admin",
220
+ "id": "u-admin-anon",
221
+ "name": "Admin",
222
+ "role": "user",
223
+ "timestamp": 2026-07-19T09:00:02.000Z,
224
+ },
225
+ ]
226
+ `;
227
+
228
+ exports[`processHistoricalMessages — golden corpus > processes the full recorded dialog (snapshot) 1`] = `
229
+ {
230
+ "escalatedApprovals": [],
231
+ "messages": [
232
+ {
233
+ "authorType": "user",
234
+ "avatar": undefined,
235
+ "content": "diagnose this device please",
236
+ "contextItems": [
237
+ {
238
+ "id": "dev-1",
239
+ "label": "dev-1",
240
+ "type": "device",
241
+ },
242
+ ],
243
+ "id": "u1",
244
+ "name": "You",
245
+ "role": "user",
246
+ "streamSeq": 10,
247
+ "timestamp": 2026-07-19T09:00:00.000Z,
248
+ },
249
+ {
250
+ "assistantType": "mingo",
251
+ "authorType": "mingo",
252
+ "avatar": "/avatars/mingo.png",
253
+ "content": [
254
+ {
255
+ "text": "Checking device state… looks like disk pressure.",
256
+ "type": "thinking",
257
+ },
258
+ {
259
+ "text": "The device is low on disk. ",
260
+ "type": "text",
261
+ },
262
+ {
263
+ "data": {
264
+ "integratedToolType": "TACTICAL_RMM",
265
+ "parameters": {
266
+ "script": "cleanup.sh",
267
+ },
268
+ "result": "Freed 2.3 GB",
269
+ "success": true,
270
+ "toolExecutionRequestId": "exec-1",
271
+ "toolFunction": "run_script",
272
+ "toolTitle": "Run cleanup script",
273
+ "type": "EXECUTED_TOOL",
274
+ },
275
+ "type": "tool_execution",
276
+ },
277
+ {
278
+ "text": "Cleanup done.",
279
+ "type": "text",
280
+ },
281
+ ],
282
+ "id": "a2",
283
+ "name": "Mingo AI",
284
+ "role": "assistant",
285
+ "streamSeq": 20,
286
+ "timestamp": 2026-07-19T09:00:05.000Z,
287
+ },
288
+ {
289
+ "authorType": "admin",
290
+ "avatar": "/avatars/jane.png",
291
+ "content": "please restart the broker",
292
+ "id": "u2",
293
+ "name": "Jane Admin",
294
+ "role": "user",
295
+ "timestamp": 2026-07-19T09:01:00.000Z,
296
+ },
297
+ {
298
+ "assistantType": "mingo",
299
+ "authorType": "mingo",
300
+ "avatar": "/avatars/mingo.png",
301
+ "content": [
302
+ {
303
+ "text": "I need approval to restart it.",
304
+ "type": "text",
305
+ },
306
+ {
307
+ "data": {
308
+ "approvalType": "CLIENT",
309
+ "command": "systemctl restart nats",
310
+ "explanation": "Restart the message broker",
311
+ "requestId": "req-1",
312
+ },
313
+ "onApprove": undefined,
314
+ "onReject": undefined,
315
+ "status": "approved",
316
+ "type": "approval_request",
317
+ },
318
+ {
319
+ "data": {
320
+ "approvalRequestId": "batch-1",
321
+ "approvalType": "CLIENT",
322
+ "executions": {
323
+ "exec-a": {
324
+ "result": "Ticket #77 created",
325
+ "status": "done",
326
+ "success": true,
327
+ },
328
+ },
329
+ "toolCalls": [
330
+ {
331
+ "approvalType": "CLIENT",
332
+ "requiresApproval": true,
333
+ "toolCallArguments": {
334
+ "subject": "Printer down",
335
+ },
336
+ "toolExecutionRequestId": "exec-a",
337
+ "toolName": "create_ticket",
338
+ "toolTitle": "Create ticket",
339
+ },
340
+ {
341
+ "requiresApproval": false,
342
+ "toolExecutionRequestId": "exec-b",
343
+ "toolName": "read_kb",
344
+ },
345
+ ],
346
+ },
347
+ "onApprove": undefined,
348
+ "onReject": undefined,
349
+ "resolvedByName": "Alice Client",
350
+ "status": "approved",
351
+ "type": "approval_batch",
352
+ },
353
+ ],
354
+ "id": "a4",
355
+ "name": "Mingo AI",
356
+ "role": "assistant",
357
+ "streamSeq": 30,
358
+ "timestamp": 2026-07-19T09:01:05.000Z,
359
+ },
360
+ {
361
+ "authorType": "system",
362
+ "content": "",
363
+ "id": "s1",
364
+ "name": "Technician joined the chat",
365
+ "role": "user",
366
+ "streamSeq": 40,
367
+ "timestamp": 2026-07-19T09:03:00.000Z,
368
+ },
369
+ {
370
+ "assistantType": "mingo",
371
+ "authorType": "mingo",
372
+ "avatar": "/avatars/mingo.png",
373
+ "content": [
374
+ {
375
+ "text": "Attempting one more thing… ",
376
+ "type": "text",
377
+ },
378
+ {
379
+ "details": "boom",
380
+ "title": "Agent crashed",
381
+ "type": "error",
382
+ },
383
+ ],
384
+ "id": "a5",
385
+ "name": "Mingo AI",
386
+ "role": "assistant",
387
+ "timestamp": 2026-07-19T09:04:00.000Z,
388
+ },
389
+ ],
390
+ }
391
+ `;
392
+
393
+ exports[`processHistoricalMessages — golden corpus > unresolved single approval is resurrected as a synthetic pending-approvals bubble 1`] = `
394
+ [
395
+ {
396
+ "assistantType": "fae",
397
+ "avatar": undefined,
398
+ "content": [
399
+ {
400
+ "data": {
401
+ "approvalType": "CLIENT",
402
+ "command": "reboot server",
403
+ "explanation": undefined,
404
+ "requestId": "req-pending",
405
+ },
406
+ "onApprove": undefined,
407
+ "onReject": undefined,
408
+ "status": "pending",
409
+ "type": "approval_request",
410
+ },
411
+ ],
412
+ "id": "pending-approvals-1784541600000",
413
+ "name": "Fae",
414
+ "role": "assistant",
415
+ "timestamp": 2026-07-20T10:00:00.000Z,
416
+ },
417
+ ]
418
+ `;