@flamingo-stack/openframe-frontend-core 0.0.508 → 0.0.509

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 (306) 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 +216 -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 +506 -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 +490 -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-3SQ5KXHQ.cjs → chunk-2T4GTV25.cjs} +9 -9
  22. package/dist/{chunk-3SQ5KXHQ.cjs.map → chunk-2T4GTV25.cjs.map} +1 -1
  23. package/dist/{chunk-CWAOV2FK.cjs → chunk-3CGZPAGR.cjs} +3 -3
  24. package/dist/{chunk-CWAOV2FK.cjs.map → chunk-3CGZPAGR.cjs.map} +1 -1
  25. package/dist/{chunk-TLMJHMXJ.js → chunk-3QSR22IC.js} +12 -12
  26. package/dist/chunk-3QSR22IC.js.map +1 -0
  27. package/dist/{chunk-TWYNR4TZ.cjs → chunk-4G5TLHJD.cjs} +7141 -4799
  28. package/dist/chunk-4G5TLHJD.cjs.map +1 -0
  29. package/dist/{chunk-ADPMHWOE.js → chunk-72XAID7Y.js} +4 -4
  30. package/dist/{chunk-PAGKRNWK.js → chunk-7WZHBQ4J.js} +2 -2
  31. package/dist/{chunk-OCEKO5CW.js → chunk-AEELJC4N.js} +12106 -9764
  32. package/dist/chunk-AEELJC4N.js.map +1 -0
  33. package/dist/{chunk-Z42BGM6Q.cjs → chunk-BT2WWDFP.cjs} +5 -5
  34. package/dist/{chunk-Z42BGM6Q.cjs.map → chunk-BT2WWDFP.cjs.map} +1 -1
  35. package/dist/{chunk-7LEL3RIX.cjs → chunk-C7OY3PQP.cjs} +11 -11
  36. package/dist/{chunk-7LEL3RIX.cjs.map → chunk-C7OY3PQP.cjs.map} +1 -1
  37. package/dist/{chunk-RHGGEKPQ.cjs → chunk-CIOLOQKQ.cjs} +4 -4
  38. package/dist/{chunk-RHGGEKPQ.cjs.map → chunk-CIOLOQKQ.cjs.map} +1 -1
  39. package/dist/{chunk-TSZHM74B.js → chunk-DC2TKS7C.js} +2 -2
  40. package/dist/{chunk-M2GOR3XQ.cjs → chunk-DYPYR7FR.cjs} +87 -87
  41. package/dist/{chunk-M2GOR3XQ.cjs.map → chunk-DYPYR7FR.cjs.map} +1 -1
  42. package/dist/{chunk-I64ABCDX.js → chunk-I2B6X77L.js} +2 -2
  43. package/dist/{chunk-NIZDKTGL.cjs → chunk-K5MSCMDK.cjs} +37 -37
  44. package/dist/{chunk-NIZDKTGL.cjs.map → chunk-K5MSCMDK.cjs.map} +1 -1
  45. package/dist/{chunk-DTYRYB2N.js → chunk-K6QTZ7CZ.js} +2 -2
  46. package/dist/{chunk-4LTMXDUS.js → chunk-KBN7PMFT.js} +2 -2
  47. package/dist/{chunk-TBMV7I5N.js → chunk-KXZO2WZX.js} +2 -2
  48. package/dist/{chunk-QTYZMP6D.cjs → chunk-LBAKLT6T.cjs} +62 -62
  49. package/dist/chunk-LBAKLT6T.cjs.map +1 -0
  50. package/dist/{chunk-KEBYLU3U.js → chunk-LFUPI7VX.js} +2 -2
  51. package/dist/{chunk-LDTR4IVZ.cjs → chunk-M37PBG4N.cjs} +31 -31
  52. package/dist/{chunk-LDTR4IVZ.cjs.map → chunk-M37PBG4N.cjs.map} +1 -1
  53. package/dist/{chunk-WA7RR64F.js → chunk-PO5O654H.js} +6 -5
  54. package/dist/chunk-PO5O654H.js.map +1 -0
  55. package/dist/{chunk-WK4N5VBX.cjs → chunk-QJJISLPA.cjs} +28 -27
  56. package/dist/chunk-QJJISLPA.cjs.map +1 -0
  57. package/dist/{chunk-2F44PLTV.cjs → chunk-T7MCSA55.cjs} +26 -26
  58. package/dist/{chunk-2F44PLTV.cjs.map → chunk-T7MCSA55.cjs.map} +1 -1
  59. package/dist/{chunk-WJQHJD7J.js → chunk-TWSKTJHW.js} +2 -2
  60. package/dist/{chunk-ZSQHZYCO.cjs → chunk-UQDMJ6DH.cjs} +13 -13
  61. package/dist/{chunk-ZSQHZYCO.cjs.map → chunk-UQDMJ6DH.cjs.map} +1 -1
  62. package/dist/{chunk-TZRUCD56.js → chunk-V3ZAAFE3.js} +5 -5
  63. package/dist/{chunk-LRGHJPET.js → chunk-XGIFOHKE.js} +2 -2
  64. package/dist/{chunk-POOMO3PA.cjs → chunk-YQEPRYT5.cjs} +7 -7
  65. package/dist/{chunk-POOMO3PA.cjs.map → chunk-YQEPRYT5.cjs.map} +1 -1
  66. package/dist/components/case-studies/index.cjs +8 -8
  67. package/dist/components/case-studies/index.js +2 -2
  68. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  69. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  70. package/dist/components/chat/hooks/index.d.ts +0 -1
  71. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  72. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  73. package/dist/components/chat/hooks/use-chunk-catchup.d.ts.map +1 -1
  74. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +15 -48
  75. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  76. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +10 -57
  77. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  78. package/dist/components/chat/index.cjs +10 -2
  79. package/dist/components/chat/index.cjs.map +1 -1
  80. package/dist/components/chat/index.d.ts +1 -0
  81. package/dist/components/chat/index.d.ts.map +1 -1
  82. package/dist/components/chat/index.js +21 -13
  83. package/dist/components/chat/stream/chat-dialog-store.d.ts +184 -0
  84. package/dist/components/chat/stream/chat-dialog-store.d.ts.map +1 -0
  85. package/dist/components/chat/stream/chat-stream-reducer.d.ts +380 -0
  86. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -0
  87. package/dist/components/chat/stream/delta-batcher.d.ts +51 -0
  88. package/dist/components/chat/stream/delta-batcher.d.ts.map +1 -0
  89. package/dist/components/chat/stream/index.d.ts +17 -0
  90. package/dist/components/chat/stream/index.d.ts.map +1 -0
  91. package/dist/components/chat/stream/message-mutations.d.ts +77 -0
  92. package/dist/components/chat/stream/message-mutations.d.ts.map +1 -0
  93. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +22 -0
  94. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +1 -0
  95. package/dist/components/chat/types/api.types.d.ts +1 -81
  96. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  97. package/dist/components/chat/types/processing.types.d.ts +2 -93
  98. package/dist/components/chat/types/processing.types.d.ts.map +1 -1
  99. package/dist/components/chat/types/unified-chat-state.types.d.ts +15 -0
  100. package/dist/components/chat/types/unified-chat-state.types.d.ts.map +1 -1
  101. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +34 -6
  102. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
  103. package/dist/components/chat/utils/history-merge.d.ts.map +1 -1
  104. package/dist/components/chat/utils/index.d.ts +2 -3
  105. package/dist/components/chat/utils/index.d.ts.map +1 -1
  106. package/dist/components/chat/utils/process-historical-messages.d.ts +59 -11
  107. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  108. package/dist/components/contact/index.cjs +3 -3
  109. package/dist/components/contact/index.js +2 -2
  110. package/dist/components/docs/index.cjs +5 -5
  111. package/dist/components/docs/index.js +4 -4
  112. package/dist/components/embeds/index.cjs +3 -3
  113. package/dist/components/embeds/index.js +2 -2
  114. package/dist/components/faq/index.cjs +3 -3
  115. package/dist/components/faq/index.js +2 -2
  116. package/dist/components/features/index.cjs +2 -2
  117. package/dist/components/features/index.js +1 -1
  118. package/dist/components/help-center-pages/index.cjs +22 -22
  119. package/dist/components/help-center-pages/index.js +13 -13
  120. package/dist/components/index.cjs +174 -132
  121. package/dist/components/index.cjs.map +1 -1
  122. package/dist/components/index.js +65 -23
  123. package/dist/components/index.js.map +1 -1
  124. package/dist/components/meeting-scheduler/index.cjs +34 -34
  125. package/dist/components/meeting-scheduler/index.js +3 -3
  126. package/dist/components/navigation/index.cjs +2 -2
  127. package/dist/components/navigation/index.js +1 -1
  128. package/dist/components/onboarding-guides/index.cjs +5 -5
  129. package/dist/components/onboarding-guides/index.js +4 -4
  130. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  131. package/dist/components/related-content/index.cjs +3 -3
  132. package/dist/components/related-content/index.js +2 -2
  133. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  134. package/dist/components/tickets/index.cjs +6 -6
  135. package/dist/components/tickets/index.js +5 -5
  136. package/dist/components/ui/index.cjs +44 -2
  137. package/dist/components/ui/index.cjs.map +1 -1
  138. package/dist/components/ui/index.d.ts +1 -2
  139. package/dist/components/ui/index.d.ts.map +1 -1
  140. package/dist/components/ui/index.js +55 -13
  141. package/dist/components/ui/markdown/base-components.d.ts +51 -0
  142. package/dist/components/ui/markdown/base-components.d.ts.map +1 -0
  143. package/dist/components/ui/markdown/engine.d.ts +99 -0
  144. package/dist/components/ui/markdown/engine.d.ts.map +1 -0
  145. package/dist/components/ui/markdown/heading-ids.d.ts +65 -0
  146. package/dist/components/ui/markdown/heading-ids.d.ts.map +1 -0
  147. package/dist/components/ui/markdown/index.d.ts +18 -0
  148. package/dist/components/ui/markdown/index.d.ts.map +1 -0
  149. package/dist/components/ui/markdown/mermaid-diagram.d.ts +79 -0
  150. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +1 -0
  151. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +14 -0
  152. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +1 -0
  153. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +40 -0
  154. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -0
  155. package/dist/components/ui/markdown/rich/shortcodes.d.ts +8 -0
  156. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +1 -0
  157. package/dist/components/ui/markdown/sanitize.d.ts +153 -0
  158. package/dist/components/ui/markdown/sanitize.d.ts.map +1 -0
  159. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +23 -0
  160. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +1 -0
  161. package/dist/components/ui/markdown/streaming.d.ts +78 -0
  162. package/dist/components/ui/markdown/streaming.d.ts.map +1 -0
  163. package/dist/components/ui/markdown/text-size.d.ts +34 -0
  164. package/dist/components/ui/markdown/text-size.d.ts.map +1 -0
  165. package/dist/index.cjs +60 -2
  166. package/dist/index.cjs.map +1 -1
  167. package/dist/index.js +71 -13
  168. package/dist/utils/index.cjs +169 -40
  169. package/dist/utils/index.cjs.map +1 -1
  170. package/dist/utils/index.d.ts +1 -0
  171. package/dist/utils/index.d.ts.map +1 -1
  172. package/dist/utils/index.js +162 -41
  173. package/dist/utils/index.js.map +1 -1
  174. package/dist/utils/markdown-fences.d.ts +42 -0
  175. package/dist/utils/markdown-fences.d.ts.map +1 -0
  176. package/dist/utils/markdown-heading-id.d.ts +85 -0
  177. package/dist/utils/markdown-heading-id.d.ts.map +1 -0
  178. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  179. package/package.json +7 -1
  180. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +319 -0
  181. package/src/chat-protocol/__tests__/chat-protocol.test.ts +516 -0
  182. package/src/chat-protocol/__tests__/env-flag.test.ts +52 -0
  183. package/src/chat-protocol/__tests__/ip-normalize.test.ts +136 -0
  184. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +237 -0
  185. package/src/chat-protocol/decode.ts +278 -0
  186. package/src/chat-protocol/encode.ts +71 -0
  187. package/src/chat-protocol/env-flag.ts +39 -0
  188. package/src/chat-protocol/events.ts +254 -0
  189. package/src/chat-protocol/frames.ts +245 -0
  190. package/src/chat-protocol/index.ts +21 -0
  191. package/src/chat-protocol/ip-normalize.ts +146 -0
  192. package/src/chat-protocol/nats-decoder.ts +264 -0
  193. package/src/components/chat/.chat-message-list.md +10 -6
  194. package/src/components/chat/__tests__/chat-message-list.test.tsx +450 -9
  195. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +207 -0
  196. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +250 -0
  197. package/src/components/chat/chat-message-enhanced.tsx +122 -20
  198. package/src/components/chat/chat-message-list.tsx +515 -133
  199. package/src/components/chat/embeddable-chat.tsx +6 -0
  200. package/src/components/chat/hooks/.index.md +30 -33
  201. package/src/components/chat/hooks/.use-nats-chat-adapter.md +36 -55
  202. package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +37 -0
  203. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  204. package/src/components/chat/hooks/__tests__/chunk-catchup-dialog-staleness.test.ts +92 -0
  205. package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +438 -0
  206. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +318 -0
  207. package/src/components/chat/hooks/index.ts +0 -1
  208. package/src/components/chat/hooks/use-chat.ts +8 -0
  209. package/src/components/chat/hooks/use-chunk-catchup.ts +26 -1
  210. package/src/components/chat/hooks/use-nats-chat-adapter.ts +254 -825
  211. package/src/components/chat/hooks/use-sse-chat-adapter.ts +380 -684
  212. package/src/components/chat/index.ts +5 -0
  213. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +944 -0
  214. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +806 -0
  215. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +467 -0
  216. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +1330 -0
  217. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +255 -0
  218. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +105 -0
  219. package/src/components/chat/stream/chat-dialog-store.ts +536 -0
  220. package/src/components/chat/stream/chat-stream-reducer.ts +1928 -0
  221. package/src/components/chat/stream/delta-batcher.ts +168 -0
  222. package/src/components/chat/stream/index.ts +55 -0
  223. package/src/components/chat/stream/message-mutations.ts +340 -0
  224. package/src/components/chat/stream/use-chat-stream-reducer.ts +126 -0
  225. package/src/components/chat/thinking-display.tsx +1 -1
  226. package/src/components/chat/types/.api.types.md +39 -49
  227. package/src/components/chat/types/.processing.types.md +29 -58
  228. package/src/components/chat/types/.unified-chat-state.types.md +2 -2
  229. package/src/components/chat/types/api.types.ts +6 -73
  230. package/src/components/chat/types/processing.types.ts +11 -53
  231. package/src/components/chat/types/unified-chat-state.types.ts +16 -0
  232. package/src/components/chat/utils/.extract-incomplete-message-state.md +21 -3
  233. package/src/components/chat/utils/.history-merge.md +44 -3
  234. package/src/components/chat/utils/.index.md +31 -40
  235. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +420 -0
  236. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +605 -0
  237. package/src/components/chat/utils/__tests__/extract-incomplete-message-state.test.ts +106 -0
  238. package/src/components/chat/utils/__tests__/history-merge.test.ts +160 -0
  239. package/src/components/chat/utils/__tests__/process-historical-messages-approvals.test.ts +61 -0
  240. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +394 -0
  241. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +270 -0
  242. package/src/components/chat/utils/extract-incomplete-message-state.ts +93 -6
  243. package/src/components/chat/utils/history-merge.ts +85 -5
  244. package/src/components/chat/utils/index.ts +5 -8
  245. package/src/components/chat/utils/process-historical-messages.ts +361 -385
  246. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +22 -4
  247. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  248. package/src/components/shared/product-release/release-detail-page.tsx +19 -4
  249. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +2420 -0
  250. package/src/components/ui/__tests__/markdown-parity.test.tsx +2540 -0
  251. package/src/components/ui/index.ts +1 -2
  252. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +176 -0
  253. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +151 -0
  254. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +354 -0
  255. package/src/components/ui/markdown/__tests__/sanitize-render.test.tsx +118 -0
  256. package/src/components/ui/markdown/__tests__/streaming.test.tsx +436 -0
  257. package/src/components/ui/markdown/base-components.tsx +360 -0
  258. package/src/components/ui/markdown/engine.tsx +315 -0
  259. package/src/components/ui/markdown/heading-ids.ts +239 -0
  260. package/src/components/ui/markdown/index.ts +49 -0
  261. package/src/components/ui/markdown/mermaid-diagram.tsx +323 -0
  262. package/src/components/ui/markdown/rich/embed-overrides.tsx +199 -0
  263. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +184 -0
  264. package/src/components/ui/markdown/rich/shortcodes.ts +170 -0
  265. package/src/components/ui/markdown/sanitize.ts +3584 -0
  266. package/src/components/ui/markdown/simple-markdown-renderer.tsx +28 -0
  267. package/src/components/ui/markdown/streaming.ts +390 -0
  268. package/src/components/ui/markdown/text-size.ts +106 -0
  269. package/src/components/ui/release-changelog-section.tsx +1 -1
  270. package/src/components/ui/ticket-info-section.tsx +1 -1
  271. package/src/utils/index.ts +1 -0
  272. package/src/utils/markdown-fences.ts +127 -0
  273. package/src/utils/markdown-heading-id.ts +348 -0
  274. package/src/utils/markdown-section-extractor.ts +41 -56
  275. package/dist/chunk-OCEKO5CW.js.map +0 -1
  276. package/dist/chunk-QTYZMP6D.cjs.map +0 -1
  277. package/dist/chunk-TLMJHMXJ.js.map +0 -1
  278. package/dist/chunk-TWYNR4TZ.cjs.map +0 -1
  279. package/dist/chunk-WA7RR64F.js.map +0 -1
  280. package/dist/chunk-WK4N5VBX.cjs.map +0 -1
  281. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +0 -6
  282. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +0 -1
  283. package/dist/components/chat/utils/chunk-parser.d.ts +0 -25
  284. package/dist/components/chat/utils/chunk-parser.d.ts.map +0 -1
  285. package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
  286. package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
  287. package/dist/components/ui/simple-markdown-renderer.d.ts +0 -73
  288. package/dist/components/ui/simple-markdown-renderer.d.ts.map +0 -1
  289. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +0 -77
  290. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +0 -489
  291. package/src/components/chat/utils/.chunk-parser.md +0 -62
  292. package/src/components/chat/utils/chunk-parser.ts +0 -262
  293. package/src/components/ui/.simple-markdown-renderer.md +0 -52
  294. package/src/components/ui/rich-markdown-renderer.tsx +0 -1223
  295. package/src/components/ui/simple-markdown-renderer.tsx +0 -964
  296. /package/dist/{chunk-ADPMHWOE.js.map → chunk-72XAID7Y.js.map} +0 -0
  297. /package/dist/{chunk-PAGKRNWK.js.map → chunk-7WZHBQ4J.js.map} +0 -0
  298. /package/dist/{chunk-TSZHM74B.js.map → chunk-DC2TKS7C.js.map} +0 -0
  299. /package/dist/{chunk-I64ABCDX.js.map → chunk-I2B6X77L.js.map} +0 -0
  300. /package/dist/{chunk-DTYRYB2N.js.map → chunk-K6QTZ7CZ.js.map} +0 -0
  301. /package/dist/{chunk-4LTMXDUS.js.map → chunk-KBN7PMFT.js.map} +0 -0
  302. /package/dist/{chunk-TBMV7I5N.js.map → chunk-KXZO2WZX.js.map} +0 -0
  303. /package/dist/{chunk-KEBYLU3U.js.map → chunk-LFUPI7VX.js.map} +0 -0
  304. /package/dist/{chunk-WJQHJD7J.js.map → chunk-TWSKTJHW.js.map} +0 -0
  305. /package/dist/{chunk-TZRUCD56.js.map → chunk-V3ZAAFE3.js.map} +0 -0
  306. /package/dist/{chunk-LRGHJPET.js.map → chunk-XGIFOHKE.js.map} +0 -0
@@ -1,489 +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 'guide': {
177
- const segments = accumulator.appendGuide(action.text)
178
- if (isInStreamRef.current || !hasEverStreamedRef.current) {
179
- emitSegments(segments)
180
- } else {
181
- emitSegments([{ type: 'guide', text: action.text }], { append: true })
182
- }
183
- break
184
- }
185
-
186
- case 'tool_execution': {
187
- // A starting tool run means the agent's turn is in progress even
188
- // when this lands after MESSAGE_END (approved commands execute
189
- // between the approval bubble and the continuation stream).
190
- if (action.segment.data.type === 'EXECUTING_TOOL') {
191
- callbacks.onAgentBusy?.()
192
- }
193
- // Post-MESSAGE_END tool chunks (cancellations / async batch
194
- // results for a batch in a prior bubble) flow only through the
195
- // cross-message updater. Skipping the accumulator avoids
196
- // pushing a standalone segment that the next text chunk would
197
- // replay into a new bubble.
198
- if (!isInStreamRef.current && callbacks.onToolExecuted) {
199
- callbacks.onToolExecuted(action.segment)
200
- break
201
- }
202
- // In-stream: accumulator-driven update of the streaming bubble
203
- // is the source of truth. Don't fire onToolExecuted here — its
204
- // cross-message scan is first-match-wins and could touch a
205
- // same-execId segment in a prior bubble (agent retry case).
206
- //
207
- // KNOWN EDGE (accepted): a slow async batch tool whose EXECUTED
208
- // lands only AFTER the continuation stream's MESSAGE_START takes
209
- // this path too — the freshly reset accumulator has no batch
210
- // segment to merge into, so the chunk renders as a standalone card
211
- // in the new bubble while the prior batch card's executions slot
212
- // stays 'executing' until the next history refetch. Routing such
213
- // chunks cross-message would reintroduce the retry hazard above;
214
- // revisit only if the backend confirms batch executions can
215
- // overlap the continuation stream.
216
- const segments = accumulator.addToolExecution(action.segment)
217
- emitSegments(segments)
218
- break
219
- }
220
-
221
- case 'approval_request': {
222
- const { requestId, command, explanation, approvalType } = action
223
-
224
- if (displayApprovalTypes.includes(approvalType)) {
225
- // Display directly
226
- const status = approvalStatuses[requestId] || 'pending'
227
- const segments = accumulator.addApprovalRequest(
228
- requestId,
229
- command,
230
- explanation,
231
- approvalType,
232
- status as ChatApprovalStatus
233
- )
234
- emitSegments(segments)
235
- } else {
236
- // Track as escalated
237
- pendingEscalatedRef.current.set(requestId, { command, explanation, approvalType })
238
- callbacks.onEscalatedApproval?.(requestId, { command, explanation, approvalType })
239
- }
240
- break
241
- }
242
-
243
- case 'approval_batch': {
244
- const { requestId, approvalType, toolCalls } = action
245
- const status = (approvalStatuses[requestId] || 'pending') as ChatApprovalStatus
246
-
247
- if (!displayApprovalTypes.includes(approvalType)) {
248
- // Escalated: keep batch context locally for replay on result; surface a
249
- // summary command via the legacy escalation callback.
250
- const required = toolCalls.find((c) => c.requiresApproval) ?? toolCalls[0]
251
- const summary = required ? getCommandText(required) : `Batch of ${toolCalls.length} tool calls`
252
- pendingEscalatedRef.current.set(requestId, {
253
- command: summary,
254
- explanation: required?.toolExplanation,
255
- approvalType,
256
- toolCalls,
257
- })
258
- callbacks.onEscalatedApproval?.(requestId, {
259
- command: summary,
260
- explanation: required?.toolExplanation,
261
- approvalType,
262
- })
263
- break
264
- }
265
-
266
- if (batchApprovalsEnabled) {
267
- const segments = accumulator.addApprovalBatch(requestId, approvalType, toolCalls, status)
268
- emitSegments(segments)
269
- break
270
- }
271
-
272
- // Flag OFF — unfold batch into N legacy approval cards. They share
273
- // `requestId`, so a click on any will approve the whole batch via a
274
- // single backend call, and the resulting APPROVAL_RESULT chunk will
275
- // flip status on every matching segment (see updateApprovalStatus).
276
- let segments = accumulator.getSegments()
277
- for (const call of toolCalls) {
278
- if (!call.requiresApproval) continue
279
- segments = accumulator.addApprovalRequest(
280
- requestId,
281
- getCommandText(call),
282
- call.toolExplanation,
283
- approvalType,
284
- status,
285
- )
286
- }
287
- emitSegments(segments)
288
- break
289
- }
290
-
291
- case 'approval_result': {
292
- const { requestId, approved, approvalType, resolvedByName } = action
293
- // Approved → the agent resumes to execute the command(s); surface
294
- // busy immediately so the composer locks before EXECUTING_TOOL
295
- // lands. Rejection keeps the input free — the user may want to
296
- // type a correction right away.
297
- if (approved) callbacks.onAgentBusy?.()
298
- const escalatedData = pendingEscalatedRef.current.get(requestId)
299
- const status: ChatApprovalStatus = approved ? 'approved' : 'rejected'
300
-
301
- if (escalatedData) {
302
- pendingEscalatedRef.current.delete(requestId)
303
- callbacks.onEscalatedApprovalResult?.(requestId, approved, {
304
- command: escalatedData.command,
305
- explanation: escalatedData.explanation,
306
- approvalType: escalatedData.approvalType,
307
- })
308
-
309
- // The escalated card was never displayed inline, so this emit is
310
- // what surfaces it after resolution. In-stream the cumulative
311
- // array is correct; post-MESSAGE_END the accumulator was RESET,
312
- // so a cumulative (replace-mode) emit would wipe the trailing
313
- // bubble down to the lone card — emit only the resolved card(s)
314
- // as an append instead. Store hosts upsert batches by request id,
315
- // so a replayed append stays idempotent.
316
- const emitResolved = (segments: MessageSegment[]) => {
317
- if (isInStreamRef.current) {
318
- emitSegments(segments)
319
- return
320
- }
321
- const delta = segments.filter(
322
- (s) =>
323
- (s.type === 'approval_request' && s.data.requestId === requestId) ||
324
- (s.type === 'approval_batch' && s.data.approvalRequestId === requestId),
325
- )
326
- emitSegments(delta, { append: true })
327
- }
328
-
329
- if (escalatedData.toolCalls && escalatedData.toolCalls.length > 0) {
330
- if (batchApprovalsEnabled) {
331
- const segments = accumulator.addApprovalBatch(
332
- requestId,
333
- escalatedData.approvalType,
334
- escalatedData.toolCalls,
335
- status,
336
- undefined,
337
- resolvedByName,
338
- )
339
- emitResolved(segments)
340
- } else {
341
- let segments = accumulator.getSegments()
342
- for (const call of escalatedData.toolCalls) {
343
- if (!call.requiresApproval) continue
344
- segments = accumulator.addApprovalRequest(
345
- requestId,
346
- getCommandText(call),
347
- call.toolExplanation,
348
- escalatedData.approvalType,
349
- status,
350
- )
351
- }
352
- emitResolved(segments)
353
- }
354
- } else {
355
- const segments = accumulator.addApprovalRequest(
356
- requestId,
357
- escalatedData.command,
358
- escalatedData.explanation,
359
- escalatedData.approvalType,
360
- status,
361
- )
362
- emitResolved(segments)
363
- }
364
- } else {
365
- // Always keep the in-memory accumulator in sync so a following
366
- // text/tool chunk replays the resolved status into the message.
367
- accumulator.updateApprovalStatus(requestId, status, resolvedByName)
368
- // When the consumer wires cross-message resolution via
369
- // `onApprovalResolved`, skip `onSegmentsUpdate` here: this path
370
- // routes through `ensureAssistantMessage` + `updateStreamingMessageSegments`,
371
- // which adopts/creates an assistant bubble and replays the
372
- // accumulator's segments into it — turning a status flip into a
373
- // bubble overwrite that wipes the original card.
374
- if (!callbacks.onApprovalResolved) {
375
- emitSegments(accumulator.getSegments())
376
- }
377
- }
378
- callbacks.onApprovalResolved?.(requestId, status, approvalType, resolvedByName)
379
- break
380
- }
381
-
382
- case 'error': {
383
- let message: string | undefined
384
- if ('details' in action && action?.details) {
385
- try {
386
- message = JSON.parse(action.details)?.error?.message
387
- } catch {
388
- message = action.details
389
- }
390
- }
391
- const segments = accumulator.addError(action.error, message)
392
- emitSegments(segments)
393
- callbacks.onError?.(action.error, message)
394
- break
395
- }
396
-
397
- case 'system': {
398
- callbacks.onSystemMessage?.(action.text, { streamSeq })
399
- break
400
- }
401
-
402
- case 'direct_message': {
403
- callbacks.onDirectMessage?.(action.text, {
404
- ownerType: action.ownerType,
405
- displayName: action.displayName,
406
- userId: action.userId,
407
- streamSeq,
408
- })
409
- break
410
- }
411
-
412
- case 'message_request':
413
- callbacks.onUserMessage?.(action.text, {
414
- ownerType: action.ownerType,
415
- displayName: action.displayName,
416
- userId: action.userId,
417
- streamSeq,
418
- contextItems: action.contextItems,
419
- })
420
- break
421
-
422
- case 'token_usage':
423
- callbacks.onTokenUsage?.(action.data)
424
- break
425
-
426
- case 'context_compaction_start': {
427
- const standalone = !isInStreamRef.current
428
- const segments = accumulator.addContextCompaction()
429
- emitSegments(segments, standalone ? { append: true, isCompacting: true } : undefined)
430
- break
431
- }
432
-
433
- case 'context_compaction_end': {
434
- const standalone = !isInStreamRef.current
435
- const segments = accumulator.completeContextCompaction(action.summary)
436
- emitSegments(segments, standalone ? { append: true, isCompacting: true } : undefined)
437
- break
438
- }
439
-
440
- case 'dialog_closed':
441
- callbacks.onDialogClosed?.()
442
- break
443
-
444
- default:
445
- // Unknown action - ignore
446
- break
447
- }
448
- },
449
- [callbacks, displayApprovalTypes, approvalStatuses, initialState]
450
- )
451
-
452
- const getSegments = useCallback(() => {
453
- return accumulatorRef.current.getSegments()
454
- }, [])
455
-
456
- const reset = useCallback(() => {
457
- accumulatorRef.current.reset()
458
- pendingEscalatedRef.current.clear()
459
- hasInitializedWithData.current = false
460
- sawDirectMessageRef.current = false
461
- directTeardownFiredRef.current = false
462
- // Stream-state flags are per-dialog too. Leaking them across a reset
463
- // made the next dialog's cold-start chunks take the post-stream append
464
- // path (hasEverStreamed stuck true) — which consumers may silently drop
465
- // when no assistant bubble exists yet — and left tool/compaction routing
466
- // thinking a stream was still open (isInStream stuck true).
467
- isInStreamRef.current = false
468
- hasEverStreamedRef.current = false
469
- }, [])
470
-
471
- const updateApprovalStatus = useCallback(
472
- (requestId: string, status: ChatApprovalStatus, resolvedByName?: string | null) => {
473
- return accumulatorRef.current.updateApprovalStatus(requestId, status, resolvedByName)
474
- },
475
- []
476
- )
477
-
478
- const getPendingApprovals = useCallback(() => {
479
- return new Map(pendingEscalatedRef.current)
480
- }, [])
481
-
482
- return {
483
- processChunk,
484
- getSegments,
485
- reset,
486
- updateApprovalStatus,
487
- getPendingApprovals,
488
- }
489
- }
@@ -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)