@elabs-ai/components-ai 4.2.0 → 5.1.0

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 (462) hide show
  1. package/README.md +1 -1
  2. package/dist/{_audio-player-media-chrome-T3XVXWRZ.js → _audio-player-media-chrome.js} +1 -1
  3. package/dist/_code-block-theme.js +12 -0
  4. package/dist/_code-block-theme.js.map +1 -0
  5. package/dist/{_flow-boundary-SHNWLQG5.js → _flow-boundary.js} +1 -1
  6. package/dist/_flow-boundary.js.map +1 -0
  7. package/dist/_flow-lazy.js +8 -0
  8. package/dist/_flow-lazy.js.map +1 -0
  9. package/dist/_lazy-boundary-conformance.js +2 -0
  10. package/dist/_lazy-boundary-conformance.js.map +1 -0
  11. package/dist/_lazy-cjk.js +13 -0
  12. package/dist/_lazy-cjk.js.map +1 -0
  13. package/dist/_lazy-engine-boundary.js +9 -0
  14. package/dist/_lazy-engine-boundary.js.map +1 -0
  15. package/dist/_lazy-math.js +13 -0
  16. package/dist/_lazy-math.js.map +1 -0
  17. package/dist/_lazy-mermaid.js +12 -0
  18. package/dist/_lazy-mermaid.js.map +1 -0
  19. package/dist/_mermaid-error-panel.js +9 -0
  20. package/dist/_mermaid-error-panel.js.map +1 -0
  21. package/dist/{_persona-rive-JEG44YHX.js → _persona-rive.js} +19 -24
  22. package/dist/_persona-rive.js.map +1 -0
  23. package/dist/_streamdown-i18n.js +21 -0
  24. package/dist/_streamdown-i18n.js.map +1 -0
  25. package/dist/_streamdown-safety.js +10 -0
  26. package/dist/_streamdown-safety.js.map +1 -0
  27. package/dist/_theme-scope-store.js +13 -0
  28. package/dist/_theme-scope-store.js.map +1 -0
  29. package/dist/a2ui/a2ui-surface.js +17 -0
  30. package/dist/a2ui/a2ui-surface.js.map +1 -0
  31. package/dist/a2ui/core/catalog.generated.js +10 -0
  32. package/dist/a2ui/core/catalog.generated.js.map +1 -0
  33. package/dist/a2ui/core/complete-json.js +10 -0
  34. package/dist/a2ui/core/complete-json.js.map +1 -0
  35. package/dist/a2ui/core/index.js +37 -0
  36. package/dist/a2ui/core/index.js.map +1 -0
  37. package/dist/a2ui/core/schema.js +11 -0
  38. package/dist/a2ui/core/schema.js.map +1 -0
  39. package/dist/a2ui/core/spec.js +10 -0
  40. package/dist/a2ui/core/spec.js.map +1 -0
  41. package/dist/a2ui/core/validate.js +16 -0
  42. package/dist/a2ui/core/validate.js.map +1 -0
  43. package/dist/a2ui/index.js +54 -0
  44. package/dist/a2ui/index.js.map +1 -0
  45. package/dist/a2ui/ui-catalog.js +18 -0
  46. package/dist/a2ui/ui-catalog.js.map +1 -0
  47. package/dist/agent-event.js +10 -0
  48. package/dist/agent-event.js.map +1 -0
  49. package/dist/agent-timeline.js +11 -0
  50. package/dist/agent-timeline.js.map +1 -0
  51. package/dist/agent.js +25 -0
  52. package/dist/agent.js.map +1 -0
  53. package/dist/artifact.js +23 -0
  54. package/dist/artifact.js.map +1 -0
  55. package/dist/asset-preview.js +22 -0
  56. package/dist/asset-preview.js.map +1 -0
  57. package/dist/attachments.js +33 -0
  58. package/dist/attachments.js.map +1 -0
  59. package/dist/audio-player.js +30 -0
  60. package/dist/audio-player.js.map +1 -0
  61. package/dist/audio-visualizer.js +9 -0
  62. package/dist/audio-visualizer.js.map +1 -0
  63. package/dist/canvas.js +10 -0
  64. package/dist/canvas.js.map +1 -0
  65. package/dist/chain-of-thought.js +22 -0
  66. package/dist/chain-of-thought.js.map +1 -0
  67. package/dist/chat-greeting.js +8 -0
  68. package/dist/chat-greeting.js.map +1 -0
  69. package/dist/chat-shell.js +9 -0
  70. package/dist/chat-shell.js.map +1 -0
  71. package/dist/checkpoint.js +13 -0
  72. package/dist/checkpoint.js.map +1 -0
  73. package/dist/chunk-2XOIG5TG.js +72 -0
  74. package/dist/chunk-2XOIG5TG.js.map +1 -0
  75. package/dist/chunk-34CQ2VHM.js +172 -0
  76. package/dist/chunk-34CQ2VHM.js.map +1 -0
  77. package/dist/chunk-3TDHPXZZ.js +60 -0
  78. package/dist/chunk-3TDHPXZZ.js.map +1 -0
  79. package/dist/chunk-3XNPMDZY.js +478 -0
  80. package/dist/chunk-3XNPMDZY.js.map +1 -0
  81. package/dist/chunk-3YPT3V7L.js +56 -0
  82. package/dist/chunk-3YPT3V7L.js.map +1 -0
  83. package/dist/chunk-475UEU2Q.js +87 -0
  84. package/dist/chunk-475UEU2Q.js.map +1 -0
  85. package/dist/chunk-4CBTII2I.js +95 -0
  86. package/dist/chunk-4CBTII2I.js.map +1 -0
  87. package/dist/chunk-4XRNIZMG.js +22 -0
  88. package/dist/chunk-4XRNIZMG.js.map +1 -0
  89. package/dist/chunk-5NNWUKK5.js +2 -0
  90. package/dist/chunk-5NNWUKK5.js.map +1 -0
  91. package/dist/chunk-5UOMU27Z.js +164 -0
  92. package/dist/chunk-5UOMU27Z.js.map +1 -0
  93. package/dist/chunk-5VGYZ62I.js +264 -0
  94. package/dist/chunk-5VGYZ62I.js.map +1 -0
  95. package/dist/chunk-6IQPH2OS.js +21 -0
  96. package/dist/chunk-6IQPH2OS.js.map +1 -0
  97. package/dist/chunk-6PB2MXCI.js +482 -0
  98. package/dist/chunk-6PB2MXCI.js.map +1 -0
  99. package/dist/chunk-7FD5CZEU.js +215 -0
  100. package/dist/chunk-7FD5CZEU.js.map +1 -0
  101. package/dist/chunk-7RL6KZDF.js +266 -0
  102. package/dist/chunk-7RL6KZDF.js.map +1 -0
  103. package/dist/chunk-ADOYAGGK.js +482 -0
  104. package/dist/chunk-ADOYAGGK.js.map +1 -0
  105. package/dist/chunk-BA3AEMOU.js +21 -0
  106. package/dist/chunk-BA3AEMOU.js.map +1 -0
  107. package/dist/chunk-BBHFOYML.js +336 -0
  108. package/dist/chunk-BBHFOYML.js.map +1 -0
  109. package/dist/chunk-BHUVISIY.js +221 -0
  110. package/dist/chunk-BHUVISIY.js.map +1 -0
  111. package/dist/chunk-BM2LWERA.js +100 -0
  112. package/dist/chunk-BM2LWERA.js.map +1 -0
  113. package/dist/chunk-CMOYXNPJ.js +211 -0
  114. package/dist/chunk-CMOYXNPJ.js.map +1 -0
  115. package/dist/chunk-CZP3RHC4.js +74 -0
  116. package/dist/chunk-CZP3RHC4.js.map +1 -0
  117. package/dist/chunk-DDG5JHQT.js +112 -0
  118. package/dist/chunk-DDG5JHQT.js.map +1 -0
  119. package/dist/chunk-DJODXO7I.js +38 -0
  120. package/dist/chunk-DJODXO7I.js.map +1 -0
  121. package/dist/chunk-DWJDJLPU.js +192 -0
  122. package/dist/chunk-DWJDJLPU.js.map +1 -0
  123. package/dist/chunk-DZW6LM22.js +45 -0
  124. package/dist/chunk-DZW6LM22.js.map +1 -0
  125. package/dist/chunk-ELGCZLZF.js +305 -0
  126. package/dist/chunk-ELGCZLZF.js.map +1 -0
  127. package/dist/chunk-EV3U6ZZB.js +209 -0
  128. package/dist/chunk-EV3U6ZZB.js.map +1 -0
  129. package/dist/chunk-EY7LVUKQ.js +87 -0
  130. package/dist/chunk-EY7LVUKQ.js.map +1 -0
  131. package/dist/chunk-F4C74F7M.js +230 -0
  132. package/dist/chunk-F4C74F7M.js.map +1 -0
  133. package/dist/chunk-FERYDFZA.js +108 -0
  134. package/dist/chunk-FERYDFZA.js.map +1 -0
  135. package/dist/chunk-FUIYG2DS.js +166 -0
  136. package/dist/chunk-FUIYG2DS.js.map +1 -0
  137. package/dist/chunk-GA7M34KU.js +236 -0
  138. package/dist/chunk-GA7M34KU.js.map +1 -0
  139. package/dist/chunk-GKYZT3LA.js +136 -0
  140. package/dist/chunk-GKYZT3LA.js.map +1 -0
  141. package/dist/chunk-H42LRUQ4.js +102 -0
  142. package/dist/chunk-H42LRUQ4.js.map +1 -0
  143. package/dist/chunk-HVXM2G5F.js +222 -0
  144. package/dist/chunk-HVXM2G5F.js.map +1 -0
  145. package/dist/chunk-I4RDAGVY.js +53 -0
  146. package/dist/chunk-I4RDAGVY.js.map +1 -0
  147. package/dist/chunk-IQJG4IDX.js +208 -0
  148. package/dist/chunk-IQJG4IDX.js.map +1 -0
  149. package/dist/chunk-IX2PXG4Y.js +144 -0
  150. package/dist/chunk-IX2PXG4Y.js.map +1 -0
  151. package/dist/chunk-IXICSOOP.js +287 -0
  152. package/dist/chunk-IXICSOOP.js.map +1 -0
  153. package/dist/chunk-JY5HSN4D.js +84 -0
  154. package/dist/chunk-JY5HSN4D.js.map +1 -0
  155. package/dist/chunk-L4SU3QJV.js +174 -0
  156. package/dist/chunk-L4SU3QJV.js.map +1 -0
  157. package/dist/chunk-LMNSBOBG.js +19 -0
  158. package/dist/chunk-LMNSBOBG.js.map +1 -0
  159. package/dist/chunk-MBI7D6IL.js +42 -0
  160. package/dist/chunk-MBI7D6IL.js.map +1 -0
  161. package/dist/chunk-MLFMYCPH.js +192 -0
  162. package/dist/chunk-MLFMYCPH.js.map +1 -0
  163. package/dist/chunk-MOK66734.js +33 -0
  164. package/dist/chunk-MOK66734.js.map +1 -0
  165. package/dist/chunk-MXTAWPYM.js +196 -0
  166. package/dist/chunk-MXTAWPYM.js.map +1 -0
  167. package/dist/chunk-NCL2UZKI.js +96 -0
  168. package/dist/chunk-NCL2UZKI.js.map +1 -0
  169. package/dist/chunk-NET4YLRY.js +107 -0
  170. package/dist/chunk-NET4YLRY.js.map +1 -0
  171. package/dist/chunk-NIG67CFM.js +329 -0
  172. package/dist/chunk-NIG67CFM.js.map +1 -0
  173. package/dist/chunk-NMVNNO3L.js +10 -0
  174. package/dist/chunk-NMVNNO3L.js.map +1 -0
  175. package/dist/chunk-NP7VID4K.js +2 -0
  176. package/dist/chunk-NP7VID4K.js.map +1 -0
  177. package/dist/chunk-NPUCMAG2.js +382 -0
  178. package/dist/chunk-NPUCMAG2.js.map +1 -0
  179. package/dist/chunk-NSCLRHES.js +102 -0
  180. package/dist/chunk-NSCLRHES.js.map +1 -0
  181. package/dist/chunk-OEUXHVFW.js +86 -0
  182. package/dist/chunk-OEUXHVFW.js.map +1 -0
  183. package/dist/chunk-ONBHFIMZ.js +137 -0
  184. package/dist/chunk-ONBHFIMZ.js.map +1 -0
  185. package/dist/chunk-OPH2HHL2.js +228 -0
  186. package/dist/chunk-OPH2HHL2.js.map +1 -0
  187. package/dist/chunk-OQERHIQP.js +287 -0
  188. package/dist/chunk-OQERHIQP.js.map +1 -0
  189. package/dist/chunk-P6YJAZFG.js +103 -0
  190. package/dist/chunk-P6YJAZFG.js.map +1 -0
  191. package/dist/chunk-PG7ERDOD.js +65 -0
  192. package/dist/chunk-PG7ERDOD.js.map +1 -0
  193. package/dist/chunk-PIB5JBMA.js +90 -0
  194. package/dist/chunk-PIB5JBMA.js.map +1 -0
  195. package/dist/chunk-PQ5BPIWQ.js +22 -0
  196. package/dist/chunk-PQ5BPIWQ.js.map +1 -0
  197. package/dist/chunk-PQBF6ZIQ.js +55 -0
  198. package/dist/chunk-PQBF6ZIQ.js.map +1 -0
  199. package/dist/chunk-PTWCTSZL.js +173 -0
  200. package/dist/chunk-PTWCTSZL.js.map +1 -0
  201. package/dist/chunk-QJUNPVOS.js +101 -0
  202. package/dist/chunk-QJUNPVOS.js.map +1 -0
  203. package/dist/chunk-QOBSEGCG.js +996 -0
  204. package/dist/chunk-QOBSEGCG.js.map +1 -0
  205. package/dist/chunk-QUDZOTRV.js +43 -0
  206. package/dist/chunk-QUDZOTRV.js.map +1 -0
  207. package/dist/chunk-RB7G65JC.js +213 -0
  208. package/dist/chunk-RB7G65JC.js.map +1 -0
  209. package/dist/chunk-RPHAOR7P.js +45 -0
  210. package/dist/chunk-RPHAOR7P.js.map +1 -0
  211. package/dist/chunk-RTCSH2AN.js +331 -0
  212. package/dist/chunk-RTCSH2AN.js.map +1 -0
  213. package/dist/chunk-S3ISPW3A.js +28 -0
  214. package/dist/chunk-S3ISPW3A.js.map +1 -0
  215. package/dist/chunk-SEVN656N.js +36 -0
  216. package/dist/chunk-SEVN656N.js.map +1 -0
  217. package/dist/chunk-SKVG672B.js +64 -0
  218. package/dist/chunk-SKVG672B.js.map +1 -0
  219. package/dist/chunk-SSGJ6MEM.js +1076 -0
  220. package/dist/chunk-SSGJ6MEM.js.map +1 -0
  221. package/dist/chunk-SSKZ2AED.js +118 -0
  222. package/dist/chunk-SSKZ2AED.js.map +1 -0
  223. package/dist/chunk-T56JFGXI.js +561 -0
  224. package/dist/chunk-T56JFGXI.js.map +1 -0
  225. package/dist/chunk-TCB6O74A.js +137 -0
  226. package/dist/chunk-TCB6O74A.js.map +1 -0
  227. package/dist/chunk-TTEYPO6X.js +57 -0
  228. package/dist/chunk-TTEYPO6X.js.map +1 -0
  229. package/dist/chunk-TWPHAJNM.js +462 -0
  230. package/dist/chunk-TWPHAJNM.js.map +1 -0
  231. package/dist/chunk-TXJJLP4O.js +336 -0
  232. package/dist/chunk-TXJJLP4O.js.map +1 -0
  233. package/dist/chunk-TZ6TB7VM.js +245 -0
  234. package/dist/chunk-TZ6TB7VM.js.map +1 -0
  235. package/dist/chunk-UBLKJJ7K.js +278 -0
  236. package/dist/chunk-UBLKJJ7K.js.map +1 -0
  237. package/dist/chunk-UCJ6IUFS.js +52 -0
  238. package/dist/chunk-UCJ6IUFS.js.map +1 -0
  239. package/dist/chunk-UCKFJ3QF.js +197 -0
  240. package/dist/chunk-UCKFJ3QF.js.map +1 -0
  241. package/dist/chunk-UPXSLILN.js +20 -0
  242. package/dist/chunk-UPXSLILN.js.map +1 -0
  243. package/dist/chunk-V4DORGWJ.js +92 -0
  244. package/dist/chunk-V4DORGWJ.js.map +1 -0
  245. package/dist/chunk-V6E5DYZD.js +80 -0
  246. package/dist/chunk-V6E5DYZD.js.map +1 -0
  247. package/dist/chunk-VLLYKF3P.js +96 -0
  248. package/dist/chunk-VLLYKF3P.js.map +1 -0
  249. package/dist/chunk-VLNBTOH6.js +43 -0
  250. package/dist/chunk-VLNBTOH6.js.map +1 -0
  251. package/dist/chunk-WMDSMSPL.js +303 -0
  252. package/dist/chunk-WMDSMSPL.js.map +1 -0
  253. package/dist/chunk-WU5BLGTF.js +149 -0
  254. package/dist/chunk-WU5BLGTF.js.map +1 -0
  255. package/dist/chunk-WYTZVSGK.js +245 -0
  256. package/dist/chunk-WYTZVSGK.js.map +1 -0
  257. package/dist/chunk-X47QMM6K.js +187 -0
  258. package/dist/chunk-X47QMM6K.js.map +1 -0
  259. package/dist/chunk-YHUSW7D2.js +40 -0
  260. package/dist/chunk-YHUSW7D2.js.map +1 -0
  261. package/dist/chunk-YSKD7UXX.js +126 -0
  262. package/dist/chunk-YSKD7UXX.js.map +1 -0
  263. package/dist/chunk-YYRDGWOU.js +72 -0
  264. package/dist/chunk-YYRDGWOU.js.map +1 -0
  265. package/dist/chunk-ZIGZMWM7.js +19 -0
  266. package/dist/chunk-ZIGZMWM7.js.map +1 -0
  267. package/dist/chunk-ZKRTUKNP.js +40 -0
  268. package/dist/chunk-ZKRTUKNP.js.map +1 -0
  269. package/dist/code-block.js +38 -0
  270. package/dist/code-block.js.map +1 -0
  271. package/dist/commit.js +51 -0
  272. package/dist/commit.js.map +1 -0
  273. package/dist/composer.js +15 -0
  274. package/dist/composer.js.map +1 -0
  275. package/dist/confirmation.js +53 -0
  276. package/dist/confirmation.js.map +1 -0
  277. package/dist/connection.js +8 -0
  278. package/dist/connection.js.map +1 -0
  279. package/dist/context-panel.js +25 -0
  280. package/dist/context-panel.js.map +1 -0
  281. package/dist/controls.js +10 -0
  282. package/dist/controls.js.map +1 -0
  283. package/dist/conversation.js +19 -0
  284. package/dist/conversation.js.map +1 -0
  285. package/dist/diff-view.js +15 -0
  286. package/dist/diff-view.js.map +1 -0
  287. package/dist/edge.js +10 -0
  288. package/dist/edge.js.map +1 -0
  289. package/dist/environment-variables.js +29 -0
  290. package/dist/environment-variables.js.map +1 -0
  291. package/dist/file-tree.js +23 -0
  292. package/dist/file-tree.js.map +1 -0
  293. package/dist/gallery.js +9 -0
  294. package/dist/gallery.js.map +1 -0
  295. package/dist/grouped-parts.js +21 -0
  296. package/dist/grouped-parts.js.map +1 -0
  297. package/dist/image.js +9 -0
  298. package/dist/image.js.map +1 -0
  299. package/dist/index.d.ts +366 -98
  300. package/dist/index.js +672 -13577
  301. package/dist/index.js.map +1 -1
  302. package/dist/inline-citation.js +39 -0
  303. package/dist/inline-citation.js.map +1 -0
  304. package/dist/jsx-preview.js +17 -0
  305. package/dist/jsx-preview.js.map +1 -0
  306. package/dist/markdown-view.js +17 -0
  307. package/dist/markdown-view.js.map +1 -0
  308. package/dist/message-compare.js +12 -0
  309. package/dist/message-compare.js.map +1 -0
  310. package/dist/message-edit.js +19 -0
  311. package/dist/message-edit.js.map +1 -0
  312. package/dist/message-feedback.js +11 -0
  313. package/dist/message-feedback.js.map +1 -0
  314. package/dist/message-form-spec.js +38 -0
  315. package/dist/message-form-spec.js.map +1 -0
  316. package/dist/message-form.js +26 -0
  317. package/dist/message-form.js.map +1 -0
  318. package/dist/message-table-spec.js +26 -0
  319. package/dist/message-table-spec.js.map +1 -0
  320. package/dist/message-table.js +12 -0
  321. package/dist/message-table.js.map +1 -0
  322. package/dist/message.js +51 -0
  323. package/dist/message.js.map +1 -0
  324. package/dist/mic-selector.js +27 -0
  325. package/dist/mic-selector.js.map +1 -0
  326. package/dist/model-provider-logo.js +13 -0
  327. package/dist/model-provider-logo.js.map +1 -0
  328. package/dist/motion-config.js +9 -0
  329. package/dist/motion-config.js.map +1 -0
  330. package/dist/node.js +22 -0
  331. package/dist/node.js.map +1 -0
  332. package/dist/open-in-chat.js +31 -0
  333. package/dist/open-in-chat.js.map +1 -0
  334. package/dist/package-info.js +25 -0
  335. package/dist/package-info.js.map +1 -0
  336. package/dist/panel.js +10 -0
  337. package/dist/panel.js.map +1 -0
  338. package/dist/part-groups.js +18 -0
  339. package/dist/part-groups.js.map +1 -0
  340. package/dist/permission-mode-select.js +9 -0
  341. package/dist/permission-mode-select.js.map +1 -0
  342. package/dist/persona-sources.js +8 -0
  343. package/dist/persona-sources.js.map +1 -0
  344. package/dist/persona.js +14 -0
  345. package/dist/persona.js.map +1 -0
  346. package/dist/plan.js +32 -0
  347. package/dist/plan.js.map +1 -0
  348. package/dist/prompt-input-effort.js +9 -0
  349. package/dist/prompt-input-effort.js.map +1 -0
  350. package/dist/prompt-input-mode.js +10 -0
  351. package/dist/prompt-input-mode.js.map +1 -0
  352. package/dist/prompt-input-slash.js +12 -0
  353. package/dist/prompt-input-slash.js.map +1 -0
  354. package/dist/prompt-input.js +89 -0
  355. package/dist/prompt-input.js.map +1 -0
  356. package/dist/queue.js +37 -0
  357. package/dist/queue.js.map +1 -0
  358. package/dist/reasoning.js +23 -0
  359. package/dist/reasoning.js.map +1 -0
  360. package/dist/sandbox.js +28 -0
  361. package/dist/sandbox.js.map +1 -0
  362. package/dist/schema-display.js +33 -0
  363. package/dist/schema-display.js.map +1 -0
  364. package/dist/selection-toolbar.js +11 -0
  365. package/dist/selection-toolbar.js.map +1 -0
  366. package/dist/session-header.js +9 -0
  367. package/dist/session-header.js.map +1 -0
  368. package/dist/session-status-bar.js +9 -0
  369. package/dist/session-status-bar.js.map +1 -0
  370. package/dist/shimmer.js +9 -0
  371. package/dist/shimmer.js.map +1 -0
  372. package/dist/snippet.js +17 -0
  373. package/dist/snippet.js.map +1 -0
  374. package/dist/sources.js +17 -0
  375. package/dist/sources.js.map +1 -0
  376. package/dist/speech-input.js +9 -0
  377. package/dist/speech-input.js.map +1 -0
  378. package/dist/stack-trace.js +27 -0
  379. package/dist/stack-trace.js.map +1 -0
  380. package/dist/suggestion.js +16 -0
  381. package/dist/suggestion.js.map +1 -0
  382. package/dist/task.js +18 -0
  383. package/dist/task.js.map +1 -0
  384. package/dist/test-results.js +43 -0
  385. package/dist/test-results.js.map +1 -0
  386. package/dist/token-usage.js +27 -0
  387. package/dist/token-usage.js.map +1 -0
  388. package/dist/tool-result-card.js +9 -0
  389. package/dist/tool-result-card.js.map +1 -0
  390. package/dist/tool.js +27 -0
  391. package/dist/tool.js.map +1 -0
  392. package/dist/toolbar.js +10 -0
  393. package/dist/toolbar.js.map +1 -0
  394. package/dist/transcription.js +11 -0
  395. package/dist/transcription.js.map +1 -0
  396. package/dist/turn-status.js +9 -0
  397. package/dist/turn-status.js.map +1 -0
  398. package/dist/use-audio-level.js +9 -0
  399. package/dist/use-audio-level.js.map +1 -0
  400. package/dist/voice-selector.js +47 -0
  401. package/dist/voice-selector.js.map +1 -0
  402. package/dist/web-preview.js +19 -0
  403. package/dist/web-preview.js.map +1 -0
  404. package/package.json +11 -9
  405. package/schemas/a2ui-surface.v1.schema.json +5434 -0
  406. package/src/_chat-shell-rail.tsx +3 -1
  407. package/src/_flow-boundary.tsx +2 -2
  408. package/src/_persona-rive.tsx +27 -41
  409. package/src/a2ui/a2ui-surface.stories.tsx +662 -0
  410. package/src/a2ui/a2ui-surface.test.tsx +201 -0
  411. package/src/a2ui/a2ui-surface.tsx +354 -0
  412. package/src/a2ui/catalog.source.json +772 -0
  413. package/src/a2ui/core/a2ui-core.test.ts +178 -0
  414. package/src/a2ui/core/catalog.generated.ts +1019 -0
  415. package/src/a2ui/core/complete-json.ts +81 -0
  416. package/src/a2ui/core/index.ts +10 -0
  417. package/src/a2ui/core/schema.ts +111 -0
  418. package/src/a2ui/core/spec.ts +148 -0
  419. package/src/a2ui/core/validate.ts +266 -0
  420. package/src/a2ui/index.ts +7 -0
  421. package/src/a2ui/ui-catalog.tsx +225 -0
  422. package/src/a2ui/wave1-chart-spec.test.ts +87 -0
  423. package/src/a2ui/wave2-chart-spec.test.ts +108 -0
  424. package/src/agentic-workspace.stories.tsx +6 -45
  425. package/src/chat-shell.test.tsx +40 -10
  426. package/src/chat-shell.tsx +90 -44
  427. package/src/chat.stories.tsx +47 -42
  428. package/src/composer.stories.tsx +4 -5
  429. package/src/composer.test.tsx +45 -0
  430. package/src/composer.tsx +104 -21
  431. package/src/context-panel.stories.tsx +1 -1
  432. package/src/context-panel.tsx +1 -1
  433. package/src/conversation.stories.tsx +1 -0
  434. package/src/conversation.test.tsx +16 -0
  435. package/src/conversation.tsx +16 -2
  436. package/src/diff-view.stories.tsx +79 -0
  437. package/src/diff-view.tsx +3 -2
  438. package/src/file-tree.tsx +24 -17
  439. package/src/gallery.stories.tsx +42 -0
  440. package/src/gallery.tsx +2 -2
  441. package/src/grouped-parts.stories.tsx +23 -0
  442. package/src/grouped-parts.tsx +1 -1
  443. package/src/index.ts +1 -0
  444. package/src/message-compare.stories.tsx +40 -0
  445. package/src/message-compare.tsx +2 -1
  446. package/src/message-form.tsx +1 -1
  447. package/src/message-table.stories.tsx +24 -0
  448. package/src/message-table.tsx +1 -1
  449. package/src/package-info.tsx +12 -9
  450. package/src/reasoning.stories.tsx +27 -0
  451. package/src/reasoning.tsx +1 -1
  452. package/src/session-header.stories.tsx +35 -1
  453. package/src/session-header.tsx +1 -1
  454. package/src/sources.stories.tsx +30 -0
  455. package/src/sources.tsx +4 -1
  456. package/src/templates-ai-assistant.stories.tsx +151 -87
  457. package/src/tool.stories.tsx +39 -0
  458. package/src/tool.tsx +3 -3
  459. package/src/toolbar.tsx +0 -10
  460. package/dist/_flow-boundary-SHNWLQG5.js.map +0 -1
  461. package/dist/_persona-rive-JEG44YHX.js.map +0 -1
  462. /package/dist/{_audio-player-media-chrome-T3XVXWRZ.js.map → _audio-player-media-chrome.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/_lazy-math.ts"],"sourcesContent":["\"use client\";\n\n/**\n * Lazy-loaded replacement for `@streamdown/math`'s eager `math` export.\n *\n * Why this exists\n * ----------------\n * `@streamdown/math` bundles KaTeX (~600 KB unminified) plus `remark-math` and\n * `rehype-katex`. `useStreamdownPlugins()` (`_streamdown-i18n.ts`) used to\n * import it statically, so every consumer of `MessageResponse`/`MarkdownView`/\n * `ReasoningContent` paid for KaTeX in their entry chunk whether or not a\n * single conversation ever contains `$…$`.\n *\n * How it stays correct\n * ---------------------\n * Unlike Mermaid (`_lazy-mermaid.ts`), a remark/rehype `Pluggable` cannot be\n * wrapped in a lazy accessor: `remark-math`'s micromark extension has to be\n * registered on the unified processor BEFORE it parses, so there is no way to\n * hand Streamdown a present-but-deferred math plugin the way `DiagramPlugin`\n * defers its render. Instead:\n *\n * 1. `needsMathPlugin(text)` cheaply sniffs the RAW markdown source for `$…$`\n * / `\\(…\\)` / `\\[…\\]` delimiters — no parsing, just a regex.\n * 2. `useLazyMathPlugin(text)` returns `undefined` until that sniff is true,\n * at which point it kicks off `import(\"@streamdown/math\")` and returns the\n * loaded plugin once it resolves, triggering a re-render.\n *\n * The one user-visible cost: a message whose FIRST rendered chunk already\n * contains math delimiters shows literal `$x^2$` for one paint before the\n * import resolves (typically well under a frame from a warm cache, since the\n * chunk is tiny next to KaTeX's own parse/layout work). Every subsequent\n * message reuses the module-level cache and never re-pays it.\n */\nimport type { MathPlugin } from \"@streamdown/math\";\nimport { useEffect, useState } from \"react\";\n\n/** Cheap, over-inclusive sniff — a false positive just means an unneeded fetch. */\nconst MATH_DELIMITER_RE = /\\$\\$[\\s\\S]*?\\$\\$|\\$[^\\s$][^$\\n]*\\$|\\\\\\(|\\\\\\)|\\\\\\[|\\\\\\]/;\n\n/** Does `text` look like it contains LaTeX math delimiters? */\nexport function needsMathPlugin(text: string): boolean {\n return MATH_DELIMITER_RE.test(text);\n}\n\n/** Module-level singleton: the plugin (and its KaTeX bytes) load at most once. */\nlet cachedPlugin: MathPlugin | undefined;\nlet loadPromise: Promise<MathPlugin> | undefined;\n\nfunction loadMathPlugin(): Promise<MathPlugin> {\n loadPromise ??= import(\"@streamdown/math\").then((mod) => {\n cachedPlugin = mod.math;\n return cachedPlugin;\n });\n return loadPromise;\n}\n\n/**\n * Start fetching the math plugin ahead of time (e.g. once a conversation is\n * known to contain math, or on route entry). Optional; rendering math loads\n * it either way.\n */\nexport const preloadMath = (): void => {\n void loadMathPlugin();\n};\n\n/**\n * Returns the loaded `MathPlugin` once `text` needs one, else `undefined`\n * (Streamdown treats an absent `plugins.math` slot as \"no math support\" — the\n * delimiters render as literal text until the plugin arrives).\n */\nexport function useLazyMathPlugin(text: string): MathPlugin | undefined {\n const needed = needsMathPlugin(text);\n const [plugin, setPlugin] = useState<MathPlugin | undefined>(cachedPlugin);\n\n useEffect(() => {\n if (!needed || cachedPlugin) return;\n let cancelled = false;\n loadMathPlugin().then((loaded) => {\n if (!cancelled) setPlugin(loaded);\n });\n return () => {\n cancelled = true;\n };\n }, [needed]);\n\n if (!needed) return undefined;\n // `cachedPlugin` covers the case where another instance finished loading\n // between this component's mount and this render (state update pending).\n return plugin ?? cachedPlugin;\n}\n"],"mappings":";;;AAkCA,SAAS,WAAW,gBAAgB;AAGpC,IAAM,oBAAoB;AAGnB,SAAS,gBAAgB,MAAuB;AACrD,SAAO,kBAAkB,KAAK,IAAI;AACpC;AAGA,IAAI;AACJ,IAAI;AAEJ,SAAS,iBAAsC;AAC7C,kBAAgB,OAAO,kBAAkB,EAAE,KAAK,CAAC,QAAQ;AACvD,mBAAe,IAAI;AACnB,WAAO;AAAA,EACT,CAAC;AACD,SAAO;AACT;AAOO,IAAM,cAAc,MAAY;AACrC,OAAK,eAAe;AACtB;AAOO,SAAS,kBAAkB,MAAsC;AACtE,QAAM,SAAS,gBAAgB,IAAI;AACnC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiC,YAAY;AAEzE,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,aAAc;AAC7B,QAAI,YAAY;AAChB,mBAAe,EAAE,KAAK,CAAC,WAAW;AAChC,UAAI,CAAC,UAAW,WAAU,MAAM;AAAA,IAClC,CAAC;AACD,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,MAAI,CAAC,OAAQ,QAAO;AAGpB,SAAO,UAAU;AACnB;","names":[]}
@@ -0,0 +1,303 @@
1
+ "use client";
2
+ import {
3
+ PromptInputCommand,
4
+ PromptInputCommandEmpty,
5
+ PromptInputCommandItem,
6
+ PromptInputCommandList,
7
+ PromptInputTextarea
8
+ } from "./chunk-SSGJ6MEM.js";
9
+
10
+ // src/prompt-input-slash.tsx
11
+ import {
12
+ createContext,
13
+ forwardRef,
14
+ use,
15
+ useCallback,
16
+ useEffect,
17
+ useLayoutEffect,
18
+ useMemo,
19
+ useRef,
20
+ useState
21
+ } from "react";
22
+ import {
23
+ Popover,
24
+ PopoverAnchor,
25
+ PopoverContent,
26
+ cn,
27
+ defaultSlashCommandFilter,
28
+ findTriggerQuery,
29
+ replaceTriggerRun,
30
+ stepIndex,
31
+ useLocale
32
+ } from "@elabs-ai/components-ui";
33
+ import { jsx, jsxs } from "react/jsx-runtime";
34
+ var TRIGGER = "/";
35
+ function mergeRefs(...refs) {
36
+ return (node) => {
37
+ for (const ref of refs) {
38
+ if (typeof ref === "function") ref(node);
39
+ else if (ref) ref.current = node;
40
+ }
41
+ };
42
+ }
43
+ var PromptInputSlashWiringContext = createContext(null);
44
+ var PromptInputSlash = forwardRef(
45
+ function PromptInputSlash2({
46
+ commands,
47
+ value,
48
+ textareaRef,
49
+ lineStartOnly = true,
50
+ filter = defaultSlashCommandFilter,
51
+ onValueChange,
52
+ onSelect,
53
+ onOpenChange,
54
+ className,
55
+ children,
56
+ ...props
57
+ }, ref) {
58
+ const { t } = useLocale();
59
+ const rootRef = useRef(null);
60
+ const mergedRootRef = useMemo(() => mergeRefs(ref, rootRef), [ref]);
61
+ const [caret, setCaret] = useState(() => value.length);
62
+ const pendingCaretRef = useRef(null);
63
+ const syncCaret = useCallback((element) => {
64
+ setCaret(element.selectionStart ?? 0);
65
+ }, []);
66
+ useLayoutEffect(() => {
67
+ const position = pendingCaretRef.current;
68
+ if (position === null) return;
69
+ pendingCaretRef.current = null;
70
+ textareaRef.current?.setSelectionRange(position, position);
71
+ });
72
+ const boundary = lineStartOnly ? "line-start" : "word";
73
+ const queryInfo = useMemo(
74
+ () => findTriggerQuery(value, caret, TRIGGER, { boundary }),
75
+ [value, caret, boundary]
76
+ );
77
+ const [dismissedStart, setDismissedStart] = useState(null);
78
+ useEffect(() => {
79
+ if (queryInfo === null && dismissedStart !== null) setDismissedStart(null);
80
+ }, [queryInfo, dismissedStart]);
81
+ const open = queryInfo !== null && dismissedStart !== queryInfo.start;
82
+ const query = open && queryInfo ? queryInfo.query : null;
83
+ const setOpen = useCallback(
84
+ (next) => {
85
+ onOpenChange?.(next);
86
+ if (!next) setDismissedStart(queryInfo?.start ?? null);
87
+ },
88
+ [onOpenChange, queryInfo]
89
+ );
90
+ const filtered = useMemo(
91
+ () => query !== null ? commands.filter((command) => filter(command, query)) : [],
92
+ [query, commands, filter]
93
+ );
94
+ const [activeIndexState, setActiveIndexState] = useState(0);
95
+ const activeIndex = useMemo(() => {
96
+ if (filtered.length === 0) return -1;
97
+ if (activeIndexState < 0 || activeIndexState >= filtered.length) return 0;
98
+ return activeIndexState;
99
+ }, [filtered, activeIndexState]);
100
+ useEffect(() => {
101
+ setActiveIndexState(0);
102
+ }, [query]);
103
+ const activeCommand = activeIndex >= 0 ? filtered[activeIndex] : void 0;
104
+ const [activeDomId, setActiveDomId] = useState(void 0);
105
+ useEffect(() => {
106
+ if (!open) setActiveDomId(void 0);
107
+ }, [open]);
108
+ const [listDomId, setListDomId] = useState(void 0);
109
+ const handleListRef = useCallback((node) => {
110
+ setListDomId(node?.id);
111
+ }, []);
112
+ const handleActiveValueChange = useCallback(
113
+ (nextValue) => {
114
+ const index = filtered.findIndex((command) => command.name === nextValue);
115
+ if (index >= 0) setActiveIndexState(index);
116
+ },
117
+ [filtered]
118
+ );
119
+ const select = useCallback(
120
+ (command) => {
121
+ if (!queryInfo) return;
122
+ const insertText = `${TRIGGER}${command.name} `;
123
+ const result = replaceTriggerRun(value, queryInfo.start, caret, insertText);
124
+ pendingCaretRef.current = result.caret;
125
+ onValueChange(result);
126
+ onSelect?.(command);
127
+ },
128
+ [queryInfo, value, caret, onValueChange, onSelect]
129
+ );
130
+ const close = useCallback(() => setOpen(false), [setOpen]);
131
+ const handleKeyDown = useCallback(
132
+ (event) => {
133
+ if (!open) return;
134
+ switch (event.key) {
135
+ case "ArrowDown":
136
+ event.preventDefault();
137
+ setActiveIndexState(stepIndex(filtered.length, activeIndex, 1));
138
+ return;
139
+ case "ArrowUp":
140
+ event.preventDefault();
141
+ setActiveIndexState(stepIndex(filtered.length, activeIndex < 0 ? 0 : activeIndex, -1));
142
+ return;
143
+ case "Home":
144
+ event.preventDefault();
145
+ setActiveIndexState(0);
146
+ return;
147
+ case "End":
148
+ event.preventDefault();
149
+ setActiveIndexState(filtered.length - 1);
150
+ return;
151
+ case "Enter":
152
+ case "Tab": {
153
+ if (activeCommand) {
154
+ event.preventDefault();
155
+ select(activeCommand);
156
+ }
157
+ return;
158
+ }
159
+ case "Escape":
160
+ event.preventDefault();
161
+ close();
162
+ textareaRef.current?.focus();
163
+ return;
164
+ default:
165
+ return;
166
+ }
167
+ },
168
+ [open, filtered.length, activeIndex, activeCommand, select, close, textareaRef]
169
+ );
170
+ const wiring = useMemo(
171
+ () => ({
172
+ open,
173
+ listDomId,
174
+ activeId: activeDomId,
175
+ textareaRef,
176
+ syncCaret,
177
+ onKeyDown: handleKeyDown
178
+ }),
179
+ [open, listDomId, activeDomId, textareaRef, syncCaret, handleKeyDown]
180
+ );
181
+ return /* @__PURE__ */ jsx(PromptInputSlashWiringContext, { value: wiring, children: /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: (next) => !next && setOpen(false), children: [
182
+ /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsx(
183
+ "div",
184
+ {
185
+ ref: mergedRootRef,
186
+ "data-slot": "prompt-input-slash",
187
+ className: cn("relative", className),
188
+ ...props,
189
+ children
190
+ }
191
+ ) }),
192
+ /* @__PURE__ */ jsx(
193
+ PopoverContent,
194
+ {
195
+ "data-slot": "prompt-input-slash-content",
196
+ role: "presentation",
197
+ align: "start",
198
+ side: "top",
199
+ sideOffset: 8,
200
+ className: "w-72 p-0",
201
+ onOpenAutoFocus: (event) => event.preventDefault(),
202
+ onCloseAutoFocus: (event) => event.preventDefault(),
203
+ onPointerDownOutside: (event) => {
204
+ const target = event.detail.originalEvent.target;
205
+ if (target && textareaRef.current?.contains(target)) event.preventDefault();
206
+ },
207
+ children: /* @__PURE__ */ jsx(
208
+ PromptInputCommand,
209
+ {
210
+ shouldFilter: false,
211
+ value: activeCommand?.name ?? "",
212
+ onValueChange: handleActiveValueChange,
213
+ onActiveItemIdChange: setActiveDomId,
214
+ "data-slot": "prompt-input-slash-command",
215
+ children: /* @__PURE__ */ jsx(
216
+ PromptInputCommandList,
217
+ {
218
+ ref: handleListRef,
219
+ label: t("ai.promptInputSlash.listLabel"),
220
+ "data-slot": "prompt-input-slash-list",
221
+ children: filtered.length === 0 ? /* @__PURE__ */ jsx(PromptInputCommandEmpty, { "data-slot": "prompt-input-slash-empty", children: t("ai.promptInputSlash.empty") }) : filtered.map((command) => /* @__PURE__ */ jsxs(
222
+ PromptInputCommandItem,
223
+ {
224
+ value: command.name,
225
+ "data-slot": "prompt-input-slash-item",
226
+ onSelect: () => select(command),
227
+ onMouseDown: (event) => event.preventDefault(),
228
+ children: [
229
+ command.icon ? /* @__PURE__ */ jsx(
230
+ "span",
231
+ {
232
+ "aria-hidden": "true",
233
+ className: "flex size-5 shrink-0 items-center justify-center text-muted-foreground [&_svg]:size-4",
234
+ children: command.icon
235
+ }
236
+ ) : null,
237
+ /* @__PURE__ */ jsxs("span", { className: "w-28 shrink-0 truncate text-body", children: [
238
+ TRIGGER,
239
+ command.name
240
+ ] }),
241
+ command.description ? /* @__PURE__ */ jsx("span", { className: "truncate text-meta text-muted-foreground", children: command.description }) : null
242
+ ]
243
+ },
244
+ command.name
245
+ ))
246
+ }
247
+ )
248
+ }
249
+ )
250
+ }
251
+ )
252
+ ] }) });
253
+ }
254
+ );
255
+ var PromptInputSlashTextarea = forwardRef(function PromptInputSlashTextarea2({ onChange, onKeyDown, onSelect, onKeyUp, onClick, className, ...props }, ref) {
256
+ const wiring = use(PromptInputSlashWiringContext);
257
+ if (!wiring) {
258
+ throw new Error("PromptInputSlashTextarea must be used inside a <PromptInputSlash>.");
259
+ }
260
+ const mergedRef = useMemo(
261
+ () => mergeRefs(ref, wiring.textareaRef),
262
+ [ref, wiring.textareaRef]
263
+ );
264
+ return /* @__PURE__ */ jsx(
265
+ PromptInputTextarea,
266
+ {
267
+ ref: mergedRef,
268
+ "data-slot": "prompt-input-slash-textarea",
269
+ "aria-autocomplete": "list",
270
+ "aria-haspopup": "listbox",
271
+ "aria-controls": wiring.open ? wiring.listDomId : void 0,
272
+ "aria-activedescendant": wiring.activeId,
273
+ className: cn("relative z-0", className),
274
+ ...props,
275
+ onChange: (event) => {
276
+ wiring.syncCaret(event.currentTarget);
277
+ onChange?.(event);
278
+ },
279
+ onKeyDown: (event) => {
280
+ wiring.onKeyDown(event);
281
+ onKeyDown?.(event);
282
+ },
283
+ onSelect: (event) => {
284
+ wiring.syncCaret(event.currentTarget);
285
+ onSelect?.(event);
286
+ },
287
+ onKeyUp: (event) => {
288
+ wiring.syncCaret(event.currentTarget);
289
+ onKeyUp?.(event);
290
+ },
291
+ onClick: (event) => {
292
+ wiring.syncCaret(event.currentTarget);
293
+ onClick?.(event);
294
+ }
295
+ }
296
+ );
297
+ });
298
+
299
+ export {
300
+ PromptInputSlash,
301
+ PromptInputSlashTextarea
302
+ };
303
+ //# sourceMappingURL=chunk-WMDSMSPL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/prompt-input-slash.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * PromptInputSlash — a slash-command palette for the chat composer.\n *\n * Reuses the generic trigger machinery `@elabs-ai/components-ui` ships at\n * `lib/trigger-query.ts` (`findTriggerQuery` / `replaceTriggerRun`) with\n * `trigger: \"/\"` and `boundary: \"line-start\"` — the same algorithm\n * `MentionInput` runs with `trigger: \"@\"` and the `\"word\"` boundary. See\n * docs/decisions/2026-09-01-brainless-adoption-architecture.md § 5: this\n * package NEVER re-implements trigger detection, and never imports the\n * markdown-scoped slash menu in `@elabs-ai/components-editor` (that would be\n * a sideways edge in the one-way dependency graph).\n *\n * Rendering goes through the existing `PromptInputCommand*` parts (thin\n * `cmdk` wrappers), controlled rather than driven by `cmdk`'s own keyboard\n * handling — the caret must stay in the composer's `<textarea>` the whole\n * time, so every keystroke (Arrow/Home/End/Enter/Escape) is intercepted on\n * the textarea itself and only the *highlighted* `value` is pushed into\n * `PromptInputCommand`. `aria-activedescendant` is read back via\n * `PromptInputCommand`'s existing `onActiveItemIdChange` seam (the doc-block\n * on `PromptInputCommandItem` names this exact composition) rather than by\n * guessing a DOM id — `cmdk` assigns each item's `id` internally and\n * overwrites any id a consumer passes.\n *\n * `SlashCommand`, `defaultSlashCommandFilter` and the index-stepping helper\n * (`stepIndex`, formerly this file's private `step`) are promoted to\n * `@elabs-ai/components-ui` (T0 — the terminal CLI look-alike family's own\n * palette, issue #117, reuses the same model; `ui` is the one legal shared\n * home for two layer-2 DAG siblings — see\n * docs/decisions/2026-09-01-brainless-adoption-architecture.md § 4).\n */\nimport {\n createContext,\n forwardRef,\n use,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ForwardedRef,\n type HTMLAttributes,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n type RefObject,\n} from \"react\";\nimport {\n Popover,\n PopoverAnchor,\n PopoverContent,\n cn,\n defaultSlashCommandFilter,\n findTriggerQuery,\n replaceTriggerRun,\n stepIndex,\n useLocale,\n type SlashCommand,\n type TriggerBoundary,\n} from \"@elabs-ai/components-ui\";\n\nimport {\n PromptInputCommand,\n PromptInputCommandEmpty,\n PromptInputCommandItem,\n PromptInputCommandList,\n PromptInputTextarea,\n type PromptInputTextareaProps,\n} from \"./prompt-input\";\n\nconst TRIGGER = \"/\";\n\n// ---------------------------------------------------------------------------\n// Small local helpers (deliberately NOT shared — see the doc-comments below)\n// ---------------------------------------------------------------------------\n\n/**\n * Merge multiple refs into one callback ref. A private, ~10-line copy rather\n * than a cross-package import: `mergeRefs` lives in `@elabs-ai/components-ui`'s\n * `lib/` but is not exported from its barrel or any subpath today, and adding\n * one is a subpath-export decision this change is not scoped to make (see\n * `.claude/rules/component-api.md` § \"Subpath exports\"). Ordinary React\n * ref-composition boilerplate, not the trigger algorithm this file exists to\n * avoid re-implementing.\n */\ntype MaybeRef<T> = ForwardedRef<T> | undefined;\n\n// prettier-ignore\nfunction mergeRefs<T>(\n ...refs: Array<MaybeRef<T>>\n) {\n return (node: T | null) => {\n for (const ref of refs) {\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as { current: T | null }).current = node;\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n//\n// `SlashCommand` and `defaultSlashCommandFilter` moved to\n// `@elabs-ai/components-ui` (`lib/slash-command.ts`) — see the promotion\n// note at the top of this file.\n\nexport interface PromptInputSlashProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"onSelect\" | \"children\"\n> {\n /** The registered commands the palette offers. */\n commands: SlashCommand[];\n /** The composer's current text — must match what the wrapped textarea renders. */\n value: string;\n /** Ref to the composer's `<textarea>` (usually the one `PromptInputSlashTextarea` renders). */\n textareaRef: RefObject<HTMLTextAreaElement | null>;\n /**\n * Only trigger at the start of a line (index 0, or right after `\"\\n\"`).\n * `false` falls back to `MentionInput`'s word-boundary rule.\n * @default true\n */\n lineStartOnly?: boolean;\n /** Which commands survive the current query. @default defaultSlashCommandFilter */\n filter?: (command: SlashCommand, query: string) => boolean;\n /**\n * A command was chosen — apply the spliced `{ text, caret }` to your own\n * controlled value (the same shape `replaceTriggerRun` returns). The\n * splice inserts `\"/\" + command.name + \" \"` in place of the typed query.\n */\n onValueChange: (next: { text: string; caret: number }) => void;\n /** A command was chosen (fires alongside, not instead of, `onValueChange`). */\n onSelect?: (command: SlashCommand) => void;\n /** The popup opened or closed. */\n onOpenChange?: (open: boolean) => void;\n children: ReactNode;\n}\n\n// ---------------------------------------------------------------------------\n// Wiring context — private plumbing between the root and its `Textarea` part\n// (component-api.md: \"compound components share a context, not props\").\n// ---------------------------------------------------------------------------\n\ninterface PromptInputSlashWiring {\n open: boolean;\n /**\n * The REAL DOM id `cmdk` assigned to the listbox, read back off the\n * rendered node — `cmdk`'s `CommandList` forces its own internally\n * generated `id` after spreading consumer props (the same override\n * `CMDK_OVERRIDDEN_ITEM_PROPS` documents for `CommandItem`), so a\n * self-minted id passed as a prop is silently dropped.\n */\n listDomId?: string;\n /** DOM id of the highlighted `PromptInputCommandItem`, from `onActiveItemIdChange`. */\n activeId?: string;\n textareaRef: RefObject<HTMLTextAreaElement | null>;\n syncCaret: (element: HTMLTextAreaElement) => void;\n onKeyDown: (event: ReactKeyboardEvent<HTMLTextAreaElement>) => void;\n}\n\nconst PromptInputSlashWiringContext = createContext<PromptInputSlashWiring | null>(null);\n\n// ---------------------------------------------------------------------------\n// PromptInputSlash (root — provider + Popover, mirrors MentionInput's shape)\n// ---------------------------------------------------------------------------\n\n/**\n * PromptInputSlash — wrap the composer's textarea (rendered via\n * `PromptInputSlashTextarea`) to add a `/`-triggered command palette.\n *\n * ```tsx\n * const textareaRef = useRef<HTMLTextAreaElement>(null);\n * const [text, setText] = useState(\"\");\n *\n * <PromptInputSlash\n * commands={commands}\n * value={text}\n * textareaRef={textareaRef}\n * onValueChange={({ text }) => setText(text)}\n * >\n * <PromptInputSlashTextarea value={text} onChange={(e) => setText(e.target.value)} />\n * </PromptInputSlash>\n * ```\n */\nexport const PromptInputSlash = forwardRef<HTMLDivElement, PromptInputSlashProps>(\n function PromptInputSlash(\n {\n commands,\n value,\n textareaRef,\n lineStartOnly = true,\n filter = defaultSlashCommandFilter,\n onValueChange,\n onSelect,\n onOpenChange,\n className,\n children,\n ...props\n },\n ref,\n ) {\n const { t } = useLocale();\n\n const rootRef = useRef<HTMLDivElement>(null);\n const mergedRootRef = useMemo(() => mergeRefs<HTMLDivElement>(ref, rootRef), [ref]);\n\n // ------------------------------------------------------------------\n // Caret — tracked from the wrapped textarea's own DOM events, exactly\n // like `MentionInput`'s `syncCaret`/`applyCaret` pair.\n // ------------------------------------------------------------------\n const [caret, setCaret] = useState(() => value.length);\n const pendingCaretRef = useRef<number | null>(null);\n\n const syncCaret = useCallback((element: HTMLTextAreaElement) => {\n setCaret(element.selectionStart ?? 0);\n }, []);\n\n // Post-commit pass: only after `value` has actually re-rendered into the\n // DOM can the caret be restored — see MentionInput's identical comment.\n useLayoutEffect(() => {\n const position = pendingCaretRef.current;\n if (position === null) return;\n pendingCaretRef.current = null;\n // `setSelectionRange` fires a native `select` event, which\n // `PromptInputSlashTextarea`'s `onSelect` handler already routes to\n // `syncCaret` — no need to call `setCaret` here too (mirrors\n // `MentionInput`'s identical caret-restore effect).\n textareaRef.current?.setSelectionRange(position, position);\n });\n\n // ------------------------------------------------------------------\n // Query / open state\n // ------------------------------------------------------------------\n const boundary: TriggerBoundary = lineStartOnly ? \"line-start\" : \"word\";\n\n const queryInfo = useMemo(\n () => findTriggerQuery(value, caret, TRIGGER, { boundary }),\n [value, caret, boundary],\n );\n\n // Escape (and an outside dismissal) suppress the popup for the run it was\n // dismissed on, without touching the text — same rationale as MentionInput.\n const [dismissedStart, setDismissedStart] = useState<number | null>(null);\n useEffect(() => {\n if (queryInfo === null && dismissedStart !== null) setDismissedStart(null);\n }, [queryInfo, dismissedStart]);\n\n const open = queryInfo !== null && dismissedStart !== queryInfo.start;\n const query = open && queryInfo ? queryInfo.query : null;\n\n const setOpen = useCallback(\n (next: boolean) => {\n onOpenChange?.(next);\n if (!next) setDismissedStart(queryInfo?.start ?? null);\n },\n [onOpenChange, queryInfo],\n );\n\n // ------------------------------------------------------------------\n // Filtering + highlight\n // ------------------------------------------------------------------\n const filtered = useMemo(\n () => (query !== null ? commands.filter((command) => filter(command, query)) : []),\n [query, commands, filter],\n );\n\n const [activeIndexState, setActiveIndexState] = useState(0);\n\n // Resolved DURING render, never repaired in an effect, so a stale index\n // from before a filter keystroke can never reach the DOM — see the\n // identical rationale in `MentionInput`'s `activeIndex` docblock.\n const activeIndex = useMemo(() => {\n if (filtered.length === 0) return -1;\n if (activeIndexState < 0 || activeIndexState >= filtered.length) return 0;\n return activeIndexState;\n }, [filtered, activeIndexState]);\n\n useEffect(() => {\n setActiveIndexState(0);\n }, [query]);\n\n const activeCommand = activeIndex >= 0 ? filtered[activeIndex] : undefined;\n const [activeDomId, setActiveDomId] = useState<string | undefined>(undefined);\n\n // The listbox lives inside `PopoverContent`, which UNMOUNTS on close — its\n // `onActiveItemIdChange` never fires again to report \"no active item\", so\n // without this the textarea would keep pointing `aria-activedescendant`\n // at a node that no longer exists.\n useEffect(() => {\n if (!open) setActiveDomId(undefined);\n }, [open]);\n\n // The REAL DOM id `cmdk` assigns to the listbox (see `listDomId`'s\n // docblock on `PromptInputSlashWiring`) — read off the rendered node\n // rather than trusted from a prop we pass in, since `cmdk` overwrites it.\n const [listDomId, setListDomId] = useState<string | undefined>(undefined);\n const handleListRef = useCallback((node: HTMLDivElement | null) => {\n setListDomId(node?.id);\n }, []);\n\n // `PromptInputCommand` is controlled (`value=`), so `cmdk`'s own pointer\n // hover / mount-time auto-select report back here instead of self-applying\n // — keep mouse and keyboard highlighting as one source of truth.\n const handleActiveValueChange = useCallback(\n (nextValue: string) => {\n const index = filtered.findIndex((command) => command.name === nextValue);\n if (index >= 0) setActiveIndexState(index);\n },\n [filtered],\n );\n\n // ------------------------------------------------------------------\n // Actions\n // ------------------------------------------------------------------\n const select = useCallback(\n (command: SlashCommand) => {\n if (!queryInfo) return;\n const insertText = `${TRIGGER}${command.name} `;\n const result = replaceTriggerRun(value, queryInfo.start, caret, insertText);\n pendingCaretRef.current = result.caret;\n onValueChange(result);\n onSelect?.(command);\n },\n [queryInfo, value, caret, onValueChange, onSelect],\n );\n\n const close = useCallback(() => setOpen(false), [setOpen]);\n\n const handleKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLTextAreaElement>) => {\n if (!open) return;\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n setActiveIndexState(stepIndex(filtered.length, activeIndex, 1));\n return;\n case \"ArrowUp\":\n event.preventDefault();\n setActiveIndexState(stepIndex(filtered.length, activeIndex < 0 ? 0 : activeIndex, -1));\n return;\n case \"Home\":\n event.preventDefault();\n setActiveIndexState(0);\n return;\n case \"End\":\n event.preventDefault();\n setActiveIndexState(filtered.length - 1);\n return;\n case \"Enter\":\n case \"Tab\": {\n if (activeCommand) {\n event.preventDefault();\n select(activeCommand);\n }\n return;\n }\n case \"Escape\":\n event.preventDefault();\n close();\n textareaRef.current?.focus();\n return;\n default:\n return;\n }\n },\n [open, filtered.length, activeIndex, activeCommand, select, close, textareaRef],\n );\n\n const wiring = useMemo<PromptInputSlashWiring>(\n () => ({\n open,\n listDomId,\n activeId: activeDomId,\n textareaRef,\n syncCaret,\n onKeyDown: handleKeyDown,\n }),\n [open, listDomId, activeDomId, textareaRef, syncCaret, handleKeyDown],\n );\n\n return (\n <PromptInputSlashWiringContext value={wiring}>\n <Popover open={open} onOpenChange={(next) => !next && setOpen(false)}>\n <PopoverAnchor asChild>\n <div\n ref={mergedRootRef}\n data-slot=\"prompt-input-slash\"\n className={cn(\"relative\", className)}\n {...props}\n >\n {children}\n </div>\n </PopoverAnchor>\n <PopoverContent\n data-slot=\"prompt-input-slash-content\"\n // A plain container, not a dialog — the listbox inside carries all\n // the semantics (same rationale as `MentionInputContent`).\n role=\"presentation\"\n align=\"start\"\n side=\"top\"\n sideOffset={8}\n className=\"w-72 p-0\"\n onOpenAutoFocus={(event) => event.preventDefault()}\n onCloseAutoFocus={(event) => event.preventDefault()}\n onPointerDownOutside={(event) => {\n // Clicking the field itself only moves the caret; it must not\n // count as a dismissal, or the popup would fight the caret it\n // depends on (same rationale as `MentionInputContent`).\n const target = event.detail.originalEvent.target as Node | null;\n if (target && textareaRef.current?.contains(target)) event.preventDefault();\n }}\n >\n <PromptInputCommand\n shouldFilter={false}\n value={activeCommand?.name ?? \"\"}\n onValueChange={handleActiveValueChange}\n onActiveItemIdChange={setActiveDomId}\n data-slot=\"prompt-input-slash-command\"\n >\n <PromptInputCommandList\n ref={handleListRef}\n // `cmdk`'s `CommandList` reads its accessible name off its own\n // `label` prop (defaulting to \"Suggestions\"), not `aria-label`\n // — an `aria-label` prop would land in the spread `cmdk`\n // overwrites, same as the `id` it also owns.\n label={t(\"ai.promptInputSlash.listLabel\")}\n data-slot=\"prompt-input-slash-list\"\n >\n {filtered.length === 0 ? (\n <PromptInputCommandEmpty data-slot=\"prompt-input-slash-empty\">\n {t(\"ai.promptInputSlash.empty\")}\n </PromptInputCommandEmpty>\n ) : (\n filtered.map((command) => (\n <PromptInputCommandItem\n key={command.name}\n value={command.name}\n data-slot=\"prompt-input-slash-item\"\n onSelect={() => select(command)}\n // The field keeps focus — select on mousedown, before a\n // click on a non-focusable row could ever move it.\n onMouseDown={(event) => event.preventDefault()}\n >\n {command.icon ? (\n <span\n aria-hidden=\"true\"\n className=\"flex size-5 shrink-0 items-center justify-center text-muted-foreground [&_svg]:size-4\"\n >\n {command.icon}\n </span>\n ) : null}\n {/* Fixed-width name column: the selection moving never\n shifts the description text under the user's eyes. */}\n <span className=\"w-28 shrink-0 truncate text-body\">\n {TRIGGER}\n {command.name}\n </span>\n {command.description ? (\n <span className=\"truncate text-meta text-muted-foreground\">\n {command.description}\n </span>\n ) : null}\n </PromptInputCommandItem>\n ))\n )}\n </PromptInputCommandList>\n </PromptInputCommand>\n </PopoverContent>\n </Popover>\n </PromptInputSlashWiringContext>\n );\n },\n);\n\n// ---------------------------------------------------------------------------\n// PromptInputSlashTextarea\n// ---------------------------------------------------------------------------\n\nexport type PromptInputSlashTextareaProps = PromptInputTextareaProps;\n\n/**\n * The composer's `<textarea>`, carrying the combobox semantics the palette\n * needs. A thin wrapper around `PromptInputTextarea` — every prop you'd pass\n * that component still works; this one additionally merges in the palette's\n * `ref`, caret tracking and `aria-activedescendant`.\n *\n * Must be rendered inside a `<PromptInputSlash>`.\n */\nexport const PromptInputSlashTextarea = forwardRef<\n HTMLTextAreaElement,\n PromptInputSlashTextareaProps\n>(function PromptInputSlashTextarea(\n { onChange, onKeyDown, onSelect, onKeyUp, onClick, className, ...props },\n ref,\n) {\n const wiring = use(PromptInputSlashWiringContext);\n if (!wiring) {\n throw new Error(\"PromptInputSlashTextarea must be used inside a <PromptInputSlash>.\");\n }\n const mergedRef = useMemo(\n () => mergeRefs<HTMLTextAreaElement>(ref, wiring.textareaRef),\n [ref, wiring.textareaRef],\n );\n\n return (\n <PromptInputTextarea\n ref={mergedRef}\n data-slot=\"prompt-input-slash-textarea\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n // Only while the popup is mounted: the listbox lives in a Radix portal\n // that unmounts on close, and an `aria-controls` pointing at a removed\n // node is a dangling reference (same rationale as `MentionInputTextarea`).\n aria-controls={wiring.open ? wiring.listDomId : undefined}\n aria-activedescendant={wiring.activeId}\n className={cn(\"relative z-0\", className)}\n {...props}\n onChange={(event) => {\n wiring.syncCaret(event.currentTarget);\n onChange?.(event);\n }}\n onKeyDown={(event) => {\n wiring.onKeyDown(event);\n onKeyDown?.(event);\n }}\n onSelect={(event) => {\n wiring.syncCaret(event.currentTarget);\n onSelect?.(event);\n }}\n onKeyUp={(event) => {\n wiring.syncCaret(event.currentTarget);\n onKeyUp?.(event);\n }}\n onClick={(event) => {\n wiring.syncCaret(event.currentTarget);\n onClick?.(event);\n }}\n />\n );\n});\n"],"mappings":"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","names":["PromptInputSlash","PromptInputSlashTextarea"]}
@@ -0,0 +1,149 @@
1
+ "use client";
2
+ import {
3
+ Reasoning,
4
+ ReasoningContent,
5
+ ReasoningTrigger
6
+ } from "./chunk-X47QMM6K.js";
7
+ import {
8
+ Tool,
9
+ ToolContent,
10
+ ToolHeader,
11
+ ToolInput,
12
+ ToolOutput,
13
+ statusFromToolState
14
+ } from "./chunk-PTWCTSZL.js";
15
+ import {
16
+ buildPartGroups,
17
+ defaultPartStatus,
18
+ groupPartByType,
19
+ partsFingerprint
20
+ } from "./chunk-YSKD7UXX.js";
21
+
22
+ // src/grouped-parts.tsx
23
+ import { Fragment, useMemo } from "react";
24
+ import { BrainIcon, ChevronDownIcon } from "lucide-react";
25
+ import {
26
+ Badge,
27
+ Collapsible,
28
+ CollapsibleContent,
29
+ CollapsibleTrigger
30
+ } from "@elabs-ai/components-ui";
31
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
32
+ import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
33
+ function DefaultGroup({
34
+ status,
35
+ count,
36
+ children
37
+ }) {
38
+ const running = status === "running";
39
+ return /* @__PURE__ */ jsxs(Collapsible, { defaultOpen: running, className: "not-prose w-full rounded-md border border-border", children: [
40
+ /* @__PURE__ */ jsxs(
41
+ CollapsibleTrigger,
42
+ {
43
+ className: cn(
44
+ "group flex w-full items-center gap-2 p-3 text-body text-muted-foreground",
45
+ "transition-colors duration-fast ease-standard hover:text-foreground motion-reduce:transition-none",
46
+ "focus-ring-inset"
47
+ ),
48
+ children: [
49
+ /* @__PURE__ */ jsx(BrainIcon, { "aria-hidden": "true", className: "size-4 shrink-0" }),
50
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-start", children: running ? "Working\u2026" : "Thought process" }),
51
+ count > 0 && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "shrink-0", children: count }),
52
+ /* @__PURE__ */ jsx(
53
+ ChevronDownIcon,
54
+ {
55
+ "aria-hidden": "true",
56
+ className: "size-4 shrink-0 transition-transform group-data-[state=open]:rotate-180 motion-reduce:transition-none"
57
+ }
58
+ )
59
+ ]
60
+ }
61
+ ),
62
+ /* @__PURE__ */ jsx(CollapsibleContent, { className: "space-y-3 p-3 pt-0", children })
63
+ ] });
64
+ }
65
+ function defaultRenderPart(args) {
66
+ if (args.isGroup) {
67
+ return /* @__PURE__ */ jsx(DefaultGroup, { status: args.status, count: args.indices?.length ?? 0, children: args.children });
68
+ }
69
+ const part = args.part;
70
+ const streaming = args.status === "running";
71
+ if (part.type === "reasoning" || part.type.startsWith("reasoning")) {
72
+ const text = typeof part.text === "string" ? part.text : "";
73
+ return /* @__PURE__ */ jsxs(Reasoning, { isStreaming: streaming, defaultOpen: streaming, children: [
74
+ /* @__PURE__ */ jsx(ReasoningTrigger, {}),
75
+ /* @__PURE__ */ jsx(ReasoningContent, { children: text })
76
+ ] });
77
+ }
78
+ if (part.type.startsWith("tool-") || part.type === "dynamic-tool") {
79
+ const p = part;
80
+ const headerProps = {
81
+ type: p.type,
82
+ state: p.state ?? "input-available",
83
+ toolName: p.type === "dynamic-tool" ? p.toolName : void 0
84
+ };
85
+ const toolStreaming = statusFromToolState(p.state ?? "input-available") === "pending";
86
+ return /* @__PURE__ */ jsxs(Tool, { children: [
87
+ /* @__PURE__ */ jsx(ToolHeader, { ...headerProps }),
88
+ /* @__PURE__ */ jsxs(ToolContent, { children: [
89
+ p.input !== void 0 && /* @__PURE__ */ jsx(ToolInput, { input: p.input }),
90
+ (toolStreaming || p.output !== void 0 || Boolean(p.errorText)) && /* @__PURE__ */ jsx(
91
+ ToolOutput,
92
+ {
93
+ output: p.output,
94
+ errorText: p.errorText ?? void 0,
95
+ isStreaming: toolStreaming
96
+ }
97
+ )
98
+ ] })
99
+ ] });
100
+ }
101
+ if (part.type === "text") {
102
+ const text = typeof part.text === "string" ? part.text : "";
103
+ return /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap text-body text-foreground", children: text });
104
+ }
105
+ return null;
106
+ }
107
+ function GroupedParts({
108
+ parts,
109
+ groupBy = groupPartByType(),
110
+ getStatus,
111
+ children,
112
+ className,
113
+ ...props
114
+ }) {
115
+ const fingerprint = partsFingerprint(parts, getStatus);
116
+ const tree = useMemo(
117
+ () => buildPartGroups(parts, groupBy, getStatus),
118
+ // Rebuild only on a structural change; `parts`/`groupBy`/`getStatus` identity
119
+ // may churn per render, but the fingerprint is the real dependency.
120
+ // eslint-disable-next-line react-hooks/exhaustive-deps
121
+ [fingerprint, groupBy, getStatus]
122
+ );
123
+ const renderPart = children ?? defaultRenderPart;
124
+ const statusOf = (part) => getStatus?.(part) ?? defaultPartStatus(part);
125
+ const renderNode = (node) => {
126
+ if (node.kind === "leaf") {
127
+ return /* @__PURE__ */ jsx(Fragment, { children: renderPart({
128
+ part: node.part,
129
+ isGroup: false,
130
+ status: statusOf(node.part),
131
+ index: node.index
132
+ }) }, node.key);
133
+ }
134
+ const kids = node.children.map(renderNode);
135
+ return /* @__PURE__ */ jsx(Fragment, { children: renderPart({
136
+ part: node.group,
137
+ isGroup: true,
138
+ status: node.group.status,
139
+ indices: node.group.indices,
140
+ children: /* @__PURE__ */ jsx(Fragment2, { children: kids })
141
+ }) }, node.key);
142
+ };
143
+ return /* @__PURE__ */ jsx("div", { className: cn("flex w-full flex-col gap-3", className), ...props, children: tree.map(renderNode) });
144
+ }
145
+
146
+ export {
147
+ GroupedParts
148
+ };
149
+ //# sourceMappingURL=chunk-WU5BLGTF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/grouped-parts.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * GroupedParts — renders an ordered part list, folding adjacent reasoning/tool\n * parts into collapsible traces (see `part-groups.ts` for the pure engine).\n *\n * A render-prop switches on `part.type`. Group nodes arrive as synthetic\n * `{ type: \"group-…\", status, indices }` with their rendered `children`; real\n * parts arrive as leaves. When no render-prop is given, sensible defaults\n * integrate the existing `Reasoning` / `Tool` components (and a collapsible\n * trace for groups). It is presentational only — the grouping is a client-side\n * view transform, never a model output format.\n *\n * NOTE: this is a generic function component (not `forwardRef`) because the\n * render-prop is generic over the part type `T`; `forwardRef` erases generics.\n */\n\nimport { Fragment, useMemo, type ComponentProps, type HTMLAttributes, type ReactNode } from \"react\";\nimport { BrainIcon, ChevronDownIcon } from \"lucide-react\";\nimport {\n Badge,\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\n\nimport { Reasoning, ReasoningContent, ReasoningTrigger } from \"./reasoning\";\nimport {\n Tool,\n ToolContent,\n ToolHeader,\n ToolInput,\n ToolOutput,\n statusFromToolState,\n type ToolPart,\n} from \"./tool\";\nimport {\n buildPartGroups,\n defaultPartStatus,\n groupPartByType,\n partsFingerprint,\n type GetPartStatus,\n type GroupablePart,\n type GroupBy,\n type GroupedNode,\n type GroupStatus,\n type PartGroupNode,\n} from \"./part-groups\";\n\n// ─── Render-prop args ─────────────────────────────────────────────────────────\n\nexport interface GroupedPartRenderArgs<T extends GroupablePart> {\n /** The real part (leaf) or the synthetic group node. */\n part: T | PartGroupNode;\n /** True when `part` is a synthetic group node. */\n isGroup: boolean;\n /** The rendered subtree — group nodes only. */\n children?: ReactNode;\n /** Rolled-up status (groups) or the part's status (leaves). */\n status: GroupStatus;\n /** Original part indices under this group (groups only). */\n indices?: number[];\n /** Original part index (leaves only). */\n index?: number;\n}\n\nexport type GroupedPartRenderer<T extends GroupablePart> = (\n args: GroupedPartRenderArgs<T>,\n) => ReactNode;\n\n// ─── Default renderers ────────────────────────────────────────────────────────\n\nfunction DefaultGroup({\n status,\n count,\n children,\n}: {\n status: GroupStatus;\n count: number;\n children: ReactNode;\n}) {\n const running = status === \"running\";\n return (\n <Collapsible defaultOpen={running} className=\"not-prose w-full rounded-md border border-border\">\n <CollapsibleTrigger\n className={cn(\n \"group flex w-full items-center gap-2 p-3 text-body text-muted-foreground\",\n \"transition-colors duration-fast ease-standard hover:text-foreground motion-reduce:transition-none\",\n \"focus-ring-inset\",\n )}\n >\n <BrainIcon aria-hidden=\"true\" className=\"size-4 shrink-0\" />\n <span className=\"flex-1 text-start\">{running ? \"Working…\" : \"Thought process\"}</span>\n {count > 0 && (\n <Badge variant=\"secondary\" className=\"shrink-0\">\n {count}\n </Badge>\n )}\n <ChevronDownIcon\n aria-hidden=\"true\"\n className=\"size-4 shrink-0 transition-transform group-data-[state=open]:rotate-180 motion-reduce:transition-none\"\n />\n </CollapsibleTrigger>\n <CollapsibleContent className=\"space-y-3 p-3 pt-0\">{children}</CollapsibleContent>\n </Collapsible>\n );\n}\n\nfunction defaultRenderPart<T extends GroupablePart>(args: GroupedPartRenderArgs<T>): ReactNode {\n if (args.isGroup) {\n return (\n <DefaultGroup status={args.status} count={args.indices?.length ?? 0}>\n {args.children}\n </DefaultGroup>\n );\n }\n\n const part = args.part as GroupablePart;\n const streaming = args.status === \"running\";\n\n // Reasoning → the branded Reasoning disclosure.\n if (part.type === \"reasoning\" || part.type.startsWith(\"reasoning\")) {\n const text = typeof part.text === \"string\" ? part.text : \"\";\n return (\n <Reasoning isStreaming={streaming} defaultOpen={streaming}>\n <ReasoningTrigger />\n <ReasoningContent>{text}</ReasoningContent>\n </Reasoning>\n );\n }\n\n // Tool call → the branded Tool disclosure (defensive: parts are plain objects).\n if (part.type.startsWith(\"tool-\") || part.type === \"dynamic-tool\") {\n const p = part as Record<string, unknown>;\n const headerProps = {\n type: p.type,\n state: p.state ?? \"input-available\",\n toolName: p.type === \"dynamic-tool\" ? p.toolName : undefined,\n } as ComponentProps<typeof ToolHeader>;\n // The output area must reflect an in-flight call, not just a settled one\n // (loading-states.md / #269): a `tool-*` part in `input-streaming` (or\n // `input-available`, before output/error land) is \"pending\", so\n // `ToolOutput` renders its skeleton instead of nothing.\n const toolStreaming =\n statusFromToolState((p.state as ToolPart[\"state\"]) ?? \"input-available\") === \"pending\";\n return (\n <Tool>\n <ToolHeader {...headerProps} />\n <ToolContent>\n {p.input !== undefined && <ToolInput input={p.input} />}\n {(toolStreaming || p.output !== undefined || Boolean(p.errorText)) && (\n <ToolOutput\n output={p.output}\n errorText={(p.errorText as string) ?? undefined}\n isStreaming={toolStreaming}\n />\n )}\n </ToolContent>\n </Tool>\n );\n }\n\n // Text → plain prose (consumers usually override with a markdown renderer).\n if (part.type === \"text\") {\n const text = typeof part.text === \"string\" ? part.text : \"\";\n return <div className=\"whitespace-pre-wrap text-body text-foreground\">{text}</div>;\n }\n\n // Unknown leaf types: nothing by default (supply a render-prop for coverage).\n return null;\n}\n\n// ─── GroupedParts ─────────────────────────────────────────────────────────────\n\nexport interface GroupedPartsProps<T extends GroupablePart> extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"children\"\n> {\n /** The ordered message parts to render. */\n parts: readonly T[];\n /** How to group parts. @default `groupPartByType()` */\n groupBy?: GroupBy<T>;\n /** Extract a part's status (drives group rollup + streaming affordances). */\n getStatus?: GetPartStatus<T>;\n /** Render-prop switching on `part.type`. Omit to use the default renderers. */\n children?: GroupedPartRenderer<T>;\n}\n\n/**\n * Renders `parts`, coalescing adjacent grouped parts into collapsible traces.\n * The tree only rebuilds when the parts' identity/type/status fingerprint\n * changes, so streaming token updates don't remount rows.\n */\nexport function GroupedParts<T extends GroupablePart>({\n parts,\n groupBy = groupPartByType<T>(),\n getStatus,\n children,\n className,\n ...props\n}: GroupedPartsProps<T>) {\n const fingerprint = partsFingerprint(parts, getStatus);\n const tree = useMemo<GroupedNode<T>[]>(\n () => buildPartGroups(parts, groupBy, getStatus),\n // Rebuild only on a structural change; `parts`/`groupBy`/`getStatus` identity\n // may churn per render, but the fingerprint is the real dependency.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [fingerprint, groupBy, getStatus],\n );\n\n const renderPart = children ?? defaultRenderPart<T>;\n const statusOf = (part: T): GroupStatus => getStatus?.(part) ?? defaultPartStatus(part);\n\n const renderNode = (node: GroupedNode<T>): ReactNode => {\n if (node.kind === \"leaf\") {\n return (\n <Fragment key={node.key}>\n {renderPart({\n part: node.part,\n isGroup: false,\n status: statusOf(node.part),\n index: node.index,\n })}\n </Fragment>\n );\n }\n const kids = node.children.map(renderNode);\n return (\n <Fragment key={node.key}>\n {renderPart({\n part: node.group,\n isGroup: true,\n status: node.group.status,\n indices: node.group.indices,\n children: <>{kids}</>,\n })}\n </Fragment>\n );\n };\n\n return (\n <div className={cn(\"flex w-full flex-col gap-3\", className)} {...props}>\n {tree.map(renderNode)}\n </div>\n );\n}\n"],"mappings":"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","names":["Fragment"]}