@flamingo-stack/openframe-frontend-core 0.0.492-1506.3956.1 → 0.0.492

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 (296) hide show
  1. package/dist/{chunk-KX3K2EH4.cjs → chunk-2XAAFAQT.cjs} +11 -11
  2. package/dist/{chunk-KX3K2EH4.cjs.map → chunk-2XAAFAQT.cjs.map} +1 -1
  3. package/dist/{chunk-JHEIOXXZ.js → chunk-4AWRPTKE.js} +5 -6
  4. package/dist/chunk-4AWRPTKE.js.map +1 -0
  5. package/dist/{chunk-PTXZB2KW.js → chunk-4J3CB4KO.js} +2 -2
  6. package/dist/{chunk-7N7YZCHR.cjs → chunk-4MLOMMDX.cjs} +5519 -7555
  7. package/dist/chunk-4MLOMMDX.cjs.map +1 -0
  8. package/dist/{chunk-MEMRQTOI.js → chunk-56J7RLMM.js} +10434 -12470
  9. package/dist/chunk-56J7RLMM.js.map +1 -0
  10. package/dist/{chunk-MEIGDK7M.cjs → chunk-5ICPQAUI.cjs} +60 -60
  11. package/dist/chunk-5ICPQAUI.cjs.map +1 -0
  12. package/dist/{chunk-BEEPU44B.js → chunk-5RHJVPL7.js} +10 -10
  13. package/dist/chunk-5RHJVPL7.js.map +1 -0
  14. package/dist/{chunk-XOFE2RT4.js → chunk-BTIRYGDT.js} +4 -4
  15. package/dist/{chunk-JSEJ5MH5.cjs → chunk-DY6AJNVK.cjs} +5 -5
  16. package/dist/{chunk-JSEJ5MH5.cjs.map → chunk-DY6AJNVK.cjs.map} +1 -1
  17. package/dist/{chunk-PLB6CQSO.js → chunk-FG5ALORQ.js} +2 -2
  18. package/dist/{chunk-QG2EBIH5.cjs → chunk-J2J36PEN.cjs} +31 -31
  19. package/dist/{chunk-QG2EBIH5.cjs.map → chunk-J2J36PEN.cjs.map} +1 -1
  20. package/dist/{chunk-A6FPYAUD.cjs → chunk-LIRXKEOE.cjs} +15 -15
  21. package/dist/{chunk-A6FPYAUD.cjs.map → chunk-LIRXKEOE.cjs.map} +1 -1
  22. package/dist/{chunk-MSL5NE3N.cjs → chunk-LVDI7R7T.cjs} +37 -37
  23. package/dist/{chunk-MSL5NE3N.cjs.map → chunk-LVDI7R7T.cjs.map} +1 -1
  24. package/dist/{chunk-MPUQFRJG.cjs → chunk-M4SCYPCR.cjs} +7 -7
  25. package/dist/{chunk-MPUQFRJG.cjs.map → chunk-M4SCYPCR.cjs.map} +1 -1
  26. package/dist/{chunk-QDGB2DKY.cjs → chunk-O6S6Q52W.cjs} +26 -26
  27. package/dist/{chunk-QDGB2DKY.cjs.map → chunk-O6S6Q52W.cjs.map} +1 -1
  28. package/dist/{chunk-W56JYDSC.cjs → chunk-OFFYASUY.cjs} +27 -28
  29. package/dist/chunk-OFFYASUY.cjs.map +1 -0
  30. package/dist/{chunk-NCAN6VUF.js → chunk-P3ITKTUE.js} +2 -2
  31. package/dist/{chunk-M6FEGPQJ.cjs → chunk-PI5BMKV3.cjs} +62 -62
  32. package/dist/{chunk-M6FEGPQJ.cjs.map → chunk-PI5BMKV3.cjs.map} +1 -1
  33. package/dist/{chunk-34TDA22K.js → chunk-QHRNQTW5.js} +2 -2
  34. package/dist/{chunk-OL3MJKUI.js → chunk-SZWMJIH3.js} +2 -2
  35. package/dist/{chunk-MZRIRQYV.js → chunk-U5LU56JE.js} +2 -2
  36. package/dist/{chunk-C65NCIMV.cjs → chunk-VML66FJQ.cjs} +9 -9
  37. package/dist/{chunk-C65NCIMV.cjs.map → chunk-VML66FJQ.cjs.map} +1 -1
  38. package/dist/{chunk-3LKB722U.js → chunk-WKWZ7LVC.js} +2 -2
  39. package/dist/{chunk-J3VBVR4W.js → chunk-WPFLV4QJ.js} +4 -4
  40. package/dist/components/case-studies/index.cjs +8 -8
  41. package/dist/components/case-studies/index.js +2 -2
  42. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  43. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  44. package/dist/components/chat/hooks/index.d.ts +1 -0
  45. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  46. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  47. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +48 -15
  48. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  49. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +6 -0
  50. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +1 -0
  51. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +57 -10
  52. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  53. package/dist/components/chat/index.cjs +2 -10
  54. package/dist/components/chat/index.cjs.map +1 -1
  55. package/dist/components/chat/index.d.ts +0 -1
  56. package/dist/components/chat/index.d.ts.map +1 -1
  57. package/dist/components/chat/index.js +13 -21
  58. package/dist/components/chat/types/api.types.d.ts +81 -1
  59. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  60. package/dist/components/chat/types/processing.types.d.ts +93 -2
  61. package/dist/components/chat/types/processing.types.d.ts.map +1 -1
  62. package/dist/components/chat/utils/chunk-parser.d.ts +25 -0
  63. package/dist/components/chat/utils/chunk-parser.d.ts.map +1 -0
  64. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +6 -34
  65. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
  66. package/dist/components/chat/utils/index.d.ts +3 -2
  67. package/dist/components/chat/utils/index.d.ts.map +1 -1
  68. package/dist/components/chat/utils/process-historical-messages.d.ts +11 -59
  69. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  70. package/dist/components/contact/index.cjs +3 -3
  71. package/dist/components/contact/index.js +2 -2
  72. package/dist/components/docs/index.cjs +5 -5
  73. package/dist/components/docs/index.js +4 -4
  74. package/dist/components/embeds/index.cjs +3 -3
  75. package/dist/components/embeds/index.js +2 -2
  76. package/dist/components/faq/index.cjs +3 -3
  77. package/dist/components/faq/index.js +2 -2
  78. package/dist/components/features/floating-walkthrough-video.d.ts.map +1 -1
  79. package/dist/components/features/index.cjs +2 -2
  80. package/dist/components/features/index.js +1 -1
  81. package/dist/components/help-center-pages/index.cjs +20 -20
  82. package/dist/components/help-center-pages/index.js +11 -11
  83. package/dist/components/index.cjs +130 -172
  84. package/dist/components/index.cjs.map +1 -1
  85. package/dist/components/index.js +21 -63
  86. package/dist/components/index.js.map +1 -1
  87. package/dist/components/navigation/index.cjs +2 -2
  88. package/dist/components/navigation/index.js +1 -1
  89. package/dist/components/navigation/navigation-sidebar-item.d.ts +23 -1
  90. package/dist/components/navigation/navigation-sidebar-item.d.ts.map +1 -1
  91. package/dist/components/navigation/navigation-sidebar.d.ts.map +1 -1
  92. package/dist/components/onboarding-guides/index.cjs +5 -5
  93. package/dist/components/onboarding-guides/index.js +4 -4
  94. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  95. package/dist/components/related-content/index.cjs +3 -3
  96. package/dist/components/related-content/index.js +2 -2
  97. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  98. package/dist/components/tickets/index.cjs +5 -5
  99. package/dist/components/tickets/index.js +4 -4
  100. package/dist/components/ui/data-table/data-table-column-filter.d.ts.map +1 -1
  101. package/dist/components/ui/data-table/data-table-header.d.ts.map +1 -1
  102. package/dist/components/ui/data-table/data-table-skeleton.d.ts.map +1 -1
  103. package/dist/components/ui/index.cjs +2 -44
  104. package/dist/components/ui/index.cjs.map +1 -1
  105. package/dist/components/ui/index.d.ts +2 -1
  106. package/dist/components/ui/index.d.ts.map +1 -1
  107. package/dist/components/ui/index.js +13 -55
  108. package/dist/components/ui/rich-markdown-renderer.d.ts +34 -0
  109. package/dist/components/ui/rich-markdown-renderer.d.ts.map +1 -0
  110. package/dist/components/ui/simple-markdown-renderer.d.ts +73 -0
  111. package/dist/components/ui/simple-markdown-renderer.d.ts.map +1 -0
  112. package/dist/components/ui/tab-navigation.d.ts.map +1 -1
  113. package/dist/index.cjs +2 -60
  114. package/dist/index.cjs.map +1 -1
  115. package/dist/index.js +13 -71
  116. package/dist/utils/index.cjs +40 -169
  117. package/dist/utils/index.cjs.map +1 -1
  118. package/dist/utils/index.d.ts +0 -1
  119. package/dist/utils/index.d.ts.map +1 -1
  120. package/dist/utils/index.js +41 -162
  121. package/dist/utils/index.js.map +1 -1
  122. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  123. package/package.json +1 -7
  124. package/src/components/chat/__tests__/chat-message-list.test.tsx +5 -293
  125. package/src/components/chat/chat-message-enhanced.tsx +20 -122
  126. package/src/components/chat/chat-message-list.tsx +109 -358
  127. package/src/components/chat/embeddable-chat.tsx +0 -6
  128. package/src/components/chat/hooks/.index.md +33 -30
  129. package/src/components/chat/hooks/.use-nats-chat-adapter.md +55 -36
  130. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +77 -0
  131. package/src/components/chat/hooks/index.ts +1 -0
  132. package/src/components/chat/hooks/use-chat.ts +0 -8
  133. package/src/components/chat/hooks/use-nats-chat-adapter.ts +825 -243
  134. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +489 -0
  135. package/src/components/chat/hooks/use-sse-chat-adapter.ts +684 -380
  136. package/src/components/chat/index.ts +0 -5
  137. package/src/components/chat/thinking-display.tsx +1 -1
  138. package/src/components/chat/types/.api.types.md +49 -39
  139. package/src/components/chat/types/.processing.types.md +58 -29
  140. package/src/components/chat/types/api.types.ts +73 -6
  141. package/src/components/chat/types/processing.types.ts +53 -11
  142. package/src/components/chat/utils/.chunk-parser.md +62 -0
  143. package/src/components/chat/utils/.index.md +40 -31
  144. package/src/components/chat/utils/chunk-parser.ts +262 -0
  145. package/src/components/chat/utils/extract-incomplete-message-state.ts +5 -63
  146. package/src/components/chat/utils/index.ts +8 -5
  147. package/src/components/chat/utils/process-historical-messages.ts +386 -358
  148. package/src/components/features/floating-walkthrough-video.tsx +3 -1
  149. package/src/components/navigation/navigation-sidebar-item.tsx +80 -30
  150. package/src/components/navigation/navigation-sidebar.tsx +106 -46
  151. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +4 -22
  152. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  153. package/src/components/shared/product-release/release-detail-page.tsx +4 -19
  154. package/src/components/ui/.simple-markdown-renderer.md +52 -0
  155. package/src/components/ui/__tests__/tab-navigation.test.tsx +159 -0
  156. package/src/components/ui/data-table/data-table-column-filter.tsx +7 -1
  157. package/src/components/ui/data-table/data-table-header.tsx +4 -1
  158. package/src/components/ui/data-table/data-table-skeleton.tsx +7 -0
  159. package/src/components/ui/index.ts +2 -1
  160. package/src/components/ui/release-changelog-section.tsx +1 -1
  161. package/src/components/ui/rich-markdown-renderer.tsx +1223 -0
  162. package/src/components/ui/simple-markdown-renderer.tsx +964 -0
  163. package/src/components/ui/tab-navigation.tsx +370 -171
  164. package/src/components/ui/ticket-info-section.tsx +1 -1
  165. package/src/utils/index.ts +0 -1
  166. package/src/utils/markdown-section-extractor.ts +56 -41
  167. package/dist/chat-protocol/decode.d.ts +0 -58
  168. package/dist/chat-protocol/decode.d.ts.map +0 -1
  169. package/dist/chat-protocol/encode.d.ts +0 -44
  170. package/dist/chat-protocol/encode.d.ts.map +0 -1
  171. package/dist/chat-protocol/env-flag.d.ts +0 -35
  172. package/dist/chat-protocol/env-flag.d.ts.map +0 -1
  173. package/dist/chat-protocol/events.d.ts +0 -207
  174. package/dist/chat-protocol/events.d.ts.map +0 -1
  175. package/dist/chat-protocol/frames.d.ts +0 -213
  176. package/dist/chat-protocol/frames.d.ts.map +0 -1
  177. package/dist/chat-protocol/index.cjs +0 -500
  178. package/dist/chat-protocol/index.cjs.map +0 -1
  179. package/dist/chat-protocol/index.d.ts +0 -18
  180. package/dist/chat-protocol/index.d.ts.map +0 -1
  181. package/dist/chat-protocol/index.js +0 -484
  182. package/dist/chat-protocol/index.js.map +0 -1
  183. package/dist/chat-protocol/ip-normalize.d.ts +0 -44
  184. package/dist/chat-protocol/ip-normalize.d.ts.map +0 -1
  185. package/dist/chat-protocol/nats-decoder.d.ts +0 -26
  186. package/dist/chat-protocol/nats-decoder.d.ts.map +0 -1
  187. package/dist/chunk-7N7YZCHR.cjs.map +0 -1
  188. package/dist/chunk-BEEPU44B.js.map +0 -1
  189. package/dist/chunk-JHEIOXXZ.js.map +0 -1
  190. package/dist/chunk-MEIGDK7M.cjs.map +0 -1
  191. package/dist/chunk-MEMRQTOI.js.map +0 -1
  192. package/dist/chunk-W56JYDSC.cjs.map +0 -1
  193. package/dist/components/chat/stream/chat-dialog-store.d.ts +0 -184
  194. package/dist/components/chat/stream/chat-dialog-store.d.ts.map +0 -1
  195. package/dist/components/chat/stream/chat-stream-reducer.d.ts +0 -367
  196. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +0 -1
  197. package/dist/components/chat/stream/delta-batcher.d.ts +0 -51
  198. package/dist/components/chat/stream/delta-batcher.d.ts.map +0 -1
  199. package/dist/components/chat/stream/index.d.ts +0 -17
  200. package/dist/components/chat/stream/index.d.ts.map +0 -1
  201. package/dist/components/chat/stream/message-mutations.d.ts +0 -77
  202. package/dist/components/chat/stream/message-mutations.d.ts.map +0 -1
  203. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +0 -22
  204. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +0 -1
  205. package/dist/components/ui/markdown/base-components.d.ts +0 -51
  206. package/dist/components/ui/markdown/base-components.d.ts.map +0 -1
  207. package/dist/components/ui/markdown/engine.d.ts +0 -99
  208. package/dist/components/ui/markdown/engine.d.ts.map +0 -1
  209. package/dist/components/ui/markdown/heading-ids.d.ts +0 -65
  210. package/dist/components/ui/markdown/heading-ids.d.ts.map +0 -1
  211. package/dist/components/ui/markdown/index.d.ts +0 -18
  212. package/dist/components/ui/markdown/index.d.ts.map +0 -1
  213. package/dist/components/ui/markdown/mermaid-diagram.d.ts +0 -79
  214. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +0 -1
  215. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +0 -14
  216. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +0 -1
  217. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +0 -40
  218. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +0 -1
  219. package/dist/components/ui/markdown/rich/shortcodes.d.ts +0 -8
  220. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +0 -1
  221. package/dist/components/ui/markdown/sanitize.d.ts +0 -153
  222. package/dist/components/ui/markdown/sanitize.d.ts.map +0 -1
  223. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +0 -23
  224. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +0 -1
  225. package/dist/components/ui/markdown/streaming.d.ts +0 -78
  226. package/dist/components/ui/markdown/streaming.d.ts.map +0 -1
  227. package/dist/components/ui/markdown/text-size.d.ts +0 -34
  228. package/dist/components/ui/markdown/text-size.d.ts.map +0 -1
  229. package/dist/utils/markdown-fences.d.ts +0 -42
  230. package/dist/utils/markdown-fences.d.ts.map +0 -1
  231. package/dist/utils/markdown-heading-id.d.ts +0 -85
  232. package/dist/utils/markdown-heading-id.d.ts.map +0 -1
  233. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +0 -317
  234. package/src/chat-protocol/__tests__/chat-protocol.test.ts +0 -516
  235. package/src/chat-protocol/__tests__/env-flag.test.ts +0 -52
  236. package/src/chat-protocol/__tests__/ip-normalize.test.ts +0 -136
  237. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +0 -232
  238. package/src/chat-protocol/decode.ts +0 -278
  239. package/src/chat-protocol/encode.ts +0 -71
  240. package/src/chat-protocol/env-flag.ts +0 -39
  241. package/src/chat-protocol/events.ts +0 -245
  242. package/src/chat-protocol/frames.ts +0 -245
  243. package/src/chat-protocol/index.ts +0 -21
  244. package/src/chat-protocol/ip-normalize.ts +0 -146
  245. package/src/chat-protocol/nats-decoder.ts +0 -258
  246. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +0 -207
  247. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +0 -230
  248. package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +0 -37
  249. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  250. package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +0 -438
  251. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +0 -318
  252. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +0 -940
  253. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +0 -756
  254. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +0 -460
  255. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +0 -973
  256. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +0 -255
  257. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +0 -98
  258. package/src/components/chat/stream/chat-dialog-store.ts +0 -536
  259. package/src/components/chat/stream/chat-stream-reducer.ts +0 -1808
  260. package/src/components/chat/stream/delta-batcher.ts +0 -168
  261. package/src/components/chat/stream/index.ts +0 -55
  262. package/src/components/chat/stream/message-mutations.ts +0 -340
  263. package/src/components/chat/stream/use-chat-stream-reducer.ts +0 -126
  264. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +0 -420
  265. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +0 -605
  266. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +0 -394
  267. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +0 -270
  268. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +0 -2420
  269. package/src/components/ui/__tests__/markdown-parity.test.tsx +0 -2528
  270. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +0 -115
  271. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +0 -95
  272. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +0 -309
  273. package/src/components/ui/markdown/__tests__/streaming.test.tsx +0 -388
  274. package/src/components/ui/markdown/base-components.tsx +0 -360
  275. package/src/components/ui/markdown/engine.tsx +0 -315
  276. package/src/components/ui/markdown/heading-ids.ts +0 -239
  277. package/src/components/ui/markdown/index.ts +0 -49
  278. package/src/components/ui/markdown/mermaid-diagram.tsx +0 -291
  279. package/src/components/ui/markdown/rich/embed-overrides.tsx +0 -199
  280. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +0 -184
  281. package/src/components/ui/markdown/rich/shortcodes.ts +0 -170
  282. package/src/components/ui/markdown/sanitize.ts +0 -3499
  283. package/src/components/ui/markdown/simple-markdown-renderer.tsx +0 -28
  284. package/src/components/ui/markdown/streaming.ts +0 -362
  285. package/src/components/ui/markdown/text-size.ts +0 -106
  286. package/src/utils/markdown-fences.ts +0 -127
  287. package/src/utils/markdown-heading-id.ts +0 -348
  288. /package/dist/{chunk-PTXZB2KW.js.map → chunk-4J3CB4KO.js.map} +0 -0
  289. /package/dist/{chunk-XOFE2RT4.js.map → chunk-BTIRYGDT.js.map} +0 -0
  290. /package/dist/{chunk-PLB6CQSO.js.map → chunk-FG5ALORQ.js.map} +0 -0
  291. /package/dist/{chunk-NCAN6VUF.js.map → chunk-P3ITKTUE.js.map} +0 -0
  292. /package/dist/{chunk-34TDA22K.js.map → chunk-QHRNQTW5.js.map} +0 -0
  293. /package/dist/{chunk-OL3MJKUI.js.map → chunk-SZWMJIH3.js.map} +0 -0
  294. /package/dist/{chunk-MZRIRQYV.js.map → chunk-U5LU56JE.js.map} +0 -0
  295. /package/dist/{chunk-3LKB722U.js.map → chunk-WKWZ7LVC.js.map} +0 -0
  296. /package/dist/{chunk-J3VBVR4W.js.map → chunk-WPFLV4QJ.js.map} +0 -0
@@ -1,230 +0,0 @@
1
- /**
2
- * Pending-turn + hidden-row contracts.
3
- *
4
- * Two reader-visible defects this pins against:
5
- *
6
- * 1. Approving a tool call minted an author-label row with NO body
7
- * ("Michael Assraf:" then nothing). The approval decision is
8
- * out-of-band metadata, so the reducer must not materialize a user
9
- * row for it at all — fixing it at render would leave dead state.
10
- * 2. While the model was thinking, the transcript showed a second,
11
- * empty "Mingo:" row ABOVE the footer progress indicator — two
12
- * owners for one pending turn, and an `aria-live` log announcing a
13
- * bare "Mingo". Exactly one affordance must be present.
14
- *
15
- * Plus the two idioms that must SURVIVE both fixes: a hidden row that
16
- * carries real text (auto-continuation directive) stays in state while
17
- * never rendering, and the SYSTEM name-only row still renders.
18
- */
19
-
20
- import { render } from '@testing-library/react'
21
- import { describe, expect, it, vi } from 'vitest'
22
- import { createChatStreamReducer } from '../stream/chat-stream-reducer'
23
- import {
24
- AUTO_CONTINUATION_DIRECTIVE_PREFIX,
25
- buildAutoContinuationDirective,
26
- } from '../utils/auto-continuation-directive'
27
- import type { Message } from '../types/message.types'
28
-
29
- // ─── Render harness (mirrors chat-message-list.test.tsx) ────────────────────
30
-
31
- const scrollToBottom = vi.fn()
32
- const stopScroll = vi.fn()
33
-
34
- function makeRef() {
35
- const fn = ((el: HTMLElement | null) => {
36
- ;(fn as { current: HTMLElement | null }).current = el
37
- }) as ((el: HTMLElement | null) => void) & { current: HTMLElement | null }
38
- fn.current = null
39
- return fn
40
- }
41
-
42
- vi.mock('use-stick-to-bottom', () => ({
43
- useStickToBottom: () => ({
44
- scrollRef: makeRef(),
45
- contentRef: makeRef(),
46
- scrollToBottom,
47
- stopScroll,
48
- }),
49
- }))
50
-
51
- // Row stub that renders the author label the way the real component does
52
- // (`Name:`), so "labeled row with no body" is directly assertable.
53
- vi.mock('../chat-message-enhanced', () => ({
54
- ChatMessageEnhanced: ({ name, content }: { name?: string; content: unknown }) => (
55
- <div data-testid="row">
56
- <span data-testid="row-name">{name ?? ''}</span>
57
- <span data-testid="row-body">
58
- {typeof content === 'string'
59
- ? content
60
- : Array.isArray(content)
61
- ? content
62
- .map((s) => (s && (s as { type?: string }).type === 'text' ? (s as { text: string }).text : '[seg]'))
63
- .join('')
64
- : ''}
65
- </span>
66
- </div>
67
- ),
68
- }))
69
-
70
- import { ChatMessageList } from '../chat-message-list'
71
-
72
- class ObserverStub {
73
- observe() {}
74
- unobserve() {}
75
- disconnect() {}
76
- }
77
- vi.stubGlobal('IntersectionObserver', ObserverStub)
78
- vi.stubGlobal('ResizeObserver', ObserverStub)
79
-
80
- const names = (c: HTMLElement) =>
81
- Array.from(c.querySelectorAll('[data-testid="row-name"]')).map((n) => n.textContent)
82
- const bodies = (c: HTMLElement) =>
83
- Array.from(c.querySelectorAll('[data-testid="row-body"]')).map((n) => n.textContent)
84
-
85
- // ─── State-level contracts ─────────────────────────────────────────────────
86
-
87
- describe('approval sends mint no visible user row', () => {
88
- it('beginSseSend with empty text pushes only the assistant placeholder', () => {
89
- const r = createChatStreamReducer({ transport: 'sse' })
90
- // What `cardApprove` triggers: ('', { hidden: true, approvalAction }).
91
- r.beginSseSend({ text: '', hidden: true, assistantName: 'Mingo AI' })
92
-
93
- expect(r.state.messages).toHaveLength(1)
94
- expect(r.state.messages[0].role).toBe('assistant')
95
- expect(r.state.messages.some((m) => m.role === 'user')).toBe(false)
96
- expect(r.state.streamingPhase).toBe('thinking')
97
- })
98
-
99
- it('pushOptimisticSend with empty text likewise mints no user row', () => {
100
- const r = createChatStreamReducer({ transport: 'nats' })
101
- r.pushOptimisticSend('', true)
102
-
103
- expect(r.state.messages).toHaveLength(1)
104
- expect(r.state.messages[0].role).toBe('assistant')
105
- })
106
-
107
- it('a normal send still mints the user row', () => {
108
- const r = createChatStreamReducer({ transport: 'sse' })
109
- r.beginSseSend({ text: 'hello', assistantName: 'Mingo AI' })
110
-
111
- expect(r.state.messages).toHaveLength(2)
112
- expect(r.state.messages[0]).toMatchObject({ role: 'user', content: 'hello' })
113
- expect(r.state.messages[0].hidden).toBeUndefined()
114
- })
115
- })
116
-
117
- describe('hidden rows that carry text', () => {
118
- it('an auto-continuation directive IS state (the model sees it) but is flagged hidden', () => {
119
- const directive = buildAutoContinuationDirective('create_ticket', { ticketId: '42' })
120
- expect(directive.startsWith(AUTO_CONTINUATION_DIRECTIVE_PREFIX)).toBe(true)
121
-
122
- const r = createChatStreamReducer({ transport: 'sse' })
123
- r.beginSseSend({ text: directive, hidden: true, assistantName: 'Mingo AI' })
124
-
125
- const userRow = r.state.messages.find((m) => m.role === 'user')
126
- expect(userRow?.content).toBe(directive)
127
- expect(userRow?.hidden).toBe(true)
128
- })
129
-
130
- it('never renders — the raw directive text must not reach the transcript', () => {
131
- const directive = buildAutoContinuationDirective('create_ticket', { ticketId: '42' })
132
- const messages: Message[] = [
133
- { id: 'u1', role: 'user', name: 'Michael Assraf', content: 'my laptop is dead' },
134
- { id: 'h1', role: 'user', name: 'Michael Assraf', content: directive, hidden: true },
135
- { id: 'a1', role: 'assistant', name: 'Mingo', content: 'Opened a ticket.' },
136
- ]
137
- const { container } = render(<ChatMessageList dialogId="d" messages={messages} />)
138
-
139
- expect(container.textContent).not.toContain(AUTO_CONTINUATION_DIRECTIVE_PREFIX)
140
- expect(bodies(container)).toEqual(['my laptop is dead', 'Opened a ticket.'])
141
- })
142
- })
143
-
144
- // ─── Render-level contracts ────────────────────────────────────────────────
145
-
146
- describe('a thinking turn has exactly ONE pending affordance', () => {
147
- const pending: Message[] = [
148
- { id: 'u1', role: 'user', name: 'Michael Assraf', content: 'what is broken?' },
149
- { id: 'a1', role: 'assistant', name: 'Mingo', content: '', segments: [] },
150
- ]
151
-
152
- it('does not render the empty labeled assistant row while typing', () => {
153
- const { container } = render(
154
- <ChatMessageList dialogId="d" messages={pending} isTyping />,
155
- )
156
- // The bare "Mingo" label must be gone from the transcript entirely —
157
- // removed from the DOM, not visually hidden (the list is an aria-live
158
- // log; a zero-height node would still be announced).
159
- expect(names(container)).toEqual(['Michael Assraf'])
160
- expect(bodies(container)).toEqual(['what is broken?'])
161
- // …and the single remaining owner is the polite status indicator.
162
- expect(container.querySelectorAll('[role="status"]')).toHaveLength(1)
163
- })
164
-
165
- it('renders the assistant row as soon as it carries text', () => {
166
- const withText: Message[] = [
167
- pending[0],
168
- { id: 'a1', role: 'assistant', name: 'Mingo', content: [{ type: 'text', text: 'Chec' }] },
169
- ]
170
- const { container } = render(
171
- <ChatMessageList dialogId="d" messages={withText} isTyping />,
172
- )
173
- expect(names(container)).toEqual(['Michael Assraf', 'Mingo'])
174
- })
175
-
176
- it('renders the assistant row when it carries a NON-text segment (tool call)', () => {
177
- const withTool: Message[] = [
178
- pending[0],
179
- {
180
- id: 'a1',
181
- role: 'assistant',
182
- name: 'Mingo',
183
- content: [
184
- { type: 'tool_execution', toolExecutionRequestId: 'e1', status: 'executing' },
185
- ] as Message['content'],
186
- },
187
- ]
188
- const { container } = render(
189
- <ChatMessageList dialogId="d" messages={withTool} isTyping />,
190
- )
191
- expect(names(container)).toEqual(['Michael Assraf', 'Mingo'])
192
- })
193
-
194
- it('renders the assistant row when it carries ONLY a guide segment', () => {
195
- // A `guide` body is the whole visible answer for a how-to question. If
196
- // the empty-pending-turn predicate ever counted it as "nothing visible"
197
- // (e.g. by widening its text-only clause), a guide-only turn would render
198
- // NOTHING until the turn ended — the footer loader would be the sole
199
- // affordance while a fully-formed guide card sat in state.
200
- const withGuide: Message[] = [
201
- pending[0],
202
- {
203
- id: 'a1',
204
- role: 'assistant',
205
- name: 'Mingo',
206
- content: [{ type: 'guide', text: '## Enroll a device' }],
207
- },
208
- ]
209
- const { container } = render(
210
- <ChatMessageList dialogId="d" messages={withGuide} isTyping />,
211
- )
212
- expect(names(container)).toEqual(['Michael Assraf', 'Mingo'])
213
- })
214
-
215
- it('renders a completed empty-ish assistant row when NOT typing', () => {
216
- const { container } = render(<ChatMessageList dialogId="d" messages={pending} />)
217
- expect(names(container)).toEqual(['Michael Assraf', 'Mingo'])
218
- })
219
- })
220
-
221
- describe('the SYSTEM name-only row is a legitimate label-without-body', () => {
222
- it('still renders', () => {
223
- const messages: Message[] = [
224
- { id: 'u1', role: 'user', name: 'Michael Assraf', content: 'hi' },
225
- { id: 's1', role: 'user', name: 'Technician joined', content: '', authorType: 'system' },
226
- ]
227
- const { container } = render(<ChatMessageList dialogId="d" messages={messages} isTyping />)
228
- expect(names(container)).toContain('Technician joined')
229
- })
230
- })
@@ -1,37 +0,0 @@
1
- // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
-
3
- exports[`server-history hydration (materializes through the reducer) > rebuilds messages + sendIdx-keyed refs + send counter from the transcript 1`] = `
4
- [
5
- {
6
- "content": "open a ticket for the broken printer",
7
- "id": "hydrated-1",
8
- "role": "user",
9
- },
10
- {
11
- "chatRefs": {
12
- "ticket:77": {
13
- "id": "77",
14
- "metadata": {
15
- "status": "OPEN",
16
- },
17
- "title": "Broken printer",
18
- "type": "ticket",
19
- "url": null,
20
- },
21
- },
22
- "content": "✅ Approved — ticket created: [card://ticket:77]",
23
- "id": "hydrated-2",
24
- "role": "assistant",
25
- },
26
- {
27
- "content": "what is the pricing?",
28
- "id": "hydrated-3",
29
- "role": "user",
30
- },
31
- {
32
- "content": "Pricing starts at $99/month per site.",
33
- "id": "hydrated-4",
34
- "role": "assistant",
35
- },
36
- ]
37
- `;