@kitn.ai/ui 0.25.2 → 0.27.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 (603) hide show
  1. package/README.md +17 -6
  2. package/bin/mcp.js +16 -3
  3. package/bin/route.js +23 -0
  4. package/bin/route.test.js +58 -0
  5. package/dist/{elements/chunks/Icon-b5A8hlHs.js → Icon-BnFKqqtY.js} +1 -1
  6. package/dist/action-icons-CBskfBMz.js +1 -0
  7. package/dist/arrow-down-Br0qtpsz.js +1 -0
  8. package/dist/arrow-left-Dj7xgE12.js +1 -0
  9. package/dist/artifact-CvXEm1lS.js +1 -0
  10. package/dist/assets/dev-5XzXYR21.js +91 -0
  11. package/dist/attachments-C43ZegEq.js +1 -0
  12. package/dist/audio-visualizer-B-79y1Tj.js +1 -0
  13. package/dist/badge-BpUbq8c0.js +1 -0
  14. package/dist/bash-InADTalH.js +1 -6
  15. package/dist/bell-sn17Ip9v.js +1 -0
  16. package/dist/{elements/chunks/button-B9okqG73.js → button-BH6rN0U-.js} +1 -1
  17. package/dist/card-renderer-Cb1gQmth.js +1 -0
  18. package/dist/card-routing-DifQgS7n.js +1 -0
  19. package/dist/check-DPeeMUYx.js +1 -0
  20. package/dist/checkbox-Dc9Yov_B.js +1 -0
  21. package/dist/checkbox-group-B1kDLLYk.js +1 -0
  22. package/dist/chevron-down-CHSWk7ZT.js +1 -0
  23. package/dist/chevron-right-B7l_fMgx.js +1 -0
  24. package/dist/choice-card-BT3c1S8g.js +1 -0
  25. package/dist/circle-Bb0yOpqM.js +1 -0
  26. package/dist/circle-check-BGZpCiz7.js +1 -0
  27. package/dist/circle-x-wobWkoSx.js +1 -0
  28. package/dist/{elements/chunks/cn-CU7UAWzk.js → cn-DN5AWfiS.js} +1 -1
  29. package/dist/code-block-CUQ5mtv0.js +1 -0
  30. package/dist/collapsible-CPJbf6FM.js +1 -0
  31. package/dist/components/attachment-types.d.ts +53 -1
  32. package/dist/components/attachments.d.ts +31 -0
  33. package/dist/components/audio-visualizer/fit-scale.d.ts +50 -0
  34. package/dist/components/audio-visualizer/index.d.ts +15 -1
  35. package/dist/components/audio-visualizer/variant-bar.d.ts +24 -1
  36. package/dist/components/card-renderer.d.ts +13 -0
  37. package/dist/components/card.d.ts +4 -0
  38. package/dist/components/chat-thread.d.ts +49 -42
  39. package/dist/components/code-block.d.ts +22 -0
  40. package/dist/components/conversation-item.d.ts +66 -1
  41. package/dist/components/conversation-list.d.ts +77 -0
  42. package/dist/components/form-widgets.d.ts +67 -2
  43. package/dist/components/form.d.ts +89 -0
  44. package/dist/components/message.d.ts +29 -0
  45. package/dist/components/reasoning.d.ts +6 -0
  46. package/dist/components/scroll-button.d.ts +11 -0
  47. package/dist/components/thread.d.ts +5 -0
  48. package/dist/components/toast.d.ts +2 -1
  49. package/dist/components/tool-types.d.ts +9 -0
  50. package/dist/components/voice-input.d.ts +8 -0
  51. package/dist/components/voice-output.d.ts +12 -1
  52. package/dist/components/workspace-shell.d.ts +87 -0
  53. package/dist/composer-CjngLzal.js +106 -0
  54. package/dist/confirm-card-DCx_A4bU.js +1 -0
  55. package/dist/construct-cli.es.js +1169 -0
  56. package/dist/context-BY8V-Nlp.js +1 -0
  57. package/dist/controllable-D43BKmtX.js +1 -0
  58. package/dist/conversation-list-D4lLU_yS.js +1 -0
  59. package/dist/copy-B6DO4PqB.js +1 -0
  60. package/dist/core-AYMC6_lb.js +12 -5874
  61. package/dist/{create-tween-CUzOlaMS.js → create-tween-BPzaefTp.js} +1 -1
  62. package/dist/{create-tween-B5Y4Im8G.js → create-tween-CnMHviKB.js} +1 -1
  63. package/dist/{create-tween-4z1XYLkR.js → create-tween-D1aiGZZh.js} +1 -1
  64. package/dist/{elements/chunks/create-tween-CUrM6D_o.js → create-tween-DUSQUKpr.js} +2 -2
  65. package/dist/css-M7EaDHN_.js +1 -6
  66. package/dist/custom-elements.json +3468 -1927
  67. package/dist/default-input-CucQEOqH.js +1 -0
  68. package/dist/define-CGGX-7Vg.js +1 -0
  69. package/dist/define.d.ts +4 -0
  70. package/dist/define.js +510 -0
  71. package/dist/define.server.d.ts +5 -0
  72. package/dist/define.server.js +506 -0
  73. package/dist/diagnostics/hook.d.ts +81 -0
  74. package/dist/diagnostics/index.d.ts +7 -0
  75. package/dist/diagnostics/report-request.d.ts +61 -0
  76. package/dist/diagnostics.d.ts +5 -0
  77. package/dist/diagnostics.js +209 -0
  78. package/dist/disclosure-CbLtajUQ.js +1 -0
  79. package/dist/dropdown-BwhViJFd.js +1 -0
  80. package/dist/elements/agent-card.js +1 -1
  81. package/dist/elements/artifact.js +1 -1
  82. package/dist/elements/attachments.js +1 -1
  83. package/dist/elements/audio-visualizer.js +1 -1
  84. package/dist/elements/autoloader.js +1 -1
  85. package/dist/elements/avatar.js +1 -1
  86. package/dist/elements/badge.js +1 -1
  87. package/dist/elements/button.js +1 -1
  88. package/dist/elements/card.js +1 -1
  89. package/dist/elements/cards.js +1 -1
  90. package/dist/elements/chain-of-thought.js +1 -1
  91. package/dist/elements/chat-scope-picker.js +1 -1
  92. package/dist/elements/chat-workspace.js +1 -1
  93. package/dist/elements/chat.js +1 -1
  94. package/dist/elements/checkbox-group.d.ts +1 -0
  95. package/dist/elements/checkbox-group.js +1 -0
  96. package/dist/elements/checkbox.d.ts +1 -0
  97. package/dist/elements/checkbox.js +1 -0
  98. package/dist/elements/checkpoint.js +1 -1
  99. package/dist/elements/choice.js +1 -1
  100. package/dist/elements/coachmark.js +1 -1
  101. package/dist/elements/code-block.js +1 -1
  102. package/dist/elements/command.js +1 -1
  103. package/dist/elements/compare.js +1 -1
  104. package/dist/elements/composer.js +1 -1
  105. package/dist/elements/confirm-card.js +1 -1
  106. package/dist/elements/context-meter.js +1 -1
  107. package/dist/elements/conversation-item.d.ts +1 -0
  108. package/dist/elements/conversation-item.js +1 -0
  109. package/dist/elements/conversation-list.js +1 -1
  110. package/dist/elements/default-input.d.ts +3 -3
  111. package/dist/elements/define-entry.d.ts +12 -0
  112. package/dist/elements/define.d.ts +27 -0
  113. package/dist/elements/diagnostic-events.d.ts +74 -0
  114. package/dist/elements/dialog.js +1 -1
  115. package/dist/elements/dock.d.ts +1 -0
  116. package/dist/elements/dock.js +243 -0
  117. package/dist/elements/dropdown.d.ts +1 -0
  118. package/dist/elements/dropdown.js +1 -0
  119. package/dist/elements/editable-label.js +1 -1
  120. package/dist/elements/element-data-types.d.ts +37 -0
  121. package/dist/elements/element-diagnostics.d.ts +81 -0
  122. package/dist/elements/embed.js +1 -1
  123. package/dist/elements/empty.js +1 -1
  124. package/dist/elements/feedback-bar.js +1 -1
  125. package/dist/elements/file-tree.js +1 -1
  126. package/dist/elements/file-upload.js +1 -1
  127. package/dist/elements/form.js +1 -1
  128. package/dist/elements/hover-card.js +1 -1
  129. package/dist/elements/icon.js +1 -1
  130. package/dist/elements/image.js +1 -1
  131. package/dist/elements/input.js +1 -1
  132. package/dist/elements/kbd.js +1 -1
  133. package/dist/elements/link-preview.js +1 -1
  134. package/dist/elements/loader.js +1 -1
  135. package/dist/elements/markdown.js +1 -1
  136. package/dist/elements/menu.js +1 -1
  137. package/dist/elements/message-skills.js +1 -1
  138. package/dist/elements/message.js +1 -1
  139. package/dist/elements/model-switcher.js +1 -1
  140. package/dist/elements/nav.js +1 -1
  141. package/dist/elements/notice.js +1 -1
  142. package/dist/elements/pane-grid.d.ts +1 -0
  143. package/dist/elements/pane-grid.js +1 -0
  144. package/dist/elements/pane-group.js +1 -1
  145. package/dist/elements/pane.js +1 -1
  146. package/dist/elements/popover.js +1 -1
  147. package/dist/elements/progress-bar.js +1 -1
  148. package/dist/elements/prompt-dock.js +1 -1
  149. package/dist/elements/prompt-input.js +1 -1
  150. package/dist/elements/prompt-suggestions.js +1 -1
  151. package/dist/elements/radio-group.d.ts +1 -0
  152. package/dist/elements/radio-group.js +1 -0
  153. package/dist/elements/reasoning.js +1 -1
  154. package/dist/elements/register.d.ts +2 -0
  155. package/dist/elements/remote.js +1 -1
  156. package/dist/elements/resizable.js +1 -1
  157. package/dist/elements/response-stream.js +3 -3
  158. package/dist/elements/screen.js +1 -1
  159. package/dist/elements/scroll-area.js +1 -1
  160. package/dist/elements/scroll-button.js +1 -1
  161. package/dist/elements/search.js +1 -1
  162. package/dist/elements/segmented.js +1 -1
  163. package/dist/elements/select.d.ts +1 -0
  164. package/dist/elements/select.js +1 -0
  165. package/dist/elements/separator.js +1 -1
  166. package/dist/elements/setting-item.js +1 -1
  167. package/dist/elements/settings-group.js +1 -1
  168. package/dist/elements/skeleton.js +1 -1
  169. package/dist/elements/slider.d.ts +1 -0
  170. package/dist/elements/slider.js +1 -0
  171. package/dist/elements/slots.d.ts +36 -4
  172. package/dist/elements/source.js +1 -1
  173. package/dist/elements/status.js +1 -1
  174. package/dist/elements/switch.js +1 -1
  175. package/dist/elements/tabs.js +1 -1
  176. package/dist/elements/tasks.js +1 -1
  177. package/dist/elements/text-shimmer.js +1 -1
  178. package/dist/elements/thinking-bar.js +1 -1
  179. package/dist/elements/thread.js +1 -1
  180. package/dist/elements/toast.js +1 -1
  181. package/dist/elements/tool.js +1 -1
  182. package/dist/elements/tooltip.js +1 -1
  183. package/dist/elements/voice-input.js +1 -1
  184. package/dist/elements/voice-output.js +1 -1
  185. package/dist/elements.d.ts +589 -167
  186. package/dist/{elements/chunks/ellipsis-CVxqfsDZ.js → ellipsis-DFr4Vqr3.js} +1 -1
  187. package/dist/embed-5s_vU4J0.js +1 -0
  188. package/dist/engine-javascript-vq0WuIJl.js +14 -2516
  189. package/dist/{elements/chunks/external-link-DG2sRdQL.js → external-link-u9d85ORQ.js} +1 -1
  190. package/dist/file-text-CX7_x42o.js +1 -0
  191. package/dist/{elements/chunks/file-tree-yGWNK0Js.js → file-tree-D3kBjXI5.js} +1 -1
  192. package/dist/folder-V-YdIL8f.js +1 -0
  193. package/dist/form-BRNUMCN2.js +1 -0
  194. package/dist/github-dark-dimmed-DUshB20C.js +1 -4
  195. package/dist/github-light-JYsPkUQd.js +1 -4
  196. package/dist/hover-card-DaeiYrTA.js +1 -0
  197. package/dist/html-CPZ3oZQ7.js +1 -10
  198. package/dist/icon-BpixdZNq.js +1 -0
  199. package/dist/{elements/chunks/index-BCRhi84a.js → index-xu_pdcPi.js} +1 -1
  200. package/dist/index.d.ts +3 -1
  201. package/dist/index.js +8473 -6470
  202. package/dist/index.server.js +6495 -4958
  203. package/dist/info-8mFsIjS3.js +1 -0
  204. package/dist/input-d1Yuu-hz.js +1 -0
  205. package/dist/javascript-C25yR2R2.js +1 -6
  206. package/dist/json-DxJze_jm.js +1 -6
  207. package/dist/kai-provider.es.js +40 -40
  208. package/dist/kai.es.js +1 -1
  209. package/dist/kbd-961zMPFB.js +1 -0
  210. package/dist/link-DlZZBGaR.js +1 -0
  211. package/dist/{elements/chunks/link-preview-Cf5KOP-i.js → link-preview-DIIbV2Sd.js} +1 -1
  212. package/dist/loader-YQszHFaW.js +1 -0
  213. package/dist/{elements/chunks/markdown-DbozyYqa.js → markdown-CVk1MPsj.js} +1 -1
  214. package/dist/mcp.es.js +3873 -544
  215. package/dist/message-CwKVEdZg.js +1 -0
  216. package/dist/message-DS8lzHc1.js +1 -0
  217. package/dist/message-circle-Xf8Q-vZp.js +1 -0
  218. package/dist/message-square-Cxnwgkns.js +1 -0
  219. package/dist/{elements/chunks/minimize-2-SegJ_oku.js → minimize-2-UEZmP2QT.js} +1 -1
  220. package/dist/{elements/chunks/model-switcher-D7JrFFHp.js → model-switcher-Kk1jEQ5t.js} +1 -1
  221. package/dist/{elements/chunks/overlay-CV7z2YuX.js → overlay-C1od6LOz.js} +1 -1
  222. package/dist/panel-right-ryET0yyn.js +1 -0
  223. package/dist/paperclip-BDNoZFJP.js +1 -0
  224. package/dist/play-OFIvYXUQ.js +1 -0
  225. package/dist/primitives/card-data-types.d.ts +49 -0
  226. package/dist/primitives/card-routing.d.ts +1 -33
  227. package/dist/primitives/card-validate.d.ts +2 -2
  228. package/dist/primitives/chat-config.d.ts +29 -2
  229. package/dist/primitives/field-mask.d.ts +96 -0
  230. package/dist/primitives/field-semantics.d.ts +36 -0
  231. package/dist/primitives/input-mask.d.ts +46 -0
  232. package/dist/primitives/url-scheme-policy.d.ts +34 -0
  233. package/dist/primitives/use-resize-observer.d.ts +23 -0
  234. package/dist/primitives/use-speech-recognition.d.ts +8 -0
  235. package/dist/primitives/use-text-stream.d.ts +5 -0
  236. package/dist/progress-bar-BvYX0aoy.js +1 -0
  237. package/dist/prompt-suggestion-BRFu2lcu.js +1 -0
  238. package/dist/radio-DcL23cNJ.js +1 -0
  239. package/dist/react/index.d.ts +306 -283
  240. package/dist/react.js +309 -247
  241. package/dist/reasoning-Cackq4Rh.js +1 -0
  242. package/dist/register-impl-C7rENvPK.js +424 -0
  243. package/dist/{elements/chunks/resizable-Dpzjlvp4.js → resizable-Cp9HUYih.js} +1 -1
  244. package/dist/rotate-ccw-0DLRDHH5.js +1 -0
  245. package/dist/rotate-cw-DOB9IGcU.js +1 -0
  246. package/dist/schemas/form.schema.json +21 -1
  247. package/dist/schemas/index.d.ts +1 -1
  248. package/dist/schemas/tool-defs.d.ts +45 -0
  249. package/dist/schemas.js +398 -305
  250. package/dist/scroll-area-emVmWP4K.js +1 -0
  251. package/dist/scroll-button-CeP_gv1x.js +1 -0
  252. package/dist/select-CWmu00tS.js +1 -0
  253. package/dist/{elements/chunks/separator-DH2r_ZSZ.js → separator-CE6vly6z.js} +1 -1
  254. package/dist/{elements/chunks/settings-BFMOd6yB.js → settings-CE-78SvZ.js} +1 -1
  255. package/dist/{elements/chunks/settings-group-B3VZKIcz.js → settings-group-ZFWNxFQR.js} +1 -1
  256. package/dist/{elements/chunks/skeleton-N8BuWYmf.js → skeleton-BebdP4mf.js} +1 -1
  257. package/dist/slider-BAKRYUlz.js +1 -0
  258. package/dist/slots-DaNjX0rc.js +1 -0
  259. package/dist/{solid-BMuDmFo_.js → solid-BE5ui6sy.js} +10672 -8116
  260. package/dist/{solid-CGYNdLRR.js → solid-DFhsce3O.js} +8137 -6056
  261. package/dist/solid.d.ts +15 -0
  262. package/dist/solid.js +248 -235
  263. package/dist/solid.server.js +248 -235
  264. package/dist/source-B0FlguSx.js +1 -0
  265. package/dist/star-CBMZvLuN.js +1 -0
  266. package/dist/state/index.d.ts +5 -1
  267. package/dist/state/mock.d.ts +32 -2
  268. package/dist/state/persistence.d.ts +51 -0
  269. package/dist/state/stream.d.ts +50 -0
  270. package/dist/state/threads.d.ts +71 -0
  271. package/dist/state.js +297 -172
  272. package/dist/store-7eoadydQ.js +1 -0
  273. package/dist/svelte--5p79yCD.js +1 -15
  274. package/dist/switch-CViARZCy.js +1 -0
  275. package/dist/tasks-card-MjCcOhR_.js +1 -0
  276. package/dist/text-shimmer-DKlwRF2G.js +1 -0
  277. package/dist/textarea-3ay2Me2-.js +1 -0
  278. package/dist/theme.tokens.css +82 -13
  279. package/dist/{elements/chunks/thumbs-up-DQe0hvkZ.js → thumbs-up-DQcu2HMO.js} +1 -1
  280. package/dist/toast-store-C6yKOhbk.js +1 -0
  281. package/dist/{elements/chunks/tool-C1YtxwPu.js → tool-BCYNlfKy.js} +1 -1
  282. package/dist/{elements/chunks/tooltip-BqwnFWhn.js → tooltip-05zI4hjs.js} +1 -1
  283. package/dist/trash-2-BR1RxGky.js +1 -0
  284. package/dist/{elements/chunks/triangle-alert-B6or7F5u.js → triangle-alert-DHohDOCy.js} +1 -1
  285. package/dist/tsx-B8rCNbgL.js +1 -6
  286. package/dist/types.d.ts +4 -2
  287. package/dist/typescript-RycA9KXf.js +1 -6
  288. package/dist/ui/checkbox-group.d.ts +83 -0
  289. package/dist/ui/checkbox.d.ts +40 -0
  290. package/dist/ui/dock.d.ts +131 -0
  291. package/dist/ui/hover-card.d.ts +44 -0
  292. package/dist/ui/icon.d.ts +3 -0
  293. package/dist/ui/input.d.ts +48 -2
  294. package/dist/ui/radio.d.ts +85 -0
  295. package/dist/ui/select.d.ts +71 -0
  296. package/dist/ui/slider.d.ts +65 -0
  297. package/dist/ui/switch.d.ts +9 -2
  298. package/dist/upload-BbGW6A_u.js +1 -0
  299. package/dist/url-scheme-policy-DHpoTJwB.js +1 -0
  300. package/dist/use-card-resolution-CJW4grFa.js +1 -0
  301. package/dist/{variant-aurora-DwSOfraQ.js → variant-aurora-BUOVgPOB.js} +27 -27
  302. package/dist/{variant-aurora-wKvAQ5wp.js → variant-aurora-CUsUJvFI.js} +28 -28
  303. package/dist/{variant-aurora-XEkPT0_z.js → variant-aurora-CW2i4bfr.js} +2 -2
  304. package/dist/{elements/chunks/variant-aurora-QXTZPyST.js → variant-aurora-xiMPty8f.js} +2 -2
  305. package/dist/variant-custom-BQtOnmeO.js +1 -0
  306. package/dist/{variant-custom-BhS9wIpU.js → variant-custom-CAm9L-E5.js} +65 -65
  307. package/dist/{variant-custom-eFIg2XWQ.js → variant-custom-CAnzzppW.js} +40 -40
  308. package/dist/variant-custom-D91HjAKz.js +1 -0
  309. package/dist/{variant-wave-CUWGx9Bn.js → variant-wave-Ca1Ls4_y.js} +21 -21
  310. package/dist/{variant-wave-CbVsmgwT.js → variant-wave-CxX39DKd.js} +25 -25
  311. package/dist/{variant-wave-BwzrHD1s.js → variant-wave-DYyzIIZv.js} +2 -2
  312. package/dist/{elements/chunks/variant-wave-DDCwhLas.js → variant-wave-uY5crU_K.js} +2 -2
  313. package/dist/vue-BmIZj4XD.js +1 -33
  314. package/dist/wire/chunk.d.ts +47 -0
  315. package/dist/wire/diagnostics.d.ts +575 -0
  316. package/dist/wire/encode-probe.d.ts +70 -0
  317. package/dist/wire/encode.d.ts +24 -0
  318. package/dist/wire/index.d.ts +2 -0
  319. package/dist/wire/sse.d.ts +10 -2
  320. package/dist/wire.js +917 -480
  321. package/dist/x-C5m1JFgi.js +1 -0
  322. package/frameworks/react/index.tsx +325 -108
  323. package/llms-full.txt +1354 -82
  324. package/llms.txt +6 -3
  325. package/package.json +39 -6
  326. package/src/agent-tooling/archetypes.ts +41 -9
  327. package/src/agent-tooling/catalog/README.md +676 -0
  328. package/src/agent-tooling/catalog/catalog-types.ts +231 -0
  329. package/src/agent-tooling/catalog/fabrications.ts +96 -0
  330. package/src/agent-tooling/catalog/invariants.ts +284 -0
  331. package/src/agent-tooling/catalog/labs-titles.ts +114 -0
  332. package/src/agent-tooling/catalog/scenarios.ts +87 -0
  333. package/src/agent-tooling/catalog/surfaces.ts +347 -0
  334. package/src/agent-tooling/construct/cli-entry.ts +8 -0
  335. package/src/agent-tooling/construct/cli.ts +131 -0
  336. package/src/agent-tooling/construct/codegen.ts +1353 -0
  337. package/src/agent-tooling/construct/construct.v1.schema.json +250 -0
  338. package/src/agent-tooling/construct/dev.ts +148 -0
  339. package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +7 -0
  340. package/src/agent-tooling/construct/fixtures/ops-console.construct.json +44 -0
  341. package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +23 -0
  342. package/src/agent-tooling/construct/schema.ts +371 -0
  343. package/src/agent-tooling/integrations/anthropic.ts +7 -1
  344. package/src/agent-tooling/integrations/cloudflare.ts +43 -2
  345. package/src/agent-tooling/integrations/langgraph.ts +7 -1
  346. package/src/agent-tooling/integrations/mastra.ts +7 -1
  347. package/src/agent-tooling/integrations/mock.ts +92 -17
  348. package/src/agent-tooling/integrations/ollama.ts +7 -1
  349. package/src/agent-tooling/integrations/openai.ts +7 -1
  350. package/src/agent-tooling/integrations/openrouter.ts +7 -1
  351. package/src/agent-tooling/integrations/pi.ts +56 -1
  352. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +7 -1
  353. package/src/agent-tooling/mcp/css-raw.d.ts +12 -0
  354. package/src/agent-tooling/mcp/manifest.ts +100 -1
  355. package/src/agent-tooling/mcp/server.ts +63 -6
  356. package/src/agent-tooling/mcp/tools/construct.ts +130 -0
  357. package/src/agent-tooling/mcp/tools/debug.ts +126 -4
  358. package/src/agent-tooling/mcp/tools/reference.ts +542 -5
  359. package/src/agent-tooling/mcp/tools/scaffold.ts +1834 -307
  360. package/src/agent-tooling/mcp/tools/theme.ts +146 -30
  361. package/src/agent-tooling/mcp/validate-args.ts +141 -0
  362. package/src/agent-tooling/recipes/composed-thread.ts +714 -0
  363. package/src/agent-tooling/recipes/index.ts +22 -0
  364. package/src/agent-tooling/recipes/types.ts +32 -0
  365. package/src/agent-tooling/registry.ts +24 -7
  366. package/src/agent-tooling/route-emit.ts +26 -2
  367. package/src/components/attachment-types.ts +54 -1
  368. package/src/components/attachments.tsx +169 -22
  369. package/src/components/audio-visualizer/fit-scale.ts +112 -0
  370. package/src/components/audio-visualizer/index.tsx +80 -3
  371. package/src/components/audio-visualizer/variant-aurora.tsx +10 -4
  372. package/src/components/audio-visualizer/variant-bar.tsx +38 -6
  373. package/src/components/audio-visualizer/variant-custom.tsx +8 -2
  374. package/src/components/audio-visualizer/variant-grid.tsx +16 -11
  375. package/src/components/audio-visualizer/variant-radial.tsx +15 -10
  376. package/src/components/audio-visualizer/variant-wave.tsx +7 -2
  377. package/src/components/card-renderer.tsx +39 -8
  378. package/src/components/card.tsx +10 -2
  379. package/src/components/chat-container.tsx +4 -1
  380. package/src/components/chat-scope-picker.tsx +2 -2
  381. package/src/components/chat-thread.tsx +105 -13
  382. package/src/components/choice-card.tsx +102 -37
  383. package/src/components/coachmark.tsx +1 -1
  384. package/src/components/code-block.tsx +81 -5
  385. package/src/components/composer.tsx +89 -8
  386. package/src/components/confirm-card.tsx +20 -4
  387. package/src/components/conversation-item.tsx +138 -4
  388. package/src/components/conversation-list.tsx +230 -15
  389. package/src/components/embed.tsx +4 -0
  390. package/src/components/empty.tsx +14 -3
  391. package/src/components/file-tree.tsx +5 -1
  392. package/src/components/form-widgets.tsx +257 -195
  393. package/src/components/form.tsx +336 -21
  394. package/src/components/loader.tsx +12 -5
  395. package/src/components/message-skills.tsx +1 -1
  396. package/src/components/message.tsx +142 -12
  397. package/src/components/prompt-input.tsx +7 -1
  398. package/src/components/prompt-suggestion.tsx +4 -1
  399. package/src/components/reasoning.tsx +30 -3
  400. package/src/components/response-compare.tsx +2 -2
  401. package/src/components/response-stream.tsx +13 -7
  402. package/src/components/screen.tsx +5 -0
  403. package/src/components/scroll-button.tsx +63 -4
  404. package/src/components/source.tsx +6 -1
  405. package/src/components/tasks-card.tsx +58 -16
  406. package/src/components/thread.tsx +10 -1
  407. package/src/components/toast.tsx +11 -5
  408. package/src/components/tool-types.ts +9 -0
  409. package/src/components/voice-input.tsx +35 -3
  410. package/src/components/voice-output.tsx +46 -6
  411. package/src/components/workspace-shell.tsx +285 -0
  412. package/src/diagnostics/hook.ts +352 -0
  413. package/src/diagnostics/index.ts +82 -0
  414. package/src/diagnostics/report-request.ts +296 -0
  415. package/src/elements/attachments.tsx +9 -8
  416. package/src/elements/audio-visualizer.tsx +48 -4
  417. package/src/elements/chat-workspace.tsx +159 -287
  418. package/src/elements/chat.tsx +31 -10
  419. package/src/elements/checkbox-group.tsx +164 -0
  420. package/src/elements/checkbox.tsx +134 -0
  421. package/src/elements/code-block.tsx +19 -1
  422. package/src/elements/command.tsx +4 -1
  423. package/src/elements/compiled.css +1 -1
  424. package/src/elements/composer.tsx +12 -1
  425. package/src/elements/conversation-item.tsx +120 -0
  426. package/src/elements/conversation-list.tsx +60 -11
  427. package/src/elements/default-input.tsx +5 -5
  428. package/src/elements/define-entry.ts +12 -0
  429. package/src/elements/define.tsx +168 -8
  430. package/src/elements/diagnostic-events.ts +114 -0
  431. package/src/elements/dialog.tsx +47 -0
  432. package/src/elements/disclosure.ts +34 -12
  433. package/src/elements/dock.tsx +215 -0
  434. package/src/elements/dropdown.tsx +123 -0
  435. package/src/elements/element-data-types.ts +40 -0
  436. package/src/elements/element-diagnostics.ts +392 -0
  437. package/src/elements/element-manifest.json +36 -0
  438. package/src/elements/element-meta.json +1483 -560
  439. package/src/elements/element-nonscalar.json +185 -0
  440. package/src/elements/element-types.d.ts +589 -167
  441. package/src/elements/feedback-bar.tsx +5 -0
  442. package/src/elements/icon-names.json +29 -0
  443. package/src/elements/input.tsx +312 -23
  444. package/src/elements/menu.tsx +13 -0
  445. package/src/elements/message.tsx +2 -0
  446. package/src/elements/pane-grid.tsx +111 -0
  447. package/src/elements/prompt-dock.tsx +2 -1
  448. package/src/elements/prompt-input.tsx +16 -10
  449. package/src/elements/radio-group.tsx +129 -0
  450. package/src/elements/register-impl.ts +52 -0
  451. package/src/elements/register.ts +28 -0
  452. package/src/elements/resizable.tsx +52 -25
  453. package/src/elements/scroll-button.tsx +59 -6
  454. package/src/elements/select.tsx +165 -0
  455. package/src/elements/slider.tsx +171 -0
  456. package/src/elements/slots.ts +108 -13
  457. package/src/elements/styles.css +119 -9
  458. package/src/elements/thinking-bar.tsx +16 -7
  459. package/src/elements/thread.tsx +2 -0
  460. package/src/elements/toast.tsx +17 -1
  461. package/src/elements/tool.tsx +26 -5
  462. package/src/elements/voice-input.tsx +11 -2
  463. package/src/elements/voice-output.tsx +16 -3
  464. package/src/index.ts +4 -1
  465. package/src/primitives/card-data-types.ts +49 -0
  466. package/src/primitives/card-host.tsx +4 -2
  467. package/src/primitives/card-routing.ts +7 -56
  468. package/src/primitives/card-schemas/form.schema.json +21 -1
  469. package/src/primitives/card-validate.ts +10 -2
  470. package/src/primitives/chat-config.tsx +33 -6
  471. package/src/primitives/field-mask.ts +256 -0
  472. package/src/primitives/field-semantics.ts +115 -0
  473. package/src/primitives/input-mask.ts +853 -0
  474. package/src/primitives/toast-store.ts +66 -4
  475. package/src/primitives/url-scheme-policy.ts +70 -0
  476. package/src/primitives/use-resize-observer.ts +33 -0
  477. package/src/primitives/use-speech-recognition.ts +12 -1
  478. package/src/primitives/use-stick-to-bottom.ts +34 -2
  479. package/src/primitives/use-text-stream.ts +33 -2
  480. package/src/remote/provider-runtime.ts +6 -3
  481. package/src/schemas/index.ts +1 -0
  482. package/src/schemas/tool-defs.ts +307 -6
  483. package/src/solid.ts +15 -0
  484. package/src/state/index.ts +13 -1
  485. package/src/state/mock.ts +92 -6
  486. package/src/state/persistence.ts +180 -0
  487. package/src/state/stream.ts +71 -4
  488. package/src/state/threads.ts +142 -0
  489. package/src/types.ts +4 -2
  490. package/src/ui/agent-card.tsx +2 -2
  491. package/src/ui/avatar.tsx +1 -1
  492. package/src/ui/checkbox-group.tsx +153 -0
  493. package/src/ui/checkbox.tsx +63 -0
  494. package/src/ui/dialog.tsx +6 -0
  495. package/src/ui/dock.tsx +584 -0
  496. package/src/ui/dropdown.tsx +67 -23
  497. package/src/ui/hover-card.tsx +156 -6
  498. package/src/ui/icon.tsx +53 -0
  499. package/src/ui/input.tsx +275 -16
  500. package/src/ui/kbd.tsx +1 -1
  501. package/src/ui/nav.tsx +1 -1
  502. package/src/ui/pane-group.tsx +2 -2
  503. package/src/ui/radio.tsx +150 -0
  504. package/src/ui/resizable.tsx +11 -0
  505. package/src/ui/select.tsx +168 -0
  506. package/src/ui/slider.tsx +178 -0
  507. package/src/ui/switch.tsx +49 -18
  508. package/src/utils/cn.ts +11 -5
  509. package/src/wire/chunk.ts +47 -0
  510. package/src/wire/consume.ts +185 -26
  511. package/src/wire/diagnostics.ts +727 -0
  512. package/src/wire/encode-probe.ts +214 -0
  513. package/src/wire/encode.ts +267 -14
  514. package/src/wire/formats/anthropic.ts +8 -1
  515. package/src/wire/formats/openai.ts +5 -0
  516. package/src/wire/index.ts +22 -0
  517. package/src/wire/read.ts +250 -6
  518. package/src/wire/sse.ts +16 -3
  519. package/theme.css +84 -13
  520. package/dist/elements/chunks/action-icons-DW9muWrY.js +0 -1
  521. package/dist/elements/chunks/arrow-left-iJVnQmxA.js +0 -1
  522. package/dist/elements/chunks/artifact-BSuPYFHY.js +0 -1
  523. package/dist/elements/chunks/attachments-CL6TaqIb.js +0 -1
  524. package/dist/elements/chunks/audio-visualizer-BuUqQmaO.js +0 -1
  525. package/dist/elements/chunks/badge-TIMiJFKc.js +0 -1
  526. package/dist/elements/chunks/bash-InADTalH.js +0 -1
  527. package/dist/elements/chunks/card-renderer-CSoTL_e1.js +0 -1
  528. package/dist/elements/chunks/card-routing-BK09BdmL.js +0 -1
  529. package/dist/elements/chunks/chat-thread-DxoKaStk.js +0 -1
  530. package/dist/elements/chunks/check-MdLzbxrm.js +0 -1
  531. package/dist/elements/chunks/chevron-down-MK7IzDqe.js +0 -1
  532. package/dist/elements/chunks/chevron-right-C5jXhmtV.js +0 -1
  533. package/dist/elements/chunks/choice-card-CGMc3kek.js +0 -1
  534. package/dist/elements/chunks/circle-BG7VkPep.js +0 -1
  535. package/dist/elements/chunks/circle-check-GqvO2UBs.js +0 -1
  536. package/dist/elements/chunks/circle-x-mhH7pOK2.js +0 -1
  537. package/dist/elements/chunks/code-block-ClhQO9RW.js +0 -1
  538. package/dist/elements/chunks/collapsible-DBcBkFPh.js +0 -1
  539. package/dist/elements/chunks/composer-CZZmtYOT.js +0 -69
  540. package/dist/elements/chunks/confirm-card-BWjf2-xo.js +0 -1
  541. package/dist/elements/chunks/context-hKjNqiyQ.js +0 -1
  542. package/dist/elements/chunks/conversation-list-CsGJjSKG.js +0 -1
  543. package/dist/elements/chunks/core-AYMC6_lb.js +0 -12
  544. package/dist/elements/chunks/css-M7EaDHN_.js +0 -1
  545. package/dist/elements/chunks/default-input-B1Mem5wu.js +0 -1
  546. package/dist/elements/chunks/define-B_tXMYRm.js +0 -1
  547. package/dist/elements/chunks/disclosure-DAoYOKew.js +0 -1
  548. package/dist/elements/chunks/download-DnCyWFJE.js +0 -1
  549. package/dist/elements/chunks/dropdown-CmNna5lT.js +0 -1
  550. package/dist/elements/chunks/embed-CjAD2jSi.js +0 -1
  551. package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +0 -141
  552. package/dist/elements/chunks/file-text-D0J9F6M7.js +0 -1
  553. package/dist/elements/chunks/folder-NV1pi_ud.js +0 -1
  554. package/dist/elements/chunks/form-Cp8Y00Wn.js +0 -1
  555. package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +0 -1
  556. package/dist/elements/chunks/github-light-JYsPkUQd.js +0 -1
  557. package/dist/elements/chunks/hover-card-6KtXpLwT.js +0 -1
  558. package/dist/elements/chunks/html-CPZ3oZQ7.js +0 -1
  559. package/dist/elements/chunks/icon-97R8SR2p.js +0 -1
  560. package/dist/elements/chunks/info-C8r5Q6cc.js +0 -1
  561. package/dist/elements/chunks/input-DrseEjhp.js +0 -1
  562. package/dist/elements/chunks/javascript-C25yR2R2.js +0 -1
  563. package/dist/elements/chunks/json-DxJze_jm.js +0 -1
  564. package/dist/elements/chunks/kbd-OGJDUT-O.js +0 -1
  565. package/dist/elements/chunks/link-BdsfLB7b.js +0 -1
  566. package/dist/elements/chunks/loader-B5QzK_8_.js +0 -1
  567. package/dist/elements/chunks/message-CE4k-qaj.js +0 -1
  568. package/dist/elements/chunks/message-DtXKPqiR.js +0 -1
  569. package/dist/elements/chunks/message-square-C9ovmtOo.js +0 -1
  570. package/dist/elements/chunks/paperclip-Bg0ITU3b.js +0 -1
  571. package/dist/elements/chunks/progress-bar-D1_rzt6N.js +0 -1
  572. package/dist/elements/chunks/prompt-suggestion-D5Sm8xF1.js +0 -1
  573. package/dist/elements/chunks/reasoning-BrxQfpfI.js +0 -1
  574. package/dist/elements/chunks/rotate-cw-DzVDJOA1.js +0 -1
  575. package/dist/elements/chunks/scroll-area-93A1bbeG.js +0 -1
  576. package/dist/elements/chunks/scroll-button-CrTo7wm4.js +0 -1
  577. package/dist/elements/chunks/share-DgNbkJKY.js +0 -1
  578. package/dist/elements/chunks/slots-CIw9RlAe.js +0 -1
  579. package/dist/elements/chunks/source-w9V0NnBn.js +0 -1
  580. package/dist/elements/chunks/star-DHvACxtm.js +0 -1
  581. package/dist/elements/chunks/store-HIPGhNz9.js +0 -1
  582. package/dist/elements/chunks/svelte--5p79yCD.js +0 -1
  583. package/dist/elements/chunks/tasks-card-lPxoodlA.js +0 -1
  584. package/dist/elements/chunks/text-shimmer-BY_rI3s5.js +0 -1
  585. package/dist/elements/chunks/textarea-DPfuhswM.js +0 -1
  586. package/dist/elements/chunks/toast-store-VUZZBhzH.js +0 -1
  587. package/dist/elements/chunks/tsx-B8rCNbgL.js +0 -1
  588. package/dist/elements/chunks/typescript-RycA9KXf.js +0 -1
  589. package/dist/elements/chunks/use-card-resolution-DJg32jGH.js +0 -1
  590. package/dist/elements/chunks/variant-custom-D5ZlmziF.js +0 -1
  591. package/dist/elements/chunks/video-Bb86fVYI.js +0 -1
  592. package/dist/elements/chunks/vue-BmIZj4XD.js +0 -1
  593. package/dist/elements/chunks/x-BOhjBeOd.js +0 -1
  594. package/dist/llms/llms-full.txt +0 -2834
  595. package/dist/llms/llms.txt +0 -156
  596. package/dist/primitives/card-validate-generator.testlib.d.ts +0 -20
  597. package/dist/register-impl-DGmGzrEM.js +0 -145
  598. package/dist/ui/stat.d.ts +0 -16
  599. package/dist/variant-custom-MkTNTycd.js +0 -1
  600. package/src/primitives/card-validate-generator.testlib.ts +0 -38
  601. package/src/ui/stat.tsx +0 -41
  602. /package/dist/{elements/chunks/card-tags-D8lZ-C_U.js → card-tags-D8lZ-C_U.js} +0 -0
  603. /package/dist/{elements/chunks/link-preview-DNILK391.js → link-preview-DNILK391.js} +0 -0
package/src/wire/index.ts CHANGED
@@ -52,6 +52,28 @@ export { anthropicMessagesFormat } from './formats/anthropic';
52
52
  export { sseDataFrames, sseJson, readableToAsyncIterable } from './sse';
53
53
  export type { ByteSource } from './sse';
54
54
 
55
+ // The diagnostic event stream: metadata about what the pipeline SAW.
56
+ //
57
+ // Only the subscription and the types are public. `emitWireDiagnostic`,
58
+ // `wireDiagnosticsActive` and `nextStreamId` stay internal on purpose -- they
59
+ // are the producer side, and a consumer that can forge events or reset the
60
+ // stream counter can make a panel lie about a stream that never happened.
61
+ export { subscribeWireDiagnostics } from './diagnostics';
62
+ export type {
63
+ AppRequestEvent,
64
+ EncodeAttachmentReport,
65
+ EncodeDroppedEvent,
66
+ EncodeRequestEvent,
67
+ WireCloseEvent,
68
+ WireDiagnosticBase,
69
+ WireDiagnosticEvent,
70
+ WireFailedEvent,
71
+ WireFrameEvent,
72
+ WireInterruptedEvent,
73
+ WireOpenEvent,
74
+ WirePartEvent,
75
+ } from './diagnostics';
76
+
55
77
  export { normalizeStopReason } from './chunk';
56
78
  export type {
57
79
  AssistantStreamSink,
package/src/wire/read.ts CHANGED
@@ -21,6 +21,85 @@ import type {
21
21
  } from './chunk';
22
22
  import { openaiChatFormat } from './formats/openai';
23
23
  import { anthropicMessagesFormat } from './formats/anthropic';
24
+ import {
25
+ emitWireDiagnostic,
26
+ nextStreamId,
27
+ wireCorrelation,
28
+ wireDiagnosticsActive,
29
+ withPayload,
30
+ type WireCorrelation,
31
+ } from './diagnostics';
32
+
33
+ /** Byte length, not `String.length`: a multibyte frame is bigger than its
34
+ * character count and the number is meant to be comparable with what the socket
35
+ * carried.
36
+ *
37
+ * Built on first use and cached, never at module scope -- the same rule
38
+ * `sseJson` follows for its TextDecoder, so this module keeps importing cleanly
39
+ * in a runtime that lacks the global. Only ever reached from inside an
40
+ * active-diagnostics branch. */
41
+ let encoder: TextEncoder | undefined;
42
+
43
+ function byteLength(raw: string): number {
44
+ encoder ??= new TextEncoder();
45
+ return encoder.encode(raw).length;
46
+ }
47
+
48
+ /** What the caller handed over, for `wire.open`. Duck-typed on the same terms as
49
+ * `isResponse`, because none of these globals is guaranteed to exist. */
50
+ function sourceKind(source: StreamSource): 'response' | 'stream' | 'iterable' {
51
+ if (isResponse(source)) return 'response';
52
+ return typeof (source as ReadableStream<Uint8Array>).getReader === 'function'
53
+ ? 'stream'
54
+ : 'iterable';
55
+ }
56
+
57
+ /**
58
+ * The connection identity fields of `wire.open`, for a `Response` source.
59
+ *
60
+ * ORIGIN AND PATHNAME ONLY. The query string is dropped here and is reported
61
+ * nowhere, under no switch: `?api_key=sk-...` is a credential rather than
62
+ * conversation content, so it is not the payload key's business either. What a
63
+ * reader actually needs from it is one bit -- was there one -- and that is
64
+ * `hasQuery`.
65
+ *
66
+ * EVERY FIELD IS OMITTED RATHER THAN GUESSED. A `Response` constructed in a test
67
+ * or handed back by a service worker carries `url: ''`, and an empty string
68
+ * would read as "served from the origin root". Same for a missing content-type:
69
+ * absent means "the response did not say", which is a different fact from
70
+ * "it said nothing", and only one of them is true.
71
+ *
72
+ * Only ever called from inside an active-diagnostics branch.
73
+ */
74
+ function connectionOf(res: Response): {
75
+ url?: string;
76
+ hasQuery?: boolean;
77
+ status?: number;
78
+ contentType?: string;
79
+ } {
80
+ const out: { url?: string; hasQuery?: boolean; status?: number; contentType?: string } = {};
81
+
82
+ if (typeof res.status === 'number') out.status = res.status;
83
+
84
+ // `headers` is duck-typed like the rest of this file: a Response-shaped object
85
+ // from a runtime we have not met may not carry a full Headers implementation.
86
+ const contentType = res.headers?.get?.('content-type');
87
+ if (typeof contentType === 'string' && contentType !== '') out.contentType = contentType;
88
+
89
+ const raw = typeof res.url === 'string' ? res.url : '';
90
+ if (raw !== '') {
91
+ try {
92
+ const parsed = new URL(raw);
93
+ out.url = `${parsed.origin}${parsed.pathname}`;
94
+ out.hasQuery = parsed.search !== '';
95
+ } catch {
96
+ // A relative or malformed URL. Reporting the raw string would leak the
97
+ // very query string this function exists to strip, so it is dropped whole.
98
+ }
99
+ }
100
+
101
+ return out;
102
+ }
24
103
 
25
104
  export type StreamSource =
26
105
  | Response
@@ -71,6 +150,21 @@ function providerMessage(body: unknown): string | undefined {
71
150
  return typeof top === 'string' ? top : undefined;
72
151
  }
73
152
 
153
+ /** The provider's error CODE, by the same walk `providerMessage` does for the
154
+ * message. The code is the half that can travel on a diagnostic event: it is a
155
+ * closed vocabulary a panel can key its own explanation off, while the message
156
+ * is free text some providers fill with echoed request content. */
157
+ function providerErrorCode(body: unknown): string | number | undefined {
158
+ if (typeof body !== 'object' || body === null) return undefined;
159
+ const error = (body as { error?: unknown }).error;
160
+ if (typeof error === 'object' && error !== null) {
161
+ const code = (error as { code?: unknown }).code;
162
+ if (typeof code === 'string' || typeof code === 'number') return code;
163
+ }
164
+ const top = (body as { code?: unknown }).code;
165
+ return typeof top === 'string' || typeof top === 'number' ? top : undefined;
166
+ }
167
+
74
168
  function buildMessage(status: number, statusText: string, bodyText: string, body: unknown): string {
75
169
  const head = `Model request failed: HTTP ${status}${statusText ? ` ${statusText}` : ''}`;
76
170
  const provider = providerMessage(body);
@@ -79,6 +173,20 @@ function buildMessage(status: number, statusText: string, bodyText: string, body
79
173
  return snippet ? `${head}: ${snippet}` : head;
80
174
  }
81
175
 
176
+ /**
177
+ * The `name` of whatever was thrown, when there is one to read.
178
+ *
179
+ * Duck-typed rather than `instanceof Error`: a `DOMException` from a fetch
180
+ * abort, an error from another realm, and a host object that merely looks like
181
+ * an error all carry a usable `name`, and only the first of those is an `Error`
182
+ * in this realm. A bare string or number carries none, and that is reported as
183
+ * ABSENT -- filling in `'Error'` would invent a class the throw never claimed.
184
+ */
185
+ function errorNameOf(err: unknown): string | undefined {
186
+ const name = (err as { name?: unknown } | null | undefined)?.name;
187
+ return typeof name === 'string' && name !== '' ? name : undefined;
188
+ }
189
+
82
190
  /** Duck-typed, because `Response` may not be a global in every runtime the kit
83
191
  * is imported into. A ReadableStream has no `ok`, and an async iterable that
84
192
  * happens to have all three of these is not a shape any transport produces. */
@@ -103,9 +211,40 @@ async function wireErrorFrom(res: Response): Promise<WireError> {
103
211
  return new WireError(res.status, res.statusText, bodyText, body);
104
212
  }
105
213
 
106
- async function toByteSource(source: StreamSource): Promise<ByteSource> {
214
+ async function toByteSource(
215
+ source: StreamSource,
216
+ correlation?: WireCorrelation,
217
+ ): Promise<ByteSource> {
107
218
  if (!isResponse(source)) return source;
108
- if (!source.ok) throw await wireErrorFrom(source);
219
+ if (!source.ok) {
220
+ const err = await wireErrorFrom(source);
221
+ if (wireDiagnosticsActive()) {
222
+ emitWireDiagnostic({
223
+ type: 'wire.failed',
224
+ t: Date.now(),
225
+ ...correlation,
226
+ status: err.status,
227
+ statusText: err.statusText,
228
+ bodyBytes: byteLength(err.bodyText),
229
+ // `wireErrorFrom` leaves `body` undefined when the text was empty or did
230
+ // not parse, so this is exactly "the body was JSON".
231
+ bodyIsJson: err.body !== undefined,
232
+ // The code travels; `bodyText` and the provider's message do NOT.
233
+ ...(providerErrorCode(err.body) !== undefined
234
+ ? { providerCode: providerErrorCode(err.body) }
235
+ : {}),
236
+ // The message is the field that echoes request content back, which is
237
+ // precisely why it is here and not beside `providerCode`.
238
+ ...withPayload(() => ({
239
+ bodyText: err.bodyText,
240
+ ...(providerMessage(err.body) !== undefined
241
+ ? { message: providerMessage(err.body) }
242
+ : {}),
243
+ })),
244
+ });
245
+ }
246
+ throw err;
247
+ }
109
248
  if (!source.body) {
110
249
  throw new Error(
111
250
  'The model response has no body to stream. Check that the request set stream: true and that nothing between you and the provider buffered it.',
@@ -120,16 +259,121 @@ export async function readModelStream(
120
259
  sink: AssistantStreamSink,
121
260
  opts: ReadOptions,
122
261
  ): Promise<ModelTurn> {
123
- const bytes = await toByteSource(source);
262
+ // FIRST, before the source is even resolved: a failure inside `toByteSource`
263
+ // still needs an id to report itself under.
264
+ const streamId = opts.streamId ?? nextStreamId();
265
+ // Built once and spread onto every event this read emits, `wire.failed`
266
+ // included -- a read that dies before its first frame still belongs to the
267
+ // app's trace, and that is exactly the read someone is looking for.
268
+ const correlation = wireCorrelation(streamId, opts);
269
+ const bytes = await toByteSource(source, correlation);
270
+ if (wireDiagnosticsActive()) {
271
+ emitWireDiagnostic({
272
+ type: 'wire.open',
273
+ t: Date.now(),
274
+ ...correlation,
275
+ format: opts.format.id,
276
+ source: sourceKind(source),
277
+ ...(isResponse(source) ? connectionOf(source) : {}),
278
+ });
279
+ }
124
280
  // Opened ONCE per stream, which is the whole point of the open()/push() shape:
125
281
  // a stateful format (Anthropic) gets a fresh block map per call.
126
282
  const reader = opts.format.open();
283
+
284
+ let frames = 0;
285
+ // Chunks YIELDED by this generator, counted here rather than read back off
286
+ // `consumeModelStream`: when the read dies, that function is mid-throw and
287
+ // has nothing to hand back.
288
+ let yielded = 0;
289
+ // The raw payload of the frame currently being handed over. `onRawFrame` fires
290
+ // immediately before `sseJson` yields, so this is always the frame the next
291
+ // loop iteration is about to push.
292
+ //
293
+ // ALWAYS INSTALLED, deliberately. Deciding this once at read entry meant a
294
+ // subscriber attaching mid-stream saw `bytes: 0` on every later frame -- a
295
+ // confident zero, and the forward-compat rule exists precisely so a consumer
296
+ // is never handed one. The capture is a reference stash and nothing else; the
297
+ // UTF-8 length is computed only inside the active-gated branch below, so with
298
+ // nobody listening the cost is one closure call and one assignment per frame.
299
+ let rawFrame = '';
300
+ const onRawFrame = (raw: string) => {
301
+ rawFrame = raw;
302
+ };
303
+
127
304
  async function* chunks(): AsyncGenerator<ModelStreamChunk> {
128
- for await (const frame of sseJson<unknown>(bytes)) {
129
- for (const chunk of reader.push(frame)) yield chunk;
305
+ for await (const frame of sseJson<unknown>(bytes, onRawFrame)) {
306
+ frames++;
307
+ const produced = reader.push(frame);
308
+ // Gated BEFORE the event object exists, and before the keys are walked.
309
+ if (wireDiagnosticsActive()) {
310
+ const fields = new Set<string>();
311
+ let model: string | undefined;
312
+ for (const chunk of produced) {
313
+ for (const key of Object.keys(chunk)) fields.add(key);
314
+ if (chunk.model) model = chunk.model;
315
+ }
316
+ emitWireDiagnostic({
317
+ type: 'wire.frame',
318
+ t: Date.now(),
319
+ ...correlation,
320
+ seq: frames,
321
+ bytes: byteLength(rawFrame),
322
+ chunks: produced.length,
323
+ fields: [...fields],
324
+ ...(model ? { model } : {}),
325
+ ...withPayload(() => ({ raw: rawFrame })),
326
+ });
327
+ }
328
+ for (const chunk of produced) {
329
+ yielded++;
330
+ yield chunk;
331
+ }
332
+ }
333
+ }
334
+ // `_frames` is INTERNAL and deliberately not on `ConsumeOptions`: it is read
335
+ // once, at the close event, and a public option would invite a caller to
336
+ // supply one. A direct `consumeModelStream` caller passes nothing and its
337
+ // `wire.close` correctly omits `frames` -- there were none.
338
+ //
339
+ // OBSERVE AND RETHROW. `wire.close` is emitted inside `consumeModelStream`, so
340
+ // a read that throws before reaching it ended with no terminal event at all --
341
+ // a stream a panel showed open forever. This is the terminal event for that
342
+ // case, and it is the ONLY thing this wrapper does: the error is not caught,
343
+ // not wrapped, not delayed and not swallowed. `return await` rather than a
344
+ // bare `return` is what puts the rejection inside this try at all.
345
+ //
346
+ // It covers a throw from anywhere under the read -- the byte source dying, the
347
+ // format reader, the host's own sink -- because from the outside all of them
348
+ // are the same fact: this read stopped and produced no turn.
349
+ try {
350
+ return await consumeModelStream(chunks(), sink, {
351
+ ...opts,
352
+ streamId,
353
+ _frames: () => frames,
354
+ } as ConsumeOptions);
355
+ } catch (err) {
356
+ if (wireDiagnosticsActive()) {
357
+ const name = errorNameOf(err);
358
+ emitWireDiagnostic({
359
+ type: 'wire.interrupted',
360
+ t: Date.now(),
361
+ ...correlation,
362
+ frames,
363
+ chunks: yielded,
364
+ // Only a self-identifying abort is called one. Guessing would turn "the
365
+ // provider dropped the connection" into "your user navigated away", and
366
+ // those two have opposite fixes.
367
+ reason: name === 'AbortError' ? 'abort' : 'error',
368
+ ...(name !== undefined ? { errorName: name } : {}),
369
+ ...withPayload(() => {
370
+ const message = (err as { message?: unknown } | null | undefined)?.message;
371
+ return typeof message === 'string' ? { message } : {};
372
+ }),
373
+ });
130
374
  }
375
+ throw err;
131
376
  }
132
- return consumeModelStream(chunks(), sink, opts);
133
377
  }
134
378
 
135
379
  /** OpenAI chat-completions SSE. Also what all nine catalog integrations except
package/src/wire/sse.ts CHANGED
@@ -122,8 +122,19 @@ export async function* sseDataFrames(source: ByteSource): AsyncGenerator<string>
122
122
  * iteration, which is the only thing that makes `drained` mean what it says.
123
123
  * In practice that costs exactly one more `read()`: a server that has sent
124
124
  * `[DONE]` has finished the response body. Frames after the sentinel are
125
- * dropped, so what a caller sees is unchanged. */
126
- export async function* sseJson<T>(source: ByteSource): AsyncGenerator<T> {
125
+ * dropped, so what a caller sees is unchanged.
126
+ *
127
+ * `onRawFrame` is the diagnostics seam: it receives the raw `data:` payload
128
+ * STRING for each frame that parsed, immediately before that frame is yielded,
129
+ * because the payload is discarded here and its byte length cannot be recovered
130
+ * downstream. It is not called for `[DONE]`, for a keep-alive, or for a payload
131
+ * that failed to parse -- so a caller counting calls counts exactly the frames
132
+ * it will be handed. Default undefined: with no diagnostics subscriber nothing
133
+ * passes one in and this is a dead branch. */
134
+ export async function* sseJson<T>(
135
+ source: ByteSource,
136
+ onRawFrame?: (raw: string) => void,
137
+ ): AsyncGenerator<T> {
127
138
  let done = false;
128
139
  for await (const payload of sseDataFrames(source)) {
129
140
  if (done) continue; // drain the rest of the body; yield nothing more
@@ -132,7 +143,9 @@ export async function* sseJson<T>(source: ByteSource): AsyncGenerator<T> {
132
143
  continue;
133
144
  }
134
145
  try {
135
- yield JSON.parse(payload) as T;
146
+ const frame = JSON.parse(payload) as T;
147
+ onRawFrame?.(payload);
148
+ yield frame;
136
149
  } catch {
137
150
  // a keep-alive or a provider's stray line: ignore rather than throw
138
151
  }
package/theme.css CHANGED
@@ -74,8 +74,45 @@
74
74
  added at the bottom. */
75
75
  --color-hover: var(--kai-color-hover, color-mix(in oklab, var(--color-muted) 60%, var(--color-background)));
76
76
  --color-selected: var(--kai-color-selected, color-mix(in oklab, var(--color-primary) 8%, var(--color-background)));
77
+ /* MARKED text — the fill behind a keyword the app has flagged (the composer's
78
+ `highlights` rules, decorated through the CSS Custom Highlight API). This is
79
+ `<mark>`, not a selection and not a status: a warm yellow, the convention
80
+ every browser already ships for <mark> and every reader already reads as
81
+ "someone marked this". Deliberately NOT derived from --color-primary — that
82
+ token is a NEUTRAL near-black in light and near-white in dark, so any tint of
83
+ it is grey, which is why the highlight used to be invisible. Also not blue
84
+ (the browser's own ::selection is blue — a highlight must not read as a
85
+ selection), not red (error) and not the skill/agent pill hues (blue/violet).
86
+ OPAQUE, so it composites predictably over whichever field it lands on.
87
+ Override via --kai-color-highlight. Light: near-black text over it is 15.6:1;
88
+ dark: near-white text over it is 6.7:1 — both well clear of WCAG AA. */
89
+ --color-highlight: var(--kai-color-highlight, hsl(45 96% 78%));
90
+ /* SELECTED text — the kit's own ::selection fill, applied inside every kai-*
91
+ shadow root (see src/elements/styles.css for the scoping rationale). The kit
92
+ owns this because leaving it to the UA meant the browser's blue outranked the
93
+ kit's own deliberate emphasis: a marked keyword was LESS prominent than an
94
+ incidental drag-select. Stays in the cool/blue family the UA trained everyone
95
+ to read as "selected", so it can never be confused with the warm --color-highlight
96
+ mark above; OPAQUE, so a selection over a mark composites cleanly (selection
97
+ paints on top of a custom highlight) instead of muddying into a third colour.
98
+ The FOREGROUND is set too, and that is not cosmetic: without it the selected
99
+ glyph keeps its own colour, and the kit's coloured text — muted text (3.8:1),
100
+ the skill/agent pill hues (3.6:1 / 4.0:1), inline code (4.7:1) — lands at or
101
+ under WCAG AA on this fill. Forcing the foreground token makes the guarantee
102
+ hold for every glyph regardless of what colour it had. Light 13.99:1,
103
+ dark 8.87:1. Override via --kai-color-selection(-foreground). */
104
+ --color-selection: var(--kai-color-selection, hsl(213 94% 87%));
105
+ --color-selection-foreground: var(--kai-color-selection-foreground, hsl(240 10% 3.9%));
77
106
  --color-border: var(--kai-color-border, hsl(240 5.9% 90%));
78
- --color-input: var(--kai-color-input, hsl(240 5.9% 90%));
107
+ /* CONTROL boundary the visible edge of an interactive form control (text
108
+ input, textarea, select, the radio/checkbox ring). WCAG 2.1 SC 1.4.11
109
+ Non-text Contrast requires >=3:1 against the adjacent surface for exactly
110
+ this: a control whose boundary you cannot see is not perceivable. That is
111
+ why this is NOT --color-border: a divider or a card outline is decorative
112
+ and may sit below 3:1, a control's edge may not. Do NOT use border-input
113
+ for list wrappers or panel outlines — use border-border there.
114
+ Contrast is the requirement; a thicker border does not satisfy 1.4.11. */
115
+ --color-input: var(--kai-color-input, hsl(240 5% 53%));
79
116
  /* Focus ring — a deliberate blue (not a neutral) so keyboard focus is always
80
117
  obvious and on-brand in both modes. Light uses a strong blue; dark uses a
81
118
  brighter one for contrast on dark surfaces. Both clear WCAG 2.1 non-text
@@ -108,18 +145,42 @@
108
145
  --radius-lg: var(--radius);
109
146
  --radius-xl: calc(var(--radius) + 4px);
110
147
 
111
- /* Typography scale — semantic sizes shared by all components. Each generates a
112
- Tailwind utility (text-caption / text-meta / text-body / text-title). To
113
- restyle the kit's typography, override the namespaced --kai-text-* token on
114
- :root (e.g. `--kai-text-body: 0.9375rem`) it pierces the Shadow DOM via the
148
+ /* Typography scale — ONE scale for the whole kit. Each semantic name
149
+ (text-micro / text-caption / text-meta / text-compact / text-body /
150
+ text-title / text-lg)
151
+ resolves through a namespaced --kai-text-* token, so overriding that token
152
+ on :root restyles the kit globally — it pierces the Shadow DOM via the
115
153
  var() fallback, exactly like the --kai-color-* tokens. The bare --text-*
116
- names stay internal so a host's own --text-* can't collide. (Message/markdown/
117
- input reading size also scales with the `proseSize` prop; these tokens cover
118
- the fixed chrome & controls.) */
119
- --text-caption: var(--kai-text-caption, 0.6875rem); --text-caption--line-height: 1rem; /* 11px micro labels, badges, sub-counts */
120
- --text-meta: var(--kai-text-meta, 0.75rem); --text-meta--line-height: 1.1rem; /* 12px controls, toggles, switchers, captions */
121
- --text-body: var(--kai-text-body, 0.875rem); --text-body--line-height: 1.45rem; /* 14px primary reading text */
122
- --text-title: var(--kai-text-title, 1rem); --text-title--line-height: 1.5rem; /* 16px emphasis / headers */
154
+ names stay internal so a host's own --text-* can't collide.
155
+
156
+ Tailwind's OWN scale is re-pointed at the same tokens: in Tailwind v4 the
157
+ `text-xs` / `text-sm` / `text-base` / `text-lg` utilities are generated FROM
158
+ --text-xs/sm/base/lg in this very @theme block, so aliasing them makes
159
+ text-xs text-meta, text-sm text-body, text-base text-title and
160
+ text-lg text-lg. That matters because the vast majority of the kit's call
161
+ sites spell the Tailwind name; without the alias the --kai-text-* knobs
162
+ reached ~12% of them and the "globally" promise in the theming guide was
163
+ false. Defaults are byte-identical to stock Tailwind, so nothing moves
164
+ until a consumer actually sets a --kai-text-* token — including in a
165
+ consumer's own Tailwind build that imports this file, which is the point:
166
+ one scale everywhere, kit and app moving together.
167
+
168
+ Line-heights are UNITLESS RATIOS (Tailwind's own), never fixed rem. A fixed
169
+ leading does not scale: --kai-text-body: 1.25rem under the old 1.45rem
170
+ leading gave 20px text on 23.2px leading — near solid-set — which made the
171
+ themable token unsafe to actually theme.
172
+ (Message/markdown reading size also scales with the `proseSize` prop; these
173
+ tokens cover the fixed chrome & controls.) */
174
+ --text-micro: var(--kai-text-micro, 0.625rem); --text-micro--line-height: calc(0.875 / 0.625); /* 10px — badges, pills, uppercase eyebrows */
175
+ --text-caption: var(--kai-text-caption, 0.6875rem); --text-caption--line-height: calc(1 / 0.6875); /* 11px — micro labels, sub-counts, xs code */
176
+ --text-meta: var(--kai-text-meta, 0.75rem); --text-meta--line-height: calc(1 / 0.75); /* 12px — controls, toggles, switchers, captions */
177
+ --text-xs: var(--kai-text-meta, 0.75rem); --text-xs--line-height: calc(1 / 0.75); /* ≡ text-meta */
178
+ --text-compact: var(--kai-text-compact, 0.8125rem); --text-compact--line-height: calc(1.21875 / 0.8125); /* 13px — dense chrome & code: a notch below body */
179
+ --text-body: var(--kai-text-body, 0.875rem); --text-body--line-height: calc(1.25 / 0.875); /* 14px — primary reading text */
180
+ --text-sm: var(--kai-text-body, 0.875rem); --text-sm--line-height: calc(1.25 / 0.875); /* ≡ text-body */
181
+ --text-title: var(--kai-text-title, 1rem); --text-title--line-height: calc(1.5 / 1); /* 16px — emphasis / headers */
182
+ --text-base: var(--kai-text-title, 1rem); --text-base--line-height: calc(1.5 / 1); /* ≡ text-title */
183
+ --text-lg: var(--kai-text-lg, 1.125rem); --text-lg--line-height: calc(1.75 / 1.125); /* 18px — section headings, lg prose */
123
184
 
124
185
  @keyframes typing { 0%,100% { transform: translateY(0); opacity: .5 } 50% { transform: translateY(-2px); opacity: 1 } }
125
186
  @keyframes loading-dots { 0%,100% { opacity: 0 } 50% { opacity: 1 } }
@@ -180,8 +241,18 @@
180
241
  --color-destructive-soft: var(--kai-color-destructive-soft, color-mix(in oklab, var(--color-destructive) 14%, var(--color-background)));
181
242
  --color-hover: var(--kai-color-hover, color-mix(in oklab, var(--color-muted) 60%, var(--color-background)));
182
243
  --color-selected: var(--kai-color-selected, color-mix(in oklab, var(--color-primary) 8%, var(--color-background)));
244
+ /* Marked text — dark. A deep warm amber rather than the light yellow: a pale
245
+ highlighter on a near-black field would blow out and force the text to flip
246
+ colour. See the light block for the full note. */
247
+ --color-highlight: var(--kai-color-highlight, hsl(40 75% 26%));
248
+ /* Selected text — dark. A deep blue rather than the light one, for the same
249
+ reason the mark darkens. See the light block for the full note. */
250
+ --color-selection: var(--kai-color-selection, hsl(217 60% 32%));
251
+ --color-selection-foreground: var(--kai-color-selection-foreground, hsl(0 0% 98%));
183
252
  --color-border: var(--kai-color-border, hsl(45 4% 17%));
184
- --color-input: var(--kai-color-input, hsl(45 4% 17%));
253
+ /* Control boundary — see the light block. Lifted to clear 3:1 (SC 1.4.11)
254
+ against the dark background and card surfaces. */
255
+ --color-input: var(--kai-color-input, hsl(45 4% 48%));
185
256
  --color-ring: var(--kai-color-ring, hsl(217 91% 68%));
186
257
  --color-scrollbar-thumb: var(--kai-color-scrollbar-thumb, hsl(45 3% 30%));
187
258
  --color-scrollbar-thumb-hover: var(--kai-color-scrollbar-thumb-hover, hsl(45 3% 42%));
@@ -1 +0,0 @@
1
- import{I as a}from"./Icon-b5A8hlHs.js";import{c as o,m as r}from"./define-B_tXMYRm.js";import{f as t,b as i,s,p,c as m}from"./share-DgNbkJKY.js";import{c as k}from"./check-MdLzbxrm.js";import{d}from"./download-DnCyWFJE.js";import{e as y}from"./ellipsis-CVxqfsDZ.js";import{l as n}from"./link-BdsfLB7b.js";import{s as c}from"./star-DHvACxtm.js";import{a as l,t as h}from"./thumbs-up-DQe0hvkZ.js";import{x as f}from"./x-BOhjBeOd.js";var v=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],M=e=>o(a,r(e,{name:"RefreshCw",iconNode:v})),u=M,x=[["polyline",{points:"9 17 4 12 9 7",key:"hvgpf2"}],["path",{d:"M20 18v-2a4 4 0 0 0-4-4H4",key:"5vmcpk"}]],g=e=>o(a,r(e,{name:"Reply",iconNode:x})),N=g,w=[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]],L=e=>o(a,r(e,{name:"Trash2",iconNode:w})),R=L,b=[["polygon",{points:"11 5 6 9 2 9 2 15 6 15 11 19 11 5",key:"16drj5"}],["path",{d:"M15.54 8.46a5 5 0 0 1 0 7.07",key:"ltjumu"}],["path",{d:"M19.07 4.93a10 10 0 0 1 0 14.14",key:"1kegas"}]],j=e=>o(a,r(e,{name:"Volume2",iconNode:b})),C=j;const H={copy:m,like:h,dislike:l,regenerate:u,edit:p,share:s,bookmark:i,download:d,link:n,trash:R,check:k,x:f,star:c,flag:t,reply:N,more:y,"volume-2":C};function V(e){if(e)return H[e]}const D={copy:"Copy",like:"Like",dislike:"Dislike",regenerate:"Regenerate",edit:"Edit"};export{D as B,V as a};
@@ -1 +0,0 @@
1
- import{I as o}from"./Icon-b5A8hlHs.js";import{c as m,m as r}from"./define-B_tXMYRm.js";var e=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],t=a=>m(o,r(a,{name:"ArrowLeft",iconNode:e})),p=t;export{p as a};
@@ -1 +0,0 @@
1
- import{c as a,m as P,s as fe,g as k,l as y,k as F,x as J,o as Q,q as ge,i as c,S as g,t as v,d as p,a as z,b as X,v as Y,j as be,h as ve,e as me}from"./define-B_tXMYRm.js";import{c as H}from"./cn-CU7UAWzk.js";import{B as C}from"./button-B9okqG73.js";import{C as pe,a as we}from"./code-block-ClhQO9RW.js";import{F as xe}from"./file-tree-yGWNK0Js.js";import{L as ke}from"./loader-B5QzK_8_.js";import{i as ye,a as ee}from"./card-routing-BK09BdmL.js";import{a as ze}from"./arrow-left-iJVnQmxA.js";import{I as re}from"./Icon-b5A8hlHs.js";import{r as Ce,h as Te,c as Fe}from"./rotate-cw-DzVDJOA1.js";import{d as Pe}from"./download-DnCyWFJE.js";import{e as ne}from"./external-link-DG2sRdQL.js";import{f as Oe}from"./file-text-D0J9F6M7.js";import{m as Re,a as Se}from"./minimize-2-SegJ_oku.js";var je=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]],Ie=r=>a(re,P(r,{name:"ArrowRight",iconNode:je})),Ne=Ie,He=[["path",{d:"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z",key:"rwhkz3"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],Me=r=>a(re,P(r,{name:"Eye",iconNode:He})),Ee=Me;const $e="6.0.227",te=`https://cdn.jsdelivr.net/npm/pdfjs-dist@${$e}/build`,Be=()=>import(/*@vite-ignore*/`${te}/pdf.min.mjs`),Le=`${te}/pdf.worker.min.mjs`;let Ue=Be,De=Le,M=null;function Ae(){if(!M){const r=Ue;M=(async()=>{const t=await r(),e=t.default??t;return e.GlobalWorkerOptions.workerSrc=De,e})()}return M}async function Ve(r,t,e){const i=await(await Ae()).getDocument({url:r}).promise;t.replaceChildren();const l=typeof window<"u"&&window.devicePixelRatio?window.devicePixelRatio:1;for(let s=1;s<=i.numPages;s++){const d=await i.getPage(s),u=d.getViewport({scale:1}),h=u.width>0?e/u.width:1,f=d.getViewport({scale:h*l}),b=document.createElement("canvas");b.width=Math.max(1,Math.floor(f.width)),b.height=Math.max(1,Math.floor(f.height)),b.setAttribute("role","img"),b.setAttribute("aria-label",`Page ${s}`),b.style.width="100%",b.style.height="auto",b.style.display="block";const w=b.getContext("2d");t.appendChild(b),await d.render({canvasContext:w,viewport:f}).promise}return{pages:i.numPages}}var We=v('<div><div class="relative min-h-0 flex-1">'),qe=v('<form class="min-w-0 flex-1"><label class=sr-only for=kai-artifact-path>Address</label><input id=kai-artifact-path name=kai-artifact-path type=text autocomplete=off placeholder="Enter a path or URL\u2026">'),Ke=v("<div class=flex-1 aria-hidden=true>"),_e=v('<div role=tablist aria-label=View class="flex shrink-0 items-center gap-0.5 rounded-md bg-muted p-0.5">'),Ge=v('<div data-artifact-toolbar class="flex shrink-0 items-center gap-1.5 border-b border-border bg-surface px-2 py-1.5">'),Ze=v("<button type=button role=tab>"),Je=v('<iframe class="absolute inset-0 h-full w-full border-0 bg-white">'),Qe=v('<div class="absolute inset-0 flex"><div class="w-56 shrink-0 overflow-auto border-r border-border bg-surface-sunken py-1.5 scrollbar-thin"></div><div class="min-w-0 flex-1 overflow-auto scrollbar-thin">'),Xe=v('<div class="flex h-full items-center justify-center p-6 text-sm text-muted-foreground">Select a file to view its source.'),Ye=v('<div class="flex h-full items-center justify-center p-6 text-sm text-muted-foreground">No source \u2014 this file (<!>) has no code view.'),er=v('<div class="flex flex-wrap items-center justify-center gap-2"><a class="inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"target=_blank rel="noopener noreferrer">Open in new tab</a><a class="inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"download>Download'),rr=v(`<div role=region aria-label="PDF preview unavailable"class="absolute inset-0 flex flex-col items-center justify-center gap-3 bg-card p-6 text-center"><div class="text-sm font-medium text-foreground"></div><div class="text-xs text-muted-foreground">Can't preview this PDF inline.`),nr=v(`<div class="text-xs text-muted-foreground">Blocked: that address uses a scheme this viewer won't open.`),tr=v('<div class="pointer-events-none absolute inset-0 flex items-center justify-center">'),ar=v('<div class="absolute inset-0"><div role=region aria-label="PDF preview"tabindex=0 class="absolute inset-0 flex flex-col items-center gap-3 overflow-auto bg-surface-sunken p-3 scrollbar-thin focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset">');const ir="allow-scripts allow-forms";function E(r,t){console.warn(`[kai-artifact] blocked unsafe url in ${r}: ${t}`)}function or(r,t){if(r.url)return r.url;if(!t)return r.path;try{return new URL(r.path,t).href}catch{return r.path}}function lr(r,t){if(!r)return!1;const e=t.find(l=>l.url===r||l.path===r);if(e?.type==="pdf")return!0;const i=r.split(/[?#]/)[0];return/\.pdf$/i.test(i)}function sr(r){const t=P({files:[],defaultTab:"preview",sandbox:ir,showNav:!0,showReload:!0,showHome:!0,showPathField:!0,showTabs:!0,expandable:!1,openInTab:!1,standalone:!1,readonlyPath:!1,maximized:!1},r),[e,i]=fe(t,["src","files","tab","defaultTab","activeFile","sandbox","iframeTitle","onNavigate","onTabChange","onFileSelect","maximized","onMaximizeChange","showNav","showReload","showHome","showPathField","showTabs","expandable","openInTab","standalone","readonlyPath","displayUrl","controllerRef","class"]),[l,s]=k(e.src?[e.src]:[]),[d,u]=k(e.src?0:-1),h=()=>l()[d()]??"",f=()=>d()>0,b=()=>d()<l().length-1,w=y(()=>{const n=h();return n&&ye(n)?(E("preview",n),""):n}),[O,$]=k(e.tab??e.defaultTab),[B,L]=k(e.activeFile),[ie,oe]=k(0),[R,S]=k(e.maximized??!1);F(()=>S(e.maximized??!1));const le=()=>{var n;const o=!R();S(o),(n=e.onMaximizeChange)==null||n.call(e,o)},U=y(()=>{const n=h();return!!n&&n!=="about:blank"&&ee(n)}),D=()=>{const n=h();if(!U()){n&&n!=="about:blank"&&E("openExternal",n);return}window.open(n,"_blank","noopener,noreferrer")},A=y(()=>e.expandable&&!e.standalone),se=y(()=>e.showNav||e.showReload||e.showHome||e.showPathField||e.showTabs||A()||e.openInTab);let x;F(()=>{e.tab!==void 0&&$(e.tab)}),F(()=>L(e.activeFile)),F(J(()=>e.src,n=>{n&&n!==h()&&T(n)},{defer:!0}));const V=n=>n===void 0?void 0:e.files.find(o=>o.path===n),W=y(()=>V(B())),de=y(()=>{const n=W();return!!n&&n.type!=="image"&&n.type!=="pdf"&&typeof n.code=="string"});function T(n){if(n===h()){I();return}s(o=>[...o.slice(0,d()+1),n]),u(o=>o+1),j()}function j(){var n;x&&(x.src=w()||"about:blank"),(n=e.onNavigate)==null||n.call(e,h())}function ue(n){var o;n!==O()&&($(n),(o=e.onTabChange)==null||o.call(e,n))}function q(n,o){var m;L(n),(m=e.onFileSelect)==null||m.call(e,n),T(or(o,e.src))}const K=()=>{f()&&(u(n=>n-1),j())},_=()=>{b()&&(u(n=>n+1),j())};function I(){var n;x&&(x.src="about:blank",x.src=w()||"about:blank"),oe(o=>o+1),(n=e.onNavigate)==null||n.call(e,h())}const G=()=>{e.src&&T(e.src)},Z=n=>{var o;R()!==n&&(S(n),(o=e.onMaximizeChange)==null||o.call(e,n))};Q(()=>{var n;(n=e.controllerRef)==null||n.call(e,{back:()=>K(),forward:()=>_(),reload:()=>I(),home:()=>G(),navigate:o=>T(o),selectFile:o=>{const m=V(o);m&&q(o,m)},openExternal:()=>D(),maximize:()=>Z(!0),restore:()=>Z(!1)})});const ce=()=>{var n,o;try{const m=(n=x?.contentWindow)==null?void 0:n.location.href;m&&m!=="about:blank"&&m!==h()&&(s(N=>[...N.slice(0,d()+1),m]),u(N=>N+1),(o=e.onNavigate)==null||o.call(e,m))}catch{}},he=n=>{n.preventDefault();const o=n.currentTarget.elements.namedItem("kai-artifact-path");if(e.readonlyPath||e.displayUrl!=null){o&&(o.value=e.displayUrl??h());return}o&&o.value&&T(o.value)};return(()=>{var n=We(),o=n.firstChild;return ge(n,P({get class(){return H("flex h-full w-full flex-col overflow-hidden bg-card text-card-foreground",e.standalone&&"rounded-xl border border-border",e.class)}},i),!1,!0),c(n,a(g,{get when(){return se()},get children(){return a(dr,{url:()=>e.displayUrl??h(),tab:O,canBack:f,canForward:b,canHome:()=>!!e.src,onBack:K,onForward:_,onReload:I,onHome:G,onSubmitPath:he,onTab:ue,showNav:()=>e.showNav,showReload:()=>e.showReload,showHome:()=>e.showHome,showPathField:()=>e.showPathField,showTabs:()=>e.showTabs,showExpand:A,showOpenInTab:()=>e.openInTab,maximized:R,onToggleMaximize:le,canOpenInTab:U,onOpenInTab:D,readonlyPath:()=>e.readonlyPath||e.displayUrl!=null})}}),o),c(o,a(g,{get when(){return O()==="preview"},get fallback(){return a(cr,{get files(){return e.files},activeFile:B,activeFileObj:W,hasSource:de,onSelect:q})},get children(){return a(g,{get when(){return lr(h(),e.files)},get fallback(){return a(ur,{ref:m=>x=m,src:w,get sandbox(){return e.sandbox},get title(){return e.iframeTitle??"Artifact preview"},onLoad:ce})},get children(){return a(fr,{get url(){return h()},get reloadKey(){return ie()}})}})}})),n})()}function dr(r){return(()=>{var t=Ge();return c(t,a(g,{get when(){return r.showNav()},get children(){return[a(C,{variant:"ghost",size:"icon-sm","aria-label":"Back",get disabled(){return!r.canBack()},onClick:()=>r.onBack(),get children(){return a(ze,{size:16,"aria-hidden":"true"})}}),a(C,{variant:"ghost",size:"icon-sm","aria-label":"Forward",get disabled(){return!r.canForward()},onClick:()=>r.onForward(),get children(){return a(Ne,{size:16,"aria-hidden":"true"})}})]}}),null),c(t,a(g,{get when(){return r.showReload()},get children(){return a(C,{variant:"ghost",size:"icon-sm","aria-label":"Reload",onClick:()=>r.onReload(),get children(){return a(Ce,{size:15,"aria-hidden":"true"})}})}}),null),c(t,a(g,{get when(){return r.showHome()},get children(){return a(C,{variant:"ghost",size:"icon-sm","aria-label":"Home",get disabled(){return!r.canHome()},onClick:()=>r.onHome(),get children(){return a(Te,{size:15,"aria-hidden":"true"})}})}}),null),c(t,a(g,{get when(){return r.showPathField()},get children(){var e=qe(),i=e.firstChild,l=i.nextSibling;return e.addEventListener("submit",s=>r.onSubmitPath(s)),p(l,"spellcheck",!1),z(s=>{var d=r.readonlyPath()||void 0,u=r.readonlyPath()?"true":void 0,h=H("h-7 w-full rounded-md border border-border px-2.5 text-xs text-foreground font-mono outline-none",r.readonlyPath()?"bg-muted/40 cursor-default":"bg-background focus-visible:ring-2 focus-visible:ring-ring");return d!==s.e&&(l.readOnly=s.e=d),u!==s.t&&p(l,"aria-readonly",s.t=u),h!==s.a&&X(l,s.a=h),s},{e:void 0,t:void 0,a:void 0}),z(()=>l.value=r.url()),e}}),null),c(t,a(g,{get when(){return!r.showPathField()},get children(){return Ke()}}),null),c(t,a(g,{get when(){return r.showExpand()},get children(){return a(C,{variant:"ghost",size:"icon-sm",get"aria-label"(){return r.maximized()?"Collapse":"Expand"},get"aria-expanded"(){return r.maximized()},onClick:()=>r.onToggleMaximize(),get children(){return a(g,{get when(){return r.maximized()},get fallback(){return a(Se,{size:15,"aria-hidden":"true"})},get children(){return a(Re,{size:15,"aria-hidden":"true"})}})}})}}),null),c(t,a(g,{get when(){return r.showOpenInTab()},get children(){return a(C,{variant:"ghost",size:"icon-sm","aria-label":"Open in new tab",get disabled(){return!r.canOpenInTab()},onClick:()=>r.onOpenInTab(),get children(){return a(ne,{size:15,"aria-hidden":"true"})}})}}),null),c(t,a(g,{get when(){return r.showTabs()},get children(){var e=_e();return c(e,a(ae,{label:"Preview",get icon(){return a(Ee,{size:14,"aria-hidden":"true"})},get selected(){return r.tab()==="preview"},onClick:()=>r.onTab("preview")}),null),c(e,a(ae,{label:"Code",get icon(){return a(Fe,{size:14,"aria-hidden":"true"})},get selected(){return r.tab()==="code"},onClick:()=>r.onTab("code")}),null),e}}),null),t})()}function ae(r){return(()=>{var t=Ze();return t.$$click=()=>r.onClick(),c(t,()=>r.icon,null),c(t,()=>r.label,null),z(e=>{var i=r.selected,l=H("inline-flex h-6 items-center gap-1.5 rounded px-2 text-xs font-medium transition-colors outline-none","focus-visible:ring-2 focus-visible:ring-ring",r.selected?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground");return i!==e.e&&p(t,"aria-selected",e.e=i),l!==e.t&&X(t,e.t=l),e},{e:void 0,t:void 0}),t})()}function ur(r){return(()=>{var t=Je();t.addEventListener("load",()=>r.onLoad());var e=r.ref;return typeof e=="function"?Y(e,t):r.ref=t,z(i=>{var l=r.src()||"about:blank",s=r.sandbox,d=r.title;return l!==i.e&&p(t,"src",i.e=l),s!==i.t&&p(t,"sandbox",i.t=s),d!==i.a&&p(t,"title",i.a=d),i},{e:void 0,t:void 0,a:void 0}),t})()}function cr(r){return(()=>{var t=Qe(),e=t.firstChild,i=e.nextSibling;return c(e,a(xe,{get files(){return r.files},get activeFile(){return r.activeFile()},onSelect:(l,s)=>r.onSelect(l,s)})),c(i,a(g,{get when(){return r.activeFileObj()},get fallback(){return Xe()},get children(){return a(g,{get when(){return r.hasSource()},get fallback(){return(()=>{var l=Ye(),s=l.firstChild,d=s.nextSibling;return d.nextSibling,c(l,()=>r.activeFileObj().type??"binary",d),l})()},get children(){return a(pe,{class:"h-full rounded-none border-0",get children(){return a(we,{get code(){return r.activeFileObj().code??""},get language(){return r.activeFileObj().language}})}})}})}})),t})()}function hr(r){const t=()=>{const i=r.url.split(/[?#]/)[0];return i.slice(i.lastIndexOf("/")+1)||"document.pdf"},e=y(()=>{if(r.url){if(ee(r.url))return r.url;E("pdf fallback",r.url)}});return(()=>{var i=rr(),l=i.firstChild;return l.nextSibling,c(i,a(Oe,{size:40,class:"text-muted-foreground","aria-hidden":"true"}),l),c(l,t),c(i,a(g,{get when(){return e()},get fallback(){return nr()},get children(){var s=er(),d=s.firstChild;d.firstChild;var u=d.nextSibling,h=u.firstChild;return c(d,a(ne,{size:13,"aria-hidden":"true"}),null),c(u,a(Pe,{size:13,"aria-hidden":"true"}),h),z(f=>{var b=e(),w=e();return b!==f.e&&p(d,"href",f.e=b),w!==f.t&&p(u,"href",f.t=w),f},{e:void 0,t:void 0}),s}}),null),i})()}function fr(r){const[t,e]=k("loading");let i,l=0,s;const d=async()=>{if(!i){e("error");return}const u=++l;e("loading");try{const h=i.clientWidth||600;await Ve(r.url,i,h),u===l&&e("success")}catch{u===l&&e("error")}};return F(J(()=>[r.url,r.reloadKey],()=>{d()})),Q(()=>{if(!i||typeof ResizeObserver>"u")return;const u=new ResizeObserver(()=>{t()==="success"&&(clearTimeout(s),s=setTimeout(()=>{d()},200))});u.observe(i),ve(()=>{u.disconnect(),clearTimeout(s),l++})}),(()=>{var u=ar(),h=u.firstChild;return Y(f=>i=f,h),c(u,a(g,{get when(){return be(()=>!0)()&&t()==="loading"},get children(){var f=tr();return c(f,a(ke,{variant:"circular",size:"md"})),f}}),null),c(u,a(g,{get when(){return t()==="error"},get children(){return a(hr,{get url(){return r.url}})}}),null),z(()=>p(h,"aria-busy",t()==="loading")),u})()}me(["click"]);export{sr as A};
@@ -1 +0,0 @@
1
- import{c as n,m,s as h,q as p,i as u,S as w,j as R,t as g,z as C,A as I,a as k,d as y}from"./define-B_tXMYRm.js";import{c as d}from"./cn-CU7UAWzk.js";import{B as D}from"./button-B9okqG73.js";import{H as M,a as P,b as N}from"./hover-card-6KtXpLwT.js";import{x as S}from"./x-BOhjBeOd.js";import{f as q}from"./file-text-D0J9F6M7.js";import{p as B,g as E,i as H}from"./paperclip-Bg0ITU3b.js";import{I as V}from"./Icon-b5A8hlHs.js";import{v as F}from"./video-Bb86fVYI.js";var G=[["circle",{cx:"8",cy:"18",r:"4",key:"1fc0mg"}],["path",{d:"M12 18V2l7 4",key:"g04rme"}]],J=r=>n(V,m(r,{name:"Music2",iconNode:G})),K=J,b=g("<div>"),L=g('<img class="size-full object-cover"height=96 width=96>'),O=g('<img class="size-full rounded object-cover"height=20 width=20>'),Q=g('<video class="size-full object-cover"muted>'),U=g('<span class="text-muted-foreground text-caption block truncate">'),X=g('<div><span class="block truncate">'),Y=g("<span class=sr-only>");const _={audio:K,document:q,image:H,source:E,unknown:B,video:F},z=r=>{if(r.type==="source-document")return"source";const t=r.mediaType??"";return t.startsWith("image/")?"image":t.startsWith("video/")?"video":t.startsWith("audio/")?"audio":t.startsWith("application/")||t.startsWith("text/")?"document":"unknown"},A=r=>{if(r.type==="source-document")return r.title||r.filename||"Source";const t=z(r);return r.filename||(t==="image"?"Image":"Attachment")},T=C(),W=C(),$=()=>I(T)??{variant:"grid"},j=()=>{const r=I(W);if(!r)throw new Error("Attachment components must be used within <Attachment>");return r};function Z(r){const[t,i]=h(r,["variant","class","children"]),e=()=>t.variant??"grid";return n(T.Provider,{value:{get variant(){return e()}},get children(){var a=b();return p(a,m({get class(){return d("flex items-start",e()==="list"?"flex-col gap-2":"flex-wrap gap-2",e()==="grid"&&"w-fit",t.class)}},i),!1,!0),u(a,()=>t.children),a}})}function ee(r){const[t,i]=h(r,["data","onRemove","class","children"]),e=$(),a=()=>z(t.data);return n(W.Provider,{value:{get data(){return t.data},get mediaCategory(){return a()},get onRemove(){return t.onRemove},get variant(){return e.variant}},get children(){var o=b();return p(o,m({get class(){return d("group relative",e.variant==="grid"&&"size-24 overflow-hidden rounded-lg",e.variant==="inline"&&["flex h-8 cursor-pointer select-none items-center gap-1.5","rounded-md bg-surface-strong px-1.5 text-foreground","font-medium text-sm transition-all","hover:bg-muted"],e.variant==="list"&&["flex w-full items-center gap-3 rounded-lg bg-surface p-3 text-foreground","hover:bg-muted/50"],t.class)}},i),!1,!0),u(o,()=>t.children),o}})}function re(r){const[t,i]=h(r,["fallbackIcon","class"]),e=j(),a=()=>e.variant==="inline"?"size-3":"size-4",o=c=>n(c,{get class(){return d(a(),"text-muted-foreground")}}),x=()=>{if(e.mediaCategory==="image"&&e.data.type==="file"&&e.data.url)return e.variant==="grid"?(()=>{var l=L();return k(s=>{var v=e.data.filename||"Image",f=e.data.url;return v!==s.e&&y(l,"alt",s.e=v),f!==s.t&&y(l,"src",s.t=f),s},{e:void 0,t:void 0}),l})():(()=>{var l=O();return k(s=>{var v=e.data.filename||"Image",f=e.data.url;return v!==s.e&&y(l,"alt",s.e=v),f!==s.t&&y(l,"src",s.t=f),s},{e:void 0,t:void 0}),l})();if(e.mediaCategory==="video"&&e.data.type==="file"&&e.data.url)return(()=>{var l=Q();return k(()=>y(l,"src",e.data.url)),l})();const c=_[e.mediaCategory];return t.fallbackIcon??o(c)};return(()=>{var c=b();return p(c,m({get class(){return d("flex shrink-0 items-center justify-center overflow-hidden",e.variant==="grid"&&"size-full bg-muted",e.variant==="inline"&&"size-5 rounded bg-background",e.variant==="list"&&"size-12 rounded bg-muted",t.class)}},i),!1,!0),u(c,x),c})()}function te(r){const[t,i]=h(r,["showMediaType","class"]),e=j(),a=()=>A(e.data);return n(w,{get when(){return e.variant!=="grid"},get children(){var o=X(),x=o.firstChild;return p(o,m({get class(){return d("min-w-0 flex-1",t.class)}},i),!1,!0),u(x,a),u(o,n(w,{get when(){return R(()=>!!(t.showMediaType&&e.variant==="list"))()&&e.data.mediaType},get children(){var c=U();return u(c,()=>e.data.mediaType),c}}),null),o}})}function ae(r){const t=j(),i=e=>{var a;e.stopPropagation(),(a=t.onRemove)==null||a.call(t)};return n(w,{get when(){return t.onRemove},get children(){return n(D,{get"aria-label"(){return r.label??"Remove"},get class(){return d(t.variant==="grid"&&["absolute top-2 right-2 size-6 rounded-full p-0","bg-background/80 backdrop-blur-sm","opacity-0 transition-opacity group-hover:opacity-100","hover:bg-background","[&>svg]:size-3"],t.variant==="inline"&&["size-5 rounded p-0","opacity-0 transition-opacity group-hover:opacity-100","[&>svg]:size-2.5"],t.variant==="list"&&["size-8 shrink-0 rounded p-0","[&>svg]:size-4"],r.class)},onClick:i,type:"button",variant:"ghost",get children(){return[R(()=>r.children??n(S,{})),(()=>{var e=Y();return u(e,()=>r.label??"Remove"),e})()]}})}})}function ne(r){return n(M,{get openDelay(){return r.openDelay??0},get closeDelay(){return r.closeDelay??0},get children(){return r.children}})}function ie(r){return n(P,{get class(){return r.class},get children(){return r.children}})}function se(r){return n(N,{get class(){return d("w-auto p-2",r.class)},get children(){return r.children}})}function oe(r){const[t,i]=h(r,["class","children"]);return(()=>{var e=b();return p(e,m({get class(){return d("flex items-center justify-center p-4 text-muted-foreground text-sm",t.class)}},i),!1,!0),u(e,()=>t.children??"No attachments"),e})()}export{Z as A,ee as a,ne as b,ie as c,re as d,te as e,se as f,A as g,z as h,ae as i,oe as j};
@@ -1 +0,0 @@
1
- import{g as z,k as W,h as V,l as ut,i as L,c as M,a as C,d as w,b as E,n as A,I as j,p as B,t as F,q as dt,m as D,M as U,S as ht,j as gt,r as ft,f as mt}from"./define-B_tXMYRm.js";import{c as q}from"./cn-CU7UAWzk.js";const vt=-100,pt=-10;function bt(t){if(t===-1/0)return 0;const e=Math.max(vt,Math.min(pt,t));return Math.sqrt(1-e*-1/100)}function xt(t,e,n,r){const a=t.slice(Math.max(0,n),Math.max(0,r)),s=a.length,c=[];for(let i=0;i<e;i++){const l=Math.floor(i*s/e),h=Math.floor((i+1)*s/e);if(h<=l){c.push(0);continue}let g=0;for(let u=l;u<h;u++)g+=bt(a[u]);c.push(g/(h-l))}return c}function yt(t){if(t.length===0)return 0;let e=0;for(let n=0;n<t.length;n++){const r=t[n];e+=r*r}return Math.sqrt(e/t.length)/255}function Y(t,e){if(t.length===e)return t;if(t.length>e)return t.slice(0,e);const n=t[t.length-1]??0;return[...t,...new Array(e-t.length).fill(n)]}function kt(t,e){const n=(e-1)/2,r=new Array(e);for(let a=0;a<e;a++){const s=Math.floor(Math.abs(a-n));r[a]=t[Math.min(s,t.length-1)]??0}return r}function Mt(t,e){const n=new Array(e);for(let r=0;r<e;r++){const a=Math.min(r,e-r);n[r]=t[Math.min(a,t.length-1)]??0}return n}const wt={bands:5,loPass:100,hiPass:200,updateInterval:32},Q={fftSize:2048,smoothingTimeConstant:.8},I={fftSize:512,smoothingTimeConstant:.55,minDecibels:-100,maxDecibels:-80};function R(t){return typeof t=="function"?t():t}let G;function At(){if(!(typeof AudioContext>"u"))return G??(G=new AudioContext),G}const X=new WeakMap,Z=new WeakMap;function zt(t){return"tagName"in t}function Ct(t){if(t.state!=="suspended")return()=>{};if(typeof document>"u")return()=>{};const e=()=>{t.resume().catch(()=>{})},n=["pointerdown","keydown","touchstart"];return n.forEach(r=>document.addEventListener(r,e,{once:!0,passive:!0})),()=>n.forEach(r=>document.removeEventListener(r,e))}function qt(t,e={}){const n={...wt,...e},[r,a]=z(new Array(R(n.bands)).fill(0)),[s,c]=z(0);return W(()=>{const i=t(),l=R(n.bands);if(a(new Array(l).fill(0)),c(0),!i)return;const h=At();if(!h||typeof requestAnimationFrame>"u"||typeof cancelAnimationFrame>"u")return;const g=cancelAnimationFrame.bind(globalThis),u=Ct(h);let o;if(zt(i)){const b=i;let k=X.get(b);k||(k=h.createMediaElementSource(b),k.connect(h.destination),X.set(b,k)),o=k}else{let b=Z.get(i);b||(b=h.createMediaStreamSource(i),Z.set(i,b)),o=b}const f=h.createAnalyser();f.fftSize=Q.fftSize,f.smoothingTimeConstant=Q.smoothingTimeConstant;const m=h.createAnalyser();m.fftSize=I.fftSize,m.smoothingTimeConstant=I.smoothingTimeConstant,m.minDecibels=I.minDecibels,m.maxDecibels=I.maxDecibels,o.connect(f),o.connect(m);const v=new Float32Array(f.frequencyBinCount),d=new Uint8Array(m.frequencyBinCount);let p=0,x=0;const y=b=>{b-x>=n.updateInterval&&(f.getFloatFrequencyData(v),m.getByteFrequencyData(d),a(xt(v,l,n.loPass,n.hiPass)),c(yt(d)),x=b),p=requestAnimationFrame(y)};p=requestAnimationFrame(y),V(()=>{g(p),u(),f.disconnect(),m.disconnect(),o.disconnect(f),o.disconnect(m)})}),{bands:r,volume:s}}const $t=["idle","connecting","listening","thinking","speaking","disconnected"],Et={failed:"disconnected",initializing:"connecting","pre-connect-buffering":"connecting"};function Ft(t){return t?$t.includes(t)?t:Et[t]??"idle":"idle"}function Dt(t,e){switch(t){case"connecting":{const n=[];for(let r=0;r<e;r++)n.push([r,e-1-r]);return n.length?n:[[]]}case"listening":case"thinking":return[[Math.floor(e/2)],[-1]];case"speaking":return[Array.from({length:e},(n,r)=>r)];case"disconnected":return[[]];default:return[[]]}}function Nt(t,e){switch(t){case"connecting":return 2e3/Math.max(1,e);case"listening":return 500;case"thinking":return 150;default:return 1e3}}function St(t,e,n){const r=[],a=Math.floor(e/2),s=Math.floor(t/2),c={x:Math.max(0,a-n),y:Math.max(0,s-n)},i={x:Math.min(e-1,a+n),y:Math.min(t-1,s+n)};for(let l=c.x;l<=i.x;l++)r.push({x:l,y:c.y});for(let l=c.y+1;l<=i.y;l++)r.push({x:i.x,y:l});for(let l=i.x-1;l>=c.x;l--)r.push({x:l,y:i.y});for(let l=i.y-1;l>c.y;l--)r.push({x:c.x,y:l});return r}function Tt(t,e,n,r){const a={x:Math.floor(n/2),y:Math.floor(e/2)};switch(t){case"connecting":{const s=Math.floor(Math.max(e,n)/2),c=r!==void 0?Math.min(r,s):s,i=St(e,n,c);return i.length?i:[a]}case"listening":{const s={x:-1,y:-1};return[a,s,s,s,s,s,s,s,s]}case"thinking":{const s=Math.floor(e/2),c=[];for(let i=0;i<n;i++)c.push({x:i,y:s});for(let i=n-1;i>=0;i--)c.push({x:i,y:s});return c.length?c:[a]}case"disconnected":return[a];default:return[a]}}function _(t,e){const n=(r,a)=>{for(;a!==0;){const s=a;a=r%a,r=s}return r};for(let r=e;r>=1;r--)if(n(t,r)===r)return r;return 1}function Wt(t){const e=t>8?t/_(t,4):_(t,2),n=Math.max(1,Math.floor(e)),r=Math.floor(t/n);return Array.from({length:n},(a,s)=>Array.from({length:r},(c,i)=>i*n+s))}function Vt(t,e){switch(t){case"connecting":{const n=Math.floor(e/2),r=[];for(let a=0;a<e;a++)r.push([a,(a+n)%e]);return r.length?r:[[]]}case"listening":case"thinking":{const n=Wt(e);return n.length?n:[[]]}case"speaking":return[Array.from({length:e},(n,r)=>r)];case"disconnected":return[[]];default:return[[]]}}function Lt(t){switch(t){case"connecting":case"listening":return 500;case"thinking":return 1/0;default:return 1e3}}function Pt(t){switch(t){case"listening":return{intensity:[.5,.8],speed:2.5};case"thinking":return{intensity:[.25,.5],speed:4};case"connecting":return{intensity:[.25,.5],speed:6};case"speaking":return{intensity:.3,speed:2.5};case"disconnected":return{intensity:.3,speed:.5};default:return{intensity:.3,speed:1}}}const P=5,H=.025,J=10;function It(t){switch(t){case"listening":return{speed:P,amplitude:H,frequency:J,opacity:[1,.3],pulseDuration:.75};case"thinking":case"connecting":return{speed:P*4,amplitude:H/4,frequency:J*4,opacity:[1,.3],pulseDuration:.4};case"speaking":case"idle":return{speed:P*2,amplitude:H,frequency:J,opacity:1,pulseDuration:0};case"disconnected":return{speed:P,amplitude:0,frequency:0,opacity:1,pulseDuration:0};default:return{speed:P,amplitude:0,frequency:0,opacity:1,pulseDuration:0}}}function K(t){const[e,n]=z(0),r=ut(()=>t());return W(()=>{const a=r();if(n(0),!Number.isFinite(a)||a<=0||typeof requestAnimationFrame>"u"||typeof cancelAnimationFrame>"u")return;const s=cancelAnimationFrame.bind(globalThis);let c=0,i=performance.now();const l=h=>{h-i>=a&&(n(g=>g+1),i=h),c=requestAnimationFrame(l)};c=requestAnimationFrame(l),V(()=>s(c))}),e}const O={icon:24,sm:56,md:112,lg:224,xl:448},jt={icon:2,sm:4,md:8,lg:16,xl:32},tt={icon:4,sm:8,md:16,lg:32,xl:64},et={icon:2,sm:4,md:8,lg:12,xl:16},Bt={icon:2,sm:4,md:8,lg:12,xl:16},Ut={icon:6,sm:16,md:32,lg:64,xl:128};function nt(t){return t==="icon"||t==="sm"?3:5}function rt(t){return t==="icon"||t==="sm"?12:24}function at(t){return t==="icon"?3:5}var it=F("<div>");function ot(t){const e=()=>t.barCount??nt(t.size),n=K(()=>t.frozen?1/0:Nt(t.state,e())),r=()=>Dt(t.state,e()),a=()=>r()[n()%r().length]??[],s=()=>t.state==="speaking"?Y(t.bands,e()):new Array(e()).fill(0);return(()=>{var c=it();return L(c,M(j,{get each(){return s()},children:(i,l)=>{var h;const g={index:l,highlighted:()=>a().includes(l),value:()=>i()};return((h=t.children)==null?void 0:h.call(t,g))??(()=>{var u=it();return C(o=>{var f=g.highlighted()?"bar highlighted":"bar",m=g.index,v=g.highlighted(),d=q("rounded-full bg-current/10","data-[kai-highlighted=true]:bg-current"),p=`${tt[t.size]}px`,x=`${tt[t.size]}px`,y=`${i()*100}%`,b=t.frozen?"none":"height 100ms ease-linear, background-color 250ms ease-linear";return f!==o.e&&w(u,"part",o.e=f),m!==o.t&&w(u,"data-kai-index",o.t=m),v!==o.a&&w(u,"data-kai-highlighted",o.a=v),d!==o.o&&E(u,o.o=d),p!==o.i&&A(u,"width",o.i=p),x!==o.n&&A(u,"min-height",o.n=x),y!==o.s&&A(u,"height",o.s=y),b!==o.h&&A(u,"transition",o.h=b),o},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0}),u})()}})),C(i=>{var l=t.state,h=q("relative flex items-center justify-center",t.class),g={height:`${O[t.size]}px`,gap:`${jt[t.size]}px`,...t.color?{color:t.color}:{}};return l!==i.e&&w(c,"data-kai-state",i.e=l),h!==i.t&&E(c,i.t=h),i.a=B(c,g,i.a),i},{e:void 0,t:void 0,a:void 0}),c})()}var st=F("<div>");const Yt=.65,Gt=.02;function Ht(t){const e=()=>t.count??at(t.size),n=()=>e(),r=()=>t.interval??100,a=()=>Array.from({length:e()*n()},(u,o)=>o),s=K(()=>t.frozen||t.state==="speaking"?1/0:r()),c=()=>Tt(t.state,e(),n(),t.spread),i=()=>c()[s()%c().length]??{x:-1,y:-1},l=()=>t.state==="speaking"?Y(t.bands,n()):new Array(n()).fill(0);function h(u){if(t.state==="speaking"){const o=Math.floor(u/n()),f=Math.floor(e()/2),m=Math.abs(f-o)/(f+1)*Yt,v=Math.max(m,Gt);return(l()[u%n()]??0)>=v}return t.state==="idle"||t.state==="disconnected"?!1:i().x===u%n()&&i().y===Math.floor(u/n())}function g(u){return t.state==="speaking"?"150ms":`${r()/(h(u)?1e3:100)}s`}return(()=>{var u=st();return L(u,M(j,{get each(){return a()},children:(o,f)=>{var m;const v={index:f,highlighted:()=>h(f),value:()=>l()[f%n()]??0};return((m=t.children)==null?void 0:m.call(t,v))??(()=>{var d=st();return C(p=>{var x=v.highlighted()?"cell highlighted":"cell",y=v.index,b=v.highlighted(),k=q("place-self-center rounded-full bg-current/10 transition-all ease-out","data-[kai-highlighted=true]:bg-current"),N=`${et[t.size]}px`,S=`${et[t.size]}px`,T=g(f);return x!==p.e&&w(d,"part",p.e=x),y!==p.t&&w(d,"data-kai-index",p.t=y),b!==p.a&&w(d,"data-kai-highlighted",p.a=b),k!==p.o&&E(d,p.o=k),N!==p.i&&A(d,"width",p.i=N),S!==p.n&&A(d,"height",p.n=S),T!==p.s&&A(d,"transition-duration",p.s=T),p},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0}),d})()}})),C(o=>{var f=t.state,m=q("grid",t.class),v={"grid-template-columns":`repeat(${n()}, 1fr)`,gap:`${Bt[t.size]}px`,...t.color?{color:t.color}:{}};return f!==o.e&&w(u,"data-kai-state",o.e=f),m!==o.t&&E(u,o.t=m),o.a=B(u,v,o.a),o},{e:void 0,t:void 0,a:void 0}),u})()}var Jt=F("<div style=aspect-ratio:1>"),Kt=F('<div data-kai-spoke class="absolute top-1/2 left-1/2 h-1 w-1 -translate-x-1/2 -translate-y-1/2"style=transform-origin:center>'),Ot=F("<div>");function Qt(t){const e=()=>Math.max(1,t.barCount??rt(t.size)),n=()=>t.radius??Ut[t.size];e()%4!==0&&console.warn(`<kai-audio-visualizer variant="radial">: barCount ${e()} is not divisible by 4. The ring will look asymmetric.`);const r=()=>n()*Math.PI/e(),a=K(()=>t.frozen?1/0:Lt(t.state)),s=()=>Vt(t.state,e()),c=()=>t.state==="thinking"?Array.from({length:e()},(h,g)=>g):s()[a()%s().length]??[],i=()=>t.state==="speaking"?Y(t.bands,e()):new Array(e()).fill(0),l=()=>t.state==="thinking"&&!t.frozen;return(()=>{var h=Jt();return L(h,M(j,{get each(){return i()},children:(g,u)=>{const o={index:u,highlighted:()=>c().includes(u),value:()=>g()};return(()=>{var f=Kt();return L(f,()=>{var m;return((m=t.children)==null?void 0:m.call(t,o))??(()=>{var v=Ot();return C(d=>{var p=o.highlighted()?"bar highlighted":"bar",x=o.index,y=o.highlighted(),b=q("origin-bottom rounded-full bg-current/10","data-[kai-highlighted=true]:bg-current"),k=`${r()}px`,N=`${r()}px`,S=`${r()*10*g()}px`,T=t.frozen?"none":"height 100ms ease-linear, background-color 150ms ease-linear";return p!==d.e&&w(v,"part",d.e=p),x!==d.t&&w(v,"data-kai-index",d.t=x),y!==d.a&&w(v,"data-kai-highlighted",d.a=y),b!==d.o&&E(v,d.o=b),k!==d.i&&A(v,"width",d.i=k),N!==d.n&&A(v,"min-height",d.n=N),S!==d.s&&A(v,"height",d.s=S),T!==d.h&&A(v,"transition",d.h=T),d},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0}),v})()}),C(m=>A(f,"transform",`rotate(${u/e()*Math.PI*2}rad) translateY(${n()}px)`)),f})()}})),C(g=>{var u=t.state,o=q("relative flex items-center justify-center",l()&&"animate-spin",t.class),f={height:`${O[t.size]}px`,...l()?{"animation-duration":"5s"}:{},...t.color?{color:t.color}:{}};return u!==g.e&&w(h,"data-kai-state",g.e=u),o!==g.t&&E(h,g.t=o),g.a=B(h,f,g.a),g},{e:void 0,t:void 0,a:void 0}),h})()}var Rt=F("<div>");const Xt=["bar","grid","radial","wave","aurora","custom"],Zt={aura:"aurora"};function _t(t){return t?Xt.includes(t)?t:Zt[t]??"bar":"bar"}function te(){const[t,e]=z(!1);return W(()=>{var n;if(typeof matchMedia!="function")return;const r=matchMedia("(prefers-reduced-motion: reduce)");e(r.matches);const a=s=>e(s.matches);(n=r.addEventListener)==null||n.call(r,"change",a),V(()=>{var s;return(s=r.removeEventListener)==null?void 0:s.call(r,"change",a)})}),t}function ee(t){const[e,n]=z(!1);return W(()=>{var r;if(typeof matchMedia!="function")return;const a=matchMedia("(prefers-color-scheme: dark)");n(a.matches);const s=c=>n(c.matches);(r=a.addEventListener)==null||r.call(a,"change",s),V(()=>{var c;return(c=a.removeEventListener)==null?void 0:c.call(a,"change",s)})}),()=>{const r=t()??"auto";return r==="dark"||r==="auto"&&e()}}const ct={wave:()=>import("./variant-wave-DDCwhLas.js"),aurora:()=>import("./variant-aurora-QXTZPyST.js"),custom:()=>import("./variant-custom-D5ZlmziF.js")};function ne(t){const e=()=>_t(t.variant),n=()=>t.size??"md",r=()=>Ft(t.state),a=te(),s=ee(()=>t.theme),c=()=>e()in ct,i=()=>e()==="grid"?t.count??at(n()):e()==="radial"?t.barCount??rt(n()):t.barCount??nt(n()),l=qt(()=>t.bands?void 0:t.stream??t.audioElement,{bands:()=>Math.ceil(i()/2)}),h=()=>t.bands?t.bands:e()==="radial"?Mt(l.bands(),i()):kt(l.bands(),i()),g=()=>{if(!t.bands)return l.volume();if(t.bands.length===0)return 0;let x=0;for(const y of t.bands)x+=y*y;return Math.sqrt(x/t.bands.length)},[u,o]=z(),[f,m]=z(!1);W(()=>{const x=e(),y=ct[x];if(o(void 0),m(!1),!y)return;let b=!1;y().then(k=>{b||o(()=>k.default)}).catch(k=>{b||console.warn(`<kai-audio-visualizer variant="${x}">: failed to load the shader chunk, falling back to bars.`,k)}),V(()=>{b=!0})});const v=()=>({state:r(),size:n(),frozen:a(),color:t.color}),d=()=>({...v(),children:t.children}),p=()=>t.label?{role:"img","aria-label":t.label}:{"aria-hidden":"true"};return(()=>{var x=Rt();return dt(x,D({get class(){return q("inline-flex",t.class)}},p),!1,!0),L(x,M(ft,{get fallback(){return M(ot,D(d,{get bands(){return h()},get barCount(){return t.barCount}}))},get children(){return[M(U,{get when(){return e()==="grid"},get children(){return M(Ht,D(d,{get bands(){return h()},get count(){return t.count},get spread(){return t.spread},get interval(){return t.interval}}))}}),M(U,{get when(){return e()==="radial"},get children(){return M(Qt,D(d,{get bands(){return h()},get barCount(){return t.barCount},get radius(){return t.radius}}))}}),M(U,{get when(){return c()},get children(){return M(ht,{get when(){return gt(()=>!f())()&&u()},get fallback(){return M(ot,D(d,{get bands(){return h()},get barCount(){return t.barCount}}))},children:y=>{const b=y();return M(b,D(v,{get bands(){return h()},get volume(){return g()},get complexity(){return t.complexity},get shader(){return t.shader},get dark(){return s()},get animateWhenNotVisible(){return t.animateWhenNotVisible},onUnavailable:()=>m(!0)}))}})}})]}})),x})()}function $(t){if(t==null||t==="")return;const e=Number(t);return Number.isFinite(e)?e:void 0}function lt(t,e){var n;const r=((n=e?.dark)==null?void 0:n.call(e))??!1,a=e!=null&&e.flag?e.flag("animateWhenNotVisible"):t.animateWhenNotVisible===!0;return M(ne,{get variant(){return t.variant},get state(){return t.state},get size(){return t.size},get barCount(){return $(t.barCount)},get count(){return $(t.count)},get radius(){return $(t.radius)},get spread(){return $(t.spread)},get interval(){return $(t.interval)},get color(){return t.color},get complexity(){return $(t.complexity)},get label(){return t.label},get stream(){return t.stream},get audioElement(){return t.audioElement},get bands(){return t.bands},get shader(){return t.shader},animateWhenNotVisible:a,theme:r?"dark":"light"})}mt("kai-audio-visualizer",{variant:"bar",state:"idle",size:"md",barCount:void 0,count:void 0,radius:void 0,spread:void 0,interval:void 0,color:void 0,complexity:void 0,label:void 0,stream:void 0,audioElement:void 0,bands:void 0,shader:void 0,animateWhenNotVisible:void 0},lt);export{lt as A,O as C,$ as n,Pt as s,It as w};
@@ -1 +0,0 @@
1
- import{s as n,q as i,m as s,i as o,t as u}from"./define-B_tXMYRm.js";import{c as m}from"./index-BCRhi84a.js";import{c}from"./cn-CU7UAWzk.js";var d=u("<span>");const f=m("inline-flex items-center justify-center rounded-full text-xs font-medium min-h-5 min-w-5",{variants:{variant:{default:"bg-muted text-muted-foreground px-2 py-0.5",count:"bg-muted text-muted-foreground h-5 px-1.5",citation:"bg-primary text-primary-foreground px-1.5 py-0.5 cursor-pointer"}},defaultVariants:{variant:"default"}});function p(a){const[t,e]=n(a,["variant","class","children"]);return(()=>{var r=d();return i(r,s({get class(){return c(f({variant:t.variant}),t.class)}},e),!1,!0),o(r,()=>t.children),r})()}export{p as B};