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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/dist/chat-protocol/decode.d.ts +58 -0
  2. package/dist/chat-protocol/decode.d.ts.map +1 -0
  3. package/dist/chat-protocol/encode.d.ts +44 -0
  4. package/dist/chat-protocol/encode.d.ts.map +1 -0
  5. package/dist/chat-protocol/env-flag.d.ts +35 -0
  6. package/dist/chat-protocol/env-flag.d.ts.map +1 -0
  7. package/dist/chat-protocol/events.d.ts +207 -0
  8. package/dist/chat-protocol/events.d.ts.map +1 -0
  9. package/dist/chat-protocol/frames.d.ts +213 -0
  10. package/dist/chat-protocol/frames.d.ts.map +1 -0
  11. package/dist/chat-protocol/index.cjs +500 -0
  12. package/dist/chat-protocol/index.cjs.map +1 -0
  13. package/dist/chat-protocol/index.d.ts +18 -0
  14. package/dist/chat-protocol/index.d.ts.map +1 -0
  15. package/dist/chat-protocol/index.js +484 -0
  16. package/dist/chat-protocol/index.js.map +1 -0
  17. package/dist/chat-protocol/ip-normalize.d.ts +44 -0
  18. package/dist/chat-protocol/ip-normalize.d.ts.map +1 -0
  19. package/dist/chat-protocol/nats-decoder.d.ts +26 -0
  20. package/dist/chat-protocol/nats-decoder.d.ts.map +1 -0
  21. package/dist/{chunk-2DER2JSI.cjs → chunk-242K7LZY.cjs} +11 -11
  22. package/dist/{chunk-2DER2JSI.cjs.map → chunk-242K7LZY.cjs.map} +1 -1
  23. package/dist/{chunk-VBSS4TPV.cjs → chunk-2LYA3RBT.cjs} +37 -37
  24. package/dist/{chunk-VBSS4TPV.cjs.map → chunk-2LYA3RBT.cjs.map} +1 -1
  25. package/dist/{chunk-ZPUCCSYA.js → chunk-34C2JV2C.js} +2 -2
  26. package/dist/{chunk-GWVNRXJU.js → chunk-3VGRZ62V.js} +2 -2
  27. package/dist/{chunk-AAHAVML2.js → chunk-42NYDEHH.js} +2 -2
  28. package/dist/{chunk-ZEHA4IC7.js → chunk-42SMPKGY.js} +2 -2
  29. package/dist/{chunk-RTG5DJWM.cjs → chunk-44C23SSC.cjs} +5 -5
  30. package/dist/{chunk-RTG5DJWM.cjs.map → chunk-44C23SSC.cjs.map} +1 -1
  31. package/dist/{chunk-SL62IZ3I.cjs → chunk-4KKGHPNE.cjs} +9 -9
  32. package/dist/{chunk-SL62IZ3I.cjs.map → chunk-4KKGHPNE.cjs.map} +1 -1
  33. package/dist/{chunk-X2CYUCGL.cjs → chunk-5BQWVNRS.cjs} +62 -62
  34. package/dist/{chunk-X2CYUCGL.cjs.map → chunk-5BQWVNRS.cjs.map} +1 -1
  35. package/dist/{chunk-HRUXC3YN.js → chunk-5QWYIPMH.js} +2 -2
  36. package/dist/{chunk-NT3BKPEC.js → chunk-5ZY5JM4Z.js} +10 -10
  37. package/dist/chunk-5ZY5JM4Z.js.map +1 -0
  38. package/dist/{chunk-4C764VBX.cjs → chunk-62TM2RVZ.cjs} +26 -26
  39. package/dist/{chunk-4C764VBX.cjs.map → chunk-62TM2RVZ.cjs.map} +1 -1
  40. package/dist/{chunk-YBTYHIXA.js → chunk-632XJ2ZT.js} +6 -5
  41. package/dist/chunk-632XJ2ZT.js.map +1 -0
  42. package/dist/{chunk-DGDUOFNY.js → chunk-BUBQEZ5J.js} +2 -2
  43. package/dist/{chunk-ZAAIVSX6.js → chunk-D3LUKR2Y.js} +11964 -9714
  44. package/dist/chunk-D3LUKR2Y.js.map +1 -0
  45. package/dist/{chunk-5KSXMJXF.cjs → chunk-EO35UHFT.cjs} +60 -60
  46. package/dist/chunk-EO35UHFT.cjs.map +1 -0
  47. package/dist/{chunk-5YKUEZIA.cjs → chunk-EORFD5WB.cjs} +15 -15
  48. package/dist/{chunk-5YKUEZIA.cjs.map → chunk-EORFD5WB.cjs.map} +1 -1
  49. package/dist/{chunk-MEIMDHQ2.cjs → chunk-F7XPMG25.cjs} +28 -27
  50. package/dist/chunk-F7XPMG25.cjs.map +1 -0
  51. package/dist/{chunk-I74ADMZS.cjs → chunk-H6GFQ4AO.cjs} +7 -7
  52. package/dist/{chunk-I74ADMZS.cjs.map → chunk-H6GFQ4AO.cjs.map} +1 -1
  53. package/dist/{chunk-EOYFMWDT.cjs → chunk-J3NHQ4JB.cjs} +31 -31
  54. package/dist/{chunk-EOYFMWDT.cjs.map → chunk-J3NHQ4JB.cjs.map} +1 -1
  55. package/dist/{chunk-23QJPSZJ.cjs → chunk-SS3D3DHL.cjs} +7049 -4799
  56. package/dist/chunk-SS3D3DHL.cjs.map +1 -0
  57. package/dist/{chunk-6XQGPFIR.js → chunk-WNXIG6YY.js} +2 -2
  58. package/dist/{chunk-5INZDVGI.js → chunk-WZCQW4MW.js} +4 -4
  59. package/dist/{chunk-B3MRHZNZ.js → chunk-ZHC2BCXK.js} +4 -4
  60. package/dist/components/case-studies/index.cjs +8 -8
  61. package/dist/components/case-studies/index.js +2 -2
  62. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  63. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  64. package/dist/components/chat/hooks/index.d.ts +0 -1
  65. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  66. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  67. package/dist/components/chat/hooks/use-chunk-catchup.d.ts.map +1 -1
  68. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +15 -48
  69. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  70. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +10 -57
  71. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  72. package/dist/components/chat/index.cjs +10 -2
  73. package/dist/components/chat/index.cjs.map +1 -1
  74. package/dist/components/chat/index.d.ts +1 -0
  75. package/dist/components/chat/index.d.ts.map +1 -1
  76. package/dist/components/chat/index.js +21 -13
  77. package/dist/components/chat/stream/chat-dialog-store.d.ts +184 -0
  78. package/dist/components/chat/stream/chat-dialog-store.d.ts.map +1 -0
  79. package/dist/components/chat/stream/chat-stream-reducer.d.ts +367 -0
  80. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -0
  81. package/dist/components/chat/stream/delta-batcher.d.ts +51 -0
  82. package/dist/components/chat/stream/delta-batcher.d.ts.map +1 -0
  83. package/dist/components/chat/stream/index.d.ts +17 -0
  84. package/dist/components/chat/stream/index.d.ts.map +1 -0
  85. package/dist/components/chat/stream/message-mutations.d.ts +77 -0
  86. package/dist/components/chat/stream/message-mutations.d.ts.map +1 -0
  87. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +22 -0
  88. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +1 -0
  89. package/dist/components/chat/types/api.types.d.ts +1 -81
  90. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  91. package/dist/components/chat/types/processing.types.d.ts +2 -93
  92. package/dist/components/chat/types/processing.types.d.ts.map +1 -1
  93. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +34 -6
  94. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
  95. package/dist/components/chat/utils/index.d.ts +2 -3
  96. package/dist/components/chat/utils/index.d.ts.map +1 -1
  97. package/dist/components/chat/utils/process-historical-messages.d.ts +59 -11
  98. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  99. package/dist/components/contact/index.cjs +3 -3
  100. package/dist/components/contact/index.js +2 -2
  101. package/dist/components/docs/index.cjs +5 -5
  102. package/dist/components/docs/index.js +4 -4
  103. package/dist/components/embeds/index.cjs +3 -3
  104. package/dist/components/embeds/index.js +2 -2
  105. package/dist/components/faq/index.cjs +3 -3
  106. package/dist/components/faq/index.js +2 -2
  107. package/dist/components/features/index.cjs +2 -2
  108. package/dist/components/features/index.js +1 -1
  109. package/dist/components/help-center-pages/index.cjs +20 -20
  110. package/dist/components/help-center-pages/index.js +11 -11
  111. package/dist/components/index.cjs +172 -130
  112. package/dist/components/index.cjs.map +1 -1
  113. package/dist/components/index.js +63 -21
  114. package/dist/components/index.js.map +1 -1
  115. package/dist/components/navigation/index.cjs +2 -2
  116. package/dist/components/navigation/index.js +1 -1
  117. package/dist/components/onboarding-guides/index.cjs +5 -5
  118. package/dist/components/onboarding-guides/index.js +4 -4
  119. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  120. package/dist/components/related-content/index.cjs +3 -3
  121. package/dist/components/related-content/index.js +2 -2
  122. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  123. package/dist/components/tickets/index.cjs +5 -5
  124. package/dist/components/tickets/index.js +4 -4
  125. package/dist/components/ui/index.cjs +44 -2
  126. package/dist/components/ui/index.cjs.map +1 -1
  127. package/dist/components/ui/index.d.ts +1 -2
  128. package/dist/components/ui/index.d.ts.map +1 -1
  129. package/dist/components/ui/index.js +55 -13
  130. package/dist/components/ui/markdown/base-components.d.ts +51 -0
  131. package/dist/components/ui/markdown/base-components.d.ts.map +1 -0
  132. package/dist/components/ui/markdown/engine.d.ts +99 -0
  133. package/dist/components/ui/markdown/engine.d.ts.map +1 -0
  134. package/dist/components/ui/markdown/heading-ids.d.ts +65 -0
  135. package/dist/components/ui/markdown/heading-ids.d.ts.map +1 -0
  136. package/dist/components/ui/markdown/index.d.ts +18 -0
  137. package/dist/components/ui/markdown/index.d.ts.map +1 -0
  138. package/dist/components/ui/markdown/mermaid-diagram.d.ts +79 -0
  139. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +1 -0
  140. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +14 -0
  141. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +1 -0
  142. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +40 -0
  143. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -0
  144. package/dist/components/ui/markdown/rich/shortcodes.d.ts +8 -0
  145. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +1 -0
  146. package/dist/components/ui/markdown/sanitize.d.ts +153 -0
  147. package/dist/components/ui/markdown/sanitize.d.ts.map +1 -0
  148. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +23 -0
  149. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +1 -0
  150. package/dist/components/ui/markdown/streaming.d.ts +78 -0
  151. package/dist/components/ui/markdown/streaming.d.ts.map +1 -0
  152. package/dist/components/ui/markdown/text-size.d.ts +34 -0
  153. package/dist/components/ui/markdown/text-size.d.ts.map +1 -0
  154. package/dist/index.cjs +60 -2
  155. package/dist/index.cjs.map +1 -1
  156. package/dist/index.js +71 -13
  157. package/dist/utils/index.cjs +169 -40
  158. package/dist/utils/index.cjs.map +1 -1
  159. package/dist/utils/index.d.ts +1 -0
  160. package/dist/utils/index.d.ts.map +1 -1
  161. package/dist/utils/index.js +162 -41
  162. package/dist/utils/index.js.map +1 -1
  163. package/dist/utils/markdown-fences.d.ts +42 -0
  164. package/dist/utils/markdown-fences.d.ts.map +1 -0
  165. package/dist/utils/markdown-heading-id.d.ts +85 -0
  166. package/dist/utils/markdown-heading-id.d.ts.map +1 -0
  167. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  168. package/package.json +7 -1
  169. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +317 -0
  170. package/src/chat-protocol/__tests__/chat-protocol.test.ts +516 -0
  171. package/src/chat-protocol/__tests__/env-flag.test.ts +52 -0
  172. package/src/chat-protocol/__tests__/ip-normalize.test.ts +136 -0
  173. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +232 -0
  174. package/src/chat-protocol/decode.ts +278 -0
  175. package/src/chat-protocol/encode.ts +71 -0
  176. package/src/chat-protocol/env-flag.ts +39 -0
  177. package/src/chat-protocol/events.ts +245 -0
  178. package/src/chat-protocol/frames.ts +245 -0
  179. package/src/chat-protocol/index.ts +21 -0
  180. package/src/chat-protocol/ip-normalize.ts +146 -0
  181. package/src/chat-protocol/nats-decoder.ts +258 -0
  182. package/src/components/chat/__tests__/chat-message-list.test.tsx +381 -6
  183. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +207 -0
  184. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +250 -0
  185. package/src/components/chat/chat-message-enhanced.tsx +122 -20
  186. package/src/components/chat/chat-message-list.tsx +409 -132
  187. package/src/components/chat/embeddable-chat.tsx +6 -0
  188. package/src/components/chat/hooks/.index.md +30 -33
  189. package/src/components/chat/hooks/.use-nats-chat-adapter.md +36 -55
  190. package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +37 -0
  191. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  192. package/src/components/chat/hooks/__tests__/chunk-catchup-dialog-staleness.test.ts +92 -0
  193. package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +438 -0
  194. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +318 -0
  195. package/src/components/chat/hooks/index.ts +0 -1
  196. package/src/components/chat/hooks/use-chat.ts +8 -0
  197. package/src/components/chat/hooks/use-chunk-catchup.ts +26 -1
  198. package/src/components/chat/hooks/use-nats-chat-adapter.ts +254 -825
  199. package/src/components/chat/hooks/use-sse-chat-adapter.ts +380 -684
  200. package/src/components/chat/index.ts +5 -0
  201. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +940 -0
  202. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +806 -0
  203. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +467 -0
  204. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +1248 -0
  205. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +255 -0
  206. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +105 -0
  207. package/src/components/chat/stream/chat-dialog-store.ts +536 -0
  208. package/src/components/chat/stream/chat-stream-reducer.ts +1876 -0
  209. package/src/components/chat/stream/delta-batcher.ts +168 -0
  210. package/src/components/chat/stream/index.ts +55 -0
  211. package/src/components/chat/stream/message-mutations.ts +340 -0
  212. package/src/components/chat/stream/use-chat-stream-reducer.ts +126 -0
  213. package/src/components/chat/thinking-display.tsx +1 -1
  214. package/src/components/chat/types/.api.types.md +39 -49
  215. package/src/components/chat/types/.processing.types.md +29 -58
  216. package/src/components/chat/types/api.types.ts +6 -73
  217. package/src/components/chat/types/processing.types.ts +11 -53
  218. package/src/components/chat/utils/.index.md +31 -40
  219. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +420 -0
  220. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +605 -0
  221. package/src/components/chat/utils/__tests__/process-historical-messages-approvals.test.ts +61 -0
  222. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +394 -0
  223. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +270 -0
  224. package/src/components/chat/utils/extract-incomplete-message-state.ts +63 -5
  225. package/src/components/chat/utils/index.ts +5 -8
  226. package/src/components/chat/utils/process-historical-messages.ts +358 -386
  227. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +22 -4
  228. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  229. package/src/components/shared/product-release/release-detail-page.tsx +19 -4
  230. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +2420 -0
  231. package/src/components/ui/__tests__/markdown-parity.test.tsx +2540 -0
  232. package/src/components/ui/index.ts +1 -2
  233. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +176 -0
  234. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +151 -0
  235. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +354 -0
  236. package/src/components/ui/markdown/__tests__/sanitize-render.test.tsx +118 -0
  237. package/src/components/ui/markdown/__tests__/streaming.test.tsx +436 -0
  238. package/src/components/ui/markdown/base-components.tsx +360 -0
  239. package/src/components/ui/markdown/engine.tsx +315 -0
  240. package/src/components/ui/markdown/heading-ids.ts +239 -0
  241. package/src/components/ui/markdown/index.ts +49 -0
  242. package/src/components/ui/markdown/mermaid-diagram.tsx +323 -0
  243. package/src/components/ui/markdown/rich/embed-overrides.tsx +199 -0
  244. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +184 -0
  245. package/src/components/ui/markdown/rich/shortcodes.ts +170 -0
  246. package/src/components/ui/markdown/sanitize.ts +3584 -0
  247. package/src/components/ui/markdown/simple-markdown-renderer.tsx +28 -0
  248. package/src/components/ui/markdown/streaming.ts +390 -0
  249. package/src/components/ui/markdown/text-size.ts +106 -0
  250. package/src/components/ui/release-changelog-section.tsx +1 -1
  251. package/src/components/ui/ticket-info-section.tsx +1 -1
  252. package/src/utils/index.ts +1 -0
  253. package/src/utils/markdown-fences.ts +127 -0
  254. package/src/utils/markdown-heading-id.ts +348 -0
  255. package/src/utils/markdown-section-extractor.ts +41 -56
  256. package/dist/chunk-23QJPSZJ.cjs.map +0 -1
  257. package/dist/chunk-5KSXMJXF.cjs.map +0 -1
  258. package/dist/chunk-MEIMDHQ2.cjs.map +0 -1
  259. package/dist/chunk-NT3BKPEC.js.map +0 -1
  260. package/dist/chunk-YBTYHIXA.js.map +0 -1
  261. package/dist/chunk-ZAAIVSX6.js.map +0 -1
  262. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +0 -6
  263. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +0 -1
  264. package/dist/components/chat/utils/chunk-parser.d.ts +0 -25
  265. package/dist/components/chat/utils/chunk-parser.d.ts.map +0 -1
  266. package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
  267. package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
  268. package/dist/components/ui/simple-markdown-renderer.d.ts +0 -73
  269. package/dist/components/ui/simple-markdown-renderer.d.ts.map +0 -1
  270. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +0 -77
  271. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +0 -489
  272. package/src/components/chat/utils/.chunk-parser.md +0 -62
  273. package/src/components/chat/utils/chunk-parser.ts +0 -262
  274. package/src/components/ui/.simple-markdown-renderer.md +0 -52
  275. package/src/components/ui/rich-markdown-renderer.tsx +0 -1223
  276. package/src/components/ui/simple-markdown-renderer.tsx +0 -964
  277. /package/dist/{chunk-ZPUCCSYA.js.map → chunk-34C2JV2C.js.map} +0 -0
  278. /package/dist/{chunk-GWVNRXJU.js.map → chunk-3VGRZ62V.js.map} +0 -0
  279. /package/dist/{chunk-AAHAVML2.js.map → chunk-42NYDEHH.js.map} +0 -0
  280. /package/dist/{chunk-ZEHA4IC7.js.map → chunk-42SMPKGY.js.map} +0 -0
  281. /package/dist/{chunk-HRUXC3YN.js.map → chunk-5QWYIPMH.js.map} +0 -0
  282. /package/dist/{chunk-DGDUOFNY.js.map → chunk-BUBQEZ5J.js.map} +0 -0
  283. /package/dist/{chunk-6XQGPFIR.js.map → chunk-WNXIG6YY.js.map} +0 -0
  284. /package/dist/{chunk-5INZDVGI.js.map → chunk-WZCQW4MW.js.map} +0 -0
  285. /package/dist/{chunk-B3MRHZNZ.js.map → chunk-ZHC2BCXK.js.map} +0 -0
@@ -1,49 +1,46 @@
1
- <!-- source-hash: 31ada6e53cd71ce93d35361e48559a56 -->
2
- Barrel export file (`'use client'`) that re-exports all React hooks from the chat hooks module, providing a single import surface for consumers.
1
+ <!-- source-hash: d1cebe46eff04115f214c16b75a69467 -->
2
+ Barrel export file for the chat hooks module, re-exporting all public hooks from their individual files into a single `'use client'` entry point.
3
3
 
4
4
  ## Key Components
5
5
 
6
- ### Streaming & Real-time Hooks
7
- - **`useChunkCatchup`** — Replays missed chunks after reconnection
8
- - **`useScriptedStream`** Drives scripted/mock streaming sequences
9
- - **`useRealtimeChunkProcessor`** Processes incoming real-time message chunks
10
- - **`useJetstreamDialogSubscription`** / **`useNatsDialogSubscription`** NATS/JetStream transport subscriptions
11
- - **`useCollapsible`** Collapsible UI state management
12
-
13
- ### Chat Core Hooks
14
- - **`useChat`** / **`useSSE`** — Core chat and Server-Sent Events hooks (ported from hub, without `MockChatService`/`useChatConfig`)
15
- - **`useSlashCommands`** — Slash command parsing and dispatch
16
- - **`useEmptyStateConfig`** — Empty state configuration
17
- - **`useChatAttachments`** / **`useChatAttachmentImageGallery`** — File attachment handling and image gallery
18
- - **`useChatIdentity`** — Chat user/agent identity resolution
19
- - **`useChatCardItem`** — Chat card rendering state
20
- - **`useCloseOnNavigation`** — Dismisses dialogs/panels on route change
21
-
22
- ### Unified Chat Surface
23
- - **`useUnifiedChat`** — Primary public hook; selects transport by `activeMode`
24
- - **`useSSEChatAdapter`** / **`useNatsChatAdapter`** — Transport adapters (SSE and NATS)
25
- - **`useEmbeddedChat`** — Legacy SSE alias for embedded surfaces
26
-
27
- ### Utilities
28
- - **`useProxiedImageUrl`** — Resolves proxied image URLs from `ChatRuntime.endpoints`
6
+ | Export Group | Hooks |
7
+ |---|---|
8
+ | **Realtime / Streaming** | `useChunkCatchup`, `useJetstreamDialogSubscription`, `useNatsDialogSubscription` |
9
+ | **UI Utilities** | `useCollapsible`, `useCloseOnNavigation`, `useChatCardItem` |
10
+ | **Chat Core** | `useChat`, `useSSE`, `useChatIdentity`, `useChatAttachments`, `useChatAttachmentImageGallery`, `useSlashCommands` |
11
+ | **Transport Adapters** | `useSSEChatAdapter`, `useNatsChatAdapter` |
12
+ | **Unified Surface** | `useUnifiedChat` (primary), `useEmbeddedChat` (legacy SSE alias) |
13
+ | **Image Proxy** | `useProxiedImageUrl` |
29
14
 
30
15
  ## Usage Example
31
16
 
32
17
  ```typescript
33
- // Preferred: import everything from the barrel
18
+ // Typical consumer — import directly from the module index
34
19
  import {
35
20
  useUnifiedChat,
36
21
  useChatAttachments,
37
- useProxiedImageUrl,
38
- } from '@openframe/chat-hooks'
22
+ useSlashCommands,
23
+ } from '@flamingo/chat-hooks'
39
24
 
40
25
  function ChatPanel({ modes, activeMode }) {
41
- const { messages, send } = useUnifiedChat({ modes, activeMode })
42
- const { attachments, addAttachment } = useChatAttachments()
43
- const proxied = useProxiedImageUrl(rawImageUrl)
26
+ const chat = useUnifiedChat({ modes, activeMode })
27
+ const attachments = useChatAttachments()
28
+ const slashCommands = useSlashCommands()
44
29
 
45
- return <ChatUI messages={messages} onSend={send} />
30
+ // ...
31
+ }
32
+
33
+ // Advanced: direct transport access
34
+ import { useNatsChatAdapter } from '@flamingo/chat-hooks'
35
+
36
+ function CustomTransportPanel() {
37
+ const nats = useNatsChatAdapter({ /* config */ })
38
+ // ...
46
39
  }
47
40
  ```
48
41
 
49
- > **Note:** For standard usage, prefer `useUnifiedChat`. The adapter hooks (`useSSEChatAdapter`, `useNatsChatAdapter`) are exposed for advanced cases requiring direct transport access.
42
+ ## Notes
43
+
44
+ - Marked `'use client'` — safe for React Server Component trees; hooks run only on the client.
45
+ - `useUnifiedChat` is the recommended entry point for new consumers; `useEmbeddedChat` is the legacy SSE alias kept for backward compatibility.
46
+ - `useProxiedImageUrl` reads proxy config from `ChatRuntime.endpoints`, keeping image-proxy resolution consistent between hub and embedder environments.
@@ -1,71 +1,52 @@
1
- <!-- source-hash: 3fbde71f6e5fc7f9b4576423ebdb08e2 -->
2
- Thin wrapper that wires together NATS subscriptions, real-time chunk processing, and dialog management into a single `UnifiedChatState` object for the Mingo/NATS transport mode of the unified chat surface.
1
+ <!-- source-hash: 6c5780e92306ea381bac35aaf97c435f -->
2
+ Provides the NATS/Mingo-mode transport adapter for the unified chat surface, implementing the `UnifiedChatState` contract so the `useChat({ mode })` dispatcher can switch between NATS and SSE adapters without shell-side branching.
3
3
 
4
4
  ## Key Components
5
5
 
6
6
  ### `UseNatsChatAdapterConfig`
7
- Primary configuration interface with two operational modes:
8
- - **Bare-transport mode** — caller supplies `dialogId` explicitly and owns dialog lifecycle (original v0 API, used by Tauri Fae Chat)
9
- - **Managed-dialog mode** — caller supplies `fetchDialogs` and related callbacks; the adapter owns dialog state, pagination, and history
7
+ Consumer-supplied configuration interface covering:
8
+ - `dialogId` active conversation identifier
9
+ - `getNatsWsUrl` factory returning the NATS WebSocket URL
10
+ - `publishUserMessage` — consumer-owned send callback (HTTP POST or NATS publish)
11
+ - `fetchChunks` — optional historical chunk fetcher for catchup
12
+ - `clientConfig` — optional NATS auth credentials
13
+ - `enableThinking` / `batchApprovalsEnabled` — processor feature flags
10
14
 
11
- ### Core Config Fields
15
+ ### `UseNatsChatAdapterOptions`
16
+ - `active` — gates the live subscription; keeps message state alive while the mode is hidden
12
17
 
13
- | Field | Required | Description |
14
- |-------|----------|-------------|
15
- | `getNatsWsUrl` | ✅ | Returns the NATS WebSocket URL or `null` to suspend |
16
- | `publishUserMessage` | ✅ | Consumer-owned send callback (HTTP POST or NATS publish) |
17
- | `dialogId` | ❌ | Explicit dialog ID (bare-transport mode) |
18
- | `fetchDialogs` | ❌ | Enables managed-dialog mode with sidebar support |
19
- | `fetchDialogMessages` | ❌ | Populates history on dialog switch |
20
- | `topics` | ❌ | NATS subject suffixes to tail (default: `['message']`) |
21
-
22
- ### Supporting Interfaces
23
-
24
- - **`FetchDialogsParams`** / **`FetchDialogsResult`** — paginated dialog list with cursor-based pagination
25
- - **`FetchDialogMessagesParams`** / **`FetchDialogMessagesResult`** — paginated message history with optional `tokenUsage`
26
-
27
- ### Composition Stack
18
+ ### `useNatsChatAdapter(config, options)`
19
+ Main hook. Composes three internal hooks:
28
20
 
29
21
  ```text
30
- useNatsDialogSubscription → live NATS event tail
31
-
32
- useRealtimeChunkProcessor chunk → MessageSegment[]
33
-
34
- useChunkCatchup → back-fills missed chunks on reconnect
35
-
36
- config.publishUserMessage → consumer-owned send (HTTP/NATS)
22
+ useNatsDialogSubscription → live NATS event tail
23
+
24
+ decodeNatsChunk + reducer chunk → ChatStreamEvent → state
25
+
26
+ useChunkCatchup → back-fills missed chunks on reconnect/activation
37
27
  ```
38
28
 
29
+ Returns a full `UnifiedChatState` object including `messages`, `isLoading`, `streamingPhase`, `sendMessage`, `stopMessage`, and `clearMessages`.
30
+
39
31
  ## Usage Example
40
32
 
41
33
  ```typescript
42
- // Bare-transport mode (v0 — Tauri Fae Chat)
43
- const chatState = useNatsChatAdapter({
44
- dialogId: activeDialogId,
45
- getNatsWsUrl: () => `wss://nats.example.com`,
46
- publishUserMessage: async (text, { dialogId }) => {
47
- await fetch(`/api/chat/${dialogId}/message`, {
48
- method: 'POST',
49
- body: JSON.stringify({ text }),
50
- })
34
+ const chatState = useNatsChatAdapter(
35
+ {
36
+ dialogId: 'dialog-abc123',
37
+ getNatsWsUrl: () => `wss://nats.example.com`,
38
+ publishUserMessage: async (text, { dialogId }) => {
39
+ await fetch('/api/chat', {
40
+ method: 'POST',
41
+ body: JSON.stringify({ text, dialogId }),
42
+ })
43
+ },
44
+ fetchChunks: ({ dialogId, after }) =>
45
+ fetch(`/api/chunks?dialogId=${dialogId}&after=${after}`).then(r => r.json()),
46
+ batchApprovalsEnabled: true,
51
47
  },
52
- topics: ['admin-message'],
53
- })
54
-
55
- // Managed-dialog mode (openframe-frontend / EmbeddableChat)
56
- const chatState = useNatsChatAdapter({
57
- getNatsWsUrl: () => natsUrl,
58
- publishUserMessage: sendMessage,
59
- fetchDialogs: async ({ cursor, limit }) => api.listDialogs({ cursor, limit }),
60
- fetchDialogMessages: async ({ dialogId, cursor }) =>
61
- api.getMessages(dialogId, { cursor }),
62
- createDialog: () => api.createDialog(),
63
- deleteDialog: (id) => api.deleteDialog(id),
64
- approveRequest: (requestId) => api.approve(requestId),
65
- rejectRequest: (requestId, reason) => api.reject(requestId, reason),
66
- })
48
+ { active: isNatsModeVisible },
49
+ )
67
50
  ```
68
51
 
69
- > **Note:** Set `topics: ['admin-message']` for Mingo/admin deployments. The default `'message'` topic is for Fae client-chat. Mismatched topics cause the assistant to hang in the `thinking` phase indefinitely.
70
-
71
- **Source:** [`use-nats-chat-adapter.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/use-nats-chat-adapter.ts)
52
+ > **Note:** `publishUserMessage` is intentionally consumer-owned the adapter only handles optimistic UI updates and phase transitions; the actual transport is wired externally.
@@ -0,0 +1,37 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`server-history hydration (materializes through the reducer) > rebuilds messages + sendIdx-keyed refs + send counter from the transcript 1`] = `
4
+ [
5
+ {
6
+ "content": "open a ticket for the broken printer",
7
+ "id": "hydrated-1",
8
+ "role": "user",
9
+ },
10
+ {
11
+ "chatRefs": {
12
+ "ticket:77": {
13
+ "id": "77",
14
+ "metadata": {
15
+ "status": "OPEN",
16
+ },
17
+ "title": "Broken printer",
18
+ "type": "ticket",
19
+ "url": null,
20
+ },
21
+ },
22
+ "content": "✅ Approved — ticket created: [card://ticket:77]",
23
+ "id": "hydrated-2",
24
+ "role": "assistant",
25
+ },
26
+ {
27
+ "content": "what is the pricing?",
28
+ "id": "hydrated-3",
29
+ "role": "user",
30
+ },
31
+ {
32
+ "content": "Pricing starts at $99/month per site.",
33
+ "id": "hydrated-4",
34
+ "role": "assistant",
35
+ },
36
+ ]
37
+ `;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * A catch-up fetch is async and the active dialog can change while it is in
3
+ * flight — switching dialogs is the ordinary interaction, not an edge case.
4
+ *
5
+ * `useChunkCatchup` already knows about staleness, but only in its `finally`:
6
+ * the processing loop ran FIRST and unconditionally. Everything downstream of
7
+ * it is bound to the CURRENT dialog — `onChunkReceived` is read through a ref
8
+ * the adapter reassigns every render, and the seq bookkeeping refs were just
9
+ * re-armed by `resetChunkTracking` for the newly-entered dialog — so a fetch
10
+ * that resolved late wrote dialog A's transcript into dialog B, and pushed B's
11
+ * seq cursor to A's JetStream sequence. Since the reducer drops anything at or
12
+ * below `lastAppliedSeq`, and A's stream position is unrelated to B's, that can
13
+ * silently discard B's own live chunks for the rest of the session.
14
+ *
15
+ * The same applies to the flags: finalizing `hasCompletedInitialCatchup` /
16
+ * `bufferUntilInitialCatchupComplete` on a stale fetch ends the NEW dialog's
17
+ * buffering window early, and draining `chunkBuffer` hands B's buffered live
18
+ * deliveries to A's stale batch.
19
+ */
20
+ import { describe, it, expect, vi } from 'vitest'
21
+ import { renderHook, act } from '@testing-library/react'
22
+ import { useChunkCatchup } from '../use-chunk-catchup'
23
+ import type { ChunkData } from '../../types'
24
+
25
+ type Deferred = {
26
+ promise: Promise<ChunkData[]>
27
+ resolve: (chunks: ChunkData[]) => void
28
+ }
29
+
30
+ function deferred(): Deferred {
31
+ let resolve!: (chunks: ChunkData[]) => void
32
+ const promise = new Promise<ChunkData[]>((r) => {
33
+ resolve = r
34
+ })
35
+ return { promise, resolve }
36
+ }
37
+
38
+ const textChunk = (text: string, streamSeq: number, sequenceId: number): ChunkData =>
39
+ ({ type: 'TEXT', text, streamSeq, sequenceId }) as unknown as ChunkData
40
+
41
+ describe('useChunkCatchup — dialog staleness', () => {
42
+ it('does not deliver a catchup that resolved after the dialog changed', async () => {
43
+ const onChunkReceived = vi.fn()
44
+ const pending = deferred()
45
+ const fetchChunks = vi.fn((dialogId: string) =>
46
+ dialogId === 'A' ? pending.promise : Promise.resolve([]),
47
+ )
48
+
49
+ const { result, rerender } = renderHook(
50
+ ({ dialogId }: { dialogId: string }) =>
51
+ useChunkCatchup({ dialogId, onChunkReceived, fetchChunks }),
52
+ { initialProps: { dialogId: 'A' } },
53
+ )
54
+
55
+ // Dialog A starts its catch-up…
56
+ let catchup!: Promise<unknown>
57
+ await act(async () => {
58
+ catchup = result.current.catchUpChunks()
59
+ })
60
+ expect(fetchChunks).toHaveBeenCalledWith('A', expect.anything(), undefined)
61
+
62
+ // …the user switches to B while A's fetch is still open…
63
+ rerender({ dialogId: 'B' })
64
+
65
+ // …and only then does A's fetch land, carrying A's own transcript.
66
+ await act(async () => {
67
+ pending.resolve([textChunk('SECRET FROM DIALOG A', 100001, 100001)])
68
+ await catchup
69
+ })
70
+
71
+ expect(onChunkReceived).not.toHaveBeenCalled()
72
+ })
73
+
74
+ it('still delivers a catchup for the dialog that is current when it lands', () => {
75
+ const onChunkReceived = vi.fn()
76
+ const fetchChunks = vi.fn(() =>
77
+ Promise.resolve([textChunk('B REAL CONTENT', 50001, 50001)]),
78
+ )
79
+
80
+ const { result } = renderHook(() =>
81
+ useChunkCatchup({ dialogId: 'B', onChunkReceived, fetchChunks }),
82
+ )
83
+
84
+ return act(async () => {
85
+ await result.current.catchUpChunks()
86
+ }).then(() => {
87
+ // Positive control: the guard must not swallow the normal path.
88
+ expect(onChunkReceived).toHaveBeenCalledTimes(1)
89
+ expect(onChunkReceived.mock.calls[0][0]).toMatchObject({ text: 'B REAL CONTENT' })
90
+ })
91
+ })
92
+ })