@kitn.ai/ui 0.20.1 → 0.22.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 (510) hide show
  1. package/README.md +44 -45
  2. package/dist/components/artifact-card.d.ts +51 -0
  3. package/dist/components/artifact.d.ts +1 -1
  4. package/dist/components/attachments.d.ts +2 -2
  5. package/dist/components/audio-visualizer/index.d.ts +3 -3
  6. package/dist/components/audio-visualizer/labs/lab-choreography.d.ts +59 -0
  7. package/dist/components/audio-visualizer/labs/lab-shaders.d.ts +22 -0
  8. package/dist/components/audio-visualizer/labs/lab-visualizer.d.ts +18 -0
  9. package/dist/components/audio-visualizer/variant-aurora.d.ts +2 -2
  10. package/dist/components/audio-visualizer/variant-bar.d.ts +2 -2
  11. package/dist/components/audio-visualizer/variant-custom.d.ts +2 -2
  12. package/dist/components/audio-visualizer/variant-grid.d.ts +1 -1
  13. package/dist/components/audio-visualizer/variant-radial.d.ts +1 -1
  14. package/dist/components/audio-visualizer/variant-wave.d.ts +1 -1
  15. package/dist/components/card-fallback.d.ts +12 -2
  16. package/dist/components/card-renderer.d.ts +63 -2
  17. package/dist/components/chat-container.d.ts +3 -0
  18. package/dist/components/chat-scope-picker.d.ts +2 -2
  19. package/dist/components/chat-thread.d.ts +77 -18
  20. package/dist/components/choice-card.d.ts +3 -28
  21. package/dist/components/composer-dom.d.ts +1 -1
  22. package/dist/components/composer-highlight.d.ts +1 -1
  23. package/dist/components/composer-history.d.ts +1 -1
  24. package/dist/components/composer.d.ts +1 -1
  25. package/dist/components/confirm-card.d.ts +3 -18
  26. package/dist/components/context.d.ts +8 -4
  27. package/dist/components/conversation-item.d.ts +1 -1
  28. package/dist/components/conversation-list.d.ts +4 -3
  29. package/dist/components/embed.d.ts +3 -3
  30. package/dist/components/file-tree.d.ts +11 -22
  31. package/dist/components/form-widgets.d.ts +1 -1
  32. package/dist/components/form.d.ts +3 -44
  33. package/dist/components/link-preview.d.ts +3 -3
  34. package/dist/components/loader.d.ts +30 -48
  35. package/dist/components/message-skills.d.ts +4 -0
  36. package/dist/components/message.d.ts +84 -21
  37. package/dist/components/model-switcher.d.ts +2 -2
  38. package/dist/components/prompt-input.d.ts +2 -2
  39. package/dist/components/response-compare-types.d.ts +11 -2
  40. package/dist/components/response-compare.d.ts +3 -3
  41. package/dist/components/source.d.ts +12 -3
  42. package/dist/components/tasks-card.d.ts +3 -31
  43. package/dist/components/thread.d.ts +17 -5
  44. package/dist/components/toast.d.ts +2 -2
  45. package/dist/components/tool-classify.d.ts +8 -0
  46. package/dist/components/tool-types.d.ts +29 -1
  47. package/dist/components/tool.d.ts +3 -3
  48. package/dist/components/use-card-resolution.d.ts +1 -1
  49. package/dist/create-tween-COnPwAQN.js +338 -0
  50. package/dist/create-tween-DmTUaXWE.js +341 -0
  51. package/dist/create-tween-qs-jjvNA.js +7 -0
  52. package/dist/custom-elements.json +1726 -463
  53. package/dist/elements/agent-card.js +1 -1
  54. package/dist/elements/artifact.js +1 -1
  55. package/dist/elements/attachments.js +1 -1
  56. package/dist/elements/audio-visualizer.js +1 -1
  57. package/dist/elements/avatar.js +1 -1
  58. package/dist/elements/badge.js +1 -1
  59. package/dist/elements/button.js +1 -1
  60. package/dist/elements/card.js +1 -1
  61. package/dist/elements/cards.js +1 -1
  62. package/dist/elements/chain-of-thought.js +1 -1
  63. package/dist/elements/chat-scope-picker.js +1 -1
  64. package/dist/elements/chat-types.d.ts +70 -10
  65. package/dist/elements/chat-workspace.js +1 -1
  66. package/dist/elements/chat.js +1 -1
  67. package/dist/elements/checkpoint.js +1 -1
  68. package/dist/elements/choice.js +1 -1
  69. package/dist/elements/chunks/{Icon-Tj58ES_d.js → Icon-CHG5z5L7.js} +1 -1
  70. package/dist/elements/chunks/{action-icons-ns1Fnedj.js → action-icons-BAtCEEgg.js} +1 -1
  71. package/dist/elements/chunks/arrow-left-CFPTeL1Y.js +1 -0
  72. package/dist/elements/chunks/artifact-fBZOE4SO.js +1 -0
  73. package/dist/elements/chunks/{attachments-mCB5F1Fq.js → attachments-DpYMe5VQ.js} +1 -1
  74. package/dist/elements/chunks/audio-visualizer-DFwzAcuL.js +1 -0
  75. package/dist/elements/chunks/{badge-B4Zuajl2.js → badge-D6zodm6E.js} +1 -1
  76. package/dist/elements/chunks/{button-ZWNif3--.js → button-C42vrGvO.js} +1 -1
  77. package/dist/elements/chunks/card-renderer-DMZsSuvU.js +1 -0
  78. package/dist/elements/chunks/card-tags-D8lZ-C_U.js +1 -0
  79. package/dist/elements/chunks/chat-thread-CNNEhol-.js +1 -0
  80. package/dist/elements/chunks/check-7Q3K-iXE.js +1 -0
  81. package/dist/elements/chunks/chevron-down-CpNYLn7E.js +1 -0
  82. package/dist/elements/chunks/chevron-right-DrH85Fha.js +1 -0
  83. package/dist/elements/chunks/choice-card-YoWjpsFV.js +1 -0
  84. package/dist/elements/chunks/circle-C9KRjKYv.js +1 -0
  85. package/dist/elements/chunks/circle-check-Dmi7Y4zw.js +1 -0
  86. package/dist/elements/chunks/{circle-x-B7faJFlY.js → circle-x-QIxXda6k.js} +1 -1
  87. package/dist/elements/chunks/code-block-CqeugReY.js +1 -0
  88. package/dist/elements/chunks/{collapsible-DM1Ckd4e.js → collapsible-sTv-_5lF.js} +1 -1
  89. package/dist/elements/chunks/{composer-BguS0QL_.js → composer-ldQyeVEB.js} +2 -2
  90. package/dist/elements/chunks/confirm-card-C0RNOwfn.js +1 -0
  91. package/dist/elements/chunks/context-5qgypNHC.js +1 -0
  92. package/dist/elements/chunks/conversation-list-DLzOacXz.js +1 -0
  93. package/dist/elements/chunks/create-tween-V4TXZ93X.js +7 -0
  94. package/dist/elements/chunks/default-input-DeeRSDHc.js +1 -0
  95. package/dist/elements/chunks/define-lE-QvQFn.js +1 -0
  96. package/dist/elements/chunks/{disclosure-CIZ5c8nO.js → disclosure-DZSa9jog.js} +1 -1
  97. package/dist/elements/chunks/{download-Dsbg3ste.js → download-B2ZmnGqW.js} +1 -1
  98. package/dist/elements/chunks/{dropdown-BDd1-Zgi.js → dropdown-R3B7cSRE.js} +1 -1
  99. package/dist/elements/chunks/{ellipsis-Dw6qrss-.js → ellipsis-BmxceY4l.js} +1 -1
  100. package/dist/elements/chunks/embed-BVrtTZPo.js +1 -0
  101. package/dist/elements/chunks/{external-link-Vt74zAoL.js → external-link-BbdR7YO7.js} +1 -1
  102. package/dist/elements/chunks/{file-text-CZrZF6_v.js → file-text-D7dijo1A.js} +1 -1
  103. package/dist/elements/chunks/{file-tree-DF4okKyo.js → file-tree-0upJ5jeb.js} +1 -1
  104. package/dist/elements/chunks/{folder-glP5rha4.js → folder-D8z58t7B.js} +1 -1
  105. package/dist/elements/chunks/form-p5BKJNw5.js +1 -0
  106. package/dist/elements/chunks/hover-card-CN9s2md5.js +1 -0
  107. package/dist/elements/chunks/{icon-BLb8beoi.js → icon-CNiKP37E.js} +1 -1
  108. package/dist/elements/chunks/{info-CIsv92JK.js → info-BSnuJiHI.js} +1 -1
  109. package/dist/elements/chunks/{input-Dds1kFyt.js → input-BauDmzxX.js} +1 -1
  110. package/dist/elements/chunks/{kbd-De_xbgi9.js → kbd-BlHJaP9b.js} +1 -1
  111. package/dist/elements/chunks/{link-i4r_k7z4.js → link-DEi5iUWC.js} +1 -1
  112. package/dist/elements/chunks/link-preview-BaHyM6W4.js +1 -0
  113. package/dist/elements/chunks/{loader-BmQH4s3V.js → loader-CmJG_Fkq.js} +1 -1
  114. package/dist/elements/chunks/{markdown-Zi21WhUz.js → markdown-D2jaMpCN.js} +1 -1
  115. package/dist/elements/chunks/message-C5UfXZ2Z.js +1 -0
  116. package/dist/elements/chunks/message-CXWLmmLn.js +1 -0
  117. package/dist/elements/chunks/message-square-hXylwsy0.js +1 -0
  118. package/dist/elements/chunks/{minimize-2--ifeCGrl.js → minimize-2-C9ytZFMU.js} +1 -1
  119. package/dist/elements/chunks/model-switcher-CivGfD7-.js +1 -0
  120. package/dist/elements/chunks/{overlay-kD8dwRv_.js → overlay-DJL_sbOm.js} +1 -1
  121. package/dist/elements/chunks/{paperclip-q21dYOSK.js → paperclip-CFaB8naM.js} +1 -1
  122. package/dist/elements/chunks/{progress-bar-BrAIIaaJ.js → progress-bar-Br5SksfR.js} +1 -1
  123. package/dist/elements/chunks/{prompt-suggestion-Bjn2K-fR.js → prompt-suggestion-CMIvtAhU.js} +1 -1
  124. package/dist/elements/chunks/reasoning-DpZcNzLq.js +1 -0
  125. package/dist/elements/chunks/{resizable-Dp4JExql.js → resizable-Q8i3T9a_.js} +1 -1
  126. package/dist/elements/chunks/{rotate-cw-CFWWkpj2.js → rotate-cw-B5IHCBFV.js} +1 -1
  127. package/dist/elements/chunks/{scroll-area-Bb0kHH1j.js → scroll-area-eLeydBje.js} +1 -1
  128. package/dist/elements/chunks/scroll-button-DWbz0yA1.js +1 -0
  129. package/dist/elements/chunks/{separator-9kRgr1X9.js → separator-Xic78AD_.js} +1 -1
  130. package/dist/elements/chunks/{settings-B8lmec4D.js → settings-B8H51pAx.js} +1 -1
  131. package/dist/elements/chunks/{settings-group-I0hEuXiN.js → settings-group-CsG9eYLe.js} +1 -1
  132. package/dist/elements/chunks/{share-C3lTiYGt.js → share-CNTx0z__.js} +1 -1
  133. package/dist/elements/chunks/skeleton-CLlHTcMI.js +1 -0
  134. package/dist/elements/chunks/slots-CIw9RlAe.js +1 -0
  135. package/dist/elements/chunks/source-BoVcU5ok.js +1 -0
  136. package/dist/elements/chunks/{star-CSJtGxgv.js → star-CxQVTVhI.js} +1 -1
  137. package/dist/elements/chunks/{store-CHyW95TP.js → store-CLtS5CUG.js} +1 -1
  138. package/dist/elements/chunks/tasks-card-CzlkLmUt.js +1 -0
  139. package/dist/elements/chunks/{text-shimmer-Cn9TmNpI.js → text-shimmer-D5NhpIQ1.js} +1 -1
  140. package/dist/elements/chunks/textarea-x5Uxsmtm.js +1 -0
  141. package/dist/elements/chunks/{thumbs-up-PNVVThEF.js → thumbs-up-UobcJnx9.js} +1 -1
  142. package/dist/elements/chunks/{toast-store-DKbQn3Wn.js → toast-store-BOfs9eXq.js} +1 -1
  143. package/dist/elements/chunks/{tool-DjTRpIpl.js → tool-Be6Dh_dt.js} +1 -1
  144. package/dist/elements/chunks/tooltip-RxMxyCLF.js +1 -0
  145. package/dist/elements/chunks/{triangle-alert-DsHTHCPm.js → triangle-alert-C4yxH2XN.js} +1 -1
  146. package/dist/elements/chunks/use-card-resolution-jva9ehH6.js +1 -0
  147. package/dist/elements/chunks/{variant-aurora-Dc4nQUia.js → variant-aurora-Dx4VRcjS.js} +2 -2
  148. package/dist/elements/chunks/{variant-custom-y_3kVQhS.js → variant-custom-Y1ZTWgEa.js} +1 -1
  149. package/dist/elements/chunks/{variant-wave-D5OR1-9Z.js → variant-wave-B9gml9Cg.js} +2 -2
  150. package/dist/elements/chunks/{video-B7vmenoC.js → video-CrPHsytT.js} +1 -1
  151. package/dist/elements/chunks/x-_-OPHept.js +1 -0
  152. package/dist/elements/coachmark.js +1 -1
  153. package/dist/elements/code-block.js +1 -1
  154. package/dist/elements/command.js +1 -1
  155. package/dist/elements/compare.js +1 -1
  156. package/dist/elements/composer.js +1 -1
  157. package/dist/elements/confirm-card.js +1 -1
  158. package/dist/elements/context-meter.js +1 -1
  159. package/dist/elements/conversation-list.js +1 -1
  160. package/dist/elements/default-input.d.ts +34 -7
  161. package/dist/elements/define.d.ts +1 -0
  162. package/dist/elements/dialog.js +1 -1
  163. package/dist/elements/disclosure.d.ts +1 -1
  164. package/dist/elements/editable-label.js +1 -1
  165. package/dist/elements/element-data-types.d.ts +107 -0
  166. package/dist/elements/embed.js +1 -1
  167. package/dist/elements/empty.js +1 -1
  168. package/dist/elements/feedback-bar.js +1 -1
  169. package/dist/elements/file-tree.js +1 -1
  170. package/dist/elements/file-upload.js +1 -1
  171. package/dist/elements/form.js +1 -1
  172. package/dist/elements/hover-card.js +1 -1
  173. package/dist/elements/icon.js +1 -1
  174. package/dist/elements/image.js +1 -1
  175. package/dist/elements/input.js +1 -1
  176. package/dist/elements/kbd.js +1 -1
  177. package/dist/elements/link-preview.js +1 -1
  178. package/dist/elements/loader.js +1 -1
  179. package/dist/elements/markdown.js +1 -1
  180. package/dist/elements/menu.js +1 -1
  181. package/dist/elements/message-skills.js +1 -1
  182. package/dist/elements/message.js +1 -1
  183. package/dist/elements/model-switcher.js +1 -1
  184. package/dist/elements/nav.js +1 -1
  185. package/dist/elements/notice.js +1 -1
  186. package/dist/elements/pane-group.js +1 -1
  187. package/dist/elements/pane.js +1 -1
  188. package/dist/elements/popover.js +1 -1
  189. package/dist/elements/progress-bar.js +1 -1
  190. package/dist/elements/prompt-dock.js +1 -1
  191. package/dist/elements/prompt-input.js +1 -1
  192. package/dist/elements/prompt-suggestions.js +1 -1
  193. package/dist/elements/reasoning.js +1 -1
  194. package/dist/elements/register.d.ts +8 -6
  195. package/dist/elements/remote.js +1 -1
  196. package/dist/elements/resizable.js +1 -1
  197. package/dist/elements/response-stream.js +1 -1
  198. package/dist/elements/screen.js +1 -1
  199. package/dist/elements/scroll-area.js +1 -1
  200. package/dist/elements/scroll-button.js +1 -1
  201. package/dist/elements/search.js +1 -1
  202. package/dist/elements/segmented.js +1 -1
  203. package/dist/elements/separator.js +1 -1
  204. package/dist/elements/setting-item.js +1 -1
  205. package/dist/elements/settings-group.js +1 -1
  206. package/dist/elements/skeleton.js +1 -1
  207. package/dist/elements/slot-text.d.ts +51 -0
  208. package/dist/elements/slots.d.ts +21 -0
  209. package/dist/elements/source.js +1 -1
  210. package/dist/elements/status.js +1 -1
  211. package/dist/elements/switch.js +1 -1
  212. package/dist/elements/tabs.js +1 -1
  213. package/dist/elements/tasks.js +1 -1
  214. package/dist/elements/text-shimmer.js +1 -1
  215. package/dist/elements/thinking-bar.js +1 -1
  216. package/dist/elements/thread.js +1 -1
  217. package/dist/elements/toast.js +1 -1
  218. package/dist/elements/tool.js +1 -1
  219. package/dist/elements/tooltip.js +1 -1
  220. package/dist/elements/validate-messages.d.ts +25 -0
  221. package/dist/elements/voice-input.js +1 -1
  222. package/dist/elements/voice-output.js +1 -1
  223. package/dist/elements.d.ts +2734 -217
  224. package/dist/index.d.ts +163 -125
  225. package/dist/index.js +6572 -5990
  226. package/dist/index.server.d.ts +5 -0
  227. package/dist/index.server.js +5403 -4860
  228. package/dist/kai-provider.es.d.ts +5 -0
  229. package/dist/kai-provider.es.js +79 -77
  230. package/dist/kai.es.d.ts +5 -0
  231. package/dist/kai.es.js +1 -1
  232. package/dist/llms/llms-full.txt +774 -151
  233. package/dist/llms/llms.txt +57 -5
  234. package/dist/mcp.es.js +4756 -782
  235. package/dist/primitives/card-component-types.d.ts +11 -0
  236. package/dist/primitives/card-data-types.d.ts +196 -0
  237. package/dist/primitives/card-host.d.ts +1 -1
  238. package/dist/primitives/card-recovery.d.ts +3 -3
  239. package/dist/primitives/card-registry.d.ts +4 -14
  240. package/dist/primitives/card-resolution.d.ts +1 -1
  241. package/dist/primitives/card-routing.d.ts +1 -1
  242. package/dist/primitives/card-tags.d.ts +11 -0
  243. package/dist/primitives/card-validate-cards.d.ts +57 -0
  244. package/dist/primitives/card-validate-generator.testlib.d.ts +20 -0
  245. package/dist/primitives/card-validate-schemas.d.ts +17 -0
  246. package/dist/primitives/card-validate.d.ts +24 -0
  247. package/dist/primitives/create-kai-chat.d.ts +3 -3
  248. package/dist/primitives/embed-providers.d.ts +1 -1
  249. package/dist/primitives/link-preview.d.ts +1 -1
  250. package/dist/primitives/message-feedback.d.ts +2 -2
  251. package/dist/primitives/toast-store.d.ts +1 -1
  252. package/dist/react/index.d.ts +730 -302
  253. package/dist/react/use-kai-chat.d.ts +8 -4
  254. package/dist/react.d.ts +5 -0
  255. package/dist/react.js +418 -317
  256. package/dist/register-impl-AxIlqjo7.js +145 -0
  257. package/dist/remote/host-embed.d.ts +1 -1
  258. package/dist/remote/index.d.ts +2 -2
  259. package/dist/remote/provider-runtime.d.ts +2 -2
  260. package/dist/remote/provider.d.ts +2 -2
  261. package/dist/remote/validate.d.ts +1 -1
  262. package/dist/remote/wire.d.ts +1 -1
  263. package/dist/schemas/artifact.schema.json +92 -0
  264. package/dist/schemas/embed.schema.json +0 -2
  265. package/dist/schemas/from-tool-call.d.ts +48 -0
  266. package/dist/schemas/index.d.ts +48 -0
  267. package/dist/schemas/link.schema.json +0 -2
  268. package/dist/schemas/provider-subsets.d.ts +136 -0
  269. package/dist/schemas/registry.d.ts +140 -0
  270. package/dist/schemas/tool-defs.d.ts +121 -0
  271. package/dist/schemas.d.ts +5 -0
  272. package/dist/schemas.js +717 -0
  273. package/dist/solid-BGYSJyHG.js +22960 -0
  274. package/dist/solid-Dt2nEwfl.js +20194 -0
  275. package/dist/solid.d.ts +66 -0
  276. package/dist/solid.js +261 -0
  277. package/dist/solid.server.d.ts +5 -0
  278. package/dist/solid.server.js +261 -0
  279. package/dist/state/index.d.ts +14 -4
  280. package/dist/state/messages.d.ts +8 -3
  281. package/dist/state/mock.d.ts +46 -0
  282. package/dist/state/parts.d.ts +85 -0
  283. package/dist/state/stream.d.ts +15 -9
  284. package/dist/state.d.ts +5 -0
  285. package/dist/state.js +253 -84
  286. package/dist/ui/action-icons.d.ts +1 -1
  287. package/dist/ui/collapsible.d.ts +11 -6
  288. package/dist/ui/dropdown.d.ts +47 -42
  289. package/dist/ui/pane-group.d.ts +1 -1
  290. package/dist/{variant-aurora-DVtGqVH6.js → variant-aurora-B44X69AG.js} +1 -1
  291. package/dist/variant-aurora-BRhV8Flk.js +391 -0
  292. package/dist/variant-aurora-Ds5ou9BH.js +381 -0
  293. package/dist/variant-custom-B20FhtYj.js +170 -0
  294. package/dist/{variant-custom-Dif-IV4u.js → variant-custom-BvA1Schl.js} +1 -1
  295. package/dist/variant-custom-D6Rtvneb.js +200 -0
  296. package/dist/{variant-wave-DbfNdvSi.js → variant-wave-BUQtkryq.js} +1 -1
  297. package/dist/variant-wave-BVYnqy9L.js +218 -0
  298. package/dist/variant-wave-DXC6_LcH.js +208 -0
  299. package/dist/wire/chunk.d.ts +171 -0
  300. package/dist/wire/consume.d.ts +26 -0
  301. package/dist/wire/encode.d.ts +221 -0
  302. package/dist/wire/files.d.ts +116 -0
  303. package/dist/wire/formats/anthropic.d.ts +2 -0
  304. package/dist/wire/formats/openai.d.ts +5 -0
  305. package/dist/wire/index.d.ts +16 -0
  306. package/dist/wire/media-types.d.ts +106 -0
  307. package/dist/wire/read.d.ts +26 -0
  308. package/dist/wire/sink-helpers.d.ts +21 -0
  309. package/dist/wire/sse.d.ts +33 -0
  310. package/dist/wire.d.ts +5 -53
  311. package/dist/wire.js +1126 -0
  312. package/frameworks/react/index.tsx +191 -158
  313. package/frameworks/react/runtime.tsx +21 -1
  314. package/frameworks/react/use-kai-chat.tsx +11 -1
  315. package/llms-full.txt +774 -151
  316. package/llms.txt +57 -5
  317. package/package.json +62 -8
  318. package/src/agent-tooling/archetypes.ts +127 -0
  319. package/src/agent-tooling/integrations/anthropic.ts +436 -0
  320. package/src/agent-tooling/integrations/cloudflare.ts +141 -52
  321. package/src/agent-tooling/integrations/langgraph.ts +80 -13
  322. package/src/agent-tooling/integrations/mastra.ts +161 -12
  323. package/src/agent-tooling/integrations/mock.ts +47 -8
  324. package/src/agent-tooling/integrations/ollama.ts +68 -24
  325. package/src/agent-tooling/integrations/openai.ts +89 -0
  326. package/src/agent-tooling/integrations/openrouter.ts +58 -8
  327. package/src/agent-tooling/integrations/pi.ts +104 -23
  328. package/src/agent-tooling/integrations/pydantic-ai.ts +61 -5
  329. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +120 -13
  330. package/src/agent-tooling/mcp/manifest.ts +206 -25
  331. package/src/agent-tooling/mcp/tools/debug.ts +13 -7
  332. package/src/agent-tooling/mcp/tools/reference.ts +285 -6
  333. package/src/agent-tooling/mcp/tools/scaffold.ts +4152 -661
  334. package/src/agent-tooling/registry.ts +74 -0
  335. package/src/agent-tooling/types.ts +361 -1
  336. package/src/components/artifact-card.tsx +120 -0
  337. package/src/components/audio-visualizer/index.tsx +9 -0
  338. package/src/components/audio-visualizer/labs/lab-choreography.ts +187 -0
  339. package/src/components/audio-visualizer/labs/lab-shaders.ts +363 -0
  340. package/src/components/audio-visualizer/labs/lab-visualizer.tsx +102 -0
  341. package/src/components/audio-visualizer/shader-canvas.tsx +31 -1
  342. package/src/components/card-fallback.tsx +42 -10
  343. package/src/components/card-renderer.tsx +146 -9
  344. package/src/components/chat-container.tsx +4 -0
  345. package/src/components/chat-thread.tsx +128 -52
  346. package/src/components/choice-card.tsx +17 -29
  347. package/src/components/composer.tsx +12 -2
  348. package/src/components/confirm-card.tsx +24 -20
  349. package/src/components/context.tsx +30 -16
  350. package/src/components/conversation-item.tsx +6 -0
  351. package/src/components/conversation-list.tsx +18 -2
  352. package/src/components/file-tree.tsx +11 -22
  353. package/src/components/file-upload.tsx +14 -8
  354. package/src/components/form.tsx +14 -47
  355. package/src/components/loader.tsx +39 -12
  356. package/src/components/message-skills.tsx +4 -0
  357. package/src/components/message.tsx +294 -46
  358. package/src/components/model-switcher.tsx +38 -8
  359. package/src/components/reasoning.tsx +92 -5
  360. package/src/components/response-compare-types.ts +25 -0
  361. package/src/components/response-compare.tsx +4 -9
  362. package/src/components/source.tsx +50 -24
  363. package/src/components/tasks-card.tsx +10 -33
  364. package/src/components/thread.tsx +84 -42
  365. package/src/components/toast.tsx +17 -6
  366. package/src/components/tool-classify.ts +26 -0
  367. package/src/components/tool-types.ts +31 -1
  368. package/src/elements/agent-card.tsx +11 -11
  369. package/src/elements/artifact.tsx +15 -7
  370. package/src/elements/attachments.tsx +6 -4
  371. package/src/elements/avatar.tsx +1 -1
  372. package/src/elements/button.tsx +29 -6
  373. package/src/elements/card.tsx +2 -2
  374. package/src/elements/cards.tsx +109 -14
  375. package/src/elements/chain-of-thought.tsx +14 -10
  376. package/src/elements/chat-scope-picker.tsx +9 -7
  377. package/src/elements/chat-types.ts +59 -6
  378. package/src/elements/chat-workspace.tsx +50 -9
  379. package/src/elements/chat.tsx +90 -3
  380. package/src/elements/choice.tsx +8 -8
  381. package/src/elements/coachmark.tsx +1 -1
  382. package/src/elements/command.tsx +8 -23
  383. package/src/elements/compare.tsx +7 -6
  384. package/src/elements/compiled.css +1 -1
  385. package/src/elements/composer.tsx +8 -8
  386. package/src/elements/confirm-card.tsx +9 -9
  387. package/src/elements/context-meter.tsx +4 -18
  388. package/src/elements/conversation-list.tsx +14 -9
  389. package/src/elements/default-input.tsx +131 -8
  390. package/src/elements/define.tsx +178 -43
  391. package/src/elements/editable-label.tsx +17 -2
  392. package/src/elements/element-data-types.ts +112 -0
  393. package/src/elements/element-meta.json +1624 -306
  394. package/src/elements/element-types.d.ts +2645 -214
  395. package/src/elements/feedback-bar.tsx +1 -1
  396. package/src/elements/file-tree.tsx +1 -1
  397. package/src/elements/file-upload.tsx +1 -1
  398. package/src/elements/form.tsx +14 -6
  399. package/src/elements/input.tsx +1 -1
  400. package/src/elements/kbd.tsx +1 -1
  401. package/src/elements/menu.tsx +40 -32
  402. package/src/elements/message-skills.tsx +7 -9
  403. package/src/elements/message.tsx +200 -32
  404. package/src/elements/model-switcher.tsx +5 -3
  405. package/src/elements/pane.tsx +1 -1
  406. package/src/elements/prompt-dock.tsx +8 -8
  407. package/src/elements/prompt-input.tsx +10 -10
  408. package/src/elements/prompt-suggestions.tsx +7 -4
  409. package/src/elements/reasoning.tsx +1 -1
  410. package/src/elements/register.ts +9 -0
  411. package/src/elements/resizable.globals.d.ts +36 -0
  412. package/src/elements/resizable.tsx +24 -13
  413. package/src/elements/response-stream.tsx +1 -1
  414. package/src/elements/scroll-button.tsx +1 -1
  415. package/src/elements/search.tsx +6 -1
  416. package/src/elements/segmented.tsx +5 -11
  417. package/src/elements/separator.tsx +1 -1
  418. package/src/elements/slot-text.ts +73 -0
  419. package/src/elements/slots.ts +67 -24
  420. package/src/elements/source.tsx +21 -22
  421. package/src/elements/switch.tsx +3 -3
  422. package/src/elements/tasks.tsx +5 -4
  423. package/src/elements/thread.tsx +36 -4
  424. package/src/elements/toast.tsx +3 -2
  425. package/src/elements/tool.tsx +1 -1
  426. package/src/elements/validate-messages.ts +76 -0
  427. package/src/elements/voice-input.tsx +7 -7
  428. package/src/elements/voice-output.tsx +4 -4
  429. package/src/index.ts +145 -6
  430. package/src/primitives/card-component-types.ts +63 -0
  431. package/src/primitives/card-data-types.ts +312 -0
  432. package/src/primitives/card-recovery.ts +13 -2
  433. package/src/primitives/card-registry.tsx +34 -23
  434. package/src/primitives/card-schemas/artifact.schema.json +92 -0
  435. package/src/primitives/card-schemas/embed.schema.json +0 -2
  436. package/src/primitives/card-schemas/link.schema.json +0 -2
  437. package/src/primitives/card-tags.ts +61 -0
  438. package/src/primitives/card-validate-cards.ts +255 -0
  439. package/src/primitives/card-validate-generator.testlib.ts +38 -0
  440. package/src/primitives/card-validate-schemas.ts +58 -0
  441. package/src/primitives/card-validate.ts +48 -20
  442. package/src/primitives/create-tween.ts +54 -2
  443. package/src/primitives/message-feedback.ts +3 -2
  444. package/src/primitives/use-audio-analysis.ts +20 -1
  445. package/src/primitives/use-sequencer.ts +20 -1
  446. package/src/schemas/from-tool-call.ts +151 -0
  447. package/src/schemas/index.ts +340 -0
  448. package/src/schemas/provider-subsets.ts +538 -0
  449. package/src/schemas/registry.ts +355 -0
  450. package/src/schemas/tool-defs.ts +492 -0
  451. package/src/solid.ts +150 -0
  452. package/src/state/index.ts +27 -1
  453. package/src/state/messages.ts +21 -4
  454. package/src/state/mock.ts +211 -0
  455. package/src/state/parts.ts +295 -0
  456. package/src/state/stream.ts +56 -58
  457. package/src/ui/collapsible.tsx +17 -5
  458. package/src/ui/dropdown.tsx +46 -12
  459. package/src/ui/overlay.tsx +10 -4
  460. package/src/wire/chunk.ts +201 -0
  461. package/src/wire/consume.ts +440 -0
  462. package/src/wire/encode.ts +689 -0
  463. package/src/wire/files.ts +342 -0
  464. package/src/wire/formats/anthropic.ts +267 -0
  465. package/src/wire/formats/openai.ts +187 -0
  466. package/src/wire/index.ts +73 -0
  467. package/src/wire/media-types.ts +344 -0
  468. package/src/wire/read.ts +152 -0
  469. package/src/wire/sink-helpers.ts +50 -0
  470. package/src/wire/sse.ts +140 -0
  471. package/dist/create-tween-hvpmSuwW.js +0 -7
  472. package/dist/elements/chunks/arrow-left-DQocUFvy.js +0 -1
  473. package/dist/elements/chunks/audio-visualizer-BqNy7dfm.js +0 -1
  474. package/dist/elements/chunks/card-BkHbp4BA.js +0 -1
  475. package/dist/elements/chunks/chat-thread-CkRN6pZ7.js +0 -1
  476. package/dist/elements/chunks/check-B9-gn6SS.js +0 -1
  477. package/dist/elements/chunks/chevron-down-BNsxc2hk.js +0 -1
  478. package/dist/elements/chunks/chevron-right-Hv00StBO.js +0 -1
  479. package/dist/elements/chunks/circle-0e3KJTDr.js +0 -1
  480. package/dist/elements/chunks/circle-check-BNAS0JEy.js +0 -1
  481. package/dist/elements/chunks/code-block-BFUHn6Va.js +0 -1
  482. package/dist/elements/chunks/context-Cb7k4F-v.js +0 -1
  483. package/dist/elements/chunks/conversation-list-CvoAkWhN.js +0 -1
  484. package/dist/elements/chunks/create-tween-oVvAIG8r.js +0 -7
  485. package/dist/elements/chunks/default-input-Cqqilg9t.js +0 -1
  486. package/dist/elements/chunks/define-D1din7Ld.js +0 -1
  487. package/dist/elements/chunks/hover-card-Cmm6Q53m.js +0 -1
  488. package/dist/elements/chunks/message-BqyXDN3-.js +0 -1
  489. package/dist/elements/chunks/message-feedback-Djr3z6Yb.js +0 -1
  490. package/dist/elements/chunks/message-square-vFAgbDaX.js +0 -1
  491. package/dist/elements/chunks/model-switcher-B94YAKsM.js +0 -1
  492. package/dist/elements/chunks/reasoning-DTpCGtnY.js +0 -1
  493. package/dist/elements/chunks/scroll-button-B0cH5fXf.js +0 -1
  494. package/dist/elements/chunks/skeleton-DSXW5Yya.js +0 -1
  495. package/dist/elements/chunks/slots--V19HwUb.js +0 -1
  496. package/dist/elements/chunks/textarea-CUwqAX0G.js +0 -1
  497. package/dist/elements/chunks/tooltip-CgBZCVKp.js +0 -1
  498. package/dist/elements/chunks/use-card-resolution-BSu_XHjH.js +0 -1
  499. package/dist/elements/chunks/x-GRUeeQFT.js +0 -1
  500. package/dist/host-embed.d.ts +0 -33
  501. package/dist/kai-provider.d.ts +0 -2
  502. package/dist/origin.d.ts +0 -5
  503. package/dist/provider-runtime.d.ts +0 -27
  504. package/dist/register-impl-DQyejdfb.js +0 -145
  505. package/dist/validate.d.ts +0 -4
  506. package/dist/version.d.ts +0 -4
  507. package/src/components/component-meta.json +0 -4550
  508. package/src/elements/card-media.jpg +0 -0
  509. package/src/elements/resizable.d.ts +0 -27
  510. package/src/elements/video-poster.jpg +0 -0
@@ -10,20 +10,26 @@
10
10
  import { createWebComponent, registerAll, type WebComponentProps } from './runtime';
11
11
  export { registerAll };
12
12
  export { useKaiChat } from './use-kai-chat';
13
- export type { UseKaiChatOptions, KaiChatController, ChatMessage } from './use-kai-chat';
13
+ export type { UseKaiChatOptions, KaiChatController } from './use-kai-chat';
14
+ // The content-model types, re-exported so a consumer can annotate a `parts`
15
+ // array or an `addSource` argument without reaching into the main entry.
16
+ export type {
17
+ ChatMessage, ChatMessageAction, CustomAction, AvatarData, FeedbackVote, MessagePart,
18
+ MessageSource, RawOrigin, ToolPart, ToolKind, CardEnvelope, AttachmentData,
19
+ } from './use-kai-chat';
14
20
  export { useVoiceInput } from './use-voice-input';
15
21
 
16
22
 
17
23
  export interface AgentCardProps extends WebComponentProps {
18
- /** The agent's name the primary label. Attribute: `name`. */
24
+ /** The agent's name, the primary label. Attribute: `name`. */
19
25
  name?: string;
20
26
  /** Selected / focused state: highlighted border + surface. Attribute: `active`. */
21
27
  active?: boolean;
22
- /** Raise a prominent "Needs you" pill plus a glowing amber edge the attention-routing signal that pulls focus to this agent. Attribute: `needs-attention`. */
28
+ /** Raise a prominent "Needs you" pill plus a glowing amber edge. This is the attention-routing signal that pulls focus to this agent. Attribute: `needs-attention`. */
23
29
  needsAttention?: boolean;
24
- /** Run status a JS PROPERTY (object), not an attribute. Shape: `{ tone, label?, pulse? }`, where `tone` is one of `working` | `idle` | `done` | `error` | `blocked` (maps to the kit's tool hues), `label` is an optional short string beside the dot, and `pulse` animates the dot. Set it with `el.status = { tone: 'working', label: 'Working', pulse: true }`. */
30
+ /** Run status. A JS PROPERTY (object), not an attribute. Shape: `{ tone, label?, pulse? }`, where `tone` is one of `working` | `idle` | `done` | `error` | `blocked` (maps to the kit's tool hues), `label` is an optional short string beside the dot, and `pulse` animates the dot. Set it with `el.status = { tone: 'working', label: 'Working', pulse: true }`. */
25
31
  status?: { tone: "working" | "idle" | "done" | "error" | "blocked"; label?: string; pulse?: boolean };
26
- /** The card was activated clicked, or Enter / Space while focused. Promote this agent back to focus. */
32
+ /** The card was activated by a click, or by Enter / Space while focused. Promote this agent back to focus. */
27
33
  onActivate?: (event: CustomEvent) => void;
28
34
  /** The trailing "..." kebab was clicked. The consumer opens its own menu; the card only surfaces the affordance (the click does not also activate the card). */
29
35
  onMenu?: (event: CustomEvent) => void;
@@ -39,13 +45,13 @@ export const AgentCard = /*#__PURE__*/ createWebComponent<AgentCardProps>(
39
45
  export interface ArtifactProps extends WebComponentProps {
40
46
  /** URL the preview iframe frames. Consumer-controlled. */
41
47
  src?: string;
42
- /** Files for the Code tab tree + each file's preview `url`. Set as a JS property (array). */
43
- files: { path: string; url?: undefined | string; code?: undefined | string; language?: undefined | string; type?: undefined | "html" | "pdf" | "image" | "other"; additions?: undefined | number; deletions?: undefined | number; status?: undefined | "added" | "modified" | "deleted" | "renamed" | "untracked" }[];
48
+ /** Files for the Code tab tree + each file's preview `url`. Omit for a preview-only artifact (the Code tab then has nothing to show; pair it with `no-tabs` to hide the toggle). Set as a JS property (array). */
49
+ files?: { path: string; url?: string; code?: string; language?: string; type?: "html" | "pdf" | "image" | "other"; additions?: number; deletions?: number; status?: "added" | "modified" | "deleted" | "renamed" | "untracked" }[];
44
50
  /** Controlled active tab: `preview` or `code`. When set, the artifact follows it (re-asserted on change). Leave unset for an uncontrolled tab (see `defaultTab`). */
45
51
  tab?: "preview" | "code";
46
52
  /** Uncontrolled INITIAL tab (used only when `tab` is unset). Default `preview`. Seeds the starting tab; the user can then switch freely without the consumer re-asserting a controlled `tab`. */
47
53
  defaultTab?: "preview" | "code";
48
- /** Selected file path syncs the tree highlight, Code source, and preview. */
54
+ /** Selected file path. Syncs the tree highlight, Code source, and preview. */
49
55
  activeFile?: string;
50
56
  /** iframe `sandbox` override. Secure default `allow-scripts allow-forms` (NOT `allow-same-origin`). */
51
57
  sandbox?: string;
@@ -77,6 +83,8 @@ export interface ArtifactProps extends WebComponentProps {
77
83
  onFileSelect?: (event: CustomEvent<{ path: string }>) => void;
78
84
  /** Artifact's own maximize button toggled (consumer-observable; non-bubbling). */
79
85
  onMaximizeChange?: (event: CustomEvent<{ maximized: boolean }>) => void;
86
+ /** The maximize PROTOCOL intent, raised as a raw bubbling + composed CustomEvent (not through `dispatch`) so an enclosing `<kai-resizable>` can catch it and maximize the containing panel. Declared here so it is typed and reaches the generated API. Listen for it to drive maximize from your own chrome, or re-emit it to trigger one. */
87
+ onMaximizeIntent?: (event: CustomEvent<{ requested: boolean }>) => void;
80
88
  /** Fired when the preview navigates. `detail.url` = the new location. */
81
89
  onNavigate?: (event: CustomEvent<{ url: string }>) => void;
82
90
  /** Fired when the Preview|Code tab changes. `detail.tab`. */
@@ -86,13 +94,13 @@ export interface ArtifactProps extends WebComponentProps {
86
94
  export const Artifact = /*#__PURE__*/ createWebComponent<ArtifactProps>(
87
95
  'kai-artifact',
88
96
  ["theme","src","files","tab","defaultTab","activeFile","sandbox","iframeTitle","maximized","expandable","openInTab","noNav","noReload","noHome","noPathField","noTabs","standalone","readonlyPath","displayUrl"],
89
- { onFileSelect: 'kai-file-select', onMaximizeChange: 'kai-maximize-change', onNavigate: 'kai-navigate', onTabChange: 'kai-tab-change' },
97
+ { onFileSelect: 'kai-file-select', onMaximizeChange: 'kai-maximize-change', onMaximizeIntent: 'kai-maximize-intent', onNavigate: 'kai-navigate', onTabChange: 'kai-tab-change' },
90
98
  () => import('@kitn.ai/ui/elements/artifact'),
91
99
  );
92
100
 
93
101
  export interface AttachmentsProps extends WebComponentProps {
94
- /** The attachments to render. Set as a JS property (array). */
95
- items: { id: string; type: "file" | "source-document"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }[];
102
+ /** The attachments to render. Omit (or pass an empty array) for the empty state, which shows `emptyText` if set and nothing otherwise. Set as a JS property (array). */
103
+ items?: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }[];
96
104
  /** Layout: `grid` = visual tiles, `inline` = icon + label chips, `list` = rows. */
97
105
  variant?: "grid" | "inline" | "list";
98
106
  /** Wrap each item in a hover card that previews its details. */
@@ -161,7 +169,7 @@ export interface AvatarProps extends WebComponentProps {
161
169
  src?: string;
162
170
  /** Alt text for the image. Defaults to `fallback`. */
163
171
  alt?: string;
164
- /** Short text shown when there's no image usually initials (e.g. "JD", "AI"). */
172
+ /** Short text shown when there's no image, usually initials (e.g. "JD", "AI"). */
165
173
  fallback?: string;
166
174
  /** Size token: `sm` | `md` (default) | `lg`. */
167
175
  size?: "sm" | "md" | "lg";
@@ -187,7 +195,7 @@ export const Badge = /*#__PURE__*/ createWebComponent<BadgeProps>(
187
195
  );
188
196
 
189
197
  export interface ButtonProps extends WebComponentProps {
190
- /** Visual style. `default` (filled), `subtle` (muted text, hover tint the toolbar icon look), `ghost` (transparent, hover fill), `outline`, or `destructive`. Defaults to `default`. */
198
+ /** Visual style. `default` (filled), `subtle` (muted text, hover tint, the toolbar icon look), `ghost` (transparent, hover fill), `outline`, or `destructive`. Defaults to `default`. */
191
199
  variant?: "default" | "subtle" | "ghost" | "outline" | "destructive";
192
200
  /** Size token. `icon` / `icon-sm` are square (for icon-only buttons); `sm` / `md` / `lg` size text buttons. Defaults to `md`. */
193
201
  size?: "sm" | "md" | "lg" | "icon" | "icon-sm";
@@ -195,11 +203,11 @@ export interface ButtonProps extends WebComponentProps {
195
203
  icon?: string;
196
204
  /** Trailing icon, after the label (e.g. `"chevron-down"` for a menu affordance). */
197
205
  iconTrailing?: string;
198
- /** Accessible name. REQUIRED for icon-only buttons (no visible text); ignored when you slot visible text, which already names the button. */
206
+ /** Accessible name. REQUIRED for icon-only buttons (no visible text); ignored when you slot visible text, which already names the button. An `aria-label` on top of visible text REPLACES that name rather than adding to it, so a button reading "Save" that answers to "Submit" is unusable by speech input (WCAG 2.5.3, Label in Name). The visible text wins. An `icon` / `icon-sm` size hides the slot, which makes the button icon-only whatever you slotted, so `label` is what names it there. */
199
207
  label?: string;
200
208
  /** Disable the button (non-interactive, dimmed). */
201
209
  disabled?: boolean;
202
- /** Stretch the button to the full width of its container (a block button) e.g. a card CTA or a stacked action. Attribute: `full`. */
210
+ /** Stretch the button to the full width of its container (a block button), e.g. a card CTA or a stacked action. Attribute: `full`. */
203
211
  full?: boolean;
204
212
  /** Justify the button's content: `start`, `center` (default), or `end`. Combine with `full` for a full-width, left-aligned button. */
205
213
  align?: "start" | "center" | "end";
@@ -219,7 +227,7 @@ export const Button = /*#__PURE__*/ createWebComponent<ButtonProps>(
219
227
  export interface CardProps extends WebComponentProps {
220
228
  /** Surface treatment: `outlined` (default) | `filled` | `plain` | `accent`. Attribute: `appearance`. */
221
229
  appearance?: "outlined" | "filled" | "plain" | "accent";
222
- /** `vertical` (default, media on top) | `horizontal` (media at the start) | `responsive` (horizontal when the card's container is wide enough, else vertical a container query on the card's own width). Attribute: `orientation`. */
230
+ /** `vertical` (default, media on top) | `horizontal` (media at the start) | `responsive` (horizontal when the card's container is wide enough, else vertical, via a container query on the card's own width). Attribute: `orientation`. */
223
231
  orientation?: "vertical" | "horizontal" | "responsive";
224
232
  /** The card width below which a `responsive` card collapses to vertical and the footer actions stack. A CSS length; default `28rem`. Attribute: `collapse`. */
225
233
  collapse?: string;
@@ -253,29 +261,33 @@ export interface CardsProps extends WebComponentProps {
253
261
  cards?: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }[];
254
262
  /** Optional type→tag overrides/additions (merged over the built-ins). Property: `el.types`. Typed as a plain string map (not the `CardTagMap` alias) so the generated React wrapper inlines it instead of emitting an unresolved named type. */
255
263
  types?: Record<string, string>;
264
+ /** JSON Schemas for the card types this app renders, keyed by envelope type. The companion of `types`, which says what DRAWS a card while this says what a VALID one looks like. An OBJECT, so it is a JS property only: `el.schemas = { 'pricing-table': pricingSchema }`, never an attribute. `createCardRegistry(...).validationSchemas` is exactly this shape. Without it the kit validates its own seven built-ins and leaves your own card type, the one your app actually cares about, as the only unchecked thing on screen. A schema here WINS over a built-in of the same name, matching `mergeCardTags`, where your entry is spread over ours. Typed `Record<string, object>` rather than `Record<string, JsonSchema>` deliberately: an imported `.json` schema widens `"type"` to `string`, and an authored one carries `$schema`/`title`/`description`/`additionalProperties`, so the tighter type would reject both of the normal ways to supply one. See `CardSchemaMap` in components/card-renderer.tsx. */
265
+ schemas?: Record<string, object>;
256
266
  /** Optional CardPolicy handling child events. Property: `el.policy`. */
257
267
  policy?: { onSubmit?: (cardId: string, data: unknown) => void; onAction?: (cardId: string, action: string, payload?: unknown) => void; onSendPrompt?: (text: string, opts: { mode: "compose" | "send"; context?: unknown; }) => void; onOpen?: (url: string, target: "tab" | "artifact") => void; onState?: (cardId: string, patch: unknown) => void; onDismiss?: (cardId: string) => void; onReopen?: (cardId: string) => void; onError?: (cardId: string, message: string) => void; maxSendPromptMode?: "compose" | "send" };
258
- /** A child card transitioned to a resolved/deferred state (an action was chosen, a form/tasks submission landed, or it was dismissed) re-emitted off the host as a non-bubbling convenience event so a consumer can observe resolution centrally without diffing the cards array. `detail` = `{ cardId, resolution }`. (A `reopen` un-resolves a card and has no `CardResolution`, so it does NOT fire this observe reopen via the underlying bubbling `kai-card` event.) */
268
+ /** Validate each envelope's `data` against the schema for its type before rendering it, using a built-in's own schema or yours from `schemas`. Default `true`; set `validate-cards="false"` (or `el.validateCards = false`) to opt out. A hard failure (wrong type, a missing required field) renders a diagnostic naming the field instead of the card; a soft failure (bounds) renders the card unchanged. Both emit a contract `error` event. On in production too: a model emitting a bad shape is a production failure mode, so stripping the check there would hide it from exactly the person who needs to see it. */
269
+ validateCards?: boolean;
270
+ /** A child card transitioned to a resolved/deferred state (an action was chosen, a form/tasks submission landed, or it was dismissed). Re-emitted off the host as a non-bubbling convenience event so a consumer can observe resolution centrally without diffing the cards array. `detail` = `{ cardId, resolution }`. (A `reopen` un-resolves a card and has no `CardResolution`, so it does NOT fire this; observe reopen via the underlying bubbling `kai-card` event.) */
259
271
  onCardResolved?: (event: CustomEvent<{ cardId: string; resolution: { kind: "action"; action: string; payload?: unknown; at?: undefined | string } | { kind: "submit"; data: unknown; at?: undefined | string } | { kind: "dismissed"; at?: undefined | string } | { kind: "expired"; reason?: undefined | string; at?: undefined | string } }>) => void;
260
272
  }
261
273
 
262
274
  export const Cards = /*#__PURE__*/ createWebComponent<CardsProps>(
263
275
  'kai-cards',
264
- ["theme","cards","types","policy"],
276
+ ["theme","cards","types","schemas","policy","validateCards"],
265
277
  { onCardResolved: 'kai-card-resolved' },
266
278
  () => import('@kitn.ai/ui/elements/cards'),
267
279
  );
268
280
 
269
281
  export interface ChainOfThoughtProps extends WebComponentProps {
270
- /** The reasoning steps. Set as a JS property. Compound sub-parts collapse to this one data model (Route 1). Each `{ label, content?, id? }`. */
271
- steps: { label: string; content?: undefined | string; id?: undefined | string }[];
272
- /** Open mode: `'multiple'` (default any number of steps open at once) or `'single'` (at most one open; opening a step closes the others). */
282
+ /** The reasoning steps. Set as a JS property. Compound sub-parts collapse to this one data model (Route 1). Each `{ label, content?, id? }`. Omit to supply the steps as `<kai-step>` light-DOM children instead; when both are present the property's steps come first. */
283
+ steps?: { label: string; content?: string; id?: string }[];
284
+ /** Open mode: `'multiple'` (default, any number of steps open at once) or `'single'` (at most one open; opening a step closes the others). */
273
285
  type?: "single" | "multiple";
274
286
  /** Controlled open step key(s). When set, it WINS over user interaction (the consumer owns the open set). String in `single` mode, string[] in `multiple` mode. Set as a JS property. */
275
287
  value?: string | string[];
276
- /** Uncontrolled INITIAL open step key(s) seeds which steps render expanded. Ignored once `value` is provided. Set as a JS property. */
288
+ /** Uncontrolled INITIAL open step key(s), seeding which steps render expanded. Ignored once `value` is provided. Set as a JS property. */
277
289
  defaultValue?: string | string[];
278
- /** The open set changed by user click OR an expand()/collapse()/toggle() call. `value` is a string in `single` mode, a string[] in `multiple` mode. (Maps Radix Accordion's onValueChange.) */
290
+ /** The open set changed, by user click OR an expand()/collapse()/toggle() call. `value` is a string in `single` mode, a string[] in `multiple` mode. (Maps Radix Accordion's onValueChange.) */
279
291
  onValueChange?: (event: CustomEvent<{ value: string | string[] }>) => void;
280
292
  }
281
293
 
@@ -287,8 +299,8 @@ export const ChainOfThought = /*#__PURE__*/ createWebComponent<ChainOfThoughtPro
287
299
  );
288
300
 
289
301
  export interface ChatProps extends WebComponentProps {
290
- /** The full message thread to render, newest last. Each entry carries its role, content, and optional reasoning/tools/attachments/actions. Set as a JS property (`el.messages = [...]`). */
291
- messages: { id: string; role: "user" | "assistant"; content: string; reasoning?: undefined | { text: string; label?: undefined | string }; tools?: undefined | { type: string; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: undefined | Record<string, unknown>; output?: undefined | Record<string, unknown>; toolCallId?: undefined | string; errorText?: undefined | string }[]; attachments?: undefined | { id: string; type: "file" | "source-document"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }[]; actions?: undefined | ("copy" | "like" | "dislike" | "regenerate" | "edit" | { id: string; label: string; icon?: undefined | string; tooltip?: undefined | string })[]; avatar?: undefined | { src?: undefined | string; fallback?: undefined | string; alt?: undefined | string }; feedback?: undefined | "like" | "dislike" }[];
302
+ /** Show a Search (Globe) button in the input toolbar; fires a `search` event. */
303
+ search?: boolean;
292
304
  /** Value of the input. A **string** is controlled (the host owns the text and updates it on `kai-value-change`). A **ComposerDoc** is a one-time seed that pre-populates pills; the user then edits freely. Leave unset for uncontrolled. */
293
305
  value?: string | ({ type: "text"; text: string } | { type: "entity"; entity: { kind: string; id: string; label: string; icon?: string; promptText?: string; data?: Record<string, unknown> } })[];
294
306
  /** Placeholder text shown in the empty input. */
@@ -302,7 +314,7 @@ export interface ChatProps extends WebComponentProps {
302
314
  /** Keep suggestions visible after the conversation starts. By default suggestions are conversation starters and hide once `messages` is non-empty; set this to keep them always shown. Default false. */
303
315
  persistSuggestions?: boolean;
304
316
  /** Body/prose font scale for rendered markdown (`'xs' | 'sm' | 'base' | 'lg'`). Defaults to `'sm'`. */
305
- proseSize?: "sm" | "lg" | "xs" | "base";
317
+ proseSize?: "xs" | "sm" | "base" | "lg";
306
318
  /** Shiki theme name for syntax-highlighted code blocks (e.g. `'github-dark-dimmed'`). */
307
319
  codeTheme?: string;
308
320
  /** Enable Shiki syntax highlighting in code blocks. Turn off to render plain `<pre>` blocks (lighter, no highlighter load). Default true. */
@@ -317,34 +329,42 @@ export interface ChatProps extends WebComponentProps {
317
329
  context?: { usedTokens: number; maxTokens: number; inputTokens?: number; outputTokens?: number; estimatedCost?: number };
318
330
  /** Show the scroll-to-bottom button inside the scroll area. Default true. */
319
331
  scrollButton?: boolean;
320
- /** Whether the host has `slot="header-start"` content (left of the title) set by the `<kai-chat>` facade so a custom control forces the header open. */
332
+ /** Whether the host has `slot="header-start"` content (left of the title). Set by the `<kai-chat>` facade so a custom control forces the header open. */
321
333
  headerStart?: boolean;
322
334
  /** Whether the host has `slot="header-end"` content (right of the controls). */
323
335
  headerEnd?: boolean;
324
- /** REPLACE full custom header in place of the built-in title/model/context bar. */
336
+ /** REPLACE: full custom header in place of the built-in title/model/context bar. */
325
337
  headerFull?: boolean;
326
- /** INJECT left sidebar column (e.g. a conversation list / your own nav). */
338
+ /** INJECT: left sidebar column (e.g. a conversation list / your own nav). */
327
339
  sidebar?: boolean;
328
- /** REPLACE custom zero-state rendered in the message area while the thread is empty (replaces the empty message list only; the composer and its suggestions still render). */
340
+ /** REPLACE: custom zero-state rendered in the message area while the thread is empty (replaces the empty message list only; the composer and its suggestions still render). */
329
341
  empty?: boolean;
330
- /** REPLACE full custom composer in place of the built-in prompt input. The projected content wires its own submit (the data-flow boundary). */
342
+ /** REPLACE: full custom composer in place of the built-in prompt input. The projected content wires its own submit (the data-flow boundary). */
331
343
  composer?: boolean;
332
- /** INJECT accessory row just above the composer (e.g. extra actions). */
344
+ /** INJECT: accessory row just above the composer (e.g. extra actions). */
333
345
  composerActions?: boolean;
334
- /** INJECT footer row below the composer (disclaimers, token meter, …). */
346
+ /** INJECT: footer row below the composer (disclaimers, token meter, …). */
335
347
  footer?: boolean;
336
- /** Show a Search (Globe) button in the input toolbar; fires a `search` event. */
337
- search?: boolean;
338
348
  /** Show a Voice (Mic) button in the input toolbar; fires a `voice` event. */
339
349
  voice?: boolean;
340
- /** Rich entity triggers each `{ char, kind, items }` opens a caret-anchored menu that inserts an atomic pill (`/` skills, `@` agents/plugins). Set as a JS property; forwarded to the input. */
350
+ /** Rich entity triggers. Each `{ char, kind, items }` opens a caret-anchored menu that inserts an atomic pill (`/` skills, `@` agents/plugins). Set as a JS property; forwarded to the input. */
341
351
  triggers?: { char: string; kind: string; items?: { id: string; label: string; icon?: string; description?: string; group?: string; kind?: string; promptText?: string; data?: Record<string, unknown> }[] }[];
342
352
  /** Default icon per entity kind (kind → image src) for pills/menu items. */
343
353
  kindIcons?: Record<string, string>;
344
354
  /** Whether each message's action bar is always visible (`'always'`, default) or only revealed on hover of that message row (`'hover'`). */
345
355
  actionsReveal?: "always" | "hover";
356
+ /** Which attachment media types the user may stage, in HTML `accept` syntax: `<kai-chat accept="image/*,application/pdf">`. A plain string, so unlike `messages` it DOES work as an attribute. Omitted means no filter. MEDIA TYPES ONLY -- exact (`image/png`) or subtype wildcard (`text/*`). HTML allows a file extension here and this does not: `accept=".py"` THROWS with the entry named, rather than silently resolving to a picker that accepts nothing. It can only NARROW what the kit can already encode: `accept="image/*"` resolves to the four image formats both APIs take, not to every image type the OS offers. Pass the SAME string to `toOpenAIMessages(msgs, { accept })` and the picker and the wire cannot disagree -- both resolve it through `resolveMediaPolicy` against one declaration. That declaration is readable as `encodableMediaTypes()` from `@kitn.ai/ui/wire`, if you would rather build your own picker than use this prop. */
357
+ accept?: string;
358
+ /** The full message thread to render, newest last. Each entry carries its role, ordered `parts`, and optional actions/avatar/feedback. Set as a JS property (`el.messages = [...]`); a NEW array reference per streaming chunk re-renders (mutating in place does not). Omit for an empty thread. Re-declared here (rather than inherited from `ChatThreadProps`) because the ELEMENT registers a `[]` default and renders the empty state without it, while the SolidJS `<ChatThread>` component still requires it. The facade hands it a validated array either way. Matches `<kai-thread>`. */
359
+ messages?: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "like" | "dislike" | "regenerate" | "edit" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" }[];
360
+ /** Optional card type -> custom-element tag overrides/additions for `card` parts (merged over the built-ins). Property: `el.cardTypes`. Typed as a plain string map (not the `CardTagMap` alias) so the generated React wrapper inlines it instead of emitting an unresolved named type. */
361
+ cardTypes?: Record<string, string>;
362
+ /** JSON Schemas for the card types this app renders, keyed by envelope type. The companion of `cardTypes`, which says what DRAWS a card while this says what a VALID one looks like. An OBJECT, so it is a JS property only: `el.cardSchemas = { 'pricing-table': pricingSchema }`, never an attribute. `createCardRegistry(...).validationSchemas` is exactly this shape. Without it the kit validates its own seven built-ins and leaves your own card type, the one your app actually cares about, as the only unchecked thing on screen. A schema here WINS over a built-in of the same name. Typed `Record<string, object>` rather than `Record<string, JsonSchema>` deliberately: an imported `.json` schema widens `"type"` to `string`, and an authored one carries `$schema`/`title`/`description`/`additionalProperties`, so the tighter type would reject both of the normal ways to supply one. */
363
+ cardSchemas?: Record<string, object>;
346
364
  /** The staged attachments changed (file added or removed). Carries the full current list so a consumer can react in real time. */
347
365
  onAttachmentsChange?: (event: CustomEvent<{ attachments: { id: string; type: "file" | "source-document"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }[] }>) => void;
366
+ /** One or more picked files were refused because `accept` excluded them. The element renders NO message of its own: it reports the facts (name, media type, whether the kit could have sent it) and what the user should see is the application's call. Only ever fires when `accept` is set. */
367
+ onAttachmentsRejected?: (event: CustomEvent<{ rejected: { filename: string; mediaType: string; reason: "filtered" | "unsupported" }[] }>) => void;
348
368
  /** An action button on a message was clicked. `action` is the built-in name or custom id. `state` is present only for the toggleable feedback votes: `'on'` when a like/dislike is set, `'off'` when re-tapped to clear. */
349
369
  onMessageAction?: (event: CustomEvent<{ messageId: string; action: string; state?: undefined | "on" | "off" }>) => void;
350
370
  /** The header model switcher changed. */
@@ -363,8 +383,8 @@ export interface ChatProps extends WebComponentProps {
363
383
 
364
384
  export const Chat = /*#__PURE__*/ createWebComponent<ChatProps>(
365
385
  'kai-chat',
366
- ["theme","messages","value","placeholder","loading","suggestions","suggestionMode","persistSuggestions","proseSize","codeTheme","codeHighlight","chatTitle","models","currentModel","context","scrollButton","headerStart","headerEnd","headerFull","sidebar","empty","composer","composerActions","footer","search","voice","triggers","kindIcons","actionsReveal"],
367
- { onAttachmentsChange: 'kai-attachments-change', onMessageAction: 'kai-message-action', onModelChange: 'kai-model-change', onSearch: 'kai-search', onSubmit: 'kai-submit', onSuggestionClick: 'kai-suggestion-click', onValueChange: 'kai-value-change', onVoice: 'kai-voice' },
386
+ ["theme","search","value","placeholder","loading","suggestions","suggestionMode","persistSuggestions","proseSize","codeTheme","codeHighlight","chatTitle","models","currentModel","context","scrollButton","headerStart","headerEnd","headerFull","sidebar","empty","composer","composerActions","footer","voice","triggers","kindIcons","actionsReveal","accept","messages","cardTypes","cardSchemas"],
387
+ { onAttachmentsChange: 'kai-attachments-change', onAttachmentsRejected: 'kai-attachments-rejected', onMessageAction: 'kai-message-action', onModelChange: 'kai-model-change', onSearch: 'kai-search', onSubmit: 'kai-submit', onSuggestionClick: 'kai-suggestion-click', onValueChange: 'kai-value-change', onVoice: 'kai-voice' },
368
388
  () => import('@kitn.ai/ui/elements/chat'),
369
389
  );
370
390
 
@@ -374,7 +394,7 @@ export interface CheckpointProps extends WebComponentProps {
374
394
  /** Tooltip on hover. */
375
395
  tooltip?: string;
376
396
  /** Visual button style. */
377
- variant?: "default" | "ghost" | "outline";
397
+ variant?: "ghost" | "default" | "outline";
378
398
  /** Button size (use an `icon*` size for an icon-only checkpoint). */
379
399
  size?: "sm" | "md" | "lg" | "icon" | "icon-sm";
380
400
  /** The checkpoint was clicked. */
@@ -390,14 +410,14 @@ export const Checkpoint = /*#__PURE__*/ createWebComponent<CheckpointProps>(
390
410
 
391
411
  export interface ChoiceProps extends WebComponentProps {
392
412
  /** The choice definition (the CardEnvelope.data). Set as a JS PROPERTY: `el.data = { prompt, options:[…], allowOther?, submitLabel? }`. Import `ChoiceCardData` from `@kitn.ai/ui` for the full shape. */
393
- data?: Record<string, unknown>;
413
+ data?: { prompt?: string; options: { id: string; label: string; description?: string; media?: { image?: string; imageAlt?: string; icon?: string }; meta?: string; recommended?: boolean; disabled?: boolean; payload?: unknown }[]; allowOther?: boolean | { label?: string; placeholder?: string }; submitLabel?: string; dismissible?: boolean };
394
414
  /** Stable card id correlating every emitted CardEvent. Attribute: `card-id`. */
395
415
  cardId?: string;
396
416
  /** Heading rendered in the card chrome (= CardEnvelope.title). Attribute: `heading`. */
397
417
  heading?: string;
398
418
  /** Set when the user resolved this card; renders the read-only view. Property: `el.resolution = { kind:'action', action:'…' }`. */
399
419
  resolution?: Record<string, unknown>;
400
- /** Controlled selection the selected option id. When set, the consumer owns the current pick (RadioGroup `value`). Attribute: `value`. */
420
+ /** Controlled selection: the selected option id. When set, the consumer owns the current pick (RadioGroup `value`). Attribute: `value`. */
401
421
  value?: string;
402
422
  /** Option id to pre-select on mount (uncontrolled seed). Attribute: `default-value`. */
403
423
  defaultValue?: string;
@@ -425,8 +445,8 @@ export interface CoachmarkProps extends WebComponentProps {
425
445
  badge?: string;
426
446
  /** Floating placement relative to the anchor (default `bottom`). */
427
447
  placement?: string;
428
- /** Color tone: `primary` (default, theme accent), `info` (blue), `success` (green), `warning` (amber), or `error` (red) reusing the kit's tool hues. */
429
- tone?: "error" | "primary" | "info" | "success" | "warning";
448
+ /** Color tone: `primary` (default, theme accent), `info` (blue), `success` (green), `warning` (amber), or `error` (red), reusing the kit's tool hues. */
449
+ tone?: "primary" | "info" | "success" | "warning" | "error";
430
450
  /** Render the arrow that points at the anchor (default `true`). Set `arrow="false"` for a plain bubble with no pointer. */
431
451
  arrow?: boolean;
432
452
  /** The × dismiss button was pressed. The consumer records that this hint was seen so it won't show again. */
@@ -452,7 +472,7 @@ export interface CodeBlockProps extends WebComponentProps {
452
472
  /** Disable syntax highlighting (renders plain text, no Shiki). */
453
473
  codeHighlight?: boolean;
454
474
  /** Code text sizing. */
455
- proseSize?: "sm" | "lg" | "xs" | "base";
475
+ proseSize?: "xs" | "sm" | "base" | "lg";
456
476
  }
457
477
 
458
478
  export const CodeBlock = /*#__PURE__*/ createWebComponent<CodeBlockProps>(
@@ -463,14 +483,14 @@ export const CodeBlock = /*#__PURE__*/ createWebComponent<CodeBlockProps>(
463
483
  );
464
484
 
465
485
  export interface CommandProps extends WebComponentProps {
466
- /** Flat list of items. Set as a JS property not an HTML attribute. */
486
+ /** Flat list of items. Set as a JS property, not an HTML attribute. */
467
487
  items?: { id: string; label: string; icon?: string; description?: string; shortcut?: string; group?: string }[];
468
488
  /** Placeholder text for the search input. */
469
489
  placeholder?: string;
470
490
  /** Label shown when no items match the current query. */
471
491
  emptyLabel?: string;
472
- /** Fired when the highlighted/active item changes via Arrow keys or when filtering re-clamps the active row. `id` is the newly active item's id, or `undefined` when no item is active (e.g. the filtered list is empty). Lets a host preview the active item without committing a selection. */
473
- onActiveChange?: (event: CustomEvent<{ id: undefined | string }>) => void;
492
+ /** Fired when the highlighted/active item changes, via Arrow keys or when filtering re-clamps the active row. `id` is the newly active item's id, or `undefined` when no item is active (e.g. the filtered list is empty). Lets a host preview the active item without committing a selection. */
493
+ onActiveChange?: (event: CustomEvent<{ id: string | undefined }>) => void;
474
494
  /** Fired on every keystroke in the search input. */
475
495
  onQueryChange?: (event: CustomEvent<{ value: string }>) => void;
476
496
  /** Fired when the user selects an item (click or Enter). */
@@ -491,10 +511,10 @@ export interface CompareProps extends WebComponentProps {
491
511
  compareId?: string;
492
512
  /** Re-hydrate / control the user's pick. Set as a JS PROPERTY: `el.selection = { chosenId, rejectedIds }`. Renders the collapsed winner. */
493
513
  selection?: Record<string, unknown>;
494
- /** Layout: `'auto'` (default columns when wide, tabs when narrow, by CONTAINER width) | `'columns'` (side-by-side) | `'tabs'` (pills to switch). Attribute: `layout`. */
514
+ /** Layout: `'auto'` (default, columns when wide, tabs when narrow, by CONTAINER width) | `'columns'` (side-by-side) | `'tabs'` (pills to switch). Attribute: `layout`. */
495
515
  layout?: "auto" | "columns" | "tabs";
496
516
  /** Prose/text size for the rendered candidates. Attribute: `prose-size`. */
497
- proseSize?: "sm" | "lg" | "xs" | "base";
517
+ proseSize?: "xs" | "sm" | "base" | "lg";
498
518
  /** Shiki theme for code blocks in the candidates. Attribute: `code-theme`. */
499
519
  codeTheme?: string;
500
520
  /** Whether code blocks are syntax-highlighted. Attribute: `code-highlight`. */
@@ -515,7 +535,7 @@ export const Compare = /*#__PURE__*/ createWebComponent<CompareProps>(
515
535
  );
516
536
 
517
537
  export interface ComposerProps extends WebComponentProps {
518
- /** Controlled value string or a full ComposerDoc (set as JS property). */
538
+ /** Controlled value: a string or a full ComposerDoc (set as JS property). */
519
539
  value?: string | ({ type: "text"; text: string } | { type: "entity"; entity: { kind: string; id: string; label: string; icon?: string; promptText?: string; data?: Record<string, unknown> } })[];
520
540
  /** Placeholder text shown when the composer is empty. */
521
541
  placeholder?: string;
@@ -524,12 +544,12 @@ export interface ComposerProps extends WebComponentProps {
524
544
  /** Show a loading/streaming state and block submit. */
525
545
  loading?: boolean;
526
546
  /** Maximum height in px before the content scrolls. Default 240. */
527
- maxHeight?: string | number;
547
+ maxHeight?: number | string;
528
548
  /** Whether pressing Enter (without Shift) submits. Default true. */
529
549
  submitOnEnter?: boolean;
530
- /** Trigger definitions set as a JS property. */
550
+ /** Trigger definitions. Set as a JS property. */
531
551
  triggers?: { char: string; kind: string; items?: { id: string; label: string; icon?: string; description?: string; group?: string; kind?: string; promptText?: string; data?: Record<string, unknown> }[] }[];
532
- /** Keyword highlight rules set as a JS property. */
552
+ /** Keyword highlight rules. Set as a JS property. */
533
553
  highlights?: (string | { pattern: string; flags?: string; class?: string })[];
534
554
  /** Default icon per entity kind (kind → image URL/data-URI) for items without their own `icon`. Overrides the built-in agent/plugin glyphs. JS property. */
535
555
  kindIcons?: Record<string, string>;
@@ -539,7 +559,7 @@ export interface ComposerProps extends WebComponentProps {
539
559
  onEntityAdd?: (event: CustomEvent<{ entity: { kind: string; id: string; label: string; icon?: undefined | string; promptText?: undefined | string; data?: undefined | Record<string, unknown> } }>) => void;
540
560
  /** An entity pill was deleted from the composer. */
541
561
  onEntityRemove?: (event: CustomEvent<{ entity: { kind: string; id: string; label: string; icon?: undefined | string; promptText?: undefined | string; data?: undefined | Record<string, unknown> } }>) => void;
542
- /** The composer gained focus. `focus`/`blur` are NOT composed natively, so they don't escape the shadow root these re-expose them on the host. (For `keydown`/`paste`/`focusin`/`focusout`, listen NATIVELY on `<kai-composer>`: they're composed and already cross the shadow boundary.) */
562
+ /** The composer gained focus. `focus`/`blur` are NOT composed natively, so they don't escape the shadow root; these re-expose them on the host. (For `keydown`/`paste`/`focusin`/`focusout`, listen NATIVELY on `<kai-composer>`: they're composed and already cross the shadow boundary.) */
543
563
  onFocus?: (event: CustomEvent<{ originalEvent: FocusEvent }>) => void;
544
564
  /** The user submitted the composer (Enter or programmatic submit). */
545
565
  onSubmit?: (event: CustomEvent<{ doc: ({ type: "text"; text: string } | { type: "entity"; entity: { kind: string; id: string; label: string; icon?: undefined | string; promptText?: undefined | string; data?: undefined | Record<string, unknown> } })[]; text: string; entities: { kind: string; id: string; label: string; icon?: undefined | string; promptText?: undefined | string; data?: undefined | Record<string, unknown> }[] }>) => void;
@@ -560,12 +580,12 @@ export const Composer = /*#__PURE__*/ createWebComponent<ComposerProps>(
560
580
 
561
581
  export interface ConfirmProps extends WebComponentProps {
562
582
  /** The confirm definition (the CardEnvelope.data). Set as a JS PROPERTY: `el.data = { body, tone, actions:[…] }`. Import `ConfirmCardData` from `@kitn.ai/ui` for the full shape. */
563
- data?: Record<string, unknown>;
583
+ data?: { heading?: string; body?: string; tone?: "default" | "warning" | "danger"; actions: { id: string; label: string; style?: "primary" | "default" | "destructive"; payload?: unknown; default?: boolean }[]; dismissible?: boolean };
564
584
  /** Stable card id correlating every emitted CardEvent. Attribute: `card-id`. */
565
585
  cardId?: string;
566
586
  /** Heading rendered in the card chrome (= CardEnvelope.title). Attribute: `heading`. */
567
587
  heading?: string;
568
- /** Focus the default action on mount (off by default no focus-stealing). Attribute: `autofocus`. */
588
+ /** Focus the default action on mount (off by default, so nothing steals focus). Attribute: `autofocus`. */
569
589
  autofocus?: boolean;
570
590
  /** Set when the user resolved this card; renders the read-only view. Property: `el.resolution = { kind:'action', action:'…' }`. */
571
591
  resolution?: Record<string, unknown>;
@@ -597,10 +617,10 @@ export const Context = /*#__PURE__*/ createWebComponent<ContextProps>(
597
617
  );
598
618
 
599
619
  export interface ConversationsProps extends WebComponentProps {
600
- /** Pre-bucketed conversation groups (e.g. "Today", "Yesterday"), each with its own conversations. Use this when you want to control the grouping/headers yourself; otherwise pass a flat `conversations` array. Set as a JS property. */
601
- groups: { id: string; userId?: undefined | string; teamId?: undefined | string; name: string; sortOrder: number; createdAt: string }[];
602
- /** A flat list of conversation summaries; the component buckets them by recency for you. Ignored when `groups` is provided. Set as a JS property. */
603
- conversations: { id: string; title: string; groupId?: undefined | string; scope: { type: "document" | "collection"; documentId?: undefined | string; filters?: undefined | { tags?: undefined | string[]; authors?: undefined | string[]; contentType?: undefined | "transcript" | "markdown"; dateRange?: undefined | { from: string; to: string } } }; messageCount: number; lastMessageAt: string; updatedAt: string; trailing?: undefined | string }[];
620
+ /** The list's section headers (`{ id, name, sortOrder, createdAt }`), rendered in array order. A group carries no conversations of its own; it is matched against `conversations` by id, so the two props are complementary rather than alternatives. Omit for an ungrouped list. Set as a JS property. */
621
+ groups?: { id: string; userId?: string; teamId?: string; name: string; sortOrder: number; createdAt: string }[];
622
+ /** Every conversation the list renders, flat. Each one is filed under the group whose `id` equals its `groupId`; one with no `groupId`, or with a `groupId` matching no entry in `groups`, falls into a trailing "Ungrouped" section, so nothing you pass in is ever dropped. There is no recency bucketing. Set as a JS property. Omit to supply them as `<kai-conversation>` light-DOM children instead, or for the empty state. */
623
+ conversations?: { id: string; title: string; groupId?: string; scope: { type: "document" | "collection"; documentId?: string; filters?: { tags?: string[]; authors?: string[]; contentType?: "transcript" | "markdown"; dateRange?: { from: string; to: string } } }; messageCount: number; lastMessageAt: string; updatedAt: string; trailing?: string }[];
604
624
  /** The id of the currently-open conversation, highlighted in the list. */
605
625
  activeId?: string;
606
626
  /** Controlled collapsed state. Set as a JS property (`el.collapsed = true`) to drive the rail from your app, updating it in response to `kai-collapse-toggle`. Omit for uncontrolled (the element manages it). Collapsed shrinks the rail to a floating reopen button. */
@@ -643,7 +663,7 @@ export const Dialog = /*#__PURE__*/ createWebComponent<DialogProps>(
643
663
  );
644
664
 
645
665
  export interface EditableLabelProps extends WebComponentProps {
646
- /** The label text settable and reflected to the `value` attribute. Read `el.value` for live state. */
666
+ /** The label text. Settable and reflected to the `value` attribute. Read `el.value` for live state. */
647
667
  value?: string;
648
668
  /** Controlled edit state. `el.editing = true` opens the field; reflected to the `editing` attribute. */
649
669
  editing?: boolean;
@@ -693,7 +713,7 @@ export const Empty = /*#__PURE__*/ createWebComponent<EmptyProps>(
693
713
  );
694
714
 
695
715
  export interface FeedbackBarProps extends WebComponentProps {
696
- /** The banner label (e.g. "Was this helpful?"). Attribute: `bar-title` (`title` is avoided it's a global HTML attribute). */
716
+ /** The banner label (e.g. "Was this helpful?"). Attribute: `bar-title` (`title` is avoided because it is a global HTML attribute). */
697
717
  barTitle?: string;
698
718
  /** When set, a not-helpful vote opens an optional detail form before the thank-you confirmation. Attribute: `collect-detail`. */
699
719
  collectDetail?: boolean;
@@ -725,7 +745,7 @@ export const FeedbackBar = /*#__PURE__*/ createWebComponent<FeedbackBarProps>(
725
745
  export interface FileTreeProps extends WebComponentProps {
726
746
  /** The files to render. Set as a JS property (array of `{ path, url?, code?, language?, type?, additions?, deletions?, status? }`). */
727
747
  files: { path: string; url?: undefined | string; code?: undefined | string; language?: undefined | string; type?: undefined | "html" | "pdf" | "image" | "other"; additions?: undefined | number; deletions?: undefined | number; status?: undefined | "added" | "modified" | "deleted" | "renamed" | "untracked" }[];
728
- /** Selected file path highlighted in the tree. */
748
+ /** Selected file path, highlighted in the tree. */
729
749
  activeFile?: string;
730
750
  /** Folder paths expanded initially. Omit to start with all folders open. */
731
751
  defaultExpanded?: string[];
@@ -747,7 +767,7 @@ export interface FileUploadProps extends WebComponentProps {
747
767
  multiple?: boolean;
748
768
  /** `accept` attribute for the file picker (e.g. `image/*`). */
749
769
  accept?: string;
750
- /** Disable the dropzone no clicking, no drag-and-drop. */
770
+ /** Disable the dropzone: no clicking, no drag-and-drop. */
751
771
  disabled?: boolean;
752
772
  /** Default dropzone label (overridable via the default slot). */
753
773
  label?: string;
@@ -763,8 +783,8 @@ export const FileUpload = /*#__PURE__*/ createWebComponent<FileUploadProps>(
763
783
  );
764
784
 
765
785
  export interface FormProps extends WebComponentProps {
766
- /** The form definition a JSON Schema (`type:'object'`) + `x-kai-*` UI hints (the CardEnvelope.data). Set as a JS PROPERTY: `el.data = { type:'object', properties:{…} }`. Import the `FormDefinition` type from `@kitn.ai/ui` for the full shape (it is self-referential, so the element types it loosely). */
767
- data?: Record<string, unknown>;
786
+ /** The form definition: a JSON Schema (`type:'object'`) + `x-kai-*` UI hints (the CardEnvelope.data). Set as a JS PROPERTY: `el.data = { type:'object', properties:{…} }`. Import the `FormDefinition` type from `@kitn.ai/ui` for the full shape. It IS self-referential (`FormField.properties` is another `FormField` map), and the generated `element-types.d.ts` inlines every named type, so the shipped declaration bottoms out in a `Record<string, unknown>` placeholder one level down rather than carrying the recursion. That is why `FormDefinition` is a `type` alias: an interface gets no implicit index signature, so it would not be assignable to that placeholder. */
787
+ data?: { type: "object"; title?: string; description?: string; required?: string[]; properties: Record<string, { type: "string" | "number" | "integer" | "boolean" | "array" | "object"; title?: string; description?: string; default?: unknown; enum?: unknown[]; format?: "email" | "uri" | "url" | "date" | "date-time" | "time"; minimum?: number; maximum?: number; minLength?: number; maxLength?: number; pattern?: string; minItems?: number; maxItems?: number; items?: Record<string, unknown> | { enum: unknown[] }; properties?: Record<string, Record<string, unknown>>; required?: string[]; readOnly?: boolean; "x-kai-widget"?: "textarea" | "slider" | "rating" | "radio" | "select" | "checkbox" | "password" | "switch"; "x-kai-placeholder"?: string; "x-kai-step"?: number }>; "x-kai-order"?: string[]; "x-kai-inlineMax"?: number; "x-kai-submitLabel"?: string; "x-kai-dismissible"?: boolean; "x-kai-actions"?: { id: string; label: string; variant?: "default" | "ghost" | "outline" }[] };
768
788
  /** Stable card id correlating every emitted CardEvent. Attribute: `card-id`. */
769
789
  cardId?: string;
770
790
  /** Heading rendered in the card chrome (= CardEnvelope.title). Attribute: `heading`. */
@@ -777,7 +797,7 @@ export interface FormProps extends WebComponentProps {
777
797
  defaultValues?: Record<string, unknown>;
778
798
  /** Disable all fields + submit. Attribute: `disabled`. */
779
799
  disabled?: boolean;
780
- /** The form's values changed on input current coerced values + validity. */
800
+ /** The form's values changed on input. Carries the current coerced values + validity. */
781
801
  onValuesChange?: (event: CustomEvent<{ values: Record<string, unknown>; valid: boolean }>) => void;
782
802
  }
783
803
 
@@ -847,7 +867,7 @@ export const Image = /*#__PURE__*/ createWebComponent<ImageProps>(
847
867
  export interface InputProps extends WebComponentProps {
848
868
  /** Native input type: `text` (default) · `email` · `url` · `search` · `tel` · `password` · `number`. Single-line only. */
849
869
  type?: string;
850
- /** Controlled value settable and reflected to the `value` attribute. `el.value = 'hi'` drives it (no event); typing updates it and fires `kai-input`. Read `el.value` for live state. */
870
+ /** Controlled value. Settable and reflected to the `value` attribute. `el.value = 'hi'` drives it (no event); typing updates it and fires `kai-input`. Read `el.value` for live state. */
851
871
  value?: string;
852
872
  /** Placeholder shown when empty. */
853
873
  placeholder?: string;
@@ -887,10 +907,10 @@ export const Input = /*#__PURE__*/ createWebComponent<InputProps>(
887
907
  );
888
908
 
889
909
  export interface KbdProps extends WebComponentProps {
890
- /** Shortcut spec tokens joined by `+` (e.g. `Mod+Shift+K`). Omit it to show default-slot content instead. Display only; the element does not bind keys. */
910
+ /** Shortcut spec: tokens joined by `+` (e.g. `Mod+Shift+K`). Omit it to show default-slot content instead. Display only; the element does not bind keys. */
891
911
  keys?: string;
892
912
  /** `mac` uses ⌘/⌥, `other` uses Ctrl. `auto` (default) sniffs the OS. */
893
- platform?: "other" | "auto" | "mac";
913
+ platform?: "auto" | "mac" | "other";
894
914
  /** Cap size: `sm` or `md`. Defaults to `md`. */
895
915
  size?: "sm" | "md";
896
916
  }
@@ -936,7 +956,7 @@ export interface MarkdownProps extends WebComponentProps {
936
956
  /** The markdown source to render. */
937
957
  content: string;
938
958
  /** Text/markdown sizing. */
939
- proseSize?: "sm" | "lg" | "xs" | "base";
959
+ proseSize?: "xs" | "sm" | "base" | "lg";
940
960
  /** Shiki theme for fenced code blocks. */
941
961
  codeTheme?: string;
942
962
  /** Disable syntax highlighting (no Shiki loads). */
@@ -951,27 +971,27 @@ export const Markdown = /*#__PURE__*/ createWebComponent<MarkdownProps>(
951
971
  );
952
972
 
953
973
  export interface MenuProps extends WebComponentProps {
954
- /** Tree of menu items. Set as a JS property not an HTML attribute. */
974
+ /** Tree of menu items. Set as a JS property, not an HTML attribute. */
955
975
  items?: { id?: string; label?: string; icon?: string; shortcut?: string; checked?: boolean; radioGroup?: string; disabled?: boolean; separator?: boolean; heading?: boolean; items?: Record<string, unknown>[] }[];
956
976
  /** Optional placement hint (unused by the underlying Dropdown which always positions bottom-start, kept for future extension). */
957
977
  placement?: string;
958
- /** Built-in trigger: leading icon (a named icon like `"plus"`, an image URL/data-URI, or text). Use this instead of slotting `slot="trigger"` for the common case a slotted trigger overrides it. */
978
+ /** Built-in trigger: leading icon (a named icon like `"plus"`, an image URL/data-URI, or text). Use this instead of slotting `slot="trigger"` for the common case; a slotted trigger overrides it. */
959
979
  triggerIcon?: string;
960
- /** Built-in trigger: a text label (e.g. `"High"`). */
980
+ /** Built-in trigger: a text label (e.g. `"High"`). This is the trigger's VISIBLE text, so it is also its accessible name, and `label` does not override it: an accessible name that does not contain the visible text is unreachable by speech input, which is what WCAG 2.5.3 (Label in Name) exists for. A slotted `slot="trigger"` replaces this built-in trigger entirely and is named differently; see `label`. */
961
981
  triggerLabel?: string;
962
982
  /** Built-in trigger: a trailing icon (e.g. `"chevron-down"` for a select look). */
963
983
  triggerIconTrailing?: string;
964
- /** Accessible name for an icon-only trigger (no visible label). */
984
+ /** Accessible name for a trigger with no visible label. Ignored when `triggerLabel` is set, which is already the visible name. It DOES name a slotted `slot="trigger"`, and that is a difference in what the two slots MEAN, not a limitation. `<kai-button>`'s slot IS the button's label, so text slotted there is the name and `label` steps aside. This slot is VISUAL content, a `+` or an `<svg>`, with the name supplied separately: decoration beside a name, never a second name competing with one. So `label` names the trigger here by design. Slotting a real WORD rather than a glyph makes that word a visible label, and an accessible name has to contain the visible text. Then either drop `label` or make it contain the word you slotted. */
965
985
  label?: string;
966
986
  /** Drive/observe open state (Shoelace-style: settable + reflected to the `open` attribute, the menu still self-manages on click/keyboard). Set `el.open = true`, or `<kai-menu open>`; listen for `kai-open-change`. */
967
987
  open?: boolean;
968
988
  /** Initial open state on mount (uncontrolled seed). */
969
989
  defaultOpen?: boolean;
970
- /** Disable the trigger click/keyboard and `show()` no longer open the menu. */
990
+ /** Disable the trigger: click/keyboard and `show()` no longer open the menu. */
971
991
  disabled?: boolean;
972
992
  /** The menu opened or closed (by click, keyboard, Escape, outside-click, or a method). */
973
993
  onOpenChange?: (event: CustomEvent<{ open: boolean }>) => void;
974
- /** Fired when the user selects a leaf item. - Plain items: `{ id }`. - Checkbox items: `{ id, checked }` where `checked` is the NEW state. - Radio items: `{ id, radioGroup }` the consumer marks `id` as the selected one in `radioGroup` and clears the others. */
994
+ /** Fired when the user selects a leaf item. - Plain items: `{ id }`. - Checkbox items: `{ id, checked }` where `checked` is the NEW state. - Radio items: `{ id, radioGroup }`, where the consumer marks `id` as the selected one in `radioGroup` and clears the others. */
975
995
  onSelect?: (event: CustomEvent<{ id: string; checked?: undefined | boolean; radioGroup?: undefined | string }>) => void;
976
996
  }
977
997
 
@@ -984,15 +1004,13 @@ export const Menu = /*#__PURE__*/ createWebComponent<MenuProps>(
984
1004
 
985
1005
  export interface MessageProps extends WebComponentProps {
986
1006
  /** The full message object. Set as a JS property. */
987
- message?: { id: string; role: "user" | "assistant"; content: string; reasoning?: { text: string; label?: string }; tools?: { type: string; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; output?: Record<string, unknown>; toolCallId?: string; errorText?: string }[]; attachments?: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }[]; actions?: ("copy" | "like" | "dislike" | "regenerate" | "edit" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" };
988
- /** Convenience for simple cases when not passing a `message` object. */
1007
+ message?: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "like" | "dislike" | "regenerate" | "edit" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" };
1008
+ /** Who is speaking: `'user'` or `'assistant'`. Convenience for simple cases when not passing a `message` object. This is the SEMANTIC role of the message, not an ARIA role. The name collides with the global ARIA `role` attribute, which is why the facade lifts it off the host (see `liftRoleOffHost`). Neither speaker is a valid ARIA role, so a `role="user"` left on `<kai-message>` is a CRITICAL axe `aria-roles` violation. The accessible role lives on the row inside the shadow root instead: `role="article"` plus an `aria-label` naming the speaker, matching the SolidJS `<Message>` component. */
989
1009
  role?: "user" | "assistant";
990
- /** Convenience content (used when `message` is not set). */
991
- content?: string;
992
1010
  /** Force markdown on/off. Defaults to on for assistant, off for user. */
993
1011
  markdown?: boolean;
994
1012
  /** Text/markdown sizing for the message body. */
995
- proseSize?: "sm" | "lg" | "xs" | "base";
1013
+ proseSize?: "xs" | "sm" | "base" | "lg";
996
1014
  /** Shiki theme name used for fenced code blocks in the content. */
997
1015
  codeTheme?: string;
998
1016
  /** Disable syntax highlighting for code blocks (no Shiki loads). */
@@ -1005,27 +1023,31 @@ export interface MessageProps extends WebComponentProps {
1005
1023
  avatarFallback?: string;
1006
1024
  /** Avatar rail mode. `'none'` omits the avatar rail entirely so the body spans the full row (predictable layout when you never show avatars). Any other value keeps the default behaviour: the built-in avatar when one resolves, or your `slot="avatar"` content when projected (which REPLACES the built-in). */
1007
1025
  avatar?: string;
1026
+ /** Optional card type -> custom-element tag overrides/additions for `card` parts (merged over the built-ins). Property: `el.cardTypes`. Typed as a plain string map (not the `CardTagMap` alias) so the generated React wrapper inlines it instead of emitting an unresolved named type. */
1027
+ cardTypes?: Record<string, string>;
1028
+ /** JSON Schemas for the card types this app renders, keyed by envelope type. The companion of `cardTypes`, which says what DRAWS a card while this says what a VALID one looks like. An OBJECT, so it is a JS property only: `el.cardSchemas = { 'pricing-table': pricingSchema }`, never an attribute. `createCardRegistry(...).validationSchemas` is exactly this shape. Without it the kit validates its own seven built-ins and leaves your own card type, the one your app actually cares about, as the only unchecked thing on screen. A schema here WINS over a built-in of the same name. Typed `Record<string, object>` rather than `Record<string, JsonSchema>` deliberately: an imported `.json` schema widens `"type"` to `string`, and an authored one carries `$schema`/`title`/`description`/`additionalProperties`, so the tighter type would reject both of the normal ways to supply one. */
1029
+ cardSchemas?: Record<string, object>;
1008
1030
  /** An action button was clicked. `action` is the built-in name or custom id. `state` is present only for the toggleable feedback votes: `'on'` when a like/dislike is set, `'off'` when re-tapped to clear. */
1009
1031
  onMessageAction?: (event: CustomEvent<{ messageId: string; action: string; state?: undefined | "on" | "off" }>) => void;
1010
1032
  }
1011
1033
 
1012
1034
  export const Message = /*#__PURE__*/ createWebComponent<MessageProps>(
1013
1035
  'kai-message',
1014
- ["theme","message","role","content","markdown","proseSize","codeTheme","codeHighlight","actionsReveal","avatarSrc","avatarFallback","avatar"],
1036
+ ["theme","message","role","markdown","proseSize","codeTheme","codeHighlight","actionsReveal","avatarSrc","avatarFallback","avatar","cardTypes","cardSchemas"],
1015
1037
  { onMessageAction: 'kai-message-action' },
1016
1038
  () => import('@kitn.ai/ui/elements/message'),
1017
1039
  );
1018
1040
 
1019
1041
  export interface ModelSwitcherProps extends WebComponentProps {
1020
- /** The selectable models. Set as a JS property (array). */
1021
- models: { id: string; name: string; provider?: undefined | string; description?: undefined | string; group?: undefined | string }[];
1042
+ /** The selectable models. Set as a JS property (array). Omit to supply them as `<kai-model>` light-DOM children instead; when both are present the property's models come first. */
1043
+ models?: { id: string; name: string; provider?: string; description?: string; group?: string }[];
1022
1044
  /** The currently-selected model id. Defaults to the first model. */
1023
1045
  currentModel?: string;
1024
1046
  /** Drive/observe the dropdown's open state (Shoelace-style: settable + reflected to the `open` attribute, the dropdown still self-manages on click/keyboard). Set `el.open = true`, or `<kai-model-switcher open>`; listen for `kai-open-change`. */
1025
1047
  open?: boolean;
1026
1048
  /** Initial open state on mount (uncontrolled seed). */
1027
1049
  defaultOpen?: boolean;
1028
- /** Disable the trigger click/keyboard and `show()` no longer open the dropdown. */
1050
+ /** Disable the trigger: click/keyboard and `show()` no longer open the dropdown. */
1029
1051
  disabled?: boolean;
1030
1052
  /** A model was selected. */
1031
1053
  onModelChange?: (event: CustomEvent<{ modelId: string }>) => void;
@@ -1042,7 +1064,7 @@ export const ModelSwitcher = /*#__PURE__*/ createWebComponent<ModelSwitcherProps
1042
1064
 
1043
1065
  export interface NavProps extends WebComponentProps {
1044
1066
  /** The nav items. Set as a JS property (array, not an attribute). Each item may carry `children` (a collapsible group), a `status` dot, and trailing `meta` text. */
1045
- items?: { id: string; label?: string; icon?: string; badge?: string; trailing?: string; disabled?: boolean; children?: Record<string, unknown>[]; status?: { tone: "error" | "primary" | "info" | "success" | "warning" | "neutral"; label?: string; pulse?: boolean }; meta?: string; action?: { icon: string; label: string }; closable?: boolean }[];
1067
+ items?: { id: string; label?: string; icon?: string; badge?: string; trailing?: string; disabled?: boolean; children?: Record<string, unknown>[]; status?: { tone: "primary" | "info" | "success" | "warning" | "error" | "neutral"; label?: string; pulse?: boolean }; meta?: string; action?: { icon: string; label: string }; closable?: boolean }[];
1046
1068
  /** Active item id (controlled). */
1047
1069
  value?: string;
1048
1070
  /** Initial active id when uncontrolled. */
@@ -1066,7 +1088,7 @@ export const Nav = /*#__PURE__*/ createWebComponent<NavProps>(
1066
1088
 
1067
1089
  export interface NoticeProps extends WebComponentProps {
1068
1090
  /** `neutral` (default) · `info` · `warning` · `error` · `success`. Drives the leading icon's color and the a11y role (`alert` for errors, else `status`). */
1069
- severity?: "error" | "info" | "success" | "warning" | "neutral";
1091
+ severity?: "neutral" | "info" | "warning" | "error" | "success";
1070
1092
  /** Leading icon: omit for the severity default, `"none"` to hide it, or a named icon to override. */
1071
1093
  icon?: string;
1072
1094
  /** Show a dismiss (×) that hides the notice and emits `kai-dismiss`. */
@@ -1101,7 +1123,7 @@ export interface PaneProps extends WebComponentProps {
1101
1123
  onClose?: (event: CustomEvent) => void;
1102
1124
  /** The dock control was clicked (only present when `show-dock`). */
1103
1125
  onDock?: (event: CustomEvent) => void;
1104
- /** The maximize/restore control was clicked. `detail.maximized` is the intended NEXT state drive the `maximized` prop yourself from it. */
1126
+ /** The maximize/restore control was clicked. `detail.maximized` is the intended NEXT state. Drive the `maximized` prop yourself from it. */
1105
1127
  onMaximize?: (event: CustomEvent<{ maximized: boolean }>) => void;
1106
1128
  /** The split control was clicked (only present when `show-split`). */
1107
1129
  onSplit?: (event: CustomEvent) => void;
@@ -1138,7 +1160,7 @@ export const PaneGroup = /*#__PURE__*/ createWebComponent<PaneGroupProps>(
1138
1160
 
1139
1161
  export interface PopoverProps extends WebComponentProps {
1140
1162
  /** Floating placement relative to the trigger (floating-ui placement). */
1141
- placement?: "top" | "right" | "bottom" | "left" | "top-start" | "top-end" | "right-start" | "right-end" | "bottom-start" | "bottom-end" | "left-start" | "left-end";
1163
+ placement?: "top" | "right" | "bottom" | "left" | "bottom-end" | "bottom-start" | "left-end" | "left-start" | "right-end" | "right-start" | "top-end" | "top-start";
1142
1164
  /** Gap in px between the trigger and the panel. */
1143
1165
  gutter?: number;
1144
1166
  /** Drive/observe open state (Shoelace-style: settable + reflected to the `open` attribute, the element still self-manages on click). Set `el.open = true`, or `<kai-popover open>`; listen for `kai-open-change`. */
@@ -1177,10 +1199,10 @@ export const ProgressBar = /*#__PURE__*/ createWebComponent<ProgressBarProps>(
1177
1199
  );
1178
1200
 
1179
1201
  export interface PromptDockProps extends WebComponentProps {
1180
- /** How the tray frames the input the SPATIAL inset axis: `inset` (default, the classic recessed frame on every side) | `edge` (top/bottom inset only; the input sits flush left/right so the lips span the full width) | `none` (no inset; the lips attach directly as a plain stack). Attribute: `frame`. */
1181
- frame?: "none" | "inset" | "edge";
1182
- /** How the tray surface looks the VISUAL axis, orthogonal to `frame`: `soft` (default, sunken surface + border + radius) | `outlined` (transparent + border + radius) | `filled` (sunken, no border, + radius) | `plain` (bare). Attribute: `appearance`. */
1183
- appearance?: "outlined" | "filled" | "plain" | "soft";
1202
+ /** How the tray frames the input, the SPATIAL inset axis: `inset` (default, the classic recessed frame on every side) | `edge` (top/bottom inset only; the input sits flush left/right so the lips span the full width) | `none` (no inset; the lips attach directly as a plain stack). Attribute: `frame`. */
1203
+ frame?: "inset" | "edge" | "none";
1204
+ /** How the tray surface looks, the VISUAL axis orthogonal to `frame`: `soft` (default, sunken surface + border + radius) | `outlined` (transparent + border + radius) | `filled` (sunken, no border, + radius) | `plain` (bare). Attribute: `appearance`. */
1205
+ appearance?: "soft" | "outlined" | "filled" | "plain";
1184
1206
  }
1185
1207
 
1186
1208
  export const PromptDock = /*#__PURE__*/ createWebComponent<PromptDockProps>(
@@ -1209,17 +1231,17 @@ export interface PromptInputProps extends WebComponentProps {
1209
1231
  voice?: boolean;
1210
1232
  /** When set and `loading` is true, the send button is replaced by a Stop button (square icon, "Stop" aria-label). Clicking it fires `kai-stop`. */
1211
1233
  stoppable?: boolean;
1212
- /** Send-button visibility. `'always'` (default) always shows it; `'auto'` shows it only when there's text/attachments (an empty composer hides it Enter still submits). To hide it entirely (Enter-only), it's pure CSS: `::part(send){display:none}` no prop needed. Restyle via `::part(send)`. The Stop button (`stoppable` + `loading`) is unaffected. */
1234
+ /** Send-button visibility. `'always'` (default) always shows it; `'auto'` shows it only when there's text/attachments (an empty composer hides it, though Enter still submits). To hide it entirely (Enter-only), it's pure CSS: `::part(send){display:none}`, no prop needed. Restyle via `::part(send)`. The Stop button (`stoppable` + `loading`) is unaffected. */
1213
1235
  submit?: "always" | "auto";
1214
1236
  /** When `false`, hides the built-in paperclip attach button even though the element otherwise supports attachments. Use this when a `+` menu in `toolbar-start` already exposes "Add files", to avoid a duplicate control. Defaults to `true`. */
1215
1237
  attach?: boolean;
1216
1238
  /** Attachments to seed the input with (so a consumer can pre-populate staged files without an upload). Set as a JS property; the element then manages its own attachment state from there (add via the paperclip, remove per chip). */
1217
1239
  attachments?: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }[];
1218
- /** Rich entity triggers each `{ char, kind, items }` opens a caret-anchored menu that inserts an atomic pill. Convention: `/` → skills, `@` → agents (plugins are the grouping/provenance of those items). Set as a JS property. */
1240
+ /** Rich entity triggers. Each `{ char, kind, items }` opens a caret-anchored menu that inserts an atomic pill. Convention: `/` → skills, `@` → agents (plugins are the grouping/provenance of those items). Set as a JS property. */
1219
1241
  triggers?: { char: string; kind: string; items?: { id: string; label: string; icon?: string; description?: string; group?: string; kind?: string; promptText?: string; data?: Record<string, unknown> }[] }[];
1220
1242
  /** Default icon per entity kind (kind → image URL/data-URI) for pills/menu items without their own `icon`. Overrides the built-in agent/plugin glyphs. JS property. */
1221
1243
  kindIcons?: Record<string, string>;
1222
- /** The staged attachments changed a file was added (via the paperclip) or removed (per-chip ×). Carries the full current list so a consumer can react in real time (validate, show upload progress, toggle the send button). */
1244
+ /** The staged attachments changed: a file was added (via the paperclip) or removed (per-chip ×). Carries the full current list so a consumer can react in real time (validate, show upload progress, toggle the send button). */
1223
1245
  onAttachmentsChange?: (event: CustomEvent<{ attachments: { id: string; type: "file" | "source-document"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }[] }>) => void;
1224
1246
  /** The Search (Globe) toolbar button was clicked. */
1225
1247
  onSearch?: (event: CustomEvent<Record<string, never>>) => void;
@@ -1257,7 +1279,7 @@ export interface ReasoningProps extends WebComponentProps {
1257
1279
  streaming?: boolean;
1258
1280
  /** Render `text` as markdown. */
1259
1281
  markdown?: boolean;
1260
- /** Gate the disclosure trigger programmatic `show()/hide()/toggle()` still work, but the trigger click no longer toggles. */
1282
+ /** Gate the disclosure trigger: programmatic `show()/hide()/toggle()` still work, but the trigger click no longer toggles. */
1261
1283
  disabled?: boolean;
1262
1284
  /** The reasoning block expanded or collapsed (via the trigger, streaming auto-open, or a method). */
1263
1285
  onOpenChange?: (event: CustomEvent<{ open: boolean }>) => void;
@@ -1290,21 +1312,23 @@ export const Remote = /*#__PURE__*/ createWebComponent<RemoteProps>(
1290
1312
 
1291
1313
  export interface ResizableProps extends WebComponentProps {
1292
1314
  /** Layout axis: `horizontal` (row, default) or `vertical` (column). */
1293
- orientation?: "vertical" | "horizontal";
1315
+ orientation?: "horizontal" | "vertical";
1294
1316
  /** Which item index is maximized (null = none). Declarative source of truth. */
1295
- maximizedIndex?: null | number;
1296
- /** Divider affordance drawn inside each draggable handle's 8px grab zone: - `line` (default) a 1px hairline, transparent at rest, tinting on hover/drag. - `grip` a dotted grip handle. - `none` no visible divider, just the invisible hit-area. The full grab zone and keyboard/ARIA behavior are identical for all three. */
1297
- handle?: "none" | "line" | "grip";
1317
+ maximizedIndex?: number | null;
1318
+ /** Divider affordance drawn inside each draggable handle's 8px grab zone: - `line` (default): a 1px hairline, transparent at rest, tinting on hover/drag. - `grip`: a dotted grip handle. - `none`: no visible divider, just the invisible hit-area. The full grab zone and keyboard/ARIA behavior are identical for all three. */
1319
+ handle?: "line" | "grip" | "none";
1298
1320
  /** Fired on drag-end / keyboard resize / visibility change. `detail.sizes` = panel sizes in percent. */
1299
1321
  onChange?: (event: CustomEvent<{ sizes: number[] }>) => void;
1300
1322
  /** Observe layout maximize state. */
1301
- onMaximizeChange?: (event: CustomEvent<{ maximized: boolean; index: null | number }>) => void;
1323
+ onMaximizeChange?: (event: CustomEvent<{ maximized: boolean; index: number | null }>) => void;
1324
+ /** Authoritative maximize state, dispatched as a raw composed CustomEvent (not through `dispatch`) onto the affected `<kai-resizable-item>` and, on restore, onto the group host. A nested element (e.g. `<kai-artifact>`) listens for it to reconcile its own toggle. */
1325
+ onMaximizeState?: (event: CustomEvent<{ maximized: boolean }>) => void;
1302
1326
  }
1303
1327
 
1304
1328
  export const Resizable = /*#__PURE__*/ createWebComponent<ResizableProps>(
1305
1329
  'kai-resizable',
1306
1330
  ["theme","orientation","maximizedIndex","handle"],
1307
- { onChange: 'kai-change', onMaximizeChange: 'kai-maximize-change' },
1331
+ { onChange: 'kai-change', onMaximizeChange: 'kai-maximize-change', onMaximizeState: 'kai-maximize-state' },
1308
1332
  () => import('@kitn.ai/ui/elements/resizable'),
1309
1333
  );
1310
1334
 
@@ -1319,21 +1343,22 @@ export interface ResizableItemProps extends WebComponentProps {
1319
1343
  locked?: boolean;
1320
1344
  /** Hide this panel; its divider is dropped and the rest reflow. */
1321
1345
  hidden?: boolean;
1322
- /** Collapse this panel same layout effect as `hidden` (divider dropped, the rest reflow), but it WORKS as a bare boolean from framework JSX. A plain `<kai-resizable-item collapsed>` in React/Solid/Vue/Svelte collapses the panel at the first render; `hidden` does not, because a JSX boolean sets neither the `hidden` attribute nor the IDL property on a custom element, so the parent never sees it. The facade reflects `collapsed` to a `collapsed` attribute the parent reads. Prefer this over `hidden` for declarative collapse. */
1346
+ /** Collapse this panel. Same layout effect as `hidden` (divider dropped, the rest reflow), but it WORKS as a bare boolean from framework JSX. A plain `<kai-resizable-item collapsed>` in React/Solid/Vue/Svelte collapses the panel at the first render; `hidden` does not, because a JSX boolean sets neither the `hidden` attribute nor the IDL property on a custom element, so the parent never sees it. The facade reflects `collapsed` to a `collapsed` attribute the parent reads. Prefer this over `hidden` for declarative collapse. */
1323
1347
  collapsed?: boolean;
1324
1348
  onChange?: (event: CustomEvent<unknown>) => void;
1325
1349
  onMaximizeChange?: (event: CustomEvent<unknown>) => void;
1350
+ onMaximizeState?: (event: CustomEvent<unknown>) => void;
1326
1351
  }
1327
1352
 
1328
1353
  export const ResizableItem = /*#__PURE__*/ createWebComponent<ResizableItemProps>(
1329
1354
  'kai-resizable-item',
1330
1355
  ["theme","size","min","max","locked","hidden","collapsed"],
1331
- { onChange: 'kai-change', onMaximizeChange: 'kai-maximize-change' },
1356
+ { onChange: 'kai-change', onMaximizeChange: 'kai-maximize-change', onMaximizeState: 'kai-maximize-state' },
1332
1357
  () => import('@kitn.ai/ui/elements/resizable'),
1333
1358
  );
1334
1359
 
1335
1360
  export interface ResponseStreamProps extends WebComponentProps {
1336
- /** Text to stream. A string, or an `AsyncIterable<string>` (set as a JS property async iterables can't be HTML attributes). */
1361
+ /** Text to stream. A string, or an `AsyncIterable<string>` (set as a JS property, since async iterables can't be HTML attributes). */
1337
1362
  text?: string | AsyncIterable<string>;
1338
1363
  /** Reveal animation. */
1339
1364
  mode?: "typewriter" | "fade";
@@ -1353,22 +1378,22 @@ export const ResponseStream = /*#__PURE__*/ createWebComponent<ResponseStreamPro
1353
1378
  );
1354
1379
 
1355
1380
  export interface ScopePickerProps extends WebComponentProps {
1356
- /** Authors to offer as scope filters. Set as a JS property. */
1357
- availableAuthors: string[];
1358
- /** Tags to offer as scope filters. Set as a JS property. */
1359
- availableTags: string[];
1381
+ /** Authors to offer as scope filters. Omit to drop the Authors section (for a tag-only picker). Set as a JS property. */
1382
+ availableAuthors?: string[];
1383
+ /** Tags to offer as scope filters. Omit to drop the Tags section (for an author-only picker). Set as a JS property. */
1384
+ availableTags?: string[];
1360
1385
  /** The label shown on the trigger for the active scope. */
1361
1386
  currentLabel?: string;
1362
1387
  /** Drive/observe the dropdown's open state (Shoelace-style: settable + reflected to the `open` attribute, the dropdown still self-manages on click/keyboard). Set `el.open = true`, or `<kai-scope-picker open>`; listen for `kai-open-change`. */
1363
1388
  open?: boolean;
1364
1389
  /** Initial open state on mount (uncontrolled seed). */
1365
1390
  defaultOpen?: boolean;
1366
- /** Disable the trigger click/keyboard and `show()` no longer open the dropdown. */
1391
+ /** Disable the trigger: click/keyboard and `show()` no longer open the dropdown. */
1367
1392
  disabled?: boolean;
1368
1393
  /** The scope dropdown opened or closed (by click, keyboard, Escape, outside-click, or a method). */
1369
1394
  onOpenChange?: (event: CustomEvent<{ open: boolean }>) => void;
1370
1395
  /** A scope was chosen (`undefined` filters = "All Content"). */
1371
- onScopeChange?: (event: CustomEvent<{ filters: undefined | { tags?: undefined | string[]; authors?: undefined | string[]; contentType?: undefined | "transcript" | "markdown"; dateRange?: undefined | { from: string; to: string } } }>) => void;
1396
+ onScopeChange?: (event: CustomEvent<{ filters: { tags?: undefined | string[]; authors?: undefined | string[]; contentType?: undefined | "transcript" | "markdown"; dateRange?: undefined | { from: string; to: string } } | undefined }>) => void;
1372
1397
  }
1373
1398
 
1374
1399
  export const ScopePicker = /*#__PURE__*/ createWebComponent<ScopePickerProps>(
@@ -1418,10 +1443,10 @@ export interface ScrollButtonProps extends WebComponentProps {
1418
1443
  /** CSS id of the scroll container to control. When omitted the element walks up the DOM (outside its own shadow root) to find the nearest scrollable ancestor. Mirrors the `for` convention of `<label for="...">`. */
1419
1444
  for?: string;
1420
1445
  /** Button visual variant: `'outline' | 'ghost' | 'default'`. Defaults to `'outline'`. */
1421
- variant?: "default" | "ghost" | "outline";
1446
+ variant?: "outline" | "ghost" | "default";
1422
1447
  /** Button size token. Defaults to `'icon'` (square). */
1423
1448
  size?: "sm" | "md" | "lg" | "icon" | "icon-sm";
1424
- /** Emitted when the user clicks the button and `scrollToBottom()` is called. Carries no detail consumers use it to know a manual scroll occurred. */
1449
+ /** Emitted when the user clicks the button and `scrollToBottom()` is called. Carries no detail; consumers use it to know a manual scroll occurred. */
1425
1450
  onScroll?: (event: CustomEvent) => void;
1426
1451
  }
1427
1452
 
@@ -1433,7 +1458,7 @@ export const ScrollButton = /*#__PURE__*/ createWebComponent<ScrollButtonProps>(
1433
1458
  );
1434
1459
 
1435
1460
  export interface SearchProps extends WebComponentProps {
1436
- /** Controlled query settable and reflected to the `value` attribute. Read `el.value` for live state. */
1461
+ /** Controlled query. Settable and reflected to the `value` attribute. Read `el.value` for live state. */
1437
1462
  value?: string;
1438
1463
  /** Placeholder. Defaults to `Search…`. */
1439
1464
  placeholder?: string;
@@ -1463,7 +1488,7 @@ export const Search = /*#__PURE__*/ createWebComponent<SearchProps>(
1463
1488
  export interface SegmentedProps extends WebComponentProps {
1464
1489
  /** The selectable segments, left to right. Set as a JS property (array). */
1465
1490
  options: { value: string; label: string; icon?: undefined | string }[];
1466
- /** Controlled selected `value` settable and reflected to the `value` attribute. `el.value = 'preview'` drives it; choosing a segment updates it and fires `kai-change`. Read `el.value` for live state. */
1491
+ /** Controlled selected `value`. Settable and reflected to the `value` attribute. `el.value = 'preview'` drives it; choosing a segment updates it and fires `kai-change`. Read `el.value` for live state. */
1467
1492
  value?: string;
1468
1493
  /** Control density: `sm` or `md`. Defaults to `md`. */
1469
1494
  size?: "sm" | "md";
@@ -1479,8 +1504,8 @@ export const Segmented = /*#__PURE__*/ createWebComponent<SegmentedProps>(
1479
1504
  );
1480
1505
 
1481
1506
  export interface SeparatorProps extends WebComponentProps {
1482
- /** `horizontal` (default, block + full-width) or `vertical` (a rule inside a flex/grid row it stretches to the row height). */
1483
- orientation?: "vertical" | "horizontal";
1507
+ /** `horizontal` (default, block + full-width) or `vertical` (a rule inside a flex/grid row, stretching to the row height). */
1508
+ orientation?: "horizontal" | "vertical";
1484
1509
  }
1485
1510
 
1486
1511
  export const Separator = /*#__PURE__*/ createWebComponent<SeparatorProps>(
@@ -1537,8 +1562,8 @@ export const Skeleton = /*#__PURE__*/ createWebComponent<SkeletonProps>(
1537
1562
  );
1538
1563
 
1539
1564
  export interface SkillsProps extends WebComponentProps {
1540
- /** The active skills to badge. Set as a JS property. */
1541
- skills: { id: string; name: string }[];
1565
+ /** The active skills to badge. Set as a JS property. Omit to supply them as `<kai-skill>` light-DOM children instead; when both are present the property's skills come first. Nothing renders when there are none. */
1566
+ skills?: { id: string; name: string }[];
1542
1567
  }
1543
1568
 
1544
1569
  export const Skills = /*#__PURE__*/ createWebComponent<SkillsProps>(
@@ -1553,7 +1578,7 @@ export interface SourceProps extends WebComponentProps {
1553
1578
  href?: string;
1554
1579
  /** Trigger label (defaults to the domain). */
1555
1580
  label?: string;
1556
- /** Hover-card headline. Attribute: `headline` (`title` is avoided it's a global HTML attribute that reflects in a CE constructor and breaks it). */
1581
+ /** Hover-card headline. Attribute: `headline` (`title` is avoided because it is a global HTML attribute that reflects in a CE constructor and breaks it). */
1557
1582
  headline?: string;
1558
1583
  /** Hover-card body text describing the source. */
1559
1584
  description?: string;
@@ -1569,11 +1594,11 @@ export const Source = /*#__PURE__*/ createWebComponent<SourceProps>(
1569
1594
  );
1570
1595
 
1571
1596
  export interface SourcesProps extends WebComponentProps {
1572
- /** The sources to render. Set as a JS property. */
1573
- sources: { href: string; title?: undefined | string; description?: undefined | string; label?: undefined | string; showFavicon?: undefined | boolean }[];
1597
+ /** The sources to render. Set as a JS property. Omit to supply them as `<kai-source>` light-DOM children instead; when both are present the property's sources come first. */
1598
+ sources?: { href: string; title?: string; description?: string; label?: string; showFavicon?: boolean }[];
1574
1599
  /** Show favicons on all items (per-item `showFavicon` overrides). */
1575
1600
  showFavicon?: boolean;
1576
- /** When true, each citation chip is labelled with its 1-based index in the merged (prop + declarative-children) list (`[1]`, `[2]`, …) instead of the per-item `label` or domain fallback. HTML attribute: `numbered` (boolean bare attribute or `numbered="true"`). JS property: `el.numbered = true`. */
1601
+ /** When true, each citation chip is labelled with its 1-based index in the merged (prop + declarative-children) list (`[1]`, `[2]`, …) instead of the per-item `label` or domain fallback. HTML attribute: `numbered` (boolean: a bare attribute or `numbered="true"`). JS property: `el.numbered = true`. */
1577
1602
  numbered?: boolean;
1578
1603
  }
1579
1604
 
@@ -1603,14 +1628,14 @@ export const Status = /*#__PURE__*/ createWebComponent<StatusProps>(
1603
1628
  );
1604
1629
 
1605
1630
  export interface SuggestionsProps extends WebComponentProps {
1606
- /** The suggestions. Strings, or `{ label, value }` when the displayed text and the emitted value differ. Set as a JS property. */
1607
- suggestions: (string | { label: string; value?: undefined | string; icon?: undefined | string })[];
1631
+ /** The suggestions. Strings, or `{ label, value }` when the displayed text and the emitted value differ. Set as a JS property. Omit to supply them as `<kai-suggestion>` light-DOM children instead; when both are present the property's suggestions come first. */
1632
+ suggestions?: (string | { label: string; value?: string; icon?: string })[];
1608
1633
  /** Chip style: `'outline'` (default), `'ghost'`, or `'default'` (filled). */
1609
- variant?: "default" | "ghost" | "outline";
1634
+ variant?: "outline" | "ghost" | "default";
1610
1635
  /** Row height for `layout="list"`: `'md'` (default) or `'lg'` for taller rows. Chips are unaffected. */
1611
1636
  size?: "md" | "lg";
1612
- /** Layout: `'chips'` (default) renders a wrapping row of rounded pills; `'list'` renders a vertical, full-width "Ideas for you" list each row is left-aligned with a leading `icon`, a label, and a hover background. */
1613
- layout?: "list" | "chips";
1637
+ /** Layout: `'chips'` (default) renders a wrapping row of rounded pills; `'list'` renders a vertical, full-width "Ideas for you" list where each row is left-aligned with a leading `icon`, a label, and a hover background. */
1638
+ layout?: "chips" | "list";
1614
1639
  /** Full-width left-aligned rows instead of pills. */
1615
1640
  block?: boolean;
1616
1641
  /** Substring to highlight within each suggestion. */
@@ -1627,7 +1652,7 @@ export const Suggestions = /*#__PURE__*/ createWebComponent<SuggestionsProps>(
1627
1652
  );
1628
1653
 
1629
1654
  export interface SwitchProps extends WebComponentProps {
1630
- /** Controlled checked state settable and reflected to the `checked` attribute. `el.checked = true` (or `<kai-switch checked>`) drives it; the toggle UI updates it and fires `kai-change`. Read `el.checked` for live state. */
1655
+ /** Controlled checked state. Settable and reflected to the `checked` attribute. `el.checked = true` (or `<kai-switch checked>`) drives it; the toggle UI updates it and fires `kai-change`. Read `el.checked` for live state. */
1631
1656
  checked?: boolean;
1632
1657
  /** Initial checked state on mount (uncontrolled seed). Bare attribute (`<kai-switch default-checked>`) turns it on. */
1633
1658
  defaultChecked?: boolean;
@@ -1676,7 +1701,7 @@ export const Tabs = /*#__PURE__*/ createWebComponent<TabsProps>(
1676
1701
 
1677
1702
  export interface TasksProps extends WebComponentProps {
1678
1703
  /** The tasks definition (the CardEnvelope.data). Set as a JS PROPERTY: `el.data = { tasks:[…], selectAll, confirmLabel, … }`. Import `TasksCardData` from `@kitn.ai/ui` for the full shape. */
1679
- data?: Record<string, unknown>;
1704
+ data?: { mode?: "select" | "progress"; heading?: string; tasks: { id: string; label: string; description?: string; checked?: boolean; disabled?: boolean }[]; selectAll?: boolean; confirmLabel?: string; allowEmpty?: boolean; min?: number; max?: number; dismissible?: boolean };
1680
1705
  /** Stable card id correlating every emitted CardEvent. Attribute: `card-id`. */
1681
1706
  cardId?: string;
1682
1707
  /** Heading rendered in the card chrome (= CardEnvelope.title). Attribute: `heading`. */
@@ -1691,7 +1716,7 @@ export interface TasksProps extends WebComponentProps {
1691
1716
  disabled?: boolean;
1692
1717
  /** Display-only: rows can't be toggled and show the default cursor (no pointer, hover, or focus affordances). Keeps the look as-is. Attribute: `readonly`. */
1693
1718
  readonly?: boolean;
1694
- /** The selection changed on a toggle the selected ids in input order. */
1719
+ /** The selection changed on a toggle. Carries the selected ids in input order. */
1695
1720
  onValueChange?: (event: CustomEvent<{ value: string[] }>) => void;
1696
1721
  }
1697
1722
 
@@ -1739,12 +1764,12 @@ export const ThinkingBar = /*#__PURE__*/ createWebComponent<ThinkingBarProps>(
1739
1764
  );
1740
1765
 
1741
1766
  export interface ThreadProps extends WebComponentProps {
1742
- /** The full message thread to render, newest last. Each entry carries its role, content, and optional reasoning/tools/attachments/actions/avatar. Set as a JS property (`el.messages = [...]`); a NEW array reference per streaming chunk re-renders (mutating in place does not). */
1743
- messages?: { id: string; role: "user" | "assistant"; content: string; reasoning?: { text: string; label?: string }; tools?: { type: string; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; output?: Record<string, unknown>; toolCallId?: string; errorText?: string }[]; attachments?: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }[]; actions?: ("copy" | "like" | "dislike" | "regenerate" | "edit" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" }[];
1744
- /** Show a typing indicator on the pending assistant turn set while awaiting the assistant's reply. */
1767
+ /** The full message thread to render, newest last. Each entry carries its role, ordered `parts`, and optional actions/avatar/feedback. Set as a JS property (`el.messages = [...]`); a NEW array reference per streaming chunk re-renders (mutating in place does not). */
1768
+ messages?: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "like" | "dislike" | "regenerate" | "edit" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" }[];
1769
+ /** Show a typing indicator on the pending assistant turn. Set it while awaiting the assistant's reply. */
1745
1770
  loading?: boolean;
1746
1771
  /** Body/prose font scale for rendered markdown (`'xs' | 'sm' | 'base' | 'lg'`). Defaults to `'sm'`. */
1747
- proseSize?: "sm" | "lg" | "xs" | "base";
1772
+ proseSize?: "xs" | "sm" | "base" | "lg";
1748
1773
  /** Shiki theme name for syntax-highlighted code blocks (e.g. `'github-dark-dimmed'`). */
1749
1774
  codeTheme?: string;
1750
1775
  /** Enable Shiki syntax highlighting in code blocks. Turn off to render plain `<pre>` blocks (lighter, no highlighter load). Default true. */
@@ -1755,20 +1780,24 @@ export interface ThreadProps extends WebComponentProps {
1755
1780
  scrollButton?: boolean;
1756
1781
  /** Extra classes applied to the thread's inner root. */
1757
1782
  class?: string;
1783
+ /** Optional card type -> custom-element tag overrides/additions for `card` parts (merged over the built-ins). Property: `el.cardTypes`. Typed as a plain string map (not the `CardTagMap` alias) so the generated React wrapper inlines it instead of emitting an unresolved named type. */
1784
+ cardTypes?: Record<string, string>;
1785
+ /** JSON Schemas for the card types this app renders, keyed by envelope type. The companion of `cardTypes`, which says what DRAWS a card while this says what a VALID one looks like. An OBJECT, so it is a JS property only: `el.cardSchemas = { 'pricing-table': pricingSchema }`, never an attribute. `createCardRegistry(...).validationSchemas` is exactly this shape. Without it the kit validates its own seven built-ins and leaves your own card type, the one your app actually cares about, as the only unchecked thing on screen. A schema here WINS over a built-in of the same name. Typed `Record<string, object>` rather than `Record<string, JsonSchema>` deliberately: an imported `.json` schema widens `"type"` to `string`, and an authored one carries `$schema`/`title`/`description`/`additionalProperties`, so the tighter type would reject both of the normal ways to supply one. */
1786
+ cardSchemas?: Record<string, object>;
1758
1787
  /** A message's action button was clicked. `action` is the built-in name (`copy` / `like` / `dislike` / `regenerate` / `edit`) or a custom id. `state` is present only for the toggleable feedback votes: `'on'` when a like/dislike is set, `'off'` when re-tapped to clear. */
1759
1788
  onMessageAction?: (event: CustomEvent<{ messageId: string; action: string; state?: undefined | "on" | "off" }>) => void;
1760
1789
  }
1761
1790
 
1762
1791
  export const Thread = /*#__PURE__*/ createWebComponent<ThreadProps>(
1763
1792
  'kai-thread',
1764
- ["theme","messages","loading","proseSize","codeTheme","codeHighlight","actionsReveal","scrollButton","class"],
1793
+ ["theme","messages","loading","proseSize","codeTheme","codeHighlight","actionsReveal","scrollButton","class","cardTypes","cardSchemas"],
1765
1794
  { onMessageAction: 'kai-message-action' },
1766
1795
  () => import('@kitn.ai/ui/elements/thread'),
1767
1796
  );
1768
1797
 
1769
1798
  export interface ToastRegionProps extends WebComponentProps {
1770
- /** The toasts to render. Newest is shown on top. Set as a JS property (array); pass a new array reference to update. */
1771
- toasts: { id: string; message: string; variant?: undefined | "error" | "info" | "success" | "warning" | "neutral"; appearance?: undefined | "pill" | "card"; inverse?: undefined | boolean; description?: undefined | string; action?: undefined | { label: string; onAction: () => void | false }; duration?: undefined | number; dismissible?: undefined | boolean; target?: undefined | HTMLElement }[];
1799
+ /** The toasts to render. Newest is shown on top. Set as a JS property (array); pass a new array reference to update. Omit for an empty region, which is the normal resting state and how the imperative `toast()` API starts. */
1800
+ toasts?: { id: string; message: string; variant?: "neutral" | "success" | "warning" | "error" | "info"; appearance?: "pill" | "card"; inverse?: boolean; description?: string; action?: { label: string; onAction: () => void | false }; duration?: number; dismissible?: boolean; target?: HTMLElement }[];
1772
1801
  /** Stack anchor: `'top-center'` (default), `'top-right'`, `'bottom-center'`, … */
1773
1802
  position?: "top-center" | "top-right" | "top-left" | "bottom-center" | "bottom-right" | "bottom-left";
1774
1803
  /** Max simultaneously-visible toasts; the rest queue. Defaults to `3`. */
@@ -1784,7 +1813,7 @@ export interface ToastRegionProps extends WebComponentProps {
1784
1813
  /** A toast's action button was pressed. */
1785
1814
  onAction?: (event: CustomEvent<{ id: string; label: string }>) => void;
1786
1815
  /** A toast left the stack. `reason` is `'timeout' | 'close' | 'action'`. */
1787
- onDismiss?: (event: CustomEvent<{ id: string; reason: "action" | "timeout" | "close" }>) => void;
1816
+ onDismiss?: (event: CustomEvent<{ id: string; reason: "timeout" | "close" | "action" }>) => void;
1788
1817
  }
1789
1818
 
1790
1819
  export const ToastRegion = /*#__PURE__*/ createWebComponent<ToastRegionProps>(
@@ -1796,12 +1825,12 @@ export const ToastRegion = /*#__PURE__*/ createWebComponent<ToastRegionProps>(
1796
1825
 
1797
1826
  export interface ToolProps extends WebComponentProps {
1798
1827
  /** The tool-call to display. Set as a JS property. */
1799
- tool?: { type: string; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; output?: Record<string, unknown>; toolCallId?: string; errorText?: string };
1828
+ tool?: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } };
1800
1829
  /** Drive/observe open state (Shoelace-style: settable + reflected to the `open` attribute; the element still self-manages on trigger click). Set `el.open = true`, or `<kai-tool open>`; listen for `kai-open-change`. */
1801
1830
  open?: boolean;
1802
1831
  /** Initial open state on mount (uncontrolled seed). */
1803
1832
  defaultOpen?: boolean;
1804
- /** Gate the disclosure trigger programmatic `show()/hide()/toggle()` still work, but the trigger click no longer toggles. */
1833
+ /** Gate the disclosure trigger: programmatic `show()/hide()/toggle()` still work, but the trigger click no longer toggles. */
1805
1834
  disabled?: boolean;
1806
1835
  /** The panel expanded or collapsed (by trigger click or a method). */
1807
1836
  onOpenChange?: (event: CustomEvent<{ open: boolean }>) => void;
@@ -1841,7 +1870,7 @@ export const Tooltip = /*#__PURE__*/ createWebComponent<TooltipProps>(
1841
1870
  );
1842
1871
 
1843
1872
  export interface VoiceInputProps extends WebComponentProps {
1844
- /** Transcriber the host supplies records audio, returns the text. This is a **function-valued property** (`el.transcribe = async blob => '...'`) because a value-returning callback can't be modelled as a fire-and-forget event. */
1873
+ /** Transcriber the host supplies: records audio, returns the text. This is a **function-valued property** (`el.transcribe = async blob => '...'`) because a value-returning callback can't be modelled as a fire-and-forget event. */
1845
1874
  transcribe?: (audio: Blob) => Promise<string>;
1846
1875
  /** Disable the mic button (non-interactive). */
1847
1876
  disabled?: boolean;
@@ -1849,13 +1878,13 @@ export interface VoiceInputProps extends WebComponentProps {
1849
1878
  recognitionLang?: string;
1850
1879
  /** Emit live partial transcripts (`kai-transcript-interim`) during native recognition. Attribute: `interim`. No-op on the transcribe/fallback paths. */
1851
1880
  interim?: boolean;
1852
- /** Raw audio captured (before transcription) for hosts that prefer to handle transcription themselves instead of via the `transcribe` property. Also the unsupported-fallback signal: no `transcribe`, no SpeechRecognition, so only the blob is produced (no text). */
1881
+ /** Raw audio captured (before transcription), for hosts that prefer to handle transcription themselves instead of via the `transcribe` property. Also the unsupported-fallback signal: no `transcribe`, no SpeechRecognition, so only the blob is produced (no text). */
1853
1882
  onAudioCaptured?: (event: CustomEvent<{ blob: Blob }>) => void;
1854
- /** Recording started or stopped lets the host drive its own UI (waveform, push-to-talk indicator) in sync with the mic. Fires on real transitions only (manual click and programmatic start()/stop()), never on mount. */
1883
+ /** Recording started or stopped. Lets the host drive its own UI (waveform, push-to-talk indicator) in sync with the mic. Fires on real transitions only (manual click and programmatic start()/stop()), never on mount. */
1855
1884
  onRecordingChange?: (event: CustomEvent<{ recording: boolean }>) => void;
1856
1885
  /** Live partial transcript during native recognition (only when `interim` is set). Fires repeatedly before the final `kai-transcription`. */
1857
1886
  onTranscriptInterim?: (event: CustomEvent<{ text: string }>) => void;
1858
- /** Final transcript the `transcribe` property resolved, OR native `SpeechRecognition` produced final text (no `transcribe` set). */
1887
+ /** Final transcript: the `transcribe` property resolved, OR native `SpeechRecognition` produced final text (no `transcribe` set). */
1859
1888
  onTranscription?: (event: CustomEvent<{ text: string }>) => void;
1860
1889
  }
1861
1890
 
@@ -1871,13 +1900,13 @@ export interface VoiceOutputProps extends WebComponentProps {
1871
1900
  text?: string;
1872
1901
  /** Speak automatically when `text` is set/changed. */
1873
1902
  autoplay?: boolean;
1874
- /** TTS model seam the host supplies given text, returns an audio `Blob` to play. This is a **function-valued property** (`el.synthesize = async text => blob`); when set, the native `speechSynthesis` path is bypassed. Mirrors `<kai-voice-input>`'s `transcribe`. A value-returning callback can't be modelled as a fire-and-forget event, hence a property. */
1903
+ /** TTS model seam the host supplies: given text, returns an audio `Blob` to play. This is a **function-valued property** (`el.synthesize = async text => blob`); when set, the native `speechSynthesis` path is bypassed. Mirrors `<kai-voice-input>`'s `transcribe`. A value-returning callback can't be modelled as a fire-and-forget event, hence a property. */
1875
1904
  synthesize?: (text: string) => Promise<Blob>;
1876
1905
  /** Disable the button (non-interactive). */
1877
1906
  disabled?: boolean;
1878
- /** Playback started or stopped drive your own UI in sync. Fires on real transitions only (manual click and programmatic speak()/stop()), never on mount. */
1907
+ /** Playback started or stopped. Drive your own UI in sync. Fires on real transitions only (manual click and programmatic speak()/stop()), never on mount. */
1879
1908
  onSpeakingChange?: (event: CustomEvent<{ speaking: boolean }>) => void;
1880
- /** The model path (`synthesize`) resolved audio the raw `Blob` before playback. */
1909
+ /** The model path (`synthesize`) resolved audio: the raw `Blob` before playback. */
1881
1910
  onSynthesized?: (event: CustomEvent<{ blob: Blob }>) => void;
1882
1911
  }
1883
1912
 
@@ -1889,20 +1918,20 @@ export const VoiceOutput = /*#__PURE__*/ createWebComponent<VoiceOutputProps>(
1889
1918
  );
1890
1919
 
1891
1920
  export interface WorkspaceProps extends WebComponentProps {
1892
- /** Pre-bucketed conversation groups for the sidebar. Set as a JS property. */
1893
- groups: { id: string; userId?: undefined | string; teamId?: undefined | string; name: string; sortOrder: number; createdAt: string }[];
1894
- /** Flat conversation list (auto-bucketed if `groups` is empty). Set as a JS property. */
1895
- conversations: { id: string; title: string; groupId?: undefined | string; scope: { type: "document" | "collection"; documentId?: undefined | string; filters?: undefined | { tags?: undefined | string[]; authors?: undefined | string[]; contentType?: undefined | "transcript" | "markdown"; dateRange?: undefined | { from: string; to: string } } }; messageCount: number; lastMessageAt: string; updatedAt: string; trailing?: undefined | string }[];
1921
+ /** The sidebar's section headers, rendered in array order. A group carries no conversations of its own; it is matched against `conversations` by id, so the two props are complementary rather than alternatives. Omit for an ungrouped sidebar. Set as a JS property. */
1922
+ groups?: { id: string; userId?: string; teamId?: string; name: string; sortOrder: number; createdAt: string }[];
1923
+ /** Every conversation in the sidebar, flat. Each one is filed under the group whose `id` equals its `groupId`; one with no `groupId`, or with a `groupId` matching no entry in `groups`, falls into a trailing ungrouped section (headerless when `compact`), so nothing you pass in is ever dropped. There is no recency bucketing. Set as a JS property. Omit for an empty sidebar, or when `no-conversations` replaces the built-in list with your own `sidebar-header` content. */
1924
+ conversations?: { id: string; title: string; groupId?: string; scope: { type: "document" | "collection"; documentId?: string; filters?: { tags?: string[]; authors?: string[]; contentType?: "transcript" | "markdown"; dateRange?: { from: string; to: string } } }; messageCount: number; lastMessageAt: string; updatedAt: string; trailing?: string }[];
1896
1925
  /** Id of the open conversation, highlighted in the sidebar. */
1897
1926
  activeId?: string;
1898
- /** The active conversation's message thread, newest last. Set as a JS property. */
1899
- messages: { id: string; role: "user" | "assistant"; content: string; reasoning?: undefined | { text: string; label?: undefined | string }; tools?: undefined | { type: string; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: undefined | Record<string, unknown>; output?: undefined | Record<string, unknown>; toolCallId?: undefined | string; errorText?: undefined | string }[]; attachments?: undefined | { id: string; type: "file" | "source-document"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }[]; actions?: undefined | ("copy" | "like" | "dislike" | "regenerate" | "edit" | { id: string; label: string; icon?: undefined | string; tooltip?: undefined | string })[]; avatar?: undefined | { src?: undefined | string; fallback?: undefined | string; alt?: undefined | string }; feedback?: undefined | "like" | "dislike" }[];
1927
+ /** The active conversation's message thread, newest last. Set as a JS property (`el.messages = [...]`); a NEW array reference per streaming chunk re-renders (mutating in place does not). Omit for an empty thread. */
1928
+ messages?: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "like" | "dislike" | "regenerate" | "edit" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" }[];
1900
1929
  value?: string;
1901
1930
  placeholder?: string;
1902
1931
  loading?: boolean;
1903
1932
  suggestions?: string[];
1904
1933
  suggestionMode?: "submit" | "fill";
1905
- proseSize?: "sm" | "lg" | "xs" | "base";
1934
+ proseSize?: "xs" | "sm" | "base" | "lg";
1906
1935
  codeTheme?: string;
1907
1936
  codeHighlight?: boolean;
1908
1937
  chatTitle?: string;
@@ -1932,6 +1961,10 @@ export interface WorkspaceProps extends WebComponentProps {
1932
1961
  compact?: boolean;
1933
1962
  /** Suppress the built-in ConversationList so the `sidebar-header` slot owns the whole rail flex region (for apps that supply their own rail nav). Default false. Attribute: `no-conversations`. */
1934
1963
  noConversations?: boolean;
1964
+ /** Optional card type -> custom-element tag overrides/additions for `card` parts (merged over the built-ins). Property: `el.cardTypes`. Typed as a plain string map (not the `CardTagMap` alias) so the generated React wrapper inlines it instead of emitting an unresolved named type. */
1965
+ cardTypes?: Record<string, string>;
1966
+ /** JSON Schemas for the card types this app renders, keyed by envelope type. The companion of `cardTypes`, which says what DRAWS a card while this says what a VALID one looks like. An OBJECT, so it is a JS property only: `el.cardSchemas = { 'pricing-table': pricingSchema }`, never an attribute. `createCardRegistry(...).validationSchemas` is exactly this shape. Without it the kit validates its own seven built-ins and leaves your own card type, the one your app actually cares about, as the only unchecked thing on screen. A schema here WINS over a built-in of the same name. Typed `Record<string, object>` rather than `Record<string, JsonSchema>` deliberately: an imported `.json` schema widens `"type"` to `string`, and an authored one carries `$schema`/`title`/`description`/`additionalProperties`, so the tighter type would reject both of the normal ways to supply one. */
1967
+ cardSchemas?: Record<string, object>;
1935
1968
  /** A conversation was selected in the sidebar. */
1936
1969
  onConversationSelect?: (event: CustomEvent<{ id: string }>) => void;
1937
1970
  /** An action button on a message was clicked. `state` is present only for the toggleable feedback votes: `'on'` when a like/dislike is set, `'off'` when re-tapped to clear. */
@@ -1956,7 +1989,7 @@ export interface WorkspaceProps extends WebComponentProps {
1956
1989
 
1957
1990
  export const Workspace = /*#__PURE__*/ createWebComponent<WorkspaceProps>(
1958
1991
  'kai-workspace',
1959
- ["theme","groups","conversations","activeId","messages","value","placeholder","loading","suggestions","suggestionMode","proseSize","codeTheme","codeHighlight","chatTitle","models","currentModel","context","scrollButton","search","voice","triggers","kindIcons","sidebarWidth","sidebarMinWidth","sidebarMaxWidth","sidebarCollapsed","defaultSidebarCollapsed","collapseBelow","compact","noConversations"],
1992
+ ["theme","groups","conversations","activeId","messages","value","placeholder","loading","suggestions","suggestionMode","proseSize","codeTheme","codeHighlight","chatTitle","models","currentModel","context","scrollButton","search","voice","triggers","kindIcons","sidebarWidth","sidebarMinWidth","sidebarMaxWidth","sidebarCollapsed","defaultSidebarCollapsed","collapseBelow","compact","noConversations","cardTypes","cardSchemas"],
1960
1993
  { onConversationSelect: 'kai-conversation-select', onMessageAction: 'kai-message-action', onModelChange: 'kai-model-change', onNewChat: 'kai-new-chat', onSearch: 'kai-search', onSidebarToggle: 'kai-sidebar-toggle', onSubmit: 'kai-submit', onSuggestionClick: 'kai-suggestion-click', onValueChange: 'kai-value-change', onVoice: 'kai-voice' },
1961
1994
  () => import('@kitn.ai/ui/elements/chat-workspace'),
1962
1995
  );