@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
@@ -0,0 +1,184 @@
1
+ /**
2
+ * createChatDialogStore — framework-free registry of `ChatStreamReducer`
3
+ * instances keyed by `(dialogId, side)`. Reducer state PERSISTS across
4
+ * component unmounts (the store outlives React), and the store is the
5
+ * `useSyncExternalStore` source for the `useChatStreamReducer` wrapper.
6
+ *
7
+ * CROSS-SIDE PROJECTION: exactly two operations fan out across sides of the
8
+ * same dialogId —
9
+ * 1. approval RESOLUTION by requestId (`approval-resolved` events), and
10
+ * 2. tool-execution MERGE by execId (`tool-execution` events)
11
+ * — implemented as idempotent pure projections over the other side's state
12
+ * (recomputed from state, never re-injected into the other side's seq
13
+ * stream; per-side seq gates stay untouched). Everything else — text,
14
+ * thinking, participant rows — is strictly per-side.
15
+ *
16
+ * LIFECYCLE / MEMORY: the reducer map is LRU-capped (`maxReducers`, default
17
+ * `DEFAULT_MAX_REDUCERS`) and evicted through the same path as `remove()`.
18
+ * Without a cap an agent cycling hundreds of dialogs would retain a reducer
19
+ * (thread + accumulator) per dialog for the process's lifetime; under SSR,
20
+ * where the store is module-scoped, that growth is shared across every
21
+ * request. `getSnapshot` is PURE — it never creates an entry — and
22
+ * `getServerSnapshot` always returns the shared frozen `EMPTY_STATE`.
23
+ *
24
+ * EVICTION SAFETY (LRU recency alone is NOT liveness):
25
+ * 1. RETAINED keys are never evicted. `retain(dialogId, side)` returns a
26
+ * release fn; the `useChatStreamReducer` hook calls it for as long as it
27
+ * is mounted, so a quiet-but-visible panel can't be dropped just because
28
+ * ten other keys were touched. NON-React hosts must call it too.
29
+ * Because the hook retains in an EFFECT but takes its reducer during
30
+ * RENDER, a key created by a public `getReducer` is protected from
31
+ * creation until its FIRST `retain()` (bounded by
32
+ * `MAX_PENDING_RETAIN_KEYS`) — see `pendingRetain`.
33
+ * 2. A reducer whose `streamingPhase !== 'idle'` is never evicted — dropping
34
+ * mid-turn would recreate an EMPTY reducer on the next `getReducer`
35
+ * while the host's seq cursor still says "caught up", i.e. the thread
36
+ * visually vanishes with no path back.
37
+ * 3. Eviction hands the host the dropped instance's PARKED state
38
+ * (`onEvict(..., { messages, approvalStatuses, lastAppliedSeq,
39
+ * pendingEchoes })`). A recreated reducer is pristine, so re-seeding
40
+ * messages alone would
41
+ * resurrect resolved approvals as actionable and reset the seq gate to
42
+ * `-Infinity`; the parked payload is what makes the round-trip lossless.
43
+ * 4. Eviction NEVER notifies synchronously. `getReducer` is called during
44
+ * render (by the hook), and notifying there means updating other
45
+ * components mid-render. The notify is deferred to a microtask.
46
+ */
47
+ import { type ChatReducerState, type ChatStreamReducer, type ChatStreamReducerOptions, type PendingEcho } from './chat-stream-reducer';
48
+ import type { ChatStreamEvent } from '../../../chat-protocol/events';
49
+ export type ChatDialogSide = string;
50
+ /** Factory for a key's reducer options, consulted ONCE at creation. A plain
51
+ * `() => options` thunk remains assignable. */
52
+ export type CreateReducerOptionsFn = (dialogId: string, side: ChatDialogSide) => ChatStreamReducerOptions;
53
+ export interface ChatDialogStore {
54
+ /** Create-or-get the reducer for `(dialogId, side)`. `createOptions` is
55
+ * consulted ONLY when the instance is first created. */
56
+ getReducer(dialogId: string, side?: ChatDialogSide, createOptions?: CreateReducerOptionsFn): ChatStreamReducer;
57
+ /** Apply one event to a side, then fan out the cross-side projections to
58
+ * the other sides of the same dialog. */
59
+ apply(dialogId: string, side: ChatDialogSide, event: ChatStreamEvent): void;
60
+ /** Run adapter commands against a reducer; subscribers are notified. */
61
+ mutate<T>(dialogId: string, side: ChatDialogSide, fn: (reducer: ChatStreamReducer) => T): T;
62
+ subscribe(listener: () => void): () => void;
63
+ /**
64
+ * Referentially-stable snapshot for `useSyncExternalStore`. PURE — an
65
+ * unknown key returns the shared frozen `EMPTY_STATE` rather than
66
+ * creating a reducer (a create-on-read would let SSR renders accumulate
67
+ * reducers in a process-global map, and would make React's snapshot read
68
+ * a mutation).
69
+ */
70
+ getSnapshot(dialogId: string, side?: ChatDialogSide): ChatReducerState;
71
+ /** `useSyncExternalStore`'s server getter — always `EMPTY_STATE`. There is
72
+ * no per-request store on the server, so a live thread cannot be rendered
73
+ * server-side; the client hydrates from the real reducer. */
74
+ getServerSnapshot(): ChatReducerState;
75
+ /** Drop a side's reducer (or every side of the dialog when omitted). */
76
+ remove(dialogId: string, side?: ChatDialogSide): void;
77
+ /**
78
+ * PIN `(dialogId, side)` against LRU eviction while a consumer is live.
79
+ * Returns the release fn (idempotent; refcounted, so nested retains are
80
+ * safe). Creation is NOT implied — retaining an absent key simply means the
81
+ * key is protected once it exists.
82
+ */
83
+ retain(dialogId: string, side?: ChatDialogSide): () => void;
84
+ /**
85
+ * POLICY retain: keep exactly `keys` pinned by this store-level set and
86
+ * release every key the set previously pinned. Independent of the refcounted
87
+ * `retain()` handles a host's components hold — the two compose.
88
+ *
89
+ * Exists because "retain this set, release the rest" is generic store
90
+ * policy that every multi-panel host otherwise re-derives (diffing its own
91
+ * key list against a map of release fns). Retains BEFORE releasing, so a key
92
+ * present in both the old and the new set never momentarily drops to zero
93
+ * retains and becomes evictable mid-swap.
94
+ */
95
+ setRetained(keys: Array<{
96
+ dialogId: string;
97
+ side?: ChatDialogSide;
98
+ }>): void;
99
+ }
100
+ export declare const DEFAULT_DIALOG_SIDE: ChatDialogSide;
101
+ /** Most-recently-used reducer keys retained before eviction. Ten covers
102
+ * every realistic multi-panel / dialog-switching session while bounding an
103
+ * agent that cycles hundreds of dialogs. */
104
+ export declare const DEFAULT_MAX_REDUCERS = 10;
105
+ /**
106
+ * Hard cap on keys held in the "created by `getReducer`, `retain()` still
107
+ * pending" protection set — the ONLY thing bounding the map while retains are
108
+ * outstanding, since that protection ends at the retain rather than on a timer.
109
+ *
110
+ * Deliberately far above `maxReducers`: a host may legitimately mount MORE
111
+ * panels than the LRU cap (once their effects run, retained keys already let
112
+ * the map exceed it), so capping the pending set at `maxReducers` would blank
113
+ * exactly the panels round 10 fixed. It is a backstop against a caller that
114
+ * reads a reducer once and drops it — or a concurrent render React discards
115
+ * before any effect runs — not a per-commit budget. Past it, the oldest pending
116
+ * key falls through to ordinary LRU.
117
+ */
118
+ export declare const MAX_PENDING_RETAIN_KEYS = 256;
119
+ export interface CreateChatDialogStoreOptions {
120
+ /** LRU cap on retained reducers (keys are `(dialogId, side)` pairs).
121
+ * Values < 1 are clamped to 1. Default `DEFAULT_MAX_REDUCERS`. */
122
+ maxReducers?: number;
123
+ /**
124
+ * Options applied to any reducer this store creates WITHOUT an explicit
125
+ * per-call `createOptions` — i.e. every reducer first materialized by
126
+ * `apply()` or `mutate()`. Hosts with non-default reducer semantics
127
+ * (`ownEchoIncludesAdmin`, `selfUserId`, approve/reject `callbacks`, …)
128
+ * MUST set this: creation options are consulted once, so a bare
129
+ * apply-created instance would keep those semantics missing for its whole
130
+ * lifetime, including for a later `getReducer(..., options)` caller.
131
+ */
132
+ defaultCreateOptions?: CreateReducerOptionsFn;
133
+ /**
134
+ * Called when LRU eviction actually DROPS a key. The store knows this
135
+ * exactly; without publishing it, hosts are left inferring eviction by
136
+ * comparing reducer OBJECT IDENTITY across `getReducer` calls and then
137
+ * suppressing the "pristine empty" snapshot that a silently-recreated
138
+ * reducer returns — archaeology about a fact this callback states outright.
139
+ *
140
+ * Fires only for LRU eviction. Host-initiated `remove()` needs no
141
+ * notification: the caller already knows which key it dropped.
142
+ *
143
+ * Called AFTER the key is gone, from `getReducer` (i.e. potentially during a
144
+ * React render) — treat it as a "schedule a refetch/rehydrate" signal, not a
145
+ * place to set state synchronously.
146
+ *
147
+ * `parked` carries the dropped reducer's non-refetchable state so the host
148
+ * can restore it on the recreated instance (`initializeWithState(messages,
149
+ * { approvalStatuses, lastAppliedSeq, pendingEchoes })`). Refetching
150
+ * messages alone is NOT
151
+ * equivalent: a recreated reducer starts with `approvalStatuses = {}` and
152
+ * `lastAppliedSeq = -Infinity`, so a resolved approval whose APPROVAL_RESULT
153
+ * row is not in the refetched history page re-renders as ACTIONABLE (the
154
+ * exact hazard `resetForDialogSwitch` preserves that map to avoid), and a
155
+ * replay from the host's own cursor re-applies events the dropped instance
156
+ * had already consumed.
157
+ */
158
+ onEvict?: (dialogId: string, side: ChatDialogSide, parked: EvictedReducerState) => void;
159
+ }
160
+ /**
161
+ * Snapshot of an LRU-evicted reducer's state, captured just before the
162
+ * instance is dropped. Everything here either cannot be refetched
163
+ * (`lastAppliedSeq`) or is not reliably present in a refetched history page
164
+ * (`approvalStatuses`); `messages` rides along so a host that keeps its own
165
+ * copy does not have to.
166
+ */
167
+ export interface EvictedReducerState {
168
+ messages: ChatReducerState['messages'];
169
+ approvalStatuses: ChatReducerState['approvalStatuses'];
170
+ /** `-Infinity` when the instance never applied a seq-carrying event. */
171
+ lastAppliedSeq: number;
172
+ /**
173
+ * Optimistic-echo entries still armed at eviction time. A key dropped
174
+ * between `pushOptimisticSend` and its `MESSAGE_REQUEST` echo would
175
+ * otherwise leave the recreated reducer with nothing armed, and the echo
176
+ * renders a DUPLICATE user bubble. Replay via
177
+ * `initializeWithState(messages, { pendingEchoes })`; the reducer drops
178
+ * entries already past `OWN_ECHO_AUTHOR_TTL_MS`. Empty for a key with no
179
+ * send in flight (the common case).
180
+ */
181
+ pendingEchoes: readonly PendingEcho[];
182
+ }
183
+ export declare function createChatDialogStore(options?: CreateChatDialogStoreOptions): ChatDialogStore;
184
+ //# sourceMappingURL=chat-dialog-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-dialog-store.d.ts","sourceRoot":"","sources":["../../../../src/components/chat/stream/chat-dialog-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAEpE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAA;AAEnC;gDACgD;AAChD,MAAM,MAAM,sBAAsB,GAAG,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,KACjB,wBAAwB,CAAA;AAE7B,MAAM,WAAW,eAAe;IAC9B;6DACyD;IACzD,UAAU,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,cAAc,EACrB,aAAa,CAAC,EAAE,sBAAsB,GACrC,iBAAiB,CAAA;IACpB;8CAC0C;IAC1C,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAAA;IAC3E,wEAAwE;IACxE,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,CAAC,GAAG,CAAC,CAAA;IAC3F,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;IAC3C;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,gBAAgB,CAAA;IACtE;;kEAE8D;IAC9D,iBAAiB,IAAI,gBAAgB,CAAA;IACrC,wEAAwE;IACxE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IACrD;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,MAAM,IAAI,CAAA;IAC3D;;;;;;;;;;OAUG;IACH,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,cAAc,CAAA;KAAE,CAAC,GAAG,IAAI,CAAA;CAC5E;AAED,eAAO,MAAM,mBAAmB,EAAE,cAAuB,CAAA;AAEzD;;6CAE6C;AAC7C,eAAO,MAAM,oBAAoB,KAAK,CAAA;AAEtC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAA;AAE1C,MAAM,WAAW,4BAA4B;IAC3C;uEACmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,sBAAsB,CAAA;IAC7C;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,OAAO,CAAC,EAAE,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,mBAAmB,KACxB,IAAI,CAAA;CACV;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAA;IACtC,gBAAgB,EAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAA;IACtD,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAA;IACtB;;;;;;;;OAQG;IACH,aAAa,EAAE,SAAS,WAAW,EAAE,CAAA;CACtC;AAyBD,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,4BAAiC,GACzC,eAAe,CAgTjB"}
@@ -0,0 +1,367 @@
1
+ /**
2
+ * createChatStreamReducer — THE master chat-stream reader (Phase 3 of the
3
+ * chat unification). One accumulation path for every event source:
4
+ *
5
+ * SSE bytes → createSseFrameDecoder ─┐
6
+ * NATS chunk → decodeNatsChunk ─┼→ ChatStreamEvent → reducer.apply()
7
+ * history → decodeHistoricalMessageData (per-item vocabulary) →
8
+ * envelope grouping → reducer.initializeWithState()
9
+ *
10
+ * The reducer absorbs, verbatim, the semantics that used to be spread over
11
+ * three layers:
12
+ * - `MessageSegmentAccumulator` stays as the internal per-turn segment
13
+ * kernel (instantiated here — its goldens remain valid);
14
+ * - the deleted `useRealtimeChunkProcessor`'s switch (in-stream vs post-END
15
+ * routing, agent-busy outside a message window, escalated approvals,
16
+ * compaction upsert, direct-mode barrier) — surfaced as
17
+ * `ChatReducerEffect`s for consumers that want the callback contract;
18
+ * - `useNatsChatAdapter`'s message-mutation callbacks (trailing-assistant
19
+ * replace/append, compaction upsert, cross-message tool merge, approval
20
+ * flip, participant dedup) — now the reducer's own state transitions via
21
+ * `./message-mutations`;
22
+ * - `useSseChatAdapter`/`useChat`'s SSE turn kernel (cumulative text
23
+ * replace, front-inserted thinking, approval card, `decision_resolved`
24
+ * receipt + cardRef stamping, sendIdx-keyed sources/refs/meta maps).
25
+ *
26
+ * Idempotency:
27
+ * - events whose `seq` ≤ the last applied seq are dropped (per instance);
28
+ * - participant rows additionally dedup via a one-shot optimistic-echo
29
+ * list and a short same-author content window (seq-less transports);
30
+ * - value-level no-op merges return prior references (see
31
+ * `message-mutations.ts`).
32
+ *
33
+ * TRANSPORT ORDERING ASSUMPTION (the seq gate, see `apply()`): every
34
+ * transport feeding this reducer is AT-LEAST-ONCE and IN-ORDER. JetStream
35
+ * redelivers (hence the gate) but never reorders within a stream, and the
36
+ * catchup back-fill replays a monotonically increasing range. So `seq <=
37
+ * lastAppliedSeq` means "already applied", and dropping is correct.
38
+ * A genuinely out-of-order arrival (seq 5 then 4) would be discarded
39
+ * PERMANENTLY — accepted deliberately: no transport here reorders, and an
40
+ * out-of-order buffer would add latency + unbounded state to guard against
41
+ * a case that cannot occur. If a reordering transport is ever added, this
42
+ * gate is the place that must change (do not paper over it downstream).
43
+ *
44
+ * `resolvePendingApprovalForExecution` (the accumulator's implicit
45
+ * approve-on-execution) is reachable ONLY on `transport: 'nats'` — the SSE
46
+ * kernel never routes tool executions through the accumulator.
47
+ *
48
+ * PURE + framework-free: no React, no timers, no network. Side effects the
49
+ * UI needs (approve/reject POSTs) enter as opaque callbacks stamped onto
50
+ * approval segments.
51
+ */
52
+ import { type AccumulatorCallbacks } from '../utils/message-segment-accumulator';
53
+ import { type ScrollAnchor } from '../utils/scroll-anchor';
54
+ import type { ChatApprovalStatus, MessageSegment, PendingToolCallData, ToolExecutionSegment, ExecutingToolState } from '../types';
55
+ import type { PendingApproval } from '../types/processing.types';
56
+ import type { DialogTokenUsage, StreamingPhase, UnifiedChatMessage, UnifiedUsageBreakdown } from '../types/unified-chat-state.types';
57
+ import { type ChatStreamEvent } from '../../../chat-protocol/events';
58
+ import type { ChatRef } from '../chat-ref.types';
59
+ /** Per-turn metadata extracted from the streamed metadata/usage frames
60
+ * (SSE transport). Canonical home — `use-sse-chat-adapter` re-exports it. */
61
+ export interface ChatTurnMeta {
62
+ provider: string | null;
63
+ modelLabel: string | null;
64
+ contextWindowMaxTokens: number | null;
65
+ /** Input tokens (from usage:start). Includes cached tokens. */
66
+ inputTokens: number | null;
67
+ /** Output tokens (from the trailing usage frame). */
68
+ outputTokens: number | null;
69
+ /** Cache hit % (read / total-input × 100). Only known after stream end. */
70
+ cacheHitRatePct: number | null;
71
+ /** Cross-call usage breakdown extracted from the trailing usage frame. */
72
+ breakdown: UnifiedUsageBreakdown | null;
73
+ /** Per-message viewport-positioning hint. */
74
+ scrollAnchor: ScrollAnchor | null;
75
+ routedComplexity: string | null;
76
+ routedThinkingBudget: number | null;
77
+ }
78
+ /** Single source of truth for a fresh `ChatTurnMeta` row. */
79
+ export declare function createEmptyTurnMeta(): ChatTurnMeta;
80
+ /** SSE per-send maps, keyed by the send counter (`sendIdx`). Each user send
81
+ * produces ONE server-side refs/sources entry but can fan out to MULTIPLE
82
+ * assistant messages client-side — the adapter maps every following
83
+ * assistant message back to its send's entry. */
84
+ export interface ChatTurnMetaState {
85
+ meta: Map<number, ChatTurnMeta>;
86
+ sources: Map<number, unknown[]>;
87
+ refs: Map<number, Record<string, ChatRef>>;
88
+ sendCount: number;
89
+ }
90
+ export interface ChatReducerState {
91
+ messages: UnifiedChatMessage[];
92
+ streamingPhase: StreamingPhase;
93
+ turnMeta: ChatTurnMetaState;
94
+ dialogTokenUsage?: DialogTokenUsage | null;
95
+ liveModel?: {
96
+ provider: string | null;
97
+ modelLabel: string | null;
98
+ contextWindowMaxTokens: number | null;
99
+ } | null;
100
+ approvalStatuses: Record<string, ChatApprovalStatus>;
101
+ }
102
+ /** Escalated-approval bookkeeping entry (mirrors the legacy processor). */
103
+ export interface EscalatedApprovalData {
104
+ command: string;
105
+ explanation?: string;
106
+ approvalType: string;
107
+ toolCalls?: PendingToolCallData[];
108
+ }
109
+ /**
110
+ * Callback-visible effect produced by `apply()`. Names + args mirror the
111
+ * legacy `RealtimeChunkCallbacks` contract 1:1 — the contract the deleted
112
+ * `useRealtimeChunkProcessor` wrapper exposed, now pinned directly by
113
+ * `__tests__/chat-stream-reducer-golden.test.ts`.
114
+ *
115
+ * `segments-after-approval-result` is the one conditional emission: the
116
+ * legacy processor emitted a cumulative `onSegmentsUpdate` for a
117
+ * non-escalated APPROVAL_RESULT only when the consumer had NOT wired
118
+ * `onApprovalResolved` — the effect sink resolves that at dispatch time.
119
+ */
120
+ export interface ChatReducerEffect {
121
+ name: 'onStreamStart' | 'onStreamEnd' | 'onMetadata' | 'onSegmentsUpdate' | 'onError' | 'onUserMessage' | 'onTokenUsage' | 'onDirectMessage' | 'onSystemMessage' | 'onEscalatedApproval' | 'onEscalatedApprovalResult' | 'onApprovalResolved' | 'onToolExecuted' | 'onAgentBusy' | 'onDialogClosed' | 'segments-after-approval-result';
122
+ args: unknown[];
123
+ }
124
+ export interface ChatStreamReducerOptions {
125
+ /** Which transport's turn kernel drives `apply()`. Default `'nats'`. */
126
+ transport?: 'sse' | 'nats';
127
+ /** Seed for the approval-status map (request-id → status). */
128
+ approvalStatuses?: Record<string, ChatApprovalStatus>;
129
+ /** Batch APPROVAL_REQUESTs render as one card (default true) or unfold. */
130
+ batchApprovalsEnabled?: boolean;
131
+ /** Approval types displayed inline; others escalate. Default ['CLIENT']. */
132
+ displayApprovalTypes?: string[];
133
+ /** Opaque approve/reject handlers stamped onto approval segments. */
134
+ callbacks?: AccumulatorCallbacks;
135
+ /** Engage the direct-mode barrier optimistically (host-known takeover). */
136
+ isDirectMode?: boolean;
137
+ /**
138
+ * Legacy-processor parity knob: post-MESSAGE_END tool chunks route
139
+ * cross-message (`onToolExecuted` effect + `applyToolExecutionToMessages`)
140
+ * only when the consumer wired the cross-message updater; otherwise they
141
+ * fall through the accumulator like the pre-callback code path. Default
142
+ * true (both first-party adapters wire it).
143
+ */
144
+ crossMessageToolRouting?: boolean;
145
+ /** Effect sink for callback-contract consumers (compat wrapper). */
146
+ onEffect?: (effect: ChatReducerEffect) => void;
147
+ /** Notified after every state mutation (the dialog store wires this). */
148
+ onChange?: () => void;
149
+ /**
150
+ * Whether an ADMIN-authored `MESSAGE_REQUEST` may be consumed as OUR OWN
151
+ * optimistic echo (see `pushOptimisticSend`). Default `false`.
152
+ *
153
+ * Who the local operator is decides this, and it differs per host:
154
+ * - Hub website chat / ticket CLIENT side: the local user is NEVER the
155
+ * admin, so an ADMIN-authored inbound row is a technician's reply and
156
+ * must ALWAYS render. Consuming it as an echo would silently delete a
157
+ * real message whenever its text happened to match ours. → `false`.
158
+ * - OpenFrame product app (Mingo + ticket ADMIN side): the operator IS
159
+ * the admin, so their own sends echo back as ADMIN and MUST be
160
+ * deduped, or every message renders twice. → `true`.
161
+ *
162
+ * Only ever applies to text the host itself registered via
163
+ * `pushOptimisticSend`, so enabling it cannot drop a message the host
164
+ * did not just send.
165
+ */
166
+ ownEchoIncludesAdmin?: boolean;
167
+ /**
168
+ * The LOCAL user's id, either as a value or as a GETTER resolved at event
169
+ * time. When it resolves to a value, an inbound `MESSAGE_REQUEST` that
170
+ * DECLARES a different author (`event.userId !== selfUserId`) may not be
171
+ * consumed as our own optimistic echo.
172
+ *
173
+ * Without it the echo list matches on RAW TEXT alone, which on a shared
174
+ * ADMIN side (two technicians in one ticket, `ownEchoIncludesAdmin: true`)
175
+ * can silently delete a colleague's message: if OUR send never echoes back,
176
+ * its entry stays armed and the next identical text from anyone — canned
177
+ * replies like "ok" / "done" / "on it" make this routine — is swallowed.
178
+ *
179
+ * The guard FAILS OPEN, deliberately: a row that carries NO `userId` is not
180
+ * "someone else's", it is UNATTRIBUTED, and rejecting it would disable
181
+ * dedup entirely (→ every send rendered twice) on any transport whose
182
+ * decoder does not surface the author id. Such a row falls back to the
183
+ * text + `OWN_ECHO_TTL_MS` behaviour instead, and a one-shot `console.warn`
184
+ * makes the missing id observable.
185
+ *
186
+ * Pass a FUNCTION whenever the id can change or arrive late (auth
187
+ * rehydration, logout / login-as-another-user without a reload): reducers
188
+ * are retained for the store's lifetime, so a value captured at creation
189
+ * time can go stale and silently disable the guard.
190
+ */
191
+ selfUserId?: string | (() => string | undefined);
192
+ }
193
+ /**
194
+ * How long an un-consumed optimistic-echo entry stays armed **on the
195
+ * UNATTRIBUTED path**. Long enough to cover any realistic send → server-echo
196
+ * round trip, short enough that a send whose echo never lands cannot swallow
197
+ * an unrelated identical message later in the conversation.
198
+ *
199
+ * A row that is DECLARED ours (`selfUserId` set and `event.userId ===
200
+ * selfUserId`) gets the LONGER `OWN_ECHO_AUTHOR_TTL_MS` instead — see there.
201
+ */
202
+ export declare const OWN_ECHO_TTL_MS = 30000;
203
+ /**
204
+ * How long an un-consumed entry stays armed on the AUTHOR-MATCHED path
205
+ * (`selfUserId` set, inbound row declares the same author).
206
+ *
207
+ * The author check rules out CROSS-technician theft, but NOT the same user on
208
+ * a second tab or device: a row THIS tab did not originate looks exactly like
209
+ * an author-matched echo. So the entry still needs an upper bound — without
210
+ * one, a send whose echo never lands (dropped frame, backend text
211
+ * normalization, reconnect gap) leaves the entry armed for the reducer's
212
+ * whole lifetime, and the next identical text from the same user on ANOTHER
213
+ * tab is silently swallowed. With `MAX_PENDING_ECHOES` armed slots and canned
214
+ * replies ("ok", "done", "on it") being exactly the recurring strings, that is
215
+ * a routine message-LOSS bug, strictly worse than the duplicate row it trades
216
+ * against.
217
+ *
218
+ * Ten minutes is the bound: generously longer than the slow echo the author
219
+ * path exists to protect (a JetStream catch-up replay after a network gap
220
+ * arrives long after the send, and its rows carry `seq`, so the seq-less
221
+ * content-dedup fallback cannot rescue it), and far shorter than the
222
+ * "same text again an hour later" window in which a stale entry does damage.
223
+ *
224
+ * It is a BACKSTOP, not the usual bound: `turn-end` disarms entries much
225
+ * sooner (see `purgeEchoesAtTurnEnd`). The ten minutes only ever apply to a
226
+ * dialog that never reports a turn boundary at all.
227
+ */
228
+ export declare const OWN_ECHO_AUTHOR_TTL_MS: number;
229
+ /** One armed optimistic-echo entry: the sent text and the wall-clock ms it was
230
+ * armed at. Exported because the LRU-eviction round trip PARKS these (see
231
+ * `getPendingEchoes` / `InitializeExtras.pendingEchoes`). */
232
+ export interface PendingEcho {
233
+ text: string;
234
+ at: number;
235
+ }
236
+ export interface InitializeExtras {
237
+ existingSegments?: MessageSegment[];
238
+ pendingApprovals?: Map<string, PendingApproval>;
239
+ executingTools?: Map<string, ExecutingToolState>;
240
+ escalatedApprovals?: Map<string, EscalatedApprovalData>;
241
+ /**
242
+ * Approval statuses PARKED from a previous instance of this key (LRU
243
+ * eviction hands them to `onEvict`). Merged with the same state-monotonic
244
+ * precedence as `mergeApprovalStatuses` — a resolved approval must not come
245
+ * back as actionable, which is exactly why `resetForDialogSwitch` preserves
246
+ * this map rather than clearing it.
247
+ */
248
+ approvalStatuses?: Record<string, ChatApprovalStatus>;
249
+ /**
250
+ * Seq cursor PARKED from a previous instance of this key. A recreated
251
+ * reducer starts at `-Infinity`, so a host that replays from its own cursor
252
+ * would re-apply already-applied events; restoring the parked value keeps
253
+ * `apply()`'s idempotency gate intact across an eviction. Only ever moves
254
+ * the gate FORWARD (a lower value is ignored).
255
+ */
256
+ lastAppliedSeq?: number;
257
+ /**
258
+ * Armed optimistic-echo entries PARKED from a previous instance of this key.
259
+ * Without them, a key LRU-evicted between `pushOptimisticSend` and its
260
+ * `MESSAGE_REQUEST` echo leaves the replacement reducer with nothing armed,
261
+ * so the echo renders a DUPLICATE user bubble. Entries already past
262
+ * `OWN_ECHO_AUTHOR_TTL_MS` are dropped on restore (an expired entry could
263
+ * only swallow an unrelated identical message), and the list is capped at
264
+ * `MAX_PENDING_ECHOES` exactly as the live path is.
265
+ */
266
+ pendingEchoes?: readonly PendingEcho[];
267
+ /**
268
+ * Whether the restored thread is a RESUMED dialog (a `MESSAGE_START` already
269
+ * fired server-side), which makes post-stream continuation chunks append
270
+ * into the existing bubble instead of taking the cold-start cumulative path.
271
+ * Defaults to "the restored thread is non-empty" — an eviction restore of a
272
+ * key that never streamed must NOT claim it did, or a cold text-delta with
273
+ * no preceding `turn-start` appends into a bubble that was never spawned.
274
+ * Pass explicitly only to override that derivation.
275
+ */
276
+ resumed?: boolean;
277
+ }
278
+ export interface BeginSseSendOptions {
279
+ text: string;
280
+ hidden?: boolean;
281
+ userName?: string;
282
+ assistantName?: string;
283
+ assistantAvatar?: string;
284
+ }
285
+ export interface ChatStreamReducer {
286
+ /** Apply one normalized stream event. */
287
+ apply(event: ChatStreamEvent): void;
288
+ /** Current immutable state snapshot (stable identity between mutations). */
289
+ readonly state: ChatReducerState;
290
+ /** Full reset — thread, per-turn kernel, dedup sets, seq gate, maps. */
291
+ reset(): void;
292
+ /**
293
+ * Seed the thread (history hydration / persisted-state rehydration) and
294
+ * optionally the per-turn kernel + escalated approvals (resume of an
295
+ * incomplete turn). `messages: null` keeps the current thread. Escalated
296
+ * entries are re-surfaced via `onEscalatedApproval` effects. Marks the
297
+ * instance as having streamed so continuation chunks append.
298
+ */
299
+ initializeWithState(messages: UnifiedChatMessage[] | null, extras?: InitializeExtras): void;
300
+ setMessages(messages: UnifiedChatMessage[]): void;
301
+ prependMessages(messages: UnifiedChatMessage[]): void;
302
+ /** Optimistic local send: user bubble (+ echo record) + assistant placeholder. */
303
+ pushOptimisticSend(text: string, hidden?: boolean): void;
304
+ /** Wipe thread + per-turn kernel, keep approval statuses (legacy clear). */
305
+ clearThread(): void;
306
+ /** Per-dialog reset (keeps approval statuses — request-ids are global). */
307
+ resetForDialogSwitch(): void;
308
+ beginSseSend(options: BeginSseSendOptions): void;
309
+ endSseTurn(): void;
310
+ failSseTurn(errorMessage: string): void;
311
+ seedSseMaps(seed: {
312
+ sources?: Array<[number, unknown[]]>;
313
+ refs?: Array<[number, Record<string, ChatRef>]>;
314
+ sendCount?: number;
315
+ }): void;
316
+ setPhase(phase: StreamingPhase): void;
317
+ setApprovalStatus(requestId: string, status: ChatApprovalStatus | null): void;
318
+ /**
319
+ * CANONICAL merge of a PERSISTED status map (host-side store, history
320
+ * hydration, dialog-switch top-up) into this reducer's map.
321
+ *
322
+ * Precedence is STATE-MONOTONIC, not source-based, because either side can
323
+ * be the stale one:
324
+ * - persisted lags (a snapshot taken before the stream resolved the
325
+ * request) → the stream's resolved status must win, or a just-approved
326
+ * card would be downgraded back to `pending` and re-arm its buttons;
327
+ * - the STREAM lags (this tab saw the request, the operator resolved it in
328
+ * a SECOND TAB, and the persisted map is the one carrying the truth) →
329
+ * the persisted resolution must win, or the card stays actionable and
330
+ * invites a second approve on an already-resolved request.
331
+ *
332
+ * With statuses being exactly `pending | approved | rejected | cancelled`,
333
+ * "resolved beats pending" is a total order that gets both directions
334
+ * right: take the persisted value when ours is `pending` and theirs isn't;
335
+ * keep ours otherwise. Persisted entries still fill in every request-id the
336
+ * stream hasn't seen (other dialogs, pre-session history).
337
+ */
338
+ mergeApprovalStatuses(persisted: Record<string, ChatApprovalStatus>): void;
339
+ setDirectMode(isDirectMode: boolean): void;
340
+ setDialogTokenUsage(usage: DialogTokenUsage | null): void;
341
+ /** +1/-1 windows during catchup replay (suppresses agent-busy locks). */
342
+ adjustAgentBusySuppression(delta: number): void;
343
+ armAdoptTrailingAssistant(value: boolean): void;
344
+ projectApprovalResolution(requestId: string, status: ChatApprovalStatus, resolvedByName?: string | null): void;
345
+ projectToolExecution(segment: ToolExecutionSegment): void;
346
+ /**
347
+ * The seq gate's current value (`-Infinity` before anything seq-carrying was
348
+ * applied). Not part of `state` — it is bookkeeping, not render input — but
349
+ * a host that PARKS a reducer (LRU eviction, dialog swap) needs it to
350
+ * restore idempotency on the recreated instance via
351
+ * `initializeWithState(messages, { lastAppliedSeq })`.
352
+ */
353
+ getLastAppliedSeq(): number;
354
+ /**
355
+ * Currently-armed optimistic-echo entries. Same rationale as
356
+ * `getLastAppliedSeq`: not render input, but a host that PARKS a reducer
357
+ * needs them to restore echo dedup on the recreated instance via
358
+ * `initializeWithState(messages, { pendingEchoes })` — otherwise an echo
359
+ * in flight across the eviction renders a duplicate user bubble.
360
+ */
361
+ getPendingEchoes(): readonly PendingEcho[];
362
+ getSegments(): MessageSegment[];
363
+ updateApprovalStatus(requestId: string, status: ChatApprovalStatus, resolvedByName?: string | null): MessageSegment[];
364
+ getPendingEscalated(): Map<string, EscalatedApprovalData>;
365
+ }
366
+ export declare function createChatStreamReducer(options?: ChatStreamReducerOptions): ChatStreamReducer;
367
+ //# sourceMappingURL=chat-stream-reducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-stream-reducer.d.ts","sourceRoot":"","sources":["../../../../src/components/chat/stream/chat-stream-reducer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * createDeltaBatcher — framework-free, append-only batching of `text-delta`
3
+ * and `thinking-delta` events.
4
+ *
5
+ * WHY THIS IS SHARED (and not a hook-private detail): every host that drives a
6
+ * `ChatStreamReducer` from a raw transport needs the SAME batching, and a
7
+ * copy-paste of it drifts. The React wrapper (`useChatStreamReducer`) and any
8
+ * non-React mirror in a product app both consume this one implementation.
9
+ *
10
+ * Behaviour:
11
+ * - `push(event, key)` queues delta events and returns true; anything else
12
+ * returns false so the caller can flush + apply it synchronously (ordering:
13
+ * completion state must always land on fully-applied deltas).
14
+ * - CONSECUTIVE same-type deltas are COALESCED into one event (the reducer's
15
+ * append semantics distribute over concatenation), so a 60-delta/sec turn
16
+ * costs ONE `applyOne` per frame instead of 60. `text-delta` additionally
17
+ * requires a matching `leading` flag before coalescing.
18
+ * - A flush is scheduled on `requestAnimationFrame` when available, with a
19
+ * timer fallback that is ALWAYS armed (rAF pauses in background tabs, and a
20
+ * hidden chat panel must still keep its thread current).
21
+ * - `key` is an opaque routing token handed back to `applyOne`. When it
22
+ * changes, the pending batch is flushed against the PREVIOUS key first, so
23
+ * deltas never land on the wrong dialog/side.
24
+ */
25
+ import type { ChatStreamEvent, TextDeltaEvent, ThinkingDeltaEvent } from '../../../chat-protocol/events';
26
+ export declare const DELTA_FLUSH_FALLBACK_MS = 50;
27
+ export type DeltaEvent = TextDeltaEvent | ThinkingDeltaEvent;
28
+ export declare function isDeltaEvent(event: ChatStreamEvent): event is DeltaEvent;
29
+ export interface CreateDeltaBatcherOptions<K> {
30
+ /** Apply one (possibly coalesced) delta against `key`'s reducer. */
31
+ applyOne: (event: DeltaEvent, key: K | undefined) => void;
32
+ /** Called after a flush that applied at least one delta. */
33
+ onFlushed?: (appliedCount: number) => void;
34
+ /** Timer fallback in ms (default `DELTA_FLUSH_FALLBACK_MS`). */
35
+ fallbackMs?: number;
36
+ }
37
+ export interface DeltaBatcher<K = unknown> {
38
+ /**
39
+ * Queue `event` when it is a delta (returns true). Non-delta events are NOT
40
+ * queued and return false — the caller flushes and applies them itself.
41
+ */
42
+ push(event: ChatStreamEvent, key?: K): boolean;
43
+ /** Synchronously apply the pending batch and cancel any scheduled flush. */
44
+ flush(): void;
45
+ /** Flush and release timers — call on teardown so tail deltas aren't lost. */
46
+ dispose(): void;
47
+ /** Queued (post-coalescing) delta count. Test/diagnostic surface. */
48
+ readonly pendingCount: number;
49
+ }
50
+ export declare function createDeltaBatcher<K = unknown>({ applyOne, onFlushed, fallbackMs, }: CreateDeltaBatcherOptions<K>): DeltaBatcher<K>;
51
+ //# sourceMappingURL=delta-batcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delta-batcher.d.ts","sourceRoot":"","sources":["../../../../src/components/chat/stream/delta-batcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAExG,eAAO,MAAM,uBAAuB,KAAK,CAAA;AAEzC,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,kBAAkB,CAAA;AAE5D,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,IAAI,UAAU,CAExE;AAED,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,oEAAoE;IACpE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,CAAA;IACzD,4DAA4D;IAC5D,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAA;IAC9C,4EAA4E;IAC5E,KAAK,IAAI,IAAI,CAAA;IACb,8EAA8E;IAC9E,OAAO,IAAI,IAAI,CAAA;IACf,qEAAqE;IACrE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,CAAC,GAAG,OAAO,EAAE,EAC9C,QAAQ,EACR,SAAS,EACT,UAAoC,GACrC,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAgGhD"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Chat stream module — ONE master reader for every chat event source
3
+ * (SSE decoder, NATS chunk decoder, historical replay). See
4
+ * `chat-stream-reducer.ts` for the architecture note.
5
+ *
6
+ * NOTE: the pure message-mutation helpers (`appendToTrailingAssistant`,
7
+ * `applyToolExecutionToMessages`, …) are intentionally NOT star-exported
8
+ * here — their legacy public home is `use-nats-chat-adapter`, which
9
+ * re-exports them from `./message-mutations`; exporting the same bindings
10
+ * from two star-exported barrels would make them ambiguous and drop them
11
+ * from the chat barrel entirely.
12
+ */
13
+ export { createChatStreamReducer, createEmptyTurnMeta, type BeginSseSendOptions, type ChatReducerEffect, type ChatReducerState, type ChatStreamReducer, type ChatStreamReducerOptions, type ChatTurnMetaState, type EscalatedApprovalData, type InitializeExtras, type PendingEcho, } from './chat-stream-reducer';
14
+ export { createChatDialogStore, DEFAULT_DIALOG_SIDE, DEFAULT_MAX_REDUCERS, MAX_PENDING_RETAIN_KEYS, type ChatDialogSide, type ChatDialogStore, type CreateChatDialogStoreOptions, type EvictedReducerState, } from './chat-dialog-store';
15
+ export { createDeltaBatcher, type CreateDeltaBatcherOptions, type DeltaBatcher, type DeltaEvent, } from './delta-batcher';
16
+ export { useChatStreamReducer, type UseChatStreamReducerOptions, type UseChatStreamReducerReturn, } from './use-chat-stream-reducer';
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/chat/stream/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,WAAW,GACjB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAA;AAO5B,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,YAAY,EACjB,KAAK,UAAU,GAChB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,oBAAoB,EACpB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,GAChC,MAAM,2BAA2B,CAAA"}