@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,1076 @@
1
+ "use client";
2
+
3
+ // src/prompt-input.tsx
4
+ import {
5
+ Command,
6
+ CommandEmpty,
7
+ CommandGroup,
8
+ CommandInput,
9
+ CommandItem,
10
+ CommandList,
11
+ CommandSeparator
12
+ } from "@elabs-ai/components-ui";
13
+ import {
14
+ DropdownMenu,
15
+ DropdownMenuContent,
16
+ DropdownMenuItem,
17
+ DropdownMenuTrigger
18
+ } from "@elabs-ai/components-ui";
19
+ import { HoverCard, HoverCardContent, HoverCardTrigger } from "@elabs-ai/components-ui";
20
+ import {
21
+ InputGroup,
22
+ InputGroupAddon,
23
+ InputGroupButton,
24
+ InputGroupTextarea
25
+ } from "@elabs-ai/components-ui";
26
+ import {
27
+ Select,
28
+ SelectContent,
29
+ SelectItem,
30
+ SelectTrigger,
31
+ SelectValue
32
+ } from "@elabs-ai/components-ui";
33
+ import { Spinner } from "@elabs-ai/components-ui";
34
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@elabs-ai/components-ui";
35
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
36
+ import { useLocale } from "@elabs-ai/components-ui";
37
+ import { CornerDownLeftIcon, ImageIcon, Monitor, PlusIcon, SquareIcon, XIcon } from "lucide-react";
38
+ import { nanoid } from "nanoid";
39
+ import {
40
+ Children,
41
+ createContext,
42
+ isValidElement,
43
+ useCallback,
44
+ useContext,
45
+ useEffect,
46
+ useMemo,
47
+ useRef,
48
+ useState
49
+ } from "react";
50
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
51
+ var convertBlobUrlToDataUrl = async (url) => {
52
+ try {
53
+ const response = await fetch(url);
54
+ const blob = await response.blob();
55
+ return new Promise((resolve) => {
56
+ const reader = new FileReader();
57
+ reader.onloadend = () => resolve(reader.result);
58
+ reader.onerror = () => resolve(null);
59
+ reader.readAsDataURL(blob);
60
+ });
61
+ } catch {
62
+ return null;
63
+ }
64
+ };
65
+ var captureScreenshot = async () => {
66
+ if (typeof navigator === "undefined" || !navigator.mediaDevices?.getDisplayMedia) {
67
+ return null;
68
+ }
69
+ let stream = null;
70
+ const video = document.createElement("video");
71
+ video.muted = true;
72
+ video.playsInline = true;
73
+ try {
74
+ stream = await navigator.mediaDevices.getDisplayMedia({
75
+ audio: false,
76
+ video: true
77
+ });
78
+ video.srcObject = stream;
79
+ await new Promise((resolve, reject) => {
80
+ video.onloadedmetadata = () => resolve();
81
+ video.onerror = () => reject(new Error("Failed to load screen stream"));
82
+ });
83
+ await video.play();
84
+ const width = video.videoWidth;
85
+ const height = video.videoHeight;
86
+ if (!width || !height) {
87
+ return null;
88
+ }
89
+ const canvas = document.createElement("canvas");
90
+ canvas.width = width;
91
+ canvas.height = height;
92
+ const context = canvas.getContext("2d");
93
+ if (!context) {
94
+ return null;
95
+ }
96
+ context.drawImage(video, 0, 0, width, height);
97
+ const blob = await new Promise((resolve) => {
98
+ canvas.toBlob(resolve, "image/png");
99
+ });
100
+ if (!blob) {
101
+ return null;
102
+ }
103
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(/[:.]/g, "-").replace("T", "_").replace("Z", "");
104
+ return new File([blob], `screenshot-${timestamp}.png`, {
105
+ lastModified: Date.now(),
106
+ type: "image/png"
107
+ });
108
+ } finally {
109
+ if (stream) {
110
+ for (const track of stream.getTracks()) {
111
+ track.stop();
112
+ }
113
+ }
114
+ video.pause();
115
+ video.srcObject = null;
116
+ }
117
+ };
118
+ var PromptInputController = createContext(null);
119
+ var ProviderAttachmentsContext = createContext(null);
120
+ var usePromptInputController = () => {
121
+ const ctx = useContext(PromptInputController);
122
+ if (!ctx) {
123
+ throw new Error(
124
+ "Wrap your component inside <PromptInputProvider> to use usePromptInputController()."
125
+ );
126
+ }
127
+ return ctx;
128
+ };
129
+ var useOptionalPromptInputController = () => useContext(PromptInputController);
130
+ var useProviderAttachments = () => {
131
+ const ctx = useContext(ProviderAttachmentsContext);
132
+ if (!ctx) {
133
+ throw new Error(
134
+ "Wrap your component inside <PromptInputProvider> to use useProviderAttachments()."
135
+ );
136
+ }
137
+ return ctx;
138
+ };
139
+ var useOptionalProviderAttachments = () => useContext(ProviderAttachmentsContext);
140
+ var PromptInputProvider = ({
141
+ initialInput: initialTextInput = "",
142
+ children
143
+ }) => {
144
+ const [textInput, setTextInput] = useState(initialTextInput);
145
+ const clearInput = useCallback(() => setTextInput(""), []);
146
+ const [attachmentFiles, setAttachmentFiles] = useState([]);
147
+ const fileInputRef = useRef(null);
148
+ const openRef = useRef(() => {
149
+ });
150
+ const add = useCallback((files) => {
151
+ const incoming = [...files];
152
+ if (incoming.length === 0) {
153
+ return;
154
+ }
155
+ setAttachmentFiles((prev) => [
156
+ ...prev,
157
+ ...incoming.map((file) => ({
158
+ filename: file.name,
159
+ id: nanoid(),
160
+ mediaType: file.type,
161
+ type: "file",
162
+ url: URL.createObjectURL(file)
163
+ }))
164
+ ]);
165
+ }, []);
166
+ const remove = useCallback((id) => {
167
+ setAttachmentFiles((prev) => {
168
+ const found = prev.find((f) => f.id === id);
169
+ if (found?.url) {
170
+ URL.revokeObjectURL(found.url);
171
+ }
172
+ return prev.filter((f) => f.id !== id);
173
+ });
174
+ }, []);
175
+ const clear = useCallback(() => {
176
+ setAttachmentFiles((prev) => {
177
+ for (const f of prev) {
178
+ if (f.url) {
179
+ URL.revokeObjectURL(f.url);
180
+ }
181
+ }
182
+ return [];
183
+ });
184
+ }, []);
185
+ const attachmentsRef = useRef(attachmentFiles);
186
+ useEffect(() => {
187
+ attachmentsRef.current = attachmentFiles;
188
+ }, [attachmentFiles]);
189
+ useEffect(
190
+ () => () => {
191
+ for (const f of attachmentsRef.current) {
192
+ if (f.url) {
193
+ URL.revokeObjectURL(f.url);
194
+ }
195
+ }
196
+ },
197
+ []
198
+ );
199
+ const openFileDialog = useCallback(() => {
200
+ openRef.current?.();
201
+ }, []);
202
+ const attachments = useMemo(
203
+ () => ({
204
+ add,
205
+ clear,
206
+ fileInputRef,
207
+ files: attachmentFiles,
208
+ openFileDialog,
209
+ remove
210
+ }),
211
+ [attachmentFiles, add, remove, clear, openFileDialog]
212
+ );
213
+ const __registerFileInput = useCallback(
214
+ (ref, open) => {
215
+ fileInputRef.current = ref.current;
216
+ openRef.current = open;
217
+ },
218
+ []
219
+ );
220
+ const controller = useMemo(
221
+ () => ({
222
+ __registerFileInput,
223
+ attachments,
224
+ textInput: {
225
+ clear: clearInput,
226
+ setInput: setTextInput,
227
+ value: textInput
228
+ }
229
+ }),
230
+ [textInput, clearInput, attachments, __registerFileInput]
231
+ );
232
+ return /* @__PURE__ */ jsx(PromptInputController.Provider, { value: controller, children: /* @__PURE__ */ jsx(ProviderAttachmentsContext.Provider, { value: attachments, children }) });
233
+ };
234
+ var LocalAttachmentsContext = createContext(null);
235
+ var PromptInputSubmitStateContext = createContext(
236
+ null
237
+ );
238
+ var useOptionalSubmitState = () => useContext(PromptInputSubmitStateContext);
239
+ var SUBMIT_SLOT = "prompt-input-submit";
240
+ var usePromptInputAttachments = () => {
241
+ const provider = useOptionalProviderAttachments();
242
+ const local = useContext(LocalAttachmentsContext);
243
+ const context = local ?? provider;
244
+ if (!context) {
245
+ throw new Error(
246
+ "usePromptInputAttachments must be used within a PromptInput or PromptInputProvider"
247
+ );
248
+ }
249
+ return context;
250
+ };
251
+ var LocalReferencedSourcesContext = createContext(null);
252
+ var usePromptInputReferencedSources = () => {
253
+ const ctx = useContext(LocalReferencedSourcesContext);
254
+ if (!ctx) {
255
+ throw new Error(
256
+ "usePromptInputReferencedSources must be used within a LocalReferencedSourcesContext.Provider"
257
+ );
258
+ }
259
+ return ctx;
260
+ };
261
+ var PromptInputActionAddAttachments = ({
262
+ label = "Add photos or files",
263
+ ...props
264
+ }) => {
265
+ const attachments = usePromptInputAttachments();
266
+ const handleSelect = useCallback(
267
+ (e) => {
268
+ e.preventDefault();
269
+ attachments.openFileDialog();
270
+ },
271
+ [attachments]
272
+ );
273
+ return /* @__PURE__ */ jsxs(DropdownMenuItem, { ...props, onSelect: handleSelect, children: [
274
+ /* @__PURE__ */ jsx(ImageIcon, { className: "me-2 size-4" }),
275
+ " ",
276
+ label
277
+ ] });
278
+ };
279
+ var PromptInputActionAddScreenshot = ({
280
+ label = "Take screenshot",
281
+ onSelect,
282
+ ...props
283
+ }) => {
284
+ const attachments = usePromptInputAttachments();
285
+ const handleSelect = useCallback(
286
+ async (event) => {
287
+ onSelect?.(event);
288
+ if (event.defaultPrevented) {
289
+ return;
290
+ }
291
+ try {
292
+ const screenshot = await captureScreenshot();
293
+ if (screenshot) {
294
+ attachments.add([screenshot]);
295
+ }
296
+ } catch (error) {
297
+ if (error instanceof DOMException && (error.name === "NotAllowedError" || error.name === "AbortError")) {
298
+ return;
299
+ }
300
+ throw error;
301
+ }
302
+ },
303
+ [onSelect, attachments]
304
+ );
305
+ return /* @__PURE__ */ jsxs(DropdownMenuItem, { ...props, onSelect: handleSelect, children: [
306
+ /* @__PURE__ */ jsx(Monitor, { className: "me-2 size-4" }),
307
+ label
308
+ ] });
309
+ };
310
+ var PromptInput = ({
311
+ className,
312
+ surfaceClassName,
313
+ tone = "surface",
314
+ accept,
315
+ multiple,
316
+ globalDrop,
317
+ syncHiddenInput,
318
+ maxFiles,
319
+ maxFileSize,
320
+ onError,
321
+ onSubmit,
322
+ children,
323
+ ...props
324
+ }) => {
325
+ const controller = useOptionalPromptInputController();
326
+ const usingProvider = !!controller;
327
+ const { t } = useLocale();
328
+ const inputRef = useRef(null);
329
+ const formRef = useRef(null);
330
+ const isSubmittingRef = useRef(false);
331
+ const [items, setItems] = useState([]);
332
+ const files = usingProvider ? controller.attachments.files : items;
333
+ const [hasLocalText, setHasLocalText] = useState(false);
334
+ const hasText = usingProvider ? controller.textInput.value.trim().length > 0 : hasLocalText;
335
+ const [hasDedicatedStop, setHasDedicatedStop] = useState(false);
336
+ const stopCountRef = useRef(0);
337
+ const registerStop = useCallback(() => {
338
+ stopCountRef.current += 1;
339
+ setHasDedicatedStop(true);
340
+ return () => {
341
+ stopCountRef.current = Math.max(0, stopCountRef.current - 1);
342
+ if (stopCountRef.current === 0) {
343
+ setHasDedicatedStop(false);
344
+ }
345
+ };
346
+ }, []);
347
+ const [referencedSources, setReferencedSources] = useState([]);
348
+ const filesRef = useRef(files);
349
+ useEffect(() => {
350
+ filesRef.current = files;
351
+ }, [files]);
352
+ const openFileDialogLocal = useCallback(() => {
353
+ inputRef.current?.click();
354
+ }, []);
355
+ const matchesAccept = useCallback(
356
+ (f) => {
357
+ if (!accept || accept.trim() === "") {
358
+ return true;
359
+ }
360
+ const patterns = accept.split(",").map((s) => s.trim()).filter(Boolean);
361
+ return patterns.some((pattern) => {
362
+ if (pattern.endsWith("/*")) {
363
+ const prefix = pattern.slice(0, -1);
364
+ return f.type.startsWith(prefix);
365
+ }
366
+ return f.type === pattern;
367
+ });
368
+ },
369
+ [accept]
370
+ );
371
+ const addLocal = useCallback(
372
+ (fileList) => {
373
+ const incoming = [...fileList];
374
+ const accepted = incoming.filter((f) => matchesAccept(f));
375
+ if (incoming.length && accepted.length === 0) {
376
+ onError?.({
377
+ code: "accept",
378
+ message: t("ai.promptInput.errorAccept")
379
+ });
380
+ return;
381
+ }
382
+ const withinSize = (f) => maxFileSize ? f.size <= maxFileSize : true;
383
+ const sized = accepted.filter(withinSize);
384
+ if (accepted.length > 0 && sized.length === 0) {
385
+ onError?.({
386
+ code: "max_file_size",
387
+ message: t("ai.promptInput.errorMaxFileSize")
388
+ });
389
+ return;
390
+ }
391
+ setItems((prev) => {
392
+ const capacity = typeof maxFiles === "number" ? Math.max(0, maxFiles - prev.length) : void 0;
393
+ const capped = typeof capacity === "number" ? sized.slice(0, capacity) : sized;
394
+ if (typeof capacity === "number" && sized.length > capacity) {
395
+ onError?.({
396
+ code: "max_files",
397
+ message: t("ai.promptInput.errorMaxFiles")
398
+ });
399
+ }
400
+ const next = [];
401
+ for (const file of capped) {
402
+ next.push({
403
+ filename: file.name,
404
+ id: nanoid(),
405
+ mediaType: file.type,
406
+ type: "file",
407
+ url: URL.createObjectURL(file)
408
+ });
409
+ }
410
+ return [...prev, ...next];
411
+ });
412
+ },
413
+ [matchesAccept, maxFiles, maxFileSize, onError]
414
+ );
415
+ const removeLocal = useCallback(
416
+ (id) => setItems((prev) => {
417
+ const found = prev.find((file) => file.id === id);
418
+ if (found?.url) {
419
+ URL.revokeObjectURL(found.url);
420
+ }
421
+ return prev.filter((file) => file.id !== id);
422
+ }),
423
+ []
424
+ );
425
+ const addWithProviderValidation = useCallback(
426
+ (fileList) => {
427
+ const incoming = [...fileList];
428
+ const accepted = incoming.filter((f) => matchesAccept(f));
429
+ if (incoming.length && accepted.length === 0) {
430
+ onError?.({
431
+ code: "accept",
432
+ message: t("ai.promptInput.errorAccept")
433
+ });
434
+ return;
435
+ }
436
+ const withinSize = (f) => maxFileSize ? f.size <= maxFileSize : true;
437
+ const sized = accepted.filter(withinSize);
438
+ if (accepted.length > 0 && sized.length === 0) {
439
+ onError?.({
440
+ code: "max_file_size",
441
+ message: t("ai.promptInput.errorMaxFileSize")
442
+ });
443
+ return;
444
+ }
445
+ const currentCount = files.length;
446
+ const capacity = typeof maxFiles === "number" ? Math.max(0, maxFiles - currentCount) : void 0;
447
+ const capped = typeof capacity === "number" ? sized.slice(0, capacity) : sized;
448
+ if (typeof capacity === "number" && sized.length > capacity) {
449
+ onError?.({
450
+ code: "max_files",
451
+ message: t("ai.promptInput.errorMaxFiles")
452
+ });
453
+ }
454
+ if (capped.length > 0) {
455
+ controller?.attachments.add(capped);
456
+ }
457
+ },
458
+ [matchesAccept, maxFileSize, maxFiles, onError, files.length, controller]
459
+ );
460
+ const clearAttachments = useCallback(
461
+ () => usingProvider ? controller?.attachments.clear() : setItems((prev) => {
462
+ for (const file of prev) {
463
+ if (file.url) {
464
+ URL.revokeObjectURL(file.url);
465
+ }
466
+ }
467
+ return [];
468
+ }),
469
+ [usingProvider, controller]
470
+ );
471
+ const clearReferencedSources = useCallback(() => setReferencedSources([]), []);
472
+ const add = usingProvider ? addWithProviderValidation : addLocal;
473
+ const remove = usingProvider ? controller.attachments.remove : removeLocal;
474
+ const openFileDialog = usingProvider ? controller.attachments.openFileDialog : openFileDialogLocal;
475
+ const clear = useCallback(() => {
476
+ clearAttachments();
477
+ clearReferencedSources();
478
+ }, [clearAttachments, clearReferencedSources]);
479
+ useEffect(() => {
480
+ if (!usingProvider) {
481
+ return;
482
+ }
483
+ controller.__registerFileInput(inputRef, () => inputRef.current?.click());
484
+ }, [usingProvider, controller]);
485
+ useEffect(() => {
486
+ if (syncHiddenInput && inputRef.current && files.length === 0) {
487
+ inputRef.current.value = "";
488
+ }
489
+ }, [files, syncHiddenInput]);
490
+ useEffect(() => {
491
+ const form = formRef.current;
492
+ if (!form) {
493
+ return;
494
+ }
495
+ if (globalDrop) {
496
+ return;
497
+ }
498
+ const onDragOver = (e) => {
499
+ if (e.dataTransfer?.types?.includes("Files")) {
500
+ e.preventDefault();
501
+ }
502
+ };
503
+ const onDrop = (e) => {
504
+ if (e.dataTransfer?.types?.includes("Files")) {
505
+ e.preventDefault();
506
+ }
507
+ if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {
508
+ add(e.dataTransfer.files);
509
+ }
510
+ };
511
+ form.addEventListener("dragover", onDragOver);
512
+ form.addEventListener("drop", onDrop);
513
+ return () => {
514
+ form.removeEventListener("dragover", onDragOver);
515
+ form.removeEventListener("drop", onDrop);
516
+ };
517
+ }, [add, globalDrop]);
518
+ useEffect(() => {
519
+ if (!globalDrop) {
520
+ return;
521
+ }
522
+ const onDragOver = (e) => {
523
+ if (e.dataTransfer?.types?.includes("Files")) {
524
+ e.preventDefault();
525
+ }
526
+ };
527
+ const onDrop = (e) => {
528
+ if (e.dataTransfer?.types?.includes("Files")) {
529
+ e.preventDefault();
530
+ }
531
+ if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {
532
+ add(e.dataTransfer.files);
533
+ }
534
+ };
535
+ document.addEventListener("dragover", onDragOver);
536
+ document.addEventListener("drop", onDrop);
537
+ return () => {
538
+ document.removeEventListener("dragover", onDragOver);
539
+ document.removeEventListener("drop", onDrop);
540
+ };
541
+ }, [add, globalDrop]);
542
+ useEffect(
543
+ () => () => {
544
+ if (!usingProvider) {
545
+ for (const f of filesRef.current) {
546
+ if (f.url) {
547
+ URL.revokeObjectURL(f.url);
548
+ }
549
+ }
550
+ }
551
+ },
552
+ [usingProvider]
553
+ );
554
+ const handleChange = useCallback(
555
+ (event) => {
556
+ if (event.currentTarget.files) {
557
+ add(event.currentTarget.files);
558
+ }
559
+ event.currentTarget.value = "";
560
+ },
561
+ [add]
562
+ );
563
+ const attachmentsCtx = useMemo(
564
+ () => ({
565
+ add,
566
+ clear: clearAttachments,
567
+ fileInputRef: inputRef,
568
+ files: files.map((item) => ({ ...item, id: item.id })),
569
+ openFileDialog,
570
+ remove
571
+ }),
572
+ [files, add, remove, clearAttachments, openFileDialog]
573
+ );
574
+ const submitState = useMemo(
575
+ () => ({
576
+ canSubmit: hasText || files.length > 0,
577
+ hasDedicatedStop,
578
+ registerStop,
579
+ setHasText: setHasLocalText
580
+ }),
581
+ [hasText, files.length, hasDedicatedStop, registerStop]
582
+ );
583
+ const refsCtx = useMemo(
584
+ () => ({
585
+ add: (incoming) => {
586
+ const array = Array.isArray(incoming) ? incoming : [incoming];
587
+ setReferencedSources((prev) => [...prev, ...array.map((s) => ({ ...s, id: nanoid() }))]);
588
+ },
589
+ clear: clearReferencedSources,
590
+ remove: (id) => {
591
+ setReferencedSources((prev) => prev.filter((s) => s.id !== id));
592
+ },
593
+ sources: referencedSources
594
+ }),
595
+ [referencedSources, clearReferencedSources]
596
+ );
597
+ const handleSubmit = useCallback(
598
+ async (event) => {
599
+ event.preventDefault();
600
+ if (isSubmittingRef.current) {
601
+ return;
602
+ }
603
+ const form = event.currentTarget;
604
+ const text = usingProvider ? controller.textInput.value : (() => {
605
+ const formData = new FormData(form);
606
+ return formData.get("message") || "";
607
+ })();
608
+ if (text.trim().length === 0 && files.length === 0) {
609
+ return;
610
+ }
611
+ isSubmittingRef.current = true;
612
+ const textarea = usingProvider ? null : form.querySelector('textarea[name="message"]');
613
+ const restoreTextOnFailure = () => {
614
+ if (textarea) {
615
+ textarea.value = text;
616
+ setHasLocalText(text.trim().length > 0);
617
+ }
618
+ };
619
+ if (!usingProvider) {
620
+ form.reset();
621
+ setHasLocalText(false);
622
+ }
623
+ try {
624
+ const convertedFiles = await Promise.all(
625
+ files.map(async ({ id: _id, ...item }) => {
626
+ if (item.url?.startsWith("blob:")) {
627
+ const dataUrl = await convertBlobUrlToDataUrl(item.url);
628
+ return {
629
+ ...item,
630
+ url: dataUrl ?? item.url
631
+ };
632
+ }
633
+ return item;
634
+ })
635
+ );
636
+ const result = onSubmit({ files: convertedFiles, text }, event);
637
+ if (result instanceof Promise) {
638
+ try {
639
+ await result;
640
+ clear();
641
+ if (usingProvider) {
642
+ controller.textInput.clear();
643
+ }
644
+ } catch {
645
+ restoreTextOnFailure();
646
+ }
647
+ } else {
648
+ clear();
649
+ if (usingProvider) {
650
+ controller.textInput.clear();
651
+ }
652
+ }
653
+ } catch {
654
+ restoreTextOnFailure();
655
+ } finally {
656
+ isSubmittingRef.current = false;
657
+ }
658
+ },
659
+ [usingProvider, controller, files, onSubmit, clear]
660
+ );
661
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
662
+ /* @__PURE__ */ jsx(
663
+ "input",
664
+ {
665
+ accept,
666
+ "aria-label": t("ai.promptInput.uploadFiles"),
667
+ className: "hidden",
668
+ multiple,
669
+ onChange: handleChange,
670
+ ref: inputRef,
671
+ title: t("ai.promptInput.uploadFiles"),
672
+ type: "file"
673
+ }
674
+ ),
675
+ /* @__PURE__ */ jsx("form", { className: cn("w-full", className), onSubmit: handleSubmit, ref: formRef, ...props, children: /* @__PURE__ */ jsx(InputGroup, { variant: tone, className: cn("overflow-hidden", surfaceClassName), children }) })
676
+ ] });
677
+ const withReferencedSources = /* @__PURE__ */ jsx(LocalReferencedSourcesContext.Provider, { value: refsCtx, children: /* @__PURE__ */ jsx(PromptInputSubmitStateContext.Provider, { value: submitState, children: inner }) });
678
+ return /* @__PURE__ */ jsx(LocalAttachmentsContext.Provider, { value: attachmentsCtx, children: withReferencedSources });
679
+ };
680
+ var PromptInputBody = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("contents", className), ...props });
681
+ var PromptInputTextarea = ({
682
+ onChange,
683
+ onKeyDown,
684
+ className,
685
+ placeholder,
686
+ ...props
687
+ }) => {
688
+ const { t } = useLocale();
689
+ const controller = useOptionalPromptInputController();
690
+ const attachments = usePromptInputAttachments();
691
+ const submitState = useOptionalSubmitState();
692
+ const [isComposing, setIsComposing] = useState(false);
693
+ const handleKeyDown = useCallback(
694
+ (e) => {
695
+ onKeyDown?.(e);
696
+ if (e.defaultPrevented) {
697
+ return;
698
+ }
699
+ if (e.key === "Enter") {
700
+ if (isComposing || e.nativeEvent.isComposing) {
701
+ return;
702
+ }
703
+ if (e.shiftKey) {
704
+ return;
705
+ }
706
+ e.preventDefault();
707
+ const { form } = e.currentTarget;
708
+ const submitControl = form?.querySelector(
709
+ `[data-slot="${SUBMIT_SLOT}"]`
710
+ );
711
+ const action = submitControl?.dataset.action ?? (submitControl?.dataset.generating === "true" ? "stop" : void 0);
712
+ if (submitControl?.disabled || submitControl?.getAttribute("aria-disabled") === "true" || action === "stop") {
713
+ return;
714
+ }
715
+ form?.requestSubmit();
716
+ }
717
+ if (e.key === "Backspace" && e.currentTarget.value === "" && attachments.files.length > 0) {
718
+ e.preventDefault();
719
+ const lastAttachment = attachments.files.at(-1);
720
+ if (lastAttachment) {
721
+ attachments.remove(lastAttachment.id);
722
+ }
723
+ }
724
+ },
725
+ [onKeyDown, isComposing, attachments]
726
+ );
727
+ const handlePaste = useCallback(
728
+ (event) => {
729
+ const items = event.clipboardData?.items;
730
+ if (!items) {
731
+ return;
732
+ }
733
+ const files = [];
734
+ for (const item of items) {
735
+ if (item.kind === "file") {
736
+ const file = item.getAsFile();
737
+ if (file) {
738
+ files.push(file);
739
+ }
740
+ }
741
+ }
742
+ if (files.length > 0) {
743
+ event.preventDefault();
744
+ attachments.add(files);
745
+ }
746
+ },
747
+ [attachments]
748
+ );
749
+ const handleCompositionEnd = useCallback(() => setIsComposing(false), []);
750
+ const handleCompositionStart = useCallback(() => setIsComposing(true), []);
751
+ const controlledProps = controller ? {
752
+ onChange: (e) => {
753
+ controller.textInput.setInput(e.currentTarget.value);
754
+ onChange?.(e);
755
+ },
756
+ value: controller.textInput.value
757
+ } : {
758
+ // Uncontrolled: report only the empty↔non-empty transition so the submit
759
+ // affordance can enable/disable. Boolean state ⇒ React bails out on
760
+ // identical values, so this stays cheap per keystroke.
761
+ onChange: (e) => {
762
+ submitState?.setHasText(e.currentTarget.value.trim().length > 0);
763
+ onChange?.(e);
764
+ }
765
+ };
766
+ return /* @__PURE__ */ jsx(
767
+ InputGroupTextarea,
768
+ {
769
+ className: cn("field-sizing-content max-h-48 min-h-10", className),
770
+ name: "message",
771
+ onCompositionEnd: handleCompositionEnd,
772
+ onCompositionStart: handleCompositionStart,
773
+ onKeyDown: handleKeyDown,
774
+ onPaste: handlePaste,
775
+ placeholder: placeholder ?? t("ai.promptInput.placeholder"),
776
+ ...props,
777
+ ...controlledProps
778
+ }
779
+ );
780
+ };
781
+ var PromptInputHeader = ({ className, ...props }) => /* @__PURE__ */ jsx(
782
+ InputGroupAddon,
783
+ {
784
+ align: "block-end",
785
+ className: cn("order-first flex-wrap gap-1", className),
786
+ ...props
787
+ }
788
+ );
789
+ var PromptInputFooter = ({ className, ...props }) => /* @__PURE__ */ jsx(
790
+ InputGroupAddon,
791
+ {
792
+ align: "block-end",
793
+ className: cn("justify-between gap-1", className),
794
+ ...props
795
+ }
796
+ );
797
+ var PromptInputTools = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("flex min-w-0 items-center gap-1", className), ...props });
798
+ var hasVisibleText = (node) => {
799
+ if (typeof node === "string" || typeof node === "number") {
800
+ return String(node).trim().length > 0;
801
+ }
802
+ if (Array.isArray(node)) {
803
+ return node.some(hasVisibleText);
804
+ }
805
+ if (isValidElement(node)) {
806
+ return hasVisibleText(node.props.children);
807
+ }
808
+ return false;
809
+ };
810
+ var PromptInputButton = ({
811
+ variant = "ghost",
812
+ className,
813
+ size,
814
+ tooltip,
815
+ "aria-label": ariaLabelProp,
816
+ ...props
817
+ }) => {
818
+ const newSize = size ?? (Children.count(props.children) > 1 ? "sm" : "icon-sm");
819
+ const tooltipContent = tooltip ? typeof tooltip === "string" ? tooltip : tooltip.content : void 0;
820
+ const isIconOnly = !hasVisibleText(props.children);
821
+ const ariaLabel = ariaLabelProp ?? (isIconOnly && typeof tooltipContent === "string" ? tooltipContent : void 0);
822
+ const button = /* @__PURE__ */ jsx(
823
+ InputGroupButton,
824
+ {
825
+ className: cn(className),
826
+ size: newSize,
827
+ type: "button",
828
+ variant,
829
+ ...props,
830
+ "aria-label": ariaLabel
831
+ }
832
+ );
833
+ if (!tooltip) {
834
+ return button;
835
+ }
836
+ const shortcut = typeof tooltip === "string" ? void 0 : tooltip.shortcut;
837
+ const side = typeof tooltip === "string" ? "top" : tooltip.side ?? "top";
838
+ return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
839
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: button }),
840
+ /* @__PURE__ */ jsxs(TooltipContent, { side, children: [
841
+ tooltipContent,
842
+ shortcut && /* @__PURE__ */ jsx("span", { className: "ms-2 text-muted-foreground", children: shortcut })
843
+ ] })
844
+ ] }) });
845
+ };
846
+ var PromptInputActionMenu = (props) => /* @__PURE__ */ jsx(DropdownMenu, { ...props });
847
+ var PromptInputActionMenuTrigger = ({
848
+ className,
849
+ children,
850
+ ...props
851
+ }) => /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(PromptInputButton, { className, ...props, children: children ?? /* @__PURE__ */ jsx(PlusIcon, { className: "size-4" }) }) });
852
+ var PromptInputActionMenuContent = ({
853
+ className,
854
+ ...props
855
+ }) => /* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", className: cn(className), ...props });
856
+ var PromptInputActionMenuItem = ({
857
+ className,
858
+ ...props
859
+ }) => /* @__PURE__ */ jsx(DropdownMenuItem, { className: cn(className), ...props });
860
+ var PromptInputSubmit = ({
861
+ className,
862
+ variant = "default",
863
+ size = "icon-sm",
864
+ status,
865
+ onStop,
866
+ onClick,
867
+ children,
868
+ sendIcon,
869
+ disabled,
870
+ ...props
871
+ }) => {
872
+ const { t } = useLocale();
873
+ const isGenerating = status === "submitted" || status === "streaming";
874
+ const submitState = useOptionalSubmitState();
875
+ const action = isGenerating && !submitState?.canSubmit && !submitState?.hasDedicatedStop ? "stop" : "send";
876
+ const autoDisabled = action === "send" && status !== "error" && submitState ? !submitState.canSubmit : false;
877
+ let Icon = sendIcon ?? /* @__PURE__ */ jsx(CornerDownLeftIcon, { className: "size-4", "data-rtl-flip": true });
878
+ if (action === "stop") {
879
+ Icon = status === "submitted" ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx(SquareIcon, { className: "size-4" });
880
+ } else if (status === "error") {
881
+ Icon = /* @__PURE__ */ jsx(XIcon, { className: "size-4" });
882
+ }
883
+ const handleClick = useCallback(
884
+ (e) => {
885
+ if (autoDisabled) {
886
+ e.preventDefault();
887
+ return;
888
+ }
889
+ if (action === "stop" && onStop) {
890
+ e.preventDefault();
891
+ onStop();
892
+ return;
893
+ }
894
+ onClick?.(e);
895
+ },
896
+ [autoDisabled, action, onStop, onClick]
897
+ );
898
+ return /* @__PURE__ */ jsx(
899
+ InputGroupButton,
900
+ {
901
+ "aria-label": action === "stop" ? t("ai.promptInput.stop") : t("ai.promptInput.submit"),
902
+ "aria-disabled": autoDisabled || void 0,
903
+ className: cn(autoDisabled && "cursor-not-allowed opacity-50 hover:bg-primary", className),
904
+ "data-action": action,
905
+ "data-generating": action === "stop" ? "true" : void 0,
906
+ "data-slot": SUBMIT_SLOT,
907
+ disabled,
908
+ onClick: handleClick,
909
+ size,
910
+ type: autoDisabled || action === "stop" && onStop ? "button" : "submit",
911
+ variant,
912
+ ...props,
913
+ children: children ?? /* @__PURE__ */ jsx(
914
+ "span",
915
+ {
916
+ className: "flex animate-in fade-in-0 zoom-in-95 duration-fast ease-entrance",
917
+ children: Icon
918
+ },
919
+ `${status ?? "ready"}-${action}`
920
+ )
921
+ }
922
+ );
923
+ };
924
+ var STOP_SLOT = "prompt-input-stop";
925
+ var PromptInputStop = ({
926
+ className,
927
+ variant = "outline",
928
+ size = "icon-sm",
929
+ status,
930
+ onStop,
931
+ onClick,
932
+ children,
933
+ ...props
934
+ }) => {
935
+ const { t } = useLocale();
936
+ const submitState = useOptionalSubmitState();
937
+ const isGenerating = status === "submitted" || status === "streaming";
938
+ useEffect(() => {
939
+ const unregister = submitState?.registerStop();
940
+ return unregister;
941
+ }, [submitState]);
942
+ const handleClick = useCallback(
943
+ (e) => {
944
+ onClick?.(e);
945
+ if (e.defaultPrevented) {
946
+ return;
947
+ }
948
+ onStop();
949
+ },
950
+ [onClick, onStop]
951
+ );
952
+ if (!isGenerating) {
953
+ return null;
954
+ }
955
+ return /* @__PURE__ */ jsx(
956
+ InputGroupButton,
957
+ {
958
+ "aria-label": t("ai.promptInput.stop"),
959
+ className: cn(className),
960
+ "data-slot": STOP_SLOT,
961
+ onClick: handleClick,
962
+ size,
963
+ type: "button",
964
+ variant,
965
+ ...props,
966
+ children: children ?? /* @__PURE__ */ jsx(SquareIcon, { className: "size-4" })
967
+ }
968
+ );
969
+ };
970
+ var PromptInputSelect = (props) => /* @__PURE__ */ jsx(Select, { ...props });
971
+ var PromptInputSelectTrigger = ({
972
+ className,
973
+ ...props
974
+ }) => /* @__PURE__ */ jsx(
975
+ SelectTrigger,
976
+ {
977
+ className: cn(
978
+ "border-none bg-transparent font-medium text-muted-foreground shadow-none transition-colors",
979
+ "hover:bg-accent hover:text-foreground aria-expanded:bg-accent aria-expanded:text-foreground",
980
+ className
981
+ ),
982
+ ...props
983
+ }
984
+ );
985
+ var PromptInputSelectContent = ({
986
+ className,
987
+ ...props
988
+ }) => /* @__PURE__ */ jsx(SelectContent, { className: cn(className), ...props });
989
+ var PromptInputSelectItem = ({ className, ...props }) => /* @__PURE__ */ jsx(SelectItem, { className: cn(className), ...props });
990
+ var PromptInputSelectValue = ({ className, ...props }) => /* @__PURE__ */ jsx(SelectValue, { className: cn(className), ...props });
991
+ var PromptInputHoverCard = ({
992
+ openDelay = 0,
993
+ closeDelay = 0,
994
+ ...props
995
+ }) => /* @__PURE__ */ jsx(HoverCard, { closeDelay, openDelay, ...props });
996
+ var PromptInputHoverCardTrigger = (props) => /* @__PURE__ */ jsx(HoverCardTrigger, { ...props });
997
+ var PromptInputHoverCardContent = ({
998
+ align = "start",
999
+ ...props
1000
+ }) => /* @__PURE__ */ jsx(HoverCardContent, { align, ...props });
1001
+ var PromptInputTabsList = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn(className), ...props });
1002
+ var PromptInputTab = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn(className), ...props });
1003
+ var PromptInputTabLabel = ({ className, ...props }) => (
1004
+ // Content provided via children in props
1005
+ // oxlint-disable-next-line eslint-plugin-jsx-a11y(heading-has-content)
1006
+ /* @__PURE__ */ jsx(
1007
+ "h3",
1008
+ {
1009
+ className: cn("mb-2 px-3 font-medium text-muted-foreground text-meta", className),
1010
+ ...props
1011
+ }
1012
+ )
1013
+ );
1014
+ var PromptInputTabBody = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("space-y-1", className), ...props });
1015
+ var PromptInputTabItem = ({ className, ...props }) => /* @__PURE__ */ jsx(
1016
+ "div",
1017
+ {
1018
+ className: cn("flex items-center gap-2 px-3 py-2 text-meta hover:bg-accent", className),
1019
+ ...props
1020
+ }
1021
+ );
1022
+ var PromptInputCommand = ({ className, ...props }) => /* @__PURE__ */ jsx(Command, { className: cn(className), ...props });
1023
+ var PromptInputCommandInput = ({ className, ...props }) => /* @__PURE__ */ jsx(CommandInput, { className: cn(className), ...props });
1024
+ var PromptInputCommandList = ({ className, ...props }) => /* @__PURE__ */ jsx(CommandList, { className: cn(className), ...props });
1025
+ var PromptInputCommandEmpty = ({ className, ...props }) => /* @__PURE__ */ jsx(CommandEmpty, { className: cn(className), ...props });
1026
+ var PromptInputCommandGroup = ({ className, ...props }) => /* @__PURE__ */ jsx(CommandGroup, { className: cn(className), ...props });
1027
+ var PromptInputCommandItem = ({ className, ...props }) => /* @__PURE__ */ jsx(CommandItem, { className: cn(className), ...props });
1028
+ var PromptInputCommandSeparator = ({
1029
+ className,
1030
+ ...props
1031
+ }) => /* @__PURE__ */ jsx(CommandSeparator, { className: cn(className), ...props });
1032
+
1033
+ export {
1034
+ usePromptInputController,
1035
+ useProviderAttachments,
1036
+ PromptInputProvider,
1037
+ usePromptInputAttachments,
1038
+ LocalReferencedSourcesContext,
1039
+ usePromptInputReferencedSources,
1040
+ PromptInputActionAddAttachments,
1041
+ PromptInputActionAddScreenshot,
1042
+ PromptInput,
1043
+ PromptInputBody,
1044
+ PromptInputTextarea,
1045
+ PromptInputHeader,
1046
+ PromptInputFooter,
1047
+ PromptInputTools,
1048
+ PromptInputButton,
1049
+ PromptInputActionMenu,
1050
+ PromptInputActionMenuTrigger,
1051
+ PromptInputActionMenuContent,
1052
+ PromptInputActionMenuItem,
1053
+ PromptInputSubmit,
1054
+ PromptInputStop,
1055
+ PromptInputSelect,
1056
+ PromptInputSelectTrigger,
1057
+ PromptInputSelectContent,
1058
+ PromptInputSelectItem,
1059
+ PromptInputSelectValue,
1060
+ PromptInputHoverCard,
1061
+ PromptInputHoverCardTrigger,
1062
+ PromptInputHoverCardContent,
1063
+ PromptInputTabsList,
1064
+ PromptInputTab,
1065
+ PromptInputTabLabel,
1066
+ PromptInputTabBody,
1067
+ PromptInputTabItem,
1068
+ PromptInputCommand,
1069
+ PromptInputCommandInput,
1070
+ PromptInputCommandList,
1071
+ PromptInputCommandEmpty,
1072
+ PromptInputCommandGroup,
1073
+ PromptInputCommandItem,
1074
+ PromptInputCommandSeparator
1075
+ };
1076
+ //# sourceMappingURL=chunk-SSGJ6MEM.js.map