@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,245 @@
1
+ "use client";
2
+
3
+ // src/mic-selector.tsx
4
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
5
+ import { Button } from "@elabs-ai/components-ui";
6
+ import {
7
+ Command,
8
+ CommandEmpty,
9
+ CommandInput,
10
+ CommandItem,
11
+ CommandList
12
+ } from "@elabs-ai/components-ui";
13
+ import { Popover, PopoverContent, PopoverTrigger } from "@elabs-ai/components-ui";
14
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
15
+ import { useLocale } from "@elabs-ai/components-ui";
16
+ import { ChevronsUpDownIcon } from "lucide-react";
17
+ import {
18
+ createContext,
19
+ useCallback,
20
+ useContext,
21
+ useEffect,
22
+ useMemo,
23
+ useRef,
24
+ useState
25
+ } from "react";
26
+ import { jsx, jsxs } from "react/jsx-runtime";
27
+ var deviceIdRegex = /\(([\da-fA-F]{4}:[\da-fA-F]{4})\)$/;
28
+ var MicSelectorContext = createContext({
29
+ data: [],
30
+ onOpenChange: void 0,
31
+ onValueChange: void 0,
32
+ open: false,
33
+ setWidth: void 0,
34
+ value: void 0,
35
+ width: 200
36
+ });
37
+ var useAudioDevices = () => {
38
+ const [devices, setDevices] = useState([]);
39
+ const [loading, setLoading] = useState(true);
40
+ const [error, setError] = useState(null);
41
+ const [hasPermission, setHasPermission] = useState(false);
42
+ const loadDevicesWithoutPermission = useCallback(async () => {
43
+ try {
44
+ setLoading(true);
45
+ setError(null);
46
+ const deviceList = await navigator.mediaDevices.enumerateDevices();
47
+ const audioInputs = deviceList.filter((device) => device.kind === "audioinput");
48
+ setDevices(audioInputs);
49
+ } catch (caughtError) {
50
+ const message = caughtError instanceof Error ? caughtError.message : "Failed to get audio devices";
51
+ setError(message);
52
+ console.error("Error getting audio devices:", message);
53
+ } finally {
54
+ setLoading(false);
55
+ }
56
+ }, []);
57
+ const loadDevicesWithPermission = useCallback(async () => {
58
+ if (loading) {
59
+ return;
60
+ }
61
+ try {
62
+ setLoading(true);
63
+ setError(null);
64
+ const tempStream = await navigator.mediaDevices.getUserMedia({
65
+ audio: true
66
+ });
67
+ for (const track of tempStream.getTracks()) {
68
+ track.stop();
69
+ }
70
+ const deviceList = await navigator.mediaDevices.enumerateDevices();
71
+ const audioInputs = deviceList.filter((device) => device.kind === "audioinput");
72
+ setDevices(audioInputs);
73
+ setHasPermission(true);
74
+ } catch (caughtError) {
75
+ const message = caughtError instanceof Error ? caughtError.message : "Failed to get audio devices";
76
+ setError(message);
77
+ console.error("Error getting audio devices:", message);
78
+ } finally {
79
+ setLoading(false);
80
+ }
81
+ }, [loading]);
82
+ useEffect(() => {
83
+ loadDevicesWithoutPermission();
84
+ }, [loadDevicesWithoutPermission]);
85
+ useEffect(() => {
86
+ const handleDeviceChange = () => {
87
+ if (hasPermission) {
88
+ loadDevicesWithPermission();
89
+ } else {
90
+ loadDevicesWithoutPermission();
91
+ }
92
+ };
93
+ navigator.mediaDevices.addEventListener("devicechange", handleDeviceChange);
94
+ return () => {
95
+ navigator.mediaDevices.removeEventListener("devicechange", handleDeviceChange);
96
+ };
97
+ }, [hasPermission, loadDevicesWithPermission, loadDevicesWithoutPermission]);
98
+ return {
99
+ devices,
100
+ error,
101
+ hasPermission,
102
+ loadDevices: loadDevicesWithPermission,
103
+ loading
104
+ };
105
+ };
106
+ var MicSelector = ({
107
+ defaultValue,
108
+ value: controlledValue,
109
+ onValueChange: controlledOnValueChange,
110
+ defaultOpen = false,
111
+ open: controlledOpen,
112
+ onOpenChange: controlledOnOpenChange,
113
+ ...props
114
+ }) => {
115
+ const [value, onValueChange] = useControllableState({
116
+ defaultProp: defaultValue,
117
+ onChange: controlledOnValueChange,
118
+ prop: controlledValue
119
+ });
120
+ const [open, onOpenChange] = useControllableState({
121
+ defaultProp: defaultOpen,
122
+ onChange: controlledOnOpenChange,
123
+ prop: controlledOpen
124
+ });
125
+ const [width, setWidth] = useState(200);
126
+ const { devices, loading, hasPermission, loadDevices } = useAudioDevices();
127
+ useEffect(() => {
128
+ if (open && !hasPermission && !loading) {
129
+ loadDevices();
130
+ }
131
+ }, [open, hasPermission, loading, loadDevices]);
132
+ const contextValue = useMemo(
133
+ () => ({
134
+ data: devices,
135
+ onOpenChange,
136
+ onValueChange,
137
+ open,
138
+ setWidth,
139
+ value,
140
+ width
141
+ }),
142
+ [devices, onOpenChange, onValueChange, open, setWidth, value, width]
143
+ );
144
+ return /* @__PURE__ */ jsx(MicSelectorContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(Popover, { ...props, onOpenChange, open }) });
145
+ };
146
+ var MicSelectorTrigger = ({ children, ...props }) => {
147
+ const { setWidth } = useContext(MicSelectorContext);
148
+ const ref = useRef(null);
149
+ useEffect(() => {
150
+ const resizeObserver = new ResizeObserver((entries) => {
151
+ for (const entry of entries) {
152
+ const newWidth = entry.target.offsetWidth;
153
+ if (newWidth) {
154
+ setWidth?.(newWidth);
155
+ }
156
+ }
157
+ });
158
+ if (ref.current) {
159
+ resizeObserver.observe(ref.current);
160
+ }
161
+ return () => {
162
+ resizeObserver.disconnect();
163
+ };
164
+ }, [setWidth]);
165
+ return /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", ...props, ref, children: [
166
+ children,
167
+ /* @__PURE__ */ jsx(ChevronsUpDownIcon, { className: "shrink-0 text-muted-foreground", size: 16 })
168
+ ] }) });
169
+ };
170
+ var MicSelectorContent = ({
171
+ className,
172
+ popoverOptions,
173
+ ...props
174
+ }) => {
175
+ const { width, onValueChange, value } = useContext(MicSelectorContext);
176
+ return /* @__PURE__ */ jsx(PopoverContent, { className: cn("p-0", className), style: { width }, ...popoverOptions, children: /* @__PURE__ */ jsx(Command, { onValueChange, value, ...props }) });
177
+ };
178
+ var MicSelectorInput = ({ ...props }) => {
179
+ const { t } = useLocale();
180
+ return /* @__PURE__ */ jsx(CommandInput, { placeholder: t("ai.micSelector.searchPlaceholder"), ...props });
181
+ };
182
+ var MicSelectorList = ({ children, ...props }) => {
183
+ const { data } = useContext(MicSelectorContext);
184
+ return /* @__PURE__ */ jsx(CommandList, { ...props, children: children(data) });
185
+ };
186
+ var MicSelectorEmpty = ({
187
+ children = "No microphone found.",
188
+ ...props
189
+ }) => /* @__PURE__ */ jsx(CommandEmpty, { ...props, children });
190
+ var MicSelectorItem = (props) => {
191
+ const { onValueChange, onOpenChange } = useContext(MicSelectorContext);
192
+ const handleSelect = useCallback(
193
+ (currentValue) => {
194
+ onValueChange?.(currentValue);
195
+ onOpenChange?.(false);
196
+ },
197
+ [onValueChange, onOpenChange]
198
+ );
199
+ return /* @__PURE__ */ jsx(CommandItem, { onSelect: handleSelect, ...props });
200
+ };
201
+ var MicSelectorLabel = ({ device, className, ...props }) => {
202
+ const matches = device.label.match(deviceIdRegex);
203
+ if (!matches) {
204
+ return /* @__PURE__ */ jsx("span", { className, ...props, children: device.label });
205
+ }
206
+ const [, deviceId] = matches;
207
+ const name = device.label.replace(deviceIdRegex, "");
208
+ return /* @__PURE__ */ jsxs("span", { className, ...props, children: [
209
+ /* @__PURE__ */ jsx("span", { children: name }),
210
+ /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
211
+ " (",
212
+ deviceId,
213
+ ")"
214
+ ] })
215
+ ] });
216
+ };
217
+ var MicSelectorValue = ({ className, ...props }) => {
218
+ const { data, value } = useContext(MicSelectorContext);
219
+ const currentDevice = data.find((d) => d.deviceId === value);
220
+ if (!currentDevice) {
221
+ return /* @__PURE__ */ jsx("span", { className: cn("flex-1 text-start", className), ...props, children: "Select microphone..." });
222
+ }
223
+ return /* @__PURE__ */ jsx(
224
+ MicSelectorLabel,
225
+ {
226
+ className: cn("flex-1 text-start", className),
227
+ device: currentDevice,
228
+ ...props
229
+ }
230
+ );
231
+ };
232
+
233
+ export {
234
+ useAudioDevices,
235
+ MicSelector,
236
+ MicSelectorTrigger,
237
+ MicSelectorContent,
238
+ MicSelectorInput,
239
+ MicSelectorList,
240
+ MicSelectorEmpty,
241
+ MicSelectorItem,
242
+ MicSelectorLabel,
243
+ MicSelectorValue
244
+ };
245
+ //# sourceMappingURL=chunk-WYTZVSGK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mic-selector.tsx"],"sourcesContent":["\"use client\";\n\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { Button } from \"@elabs-ai/components-ui\";\nimport {\n Command,\n CommandEmpty,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@elabs-ai/components-ui\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport { useLocale } from \"@elabs-ai/components-ui\";\nimport { ChevronsUpDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nconst deviceIdRegex = /\\(([\\da-fA-F]{4}:[\\da-fA-F]{4})\\)$/;\n\ninterface MicSelectorContextType {\n data: MediaDeviceInfo[];\n value: string | undefined;\n onValueChange?: (value: string) => void;\n open: boolean;\n onOpenChange?: (open: boolean) => void;\n width: number;\n setWidth?: (width: number) => void;\n}\n\nconst MicSelectorContext = createContext<MicSelectorContextType>({\n data: [],\n onOpenChange: undefined,\n onValueChange: undefined,\n open: false,\n setWidth: undefined,\n value: undefined,\n width: 200,\n});\n\nexport const useAudioDevices = () => {\n const [devices, setDevices] = useState<MediaDeviceInfo[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [hasPermission, setHasPermission] = useState(false);\n\n const loadDevicesWithoutPermission = useCallback(async () => {\n try {\n setLoading(true);\n setError(null);\n\n const deviceList = await navigator.mediaDevices.enumerateDevices();\n const audioInputs = deviceList.filter((device) => device.kind === \"audioinput\");\n\n setDevices(audioInputs);\n } catch (caughtError) {\n const message =\n caughtError instanceof Error ? caughtError.message : \"Failed to get audio devices\";\n\n setError(message);\n console.error(\"Error getting audio devices:\", message);\n } finally {\n setLoading(false);\n }\n }, []);\n\n const loadDevicesWithPermission = useCallback(async () => {\n if (loading) {\n return;\n }\n\n try {\n setLoading(true);\n setError(null);\n\n const tempStream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n\n for (const track of tempStream.getTracks()) {\n track.stop();\n }\n\n const deviceList = await navigator.mediaDevices.enumerateDevices();\n const audioInputs = deviceList.filter((device) => device.kind === \"audioinput\");\n\n setDevices(audioInputs);\n setHasPermission(true);\n } catch (caughtError) {\n const message =\n caughtError instanceof Error ? caughtError.message : \"Failed to get audio devices\";\n\n setError(message);\n console.error(\"Error getting audio devices:\", message);\n } finally {\n setLoading(false);\n }\n }, [loading]);\n\n useEffect(() => {\n loadDevicesWithoutPermission();\n }, [loadDevicesWithoutPermission]);\n\n useEffect(() => {\n const handleDeviceChange = () => {\n if (hasPermission) {\n loadDevicesWithPermission();\n } else {\n loadDevicesWithoutPermission();\n }\n };\n\n navigator.mediaDevices.addEventListener(\"devicechange\", handleDeviceChange);\n\n return () => {\n navigator.mediaDevices.removeEventListener(\"devicechange\", handleDeviceChange);\n };\n }, [hasPermission, loadDevicesWithPermission, loadDevicesWithoutPermission]);\n\n return {\n devices,\n error,\n hasPermission,\n loadDevices: loadDevicesWithPermission,\n loading,\n };\n};\n\nexport type MicSelectorProps = ComponentProps<typeof Popover> & {\n defaultValue?: string;\n value?: string | undefined;\n onValueChange?: (value: string | undefined) => void;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n};\n\nexport const MicSelector = ({\n defaultValue,\n value: controlledValue,\n onValueChange: controlledOnValueChange,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n ...props\n}: MicSelectorProps) => {\n const [value, onValueChange] = useControllableState<string | undefined>({\n defaultProp: defaultValue,\n onChange: controlledOnValueChange,\n prop: controlledValue,\n });\n const [open, onOpenChange] = useControllableState({\n defaultProp: defaultOpen,\n onChange: controlledOnOpenChange,\n prop: controlledOpen,\n });\n const [width, setWidth] = useState(200);\n const { devices, loading, hasPermission, loadDevices } = useAudioDevices();\n\n useEffect(() => {\n if (open && !hasPermission && !loading) {\n loadDevices();\n }\n }, [open, hasPermission, loading, loadDevices]);\n\n const contextValue = useMemo(\n () => ({\n data: devices,\n onOpenChange,\n onValueChange,\n open,\n setWidth,\n value,\n width,\n }),\n [devices, onOpenChange, onValueChange, open, setWidth, value, width],\n );\n\n return (\n <MicSelectorContext.Provider value={contextValue}>\n <Popover {...props} onOpenChange={onOpenChange} open={open} />\n </MicSelectorContext.Provider>\n );\n};\n\nexport type MicSelectorTriggerProps = ComponentProps<typeof Button>;\n\nexport const MicSelectorTrigger = ({ children, ...props }: MicSelectorTriggerProps) => {\n const { setWidth } = useContext(MicSelectorContext);\n const ref = useRef<HTMLButtonElement>(null);\n\n useEffect(() => {\n // Create a ResizeObserver to detect width changes\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const newWidth = (entry.target as HTMLElement).offsetWidth;\n if (newWidth) {\n setWidth?.(newWidth);\n }\n }\n });\n\n if (ref.current) {\n resizeObserver.observe(ref.current);\n }\n\n // Clean up the observer when component unmounts\n return () => {\n resizeObserver.disconnect();\n };\n }, [setWidth]);\n\n return (\n <PopoverTrigger asChild>\n <Button variant=\"outline\" {...props} ref={ref}>\n {children}\n <ChevronsUpDownIcon className=\"shrink-0 text-muted-foreground\" size={16} />\n </Button>\n </PopoverTrigger>\n );\n};\n\nexport type MicSelectorContentProps = ComponentProps<typeof Command> & {\n popoverOptions?: ComponentProps<typeof PopoverContent>;\n};\n\nexport const MicSelectorContent = ({\n className,\n popoverOptions,\n ...props\n}: MicSelectorContentProps) => {\n const { width, onValueChange, value } = useContext(MicSelectorContext);\n\n return (\n <PopoverContent className={cn(\"p-0\", className)} style={{ width }} {...popoverOptions}>\n <Command onValueChange={onValueChange} value={value} {...props} />\n </PopoverContent>\n );\n};\n\nexport type MicSelectorInputProps = ComponentProps<typeof CommandInput> & {\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n};\n\nexport const MicSelectorInput = ({ ...props }: MicSelectorInputProps) => {\n const { t } = useLocale();\n return <CommandInput placeholder={t(\"ai.micSelector.searchPlaceholder\")} {...props} />;\n};\n\nexport type MicSelectorListProps = Omit<ComponentProps<typeof CommandList>, \"children\"> & {\n children: (devices: MediaDeviceInfo[]) => ReactNode;\n};\n\nexport const MicSelectorList = ({ children, ...props }: MicSelectorListProps) => {\n const { data } = useContext(MicSelectorContext);\n\n return <CommandList {...props}>{children(data)}</CommandList>;\n};\n\nexport type MicSelectorEmptyProps = ComponentProps<typeof CommandEmpty>;\n\nexport const MicSelectorEmpty = ({\n children = \"No microphone found.\",\n ...props\n}: MicSelectorEmptyProps) => <CommandEmpty {...props}>{children}</CommandEmpty>;\n\nexport type MicSelectorItemProps = ComponentProps<typeof CommandItem>;\n\nexport const MicSelectorItem = (props: MicSelectorItemProps) => {\n const { onValueChange, onOpenChange } = useContext(MicSelectorContext);\n\n const handleSelect = useCallback(\n (currentValue: string) => {\n onValueChange?.(currentValue);\n onOpenChange?.(false);\n },\n [onValueChange, onOpenChange],\n );\n\n return <CommandItem onSelect={handleSelect} {...props} />;\n};\n\nexport type MicSelectorLabelProps = ComponentProps<\"span\"> & {\n device: MediaDeviceInfo;\n};\n\nexport const MicSelectorLabel = ({ device, className, ...props }: MicSelectorLabelProps) => {\n const matches = device.label.match(deviceIdRegex);\n\n if (!matches) {\n return (\n <span className={className} {...props}>\n {device.label}\n </span>\n );\n }\n\n const [, deviceId] = matches;\n const name = device.label.replace(deviceIdRegex, \"\");\n\n return (\n <span className={className} {...props}>\n <span>{name}</span>\n <span className=\"text-muted-foreground\"> ({deviceId})</span>\n </span>\n );\n};\n\nexport type MicSelectorValueProps = ComponentProps<\"span\">;\n\nexport const MicSelectorValue = ({ className, ...props }: MicSelectorValueProps) => {\n const { data, value } = useContext(MicSelectorContext);\n const currentDevice = data.find((d) => d.deviceId === value);\n\n if (!currentDevice) {\n return (\n <span className={cn(\"flex-1 text-start\", className)} {...props}>\n Select microphone...\n </span>\n );\n }\n\n return (\n <MicSelectorLabel\n className={cn(\"flex-1 text-start\", className)}\n device={currentDevice}\n {...props}\n />\n );\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,187 @@
1
+ "use client";
2
+ import {
3
+ Shimmer
4
+ } from "./chunk-3YPT3V7L.js";
5
+ import {
6
+ getStreamdownPluginsKey,
7
+ useStreamdownMermaidOptions,
8
+ useStreamdownPlugins,
9
+ useStreamdownTranslations
10
+ } from "./chunk-PQBF6ZIQ.js";
11
+
12
+ // src/reasoning.tsx
13
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
14
+ import {
15
+ Collapsible,
16
+ CollapsibleContent,
17
+ CollapsibleTrigger,
18
+ useLocale
19
+ } from "@elabs-ai/components-ui";
20
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
21
+ import { BrainIcon, ChevronDownIcon } from "lucide-react";
22
+ import {
23
+ createContext,
24
+ memo,
25
+ useCallback,
26
+ useContext,
27
+ useEffect,
28
+ useMemo,
29
+ useRef,
30
+ useState
31
+ } from "react";
32
+ import { Streamdown } from "streamdown";
33
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
34
+ var ReasoningContext = createContext(null);
35
+ var useReasoning = () => {
36
+ const context = useContext(ReasoningContext);
37
+ if (!context) {
38
+ throw new Error("Reasoning components must be used within Reasoning");
39
+ }
40
+ return context;
41
+ };
42
+ var AUTO_CLOSE_DELAY = 1e3;
43
+ var MS_IN_S = 1e3;
44
+ var Reasoning = memo(
45
+ ({
46
+ className,
47
+ isStreaming = false,
48
+ open,
49
+ defaultOpen,
50
+ onOpenChange,
51
+ duration: durationProp,
52
+ children,
53
+ ...props
54
+ }) => {
55
+ const resolvedDefaultOpen = defaultOpen ?? isStreaming;
56
+ const isExplicitlyClosed = defaultOpen === false;
57
+ const [isOpen, setIsOpen] = useControllableState({
58
+ defaultProp: resolvedDefaultOpen,
59
+ onChange: onOpenChange,
60
+ prop: open
61
+ });
62
+ const [duration, setDuration] = useControllableState({
63
+ defaultProp: void 0,
64
+ prop: durationProp
65
+ });
66
+ const hasEverStreamedRef = useRef(isStreaming);
67
+ const [hasAutoClosed, setHasAutoClosed] = useState(false);
68
+ const startTimeRef = useRef(null);
69
+ useEffect(() => {
70
+ if (isStreaming) {
71
+ hasEverStreamedRef.current = true;
72
+ if (startTimeRef.current === null) {
73
+ startTimeRef.current = Date.now();
74
+ }
75
+ } else if (startTimeRef.current !== null) {
76
+ setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S));
77
+ startTimeRef.current = null;
78
+ }
79
+ }, [isStreaming, setDuration]);
80
+ useEffect(() => {
81
+ if (isStreaming && !isOpen && !isExplicitlyClosed) {
82
+ setIsOpen(true);
83
+ }
84
+ }, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);
85
+ useEffect(() => {
86
+ if (hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {
87
+ const timer = setTimeout(() => {
88
+ setIsOpen(false);
89
+ setHasAutoClosed(true);
90
+ }, AUTO_CLOSE_DELAY);
91
+ return () => clearTimeout(timer);
92
+ }
93
+ }, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);
94
+ const handleOpenChange = useCallback(
95
+ (newOpen) => {
96
+ setIsOpen(newOpen);
97
+ },
98
+ [setIsOpen]
99
+ );
100
+ const contextValue = useMemo(
101
+ () => ({ duration, isOpen, isStreaming, setIsOpen }),
102
+ [duration, isOpen, isStreaming, setIsOpen]
103
+ );
104
+ return /* @__PURE__ */ jsx(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
105
+ Collapsible,
106
+ {
107
+ className: cn("not-prose mb-4", className),
108
+ onOpenChange: handleOpenChange,
109
+ open: isOpen,
110
+ ...props,
111
+ children
112
+ }
113
+ ) });
114
+ }
115
+ );
116
+ var defaultGetThinkingMessage = (isStreaming, duration, t) => {
117
+ if (isStreaming || duration === 0) {
118
+ return /* @__PURE__ */ jsx(Shimmer, { duration: 1, children: t("ai.reasoning.thinking") });
119
+ }
120
+ if (duration === void 0) {
121
+ return /* @__PURE__ */ jsx("p", { children: t("ai.reasoning.thoughtDefault") });
122
+ }
123
+ return /* @__PURE__ */ jsx("p", { children: t("ai.reasoning.thoughtForDuration", { duration }) });
124
+ };
125
+ var ReasoningTrigger = memo(
126
+ ({ className, children, getThinkingMessage, ...props }) => {
127
+ const { isStreaming, isOpen, duration } = useReasoning();
128
+ const { t } = useLocale();
129
+ return /* @__PURE__ */ jsx(
130
+ CollapsibleTrigger,
131
+ {
132
+ className: cn(
133
+ "flex w-full items-center gap-2 text-muted-foreground text-body transition-colors hover:text-foreground focus-ring",
134
+ className
135
+ ),
136
+ ...props,
137
+ children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
138
+ /* @__PURE__ */ jsx(BrainIcon, { className: "size-4" }),
139
+ getThinkingMessage ? getThinkingMessage(isStreaming, duration) : defaultGetThinkingMessage(isStreaming, duration, t),
140
+ /* @__PURE__ */ jsx(
141
+ ChevronDownIcon,
142
+ {
143
+ className: cn("size-4 transition-transform", isOpen ? "rotate-180" : "rotate-0")
144
+ }
145
+ )
146
+ ] })
147
+ }
148
+ );
149
+ }
150
+ );
151
+ var ReasoningContent = memo(({ className, children, ...props }) => {
152
+ const translations = useStreamdownTranslations();
153
+ const plugins = useStreamdownPlugins(typeof children === "string" ? children : "");
154
+ const mermaidOptions = useStreamdownMermaidOptions();
155
+ return /* @__PURE__ */ jsx(
156
+ CollapsibleContent,
157
+ {
158
+ className: cn(
159
+ "mt-4 text-body",
160
+ "data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=open]:[--tw-ease:var(--ease-entrance)] data-[state=closed]:[--tw-ease:var(--ease-exit)]",
161
+ className
162
+ ),
163
+ ...props,
164
+ children: typeof children === "string" ? /* @__PURE__ */ jsx(
165
+ Streamdown,
166
+ {
167
+ plugins,
168
+ translations,
169
+ mermaid: mermaidOptions,
170
+ children
171
+ },
172
+ getStreamdownPluginsKey(plugins)
173
+ ) : children
174
+ }
175
+ );
176
+ });
177
+ Reasoning.displayName = "Reasoning";
178
+ ReasoningTrigger.displayName = "ReasoningTrigger";
179
+ ReasoningContent.displayName = "ReasoningContent";
180
+
181
+ export {
182
+ useReasoning,
183
+ Reasoning,
184
+ ReasoningTrigger,
185
+ ReasoningContent
186
+ };
187
+ //# sourceMappingURL=chunk-X47QMM6K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/reasoning.tsx"],"sourcesContent":["\"use client\";\n\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n useLocale,\n} from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport {\n getStreamdownPluginsKey,\n useStreamdownMermaidOptions,\n useStreamdownPlugins,\n useStreamdownTranslations,\n} from \"./_streamdown-i18n\";\nimport { BrainIcon, ChevronDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Streamdown } from \"streamdown\";\n\nimport { Shimmer } from \"./shimmer\";\n\ninterface ReasoningContextValue {\n isStreaming: boolean;\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n duration: number | undefined;\n}\n\nconst ReasoningContext = createContext<ReasoningContextValue | null>(null);\n\nexport const useReasoning = () => {\n const context = useContext(ReasoningContext);\n if (!context) {\n throw new Error(\"Reasoning components must be used within Reasoning\");\n }\n return context;\n};\n\nexport type ReasoningProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n duration?: number;\n};\n\nconst AUTO_CLOSE_DELAY = 1000;\nconst MS_IN_S = 1000;\n\nexport const Reasoning = memo(\n ({\n className,\n isStreaming = false,\n open,\n defaultOpen,\n onOpenChange,\n duration: durationProp,\n children,\n ...props\n }: ReasoningProps) => {\n const resolvedDefaultOpen = defaultOpen ?? isStreaming;\n // Track if defaultOpen was explicitly set to false (to prevent auto-open)\n const isExplicitlyClosed = defaultOpen === false;\n\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: resolvedDefaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n const [duration, setDuration] = useControllableState<number | undefined>({\n defaultProp: undefined,\n prop: durationProp,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n const startTimeRef = useRef<number | null>(null);\n\n // Track when streaming starts and compute duration\n useEffect(() => {\n if (isStreaming) {\n hasEverStreamedRef.current = true;\n if (startTimeRef.current === null) {\n startTimeRef.current = Date.now();\n }\n } else if (startTimeRef.current !== null) {\n setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S));\n startTimeRef.current = null;\n }\n }, [isStreaming, setDuration]);\n\n // Auto-open when streaming starts (unless explicitly closed)\n useEffect(() => {\n if (isStreaming && !isOpen && !isExplicitlyClosed) {\n setIsOpen(true);\n }\n }, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);\n\n // Auto-close when streaming ends (once only, and only if it ever streamed)\n useEffect(() => {\n if (hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n\n return () => clearTimeout(timer);\n }\n }, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n },\n [setIsOpen],\n );\n\n const contextValue = useMemo(\n () => ({ duration, isOpen, isStreaming, setIsOpen }),\n [duration, isOpen, isStreaming, setIsOpen],\n );\n\n return (\n <ReasoningContext.Provider value={contextValue}>\n <Collapsible\n className={cn(\"not-prose mb-4\", className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n >\n {children}\n </Collapsible>\n </ReasoningContext.Provider>\n );\n },\n);\n\nexport type ReasoningTriggerProps = ComponentProps<typeof CollapsibleTrigger> & {\n getThinkingMessage?: (isStreaming: boolean, duration?: number) => ReactNode;\n};\n\nconst defaultGetThinkingMessage = (\n isStreaming: boolean,\n duration: number | undefined,\n t: (key: string, vars?: Record<string, string | number>) => string,\n) => {\n if (isStreaming || duration === 0) {\n return <Shimmer duration={1}>{t(\"ai.reasoning.thinking\")}</Shimmer>;\n }\n if (duration === undefined) {\n return <p>{t(\"ai.reasoning.thoughtDefault\")}</p>;\n }\n return <p>{t(\"ai.reasoning.thoughtForDuration\", { duration })}</p>;\n};\n\nexport const ReasoningTrigger = memo(\n ({ className, children, getThinkingMessage, ...props }: ReasoningTriggerProps) => {\n const { isStreaming, isOpen, duration } = useReasoning();\n const { t } = useLocale();\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"flex w-full items-center gap-2 text-muted-foreground text-body transition-colors hover:text-foreground focus-ring\",\n className,\n )}\n {...props}\n >\n {children ?? (\n <>\n <BrainIcon className=\"size-4\" />\n {getThinkingMessage\n ? getThinkingMessage(isStreaming, duration)\n : defaultGetThinkingMessage(isStreaming, duration, t)}\n <ChevronDownIcon\n className={cn(\"size-4 transition-transform\", isOpen ? \"rotate-180\" : \"rotate-0\")}\n />\n </>\n )}\n </CollapsibleTrigger>\n );\n },\n);\n\nexport type ReasoningContentProps = Omit<ComponentProps<typeof CollapsibleContent>, \"children\"> & {\n /**\n * The reasoning body.\n *\n * A **string** is rendered as streamed markdown (Streamdown) — the default for\n * model reasoning text. Any other node renders **as-is**, so a structured live\n * ledger (a timeline, per-step status) can live inside the disclosure without\n * being handed to a markdown parser. Mirrors the `getThinkingMessage` /\n * `children` override seam on `ReasoningTrigger`.\n *\n * Note an **array** of strings is not a `string` — `{[\"a\", \"b\"]}` renders raw.\n * Pass one string if you want it parsed as markdown.\n */\n children: ReactNode;\n};\n\nexport const ReasoningContent = memo(({ className, children, ...props }: ReasoningContentProps) => {\n // Streamdown's own chrome (code copy, table menus) reads the locale seam (#310).\n const translations = useStreamdownTranslations();\n // Brand-token-derived `code` plugin, not the package's static github-*\n // default (#315 follow-up) — re-derives when the active theme changes.\n // `math`/`cjk` are lazy-loaded off the raw text (#perf-5, see\n // `_streamdown-i18n.ts`) — pass `children` so they load only when this\n // reasoning block actually needs them.\n const plugins = useStreamdownPlugins(typeof children === \"string\" ? children : \"\");\n // The TOP-LEVEL Streamdown `mermaid` prop — catches a failed diagram\n // render, including a missing `mermaid` optional peer (issue #33).\n const mermaidOptions = useStreamdownMermaidOptions();\n\n return (\n <CollapsibleContent\n className={cn(\n \"mt-4 text-body\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=open]:[--tw-ease:var(--ease-entrance)] data-[state=closed]:[--tw-ease:var(--ease-exit)]\",\n className,\n )}\n {...props}\n >\n {typeof children === \"string\" ? (\n <Streamdown\n // Forces a remount the first time the lazy math/cjk slot resolves —\n // see `getStreamdownPluginsKey`'s doc in `_streamdown-i18n.ts` for why.\n key={getStreamdownPluginsKey(plugins)}\n plugins={plugins}\n translations={translations}\n mermaid={mermaidOptions}\n >\n {children}\n </Streamdown>\n ) : (\n children\n )}\n </CollapsibleContent>\n );\n});\n\nReasoning.displayName = \"Reasoning\";\nReasoningTrigger.displayName = \"ReasoningTrigger\";\nReasoningContent.displayName = \"ReasoningContent\";\n"],"mappings":"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","names":[]}
@@ -0,0 +1,40 @@
1
+ "use client";
2
+
3
+ // src/persona-sources.ts
4
+ var PERSONA_SOURCES = {
5
+ command: {
6
+ dynamicColor: true,
7
+ hasModel: true,
8
+ source: "https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/command-2.0.riv"
9
+ },
10
+ glint: {
11
+ dynamicColor: true,
12
+ hasModel: true,
13
+ source: "https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/glint-2.0.riv"
14
+ },
15
+ halo: {
16
+ dynamicColor: true,
17
+ hasModel: true,
18
+ source: "https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/halo-2.0.riv"
19
+ },
20
+ mana: {
21
+ dynamicColor: false,
22
+ hasModel: true,
23
+ source: "https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/mana-2.0.riv"
24
+ },
25
+ obsidian: {
26
+ dynamicColor: true,
27
+ hasModel: true,
28
+ source: "https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/obsidian-2.0.riv"
29
+ },
30
+ opal: {
31
+ dynamicColor: false,
32
+ hasModel: false,
33
+ source: "https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/orb-1.2.riv"
34
+ }
35
+ };
36
+
37
+ export {
38
+ PERSONA_SOURCES
39
+ };
40
+ //# sourceMappingURL=chunk-YHUSW7D2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/persona-sources.ts"],"sourcesContent":["/**\n * Persona artwork sources — a plain data module shared by `persona.tsx` (the\n * public shell) and `_persona-rive.tsx` (the lazily-loaded Rive half), so\n * neither has to import the other.\n */\n\nexport type PersonaState = \"idle\" | \"listening\" | \"thinking\" | \"speaking\" | \"asleep\";\n\nexport interface PersonaSource {\n /** The artwork exposes a colour view-model that follows the light/dark theme. */\n dynamicColor: boolean;\n /** The artwork has a Rive view-model (vs. a plain state machine). */\n hasModel: boolean;\n /** Absolute URL of the `.riv` artwork. */\n source: string;\n}\n\n/**\n * Where the shipped `.riv` artwork is fetched from.\n *\n * ⚠️ These are REMOTE origins fetched at runtime by the Rive runtime — a\n * deployment with a restrictive `connect-src` blocks them, and the component\n * falls back to a token-driven orb. Self-host the six files and pass\n * `<Persona src={…}>` to point at your own copies. See `docs/CSP-AND-NETWORK.md`.\n */\nexport const PERSONA_SOURCES = {\n command: {\n dynamicColor: true,\n hasModel: true,\n source: \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/command-2.0.riv\",\n },\n glint: {\n dynamicColor: true,\n hasModel: true,\n source: \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/glint-2.0.riv\",\n },\n halo: {\n dynamicColor: true,\n hasModel: true,\n source: \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/halo-2.0.riv\",\n },\n mana: {\n dynamicColor: false,\n hasModel: true,\n source: \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/mana-2.0.riv\",\n },\n obsidian: {\n dynamicColor: true,\n hasModel: true,\n source: \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/obsidian-2.0.riv\",\n },\n opal: {\n dynamicColor: false,\n hasModel: false,\n source: \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/orb-1.2.riv\",\n },\n} as const satisfies Record<string, PersonaSource>;\n\nexport type PersonaVariant = keyof typeof PERSONA_SOURCES;\n"],"mappings":";;;AAyBO,IAAM,kBAAkB;AAAA,EAC7B,SAAS;AAAA,IACP,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAAA,EACA,OAAO;AAAA,IACL,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAAA,EACA,MAAM;AAAA,IACJ,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAAA,EACA,MAAM;AAAA,IACJ,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAAA,EACA,UAAU;AAAA,IACR,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAAA,EACA,MAAM;AAAA,IACJ,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AACF;","names":[]}
@@ -0,0 +1,126 @@
1
+ "use client";
2
+
3
+ // src/part-groups.ts
4
+ var RUNNING_STATES = /* @__PURE__ */ new Set([
5
+ "input-streaming",
6
+ "input-available",
7
+ "approval-requested",
8
+ "approval-responded",
9
+ "calling",
10
+ "streaming",
11
+ "in-progress"
12
+ ]);
13
+ var ERROR_STATES = /* @__PURE__ */ new Set(["output-error", "error", "failed"]);
14
+ var COMPLETE_STATES = /* @__PURE__ */ new Set(["output-available", "output-denied", "done", "complete"]);
15
+ function defaultPartStatus(part) {
16
+ if (part.isStreaming === true) return "running";
17
+ const state = typeof part.state === "string" ? part.state : void 0;
18
+ if (state) {
19
+ if (ERROR_STATES.has(state)) return "error";
20
+ if (RUNNING_STATES.has(state)) return "running";
21
+ if (COMPLETE_STATES.has(state)) return "complete";
22
+ }
23
+ if (part.errorText || part.error) return "error";
24
+ return "complete";
25
+ }
26
+ function rollupStatus(statuses) {
27
+ if (statuses.some((s) => s === "running")) return "running";
28
+ if (statuses.some((s) => s === "error")) return "error";
29
+ if (statuses.some((s) => s === "pending")) return "pending";
30
+ return "complete";
31
+ }
32
+ function leafKey(part, index) {
33
+ const id = typeof part.id === "string" && part.id || typeof part.toolCallId === "string" && part.toolCallId || null;
34
+ return id ?? `${part.type}#${index}`;
35
+ }
36
+ function buildLevel(entries, statusOf) {
37
+ const out = [];
38
+ let i = 0;
39
+ while (i < entries.length) {
40
+ const entry = entries[i];
41
+ if (entry.path.length === 0) {
42
+ out.push({
43
+ kind: "leaf",
44
+ key: leafKey(entry.part, entry.index),
45
+ index: entry.index,
46
+ part: entry.part
47
+ });
48
+ i += 1;
49
+ continue;
50
+ }
51
+ const key0 = entry.path[0];
52
+ const run = [];
53
+ let j = i;
54
+ while (j < entries.length && entries[j].path.length > 0 && entries[j].path[0] === key0) {
55
+ run.push(entries[j]);
56
+ j += 1;
57
+ }
58
+ const childEntries = run.map((r) => ({
59
+ part: r.part,
60
+ index: r.index,
61
+ path: r.path.slice(1)
62
+ }));
63
+ const children = buildLevel(childEntries, statusOf);
64
+ const indices = run.map((r) => r.index);
65
+ const status = rollupStatus(run.map((r) => statusOf(r.part)));
66
+ out.push({
67
+ kind: "group",
68
+ // First member index keeps the group key stable across append-only streams.
69
+ key: `${key0}@${run[0].index}`,
70
+ group: { type: key0, status, indices },
71
+ children
72
+ });
73
+ i = j;
74
+ }
75
+ return out;
76
+ }
77
+ function buildPartGroups(parts, groupBy, getStatus) {
78
+ const statusOf = (part) => getStatus?.(part) ?? defaultPartStatus(part);
79
+ const entries = parts.map((part, index) => {
80
+ let path = [];
81
+ try {
82
+ path = groupBy(part, { index, parts }) ?? [];
83
+ } catch {
84
+ path = [];
85
+ }
86
+ return { part, index, path };
87
+ });
88
+ return buildLevel(entries, statusOf);
89
+ }
90
+ function partsFingerprint(parts, getStatus) {
91
+ return parts.map((part, index) => {
92
+ const status = getStatus?.(part) ?? defaultPartStatus(part);
93
+ return `${leafKey(part, index)}:${part.type}:${status}`;
94
+ }).join("|");
95
+ }
96
+ var DEFAULT_INLINE = [/^reasoning$/, /^tool-/, "dynamic-tool", "step-start"];
97
+ var DEFAULT_STANDALONE = [/approval/i, /human/i, "confirmation"];
98
+ function matchesAny(type, patterns) {
99
+ return patterns.some((p) => typeof p === "string" ? p === type : p.test(type));
100
+ }
101
+ function groupPartByType(options = {}) {
102
+ const groupKey = options.groupKey ?? "group-work";
103
+ const inline = options.inline ?? DEFAULT_INLINE;
104
+ const standalone = options.standalone ?? DEFAULT_STANDALONE;
105
+ return (part) => {
106
+ const explicit = options.classify?.(part);
107
+ if (explicit === "standalone") return [];
108
+ if (explicit === "inline") return [groupKey];
109
+ if (matchesAny(part.type, standalone)) return [];
110
+ if (matchesAny(part.type, inline)) return [groupKey];
111
+ return [];
112
+ };
113
+ }
114
+ function isGroupNode(part) {
115
+ return part.type.startsWith("group-");
116
+ }
117
+
118
+ export {
119
+ defaultPartStatus,
120
+ rollupStatus,
121
+ buildPartGroups,
122
+ partsFingerprint,
123
+ groupPartByType,
124
+ isGroupNode
125
+ };
126
+ //# sourceMappingURL=chunk-YSKD7UXX.js.map