@flamingo-stack/openframe-frontend-core 0.0.488 → 0.0.490-1506.3944.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 (311) 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 +196 -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 +494 -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 +478 -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-AJNDDXKC.js → chunk-4NWARV5I.js} +3 -3
  22. package/dist/{chunk-GQX6LFFA.cjs → chunk-5CJR2GZ4.cjs} +42 -42
  23. package/dist/{chunk-GQX6LFFA.cjs.map → chunk-5CJR2GZ4.cjs.map} +1 -1
  24. package/dist/{chunk-EUYIFALO.cjs → chunk-5EYRXSY5.cjs} +14 -14
  25. package/dist/{chunk-EUYIFALO.cjs.map → chunk-5EYRXSY5.cjs.map} +1 -1
  26. package/dist/{chunk-5RXKOGH6.cjs → chunk-5LMGFI4J.cjs} +7011 -4777
  27. package/dist/chunk-5LMGFI4J.cjs.map +1 -0
  28. package/dist/{chunk-KFQXO7QB.js → chunk-6GT557KN.js} +1 -1
  29. package/dist/chunk-6GT557KN.js.map +1 -0
  30. package/dist/{chunk-77DFPD35.js → chunk-BE6DK7QY.js} +12267 -10033
  31. package/dist/chunk-BE6DK7QY.js.map +1 -0
  32. package/dist/{chunk-A7IPON2V.cjs → chunk-BIKOJ4FH.cjs} +5 -5
  33. package/dist/{chunk-A7IPON2V.cjs.map → chunk-BIKOJ4FH.cjs.map} +1 -1
  34. package/dist/{chunk-HQYJINFV.js → chunk-CORIBKHG.js} +4 -4
  35. package/dist/{chunk-YEEHB4T6.cjs → chunk-CSYSYJCF.cjs} +40 -40
  36. package/dist/{chunk-YEEHB4T6.cjs.map → chunk-CSYSYJCF.cjs.map} +1 -1
  37. package/dist/{chunk-SIKCXKGB.cjs → chunk-DSDZ5T4P.cjs} +7 -7
  38. package/dist/{chunk-SIKCXKGB.cjs.map → chunk-DSDZ5T4P.cjs.map} +1 -1
  39. package/dist/{chunk-PNXNWGBY.js → chunk-GTWO5NAY.js} +2 -2
  40. package/dist/{chunk-SCCTJ2UI.js → chunk-HSACATCD.js} +4 -4
  41. package/dist/{chunk-PECGZWQR.cjs → chunk-KP5KRRD6.cjs} +3 -3
  42. package/dist/{chunk-PECGZWQR.cjs.map → chunk-KP5KRRD6.cjs.map} +1 -1
  43. package/dist/{chunk-2B6773QM.cjs → chunk-LILQJ3UZ.cjs} +1 -1
  44. package/dist/chunk-LILQJ3UZ.cjs.map +1 -0
  45. package/dist/{chunk-RZSA6MZL.cjs → chunk-NWX7MMF5.cjs} +15 -15
  46. package/dist/{chunk-RZSA6MZL.cjs.map → chunk-NWX7MMF5.cjs.map} +1 -1
  47. package/dist/{chunk-V3CNNMY3.cjs → chunk-P4WTZU6L.cjs} +18 -18
  48. package/dist/{chunk-V3CNNMY3.cjs.map → chunk-P4WTZU6L.cjs.map} +1 -1
  49. package/dist/{chunk-KLYHZRAD.js → chunk-PB3BTZDU.js} +2 -2
  50. package/dist/{chunk-FZOBQG6M.cjs → chunk-Q6E7VJ4W.cjs} +37 -36
  51. package/dist/chunk-Q6E7VJ4W.cjs.map +1 -0
  52. package/dist/{chunk-EYEIVYYF.cjs → chunk-QSCHCZL3.cjs} +7 -7
  53. package/dist/{chunk-EYEIVYYF.cjs.map → chunk-QSCHCZL3.cjs.map} +1 -1
  54. package/dist/{chunk-YJSKQ2ZV.js → chunk-RQLBHKXN.js} +3 -3
  55. package/dist/{chunk-CWQACI4Z.js → chunk-RW2LPL72.js} +2 -2
  56. package/dist/{chunk-DX6AOHNU.cjs → chunk-S2NHJDKQ.cjs} +77 -77
  57. package/dist/{chunk-DX6AOHNU.cjs.map → chunk-S2NHJDKQ.cjs.map} +1 -1
  58. package/dist/{chunk-AHDJMEEN.js → chunk-T2EGSZFN.js} +9 -8
  59. package/dist/chunk-T2EGSZFN.js.map +1 -0
  60. package/dist/{chunk-S52LJNMU.js → chunk-TKN5667N.js} +13 -13
  61. package/dist/chunk-TKN5667N.js.map +1 -0
  62. package/dist/{chunk-3BFX6HJM.js → chunk-UUYRJPGJ.js} +6 -6
  63. package/dist/{chunk-F6BYUO5U.js → chunk-VHG6AX5V.js} +3 -3
  64. package/dist/{chunk-FOQV6RCO.cjs → chunk-VQ523ORK.cjs} +29 -29
  65. package/dist/{chunk-FOQV6RCO.cjs.map → chunk-VQ523ORK.cjs.map} +1 -1
  66. package/dist/{chunk-PXF5J24T.js → chunk-XQ2B74SI.js} +2 -2
  67. package/dist/{chunk-H7JX2BG7.cjs → chunk-YHOIAA2E.cjs} +76 -76
  68. package/dist/chunk-YHOIAA2E.cjs.map +1 -0
  69. package/dist/{chunk-LLWBPPZ4.js → chunk-YZ2OIYQ3.js} +6 -6
  70. package/dist/components/case-studies/index.cjs +10 -10
  71. package/dist/components/case-studies/index.js +4 -4
  72. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  73. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  74. package/dist/components/chat/hooks/index.d.ts +0 -1
  75. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  76. package/dist/components/chat/hooks/use-chat-history-hydration.d.ts +47 -0
  77. package/dist/components/chat/hooks/use-chat-history-hydration.d.ts.map +1 -0
  78. package/dist/components/chat/hooks/use-chat.d.ts +1 -0
  79. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  80. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +15 -48
  81. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  82. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +10 -53
  83. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  84. package/dist/components/chat/index.cjs +12 -4
  85. package/dist/components/chat/index.cjs.map +1 -1
  86. package/dist/components/chat/index.d.ts +1 -0
  87. package/dist/components/chat/index.d.ts.map +1 -1
  88. package/dist/components/chat/index.js +23 -15
  89. package/dist/components/chat/stream/chat-dialog-store.d.ts +184 -0
  90. package/dist/components/chat/stream/chat-dialog-store.d.ts.map +1 -0
  91. package/dist/components/chat/stream/chat-stream-reducer.d.ts +367 -0
  92. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -0
  93. package/dist/components/chat/stream/delta-batcher.d.ts +51 -0
  94. package/dist/components/chat/stream/delta-batcher.d.ts.map +1 -0
  95. package/dist/components/chat/stream/index.d.ts +17 -0
  96. package/dist/components/chat/stream/index.d.ts.map +1 -0
  97. package/dist/components/chat/stream/message-mutations.d.ts +77 -0
  98. package/dist/components/chat/stream/message-mutations.d.ts.map +1 -0
  99. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +22 -0
  100. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +1 -0
  101. package/dist/components/chat/types/api.types.d.ts +1 -81
  102. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  103. package/dist/components/chat/types/processing.types.d.ts +2 -90
  104. package/dist/components/chat/types/processing.types.d.ts.map +1 -1
  105. package/dist/components/chat/types/unified-chat-state.types.d.ts +5 -0
  106. package/dist/components/chat/types/unified-chat-state.types.d.ts.map +1 -1
  107. package/dist/components/chat/utils/chat-conversation-storage.d.ts +34 -0
  108. package/dist/components/chat/utils/chat-conversation-storage.d.ts.map +1 -0
  109. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +34 -6
  110. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
  111. package/dist/components/chat/utils/index.d.ts +2 -3
  112. package/dist/components/chat/utils/index.d.ts.map +1 -1
  113. package/dist/components/chat/utils/process-historical-messages.d.ts +59 -11
  114. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  115. package/dist/components/contact/index.cjs +5 -5
  116. package/dist/components/contact/index.js +4 -4
  117. package/dist/components/docs/index.cjs +7 -7
  118. package/dist/components/docs/index.js +6 -6
  119. package/dist/components/embeds/index.cjs +5 -5
  120. package/dist/components/embeds/index.js +4 -4
  121. package/dist/components/faq/index.cjs +6 -6
  122. package/dist/components/faq/index.js +5 -5
  123. package/dist/components/features/index.cjs +4 -4
  124. package/dist/components/features/index.js +3 -3
  125. package/dist/components/help-center-pages/index.cjs +23 -23
  126. package/dist/components/help-center-pages/index.js +14 -14
  127. package/dist/components/index.cjs +182 -140
  128. package/dist/components/index.cjs.map +1 -1
  129. package/dist/components/index.js +66 -24
  130. package/dist/components/index.js.map +1 -1
  131. package/dist/components/navigation/index.cjs +4 -4
  132. package/dist/components/navigation/index.js +3 -3
  133. package/dist/components/onboarding-guides/index.cjs +8 -8
  134. package/dist/components/onboarding-guides/index.js +7 -7
  135. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  136. package/dist/components/related-content/index.cjs +6 -6
  137. package/dist/components/related-content/index.js +5 -5
  138. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  139. package/dist/components/tickets/index.cjs +7 -7
  140. package/dist/components/tickets/index.js +6 -6
  141. package/dist/components/ui/index.cjs +46 -4
  142. package/dist/components/ui/index.cjs.map +1 -1
  143. package/dist/components/ui/index.d.ts +1 -2
  144. package/dist/components/ui/index.d.ts.map +1 -1
  145. package/dist/components/ui/index.js +57 -15
  146. package/dist/components/ui/markdown/base-components.d.ts +51 -0
  147. package/dist/components/ui/markdown/base-components.d.ts.map +1 -0
  148. package/dist/components/ui/markdown/engine.d.ts +99 -0
  149. package/dist/components/ui/markdown/engine.d.ts.map +1 -0
  150. package/dist/components/ui/markdown/heading-ids.d.ts +65 -0
  151. package/dist/components/ui/markdown/heading-ids.d.ts.map +1 -0
  152. package/dist/components/ui/markdown/index.d.ts +18 -0
  153. package/dist/components/ui/markdown/index.d.ts.map +1 -0
  154. package/dist/components/ui/markdown/mermaid-diagram.d.ts +79 -0
  155. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +1 -0
  156. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +14 -0
  157. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +1 -0
  158. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +40 -0
  159. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -0
  160. package/dist/components/ui/markdown/rich/shortcodes.d.ts +8 -0
  161. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +1 -0
  162. package/dist/components/ui/markdown/sanitize.d.ts +153 -0
  163. package/dist/components/ui/markdown/sanitize.d.ts.map +1 -0
  164. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +23 -0
  165. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +1 -0
  166. package/dist/components/ui/markdown/streaming.d.ts +78 -0
  167. package/dist/components/ui/markdown/streaming.d.ts.map +1 -0
  168. package/dist/components/ui/markdown/text-size.d.ts +34 -0
  169. package/dist/components/ui/markdown/text-size.d.ts.map +1 -0
  170. package/dist/contexts/chat-runtime-context.d.ts +8 -0
  171. package/dist/contexts/chat-runtime-context.d.ts.map +1 -1
  172. package/dist/contexts/index.cjs +2 -2
  173. package/dist/contexts/index.js +1 -1
  174. package/dist/hooks/index.cjs +3 -3
  175. package/dist/hooks/index.js +2 -2
  176. package/dist/index.cjs +62 -4
  177. package/dist/index.cjs.map +1 -1
  178. package/dist/index.js +73 -15
  179. package/dist/utils/index.cjs +169 -40
  180. package/dist/utils/index.cjs.map +1 -1
  181. package/dist/utils/index.d.ts +1 -0
  182. package/dist/utils/index.d.ts.map +1 -1
  183. package/dist/utils/index.js +162 -41
  184. package/dist/utils/index.js.map +1 -1
  185. package/dist/utils/markdown-fences.d.ts +42 -0
  186. package/dist/utils/markdown-fences.d.ts.map +1 -0
  187. package/dist/utils/markdown-heading-id.d.ts +85 -0
  188. package/dist/utils/markdown-heading-id.d.ts.map +1 -0
  189. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  190. package/package.json +7 -1
  191. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +307 -0
  192. package/src/chat-protocol/__tests__/chat-protocol.test.ts +516 -0
  193. package/src/chat-protocol/__tests__/env-flag.test.ts +52 -0
  194. package/src/chat-protocol/__tests__/ip-normalize.test.ts +136 -0
  195. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +228 -0
  196. package/src/chat-protocol/decode.ts +278 -0
  197. package/src/chat-protocol/encode.ts +71 -0
  198. package/src/chat-protocol/env-flag.ts +39 -0
  199. package/src/chat-protocol/events.ts +232 -0
  200. package/src/chat-protocol/frames.ts +245 -0
  201. package/src/chat-protocol/index.ts +21 -0
  202. package/src/chat-protocol/ip-normalize.ts +146 -0
  203. package/src/chat-protocol/nats-decoder.ts +252 -0
  204. package/src/components/chat/__tests__/chat-message-list.test.tsx +293 -5
  205. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +207 -0
  206. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +209 -0
  207. package/src/components/chat/chat-message-enhanced.tsx +111 -17
  208. package/src/components/chat/chat-message-list.tsx +358 -109
  209. package/src/components/chat/embeddable-chat.tsx +6 -0
  210. package/src/components/chat/hooks/.index.md +30 -33
  211. package/src/components/chat/hooks/.use-nats-chat-adapter.md +36 -55
  212. package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +37 -0
  213. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  214. package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +438 -0
  215. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +318 -0
  216. package/src/components/chat/hooks/index.ts +0 -1
  217. package/src/components/chat/hooks/use-chat-history-hydration.ts +142 -0
  218. package/src/components/chat/hooks/use-chat.ts +20 -0
  219. package/src/components/chat/hooks/use-nats-chat-adapter.ts +243 -823
  220. package/src/components/chat/hooks/use-sse-chat-adapter.ts +417 -774
  221. package/src/components/chat/index.ts +5 -0
  222. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +940 -0
  223. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +756 -0
  224. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +460 -0
  225. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +894 -0
  226. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +255 -0
  227. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +98 -0
  228. package/src/components/chat/stream/chat-dialog-store.ts +536 -0
  229. package/src/components/chat/stream/chat-stream-reducer.ts +1796 -0
  230. package/src/components/chat/stream/delta-batcher.ts +159 -0
  231. package/src/components/chat/stream/index.ts +55 -0
  232. package/src/components/chat/stream/message-mutations.ts +338 -0
  233. package/src/components/chat/stream/use-chat-stream-reducer.ts +126 -0
  234. package/src/components/chat/thinking-display.tsx +1 -1
  235. package/src/components/chat/types/.api.types.md +39 -49
  236. package/src/components/chat/types/.processing.types.md +29 -58
  237. package/src/components/chat/types/api.types.ts +6 -73
  238. package/src/components/chat/types/processing.types.ts +11 -52
  239. package/src/components/chat/types/unified-chat-state.types.ts +6 -0
  240. package/src/components/chat/utils/.index.md +31 -40
  241. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +420 -0
  242. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +605 -0
  243. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +317 -0
  244. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +270 -0
  245. package/src/components/chat/utils/chat-conversation-storage.ts +83 -0
  246. package/src/components/chat/utils/extract-incomplete-message-state.ts +63 -5
  247. package/src/components/chat/utils/index.ts +5 -8
  248. package/src/components/chat/utils/process-historical-messages.ts +352 -384
  249. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +22 -4
  250. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  251. package/src/components/shared/product-release/release-detail-page.tsx +19 -4
  252. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +2420 -0
  253. package/src/components/ui/__tests__/markdown-parity.test.tsx +2528 -0
  254. package/src/components/ui/index.ts +1 -2
  255. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +115 -0
  256. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +95 -0
  257. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +309 -0
  258. package/src/components/ui/markdown/__tests__/streaming.test.tsx +388 -0
  259. package/src/components/ui/markdown/base-components.tsx +360 -0
  260. package/src/components/ui/markdown/engine.tsx +315 -0
  261. package/src/components/ui/markdown/heading-ids.ts +239 -0
  262. package/src/components/ui/markdown/index.ts +49 -0
  263. package/src/components/ui/markdown/mermaid-diagram.tsx +291 -0
  264. package/src/components/ui/markdown/rich/embed-overrides.tsx +199 -0
  265. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +184 -0
  266. package/src/components/ui/markdown/rich/shortcodes.ts +170 -0
  267. package/src/components/ui/markdown/sanitize.ts +3499 -0
  268. package/src/components/ui/markdown/simple-markdown-renderer.tsx +28 -0
  269. package/src/components/ui/markdown/streaming.ts +362 -0
  270. package/src/components/ui/markdown/text-size.ts +106 -0
  271. package/src/components/ui/release-changelog-section.tsx +1 -1
  272. package/src/components/ui/ticket-info-section.tsx +1 -1
  273. package/src/contexts/chat-runtime-context.tsx +8 -0
  274. package/src/utils/index.ts +1 -0
  275. package/src/utils/markdown-fences.ts +127 -0
  276. package/src/utils/markdown-heading-id.ts +348 -0
  277. package/src/utils/markdown-section-extractor.ts +41 -56
  278. package/dist/chunk-2B6773QM.cjs.map +0 -1
  279. package/dist/chunk-5RXKOGH6.cjs.map +0 -1
  280. package/dist/chunk-77DFPD35.js.map +0 -1
  281. package/dist/chunk-AHDJMEEN.js.map +0 -1
  282. package/dist/chunk-FZOBQG6M.cjs.map +0 -1
  283. package/dist/chunk-H7JX2BG7.cjs.map +0 -1
  284. package/dist/chunk-KFQXO7QB.js.map +0 -1
  285. package/dist/chunk-S52LJNMU.js.map +0 -1
  286. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +0 -6
  287. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +0 -1
  288. package/dist/components/chat/utils/chunk-parser.d.ts +0 -25
  289. package/dist/components/chat/utils/chunk-parser.d.ts.map +0 -1
  290. package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
  291. package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
  292. package/dist/components/ui/simple-markdown-renderer.d.ts +0 -73
  293. package/dist/components/ui/simple-markdown-renderer.d.ts.map +0 -1
  294. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +0 -77
  295. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +0 -479
  296. package/src/components/chat/utils/.chunk-parser.md +0 -62
  297. package/src/components/chat/utils/chunk-parser.ts +0 -256
  298. package/src/components/ui/.simple-markdown-renderer.md +0 -52
  299. package/src/components/ui/rich-markdown-renderer.tsx +0 -1223
  300. package/src/components/ui/simple-markdown-renderer.tsx +0 -964
  301. /package/dist/{chunk-AJNDDXKC.js.map → chunk-4NWARV5I.js.map} +0 -0
  302. /package/dist/{chunk-HQYJINFV.js.map → chunk-CORIBKHG.js.map} +0 -0
  303. /package/dist/{chunk-PNXNWGBY.js.map → chunk-GTWO5NAY.js.map} +0 -0
  304. /package/dist/{chunk-SCCTJ2UI.js.map → chunk-HSACATCD.js.map} +0 -0
  305. /package/dist/{chunk-KLYHZRAD.js.map → chunk-PB3BTZDU.js.map} +0 -0
  306. /package/dist/{chunk-YJSKQ2ZV.js.map → chunk-RQLBHKXN.js.map} +0 -0
  307. /package/dist/{chunk-CWQACI4Z.js.map → chunk-RW2LPL72.js.map} +0 -0
  308. /package/dist/{chunk-3BFX6HJM.js.map → chunk-UUYRJPGJ.js.map} +0 -0
  309. /package/dist/{chunk-F6BYUO5U.js.map → chunk-VHG6AX5V.js.map} +0 -0
  310. /package/dist/{chunk-PXF5J24T.js.map → chunk-XQ2B74SI.js.map} +0 -0
  311. /package/dist/{chunk-LLWBPPZ4.js.map → chunk-YZ2OIYQ3.js.map} +0 -0
@@ -1,479 +0,0 @@
1
- 'use client'
2
-
3
- /**
4
- * Hook for processing real-time NATS chunks
5
- * Provides a consistent interface for handling streaming messages
6
- */
7
-
8
- import { useCallback, useRef, useEffect } from 'react'
9
- import { parseChunkToAction } from '../utils/chunk-parser'
10
- import {
11
- MessageSegmentAccumulator,
12
- createMessageSegmentAccumulator,
13
- } from '../utils/message-segment-accumulator'
14
- import type { UseRealtimeChunkProcessorReturn, UseRealtimeChunkProcessorOptions, ChatApprovalStatus, PendingToolCallData, MessageSegment, SegmentsUpdateMetadata } from '../types'
15
- import { getCommandText } from '../utils/tool-call-helpers'
16
-
17
- // Actions allowed through once the dialog is in direct mode. Everything else is
18
- // an AI-assistant chunk and gets dropped — an allowlist so any future assistant
19
- // action is blocked by default.
20
- const DIRECT_MODE_ALLOWED = new Set(['direct_message', 'message_request', 'system', 'dialog_closed'])
21
-
22
- /**
23
- * Hook for processing real-time NATS chunks into message segments
24
- */
25
- export function useRealtimeChunkProcessor(
26
- options: UseRealtimeChunkProcessorOptions
27
- ): UseRealtimeChunkProcessorReturn {
28
- const {
29
- callbacks,
30
- displayApprovalTypes = ['CLIENT'],
31
- approvalStatuses = {},
32
- initialState,
33
- // Owned by the consumer (e.g. oss-tenant chat client / openframe-frontend
34
- // tickets view). Default ON so consumers that haven't wired the flag yet
35
- // get the new batch UI; pass `false` explicitly to fall back to legacy.
36
- batchApprovalsEnabled = true,
37
- isDirectMode = false,
38
- } = options
39
-
40
- const accumulatorRef = useRef<MessageSegmentAccumulator>(
41
- createMessageSegmentAccumulator({
42
- onApprove: callbacks.onApprove,
43
- onReject: callbacks.onReject,
44
- })
45
- )
46
-
47
- const hasInitializedWithData = useRef(false)
48
-
49
- // Initialize accumulator when we get initial state data
50
- useEffect(() => {
51
- if (initialState && !hasInitializedWithData.current) {
52
- accumulatorRef.current.initializeWithState(initialState)
53
-
54
- if (initialState.escalatedApprovals) {
55
- pendingEscalatedRef.current = new Map(initialState.escalatedApprovals)
56
-
57
- initialState.escalatedApprovals.forEach((data, requestId) => {
58
- callbacks.onEscalatedApproval?.(requestId, data)
59
- })
60
- }
61
-
62
- // Resumed dialog: a MESSAGE_START already fired server-side. Treat
63
- // subsequent continuation chunks (after the next MESSAGE_END) as
64
- // post-stream so they append into the existing bubble instead of
65
- // replacing its content via the cold-start cumulative path.
66
- hasEverStreamedRef.current = true
67
- hasInitializedWithData.current = true
68
- }
69
- }, [initialState, callbacks])
70
-
71
- const isInStreamRef = useRef(false)
72
- // Distinguishes post-MESSAGE_END continuation (append into prior bubble)
73
- // from cold-start before any MESSAGE_START (cumulative; otherwise
74
- // appendSegmentsToLastAssistant silently drops the chunk when no
75
- // assistant bubble exists yet). Flipped true on MESSAGE_START and on
76
- // resumed-dialog initializeWithState.
77
- const hasEverStreamedRef = useRef(false)
78
-
79
- // Direct-mode barrier: once engaged, AI-assistant chunks are dropped. Engaged
80
- // by the host flag (optimistic) or by an in-order DIRECT_MESSAGE chunk.
81
- const directModeFlagRef = useRef(isDirectMode)
82
- const sawDirectMessageRef = useRef(false)
83
- // One-shot teardown guard for the barrier. Busy state can be asserted
84
- // OUTSIDE an open stream (onAgentBusy on tool/approval chunks), so the
85
- // teardown must fire once even when isInStreamRef is false — otherwise a
86
- // human takeover right after an approval leaves the consumer's composer
87
- // locked forever (all releasing AI chunks get dropped by the barrier).
88
- const directTeardownFiredRef = useRef(false)
89
- useEffect(() => {
90
- directModeFlagRef.current = isDirectMode
91
- }, [isDirectMode])
92
-
93
- // Track pending escalated approvals (single or batch)
94
- const pendingEscalatedRef = useRef<
95
- Map<string, { command: string; explanation?: string; approvalType: string; toolCalls?: PendingToolCallData[] }>
96
- >(new Map())
97
-
98
- const processChunk = useCallback(
99
- (chunk: unknown) => {
100
- const action = parseChunkToAction(chunk)
101
- if (!action) return
102
-
103
- const accumulator = accumulatorRef.current
104
-
105
- // streamSeq of the chunk currently being processed (JetStream only).
106
- // Only content emissions below carry it through to the host, so the
107
- // streaming bubble is stamped with the highest CONTENT seq it saw — the
108
- // non-persisted MESSAGE_END / TOKEN_USAGE chunks never reach emitSegments.
109
- const streamSeq =
110
- chunk && typeof chunk === 'object' && typeof (chunk as { streamSeq?: unknown }).streamSeq === 'number'
111
- ? (chunk as { streamSeq: number }).streamSeq
112
- : undefined
113
- const emitSegments = (s: MessageSegment[], meta?: SegmentsUpdateMetadata) =>
114
- callbacks.onSegmentsUpdate?.(s, streamSeq != null ? { ...meta, streamSeq } : meta)
115
-
116
- if (action.action === 'direct_message') sawDirectMessageRef.current = true
117
-
118
- if ((directModeFlagRef.current || sawDirectMessageRef.current) && !DIRECT_MODE_ALLOWED.has(action.action)) {
119
- // Hard stop: tear down AI activity exactly once so the typing
120
- // indicator, composer lock, and half-rendered bubble clear, then drop
121
- // the chunk. Fires even when no stream is open — an onAgentBusy lock
122
- // (approved commands executing post-MESSAGE_END) has no other release
123
- // once the barrier starts dropping the continuation chunks.
124
- if (isInStreamRef.current || !directTeardownFiredRef.current) {
125
- isInStreamRef.current = false
126
- directTeardownFiredRef.current = true
127
- callbacks.onStreamEnd?.()
128
- accumulator.resetSegments()
129
- }
130
- return
131
- }
132
-
133
- switch (action.action) {
134
- case 'message_start':
135
- isInStreamRef.current = true
136
- hasEverStreamedRef.current = true
137
- callbacks.onStreamStart?.()
138
- accumulator.resetSegments()
139
- break
140
-
141
- case 'message_end':
142
- isInStreamRef.current = false
143
- callbacks.onStreamEnd?.()
144
- accumulator.resetSegments()
145
- break
146
-
147
- case 'metadata':
148
- callbacks.onMetadata?.(action)
149
- break
150
-
151
- case 'text': {
152
- const segments = accumulator.appendText(action.text)
153
- // Append-mode only for *true* post-stream continuation (after a
154
- // MESSAGE_END we actually saw). Cold-start chunks (no prior
155
- // MESSAGE_START) emit cumulative segments so the consumer can
156
- // spawn the first assistant bubble — otherwise appendSegmentsToLastAssistant
157
- // silently drops the chunk when no last assistant exists.
158
- if (isInStreamRef.current || !hasEverStreamedRef.current) {
159
- emitSegments(segments)
160
- } else {
161
- emitSegments([{ type: 'text', text: action.text }], { append: true })
162
- }
163
- break
164
- }
165
-
166
- case 'thinking': {
167
- const segments = accumulator.appendThinking(action.text)
168
- if (isInStreamRef.current || !hasEverStreamedRef.current) {
169
- emitSegments(segments)
170
- } else {
171
- emitSegments([{ type: 'thinking', text: action.text }], { append: true })
172
- }
173
- break
174
- }
175
-
176
- case 'tool_execution': {
177
- // A starting tool run means the agent's turn is in progress even
178
- // when this lands after MESSAGE_END (approved commands execute
179
- // between the approval bubble and the continuation stream).
180
- if (action.segment.data.type === 'EXECUTING_TOOL') {
181
- callbacks.onAgentBusy?.()
182
- }
183
- // Post-MESSAGE_END tool chunks (cancellations / async batch
184
- // results for a batch in a prior bubble) flow only through the
185
- // cross-message updater. Skipping the accumulator avoids
186
- // pushing a standalone segment that the next text chunk would
187
- // replay into a new bubble.
188
- if (!isInStreamRef.current && callbacks.onToolExecuted) {
189
- callbacks.onToolExecuted(action.segment)
190
- break
191
- }
192
- // In-stream: accumulator-driven update of the streaming bubble
193
- // is the source of truth. Don't fire onToolExecuted here — its
194
- // cross-message scan is first-match-wins and could touch a
195
- // same-execId segment in a prior bubble (agent retry case).
196
- //
197
- // KNOWN EDGE (accepted): a slow async batch tool whose EXECUTED
198
- // lands only AFTER the continuation stream's MESSAGE_START takes
199
- // this path too — the freshly reset accumulator has no batch
200
- // segment to merge into, so the chunk renders as a standalone card
201
- // in the new bubble while the prior batch card's executions slot
202
- // stays 'executing' until the next history refetch. Routing such
203
- // chunks cross-message would reintroduce the retry hazard above;
204
- // revisit only if the backend confirms batch executions can
205
- // overlap the continuation stream.
206
- const segments = accumulator.addToolExecution(action.segment)
207
- emitSegments(segments)
208
- break
209
- }
210
-
211
- case 'approval_request': {
212
- const { requestId, command, explanation, approvalType } = action
213
-
214
- if (displayApprovalTypes.includes(approvalType)) {
215
- // Display directly
216
- const status = approvalStatuses[requestId] || 'pending'
217
- const segments = accumulator.addApprovalRequest(
218
- requestId,
219
- command,
220
- explanation,
221
- approvalType,
222
- status as ChatApprovalStatus
223
- )
224
- emitSegments(segments)
225
- } else {
226
- // Track as escalated
227
- pendingEscalatedRef.current.set(requestId, { command, explanation, approvalType })
228
- callbacks.onEscalatedApproval?.(requestId, { command, explanation, approvalType })
229
- }
230
- break
231
- }
232
-
233
- case 'approval_batch': {
234
- const { requestId, approvalType, toolCalls } = action
235
- const status = (approvalStatuses[requestId] || 'pending') as ChatApprovalStatus
236
-
237
- if (!displayApprovalTypes.includes(approvalType)) {
238
- // Escalated: keep batch context locally for replay on result; surface a
239
- // summary command via the legacy escalation callback.
240
- const required = toolCalls.find((c) => c.requiresApproval) ?? toolCalls[0]
241
- const summary = required ? getCommandText(required) : `Batch of ${toolCalls.length} tool calls`
242
- pendingEscalatedRef.current.set(requestId, {
243
- command: summary,
244
- explanation: required?.toolExplanation,
245
- approvalType,
246
- toolCalls,
247
- })
248
- callbacks.onEscalatedApproval?.(requestId, {
249
- command: summary,
250
- explanation: required?.toolExplanation,
251
- approvalType,
252
- })
253
- break
254
- }
255
-
256
- if (batchApprovalsEnabled) {
257
- const segments = accumulator.addApprovalBatch(requestId, approvalType, toolCalls, status)
258
- emitSegments(segments)
259
- break
260
- }
261
-
262
- // Flag OFF — unfold batch into N legacy approval cards. They share
263
- // `requestId`, so a click on any will approve the whole batch via a
264
- // single backend call, and the resulting APPROVAL_RESULT chunk will
265
- // flip status on every matching segment (see updateApprovalStatus).
266
- let segments = accumulator.getSegments()
267
- for (const call of toolCalls) {
268
- if (!call.requiresApproval) continue
269
- segments = accumulator.addApprovalRequest(
270
- requestId,
271
- getCommandText(call),
272
- call.toolExplanation,
273
- approvalType,
274
- status,
275
- )
276
- }
277
- emitSegments(segments)
278
- break
279
- }
280
-
281
- case 'approval_result': {
282
- const { requestId, approved, approvalType, resolvedByName } = action
283
- // Approved → the agent resumes to execute the command(s); surface
284
- // busy immediately so the composer locks before EXECUTING_TOOL
285
- // lands. Rejection keeps the input free — the user may want to
286
- // type a correction right away.
287
- if (approved) callbacks.onAgentBusy?.()
288
- const escalatedData = pendingEscalatedRef.current.get(requestId)
289
- const status: ChatApprovalStatus = approved ? 'approved' : 'rejected'
290
-
291
- if (escalatedData) {
292
- pendingEscalatedRef.current.delete(requestId)
293
- callbacks.onEscalatedApprovalResult?.(requestId, approved, {
294
- command: escalatedData.command,
295
- explanation: escalatedData.explanation,
296
- approvalType: escalatedData.approvalType,
297
- })
298
-
299
- // The escalated card was never displayed inline, so this emit is
300
- // what surfaces it after resolution. In-stream the cumulative
301
- // array is correct; post-MESSAGE_END the accumulator was RESET,
302
- // so a cumulative (replace-mode) emit would wipe the trailing
303
- // bubble down to the lone card — emit only the resolved card(s)
304
- // as an append instead. Store hosts upsert batches by request id,
305
- // so a replayed append stays idempotent.
306
- const emitResolved = (segments: MessageSegment[]) => {
307
- if (isInStreamRef.current) {
308
- emitSegments(segments)
309
- return
310
- }
311
- const delta = segments.filter(
312
- (s) =>
313
- (s.type === 'approval_request' && s.data.requestId === requestId) ||
314
- (s.type === 'approval_batch' && s.data.approvalRequestId === requestId),
315
- )
316
- emitSegments(delta, { append: true })
317
- }
318
-
319
- if (escalatedData.toolCalls && escalatedData.toolCalls.length > 0) {
320
- if (batchApprovalsEnabled) {
321
- const segments = accumulator.addApprovalBatch(
322
- requestId,
323
- escalatedData.approvalType,
324
- escalatedData.toolCalls,
325
- status,
326
- undefined,
327
- resolvedByName,
328
- )
329
- emitResolved(segments)
330
- } else {
331
- let segments = accumulator.getSegments()
332
- for (const call of escalatedData.toolCalls) {
333
- if (!call.requiresApproval) continue
334
- segments = accumulator.addApprovalRequest(
335
- requestId,
336
- getCommandText(call),
337
- call.toolExplanation,
338
- escalatedData.approvalType,
339
- status,
340
- )
341
- }
342
- emitResolved(segments)
343
- }
344
- } else {
345
- const segments = accumulator.addApprovalRequest(
346
- requestId,
347
- escalatedData.command,
348
- escalatedData.explanation,
349
- escalatedData.approvalType,
350
- status,
351
- )
352
- emitResolved(segments)
353
- }
354
- } else {
355
- // Always keep the in-memory accumulator in sync so a following
356
- // text/tool chunk replays the resolved status into the message.
357
- accumulator.updateApprovalStatus(requestId, status, resolvedByName)
358
- // When the consumer wires cross-message resolution via
359
- // `onApprovalResolved`, skip `onSegmentsUpdate` here: this path
360
- // routes through `ensureAssistantMessage` + `updateStreamingMessageSegments`,
361
- // which adopts/creates an assistant bubble and replays the
362
- // accumulator's segments into it — turning a status flip into a
363
- // bubble overwrite that wipes the original card.
364
- if (!callbacks.onApprovalResolved) {
365
- emitSegments(accumulator.getSegments())
366
- }
367
- }
368
- callbacks.onApprovalResolved?.(requestId, status, approvalType, resolvedByName)
369
- break
370
- }
371
-
372
- case 'error': {
373
- let message: string | undefined
374
- if ('details' in action && action?.details) {
375
- try {
376
- message = JSON.parse(action.details)?.error?.message
377
- } catch {
378
- message = action.details
379
- }
380
- }
381
- const segments = accumulator.addError(action.error, message)
382
- emitSegments(segments)
383
- callbacks.onError?.(action.error, message)
384
- break
385
- }
386
-
387
- case 'system': {
388
- callbacks.onSystemMessage?.(action.text, { streamSeq })
389
- break
390
- }
391
-
392
- case 'direct_message': {
393
- callbacks.onDirectMessage?.(action.text, {
394
- ownerType: action.ownerType,
395
- displayName: action.displayName,
396
- userId: action.userId,
397
- streamSeq,
398
- })
399
- break
400
- }
401
-
402
- case 'message_request':
403
- callbacks.onUserMessage?.(action.text, {
404
- ownerType: action.ownerType,
405
- displayName: action.displayName,
406
- userId: action.userId,
407
- streamSeq,
408
- contextItems: action.contextItems,
409
- })
410
- break
411
-
412
- case 'token_usage':
413
- callbacks.onTokenUsage?.(action.data)
414
- break
415
-
416
- case 'context_compaction_start': {
417
- const standalone = !isInStreamRef.current
418
- const segments = accumulator.addContextCompaction()
419
- emitSegments(segments, standalone ? { append: true, isCompacting: true } : undefined)
420
- break
421
- }
422
-
423
- case 'context_compaction_end': {
424
- const standalone = !isInStreamRef.current
425
- const segments = accumulator.completeContextCompaction(action.summary)
426
- emitSegments(segments, standalone ? { append: true, isCompacting: true } : undefined)
427
- break
428
- }
429
-
430
- case 'dialog_closed':
431
- callbacks.onDialogClosed?.()
432
- break
433
-
434
- default:
435
- // Unknown action - ignore
436
- break
437
- }
438
- },
439
- [callbacks, displayApprovalTypes, approvalStatuses, initialState]
440
- )
441
-
442
- const getSegments = useCallback(() => {
443
- return accumulatorRef.current.getSegments()
444
- }, [])
445
-
446
- const reset = useCallback(() => {
447
- accumulatorRef.current.reset()
448
- pendingEscalatedRef.current.clear()
449
- hasInitializedWithData.current = false
450
- sawDirectMessageRef.current = false
451
- directTeardownFiredRef.current = false
452
- // Stream-state flags are per-dialog too. Leaking them across a reset
453
- // made the next dialog's cold-start chunks take the post-stream append
454
- // path (hasEverStreamed stuck true) — which consumers may silently drop
455
- // when no assistant bubble exists yet — and left tool/compaction routing
456
- // thinking a stream was still open (isInStream stuck true).
457
- isInStreamRef.current = false
458
- hasEverStreamedRef.current = false
459
- }, [])
460
-
461
- const updateApprovalStatus = useCallback(
462
- (requestId: string, status: ChatApprovalStatus, resolvedByName?: string | null) => {
463
- return accumulatorRef.current.updateApprovalStatus(requestId, status, resolvedByName)
464
- },
465
- []
466
- )
467
-
468
- const getPendingApprovals = useCallback(() => {
469
- return new Map(pendingEscalatedRef.current)
470
- }, [])
471
-
472
- return {
473
- processChunk,
474
- getSegments,
475
- reset,
476
- updateApprovalStatus,
477
- getPendingApprovals,
478
- }
479
- }
@@ -1,62 +0,0 @@
1
- <!-- source-hash: c8c1cef3b3966f8791e7003c4f74429f -->
2
- Utilities for parsing raw NATS message chunks into typed, structured action objects consumed by the OpenFrame chat pipeline.
3
-
4
- ## Key Components
5
-
6
- ### `parseChunkToAction(chunk: unknown): ParsedChunkAction | null`
7
- The primary export. Accepts an untyped NATS chunk, inspects its `type` field against `MESSAGE_TYPE` constants, and returns a discriminated `ParsedChunkAction` union or `null` for unrecognized types. Handles the full message lifecycle including:
8
-
9
- - **Lifecycle signals:** `message_start`, `message_end`, `dialog_closed`
10
- - **Content:** `text`, `thinking`, `system`, `direct_message`
11
- - **Tool execution:** `tool_execution` (both `EXECUTING_TOOL` and `EXECUTED_TOOL` states)
12
- - **Approval flow:** `approval_request`, `approval_batch`, `approval_result`
13
- - **Metadata & telemetry:** `metadata`, `token_usage`, `context_compaction_start/end`
14
- - **Error handling:** `error`
15
-
16
- ### `normalizeToolCalls(raw: unknown): PendingToolCallData[]` *(internal)*
17
- Safely coerces an untyped array into `PendingToolCallData[]`, filtering non-objects and providing safe defaults for all fields.
18
-
19
- ### Predicate helpers
20
- Lightweight type guards for fast chunk classification without full parsing:
21
-
22
- | Function | Returns `true` when |
23
- |---|---|
24
- | `isControlChunk` | `MESSAGE_START` or `MESSAGE_END` |
25
- | `isErrorChunk` | `ERROR` type |
26
- | `isMetadataChunk` | `AI_METADATA` type |
27
- | `extractTextFromChunk` | `TEXT` type — returns the string or `null` |
28
-
29
- ## Usage Example
30
-
31
- ```typescript
32
- import {
33
- parseChunkToAction,
34
- isControlChunk,
35
- isErrorChunk,
36
- } from './chunk-parser'
37
-
38
- // Parse an incoming NATS chunk
39
- const action = parseChunkToAction(rawChunk)
40
-
41
- if (action?.action === 'text') {
42
- appendToTranscript(action.text)
43
- } else if (action?.action === 'approval_batch') {
44
- promptUserApproval(action.toolCalls)
45
- }
46
-
47
- // Fast-path guards before full parse
48
- if (isErrorChunk(rawChunk)) {
49
- handleError()
50
- }
51
- if (isControlChunk(rawChunk)) {
52
- resetStreamState()
53
- }
54
- ```
55
-
56
- ## Notes
57
-
58
- - All field access is defensive — missing or wrong-typed properties fall back to safe defaults rather than throwing.
59
- - `approval_result` accepts both `resolvedByName` and `displayName` so realtime NATS chunks and GraphQL history replays produce identical output shapes.
60
- - `contextItems` on `message_request` back-fills `label` from `id` to satisfy the required `ChatContextItem` contract when no label is present on the wire.
61
-
62
- **Source:** [`https://github.com/flamingo-stack/openframe-oss-lib/blob/main/chunk-parser.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/chunk-parser.ts)