@flamingo-stack/openframe-frontend-core 0.0.492-1506.3956.1 → 0.0.492

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 (296) hide show
  1. package/dist/{chunk-KX3K2EH4.cjs → chunk-2XAAFAQT.cjs} +11 -11
  2. package/dist/{chunk-KX3K2EH4.cjs.map → chunk-2XAAFAQT.cjs.map} +1 -1
  3. package/dist/{chunk-JHEIOXXZ.js → chunk-4AWRPTKE.js} +5 -6
  4. package/dist/chunk-4AWRPTKE.js.map +1 -0
  5. package/dist/{chunk-PTXZB2KW.js → chunk-4J3CB4KO.js} +2 -2
  6. package/dist/{chunk-7N7YZCHR.cjs → chunk-4MLOMMDX.cjs} +5519 -7555
  7. package/dist/chunk-4MLOMMDX.cjs.map +1 -0
  8. package/dist/{chunk-MEMRQTOI.js → chunk-56J7RLMM.js} +10434 -12470
  9. package/dist/chunk-56J7RLMM.js.map +1 -0
  10. package/dist/{chunk-MEIGDK7M.cjs → chunk-5ICPQAUI.cjs} +60 -60
  11. package/dist/chunk-5ICPQAUI.cjs.map +1 -0
  12. package/dist/{chunk-BEEPU44B.js → chunk-5RHJVPL7.js} +10 -10
  13. package/dist/chunk-5RHJVPL7.js.map +1 -0
  14. package/dist/{chunk-XOFE2RT4.js → chunk-BTIRYGDT.js} +4 -4
  15. package/dist/{chunk-JSEJ5MH5.cjs → chunk-DY6AJNVK.cjs} +5 -5
  16. package/dist/{chunk-JSEJ5MH5.cjs.map → chunk-DY6AJNVK.cjs.map} +1 -1
  17. package/dist/{chunk-PLB6CQSO.js → chunk-FG5ALORQ.js} +2 -2
  18. package/dist/{chunk-QG2EBIH5.cjs → chunk-J2J36PEN.cjs} +31 -31
  19. package/dist/{chunk-QG2EBIH5.cjs.map → chunk-J2J36PEN.cjs.map} +1 -1
  20. package/dist/{chunk-A6FPYAUD.cjs → chunk-LIRXKEOE.cjs} +15 -15
  21. package/dist/{chunk-A6FPYAUD.cjs.map → chunk-LIRXKEOE.cjs.map} +1 -1
  22. package/dist/{chunk-MSL5NE3N.cjs → chunk-LVDI7R7T.cjs} +37 -37
  23. package/dist/{chunk-MSL5NE3N.cjs.map → chunk-LVDI7R7T.cjs.map} +1 -1
  24. package/dist/{chunk-MPUQFRJG.cjs → chunk-M4SCYPCR.cjs} +7 -7
  25. package/dist/{chunk-MPUQFRJG.cjs.map → chunk-M4SCYPCR.cjs.map} +1 -1
  26. package/dist/{chunk-QDGB2DKY.cjs → chunk-O6S6Q52W.cjs} +26 -26
  27. package/dist/{chunk-QDGB2DKY.cjs.map → chunk-O6S6Q52W.cjs.map} +1 -1
  28. package/dist/{chunk-W56JYDSC.cjs → chunk-OFFYASUY.cjs} +27 -28
  29. package/dist/chunk-OFFYASUY.cjs.map +1 -0
  30. package/dist/{chunk-NCAN6VUF.js → chunk-P3ITKTUE.js} +2 -2
  31. package/dist/{chunk-M6FEGPQJ.cjs → chunk-PI5BMKV3.cjs} +62 -62
  32. package/dist/{chunk-M6FEGPQJ.cjs.map → chunk-PI5BMKV3.cjs.map} +1 -1
  33. package/dist/{chunk-34TDA22K.js → chunk-QHRNQTW5.js} +2 -2
  34. package/dist/{chunk-OL3MJKUI.js → chunk-SZWMJIH3.js} +2 -2
  35. package/dist/{chunk-MZRIRQYV.js → chunk-U5LU56JE.js} +2 -2
  36. package/dist/{chunk-C65NCIMV.cjs → chunk-VML66FJQ.cjs} +9 -9
  37. package/dist/{chunk-C65NCIMV.cjs.map → chunk-VML66FJQ.cjs.map} +1 -1
  38. package/dist/{chunk-3LKB722U.js → chunk-WKWZ7LVC.js} +2 -2
  39. package/dist/{chunk-J3VBVR4W.js → chunk-WPFLV4QJ.js} +4 -4
  40. package/dist/components/case-studies/index.cjs +8 -8
  41. package/dist/components/case-studies/index.js +2 -2
  42. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  43. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  44. package/dist/components/chat/hooks/index.d.ts +1 -0
  45. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  46. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  47. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +48 -15
  48. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  49. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +6 -0
  50. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +1 -0
  51. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +57 -10
  52. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  53. package/dist/components/chat/index.cjs +2 -10
  54. package/dist/components/chat/index.cjs.map +1 -1
  55. package/dist/components/chat/index.d.ts +0 -1
  56. package/dist/components/chat/index.d.ts.map +1 -1
  57. package/dist/components/chat/index.js +13 -21
  58. package/dist/components/chat/types/api.types.d.ts +81 -1
  59. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  60. package/dist/components/chat/types/processing.types.d.ts +93 -2
  61. package/dist/components/chat/types/processing.types.d.ts.map +1 -1
  62. package/dist/components/chat/utils/chunk-parser.d.ts +25 -0
  63. package/dist/components/chat/utils/chunk-parser.d.ts.map +1 -0
  64. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +6 -34
  65. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
  66. package/dist/components/chat/utils/index.d.ts +3 -2
  67. package/dist/components/chat/utils/index.d.ts.map +1 -1
  68. package/dist/components/chat/utils/process-historical-messages.d.ts +11 -59
  69. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  70. package/dist/components/contact/index.cjs +3 -3
  71. package/dist/components/contact/index.js +2 -2
  72. package/dist/components/docs/index.cjs +5 -5
  73. package/dist/components/docs/index.js +4 -4
  74. package/dist/components/embeds/index.cjs +3 -3
  75. package/dist/components/embeds/index.js +2 -2
  76. package/dist/components/faq/index.cjs +3 -3
  77. package/dist/components/faq/index.js +2 -2
  78. package/dist/components/features/floating-walkthrough-video.d.ts.map +1 -1
  79. package/dist/components/features/index.cjs +2 -2
  80. package/dist/components/features/index.js +1 -1
  81. package/dist/components/help-center-pages/index.cjs +20 -20
  82. package/dist/components/help-center-pages/index.js +11 -11
  83. package/dist/components/index.cjs +130 -172
  84. package/dist/components/index.cjs.map +1 -1
  85. package/dist/components/index.js +21 -63
  86. package/dist/components/index.js.map +1 -1
  87. package/dist/components/navigation/index.cjs +2 -2
  88. package/dist/components/navigation/index.js +1 -1
  89. package/dist/components/navigation/navigation-sidebar-item.d.ts +23 -1
  90. package/dist/components/navigation/navigation-sidebar-item.d.ts.map +1 -1
  91. package/dist/components/navigation/navigation-sidebar.d.ts.map +1 -1
  92. package/dist/components/onboarding-guides/index.cjs +5 -5
  93. package/dist/components/onboarding-guides/index.js +4 -4
  94. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  95. package/dist/components/related-content/index.cjs +3 -3
  96. package/dist/components/related-content/index.js +2 -2
  97. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  98. package/dist/components/tickets/index.cjs +5 -5
  99. package/dist/components/tickets/index.js +4 -4
  100. package/dist/components/ui/data-table/data-table-column-filter.d.ts.map +1 -1
  101. package/dist/components/ui/data-table/data-table-header.d.ts.map +1 -1
  102. package/dist/components/ui/data-table/data-table-skeleton.d.ts.map +1 -1
  103. package/dist/components/ui/index.cjs +2 -44
  104. package/dist/components/ui/index.cjs.map +1 -1
  105. package/dist/components/ui/index.d.ts +2 -1
  106. package/dist/components/ui/index.d.ts.map +1 -1
  107. package/dist/components/ui/index.js +13 -55
  108. package/dist/components/ui/rich-markdown-renderer.d.ts +34 -0
  109. package/dist/components/ui/rich-markdown-renderer.d.ts.map +1 -0
  110. package/dist/components/ui/simple-markdown-renderer.d.ts +73 -0
  111. package/dist/components/ui/simple-markdown-renderer.d.ts.map +1 -0
  112. package/dist/components/ui/tab-navigation.d.ts.map +1 -1
  113. package/dist/index.cjs +2 -60
  114. package/dist/index.cjs.map +1 -1
  115. package/dist/index.js +13 -71
  116. package/dist/utils/index.cjs +40 -169
  117. package/dist/utils/index.cjs.map +1 -1
  118. package/dist/utils/index.d.ts +0 -1
  119. package/dist/utils/index.d.ts.map +1 -1
  120. package/dist/utils/index.js +41 -162
  121. package/dist/utils/index.js.map +1 -1
  122. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  123. package/package.json +1 -7
  124. package/src/components/chat/__tests__/chat-message-list.test.tsx +5 -293
  125. package/src/components/chat/chat-message-enhanced.tsx +20 -122
  126. package/src/components/chat/chat-message-list.tsx +109 -358
  127. package/src/components/chat/embeddable-chat.tsx +0 -6
  128. package/src/components/chat/hooks/.index.md +33 -30
  129. package/src/components/chat/hooks/.use-nats-chat-adapter.md +55 -36
  130. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +77 -0
  131. package/src/components/chat/hooks/index.ts +1 -0
  132. package/src/components/chat/hooks/use-chat.ts +0 -8
  133. package/src/components/chat/hooks/use-nats-chat-adapter.ts +825 -243
  134. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +489 -0
  135. package/src/components/chat/hooks/use-sse-chat-adapter.ts +684 -380
  136. package/src/components/chat/index.ts +0 -5
  137. package/src/components/chat/thinking-display.tsx +1 -1
  138. package/src/components/chat/types/.api.types.md +49 -39
  139. package/src/components/chat/types/.processing.types.md +58 -29
  140. package/src/components/chat/types/api.types.ts +73 -6
  141. package/src/components/chat/types/processing.types.ts +53 -11
  142. package/src/components/chat/utils/.chunk-parser.md +62 -0
  143. package/src/components/chat/utils/.index.md +40 -31
  144. package/src/components/chat/utils/chunk-parser.ts +262 -0
  145. package/src/components/chat/utils/extract-incomplete-message-state.ts +5 -63
  146. package/src/components/chat/utils/index.ts +8 -5
  147. package/src/components/chat/utils/process-historical-messages.ts +386 -358
  148. package/src/components/features/floating-walkthrough-video.tsx +3 -1
  149. package/src/components/navigation/navigation-sidebar-item.tsx +80 -30
  150. package/src/components/navigation/navigation-sidebar.tsx +106 -46
  151. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +4 -22
  152. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  153. package/src/components/shared/product-release/release-detail-page.tsx +4 -19
  154. package/src/components/ui/.simple-markdown-renderer.md +52 -0
  155. package/src/components/ui/__tests__/tab-navigation.test.tsx +159 -0
  156. package/src/components/ui/data-table/data-table-column-filter.tsx +7 -1
  157. package/src/components/ui/data-table/data-table-header.tsx +4 -1
  158. package/src/components/ui/data-table/data-table-skeleton.tsx +7 -0
  159. package/src/components/ui/index.ts +2 -1
  160. package/src/components/ui/release-changelog-section.tsx +1 -1
  161. package/src/components/ui/rich-markdown-renderer.tsx +1223 -0
  162. package/src/components/ui/simple-markdown-renderer.tsx +964 -0
  163. package/src/components/ui/tab-navigation.tsx +370 -171
  164. package/src/components/ui/ticket-info-section.tsx +1 -1
  165. package/src/utils/index.ts +0 -1
  166. package/src/utils/markdown-section-extractor.ts +56 -41
  167. package/dist/chat-protocol/decode.d.ts +0 -58
  168. package/dist/chat-protocol/decode.d.ts.map +0 -1
  169. package/dist/chat-protocol/encode.d.ts +0 -44
  170. package/dist/chat-protocol/encode.d.ts.map +0 -1
  171. package/dist/chat-protocol/env-flag.d.ts +0 -35
  172. package/dist/chat-protocol/env-flag.d.ts.map +0 -1
  173. package/dist/chat-protocol/events.d.ts +0 -207
  174. package/dist/chat-protocol/events.d.ts.map +0 -1
  175. package/dist/chat-protocol/frames.d.ts +0 -213
  176. package/dist/chat-protocol/frames.d.ts.map +0 -1
  177. package/dist/chat-protocol/index.cjs +0 -500
  178. package/dist/chat-protocol/index.cjs.map +0 -1
  179. package/dist/chat-protocol/index.d.ts +0 -18
  180. package/dist/chat-protocol/index.d.ts.map +0 -1
  181. package/dist/chat-protocol/index.js +0 -484
  182. package/dist/chat-protocol/index.js.map +0 -1
  183. package/dist/chat-protocol/ip-normalize.d.ts +0 -44
  184. package/dist/chat-protocol/ip-normalize.d.ts.map +0 -1
  185. package/dist/chat-protocol/nats-decoder.d.ts +0 -26
  186. package/dist/chat-protocol/nats-decoder.d.ts.map +0 -1
  187. package/dist/chunk-7N7YZCHR.cjs.map +0 -1
  188. package/dist/chunk-BEEPU44B.js.map +0 -1
  189. package/dist/chunk-JHEIOXXZ.js.map +0 -1
  190. package/dist/chunk-MEIGDK7M.cjs.map +0 -1
  191. package/dist/chunk-MEMRQTOI.js.map +0 -1
  192. package/dist/chunk-W56JYDSC.cjs.map +0 -1
  193. package/dist/components/chat/stream/chat-dialog-store.d.ts +0 -184
  194. package/dist/components/chat/stream/chat-dialog-store.d.ts.map +0 -1
  195. package/dist/components/chat/stream/chat-stream-reducer.d.ts +0 -367
  196. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +0 -1
  197. package/dist/components/chat/stream/delta-batcher.d.ts +0 -51
  198. package/dist/components/chat/stream/delta-batcher.d.ts.map +0 -1
  199. package/dist/components/chat/stream/index.d.ts +0 -17
  200. package/dist/components/chat/stream/index.d.ts.map +0 -1
  201. package/dist/components/chat/stream/message-mutations.d.ts +0 -77
  202. package/dist/components/chat/stream/message-mutations.d.ts.map +0 -1
  203. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +0 -22
  204. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +0 -1
  205. package/dist/components/ui/markdown/base-components.d.ts +0 -51
  206. package/dist/components/ui/markdown/base-components.d.ts.map +0 -1
  207. package/dist/components/ui/markdown/engine.d.ts +0 -99
  208. package/dist/components/ui/markdown/engine.d.ts.map +0 -1
  209. package/dist/components/ui/markdown/heading-ids.d.ts +0 -65
  210. package/dist/components/ui/markdown/heading-ids.d.ts.map +0 -1
  211. package/dist/components/ui/markdown/index.d.ts +0 -18
  212. package/dist/components/ui/markdown/index.d.ts.map +0 -1
  213. package/dist/components/ui/markdown/mermaid-diagram.d.ts +0 -79
  214. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +0 -1
  215. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +0 -14
  216. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +0 -1
  217. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +0 -40
  218. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +0 -1
  219. package/dist/components/ui/markdown/rich/shortcodes.d.ts +0 -8
  220. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +0 -1
  221. package/dist/components/ui/markdown/sanitize.d.ts +0 -153
  222. package/dist/components/ui/markdown/sanitize.d.ts.map +0 -1
  223. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +0 -23
  224. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +0 -1
  225. package/dist/components/ui/markdown/streaming.d.ts +0 -78
  226. package/dist/components/ui/markdown/streaming.d.ts.map +0 -1
  227. package/dist/components/ui/markdown/text-size.d.ts +0 -34
  228. package/dist/components/ui/markdown/text-size.d.ts.map +0 -1
  229. package/dist/utils/markdown-fences.d.ts +0 -42
  230. package/dist/utils/markdown-fences.d.ts.map +0 -1
  231. package/dist/utils/markdown-heading-id.d.ts +0 -85
  232. package/dist/utils/markdown-heading-id.d.ts.map +0 -1
  233. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +0 -317
  234. package/src/chat-protocol/__tests__/chat-protocol.test.ts +0 -516
  235. package/src/chat-protocol/__tests__/env-flag.test.ts +0 -52
  236. package/src/chat-protocol/__tests__/ip-normalize.test.ts +0 -136
  237. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +0 -232
  238. package/src/chat-protocol/decode.ts +0 -278
  239. package/src/chat-protocol/encode.ts +0 -71
  240. package/src/chat-protocol/env-flag.ts +0 -39
  241. package/src/chat-protocol/events.ts +0 -245
  242. package/src/chat-protocol/frames.ts +0 -245
  243. package/src/chat-protocol/index.ts +0 -21
  244. package/src/chat-protocol/ip-normalize.ts +0 -146
  245. package/src/chat-protocol/nats-decoder.ts +0 -258
  246. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +0 -207
  247. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +0 -230
  248. package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +0 -37
  249. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  250. package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +0 -438
  251. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +0 -318
  252. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +0 -940
  253. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +0 -756
  254. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +0 -460
  255. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +0 -973
  256. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +0 -255
  257. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +0 -98
  258. package/src/components/chat/stream/chat-dialog-store.ts +0 -536
  259. package/src/components/chat/stream/chat-stream-reducer.ts +0 -1808
  260. package/src/components/chat/stream/delta-batcher.ts +0 -168
  261. package/src/components/chat/stream/index.ts +0 -55
  262. package/src/components/chat/stream/message-mutations.ts +0 -340
  263. package/src/components/chat/stream/use-chat-stream-reducer.ts +0 -126
  264. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +0 -420
  265. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +0 -605
  266. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +0 -394
  267. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +0 -270
  268. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +0 -2420
  269. package/src/components/ui/__tests__/markdown-parity.test.tsx +0 -2528
  270. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +0 -115
  271. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +0 -95
  272. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +0 -309
  273. package/src/components/ui/markdown/__tests__/streaming.test.tsx +0 -388
  274. package/src/components/ui/markdown/base-components.tsx +0 -360
  275. package/src/components/ui/markdown/engine.tsx +0 -315
  276. package/src/components/ui/markdown/heading-ids.ts +0 -239
  277. package/src/components/ui/markdown/index.ts +0 -49
  278. package/src/components/ui/markdown/mermaid-diagram.tsx +0 -291
  279. package/src/components/ui/markdown/rich/embed-overrides.tsx +0 -199
  280. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +0 -184
  281. package/src/components/ui/markdown/rich/shortcodes.ts +0 -170
  282. package/src/components/ui/markdown/sanitize.ts +0 -3499
  283. package/src/components/ui/markdown/simple-markdown-renderer.tsx +0 -28
  284. package/src/components/ui/markdown/streaming.ts +0 -362
  285. package/src/components/ui/markdown/text-size.ts +0 -106
  286. package/src/utils/markdown-fences.ts +0 -127
  287. package/src/utils/markdown-heading-id.ts +0 -348
  288. /package/dist/{chunk-PTXZB2KW.js.map → chunk-4J3CB4KO.js.map} +0 -0
  289. /package/dist/{chunk-XOFE2RT4.js.map → chunk-BTIRYGDT.js.map} +0 -0
  290. /package/dist/{chunk-PLB6CQSO.js.map → chunk-FG5ALORQ.js.map} +0 -0
  291. /package/dist/{chunk-NCAN6VUF.js.map → chunk-P3ITKTUE.js.map} +0 -0
  292. /package/dist/{chunk-34TDA22K.js.map → chunk-QHRNQTW5.js.map} +0 -0
  293. /package/dist/{chunk-OL3MJKUI.js.map → chunk-SZWMJIH3.js.map} +0 -0
  294. /package/dist/{chunk-MZRIRQYV.js.map → chunk-U5LU56JE.js.map} +0 -0
  295. /package/dist/{chunk-3LKB722U.js.map → chunk-WKWZ7LVC.js.map} +0 -0
  296. /package/dist/{chunk-J3VBVR4W.js.map → chunk-WPFLV4QJ.js.map} +0 -0
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Utilities for parsing NATS chunks into structured actions
3
+ */
4
+
5
+ import { MESSAGE_TYPE, type ChunkData, type ParsedChunkAction, type ToolExecutionSegment, type PendingToolCallData } from '../types'
6
+
7
+ function normalizeToolCalls(raw: unknown): PendingToolCallData[] {
8
+ if (!Array.isArray(raw)) return []
9
+ return raw
10
+ .filter((item): item is Record<string, any> => !!item && typeof item === 'object')
11
+ .map((item) => ({
12
+ toolExecutionRequestId: String(item.toolExecutionRequestId ?? ''),
13
+ toolName: String(item.toolName ?? ''),
14
+ toolTitle: typeof item.toolTitle === 'string' ? item.toolTitle : undefined,
15
+ toolExplanation: typeof item.toolExplanation === 'string' ? item.toolExplanation : undefined,
16
+ toolType: typeof item.toolType === 'string' ? item.toolType : undefined,
17
+ requiresApproval: item.requiresApproval === true,
18
+ approvalType: typeof item.approvalType === 'string' ? item.approvalType : null,
19
+ toolCallArguments:
20
+ item.toolCallArguments && typeof item.toolCallArguments === 'object'
21
+ ? (item.toolCallArguments as Record<string, any>)
22
+ : null,
23
+ }))
24
+ }
25
+
26
+ /**
27
+ * Parse a raw NATS chunk into a structured action
28
+ */
29
+ export function parseChunkToAction(chunk: unknown): ParsedChunkAction | null {
30
+ if (!chunk || typeof chunk !== 'object') return null
31
+
32
+ const data = chunk as ChunkData
33
+ const type = String(data.type || '')
34
+
35
+ switch (type) {
36
+ case MESSAGE_TYPE.MESSAGE_START:
37
+ return { action: 'message_start' }
38
+
39
+ case MESSAGE_TYPE.MESSAGE_END:
40
+ return { action: 'message_end' }
41
+
42
+ case MESSAGE_TYPE.AI_METADATA: {
43
+ const providerName = data.providerName || data.provider
44
+ if (typeof data.modelName === 'string' && typeof providerName === 'string') {
45
+ return {
46
+ action: 'metadata',
47
+ modelDisplayName: data.modelDisplayName,
48
+ modelName: data.modelName,
49
+ providerName,
50
+ contextWindow: typeof data.contextWindow === 'number' ? data.contextWindow : 0,
51
+ }
52
+ }
53
+ return null
54
+ }
55
+
56
+ case MESSAGE_TYPE.TEXT:
57
+ if (typeof data.text === 'string') {
58
+ return { action: 'text', text: data.text }
59
+ }
60
+ return null
61
+
62
+ case MESSAGE_TYPE.THINKING:
63
+ if (typeof data.text === 'string') {
64
+ return { action: 'thinking', text: data.text }
65
+ }
66
+ return null
67
+
68
+ case MESSAGE_TYPE.GUIDE:
69
+ if (typeof data.text === 'string') {
70
+ return { action: 'guide', text: data.text }
71
+ }
72
+ return null
73
+
74
+ case MESSAGE_TYPE.EXECUTING_TOOL:
75
+ return {
76
+ action: 'tool_execution',
77
+ segment: {
78
+ type: 'tool_execution',
79
+ data: {
80
+ type: 'EXECUTING_TOOL',
81
+ integratedToolType: data.integratedToolType || '',
82
+ toolFunction: data.toolFunction || '',
83
+ toolTitle: typeof data.title === 'string' ? data.title : undefined,
84
+ toolExplanation: typeof data.toolExplanation === 'string' ? data.toolExplanation : undefined,
85
+ parameters: data.parameters,
86
+ toolExecutionRequestId: typeof data.toolExecutionRequestId === 'string' ? data.toolExecutionRequestId : undefined,
87
+ }
88
+ }
89
+ }
90
+
91
+ case MESSAGE_TYPE.EXECUTED_TOOL:
92
+ return {
93
+ action: 'tool_execution',
94
+ segment: {
95
+ type: 'tool_execution',
96
+ data: {
97
+ type: 'EXECUTED_TOOL',
98
+ integratedToolType: data.integratedToolType || '',
99
+ toolFunction: data.toolFunction || '',
100
+ toolTitle: typeof data.title === 'string' ? data.title : undefined,
101
+ parameters: data.parameters,
102
+ result: data.result,
103
+ success: data.success,
104
+ toolExecutionRequestId: typeof data.toolExecutionRequestId === 'string' ? data.toolExecutionRequestId : undefined,
105
+ }
106
+ }
107
+ }
108
+
109
+ case MESSAGE_TYPE.APPROVAL_REQUEST: {
110
+ const requestId = data.approvalRequestId || data.approval_request_id || ''
111
+ const approvalType = data.approvalType || 'USER'
112
+ const toolCalls = normalizeToolCalls(data.toolCalls)
113
+
114
+ if (toolCalls.length > 0) {
115
+ return {
116
+ action: 'approval_batch',
117
+ requestId,
118
+ approvalType,
119
+ toolCalls,
120
+ }
121
+ }
122
+
123
+ return {
124
+ action: 'approval_request',
125
+ requestId,
126
+ command: data.command || '',
127
+ explanation: data.explanation,
128
+ approvalType,
129
+ }
130
+ }
131
+
132
+ case MESSAGE_TYPE.APPROVAL_RESULT: {
133
+ // The realtime NATS chunk carries the resolver's name as `displayName`; the
134
+ // persisted GraphQL message exposes the same value as `resolvedByName`. Accept
135
+ // either so realtime and history-replay render "by {name}" identically.
136
+ const resolvedByName =
137
+ typeof data.resolvedByName === 'string'
138
+ ? data.resolvedByName
139
+ : typeof data.displayName === 'string'
140
+ ? data.displayName
141
+ : undefined
142
+ return {
143
+ action: 'approval_result',
144
+ requestId: data.approvalRequestId || data.approval_request_id || '',
145
+ approved: data.approved === true,
146
+ approvalType: data.approvalType || 'CLIENT',
147
+ resolvedByName,
148
+ }
149
+ }
150
+
151
+ case MESSAGE_TYPE.ERROR:
152
+ return {
153
+ action: 'error',
154
+ error: data.error || 'An error occurred',
155
+ details: data.details,
156
+ }
157
+
158
+ case MESSAGE_TYPE.MESSAGE_REQUEST:
159
+ return {
160
+ action: 'message_request',
161
+ text: String(data.text || ''),
162
+ ownerType: typeof data.ownerType === 'string' ? data.ownerType : undefined,
163
+ displayName: typeof data.displayName === 'string' ? data.displayName : undefined,
164
+ userId: typeof data.userId === 'string' ? data.userId : undefined,
165
+ // Entity-context refs the user attached to this message (backend
166
+ // `MESSAGE_REQUEST` chunk → `contextItems: [{ type, id }]`). The wire
167
+ // shape carries no label; the host resolves display text + icon. `label`
168
+ // is REQUIRED on `ChatContextItem`, so fall back to the id (same as the
169
+ // historical path in `process-historical-messages.ts`) — keeps both
170
+ // message sources producing an identical shape.
171
+ contextItems: Array.isArray(data.contextItems)
172
+ ? (data.contextItems as Array<{ type?: unknown; id?: unknown }>)
173
+ .filter((it) => typeof it?.type === 'string' && typeof it?.id === 'string')
174
+ .map((it) => ({ type: it.type as string, id: it.id as string, label: it.id as string }))
175
+ : undefined,
176
+ }
177
+
178
+ case MESSAGE_TYPE.TOKEN_USAGE:
179
+ return {
180
+ action: 'token_usage',
181
+ data: {
182
+ inputTokensSize: data.inputTokensSize ?? 0,
183
+ outputTokensSize: data.outputTokensSize ?? 0,
184
+ totalTokensSize: data.totalTokensSize ?? 0,
185
+ contextSize: data.contextSize ?? 0,
186
+ },
187
+ }
188
+
189
+ case MESSAGE_TYPE.CONTEXT_COMPACTION_START:
190
+ return { action: 'context_compaction_start' }
191
+
192
+ case MESSAGE_TYPE.CONTEXT_COMPACTION_END:
193
+ return {
194
+ action: 'context_compaction_end',
195
+ summary: typeof data.text === 'string' ? data.text : undefined,
196
+ }
197
+
198
+ case MESSAGE_TYPE.SYSTEM:
199
+ if (typeof data.text === 'string') {
200
+ return { action: 'system', text: data.text }
201
+ }
202
+ return null
203
+
204
+ case MESSAGE_TYPE.DIRECT_MESSAGE:
205
+ if (typeof data.text === 'string') {
206
+ return {
207
+ action: 'direct_message',
208
+ text: data.text,
209
+ ownerType: typeof data.ownerType === 'string' ? data.ownerType : undefined,
210
+ displayName: typeof data.displayName === 'string' ? data.displayName : undefined,
211
+ userId: typeof data.userId === 'string' ? data.userId : undefined,
212
+ }
213
+ }
214
+ return null
215
+
216
+ case MESSAGE_TYPE.DIALOG_CLOSED:
217
+ return { action: 'dialog_closed' }
218
+
219
+ default:
220
+ return null
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Check if a chunk represents a control message (start/end)
226
+ */
227
+ export function isControlChunk(chunk: unknown): boolean {
228
+ if (!chunk || typeof chunk !== 'object') return false
229
+ const data = chunk as ChunkData
230
+ const type = String(data.type || '')
231
+ return type === MESSAGE_TYPE.MESSAGE_START || type === MESSAGE_TYPE.MESSAGE_END
232
+ }
233
+
234
+ /**
235
+ * Check if a chunk represents an error
236
+ */
237
+ export function isErrorChunk(chunk: unknown): boolean {
238
+ if (!chunk || typeof chunk !== 'object') return false
239
+ const data = chunk as ChunkData
240
+ return data.type === MESSAGE_TYPE.ERROR
241
+ }
242
+
243
+ /**
244
+ * Check if a chunk represents metadata
245
+ */
246
+ export function isMetadataChunk(chunk: unknown): boolean {
247
+ if (!chunk || typeof chunk !== 'object') return false
248
+ const data = chunk as ChunkData
249
+ return data.type === MESSAGE_TYPE.AI_METADATA
250
+ }
251
+
252
+ /**
253
+ * Extract text content from a chunk if it's a text chunk
254
+ */
255
+ export function extractTextFromChunk(chunk: unknown): string | null {
256
+ if (!chunk || typeof chunk !== 'object') return null
257
+ const data = chunk as ChunkData
258
+ if (data.type === MESSAGE_TYPE.TEXT && typeof data.text === 'string') {
259
+ return data.text
260
+ }
261
+ return null
262
+ }
@@ -9,18 +9,6 @@ import type {
9
9
  PendingApproval,
10
10
  ExecutingToolState,
11
11
  } from '../types'
12
- import type { InitializeExtras } from '../stream/chat-stream-reducer'
13
-
14
- /**
15
- * What the realtime accumulator needs to RESUME an unfinished turn.
16
- *
17
- * DERIVED, not restated: this is exactly the reducer's `InitializeExtras`
18
- * minus `escalatedApprovals` (which only the live stream can produce — it has
19
- * no historical representation to extract). Hosts pass the result straight
20
- * into `reducer.initializeWithState(messages, extras)`, so the two must not
21
- * drift; a structural coincidence is not a contract.
22
- */
23
- export type IncompleteMessageState = Omit<InitializeExtras, 'escalatedApprovals'>
24
12
 
25
13
  /**
26
14
  * Extract incomplete message state from the last historical assistant message
@@ -28,7 +16,11 @@ export type IncompleteMessageState = Omit<InitializeExtras, 'escalatedApprovals'
28
16
  */
29
17
  export function extractIncompleteMessageState(
30
18
  lastMessage: ProcessedMessage | undefined
31
- ): IncompleteMessageState | undefined {
19
+ ): {
20
+ existingSegments?: MessageSegment[]
21
+ pendingApprovals?: Map<string, PendingApproval>
22
+ executingTools?: Map<string, ExecutingToolState>
23
+ } | undefined {
32
24
  if (!lastMessage || lastMessage.role !== 'assistant' || typeof lastMessage.content === 'string') {
33
25
  return undefined
34
26
  }
@@ -100,54 +92,4 @@ export function extractIncompleteMessageState(
100
92
  pendingApprovals: pendingApprovals.size > 0 ? pendingApprovals : undefined,
101
93
  executingTools: executingTools.size > 0 ? executingTools : undefined,
102
94
  }
103
- }
104
-
105
- /**
106
- * THREAD-level generalization of `extractIncompleteMessageState`: given a
107
- * processed thread, look at the TRAILING RUN of consecutive assistant
108
- * messages (not just the very last row), flatten it to one segment list, and
109
- * ask the single-message extractor whether that tail is unfinished.
110
- *
111
- * Why the run and not the last row: the backend can split one logical turn
112
- * across several assistant messages (a preamble bubble, then the approval
113
- * card, then the continuation). The unfinished artifact — a pending approval,
114
- * an EXECUTING_TOOL with no result, an open compaction — can therefore sit in
115
- * an EARLIER bubble of the same trailing run, and a last-row-only check
116
- * reports "complete" while the turn is very much still in flight.
117
- *
118
- * SSOT for every "is the tail incomplete?" question — the NATS adapter (which
119
- * used to inline the single-row check) and hosts replaying a stored thread
120
- * both call this instead of re-deriving the walk.
121
- *
122
- * A trailing non-assistant row (user / error) means the last turn closed →
123
- * `undefined`.
124
- */
125
- export function extractIncompleteTailState(
126
- messages: readonly ProcessedMessage[] | undefined,
127
- ): IncompleteMessageState | undefined {
128
- if (!messages || messages.length === 0) return undefined
129
-
130
- // Walk back over the trailing consecutive assistant run.
131
- let start = messages.length
132
- while (start > 0 && messages[start - 1]?.role === 'assistant') start -= 1
133
- if (start === messages.length) return undefined
134
-
135
- const segments: MessageSegment[] = []
136
- for (let i = start; i < messages.length; i += 1) {
137
- const content = messages[i]?.content
138
- // A string-content assistant row is a plain-text bubble with nothing to
139
- // resume; skip it rather than aborting — a later row in the same run may
140
- // still hold the unfinished segment.
141
- if (Array.isArray(content)) segments.push(...(content as MessageSegment[]))
142
- }
143
- if (segments.length === 0) return undefined
144
-
145
- // Reuse the single-message extractor verbatim by handing it a synthetic
146
- // assistant row carrying the flattened run — one incompleteness rule set,
147
- // not two.
148
- return extractIncompleteMessageState({
149
- ...messages[messages.length - 1],
150
- role: 'assistant',
151
- content: segments,
152
- } as ProcessedMessage)
153
95
  }
@@ -3,9 +3,14 @@
3
3
  * Export all utilities for processing chat messages
4
4
  */
5
5
 
6
- // NOTE: NATS chunk parsing lives in `chat-protocol/nats-decoder`
7
- // (`decodeNatsChunk`) — the legacy `chunk-parser` module was deleted once the
8
- // reducer became the single reading path.
6
+ // Chunk parsing utilities
7
+ export {
8
+ parseChunkToAction,
9
+ isControlChunk,
10
+ isErrorChunk,
11
+ isMetadataChunk,
12
+ extractTextFromChunk,
13
+ } from './chunk-parser'
9
14
 
10
15
  // Segment accumulator
11
16
  export {
@@ -19,13 +24,11 @@ export {
19
24
  processHistoricalMessages,
20
25
  extractErrorMessages,
21
26
  processHistoricalMessagesWithErrors,
22
- decodeHistoricalMessageData,
23
27
  } from './process-historical-messages'
24
28
 
25
29
  // Incomplete message state extraction
26
30
  export {
27
31
  extractIncompleteMessageState,
28
- extractIncompleteTailState,
29
32
  } from './extract-incomplete-message-state'
30
33
 
31
34
  // History <-> realtime reconciliation