@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,146 @@
1
+ /**
2
+ * `normalizeIpForBucketKey` — THE cross-repo normalizer for turning a raw
3
+ * client-IP candidate (`x-forwarded-for` hop, socket remote address, proxy
4
+ * header) into a stable rate-limit / dedup bucket key.
5
+ *
6
+ * WHY IT LIVES HERE: producer and consumer sit in DIFFERENT repos (the app
7
+ * emits the candidate, the hub buckets it) and each had grown its own
8
+ * normalizer. They disagreed — one unwrapped `::ffff:1.2.3.4` to the bare
9
+ * IPv4 and stripped `%zone`, the other kept the zone and only lower-cased the
10
+ * mapped form — so ONE visitor could land in TWO buckets depending on which
11
+ * side normalized. Both repos already depend on this package, and
12
+ * `./chat-protocol` is its server-safe subpath (no React, no browser APIs),
13
+ * so this is the one place both sides can share.
14
+ *
15
+ * Contract:
16
+ * - input longer than `IP_BUCKET_KEY_MAX_LENGTH` → `null` (an unbounded
17
+ * header must never become an unbounded map key);
18
+ * - `[…]` brackets and a trailing `]:port` are stripped, as is a bare
19
+ * `:port` on an IPv4 (`203.0.113.4:8080`) — an unbracketed IPv6 with a
20
+ * bare port stays ambiguous and is not stripped;
21
+ * - a `%zone` suffix is stripped (link-local scope is per-host, not part of
22
+ * the peer's identity);
23
+ * - IPv4-mapped IPv6 (`::ffff:203.0.113.4`) collapses to the bare IPv4, so
24
+ * the same peer buckets identically over either stack;
25
+ * - IPv6 is lower-cased;
26
+ * - IPv4 octets are range-checked and REJECTED when zero-padded (`.04`
27
+ * would otherwise bucket separately from `.4`), and IPv6 is
28
+ * charset/shape-checked (one `::` at most, ≤8 groups, an embedded IPv4
29
+ * only in the last group, no dangling separator); anything else returns
30
+ * `null` rather than a junk bucket key.
31
+ *
32
+ * It does NOT canonicalize IPv6 zero-compression (`2001:db8::1` vs
33
+ * `2001:0db8:0:0:0:0:0:1`) — peers do not spell their own address two ways
34
+ * within one deployment, and a full expander is more surface than the bucket
35
+ * key warrants.
36
+ */
37
+
38
+ /** Longest accepted candidate. A full IPv6 + zone fits well inside this. */
39
+ export const IP_BUCKET_KEY_MAX_LENGTH = 64
40
+
41
+ function isIpv4(value: string): boolean {
42
+ const parts = value.split('.')
43
+ if (parts.length !== 4) return false
44
+ for (const part of parts) {
45
+ if (!/^\d{1,3}$/.test(part)) return false
46
+ // Leading zeros are a SECOND spelling of the same address (`203.0.113.04`),
47
+ // so accepting them verbatim splits one peer across two buckets. Reject
48
+ // rather than canonicalize: no legitimate emitter zero-pads, and some
49
+ // resolvers read a `0`-prefixed octet as octal, i.e. it is not even
50
+ // reliably the same address.
51
+ if (part.length > 1 && part.startsWith('0')) return false
52
+ if (Number(part) > 255) return false
53
+ }
54
+ return true
55
+ }
56
+
57
+ function isIpv6(value: string): boolean {
58
+ if (!value.includes(':')) return false
59
+ // Charset gate first: hex digits, separators, and the dots of a trailing
60
+ // embedded IPv4. Anything else (a hostname, a header injection) is out.
61
+ if (!/^[0-9a-f:.]+$/.test(value)) return false
62
+ if (value.includes(':::')) return false
63
+ // A dangling separator (`2001:db8::1:`) leaves an EMPTY trailing group that
64
+ // is not part of a `::` compression — malformed, not an address.
65
+ if (value.endsWith(':') && !value.endsWith('::')) return false
66
+ if (value.startsWith(':') && !value.startsWith('::')) return false
67
+ const compressions = value.split('::').length - 1
68
+ if (compressions > 1) return false
69
+ const groups = value.split(':')
70
+ if (groups.length > 8) return false
71
+ for (let i = 0; i < groups.length; i += 1) {
72
+ const group = groups[i]
73
+ if (group === '') continue
74
+ if (group.includes('.')) {
75
+ // An embedded IPv4 occupies the LAST two groups; anywhere else
76
+ // (`1.2.3.4::1`) it is malformed.
77
+ if (i !== groups.length - 1) return false
78
+ if (!isIpv4(group)) return false
79
+ continue
80
+ }
81
+ if (!/^[0-9a-f]{1,4}$/.test(group)) return false
82
+ }
83
+ // Uncompressed form must be exactly 8 groups (a trailing embedded IPv4
84
+ // occupies two, so 7 written groups is also complete).
85
+ if (compressions === 0) {
86
+ const embedsIpv4 = groups[groups.length - 1]?.includes('.') ?? false
87
+ if (groups.length !== (embedsIpv4 ? 7 : 8)) return false
88
+ }
89
+ return true
90
+ }
91
+
92
+ /**
93
+ * Normalize one IP candidate to its canonical bucket key, or `null` when the
94
+ * value is not a usable address.
95
+ */
96
+ export function normalizeIpForBucketKey(value: string): string | null {
97
+ if (typeof value !== 'string') return null
98
+ let candidate = value.trim()
99
+ if (candidate === '' || candidate.length > IP_BUCKET_KEY_MAX_LENGTH) return null
100
+
101
+ // `[2001:db8::1]` / `[::1]:443` — the bracketed forms a proxy emits so the
102
+ // port is unambiguous.
103
+ if (candidate.startsWith('[')) {
104
+ const close = candidate.indexOf(']')
105
+ if (close === -1) return null
106
+ const trailer = candidate.slice(close + 1)
107
+ if (trailer !== '' && !/^:\d{1,5}$/.test(trailer)) return null
108
+ candidate = candidate.slice(1, close)
109
+ }
110
+
111
+ // `%eth0` / `%25eth0` scope id — host-local, never part of peer identity.
112
+ const zone = candidate.indexOf('%')
113
+ if (zone !== -1) candidate = candidate.slice(0, zone)
114
+ if (candidate === '') return null
115
+
116
+ // UNBRACKETED `203.0.113.4:8080` — Azure App Service / Front Door and several
117
+ // CDNs write the client hop that way. Rejecting it left the caller with NO
118
+ // candidate at all, collapsing every visitor into the single egress bucket:
119
+ // exactly the silent regression this module exists to prevent. Stripped ONLY
120
+ // when the remainder is a valid IPv4; an unbracketed IPv6 with a bare port
121
+ // (`::1:443`) is genuinely ambiguous — `:443` is equally a final group — so
122
+ // that shape is left to the IPv6 path.
123
+ const portSplit = candidate.lastIndexOf(':')
124
+ if (portSplit > 0 && /^\d{1,5}$/.test(candidate.slice(portSplit + 1))) {
125
+ const head = candidate.slice(0, portSplit)
126
+ if (isIpv4(head)) candidate = head
127
+ }
128
+
129
+ if (isIpv4(candidate)) return candidate
130
+
131
+ const lowered = candidate.toLowerCase()
132
+
133
+ // IPv4-mapped IPv6 → the bare IPv4 (same peer, one bucket). EVERY spelling
134
+ // is handled: the compressed `::ffff:1.2.3.4` that dual-stack listeners
135
+ // actually emit, the written-out `0:0:0:0:0:ffff:1.2.3.4` that a hop doing
136
+ // its own (non-compressing) formatting can produce, and the ZERO-PADDED
137
+ // `0000:0000:0000:0000:0000:ffff:1.2.3.4` that a fixed-width formatter
138
+ // produces — leading zeros in an IPv6 group are purely cosmetic, so all
139
+ // three name the same peer. Matching only some of them would split one peer
140
+ // across two buckets — the exact failure this module exists to prevent.
141
+ const mapped = /^(?:(?:0{1,4}:){5}|::)ffff:(\d{1,3}(?:\.\d{1,3}){3})$/.exec(lowered)
142
+ if (mapped) return isIpv4(mapped[1]) ? mapped[1] : null
143
+
144
+ if (isIpv6(lowered)) return lowered
145
+ return null
146
+ }
@@ -0,0 +1,252 @@
1
+ /**
2
+ * NATS chunk → normalized `ChatStreamEvent` decoder.
3
+ *
4
+ * THE live NATS reading path — the ONLY chunk parser in the codebase. Every
5
+ * consumer (this lib's `useNatsChatAdapter`, the hub, the product app) feeds
6
+ * raw chunks through `decodeNatsChunk` into `createChatStreamReducer`. The
7
+ * legacy `components/chat/utils/chunk-parser.ts` (`parseChunkToAction`) that
8
+ * this module superseded was DELETED — do not reintroduce a second decoder.
9
+ *
10
+ * Chunks map onto the transport-agnostic event union, with the JetStream
11
+ * `streamSeq` lifted into the `seq` envelope (the reducer's idempotency gate
12
+ * keys off it).
13
+ *
14
+ * Behavior is pinned by `__tests__/nats-decoder-golden.test.ts`.
15
+ *
16
+ * Server-safe: no React, no browser APIs.
17
+ */
18
+
19
+ import { MESSAGE_TYPE } from '../components/chat/types/message.types'
20
+ import type { ApprovalToolCall, ChatStreamEvent } from './events'
21
+
22
+ /** Minimal structural view of a NATS chunk (see `ChunkData` in
23
+ * `src/components/chat/types/network.types.ts`). */
24
+ type NatsChunk = Record<string, any>
25
+
26
+ /** Coerce the wire's `toolCalls[]` into the batch-approval shape, dropping
27
+ * non-object entries and defaulting every field. */
28
+ function normalizeToolCalls(raw: unknown): ApprovalToolCall[] {
29
+ if (!Array.isArray(raw)) return []
30
+ return raw
31
+ .filter((item): item is Record<string, any> => !!item && typeof item === 'object')
32
+ .map((item) => ({
33
+ toolExecutionRequestId: String(item.toolExecutionRequestId ?? ''),
34
+ toolName: String(item.toolName ?? ''),
35
+ toolTitle: typeof item.toolTitle === 'string' ? item.toolTitle : undefined,
36
+ toolExplanation:
37
+ typeof item.toolExplanation === 'string' ? item.toolExplanation : undefined,
38
+ toolType: typeof item.toolType === 'string' ? item.toolType : undefined,
39
+ requiresApproval: item.requiresApproval === true,
40
+ approvalType: typeof item.approvalType === 'string' ? item.approvalType : null,
41
+ toolCallArguments:
42
+ item.toolCallArguments && typeof item.toolCallArguments === 'object'
43
+ ? (item.toolCallArguments as Record<string, any>)
44
+ : null,
45
+ }))
46
+ }
47
+
48
+ /**
49
+ * Parse one raw NATS chunk into a normalized event. Returns `null` for
50
+ * unknown/malformed chunks — an unrecognized `type`, a missing required
51
+ * field, or a non-object payload are all tolerated as no-ops rather than
52
+ * throwing, so a backend that adds a chunk type can't break the stream.
53
+ */
54
+ export function decodeNatsChunk(chunk: unknown): ChatStreamEvent | null {
55
+ if (!chunk || typeof chunk !== 'object') return null
56
+
57
+ const data = chunk as NatsChunk
58
+ const type = String(data.type || '')
59
+ // JetStream stream sequence → the generic `seq` envelope.
60
+ const seq: { seq?: number } =
61
+ typeof data.streamSeq === 'number' ? { seq: data.streamSeq } : {}
62
+
63
+ switch (type) {
64
+ case MESSAGE_TYPE.MESSAGE_START:
65
+ return { type: 'turn-start', ...seq }
66
+
67
+ case MESSAGE_TYPE.MESSAGE_END:
68
+ return { type: 'turn-end', ...seq }
69
+
70
+ case MESSAGE_TYPE.AI_METADATA: {
71
+ const providerName = data.providerName || data.provider
72
+ if (typeof data.modelName === 'string' && typeof providerName === 'string') {
73
+ return {
74
+ type: 'metadata',
75
+ modelLabel: data.modelDisplayName,
76
+ modelName: data.modelName,
77
+ provider: providerName,
78
+ contextWindowMaxTokens:
79
+ typeof data.contextWindow === 'number' ? data.contextWindow : 0,
80
+ ...seq,
81
+ }
82
+ }
83
+ return null
84
+ }
85
+
86
+ case MESSAGE_TYPE.TEXT:
87
+ if (typeof data.text === 'string') {
88
+ return { type: 'text-delta', text: data.text, ...seq }
89
+ }
90
+ return null
91
+
92
+ case MESSAGE_TYPE.THINKING:
93
+ if (typeof data.text === 'string') {
94
+ return { type: 'thinking-delta', text: data.text, ...seq }
95
+ }
96
+ return null
97
+
98
+ case MESSAGE_TYPE.EXECUTING_TOOL:
99
+ return {
100
+ type: 'tool-execution',
101
+ data: {
102
+ type: 'EXECUTING_TOOL',
103
+ integratedToolType: data.integratedToolType || '',
104
+ toolFunction: data.toolFunction || '',
105
+ toolTitle: typeof data.title === 'string' ? data.title : undefined,
106
+ parameters: data.parameters,
107
+ toolExecutionRequestId:
108
+ typeof data.toolExecutionRequestId === 'string'
109
+ ? data.toolExecutionRequestId
110
+ : undefined,
111
+ },
112
+ ...seq,
113
+ }
114
+
115
+ case MESSAGE_TYPE.EXECUTED_TOOL:
116
+ return {
117
+ type: 'tool-execution',
118
+ data: {
119
+ type: 'EXECUTED_TOOL',
120
+ integratedToolType: data.integratedToolType || '',
121
+ toolFunction: data.toolFunction || '',
122
+ toolTitle: typeof data.title === 'string' ? data.title : undefined,
123
+ parameters: data.parameters,
124
+ result: data.result,
125
+ success: data.success,
126
+ toolExecutionRequestId:
127
+ typeof data.toolExecutionRequestId === 'string'
128
+ ? data.toolExecutionRequestId
129
+ : undefined,
130
+ },
131
+ ...seq,
132
+ }
133
+
134
+ case MESSAGE_TYPE.APPROVAL_REQUEST: {
135
+ const requestId = data.approvalRequestId || data.approval_request_id || ''
136
+ const approvalType = data.approvalType || 'USER'
137
+ const toolCalls = normalizeToolCalls(data.toolCalls)
138
+
139
+ if (toolCalls.length > 0) {
140
+ return { type: 'approval-request', requestId, approvalType, toolCalls, ...seq }
141
+ }
142
+
143
+ return {
144
+ type: 'approval-request',
145
+ requestId,
146
+ approvalType,
147
+ command: data.command || '',
148
+ explanation: data.explanation,
149
+ ...seq,
150
+ }
151
+ }
152
+
153
+ case MESSAGE_TYPE.APPROVAL_RESULT: {
154
+ // Realtime chunks carry the resolver's name as `displayName`; the
155
+ // persisted GraphQL message exposes the same value as
156
+ // `resolvedByName`. Accept either so realtime and history-replay
157
+ // render "by {name}" identically.
158
+ const resolvedByName =
159
+ typeof data.resolvedByName === 'string'
160
+ ? data.resolvedByName
161
+ : typeof data.displayName === 'string'
162
+ ? data.displayName
163
+ : undefined
164
+ return {
165
+ type: 'approval-resolved',
166
+ requestId: data.approvalRequestId || data.approval_request_id || '',
167
+ status: data.approved === true ? 'approved' : 'rejected',
168
+ approvalType: data.approvalType || 'CLIENT',
169
+ resolvedByName,
170
+ ...seq,
171
+ }
172
+ }
173
+
174
+ case MESSAGE_TYPE.ERROR:
175
+ return {
176
+ type: 'error',
177
+ title: data.error || 'An error occurred',
178
+ details: data.details,
179
+ ...seq,
180
+ }
181
+
182
+ case MESSAGE_TYPE.MESSAGE_REQUEST:
183
+ return {
184
+ type: 'participant',
185
+ kind: 'message-request',
186
+ text: String(data.text || ''),
187
+ ownerType: typeof data.ownerType === 'string' ? data.ownerType : undefined,
188
+ displayName: typeof data.displayName === 'string' ? data.displayName : undefined,
189
+ userId: typeof data.userId === 'string' ? data.userId : undefined,
190
+ // Wire shape carries no label; fall back to the id (parity with
191
+ // the history path in `process-historical-messages.ts`).
192
+ contextItems: Array.isArray(data.contextItems)
193
+ ? (data.contextItems as Array<{ type?: unknown; id?: unknown }>)
194
+ .filter((it) => typeof it?.type === 'string' && typeof it?.id === 'string')
195
+ .map((it) => ({
196
+ type: it.type as string,
197
+ id: it.id as string,
198
+ label: it.id as string,
199
+ }))
200
+ : undefined,
201
+ ...seq,
202
+ }
203
+
204
+ case MESSAGE_TYPE.TOKEN_USAGE:
205
+ return {
206
+ type: 'token-usage',
207
+ inputTokensSize: data.inputTokensSize ?? 0,
208
+ outputTokensSize: data.outputTokensSize ?? 0,
209
+ totalTokensSize: data.totalTokensSize ?? 0,
210
+ contextSize: data.contextSize ?? 0,
211
+ ...seq,
212
+ }
213
+
214
+ case MESSAGE_TYPE.CONTEXT_COMPACTION_START:
215
+ return { type: 'compaction', phase: 'start', ...seq }
216
+
217
+ case MESSAGE_TYPE.CONTEXT_COMPACTION_END:
218
+ return {
219
+ type: 'compaction',
220
+ phase: 'end',
221
+ summary: typeof data.text === 'string' ? data.text : undefined,
222
+ ...seq,
223
+ }
224
+
225
+ case MESSAGE_TYPE.SYSTEM:
226
+ if (typeof data.text === 'string') {
227
+ return { type: 'participant', kind: 'system', text: data.text, ...seq }
228
+ }
229
+ return null
230
+
231
+ case MESSAGE_TYPE.DIRECT_MESSAGE:
232
+ if (typeof data.text === 'string') {
233
+ return {
234
+ type: 'participant',
235
+ kind: 'direct-message',
236
+ text: data.text,
237
+ ownerType: typeof data.ownerType === 'string' ? data.ownerType : undefined,
238
+ displayName:
239
+ typeof data.displayName === 'string' ? data.displayName : undefined,
240
+ userId: typeof data.userId === 'string' ? data.userId : undefined,
241
+ ...seq,
242
+ }
243
+ }
244
+ return null
245
+
246
+ case MESSAGE_TYPE.DIALOG_CLOSED:
247
+ return { type: 'dialog-closed', ...seq }
248
+
249
+ default:
250
+ return null
251
+ }
252
+ }