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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/dist/chat-protocol/decode.d.ts +58 -0
  2. package/dist/chat-protocol/decode.d.ts.map +1 -0
  3. package/dist/chat-protocol/encode.d.ts +44 -0
  4. package/dist/chat-protocol/encode.d.ts.map +1 -0
  5. package/dist/chat-protocol/env-flag.d.ts +35 -0
  6. package/dist/chat-protocol/env-flag.d.ts.map +1 -0
  7. package/dist/chat-protocol/events.d.ts +216 -0
  8. package/dist/chat-protocol/events.d.ts.map +1 -0
  9. package/dist/chat-protocol/frames.d.ts +213 -0
  10. package/dist/chat-protocol/frames.d.ts.map +1 -0
  11. package/dist/chat-protocol/index.cjs +506 -0
  12. package/dist/chat-protocol/index.cjs.map +1 -0
  13. package/dist/chat-protocol/index.d.ts +18 -0
  14. package/dist/chat-protocol/index.d.ts.map +1 -0
  15. package/dist/chat-protocol/index.js +490 -0
  16. package/dist/chat-protocol/index.js.map +1 -0
  17. package/dist/chat-protocol/ip-normalize.d.ts +44 -0
  18. package/dist/chat-protocol/ip-normalize.d.ts.map +1 -0
  19. package/dist/chat-protocol/nats-decoder.d.ts +26 -0
  20. package/dist/chat-protocol/nats-decoder.d.ts.map +1 -0
  21. package/dist/{chunk-3SQ5KXHQ.cjs → chunk-2T4GTV25.cjs} +9 -9
  22. package/dist/{chunk-3SQ5KXHQ.cjs.map → chunk-2T4GTV25.cjs.map} +1 -1
  23. package/dist/{chunk-CWAOV2FK.cjs → chunk-3CGZPAGR.cjs} +3 -3
  24. package/dist/{chunk-CWAOV2FK.cjs.map → chunk-3CGZPAGR.cjs.map} +1 -1
  25. package/dist/{chunk-TLMJHMXJ.js → chunk-3QSR22IC.js} +12 -12
  26. package/dist/chunk-3QSR22IC.js.map +1 -0
  27. package/dist/{chunk-TWYNR4TZ.cjs → chunk-4G5TLHJD.cjs} +7141 -4799
  28. package/dist/chunk-4G5TLHJD.cjs.map +1 -0
  29. package/dist/{chunk-ADPMHWOE.js → chunk-72XAID7Y.js} +4 -4
  30. package/dist/{chunk-PAGKRNWK.js → chunk-7WZHBQ4J.js} +2 -2
  31. package/dist/{chunk-OCEKO5CW.js → chunk-AEELJC4N.js} +12106 -9764
  32. package/dist/chunk-AEELJC4N.js.map +1 -0
  33. package/dist/{chunk-Z42BGM6Q.cjs → chunk-BT2WWDFP.cjs} +5 -5
  34. package/dist/{chunk-Z42BGM6Q.cjs.map → chunk-BT2WWDFP.cjs.map} +1 -1
  35. package/dist/{chunk-7LEL3RIX.cjs → chunk-C7OY3PQP.cjs} +11 -11
  36. package/dist/{chunk-7LEL3RIX.cjs.map → chunk-C7OY3PQP.cjs.map} +1 -1
  37. package/dist/{chunk-RHGGEKPQ.cjs → chunk-CIOLOQKQ.cjs} +4 -4
  38. package/dist/{chunk-RHGGEKPQ.cjs.map → chunk-CIOLOQKQ.cjs.map} +1 -1
  39. package/dist/{chunk-TSZHM74B.js → chunk-DC2TKS7C.js} +2 -2
  40. package/dist/{chunk-M2GOR3XQ.cjs → chunk-DYPYR7FR.cjs} +87 -87
  41. package/dist/{chunk-M2GOR3XQ.cjs.map → chunk-DYPYR7FR.cjs.map} +1 -1
  42. package/dist/{chunk-I64ABCDX.js → chunk-I2B6X77L.js} +2 -2
  43. package/dist/{chunk-NIZDKTGL.cjs → chunk-K5MSCMDK.cjs} +37 -37
  44. package/dist/{chunk-NIZDKTGL.cjs.map → chunk-K5MSCMDK.cjs.map} +1 -1
  45. package/dist/{chunk-DTYRYB2N.js → chunk-K6QTZ7CZ.js} +2 -2
  46. package/dist/{chunk-4LTMXDUS.js → chunk-KBN7PMFT.js} +2 -2
  47. package/dist/{chunk-TBMV7I5N.js → chunk-KXZO2WZX.js} +2 -2
  48. package/dist/{chunk-QTYZMP6D.cjs → chunk-LBAKLT6T.cjs} +62 -62
  49. package/dist/chunk-LBAKLT6T.cjs.map +1 -0
  50. package/dist/{chunk-KEBYLU3U.js → chunk-LFUPI7VX.js} +2 -2
  51. package/dist/{chunk-LDTR4IVZ.cjs → chunk-M37PBG4N.cjs} +31 -31
  52. package/dist/{chunk-LDTR4IVZ.cjs.map → chunk-M37PBG4N.cjs.map} +1 -1
  53. package/dist/{chunk-WA7RR64F.js → chunk-PO5O654H.js} +6 -5
  54. package/dist/chunk-PO5O654H.js.map +1 -0
  55. package/dist/{chunk-WK4N5VBX.cjs → chunk-QJJISLPA.cjs} +28 -27
  56. package/dist/chunk-QJJISLPA.cjs.map +1 -0
  57. package/dist/{chunk-2F44PLTV.cjs → chunk-T7MCSA55.cjs} +26 -26
  58. package/dist/{chunk-2F44PLTV.cjs.map → chunk-T7MCSA55.cjs.map} +1 -1
  59. package/dist/{chunk-WJQHJD7J.js → chunk-TWSKTJHW.js} +2 -2
  60. package/dist/{chunk-ZSQHZYCO.cjs → chunk-UQDMJ6DH.cjs} +13 -13
  61. package/dist/{chunk-ZSQHZYCO.cjs.map → chunk-UQDMJ6DH.cjs.map} +1 -1
  62. package/dist/{chunk-TZRUCD56.js → chunk-V3ZAAFE3.js} +5 -5
  63. package/dist/{chunk-LRGHJPET.js → chunk-XGIFOHKE.js} +2 -2
  64. package/dist/{chunk-POOMO3PA.cjs → chunk-YQEPRYT5.cjs} +7 -7
  65. package/dist/{chunk-POOMO3PA.cjs.map → chunk-YQEPRYT5.cjs.map} +1 -1
  66. package/dist/components/case-studies/index.cjs +8 -8
  67. package/dist/components/case-studies/index.js +2 -2
  68. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  69. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  70. package/dist/components/chat/hooks/index.d.ts +0 -1
  71. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  72. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  73. package/dist/components/chat/hooks/use-chunk-catchup.d.ts.map +1 -1
  74. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +15 -48
  75. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  76. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +10 -57
  77. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  78. package/dist/components/chat/index.cjs +10 -2
  79. package/dist/components/chat/index.cjs.map +1 -1
  80. package/dist/components/chat/index.d.ts +1 -0
  81. package/dist/components/chat/index.d.ts.map +1 -1
  82. package/dist/components/chat/index.js +21 -13
  83. package/dist/components/chat/stream/chat-dialog-store.d.ts +184 -0
  84. package/dist/components/chat/stream/chat-dialog-store.d.ts.map +1 -0
  85. package/dist/components/chat/stream/chat-stream-reducer.d.ts +380 -0
  86. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -0
  87. package/dist/components/chat/stream/delta-batcher.d.ts +51 -0
  88. package/dist/components/chat/stream/delta-batcher.d.ts.map +1 -0
  89. package/dist/components/chat/stream/index.d.ts +17 -0
  90. package/dist/components/chat/stream/index.d.ts.map +1 -0
  91. package/dist/components/chat/stream/message-mutations.d.ts +77 -0
  92. package/dist/components/chat/stream/message-mutations.d.ts.map +1 -0
  93. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +22 -0
  94. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +1 -0
  95. package/dist/components/chat/types/api.types.d.ts +1 -81
  96. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  97. package/dist/components/chat/types/processing.types.d.ts +2 -93
  98. package/dist/components/chat/types/processing.types.d.ts.map +1 -1
  99. package/dist/components/chat/types/unified-chat-state.types.d.ts +15 -0
  100. package/dist/components/chat/types/unified-chat-state.types.d.ts.map +1 -1
  101. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +34 -6
  102. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
  103. package/dist/components/chat/utils/history-merge.d.ts.map +1 -1
  104. package/dist/components/chat/utils/index.d.ts +2 -3
  105. package/dist/components/chat/utils/index.d.ts.map +1 -1
  106. package/dist/components/chat/utils/process-historical-messages.d.ts +59 -11
  107. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  108. package/dist/components/contact/index.cjs +3 -3
  109. package/dist/components/contact/index.js +2 -2
  110. package/dist/components/docs/index.cjs +5 -5
  111. package/dist/components/docs/index.js +4 -4
  112. package/dist/components/embeds/index.cjs +3 -3
  113. package/dist/components/embeds/index.js +2 -2
  114. package/dist/components/faq/index.cjs +3 -3
  115. package/dist/components/faq/index.js +2 -2
  116. package/dist/components/features/index.cjs +2 -2
  117. package/dist/components/features/index.js +1 -1
  118. package/dist/components/help-center-pages/index.cjs +22 -22
  119. package/dist/components/help-center-pages/index.js +13 -13
  120. package/dist/components/index.cjs +174 -132
  121. package/dist/components/index.cjs.map +1 -1
  122. package/dist/components/index.js +65 -23
  123. package/dist/components/index.js.map +1 -1
  124. package/dist/components/meeting-scheduler/index.cjs +34 -34
  125. package/dist/components/meeting-scheduler/index.js +3 -3
  126. package/dist/components/navigation/index.cjs +2 -2
  127. package/dist/components/navigation/index.js +1 -1
  128. package/dist/components/onboarding-guides/index.cjs +5 -5
  129. package/dist/components/onboarding-guides/index.js +4 -4
  130. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  131. package/dist/components/related-content/index.cjs +3 -3
  132. package/dist/components/related-content/index.js +2 -2
  133. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  134. package/dist/components/tickets/index.cjs +6 -6
  135. package/dist/components/tickets/index.js +5 -5
  136. package/dist/components/ui/index.cjs +44 -2
  137. package/dist/components/ui/index.cjs.map +1 -1
  138. package/dist/components/ui/index.d.ts +1 -2
  139. package/dist/components/ui/index.d.ts.map +1 -1
  140. package/dist/components/ui/index.js +55 -13
  141. package/dist/components/ui/markdown/base-components.d.ts +51 -0
  142. package/dist/components/ui/markdown/base-components.d.ts.map +1 -0
  143. package/dist/components/ui/markdown/engine.d.ts +99 -0
  144. package/dist/components/ui/markdown/engine.d.ts.map +1 -0
  145. package/dist/components/ui/markdown/heading-ids.d.ts +65 -0
  146. package/dist/components/ui/markdown/heading-ids.d.ts.map +1 -0
  147. package/dist/components/ui/markdown/index.d.ts +18 -0
  148. package/dist/components/ui/markdown/index.d.ts.map +1 -0
  149. package/dist/components/ui/markdown/mermaid-diagram.d.ts +79 -0
  150. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +1 -0
  151. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +14 -0
  152. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +1 -0
  153. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +40 -0
  154. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -0
  155. package/dist/components/ui/markdown/rich/shortcodes.d.ts +8 -0
  156. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +1 -0
  157. package/dist/components/ui/markdown/sanitize.d.ts +153 -0
  158. package/dist/components/ui/markdown/sanitize.d.ts.map +1 -0
  159. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +23 -0
  160. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +1 -0
  161. package/dist/components/ui/markdown/streaming.d.ts +78 -0
  162. package/dist/components/ui/markdown/streaming.d.ts.map +1 -0
  163. package/dist/components/ui/markdown/text-size.d.ts +34 -0
  164. package/dist/components/ui/markdown/text-size.d.ts.map +1 -0
  165. package/dist/index.cjs +60 -2
  166. package/dist/index.cjs.map +1 -1
  167. package/dist/index.js +71 -13
  168. package/dist/utils/index.cjs +169 -40
  169. package/dist/utils/index.cjs.map +1 -1
  170. package/dist/utils/index.d.ts +1 -0
  171. package/dist/utils/index.d.ts.map +1 -1
  172. package/dist/utils/index.js +162 -41
  173. package/dist/utils/index.js.map +1 -1
  174. package/dist/utils/markdown-fences.d.ts +42 -0
  175. package/dist/utils/markdown-fences.d.ts.map +1 -0
  176. package/dist/utils/markdown-heading-id.d.ts +85 -0
  177. package/dist/utils/markdown-heading-id.d.ts.map +1 -0
  178. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  179. package/package.json +7 -1
  180. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +319 -0
  181. package/src/chat-protocol/__tests__/chat-protocol.test.ts +516 -0
  182. package/src/chat-protocol/__tests__/env-flag.test.ts +52 -0
  183. package/src/chat-protocol/__tests__/ip-normalize.test.ts +136 -0
  184. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +237 -0
  185. package/src/chat-protocol/decode.ts +278 -0
  186. package/src/chat-protocol/encode.ts +71 -0
  187. package/src/chat-protocol/env-flag.ts +39 -0
  188. package/src/chat-protocol/events.ts +254 -0
  189. package/src/chat-protocol/frames.ts +245 -0
  190. package/src/chat-protocol/index.ts +21 -0
  191. package/src/chat-protocol/ip-normalize.ts +146 -0
  192. package/src/chat-protocol/nats-decoder.ts +264 -0
  193. package/src/components/chat/.chat-message-list.md +10 -6
  194. package/src/components/chat/__tests__/chat-message-list.test.tsx +450 -9
  195. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +207 -0
  196. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +250 -0
  197. package/src/components/chat/chat-message-enhanced.tsx +122 -20
  198. package/src/components/chat/chat-message-list.tsx +515 -133
  199. package/src/components/chat/embeddable-chat.tsx +6 -0
  200. package/src/components/chat/hooks/.index.md +30 -33
  201. package/src/components/chat/hooks/.use-nats-chat-adapter.md +36 -55
  202. package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +37 -0
  203. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  204. package/src/components/chat/hooks/__tests__/chunk-catchup-dialog-staleness.test.ts +92 -0
  205. package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +438 -0
  206. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +318 -0
  207. package/src/components/chat/hooks/index.ts +0 -1
  208. package/src/components/chat/hooks/use-chat.ts +8 -0
  209. package/src/components/chat/hooks/use-chunk-catchup.ts +26 -1
  210. package/src/components/chat/hooks/use-nats-chat-adapter.ts +254 -825
  211. package/src/components/chat/hooks/use-sse-chat-adapter.ts +380 -684
  212. package/src/components/chat/index.ts +5 -0
  213. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +944 -0
  214. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +806 -0
  215. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +467 -0
  216. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +1330 -0
  217. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +255 -0
  218. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +105 -0
  219. package/src/components/chat/stream/chat-dialog-store.ts +536 -0
  220. package/src/components/chat/stream/chat-stream-reducer.ts +1928 -0
  221. package/src/components/chat/stream/delta-batcher.ts +168 -0
  222. package/src/components/chat/stream/index.ts +55 -0
  223. package/src/components/chat/stream/message-mutations.ts +340 -0
  224. package/src/components/chat/stream/use-chat-stream-reducer.ts +126 -0
  225. package/src/components/chat/thinking-display.tsx +1 -1
  226. package/src/components/chat/types/.api.types.md +39 -49
  227. package/src/components/chat/types/.processing.types.md +29 -58
  228. package/src/components/chat/types/.unified-chat-state.types.md +2 -2
  229. package/src/components/chat/types/api.types.ts +6 -73
  230. package/src/components/chat/types/processing.types.ts +11 -53
  231. package/src/components/chat/types/unified-chat-state.types.ts +16 -0
  232. package/src/components/chat/utils/.extract-incomplete-message-state.md +21 -3
  233. package/src/components/chat/utils/.history-merge.md +44 -3
  234. package/src/components/chat/utils/.index.md +31 -40
  235. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +420 -0
  236. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +605 -0
  237. package/src/components/chat/utils/__tests__/extract-incomplete-message-state.test.ts +106 -0
  238. package/src/components/chat/utils/__tests__/history-merge.test.ts +160 -0
  239. package/src/components/chat/utils/__tests__/process-historical-messages-approvals.test.ts +61 -0
  240. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +394 -0
  241. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +270 -0
  242. package/src/components/chat/utils/extract-incomplete-message-state.ts +93 -6
  243. package/src/components/chat/utils/history-merge.ts +85 -5
  244. package/src/components/chat/utils/index.ts +5 -8
  245. package/src/components/chat/utils/process-historical-messages.ts +361 -385
  246. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +22 -4
  247. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  248. package/src/components/shared/product-release/release-detail-page.tsx +19 -4
  249. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +2420 -0
  250. package/src/components/ui/__tests__/markdown-parity.test.tsx +2540 -0
  251. package/src/components/ui/index.ts +1 -2
  252. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +176 -0
  253. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +151 -0
  254. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +354 -0
  255. package/src/components/ui/markdown/__tests__/sanitize-render.test.tsx +118 -0
  256. package/src/components/ui/markdown/__tests__/streaming.test.tsx +436 -0
  257. package/src/components/ui/markdown/base-components.tsx +360 -0
  258. package/src/components/ui/markdown/engine.tsx +315 -0
  259. package/src/components/ui/markdown/heading-ids.ts +239 -0
  260. package/src/components/ui/markdown/index.ts +49 -0
  261. package/src/components/ui/markdown/mermaid-diagram.tsx +323 -0
  262. package/src/components/ui/markdown/rich/embed-overrides.tsx +199 -0
  263. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +184 -0
  264. package/src/components/ui/markdown/rich/shortcodes.ts +170 -0
  265. package/src/components/ui/markdown/sanitize.ts +3584 -0
  266. package/src/components/ui/markdown/simple-markdown-renderer.tsx +28 -0
  267. package/src/components/ui/markdown/streaming.ts +390 -0
  268. package/src/components/ui/markdown/text-size.ts +106 -0
  269. package/src/components/ui/release-changelog-section.tsx +1 -1
  270. package/src/components/ui/ticket-info-section.tsx +1 -1
  271. package/src/utils/index.ts +1 -0
  272. package/src/utils/markdown-fences.ts +127 -0
  273. package/src/utils/markdown-heading-id.ts +348 -0
  274. package/src/utils/markdown-section-extractor.ts +41 -56
  275. package/dist/chunk-OCEKO5CW.js.map +0 -1
  276. package/dist/chunk-QTYZMP6D.cjs.map +0 -1
  277. package/dist/chunk-TLMJHMXJ.js.map +0 -1
  278. package/dist/chunk-TWYNR4TZ.cjs.map +0 -1
  279. package/dist/chunk-WA7RR64F.js.map +0 -1
  280. package/dist/chunk-WK4N5VBX.cjs.map +0 -1
  281. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +0 -6
  282. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +0 -1
  283. package/dist/components/chat/utils/chunk-parser.d.ts +0 -25
  284. package/dist/components/chat/utils/chunk-parser.d.ts.map +0 -1
  285. package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
  286. package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
  287. package/dist/components/ui/simple-markdown-renderer.d.ts +0 -73
  288. package/dist/components/ui/simple-markdown-renderer.d.ts.map +0 -1
  289. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +0 -77
  290. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +0 -489
  291. package/src/components/chat/utils/.chunk-parser.md +0 -62
  292. package/src/components/chat/utils/chunk-parser.ts +0 -262
  293. package/src/components/ui/.simple-markdown-renderer.md +0 -52
  294. package/src/components/ui/rich-markdown-renderer.tsx +0 -1223
  295. package/src/components/ui/simple-markdown-renderer.tsx +0 -964
  296. /package/dist/{chunk-ADPMHWOE.js.map → chunk-72XAID7Y.js.map} +0 -0
  297. /package/dist/{chunk-PAGKRNWK.js.map → chunk-7WZHBQ4J.js.map} +0 -0
  298. /package/dist/{chunk-TSZHM74B.js.map → chunk-DC2TKS7C.js.map} +0 -0
  299. /package/dist/{chunk-I64ABCDX.js.map → chunk-I2B6X77L.js.map} +0 -0
  300. /package/dist/{chunk-DTYRYB2N.js.map → chunk-K6QTZ7CZ.js.map} +0 -0
  301. /package/dist/{chunk-4LTMXDUS.js.map → chunk-KBN7PMFT.js.map} +0 -0
  302. /package/dist/{chunk-TBMV7I5N.js.map → chunk-KXZO2WZX.js.map} +0 -0
  303. /package/dist/{chunk-KEBYLU3U.js.map → chunk-LFUPI7VX.js.map} +0 -0
  304. /package/dist/{chunk-WJQHJD7J.js.map → chunk-TWSKTJHW.js.map} +0 -0
  305. /package/dist/{chunk-TZRUCD56.js.map → chunk-V3ZAAFE3.js.map} +0 -0
  306. /package/dist/{chunk-LRGHJPET.js.map → chunk-XGIFOHKE.js.map} +0 -0
@@ -4,7 +4,7 @@ import { forwardRef, useState } from "react"
4
4
 
5
5
  import { cn } from "../../utils/cn"
6
6
  import { DotsLoaderIcon } from "../icons-v2-generated"
7
- import { SimpleMarkdownRenderer } from "../ui/simple-markdown-renderer"
7
+ import { SimpleMarkdownRenderer } from "../ui/markdown/simple-markdown-renderer"
8
8
  import { ExpandChevron } from "./expand-chevron"
9
9
  import { useCollapsible } from "./hooks/use-collapsible"
10
10
  import type { ThinkingDisplayProps } from "./types"
@@ -1,70 +1,60 @@
1
- <!-- source-hash: 76966dd4845d1486e56288fc8033df68 -->
2
- Defines TypeScript interfaces for API interactions and React hook contracts used in the OpenFrame real-time chat and NATS messaging system.
1
+ <!-- source-hash: 60ad035125eceb97fa074f58783d5bc8 -->
2
+ Defines TypeScript interfaces for API interactions and React hook contracts used across Flamingo's chat and dialog systems, covering NATS/JetStream subscriptions, real-time chunk processing, and REST-style request/response shapes.
3
3
 
4
4
  ## Key Components
5
5
 
6
- ### Hook Option Interfaces
7
- - **`UseChunkCatchupOptions`** Configuration for chunk catch-up logic, including dialog ID, chunk callbacks, chat type filters, and an optional custom fetch function
8
- - **`UseNatsDialogSubscriptionOptions`** — NATS WebSocket subscription config with reconnection backoff tuning, auth lifecycle hooks, and client credentials
9
- - **`UseJetStreamDialogSubscriptionOptions`** JetStream-specific variant adding stream name, sequence-based replay (`optStartSeq`), and consumer inactivity threshold
10
- - **`UseRealtimeChunkProcessorOptions`** Controls chunk processing behavior: approval type routing, batch approvals, direct-mode barrier, and initial accumulator state for reconnection
11
-
12
- ### Hook Return Interfaces
13
- - **`UseChunkCatchupReturn`** Exposes `catchUpChunks`, `processChunk`, `resetAndCatchUp`, and buffering state controls
14
- - **`UseNatsDialogSubscriptionReturn`** / **`UseJetStreamDialogSubscriptionReturn`** — Connection/subscription status and reconnection counters; JetStream variant also tracks `currentStreamSeq`
15
- - **`UseRealtimeChunkProcessorReturn`** — `processChunk`, `getSegments`, `reset`, and `updateApprovalStatus`
16
-
17
- ### Callback & Metadata Interfaces
18
- - **`RealtimeChunkCallbacks`** — Comprehensive event callback surface covering stream lifecycle (`onStreamStart`, `onStreamEnd`), message types (user, direct, system), tool execution (`onToolExecuted`, `onAgentBusy`), approval flows (`onApprove`, `onReject`, `onEscalatedApproval`, `onApprovalResolved`), token usage, and dialog closure
19
- - **`SegmentsUpdateMetadata`** — Carries append mode, compaction flags, and JetStream `streamSeq` for history deduplication
6
+ ### Hook Options
7
+ | Interface | Purpose |
8
+ |---|---|
9
+ | `UseChunkCatchupOptions` | Configure chunk catch-up replay with optional custom fetch function |
10
+ | `UseNatsDialogSubscriptionOptions` | Core NATS WebSocket subscription config with reconnection backoff tuning |
11
+ | `UseJetStreamDialogSubscriptionOptions` | JetStream-based subscription with sequence-based resume support |
12
+
13
+ ### Hook Return Types
14
+ | Interface | Purpose |
15
+ |---|---|
16
+ | `UseChunkCatchupReturn` | Exposes catchup, processing, and buffering controls |
17
+ | `UseNatsDialogSubscriptionReturn` | Connection state and reconnection counter |
18
+ | `UseJetStreamDialogSubscriptionReturn` | Connection state plus current stream sequence |
19
+
20
+ ### Callbacks
21
+ - **`RealtimeChunkCallbacks`** — Rich event callback map for streaming events: `onStreamStart`, `onStreamEnd`, `onSegmentsUpdate`, `onTokenUsage`, `onApprove`, `onReject`, `onEscalatedApproval`, `onApprovalResolved`, `onToolExecuted`, `onDialogClosed`, and more.
22
+
23
+ ### API Request/Response Types
24
+ - **Chat** — `ChatAPIRequest` / `ChatAPIResponse`
25
+ - **Dialogs** — `DialogCreateRequest/Response`, `DialogListRequest/Response`
26
+ - **Approvals** — `ApprovalRequest` / `ApprovalResponse`
27
+ - **Settings** — `ChatSettings`, `UpdateSettingsRequest/Response`
20
28
 
21
29
  ## Usage Example
22
30
 
23
31
  ```typescript
24
- import type {
25
- UseNatsDialogSubscriptionOptions,
26
- UseRealtimeChunkProcessorOptions,
27
- RealtimeChunkCallbacks,
28
- } from './api.types'
29
-
30
- const callbacks: RealtimeChunkCallbacks = {
31
- onStreamStart: () => setStreaming(true),
32
- onStreamEnd: () => setStreaming(false),
33
- onSegmentsUpdate: (segments, meta) => {
34
- if (meta?.append) appendSegments(segments)
35
- else setSegments(segments)
36
- },
37
- onToolExecuted: (segment) => mergeToolResult(segment),
38
- onApprovalResolved: (requestId, status, approvalType) => {
39
- updateApprovalCard(requestId, status)
32
+ const options: ChatStreamReducerOptions = {
33
+ callbacks: {
34
+ onSegmentsUpdate: (segments, meta) => {
35
+ if (meta?.append) appendToLastMessage(segments)
36
+ else setSegments(segments)
37
+ },
38
+ onApprovalResolved: (requestId, status, approvalType) => {
39
+ updateApprovalBadge(requestId, status)
40
+ },
41
+ onTokenUsage: (data) => console.log('Tokens used:', data),
40
42
  },
41
- }
42
-
43
- const processorOptions: UseRealtimeChunkProcessorOptions = {
44
- callbacks,
45
- displayApprovalTypes: ['CLIENT'],
46
43
  batchApprovalsEnabled: true,
47
- initialState: {
48
- existingSegments: historicalSegments,
49
- executingTools: new Map(),
50
- },
44
+ displayApprovalTypes: ['CLIENT'],
45
+ enableThinking: false,
51
46
  }
52
47
 
53
48
  const natsOptions: UseNatsDialogSubscriptionOptions = {
54
49
  enabled: true,
55
50
  dialogId: 'dialog-123',
56
- topics: ['message'],
57
51
  getNatsWsUrl: () => 'wss://nats.example.com',
58
- onBeforeReconnect: async () => refreshAuthToken(),
59
52
  reconnectionBackoff: {
60
53
  fastRetries: 3,
61
54
  fastRetryDelayMs: 500,
62
- maxDelayMs: 30_000,
55
+ maxDelayMs: 30000,
63
56
  multiplier: 2,
64
57
  },
58
+ onBeforeReconnect: async () => refreshAuthToken(),
65
59
  }
66
- ```
67
-
68
- ## Source
69
-
70
- [`api.types.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/api.types.ts)
60
+ ```
@@ -1,80 +1,51 @@
1
- <!-- source-hash: bdb71cca9908cf9cfebf089a00d84db8 -->
2
- Defines TypeScript types for the message processing pipeline, covering chunk parsing, state accumulation, stream control, and buffer management.
1
+ <!-- source-hash: 118d3a4cacf89174498282067448e4bf -->
2
+ Defines TypeScript types for message processing pipeline operations, including chunk parsing, accumulator state management, stream control, and buffer management for AI chat message flows.
3
3
 
4
4
  ## Key Components
5
5
 
6
- ### Union Types
7
- - **`ParsedChunkAction`** — Discriminated union of all possible chunk parse results: `message_start`, `message_end`, `error`, `metadata`, `text`, `thinking`, `tool_execution`, `approval_request`, `approval_batch`, `approval_result`, `token_usage`, `direct_message`, `system`, `context_compaction_start/end`, `dialog_closed`
8
-
9
- ### Accumulator State
10
- - **`AccumulatorState`** Tracks in-flight message segments, pending approvals, and executing tool states during streaming
11
- - **`PendingApproval`** Holds command, explanation, and approval type for a deferred approval card
12
-
13
- ### Processing Configuration
14
- - **`MessageProcessingOptions`** Runtime options passed to the processor: assistant identity, approval callbacks, chat type filter, approval status map, `displayApprovalTypes`, and `batchApprovalsEnabled` (consumer-owned feature flag)
15
-
16
- ### Chunk Processing
17
- - **`ChunkProcessor`** — Interface for stateful chunk parsing with `processChunk` and `reset`
18
- - **`ChunkProcessorOptions`** — Lifecycle callbacks for chunk events (`onText`, `onToolExecution`, `onApprovalRequest`, etc.)
19
-
20
- ### Message Transformation
21
- - **`MessageTransformer`** — Single and batch transform interface producing `ProcessedMessage` outputs
22
- - **`TransformationOptions`** — Flags for segment merging, timestamp formatting, and metadata inclusion
23
-
24
- ### Stream & Buffer Management
25
- - **`StreamProcessor`** — Lifecycle control (`start`, `stop`, `pause`, `resume`, `reset`, `getState`)
26
- - **`StreamState`** — Runtime counters: active state, pause flag, processed message count, buffered chunks, error log
27
- - **`BufferManager`** — FIFO buffer operations (`add`, `flush`, `clear`, `size`, `isEmpty`, `isFull`)
28
- - **`BufferOptions`** — Max size, flush interval, and overflow/flush callbacks
6
+ | Export | Type | Description |
7
+ |--------|------|-------------|
8
+ | `AccumulatorState` | Interface | Stateful container tracking message segments, pending approvals, and executing tools during stream processing |
9
+ | `PendingApproval` | Interface | Represents an approval request awaiting user action (command, explanation, type) |
10
+ | `MessageProcessingOptions` | Interface | Configuration for assistant rendering, approval callbacks, chat filtering, and batch approval UI |
11
+ | `StreamProcessor` | Interface | Full lifecycle control (start/stop/pause/resume/reset) for stream consumers |
12
+ | `StreamState` | Interface | Snapshot of stream health: active status, buffered chunks, error log, and last activity timestamp |
13
+ | `BufferManager` | Interface | CRUD-style contract for managing `ChunkData` buffers |
14
+ | `BufferOptions` | Interface | Configuration for buffer capacity, flush intervals, and overflow handling callbacks |
29
15
 
30
16
  ## Usage Example
31
17
 
32
18
  ```typescript
33
19
  import type {
34
- ParsedChunkAction,
35
20
  AccumulatorState,
36
21
  MessageProcessingOptions,
37
- StreamState,
22
+ StreamState
38
23
  } from './processing.types'
39
24
 
40
- // Narrow a parsed chunk action by discriminant
41
- function handleChunk(action: ParsedChunkAction) {
42
- switch (action.action) {
43
- case 'text':
44
- console.log('Text received:', action.text)
45
- break
46
- case 'tool_execution':
47
- console.log('Tool segment:', action.segment)
48
- break
49
- case 'approval_batch':
50
- console.log('Batch approval', action.requestId, action.toolCalls)
51
- break
52
- case 'error':
53
- console.error(action.error, action.details)
54
- break
55
- }
25
+
26
+ // Initializing accumulator state
27
+ const state: AccumulatorState = {
28
+ segments: [],
29
+ pendingApprovals: new Map(),
30
+ executingTools: new Map()
56
31
  }
57
32
 
58
- // Configure message processing with batch approvals enabled
33
+ // Configuring message processing
59
34
  const options: MessageProcessingOptions = {
60
35
  assistantName: 'Mingo',
61
36
  assistantType: 'mingo',
62
- batchApprovalsEnabled: true, // consumer sets this from their feature flag
63
- displayApprovalTypes: ['shell', 'file_write'],
37
+ batchApprovalsEnabled: true,
38
+ displayApprovalTypes: ['shell', 'file'],
64
39
  onApprove: async (requestId) => {
65
- await fetch(`/api/approvals/${requestId}/approve`, { method: 'POST' })
66
- },
67
- onReject: async (requestId) => {
68
- await fetch(`/api/approvals/${requestId}/reject`, { method: 'POST' })
40
+ await submitApproval(requestId)
69
41
  },
70
- }
71
-
72
- // Initialize accumulator state
73
- const state: AccumulatorState = {
74
- segments: [],
75
- pendingApprovals: new Map(),
76
- executingTools: new Map(),
42
+ onReject: (requestId) => {
43
+ logRejection(requestId)
44
+ }
77
45
  }
78
46
  ```
79
47
 
80
- **Source:** [`processing.types.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/processing.types.ts)
48
+ > NOTE: the wire-chunk vocabulary now lives in `src/chat-protocol/events.ts`
49
+ > (`ChatStreamEvent`, produced by `decodeNatsChunk`). The old
50
+ > `ParsedChunkAction` union and the `ChunkProcessor` contract were deleted
51
+ > together with the legacy `chunk-parser`.
@@ -1,4 +1,4 @@
1
- <!-- source-hash: cae6679d748353879069b316add2f081 -->
1
+ <!-- source-hash: c1ee0588313988b2559f2016a0a5d7cf -->
2
2
  Unified contract type definitions for the `useChat` hook's transport-agnostic return shape, shared by both the SSE (Guide mode) and NATS (Mingo mode) transport adapters.
3
3
 
4
4
  ## Key Components
@@ -9,7 +9,7 @@ Unified contract type definitions for the `useChat` hook's transport-agnostic re
9
9
  | `ChatConnectionState` | Type | Transport-level connection status: `'connected' \| 'connecting' \| 'disconnected'` |
10
10
  | `StreamingPhase` | Type | Granular streaming indicator: `'idle' \| 'thinking' \| 'streaming'` |
11
11
  | `UnifiedUsageBreakdown` | Interface | SSE-only sub-call token costs for the Haiku rewriter/classifier/summarizer pipeline |
12
- | `UnifiedChatMessage` | Interface | Transport-agnostic message shape; Guide-only fields (`sources`, `chatRefs`) are optional |
12
+ | `UnifiedChatMessage` | Interface | Transport-agnostic message shape; Guide-only fields (`sources`, `chatRefs`) are optional. `streamSeq` is not render input — it is the per-message coverage signal `mergeHistoryWithRealtime` decides with, and omitting it makes a mid-stream history refetch drop live bubbles |
13
13
  | `UnifiedSendMessageOptions` | Interface | Options accepted by `sendMessage` honoured by both transports |
14
14
  | `UnifiedChatState` | Interface | **Primary contract** — the full return shape both transport hooks must satisfy |
15
15
 
@@ -220,79 +220,12 @@ export interface RealtimeChunkCallbacks {
220
220
  onDialogClosed?: () => void
221
221
  }
222
222
 
223
- export interface UseRealtimeChunkProcessorOptions {
224
- callbacks: RealtimeChunkCallbacks
225
- /**
226
- * Filter approval types that should be displayed directly
227
- * Others will trigger onEscalatedApproval
228
- * Default: ['CLIENT']
229
- */
230
- displayApprovalTypes?: string[]
231
- /**
232
- * Map of existing approval statuses
233
- */
234
- approvalStatuses?: Record<string, ChatApprovalStatus>
235
- /**
236
- * Initialize accumulator with existing state from incomplete historical message
237
- * Used to continue building messages across page refreshes or reconnections
238
- */
239
- initialState?: {
240
- /** Existing segments to continue building upon */
241
- existingSegments?: MessageSegment[]
242
- /** Pending approvals that haven't been resolved */
243
- pendingApprovals?: Map<string, { command: string; explanation?: string; approvalType: string }>
244
- /** Executing tools waiting for completion */
245
- executingTools?: Map<string, ExecutingToolState>
246
- /** Escalated approvals */
247
- escalatedApprovals?: Map<
248
- string,
249
- { command: string; explanation?: string; approvalType: string; toolCalls?: PendingToolCallData[] }
250
- >
251
- }
252
- /**
253
- * Consumer-owned (e.g. set in `openframe-oss-tenant` chat client via the
254
- * `'batch-approvals'` feature flag and forwarded here). The lib does NOT
255
- * default this to a batch-on behavior — when omitted it falls back to the
256
- * legacy single-card rendering.
257
- *
258
- * When true: `APPROVAL_REQUEST` chunks containing `toolCalls[]` are rendered
259
- * as a single batch card. When false / omitted: the batch is split into N
260
- * legacy approval cards (one per tool that requires approval), all sharing
261
- * the same `approvalRequestId`. Tools with `requiresApproval=false` are
262
- * dropped from the UI in the unfolded mode.
263
- */
264
- batchApprovalsEnabled?: boolean
265
- /**
266
- * Engages the direct-mode barrier optimistically: once true, all AI-assistant
267
- * chunks (text, thinking, tool executions, approvals, metadata, errors, etc.)
268
- * are dropped and any open stream is torn down, leaving only human/control
269
- * messages. A `DIRECT_MESSAGE` chunk engages the same barrier automatically
270
- * regardless of this flag. Pass this from a host that already knows the dialog
271
- * switched to direct mode (e.g. an optimistic mode toggle) to close the race
272
- * window before the server emits the first `DIRECT_MESSAGE`.
273
- *
274
- * Do NOT set this when the host reconstructs history by replaying chunks
275
- * through `processChunk` — a static flag would drop legitimate pre-switch AI
276
- * history. Rely on the in-order `DIRECT_MESSAGE` detection instead.
277
- */
278
- isDirectMode?: boolean
279
- }
280
-
281
- export interface UseRealtimeChunkProcessorReturn {
282
- /** Process a single chunk */
283
- processChunk: (chunk: unknown) => void
284
- /** Get current segments */
285
- getSegments: () => MessageSegment[]
286
- /** Reset the accumulator */
287
- reset: () => void
288
- /** Update approval status for a request */
289
- updateApprovalStatus: (requestId: string, status: ChatApprovalStatus, resolvedByName?: string | null) => MessageSegment[]
290
- /** Get pending approval requests */
291
- getPendingApprovals: () => Map<
292
- string,
293
- { command: string; explanation?: string; approvalType: string; toolCalls?: PendingToolCallData[] }
294
- >
295
- }
223
+ // NOTE: `UseRealtimeChunkProcessorOptions` / `UseRealtimeChunkProcessorReturn`
224
+ // were DELETED along with the `useRealtimeChunkProcessor` compat hook. The
225
+ // equivalents are `ChatStreamReducerOptions` + `ChatStreamReducer` in
226
+ // `../stream/chat-stream-reducer`. `RealtimeChunkCallbacks` above SURVIVES:
227
+ // it is still the canonical description of the effect names/args the reducer
228
+ // emits via `ChatReducerEffect`.
296
229
 
297
230
  // ========== API Request Types ==========
298
231
 
@@ -3,38 +3,14 @@
3
3
  * Contains types for message parsing, accumulation, and processing
4
4
  */
5
5
 
6
- import type { MessageSegment, ProcessedMessage, ToolExecutionSegment, TokenUsageData, PendingToolCallData, ExecutingToolState } from './message.types'
6
+ import type { MessageSegment, PendingToolCallData, ExecutingToolState } from './message.types'
7
7
  import type { ChatApprovalStatus, AssistantType } from './chat.types'
8
- import type { ChunkData, NatsMessageType } from './network.types'
9
-
10
- // ========== Parsed Chunk Result Types ==========
11
-
12
- export type ParsedChunkAction =
13
- | { action: 'message_start' }
14
- | { action: 'message_end' }
15
- | { action: 'error'; error: string; details?: string }
16
- | { action: 'metadata'; modelDisplayName: string; modelName: string; providerName: string; contextWindow: number }
17
- | { action: 'text'; text: string }
18
- | { action: 'thinking'; text: string }
19
- | { action: 'guide'; text: string }
20
- | { action: 'tool_execution'; segment: ToolExecutionSegment }
21
- | { action: 'approval_request'; requestId: string; command: string; explanation?: string; approvalType: string }
22
- | { action: 'approval_batch'; requestId: string; approvalType: string; toolCalls: PendingToolCallData[] }
23
- | { action: 'approval_result'; requestId: string; approved: boolean; approvalType: string; resolvedByName?: string | null }
24
- | {
25
- action: 'message_request'
26
- text: string
27
- ownerType?: string
28
- displayName?: string
29
- userId?: string
30
- contextItems?: Array<{ type: string; id: string }>
31
- }
32
- | { action: 'token_usage'; data: TokenUsageData }
33
- | { action: 'direct_message'; text: string; ownerType?: string; displayName?: string; userId?: string }
34
- | { action: 'system'; text: string }
35
- | { action: 'context_compaction_start' }
36
- | { action: 'context_compaction_end'; summary?: string }
37
- | { action: 'dialog_closed' }
8
+ import type { ChunkData } from './network.types'
9
+
10
+ // NOTE: the `ParsedChunkAction` union that used to live here was DELETED
11
+ // alongside the legacy `chunk-parser`. The wire → normalized-event
12
+ // vocabulary is now `ChatStreamEvent` in `src/chat-protocol/events.ts`,
13
+ // produced by `decodeNatsChunk`.
38
14
 
39
15
  // ========== Accumulator State ==========
40
16
 
@@ -82,31 +58,13 @@ export interface MessageProcessingOptions {
82
58
  batchApprovalsEnabled?: boolean
83
59
  }
84
60
 
85
- // ========== Chunk Processing Types ==========
86
-
87
- export interface ChunkProcessor {
88
- processChunk: (chunk: ChunkData, messageType: NatsMessageType) => ParsedChunkAction | null
89
- reset: () => void
90
- }
91
-
92
- export interface ChunkProcessorOptions {
93
- onMessageStart?: () => void
94
- onMessageEnd?: () => void
95
- onError?: (error: string, details?: string) => void
96
- onText?: (text: string) => void
97
- onToolExecution?: (segment: MessageSegment) => void
98
- onApprovalRequest?: (data: any) => void
99
- onApprovalResult?: (data: any) => void
100
- onMetadata?: (data: any) => void
101
- }
61
+ // NOTE: `ChunkProcessorOptions` (the options bag of the deleted
62
+ // `ChunkProcessor`) and `MessageTransformer` were DELETED — both were left
63
+ // behind by the chunk-processor removal with zero references in lib, hub, or
64
+ // app.
102
65
 
103
66
  // ========== Message Transformation Types ==========
104
67
 
105
- export interface MessageTransformer {
106
- transform: (input: any) => ProcessedMessage | null
107
- batch: (inputs: any[]) => ProcessedMessage[]
108
- }
109
-
110
68
  export interface TransformationOptions {
111
69
  preserveOriginal?: boolean
112
70
  mergeSegments?: boolean
@@ -144,6 +144,22 @@ export interface UnifiedChatMessage {
144
144
  content: string
145
145
  segments?: MessageSegment[]
146
146
 
147
+ /**
148
+ * Highest chunk `streamSeq` consumed into THIS row. Not render input — it is
149
+ * the per-message coverage signal `mergeHistoryWithRealtime` decides with:
150
+ * a live synthetic is a twin of a persisted row only once history reaches
151
+ * its seq.
152
+ *
153
+ * Load-bearing, not bookkeeping. Without it the merge falls through to its
154
+ * wall-clock fallback ("created before the fetch instant ⇒ history has it"),
155
+ * which is wrong for every turn the backend has not finished persisting: a
156
+ * history refetch mid-stream then drops every live bubble except the single
157
+ * `streamingMessageId`, collapsing the thread to the persisted user prompt.
158
+ * The reducer stamps it on the rows it owns; hosts stamp the persisted value
159
+ * on history rows.
160
+ */
161
+ streamSeq?: number
162
+
147
163
  /**
148
164
  * Optional host-supplied message timestamp (creation/send time). Rendered
149
165
  * as the message-row time and, critically, fed into the memoized message's
@@ -1,4 +1,4 @@
1
- <!-- source-hash: d829899f7bd3695292f7399c706c0b38 -->
1
+ <!-- source-hash: 954138e90e8f1d0354f644a2df37cd43 -->
2
2
  Extracts incomplete message state from the last historical assistant message, enabling the realtime chunk processor to resume building messages across reconnected sessions.
3
3
 
4
4
  ## Key Components
@@ -10,17 +10,35 @@ Inspects a `ProcessedMessage` and returns resumable state if any in-progress seg
10
10
  **Parameters:**
11
11
  - `lastMessage` — A `ProcessedMessage` or `undefined`
12
12
 
13
- **Returns:** An object with optional `existingSegments`, `pendingApprovals`, and `executingTools`, or `undefined` if the message is complete or ineligible.
13
+ **Returns:** An object with optional `existingSegments`, `pendingApprovals`, `executingTools`, and `agentBusy`, or `undefined` if the message is complete or ineligible.
14
14
 
15
15
  **Incomplete state detection by segment type:**
16
16
 
17
17
  | Segment Type | Condition Flagged Incomplete |
18
18
  |---|---|
19
19
  | `tool_execution` | Status is `EXECUTING_TOOL` |
20
- | `approval_request` | Status is `pending` with a `requestId` |
20
+ | `approval_request` | Status is `pending` with a `requestId`, **or** `approved` as the trailing segment |
21
21
  | `approval_batch` | Not `rejected` and not all tool calls have `done` executions |
22
22
  | `context_compaction` | Status is `started` |
23
23
 
24
+ ### `agentBusy` — incomplete ≠ working
25
+
26
+ Unfinished says nothing about WHO the turn is waiting on, and only the activity
27
+ indicator's answer to that is user-visible. `agentBusy` is the second, narrower
28
+ question, derived here so every host answers it the same way (the reducer raises
29
+ `idle → thinking` off it on `initializeWithState`; callback-contract hosts fire
30
+ `onAgentBusy`). Nothing on the wire restores this after a reload: a run's
31
+ EXECUTING chunk is long past and its EXECUTED one may be minutes away.
32
+
33
+ | Tail state | Busy | Why |
34
+ |---|---|---|
35
+ | `EXECUTING_TOOL` with no result | ✅ | The tool is running now |
36
+ | `approval_batch` `approved`, calls outstanding | ✅ | Runs are recorded inside the batch, so `executingTools` is empty — gating on that map missed the whole approval path |
37
+ | `approval_request` `approved`, trailing | ✅ | A single request carries no execution record; work that followed it is the only "it came back" signal |
38
+ | `context_compaction` `started` | ✅ | Compaction is the agent's own work |
39
+ | Any approval still `pending` | ❌ | Blocked on the USER — spinning claims work that is not happening |
40
+ | `rejected` / `cancelled`, or all calls `done` | ❌ | Nothing outstanding |
41
+
24
42
  ## Usage Example
25
43
 
26
44
  ```typescript
@@ -1,4 +1,4 @@
1
- <!-- source-hash: 5df51000b55f2d031915f5b4412ac8e6 -->
1
+ <!-- source-hash: f5c3c4354e937c99e37f2acc47057b09 -->
2
2
  Reconciles persisted dialog history (processed GraphQL pages) with realtime messages accumulated from streaming chunks, preventing both duplicate and lost turns across MSP chat interfaces (Mingo, tickets, openframe-chat).
3
3
 
4
4
  ## Key Components
@@ -49,11 +49,17 @@ store.setMessages(merged)
49
49
 
50
50
  ```mermaid
51
51
  graph TD
52
- A[Synthetic message] --> B{"Per-row streamSeq\navailable?"}
53
- B -->|Yes| C{"Same-role history\nmax seq >= synthetic seq?"}
52
+ A[Synthetic message] --> B{"Synthetic carries\nits own streamSeq?"}
53
+ B -->|Yes| B2{"Any history row\nseq-stamped?"}
54
+ B2 -->|Yes| C{"Same-role history\nmax seq >= synthetic seq?"}
55
+ B2 -->|No| I{"Global\nhistoryMaxStreamSeq > 0?"}
54
56
  B -->|No| D{"Global seq\ncoverage known?"}
55
57
  C -->|Yes| E[Drop synthetic]
56
58
  C -->|No| F[Keep synthetic]
59
+ I -->|Yes| G2{"historyMaxStreamSeq\n>= synthetic seq?"}
60
+ I -->|No| F
61
+ G2 -->|Yes| E
62
+ G2 -->|No| F
57
63
  D -->|Yes| G{"historyMaxStreamSeq\n>= realtimeSeenSeq?"}
58
64
  D -->|No| H{"Created after\nhistoryFetchedAt?"}
59
65
  G -->|Yes| E
@@ -62,4 +68,39 @@ graph TD
62
68
  H -->|No| E
63
69
  ```
64
70
 
71
+ **A seq'd synthetic never falls back to wall-clock.** When nothing in history is
72
+ seq-stamped, `historyMaxStreamSeq === 0` is not "unknown, guess by clock" — it is
73
+ evidence that no persisted row has reached any seq, so the snapshot cannot
74
+ contain this turn. That case is the mid-stream refetch (a reconnect after the
75
+ window loses focus): the only persisted row of a turn in flight is the user
76
+ `MESSAGE_REQUEST`, which the backend does not stamp. Judging live bubbles by
77
+ wall-clock there read them all as "older than the fetch instant, therefore
78
+ persisted" and dropped every one except the single `streamingMessageId`,
79
+ collapsing the thread to the user's prompt.
80
+
81
+ This is why the reducer stamps `streamSeq` on the rows it owns — a live bubble
82
+ with no seq at all still lands in the wall-clock branch.
83
+
84
+ ## Turn identity (twins whose ids differ)
85
+
86
+ Keeping a live bubble is only half the job: history may hold its own PARTIAL
87
+ copy of the same in-flight turn, and then the turn renders twice with the two
88
+ copies disagreeing (a tool row `pending` in one, `failed` in the other) because
89
+ each stopped at a different chunk.
90
+
91
+ Ids do not help — they converge only through adoption, and adoption happens on a
92
+ REPLAY (a reload re-streams the turn into the persisted row). A refetch that
93
+ lands mid-stream has no replay, so the live copy keeps the synthetic id the
94
+ reducer minted.
95
+
96
+ `turnRequestKeys` supplies the missing identity: the backend's per-call request
97
+ ids (tool-call ids, approval request ids, batch ids) are carried by BOTH copies.
98
+ When history's trailing assistant shares one with a live assistant, they are the
99
+ same turn, and the trailing pin keeps the live copy if it is **streaming** (the
100
+ chunks are landing there, so history's snapshot is stale by construction) or
101
+ strictly richer. Once persistence catches up the live copy is no longer richer,
102
+ seq coverage drops it, and the persisted row wins — self-healing, no sticky
103
+ state. A turn that has produced only text yields no keys, which is treated as
104
+ "no signal", never as a match.
105
+
65
106
  > **Source:** [`history-merge.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/history-merge.ts)
@@ -1,57 +1,48 @@
1
- <!-- source-hash: 0435e7889d0ba1d3a5186507e28737c9 -->
2
- Barrel export module for the message processing utilities library, re-exporting all public APIs from specialized sub-modules covering chat message parsing, navigation, attachments, icons, and more.
1
+ <!-- source-hash: 85c0af6cd361347beeabcd097260378a -->
2
+ Barrel export module that consolidates and re-exports all message processing, chat navigation, UI styling, and content utility functions for chat interfaces.
3
3
 
4
4
  ## Key Components
5
5
 
6
- | Export Group | Source Module | Description |
7
- |---|---|---|
8
- | Chunk parsing | `chunk-parser` | Parse streaming chunks into actions, detect control/error/metadata chunks |
9
- | Segment accumulator | `message-segment-accumulator` | Accumulate streaming message segments with callbacks |
10
- | Historical messages | `process-historical-messages` | Process and reconcile chat history with error extraction |
11
- | History merge | `history-merge` | Reconcile persisted history with realtime stream data |
12
- | Navigation | `execute-navigation`, `nav-click-handler`, `decide-new-tab` | Unified navigation primitive for new-tab/same-tab, internal/external, embed/host routing |
13
- | Chat attachment | `chat-attachment-markdown` | Format and strip attachment markdown, URL/token helpers |
14
- | Icon registry | `icon-registry`, `icon-library`, `source-icons` | Single source of truth for icon-name → component lookups |
15
- | Proxy auth | `chat-proxy-auth-storage`, `chat-authed-fetch` | localStorage adapter and authenticated fetch wrapper |
16
- | Slash commands | `slash-dispatch-utils` | Command parsing, entity filtering, and dispatch utilities |
17
- | Compact card | `compact-card-classes` | Shared CSS class constants and safe-href guard |
18
- | Scripted stream | `scripted-stream` | Re-exported wholesale via `export *` |
6
+ | Category | Exports |
7
+ |----------|---------|
8
+ | **Message Accumulation** | `MessageSegmentAccumulator`, `createMessageSegmentAccumulator`, `AccumulatorCallbacks` |
9
+ | **Historical Messages** | `processHistoricalMessages`, `extractErrorMessages`, `processHistoricalMessagesWithErrors` |
10
+ | **Chat Navigation** | `handleChatNavClick`, `resolveExternalNavigation`, `decideNewTab`, `computeIsNewTab`, `buildAnchorProps` |
11
+ | **Proxy Auth** | `getChatProxyAuth`, `setChatProxyAuth`, `clearChatProxyAuth`, `applyProxyAuth`, `chatAuthedFetch` |
12
+ | **Attachments** | `formatChatAttachmentMarkdownForBubble`, `stripChatAttachmentMarkdown`, `buildChatAttachmentViewUrl` |
13
+ | **UI / Styling** | `chatChipClass`, compact card class constants (`COMPACT_CARD_*`), `getStatusColorScheme` |
14
+ | **Icon Registry** | `ICON_REGISTRY`, `getIconComponent`, `normalizeIconKey`, `getDynamicIcon` |
15
+ | **Source Utilities** | `getSourceIconName`, `getSourceLabel`, `resolveSourceRowCTA`, `resolveSourceIcon` |
16
+ | **Slash Commands** | `parseWireCommandOverride`, `sanitizeTitleForChat`, `buildDiscussAddendum` |
19
17
 
20
18
  ## Usage Example
21
19
 
22
20
  ```typescript
23
21
  import {
24
- parseChunkToAction,
25
22
  createMessageSegmentAccumulator,
26
- executeNavigation,
27
- resolveIcon,
28
- getStatusColorScheme,
29
- mergeHistoryWithRealtime,
23
+ handleChatNavClick,
24
+ getChatProxyAuth,
25
+ getIconComponent,
30
26
  formatChatAttachmentMarkdownForBubble,
31
- } from '@openframe/chat-utils'
32
-
33
- // Parse a streaming chunk
34
- const action = parseChunkToAction(rawChunk)
27
+ decideNewTab,
28
+ getStatusColorScheme,
29
+ } from '@flamingo/chat-utils'
35
30
 
36
- // Accumulate message segments from a stream
31
+ // Accumulate streamed message segments
37
32
  const accumulator = createMessageSegmentAccumulator({
38
- onSegmentComplete: (segment) => console.log('Segment done:', segment),
33
+ onSegmentComplete: (segment) => console.log('Segment:', segment),
39
34
  })
40
35
 
41
- // Execute navigation respecting new-tab rules
42
- executeNavigation({
43
- href: '/tickets/123',
44
- event: clickEvent,
45
- surface: 'chat',
36
+ // Resolve navigation target for a chat link
37
+ const { openInNewTab } = decideNewTab({
38
+ href: 'https://app.example.com/tickets/123',
39
+ surface: 'chat-bubble',
40
+ mode: 'web',
46
41
  })
47
42
 
48
- // Resolve an icon by name
49
- const Icon = resolveIcon('clickup')
50
-
51
- // Get agent status color scheme
52
- const colors = getStatusColorScheme('online')
53
- ```
54
-
55
- ## Source
43
+ // Look up a registered icon by kebab-case key
44
+ const Icon = getIconComponent('clickup')
56
45
 
57
- [`index.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/index.ts)
46
+ // Apply agent status color scheme to UI
47
+ const colors = getStatusColorScheme('running')
48
+ ```