@kitn.ai/ui 0.20.0 → 0.21.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 (500) 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 +68 -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-D3Y5qiij.js +338 -0
  50. package/dist/create-tween-DGKY1FDY.js +341 -0
  51. package/dist/create-tween-paho5Rh-.js +7 -0
  52. package/dist/custom-elements.json +1681 -454
  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-C-2LvGDG.js} +1 -1
  70. package/dist/elements/chunks/{action-icons-ns1Fnedj.js → action-icons-CaYoImEk.js} +1 -1
  71. package/dist/elements/chunks/arrow-left-Bb46H7w9.js +1 -0
  72. package/dist/elements/chunks/artifact-BBIscOxJ.js +1 -0
  73. package/dist/elements/chunks/{attachments-mCB5F1Fq.js → attachments-BB56zoji.js} +1 -1
  74. package/dist/elements/chunks/audio-visualizer-BxOx4THz.js +1 -0
  75. package/dist/elements/chunks/{badge-B4Zuajl2.js → badge-SxLSZ19R.js} +1 -1
  76. package/dist/elements/chunks/{button-ZWNif3--.js → button-CmkUkz6c.js} +1 -1
  77. package/dist/elements/chunks/card-renderer-Db4ffkWv.js +1 -0
  78. package/dist/elements/chunks/card-tags-D8lZ-C_U.js +1 -0
  79. package/dist/elements/chunks/chat-thread-B3Ks-cKr.js +1 -0
  80. package/dist/elements/chunks/check-C8desc_h.js +1 -0
  81. package/dist/elements/chunks/chevron-down-DKtc2HNB.js +1 -0
  82. package/dist/elements/chunks/chevron-right-Dw4GPhwL.js +1 -0
  83. package/dist/elements/chunks/choice-card-Q9cYYDyM.js +1 -0
  84. package/dist/elements/chunks/circle-BeokBsvB.js +1 -0
  85. package/dist/elements/chunks/circle-check-wJSqt859.js +1 -0
  86. package/dist/elements/chunks/{circle-x-B7faJFlY.js → circle-x-D0MEfxOM.js} +1 -1
  87. package/dist/elements/chunks/code-block-C8VzAraE.js +1 -0
  88. package/dist/elements/chunks/{collapsible-DM1Ckd4e.js → collapsible-Cvj61obE.js} +1 -1
  89. package/dist/elements/chunks/{composer-BguS0QL_.js → composer-D86ztyL0.js} +2 -2
  90. package/dist/elements/chunks/confirm-card-BdyDAGLw.js +1 -0
  91. package/dist/elements/chunks/context-WHDl-xSx.js +1 -0
  92. package/dist/elements/chunks/conversation-list-CdR14_Y4.js +1 -0
  93. package/dist/elements/chunks/create-tween-C_A_B638.js +7 -0
  94. package/dist/elements/chunks/{default-input-Cqqilg9t.js → default-input-CSZqUM81.js} +1 -1
  95. package/dist/elements/chunks/define-BzPnNsXg.js +1 -0
  96. package/dist/elements/chunks/{disclosure-CIZ5c8nO.js → disclosure-DVKsoc1F.js} +1 -1
  97. package/dist/elements/chunks/{download-Dsbg3ste.js → download-BjA54IMJ.js} +1 -1
  98. package/dist/elements/chunks/{dropdown-BDd1-Zgi.js → dropdown-BjVVHWXH.js} +1 -1
  99. package/dist/elements/chunks/{ellipsis-Dw6qrss-.js → ellipsis-BNedmqfi.js} +1 -1
  100. package/dist/elements/chunks/embed-DQsl4XEq.js +1 -0
  101. package/dist/elements/chunks/{external-link-Vt74zAoL.js → external-link-Di-dw2CU.js} +1 -1
  102. package/dist/elements/chunks/{file-text-CZrZF6_v.js → file-text-B3sAODCV.js} +1 -1
  103. package/dist/elements/chunks/{file-tree-DF4okKyo.js → file-tree-Dgto-bMn.js} +1 -1
  104. package/dist/elements/chunks/{folder-glP5rha4.js → folder-D6rMadFV.js} +1 -1
  105. package/dist/elements/chunks/form-CILxvhQ7.js +1 -0
  106. package/dist/elements/chunks/hover-card-BtiF4XiU.js +1 -0
  107. package/dist/elements/chunks/{icon-BLb8beoi.js → icon-DKkmze3y.js} +1 -1
  108. package/dist/elements/chunks/{info-CIsv92JK.js → info-CWRjZkuy.js} +1 -1
  109. package/dist/elements/chunks/{input-Dds1kFyt.js → input--QJBK6BA.js} +1 -1
  110. package/dist/elements/chunks/{kbd-De_xbgi9.js → kbd-C3zuKh8R.js} +1 -1
  111. package/dist/elements/chunks/{link-i4r_k7z4.js → link-BL5JA7Q0.js} +1 -1
  112. package/dist/elements/chunks/link-preview-CU37bbXh.js +1 -0
  113. package/dist/elements/chunks/{loader-BmQH4s3V.js → loader-XmpyxyRH.js} +1 -1
  114. package/dist/elements/chunks/{markdown-Zi21WhUz.js → markdown-3Gv5UZ_o.js} +1 -1
  115. package/dist/elements/chunks/message-CnBA2OUt.js +1 -0
  116. package/dist/elements/chunks/message-X5NZbq-W.js +1 -0
  117. package/dist/elements/chunks/message-square-CnpAm_P0.js +1 -0
  118. package/dist/elements/chunks/{minimize-2--ifeCGrl.js → minimize-2-DwyrUTcM.js} +1 -1
  119. package/dist/elements/chunks/{model-switcher-B94YAKsM.js → model-switcher-CclaJEHt.js} +1 -1
  120. package/dist/elements/chunks/{overlay-kD8dwRv_.js → overlay-Cepd-KcS.js} +1 -1
  121. package/dist/elements/chunks/{paperclip-q21dYOSK.js → paperclip-CdwKjrlu.js} +1 -1
  122. package/dist/elements/chunks/{progress-bar-BrAIIaaJ.js → progress-bar-DMVXBD3b.js} +1 -1
  123. package/dist/elements/chunks/{prompt-suggestion-Bjn2K-fR.js → prompt-suggestion-Di_WZE_5.js} +1 -1
  124. package/dist/elements/chunks/reasoning-D0jMch5u.js +1 -0
  125. package/dist/elements/chunks/{resizable-Dp4JExql.js → resizable-1znbL1Gv.js} +1 -1
  126. package/dist/elements/chunks/{rotate-cw-CFWWkpj2.js → rotate-cw-DVhhgx8n.js} +1 -1
  127. package/dist/elements/chunks/{scroll-area-Bb0kHH1j.js → scroll-area-Bs4bFS1P.js} +1 -1
  128. package/dist/elements/chunks/scroll-button-Bet5NLc4.js +1 -0
  129. package/dist/elements/chunks/{separator-9kRgr1X9.js → separator-C5Gh8qGC.js} +1 -1
  130. package/dist/elements/chunks/{settings-B8lmec4D.js → settings-5vmEFg0K.js} +1 -1
  131. package/dist/elements/chunks/{settings-group-I0hEuXiN.js → settings-group-BWLB38kz.js} +1 -1
  132. package/dist/elements/chunks/{share-C3lTiYGt.js → share-BZ3G_DaB.js} +1 -1
  133. package/dist/elements/chunks/skeleton-DafPJQTp.js +1 -0
  134. package/dist/elements/chunks/slots-CIw9RlAe.js +1 -0
  135. package/dist/elements/chunks/source-D_qj_6uJ.js +1 -0
  136. package/dist/elements/chunks/{star-CSJtGxgv.js → star-Cuv7j2IE.js} +1 -1
  137. package/dist/elements/chunks/{store-CHyW95TP.js → store-C1StPHfW.js} +1 -1
  138. package/dist/elements/chunks/tasks-card-EyoBZfpA.js +1 -0
  139. package/dist/elements/chunks/{text-shimmer-Cn9TmNpI.js → text-shimmer-D9gRSh34.js} +1 -1
  140. package/dist/elements/chunks/textarea-DuhtHfcm.js +1 -0
  141. package/dist/elements/chunks/{thumbs-up-PNVVThEF.js → thumbs-up-B9hwv43w.js} +1 -1
  142. package/dist/elements/chunks/{toast-store-DKbQn3Wn.js → toast-store-Bm3DUEDe.js} +1 -1
  143. package/dist/elements/chunks/{tool-DjTRpIpl.js → tool-CDtW7L0z.js} +1 -1
  144. package/dist/elements/chunks/tooltip-eB226mGK.js +1 -0
  145. package/dist/elements/chunks/{triangle-alert-DsHTHCPm.js → triangle-alert-C1SNzTqK.js} +1 -1
  146. package/dist/elements/chunks/use-card-resolution-YZh2MvI5.js +1 -0
  147. package/dist/elements/chunks/{variant-aurora-Dc4nQUia.js → variant-aurora-Cj1F7D0l.js} +2 -2
  148. package/dist/elements/chunks/{variant-custom-y_3kVQhS.js → variant-custom-T9gpt7QE.js} +1 -1
  149. package/dist/elements/chunks/{variant-wave-D5OR1-9Z.js → variant-wave-CxU9z-TE.js} +2 -2
  150. package/dist/elements/chunks/{video-B7vmenoC.js → video-CK4R7Rus.js} +1 -1
  151. package/dist/elements/chunks/x-D1qx0aLd.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 +7 -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 +2 -2
  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/slots.d.ts +16 -0
  208. package/dist/elements/source.js +1 -1
  209. package/dist/elements/status.js +1 -1
  210. package/dist/elements/switch.js +1 -1
  211. package/dist/elements/tabs.js +1 -1
  212. package/dist/elements/tasks.js +1 -1
  213. package/dist/elements/text-shimmer.js +1 -1
  214. package/dist/elements/thinking-bar.js +1 -1
  215. package/dist/elements/thread.js +1 -1
  216. package/dist/elements/toast.js +1 -1
  217. package/dist/elements/tool.js +1 -1
  218. package/dist/elements/tooltip.js +1 -1
  219. package/dist/elements/validate-messages.d.ts +25 -0
  220. package/dist/elements/voice-input.js +1 -1
  221. package/dist/elements/voice-output.js +1 -1
  222. package/dist/elements.d.ts +2725 -214
  223. package/dist/index.d.ts +163 -125
  224. package/dist/index.js +6336 -5802
  225. package/dist/index.server.d.ts +5 -0
  226. package/dist/index.server.js +16913 -0
  227. package/dist/kai-provider.es.d.ts +5 -0
  228. package/dist/kai-provider.es.js +79 -77
  229. package/dist/kai.es.d.ts +5 -0
  230. package/dist/kai.es.js +1 -1
  231. package/dist/llms/llms-full.txt +762 -148
  232. package/dist/llms/llms.txt +57 -5
  233. package/dist/mcp.es.js +4010 -770
  234. package/dist/primitives/card-component-types.d.ts +11 -0
  235. package/dist/primitives/card-data-types.d.ts +196 -0
  236. package/dist/primitives/card-host.d.ts +1 -1
  237. package/dist/primitives/card-recovery.d.ts +3 -3
  238. package/dist/primitives/card-registry.d.ts +4 -14
  239. package/dist/primitives/card-resolution.d.ts +1 -1
  240. package/dist/primitives/card-routing.d.ts +1 -1
  241. package/dist/primitives/card-tags.d.ts +11 -0
  242. package/dist/primitives/card-validate-cards.d.ts +57 -0
  243. package/dist/primitives/card-validate-generator.testlib.d.ts +20 -0
  244. package/dist/primitives/card-validate-schemas.d.ts +17 -0
  245. package/dist/primitives/card-validate.d.ts +24 -0
  246. package/dist/primitives/create-kai-chat.d.ts +3 -3
  247. package/dist/primitives/embed-providers.d.ts +1 -1
  248. package/dist/primitives/link-preview.d.ts +1 -1
  249. package/dist/primitives/message-feedback.d.ts +2 -2
  250. package/dist/primitives/toast-store.d.ts +1 -1
  251. package/dist/react/index.d.ts +717 -299
  252. package/dist/react/use-kai-chat.d.ts +8 -4
  253. package/dist/react.d.ts +5 -0
  254. package/dist/react.js +417 -316
  255. package/dist/register-impl-bzrZ44ft.js +145 -0
  256. package/dist/remote/host-embed.d.ts +1 -1
  257. package/dist/remote/index.d.ts +2 -2
  258. package/dist/remote/provider-runtime.d.ts +2 -2
  259. package/dist/remote/provider.d.ts +2 -2
  260. package/dist/remote/validate.d.ts +1 -1
  261. package/dist/remote/wire.d.ts +1 -1
  262. package/dist/schemas/artifact.schema.json +92 -0
  263. package/dist/schemas/embed.schema.json +0 -2
  264. package/dist/schemas/from-tool-call.d.ts +48 -0
  265. package/dist/schemas/index.d.ts +48 -0
  266. package/dist/schemas/link.schema.json +0 -2
  267. package/dist/schemas/provider-subsets.d.ts +136 -0
  268. package/dist/schemas/registry.d.ts +140 -0
  269. package/dist/schemas/tool-defs.d.ts +121 -0
  270. package/dist/schemas.d.ts +5 -0
  271. package/dist/schemas.js +717 -0
  272. package/dist/solid-BCJUQqwS.js +22750 -0
  273. package/dist/solid-BdENBcEq.js +20108 -0
  274. package/dist/solid.d.ts +66 -0
  275. package/dist/solid.js +261 -0
  276. package/dist/solid.server.d.ts +5 -0
  277. package/dist/solid.server.js +261 -0
  278. package/dist/state/index.d.ts +14 -4
  279. package/dist/state/messages.d.ts +8 -3
  280. package/dist/state/mock.d.ts +46 -0
  281. package/dist/state/parts.d.ts +85 -0
  282. package/dist/state/stream.d.ts +15 -9
  283. package/dist/state.d.ts +5 -0
  284. package/dist/state.js +253 -84
  285. package/dist/ui/action-icons.d.ts +1 -1
  286. package/dist/ui/collapsible.d.ts +11 -6
  287. package/dist/ui/dropdown.d.ts +47 -42
  288. package/dist/ui/pane-group.d.ts +1 -1
  289. package/dist/variant-aurora-1wMcXRUS.js +381 -0
  290. package/dist/variant-aurora-BKHHiOgL.js +391 -0
  291. package/dist/{variant-aurora-DVtGqVH6.js → variant-aurora-DOb_o4pC.js} +1 -1
  292. package/dist/{variant-custom-Dif-IV4u.js → variant-custom-CJGB0Kbw.js} +1 -1
  293. package/dist/variant-custom-Co0CkXJF.js +200 -0
  294. package/dist/variant-custom-DWSSgmd2.js +170 -0
  295. package/dist/variant-wave-C3-45cL6.js +218 -0
  296. package/dist/{variant-wave-DbfNdvSi.js → variant-wave-CEODq-9q.js} +1 -1
  297. package/dist/variant-wave-jdXBnCUZ.js +208 -0
  298. package/dist/wire/chunk.d.ts +171 -0
  299. package/dist/wire/consume.d.ts +26 -0
  300. package/dist/wire/encode.d.ts +148 -0
  301. package/dist/wire/formats/anthropic.d.ts +2 -0
  302. package/dist/wire/formats/openai.d.ts +5 -0
  303. package/dist/wire/index.d.ts +14 -0
  304. package/dist/wire/read.d.ts +26 -0
  305. package/dist/wire/sink-helpers.d.ts +21 -0
  306. package/dist/wire/sse.d.ts +33 -0
  307. package/dist/wire.d.ts +5 -53
  308. package/dist/wire.js +898 -0
  309. package/frameworks/react/index.tsx +183 -154
  310. package/frameworks/react/runtime.tsx +21 -1
  311. package/frameworks/react/use-kai-chat.tsx +11 -1
  312. package/llms-full.txt +762 -148
  313. package/llms.txt +57 -5
  314. package/package.json +65 -7
  315. package/src/agent-tooling/archetypes.ts +96 -0
  316. package/src/agent-tooling/integrations/anthropic.ts +412 -0
  317. package/src/agent-tooling/integrations/cloudflare.ts +136 -52
  318. package/src/agent-tooling/integrations/langgraph.ts +67 -13
  319. package/src/agent-tooling/integrations/mastra.ts +120 -12
  320. package/src/agent-tooling/integrations/mock.ts +43 -8
  321. package/src/agent-tooling/integrations/ollama.ts +61 -24
  322. package/src/agent-tooling/integrations/openai.ts +87 -0
  323. package/src/agent-tooling/integrations/openrouter.ts +56 -8
  324. package/src/agent-tooling/integrations/pi.ts +79 -23
  325. package/src/agent-tooling/integrations/pydantic-ai.ts +24 -2
  326. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +84 -13
  327. package/src/agent-tooling/mcp/manifest.ts +206 -25
  328. package/src/agent-tooling/mcp/tools/debug.ts +13 -7
  329. package/src/agent-tooling/mcp/tools/reference.ts +285 -6
  330. package/src/agent-tooling/mcp/tools/scaffold.ts +3345 -675
  331. package/src/agent-tooling/registry.ts +17 -0
  332. package/src/agent-tooling/types.ts +229 -1
  333. package/src/components/artifact-card.tsx +120 -0
  334. package/src/components/audio-visualizer/index.tsx +9 -0
  335. package/src/components/audio-visualizer/labs/lab-choreography.ts +187 -0
  336. package/src/components/audio-visualizer/labs/lab-shaders.ts +363 -0
  337. package/src/components/audio-visualizer/labs/lab-visualizer.tsx +102 -0
  338. package/src/components/audio-visualizer/shader-canvas.tsx +31 -1
  339. package/src/components/card-fallback.tsx +42 -10
  340. package/src/components/card-renderer.tsx +146 -9
  341. package/src/components/chat-container.tsx +4 -0
  342. package/src/components/chat-thread.tsx +118 -51
  343. package/src/components/choice-card.tsx +17 -29
  344. package/src/components/composer.tsx +12 -2
  345. package/src/components/confirm-card.tsx +24 -20
  346. package/src/components/context.tsx +12 -4
  347. package/src/components/conversation-list.tsx +18 -2
  348. package/src/components/file-tree.tsx +11 -22
  349. package/src/components/file-upload.tsx +14 -8
  350. package/src/components/form.tsx +14 -47
  351. package/src/components/loader.tsx +39 -12
  352. package/src/components/message-skills.tsx +4 -0
  353. package/src/components/message.tsx +294 -46
  354. package/src/components/reasoning.tsx +92 -5
  355. package/src/components/response-compare-types.ts +25 -0
  356. package/src/components/response-compare.tsx +4 -9
  357. package/src/components/source.tsx +50 -24
  358. package/src/components/tasks-card.tsx +10 -33
  359. package/src/components/thread.tsx +84 -42
  360. package/src/components/toast.tsx +11 -5
  361. package/src/components/tool-classify.ts +26 -0
  362. package/src/components/tool-types.ts +31 -1
  363. package/src/elements/agent-card.tsx +11 -11
  364. package/src/elements/artifact.tsx +15 -7
  365. package/src/elements/attachments.tsx +6 -4
  366. package/src/elements/avatar.tsx +1 -1
  367. package/src/elements/button.tsx +3 -3
  368. package/src/elements/card.tsx +2 -2
  369. package/src/elements/cards.tsx +109 -14
  370. package/src/elements/chain-of-thought.tsx +14 -10
  371. package/src/elements/chat-scope-picker.tsx +9 -7
  372. package/src/elements/chat-types.ts +59 -6
  373. package/src/elements/chat-workspace.tsx +50 -9
  374. package/src/elements/chat.tsx +64 -3
  375. package/src/elements/choice.tsx +8 -8
  376. package/src/elements/coachmark.tsx +1 -1
  377. package/src/elements/command.tsx +8 -23
  378. package/src/elements/compare.tsx +7 -6
  379. package/src/elements/compiled.css +1 -1
  380. package/src/elements/composer.tsx +8 -8
  381. package/src/elements/confirm-card.tsx +9 -9
  382. package/src/elements/context-meter.tsx +4 -18
  383. package/src/elements/conversation-list.tsx +14 -9
  384. package/src/elements/default-input.tsx +3 -3
  385. package/src/elements/define.tsx +178 -43
  386. package/src/elements/editable-label.tsx +17 -2
  387. package/src/elements/element-data-types.ts +112 -0
  388. package/src/elements/element-meta.json +1596 -304
  389. package/src/elements/element-types.d.ts +2636 -211
  390. package/src/elements/feedback-bar.tsx +1 -1
  391. package/src/elements/file-tree.tsx +1 -1
  392. package/src/elements/file-upload.tsx +1 -1
  393. package/src/elements/form.tsx +14 -6
  394. package/src/elements/input.tsx +1 -1
  395. package/src/elements/kbd.tsx +1 -1
  396. package/src/elements/menu.tsx +10 -29
  397. package/src/elements/message-skills.tsx +7 -9
  398. package/src/elements/message.tsx +200 -32
  399. package/src/elements/model-switcher.tsx +5 -3
  400. package/src/elements/pane.tsx +1 -1
  401. package/src/elements/prompt-dock.tsx +8 -8
  402. package/src/elements/prompt-input.tsx +10 -10
  403. package/src/elements/prompt-suggestions.tsx +7 -4
  404. package/src/elements/reasoning.tsx +1 -1
  405. package/src/elements/register.ts +9 -0
  406. package/src/elements/resizable.globals.d.ts +36 -0
  407. package/src/elements/resizable.tsx +24 -13
  408. package/src/elements/response-stream.tsx +1 -1
  409. package/src/elements/scroll-button.tsx +1 -1
  410. package/src/elements/search.tsx +6 -1
  411. package/src/elements/segmented.tsx +5 -11
  412. package/src/elements/separator.tsx +1 -1
  413. package/src/elements/slots.ts +57 -24
  414. package/src/elements/source.tsx +21 -22
  415. package/src/elements/switch.tsx +3 -3
  416. package/src/elements/tasks.tsx +5 -4
  417. package/src/elements/thread.tsx +36 -4
  418. package/src/elements/toast.tsx +3 -2
  419. package/src/elements/tool.tsx +1 -1
  420. package/src/elements/validate-messages.ts +76 -0
  421. package/src/elements/voice-input.tsx +7 -7
  422. package/src/elements/voice-output.tsx +4 -4
  423. package/src/index.ts +141 -6
  424. package/src/primitives/card-component-types.ts +63 -0
  425. package/src/primitives/card-data-types.ts +312 -0
  426. package/src/primitives/card-recovery.ts +13 -2
  427. package/src/primitives/card-registry.tsx +34 -23
  428. package/src/primitives/card-schemas/artifact.schema.json +92 -0
  429. package/src/primitives/card-schemas/embed.schema.json +0 -2
  430. package/src/primitives/card-schemas/link.schema.json +0 -2
  431. package/src/primitives/card-tags.ts +61 -0
  432. package/src/primitives/card-validate-cards.ts +255 -0
  433. package/src/primitives/card-validate-generator.testlib.ts +38 -0
  434. package/src/primitives/card-validate-schemas.ts +58 -0
  435. package/src/primitives/card-validate.ts +48 -20
  436. package/src/primitives/create-tween.ts +54 -2
  437. package/src/primitives/message-feedback.ts +3 -2
  438. package/src/primitives/use-audio-analysis.ts +20 -1
  439. package/src/primitives/use-sequencer.ts +20 -1
  440. package/src/schemas/from-tool-call.ts +151 -0
  441. package/src/schemas/index.ts +340 -0
  442. package/src/schemas/provider-subsets.ts +538 -0
  443. package/src/schemas/registry.ts +355 -0
  444. package/src/schemas/tool-defs.ts +492 -0
  445. package/src/solid.ts +150 -0
  446. package/src/state/index.ts +27 -1
  447. package/src/state/messages.ts +21 -4
  448. package/src/state/mock.ts +211 -0
  449. package/src/state/parts.ts +295 -0
  450. package/src/state/stream.ts +56 -58
  451. package/src/ui/collapsible.tsx +17 -5
  452. package/src/ui/dropdown.tsx +46 -12
  453. package/src/ui/overlay.tsx +10 -4
  454. package/src/wire/chunk.ts +201 -0
  455. package/src/wire/consume.ts +440 -0
  456. package/src/wire/encode.ts +474 -0
  457. package/src/wire/formats/anthropic.ts +267 -0
  458. package/src/wire/formats/openai.ts +187 -0
  459. package/src/wire/index.ts +52 -0
  460. package/src/wire/read.ts +152 -0
  461. package/src/wire/sink-helpers.ts +50 -0
  462. package/src/wire/sse.ts +140 -0
  463. package/dist/create-tween-hvpmSuwW.js +0 -7
  464. package/dist/elements/chunks/arrow-left-DQocUFvy.js +0 -1
  465. package/dist/elements/chunks/audio-visualizer-BqNy7dfm.js +0 -1
  466. package/dist/elements/chunks/card-BkHbp4BA.js +0 -1
  467. package/dist/elements/chunks/chat-thread-CkRN6pZ7.js +0 -1
  468. package/dist/elements/chunks/check-B9-gn6SS.js +0 -1
  469. package/dist/elements/chunks/chevron-down-BNsxc2hk.js +0 -1
  470. package/dist/elements/chunks/chevron-right-Hv00StBO.js +0 -1
  471. package/dist/elements/chunks/circle-0e3KJTDr.js +0 -1
  472. package/dist/elements/chunks/circle-check-BNAS0JEy.js +0 -1
  473. package/dist/elements/chunks/code-block-BFUHn6Va.js +0 -1
  474. package/dist/elements/chunks/context-Cb7k4F-v.js +0 -1
  475. package/dist/elements/chunks/conversation-list-CvoAkWhN.js +0 -1
  476. package/dist/elements/chunks/create-tween-oVvAIG8r.js +0 -7
  477. package/dist/elements/chunks/define-D1din7Ld.js +0 -1
  478. package/dist/elements/chunks/hover-card-Cmm6Q53m.js +0 -1
  479. package/dist/elements/chunks/message-BqyXDN3-.js +0 -1
  480. package/dist/elements/chunks/message-feedback-Djr3z6Yb.js +0 -1
  481. package/dist/elements/chunks/message-square-vFAgbDaX.js +0 -1
  482. package/dist/elements/chunks/reasoning-DTpCGtnY.js +0 -1
  483. package/dist/elements/chunks/scroll-button-B0cH5fXf.js +0 -1
  484. package/dist/elements/chunks/skeleton-DSXW5Yya.js +0 -1
  485. package/dist/elements/chunks/slots--V19HwUb.js +0 -1
  486. package/dist/elements/chunks/textarea-CUwqAX0G.js +0 -1
  487. package/dist/elements/chunks/tooltip-CgBZCVKp.js +0 -1
  488. package/dist/elements/chunks/use-card-resolution-BSu_XHjH.js +0 -1
  489. package/dist/elements/chunks/x-GRUeeQFT.js +0 -1
  490. package/dist/host-embed.d.ts +0 -33
  491. package/dist/kai-provider.d.ts +0 -2
  492. package/dist/origin.d.ts +0 -5
  493. package/dist/provider-runtime.d.ts +0 -27
  494. package/dist/register-impl-DQyejdfb.js +0 -145
  495. package/dist/validate.d.ts +0 -4
  496. package/dist/version.d.ts +0 -4
  497. package/src/components/component-meta.json +0 -4550
  498. package/src/elements/card-media.jpg +0 -0
  499. package/src/elements/resizable.d.ts +0 -27
  500. package/src/elements/video-poster.jpg +0 -0
@@ -29,6 +29,15 @@ export type { ChatMessage, ChatMessageAction } from './chat-types';
29
29
  export { configureCodeHighlighting, isCodeHighlightingEnabled } from '../primitives/highlighter';
30
30
  export type { CodeHighlightingOptions } from '../primitives/highlighter';
31
31
 
32
+ // ToolPart.kind's doc comment in the shipped dist/elements.d.ts says "Derive with
33
+ // `classifyTool(type)`", but the function was exported from NO public entry, so a
34
+ // consumer following our own docs hit an unresolvable import. Total, deterministic
35
+ // and always terminating in 'generic' — safe to expose, and needed by anyone
36
+ // rendering tool calls themselves. tool-classify.ts imports nothing, so this stays
37
+ // SSR-safe and adds no weight to the register-all bundle.
38
+ export { classifyTool } from '../components/tool-classify';
39
+ export type { ToolKind } from '../components/tool-classify';
40
+
32
41
  // Imperative toast API — usable directly from the elements entry so consumers
33
42
  // who only import the web-components bundle still get `toast()`. The store is
34
43
  // SSR-safe (no DOM touched until the first toast is raised on the client).
@@ -0,0 +1,36 @@
1
+ // src/elements/resizable.globals.d.ts
2
+ // Hand-authored ambient types for the cross-element maximize PROTOCOL — the two
3
+ // raw composed CustomEvents `<kai-artifact>` and `<kai-resizable>`/`<kai-resizable-item>`
4
+ // exchange. The generated element-types.d.ts emits no HTMLElementEventMap entries,
5
+ // so without this `el.addEventListener('kai-maximize-intent', e => e.detail)` is
6
+ // TS2339 on `Event`. NOT regenerated by `npm run build`.
7
+ //
8
+ // THE FILENAME IS LOAD-BEARING and must not go back to `resizable.d.ts`.
9
+ // TypeScript drops a .d.ts when a same-named .ts/.tsx sits beside it, and
10
+ // `resizable.tsx` does. Under the old name this whole file was in NO tsc
11
+ // program, so every augmentation below was inert. Measured on the same probe,
12
+ // `el.addEventListener('kai-maximize-intent', e => e.detail)`:
13
+ // resizable.d.ts TS2339: Property 'detail' does not exist on 'Event'
14
+ // resizable.globals.d.ts clean -- narrowed to CustomEvent<KaiMaximizeIntentDetail>
15
+ //
16
+ // This file used to ALSO declare a global `KaiResizableElement` carrying
17
+ // `maximize`/`restore` plus an HTMLElementTagNameMap entry pointing at it. That
18
+ // half never worked: element-types.d.ts declares its own module-scoped
19
+ // `KaiResizableElement` and maps the tag to THAT, so the two entries collided
20
+ // (TS2717, invisible under the `skipLibCheck: true` every pass sets) and the
21
+ // generated one won — `document.querySelector('kai-resizable').maximize(0)` stayed
22
+ // TS2339. The methods now come from the GENERATOR (resizable.tsx routes them
23
+ // through `ctx.expose`, gen-element-types.mjs emits them onto the element
24
+ // interface), so the duplicate is gone and there is exactly one declaration of
25
+ // each name. Do not reintroduce it: a hand-written interface cannot win against
26
+ // the generated one, and generated files are regenerated.
27
+ import type { KaiMaximizeIntentDetail, KaiMaximizeStateDetail } from './resizable';
28
+
29
+ declare global {
30
+ interface HTMLElementEventMap {
31
+ 'kai-maximize-intent': CustomEvent<KaiMaximizeIntentDetail>;
32
+ 'kai-maximize-state': CustomEvent<KaiMaximizeStateDetail>;
33
+ }
34
+ }
35
+
36
+ export {};
@@ -57,9 +57,9 @@ interface GroupProps extends Record<string, unknown> {
57
57
  maximizedIndex?: number | null;
58
58
  /**
59
59
  * Divider affordance drawn inside each draggable handle's 8px grab zone:
60
- * - `line` (default) a 1px hairline, transparent at rest, tinting on hover/drag.
61
- * - `grip` a dotted grip handle.
62
- * - `none` no visible divider, just the invisible hit-area.
60
+ * - `line` (default): a 1px hairline, transparent at rest, tinting on hover/drag.
61
+ * - `grip`: a dotted grip handle.
62
+ * - `none`: no visible divider, just the invisible hit-area.
63
63
  * The full grab zone and keyboard/ARIA behavior are identical for all three.
64
64
  */
65
65
  handle?: 'line' | 'grip' | 'none';
@@ -70,6 +70,11 @@ interface GroupEvents extends Record<string, unknown> {
70
70
  'kai-change': { sizes: number[] };
71
71
  /** Observe layout maximize state. */
72
72
  'kai-maximize-change': { maximized: boolean; index: number | null };
73
+ /** Authoritative maximize state, dispatched as a raw composed CustomEvent (not
74
+ * through `dispatch`) onto the affected `<kai-resizable-item>` and, on restore,
75
+ * onto the group host. A nested element (e.g. `<kai-artifact>`) listens for it
76
+ * to reconcile its own toggle. */
77
+ 'kai-maximize-state': { maximized: boolean };
73
78
  }
74
79
 
75
80
  /**
@@ -84,7 +89,7 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
84
89
  orientation: 'horizontal',
85
90
  maximizedIndex: null,
86
91
  handle: 'line',
87
- }, (props, { element, dispatch }) => {
92
+ }, (props, { element, dispatch, expose }) => {
88
93
  const [items, setItems] = createSignal<ItemInfo[]>([]);
89
94
  const orientation = (): Orientation => (props.orientation === 'vertical' ? 'vertical' : 'horizontal');
90
95
 
@@ -405,13 +410,19 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
405
410
 
406
411
  // --- Task 3: imperative host methods + declarative maximizedIndex prop ---
407
412
 
408
- // Imperative host API (assigned onto the element; typed by resizable.d.ts).
409
- const host = element as unknown as { maximize(i: number): void; restore(): void };
410
- host.maximize = (i: number) => {
411
- const it = items()[i]?.el;
412
- if (it) maximizeItem(it);
413
- };
414
- host.restore = () => restore();
413
+ // Imperative host API. Routed through `expose()` like every other element's,
414
+ // so gen-element-api.mjs sees it and the generated element interface carries
415
+ // `maximize`/`restore` a direct assignment onto `element` was invisible to
416
+ // the extractor and needed an `as unknown as` cast to type-check here.
417
+ expose({
418
+ /** Imperatively maximize the item at `index` (thin wrapper over `maximizedIndex`). */
419
+ maximize: (index: number) => {
420
+ const it = items()[index]?.el;
421
+ if (it) maximizeItem(it);
422
+ },
423
+ /** Imperatively restore from the maximized layout. */
424
+ restore: () => restore(),
425
+ });
415
426
 
416
427
  // Declarative maximizedIndex → maximize/restore. Skip the initial null run.
417
428
  createEffect(
@@ -599,8 +610,8 @@ interface ItemProps extends Record<string, unknown> {
599
610
  /** Hide this panel; its divider is dropped and the rest reflow. */
600
611
  hidden?: boolean;
601
612
  /**
602
- * Collapse this panel same layout effect as `hidden` (divider dropped, the
603
- * rest reflow), but it WORKS as a bare boolean from framework JSX. A plain
613
+ * Collapse this panel. Same layout effect as `hidden` (divider dropped, the rest
614
+ * reflow), but it WORKS as a bare boolean from framework JSX. A plain
604
615
  * `<kai-resizable-item collapsed>` in React/Solid/Vue/Svelte collapses the panel
605
616
  * at the first render; `hidden` does not, because a JSX boolean sets neither the
606
617
  * `hidden` attribute nor the IDL property on a custom element, so the parent never
@@ -3,7 +3,7 @@ import { ResponseStream, type Mode } from '../components/response-stream';
3
3
 
4
4
  interface Props extends Record<string, unknown> {
5
5
  /** Text to stream. A string, or an `AsyncIterable<string>` (set as a JS
6
- * property async iterables can't be HTML attributes). */
6
+ * property, since async iterables can't be HTML attributes). */
7
7
  text?: string | AsyncIterable<string>;
8
8
  /** Reveal animation. */
9
9
  mode?: Mode;
@@ -19,7 +19,7 @@ interface Props extends Record<string, unknown> {
19
19
  /** Events fired by `<kai-scroll-button>`. */
20
20
  interface Events {
21
21
  /** Emitted when the user clicks the button and `scrollToBottom()` is
22
- * called. Carries no detail consumers use it to know a manual scroll
22
+ * called. Carries no detail; consumers use it to know a manual scroll
23
23
  * occurred. */
24
24
  'kai-scroll': void;
25
25
  }
@@ -6,7 +6,7 @@ import { Loader } from '../components/loader';
6
6
  import { renderIcon } from '../ui/icon';
7
7
 
8
8
  interface Props extends Record<string, unknown> {
9
- /** Controlled query settable and reflected to the `value` attribute. Read
9
+ /** Controlled query. Settable and reflected to the `value` attribute. Read
10
10
  * `el.value` for live state. */
11
11
  value?: string;
12
12
  /** Placeholder. Defaults to `Search…`. */
@@ -123,7 +123,12 @@ defineWebComponent<Props, Events>('kai-search', {
123
123
  };
124
124
 
125
125
  expose({
126
+ /** Focus the search input inside the shadow root. A native `focus()` on the
127
+ * host lands on the host itself and never reaches it. */
126
128
  focus: () => getInput()?.focus(),
129
+ /** Empty the field and fire `kai-search` with an empty value immediately,
130
+ * cancelling any debounced search still in flight, then return focus to the
131
+ * input. Same path as the trailing clear button. */
127
132
  clear,
128
133
  });
129
134
 
@@ -2,20 +2,14 @@ import { createEffect, createSignal, untrack } from 'solid-js';
2
2
  import { defineWebComponent } from './define';
3
3
  import { Segmented, type SegmentedOption } from '../ui/segmented';
4
4
  import { renderIcon } from '../ui/icon';
5
-
6
- /** A single segment. `icon` is an icon-NAME string (web-component-friendly)
7
- * a curated name (e.g. `"code"`), a URL/data-URI, or plain text — resolved to a
8
- * glyph via the kit's icon renderer (the same path `kai-button`'s `icon` uses). */
9
- interface Option {
10
- value: string;
11
- label: string;
12
- icon?: string;
13
- }
5
+ // Public shape of the `options` prop; lives in ./element-data-types so the ROOT
6
+ // entry can re-export it (see that file's header).
7
+ import type { KaiSegmentedOption } from './element-data-types';
14
8
 
15
9
  interface Props extends Record<string, unknown> {
16
10
  /** The selectable segments, left to right. Set as a JS property (array). */
17
- options: Option[];
18
- /** Controlled selected `value` settable and reflected to the `value`
11
+ options: KaiSegmentedOption[];
12
+ /** Controlled selected `value`. Settable and reflected to the `value`
19
13
  * attribute. `el.value = 'preview'` drives it; choosing a segment updates it
20
14
  * and fires `kai-change`. Read `el.value` for live state. */
21
15
  value?: string;
@@ -3,7 +3,7 @@ import { defineWebComponent } from './define';
3
3
 
4
4
  interface Props extends Record<string, unknown> {
5
5
  /** `horizontal` (default, block + full-width) or `vertical` (a rule inside a
6
- * flex/grid row it stretches to the row height). */
6
+ * flex/grid row, stretching to the row height). */
7
7
  orientation?: 'horizontal' | 'vertical';
8
8
  }
9
9
 
@@ -27,7 +27,7 @@ export const CHAT_SLOTS: SlotDef[] = [
27
27
  { name: 'header-end', mode: 'inject', doc: 'Trailing header controls.' },
28
28
  { name: 'header', mode: 'replace', part: true, doc: 'Full custom header; replaces the built-in title/model/context bar.' },
29
29
  { name: 'sidebar', mode: 'inject', part: true, doc: 'Left column (your nav / conversation list). Fixed width; use compose-your-own for resizable.' },
30
- { name: 'empty', mode: 'replace', doc: 'Custom zero-state rendered in the message area while the thread is empty. Replaces the empty message list only the composer and any suggestions still render.' },
30
+ { name: 'empty', mode: 'replace', doc: 'Custom zero-state rendered in the message area while the thread is empty. Replaces the empty message list only; the composer and any suggestions still render.' },
31
31
  { name: 'composer', mode: 'replace', doc: 'Full custom composer; you own submit + loading, drive the thread via messages.' },
32
32
  { name: 'composer-actions', mode: 'inject', doc: 'Accessory row above the composer.' },
33
33
  { name: 'footer', mode: 'inject', part: true, doc: 'Row below the composer (disclaimers, token meter).' },
@@ -42,8 +42,8 @@ export const CHAT_SLOTS: SlotDef[] = [
42
42
  * no outer block slot here. (When the input is nested inside `<kai-chat>`'s shadow,
43
43
  * that surrounding hole belongs to `kai-chat` — see `composer-actions`/`footer`.) */
44
44
  export const PROMPT_INPUT_SLOTS: SlotDef[] = [
45
- { name: 'input-top', mode: 'inject', doc: 'Inside the card, above the textarea (e.g. an inline status strip). For content above/below the whole card, use your own layout that is light DOM you control.' },
46
- { name: 'toolbar-start', mode: 'inject', doc: 'Leading controls in the input toolbar where a + menu goes.' },
45
+ { name: 'input-top', mode: 'inject', doc: 'Inside the card, above the textarea (e.g. an inline status strip). For content above/below the whole card, use your own layout; that is light DOM you control.' },
46
+ { name: 'toolbar-start', mode: 'inject', doc: 'Leading controls in the input toolbar, where a + menu goes.' },
47
47
  { name: 'toolbar-end', mode: 'inject', doc: 'Trailing controls in the toolbar, before the Send button.' },
48
48
  ];
49
49
 
@@ -52,7 +52,7 @@ export const PROMPT_INPUT_SLOTS: SlotDef[] = [
52
52
  export const CONVERSATIONS_SLOTS: SlotDef[] = [
53
53
  { name: 'header', mode: 'replace', doc: 'Full custom title bar; replaces the built-in toggle / "Chats" / New-chat row.' },
54
54
  { name: 'empty', mode: 'replace', doc: 'Custom zero-state shown when there are no conversations; replaces the built-in "No conversations yet".' },
55
- { name: 'footer', mode: 'inject', doc: 'A row below the list account, settings, or usage.' },
55
+ { name: 'footer', mode: 'inject', doc: 'A row below the list: account, settings, or usage.' },
56
56
  ];
57
57
 
58
58
  /** Styleable `::part`s of `<kai-conversations>`. */
@@ -69,15 +69,15 @@ export const CONVERSATIONS_PARTS: PartDef[] = [
69
69
  * REPLACES the built-in avatar rail (pair it with `avatar="none"` to omit the
70
70
  * rail entirely). These are the keystone of compose-your-own message lists. */
71
71
  export const MESSAGE_SLOTS: SlotDef[] = [
72
- { name: 'before-body', mode: 'inject', doc: 'A per-message header at the TOP of the body, above reasoning/tools/content a model-name label, a role + timestamp line.' },
73
- { name: 'after-body', mode: 'inject', doc: 'A row at the BOTTOM of the body, below the action bar a citation/sources row, a token-cost/latency line.' },
72
+ { name: 'before-body', mode: 'inject', doc: 'A per-message header at the TOP of the body, above reasoning/tools/content: a model-name label, a role + timestamp line.' },
73
+ { name: 'after-body', mode: 'inject', doc: 'A row at the BOTTOM of the body, below the action bar: a citation/sources row, a token-cost/latency line.' },
74
74
  { name: 'avatar', mode: 'replace', part: true, doc: 'Replaces the built-in avatar rail with your own node. Use `avatar="none"` to omit the rail and let the body span the full row.' },
75
75
  ];
76
76
 
77
77
  /** Slots of `<kai-notice>`. The message is the default slot; these are the named seams. */
78
78
  export const NOTICE_SLOTS: SlotDef[] = [
79
- { name: 'action', mode: 'inject', doc: 'A trailing action beside the message a link or button.' },
80
- { name: 'icon', mode: 'replace', doc: 'A custom leading icon (any inline SVG, inherits `currentColor`). Overrides the severity default and the `icon` prop the same escape hatch as `kai-button`.' },
79
+ { name: 'action', mode: 'inject', doc: 'A trailing action beside the message: a link or button.' },
80
+ { name: 'icon', mode: 'replace', doc: 'A custom leading icon (any inline SVG, inherits `currentColor`). Overrides the severity default and the `icon` prop, the same escape hatch as `kai-button`.' },
81
81
  ];
82
82
 
83
83
  /** Slots of `<kai-button>` (the label is the default slot). */
@@ -124,7 +124,7 @@ export const CHAT_PARTS: PartDef[] = [
124
124
  export const PROMPT_INPUT_PARTS: PartDef[] = [
125
125
  {
126
126
  name: 'send',
127
- doc: 'The send button. Restyle from outside, or hide it entirely (Enter-only) hiding is pure CSS, which is why there is no `submit="never"`.',
127
+ doc: 'The send button. Restyle from outside, or hide it entirely (Enter-only). Hiding is pure CSS, which is why there is no `submit="never"`.',
128
128
  recipe: 'kai-prompt-input::part(send) { display: none } /* Enter-only; or restyle: background, border-radius, … */',
129
129
  },
130
130
  ];
@@ -206,13 +206,18 @@ export const MESSAGE_PARTS: PartDef[] = [
206
206
  doc: 'The action-bar row (copy / like / regenerate …). Restyle its spacing or hide it entirely from outside.',
207
207
  recipe: 'kai-message::part(actions) { gap: 0.25rem }',
208
208
  },
209
+ {
210
+ name: 'citations',
211
+ doc: 'The citation row rendered from the message’s `source` parts: a wrapped row of chips below the bubble, never inside it. Restyle its spacing or hide it entirely from outside.',
212
+ recipe: 'kai-message::part(citations) { gap: 0.5rem }',
213
+ },
209
214
  ];
210
215
 
211
216
  /** Styleable `::part`s of `<kai-attachments>`. */
212
217
  export const ATTACHMENTS_PARTS: PartDef[] = [
213
218
  {
214
219
  name: 'preview',
215
- doc: 'The image shown in an attachment’s hover-card preview. Bounded by default (max ~320×256, aspect preserved) so a large image never blows up the card raise or lower the cap from outside.',
220
+ doc: 'The image shown in an attachment’s hover-card preview. Bounded by default (max ~320×256, aspect preserved) so a large image never blows up the card. Raise or lower the cap from outside.',
216
221
  recipe: 'kai-attachments::part(preview) { max-width: 32rem; max-height: 24rem }',
217
222
  },
218
223
  ];
@@ -434,6 +439,17 @@ export const FILE_TREE_PARTS: PartDef[] = [
434
439
  export interface ElementComposition {
435
440
  slots?: SlotDef[];
436
441
  parts?: PartDef[];
442
+ /**
443
+ * What the element's DEFAULT (unnamed) `<slot>` projects — i.e. what a consumer
444
+ * puts between the tags. Kept OUT of `slots` on purpose: those arrays are also
445
+ * read at runtime by `readSlots()`, which would query a meaningless `[slot=""]`.
446
+ * scripts/gen-element-api.mjs merges it back in as a slot with the empty name,
447
+ * which is how the Custom Elements Manifest spells the default slot.
448
+ *
449
+ * Every facade that renders a bare `<slot />` needs one; guarded by
450
+ * tests/elements/slot-registry-coverage.test.ts.
451
+ */
452
+ children?: string;
437
453
  }
438
454
 
439
455
  /** Slots + styleable `::part`s of `<kai-prompt-dock>`. */
@@ -558,6 +574,17 @@ export const THREAD_SLOTS: SlotDef[] = [
558
574
  { name: 'empty', mode: 'replace', doc: 'Custom zero-state rendered in the message area while the thread is empty; replaces the built-in default.' },
559
575
  ];
560
576
 
577
+ /** Slots of `<kai-empty>`. The body is the default slot; `media` is the named seam. */
578
+ export const EMPTY_SLOTS: SlotDef[] = [
579
+ { name: 'media', mode: 'replace', doc: 'The leading illustration or icon above the title (any inline SVG or <img>). Replaces the built-in media box.' },
580
+ ];
581
+
582
+ /** Slots of `<kai-popover>`. The panel body is the default slot; `trigger` is the
583
+ * control the panel anchors to and opens from. */
584
+ export const POPOVER_SLOTS: SlotDef[] = [
585
+ { name: 'trigger', mode: 'replace', doc: 'The control that opens the popover (a button, an avatar, …). The panel anchors to it.' },
586
+ ];
587
+
561
588
  /** Styleable `::part`s of `<kai-audio-visualizer>`. Every DOM variant (`bar`,
562
589
  * `grid`, `radial`) shares the `bar`/`cell` markup pattern; the shader variants
563
590
  * (`wave`, `aurora`) share the `canvas` part. Lit items ALSO carry the
@@ -599,38 +626,44 @@ export const ELEMENT_COMPOSITION: Record<string, ElementComposition> = {
599
626
  'kai-message': { slots: MESSAGE_SLOTS, parts: MESSAGE_PARTS },
600
627
  'kai-thread': { slots: THREAD_SLOTS },
601
628
  'kai-prompt-input': { slots: PROMPT_INPUT_SLOTS, parts: PROMPT_INPUT_PARTS },
602
- 'kai-button': { slots: BUTTON_SLOTS, parts: BUTTON_PARTS },
603
- 'kai-badge': { parts: BADGE_PARTS },
629
+ 'kai-button': { slots: BUTTON_SLOTS, parts: BUTTON_PARTS, children: 'The button\'s label. Omit it for an icon-only button (pair with `aria-label`).' },
630
+ 'kai-badge': { parts: BADGE_PARTS, children: 'The badge\'s label: text, or a small inline icon plus text.' },
604
631
  'kai-icon': { parts: ICON_PARTS },
605
632
  'kai-separator': { parts: SEPARATOR_PARTS },
606
- 'kai-scroll-area': { parts: SCROLL_AREA_PARTS },
607
- 'kai-notice': { slots: NOTICE_SLOTS },
608
- 'kai-hover-card': { slots: HOVER_CARD_SLOTS },
633
+ 'kai-scroll-area': { parts: SCROLL_AREA_PARTS, children: 'The scrollable content.' },
634
+ 'kai-notice': { slots: NOTICE_SLOTS, children: 'The notice message. `icon` and `action` are the named seams around it.' },
635
+ 'kai-hover-card': { slots: HOVER_CARD_SLOTS, children: 'The TRIGGER the card hovers off. The card body is the `card` slot.' },
609
636
  'kai-menu': { slots: MENU_SLOTS, parts: MENU_PARTS },
610
637
  'kai-skeleton': { parts: SKELETON_PARTS },
611
638
  'kai-attachments': { parts: ATTACHMENTS_PARTS },
612
639
  'kai-status': { parts: STATUS_PARTS },
613
640
  'kai-tabs': { parts: TABS_PARTS },
614
641
  'kai-voice-output': { parts: VOICE_OUTPUT_PARTS },
615
- 'kai-screen': { slots: SCREEN_SLOTS, parts: SCREEN_PARTS },
616
- 'kai-card': { slots: CARD_SLOTS, parts: CARD_PARTS },
642
+ 'kai-screen': { slots: SCREEN_SLOTS, parts: SCREEN_PARTS, children: 'The screen body, below the title bar.' },
643
+ 'kai-card': { slots: CARD_SLOTS, parts: CARD_PARTS, children: 'The card body, below the header/media regions.' },
617
644
  'kai-workspace': { slots: WORKSPACE_SLOTS, parts: WORKSPACE_PARTS },
618
645
  'kai-nav': { parts: NAV_PARTS },
619
- 'kai-coachmark': { slots: COACHMARK_SLOTS, parts: COACHMARK_PARTS },
646
+ 'kai-coachmark': { slots: COACHMARK_SLOTS, parts: COACHMARK_PARTS, children: 'The ANCHOR the coachmark points at: the element it attaches to and positions against. The bubble body is the `content` slot.' },
620
647
  'kai-progress-bar': { parts: PROGRESS_BAR_PARTS },
621
648
  'kai-file-tree': { parts: FILE_TREE_PARTS },
622
- 'kai-prompt-dock': { slots: PROMPT_DOCK_SLOTS, parts: PROMPT_DOCK_PARTS },
649
+ 'kai-prompt-dock': { slots: PROMPT_DOCK_SLOTS, parts: PROMPT_DOCK_PARTS, children: 'The input the dock wraps, typically a `<kai-prompt-input>`. The `top`/`bottom` slots are the lips around it.' },
623
650
  'kai-segmented': { parts: SEGMENTED_PARTS },
624
- 'kai-settings-group': { parts: SETTINGS_GROUP_PARTS },
651
+ 'kai-settings-group': { parts: SETTINGS_GROUP_PARTS, children: 'The `<kai-setting-item>` rows in this group.' },
625
652
  'kai-setting-item': { slots: SETTING_ITEM_SLOTS, parts: SETTING_ITEM_PARTS },
626
- 'kai-pane': { slots: PANE_SLOTS, parts: PANE_PARTS },
627
- 'kai-pane-group': { parts: PANE_GROUP_PARTS },
653
+ 'kai-pane': { slots: PANE_SLOTS, parts: PANE_PARTS, children: 'The pane body, below the header row.' },
654
+ 'kai-pane-group': { parts: PANE_GROUP_PARTS, children: 'Content shown for every tab. Use it INSTEAD of the per-tab `slot="<tab id>"` seams when you swap the content yourself.' },
628
655
  'kai-agent-card': { parts: AGENT_CARD_PARTS },
629
- 'kai-dialog': { slots: DIALOG_SLOTS, parts: DIALOG_PARTS },
656
+ 'kai-dialog': { slots: DIALOG_SLOTS, parts: DIALOG_PARTS, children: 'The dialog body, between the `header` and `footer` slots.' },
630
657
  'kai-input': { slots: INPUT_SLOTS, parts: INPUT_PARTS },
631
658
  'kai-search': { parts: SEARCH_PARTS },
632
- 'kai-kbd': { parts: KBD_PARTS },
659
+ 'kai-kbd': { parts: KBD_PARTS, children: 'Literal key text, when you are not using the `keys` prop to render key caps.' },
633
660
  'kai-editable-label': { parts: EDITABLE_LABEL_PARTS },
661
+ 'kai-empty': { slots: EMPTY_SLOTS, children: 'The empty-state body below the title/description, usually the call to action.' },
662
+ 'kai-file-upload': { children: 'Custom dropzone content, replacing the default label (the `label` prop is the fallback).' },
663
+ 'kai-popover': { slots: POPOVER_SLOTS, children: 'The popover panel body. The control that opens it is the `trigger` slot.' },
664
+ 'kai-resizable': { children: 'The `<kai-resizable-item>` panels, in order. Dividers are inserted between them.' },
665
+ 'kai-resizable-item': { children: 'This panel\'s content.' },
666
+ 'kai-tooltip': { children: 'The TRIGGER the tooltip describes. The tip text is the `text` prop.' },
634
667
  'kai-audio-visualizer': { parts: AUDIO_VISUALIZER_PARTS },
635
668
  };
636
669
 
@@ -1,6 +1,9 @@
1
1
  import { createSignal, For, onCleanup, onMount, Show } from 'solid-js';
2
2
  import { defineWebComponent } from './define';
3
3
  import { Source, SourceTrigger, SourceContent, SourceList } from '../components/source';
4
+ // Public shape of the `sources` prop; lives in ./element-data-types so the ROOT
5
+ // entry can re-export it (see that file's header).
6
+ import type { KaiSourceItem } from './element-data-types';
4
7
 
5
8
  // --- <kai-source> — a single citation link with hover preview ---
6
9
 
@@ -9,8 +12,9 @@ interface SourceProps extends Record<string, unknown> {
9
12
  href?: string;
10
13
  /** Trigger label (defaults to the domain). */
11
14
  label?: string;
12
- /** Hover-card headline. Attribute: `headline` (`title` is avoided it's a
13
- * global HTML attribute that reflects in a CE constructor and breaks it). */
15
+ /** Hover-card headline. Attribute: `headline` (`title` is avoided because it
16
+ * is a global HTML attribute that reflects in a CE constructor and breaks
17
+ * it). */
14
18
  headline?: string;
15
19
  /** Hover-card body text describing the source. */
16
20
  description?: string;
@@ -42,17 +46,12 @@ defineWebComponent<SourceProps>('kai-source', {
42
46
 
43
47
  // --- <kai-sources> — a wrapped list of citation links ---
44
48
 
45
- interface SourceItem {
46
- href: string;
47
- title?: string;
48
- description?: string;
49
- label?: string;
50
- showFavicon?: boolean;
51
- }
52
49
 
53
50
  interface SourceListProps extends Record<string, unknown> {
54
- /** The sources to render. Set as a JS property. */
55
- sources: SourceItem[];
51
+ /** The sources to render. Set as a JS property. Omit to supply them as
52
+ * `<kai-source>` light-DOM children instead; when both are present the
53
+ * property's sources come first. */
54
+ sources?: KaiSourceItem[];
56
55
  /** Show favicons on all items (per-item `showFavicon` overrides). */
57
56
  showFavicon?: boolean;
58
57
  /**
@@ -60,22 +59,22 @@ interface SourceListProps extends Record<string, unknown> {
60
59
  * merged (prop + declarative-children) list (`[1]`, `[2]`, …) instead of the
61
60
  * per-item `label` or domain fallback.
62
61
  *
63
- * HTML attribute: `numbered` (boolean bare attribute or `numbered="true"`).
64
- * JS property: `el.numbered = true`.
62
+ * HTML attribute: `numbered` (boolean: a bare attribute or
63
+ * `numbered="true"`). JS property: `el.numbered = true`.
65
64
  */
66
65
  numbered?: boolean;
67
66
  }
68
67
 
69
- /** Parse a single light-DOM `<kai-source>` element into a `SourceItem` descriptor.
68
+ /** Parse a single light-DOM `<kai-source>` element into a `KaiSourceItem` descriptor.
70
69
  * Attribute mapping:
71
- * - `href` → SourceItem.href
72
- * - `label` → SourceItem.label
73
- * - `headline` → SourceItem.title (matches kai-source's prop name; "title" is a
70
+ * - `href` → KaiSourceItem.href
71
+ * - `label` → KaiSourceItem.label
72
+ * - `headline` → KaiSourceItem.title (matches kai-source's prop name; "title" is a
74
73
  * reserved HTMLElement attribute so kai-source uses "headline")
75
- * - `description` → SourceItem.description
76
- * - `show-favicon`→ SourceItem.showFavicon (bare boolean attribute)
74
+ * - `description` → KaiSourceItem.description
75
+ * - `show-favicon`→ KaiSourceItem.showFavicon (bare boolean attribute)
77
76
  */
78
- export function parseKaiSourceElement(n: Element): SourceItem {
77
+ export function parseKaiSourceElement(n: Element): KaiSourceItem {
79
78
  return {
80
79
  href: n.getAttribute('href') ?? '',
81
80
  label: n.getAttribute('label') ?? undefined,
@@ -92,7 +91,7 @@ defineWebComponent<SourceListProps>('kai-sources', {
92
91
  }, (props, { element, flag }) => {
93
92
  // Read declarative <kai-source> children from light DOM.
94
93
  // The shadow root has no <slot> for them, so they are invisible — pure data carriers.
95
- const [slottedSources, setSlottedSources] = createSignal<SourceItem[]>([]);
94
+ const [slottedSources, setSlottedSources] = createSignal<KaiSourceItem[]>([]);
96
95
  onMount(() => {
97
96
  const read = () => {
98
97
  const nodes = [...element.querySelectorAll('kai-source')];
@@ -105,7 +104,7 @@ defineWebComponent<SourceListProps>('kai-sources', {
105
104
  });
106
105
 
107
106
  // Prop sources take precedence; slotted children are appended after.
108
- const allSources = () => [...props.sources, ...slottedSources()];
107
+ const allSources = () => [...(props.sources ?? []), ...slottedSources()];
109
108
 
110
109
  const isNumbered = () => flag('numbered');
111
110
 
@@ -3,9 +3,9 @@ import { defineWebComponent } from './define';
3
3
  import { Switch } from '../ui/switch';
4
4
 
5
5
  interface Props extends Record<string, unknown> {
6
- /** Controlled checked state settable and reflected to the `checked`
7
- * attribute. `el.checked = true` (or `<kai-switch checked>`) drives it; the
8
- * toggle UI updates it and fires `kai-change`. Read `el.checked` for live state. */
6
+ /** Controlled checked state. Settable and reflected to the `checked` attribute.
7
+ * `el.checked = true` (or `<kai-switch checked>`) drives it; the toggle UI updates
8
+ * it and fires `kai-change`. Read `el.checked` for live state. */
9
9
  checked?: boolean;
10
10
  /** Initial checked state on mount (uncontrolled seed). Bare attribute
11
11
  * (`<kai-switch default-checked>`) turns it on. */
@@ -6,7 +6,7 @@ interface Props extends Record<string, unknown> {
6
6
  /** The tasks definition (the CardEnvelope.data). Set as a JS PROPERTY:
7
7
  * `el.data = { tasks:[…], selectAll, confirmLabel, … }`. Import
8
8
  * `TasksCardData` from `@kitn.ai/ui` for the full shape. */
9
- data?: Record<string, unknown>;
9
+ data?: TasksCardData;
10
10
  /** Stable card id correlating every emitted CardEvent. Attribute: `card-id`. */
11
11
  cardId?: string;
12
12
  /** Heading rendered in the card chrome (= CardEnvelope.title). Attribute: `heading`. */
@@ -29,7 +29,8 @@ interface Props extends Record<string, unknown> {
29
29
  * contract event — `kai-value-change` is the live selection signal, distinct from
30
30
  * the terminal submit.) */
31
31
  interface Events {
32
- /** The selection changed on a toggle the selected ids in input order. */
32
+ /** The selection changed on a toggle. Carries the selected ids in input
33
+ * order. */
33
34
  'kai-value-change': { value: string[] };
34
35
  }
35
36
 
@@ -72,7 +73,7 @@ defineWebComponent<Props, Events>(
72
73
  select: (taskIds?: string[]) => controller?.select(taskIds),
73
74
  /** Toggle one task by id, honoring the max gate (no `checked` = flip). */
74
75
  toggle: (taskId: string, checked?: boolean) => controller?.toggle(taskId, checked),
75
- /** Confirm the current selection emits the `submit` CardEvent + resolves
76
+ /** Confirm the current selection: emits the `submit` CardEvent + resolves
76
77
  * (only when the min/max gate passes). Named `send`, not `submit`. */
77
78
  send: () => controller?.send(),
78
79
  /** Focus the task group (select-all checkbox if shown, else the first row). */
@@ -85,7 +86,7 @@ defineWebComponent<Props, Events>(
85
86
 
86
87
  return (
87
88
  <TasksCard
88
- data={props.data as TasksCardData | undefined}
89
+ data={props.data}
89
90
  cardId={props.cardId ?? (element.id || 'kai-tasks')}
90
91
  heading={props.heading}
91
92
  resolution={props.resolution as CardResolution | undefined}
@@ -2,17 +2,19 @@ import { createSignal, onMount, onCleanup } from 'solid-js';
2
2
  import { defineWebComponent } from './define';
3
3
  import { readSlots, THREAD_SLOTS } from './slots';
4
4
  import { Thread, type ThreadController } from '../components/thread';
5
+ import { cardComponentsFromTags } from './message';
6
+ import { createMessagesGuard } from './validate-messages';
5
7
  import type { ChatMessage } from './chat-types';
6
8
  import type { ProseSize } from '../primitives/chat-config';
7
9
 
8
10
  interface Props extends Record<string, unknown> {
9
11
  /** The full message thread to render, newest last. Each entry carries its role,
10
- * content, and optional reasoning/tools/attachments/actions/avatar. Set as a JS
12
+ * ordered `parts`, and optional actions/avatar/feedback. Set as a JS
11
13
  * property (`el.messages = [...]`); a NEW array reference per streaming chunk
12
14
  * re-renders (mutating in place does not). */
13
15
  messages?: ChatMessage[];
14
- /** Show a typing indicator on the pending assistant turn set while awaiting
15
- * the assistant's reply. */
16
+ /** Show a typing indicator on the pending assistant turn. Set it while
17
+ * awaiting the assistant's reply. */
16
18
  loading?: boolean;
17
19
  /** Body/prose font scale for rendered markdown (`'xs' | 'sm' | 'base' | 'lg'`).
18
20
  * Defaults to `'sm'`. */
@@ -30,6 +32,26 @@ interface Props extends Record<string, unknown> {
30
32
  scrollButton?: boolean;
31
33
  /** Extra classes applied to the thread's inner root. */
32
34
  class?: string;
35
+ /** Optional card type -> custom-element tag overrides/additions for `card`
36
+ * parts (merged over the built-ins). Property: `el.cardTypes`. Typed as a
37
+ * plain string map (not the `CardTagMap` alias) so the generated React
38
+ * wrapper inlines it instead of emitting an unresolved named type. */
39
+ cardTypes?: Record<string, string>;
40
+ /** JSON Schemas for the card types this app renders, keyed by envelope type. The
41
+ * companion of `cardTypes`, which says what DRAWS a card while this says what a
42
+ * VALID one looks like. An OBJECT, so it is a JS property only: `el.cardSchemas
43
+ * = { 'pricing-table': pricingSchema }`, never an attribute.
44
+ * `createCardRegistry(...).validationSchemas` is exactly this shape.
45
+ *
46
+ * Without it the kit validates its own seven built-ins and leaves your own card
47
+ * type, the one your app actually cares about, as the only unchecked thing on
48
+ * screen. A schema here WINS over a built-in of the same name.
49
+ *
50
+ * Typed `Record<string, object>` rather than `Record<string, JsonSchema>`
51
+ * deliberately: an imported `.json` schema widens `"type"` to `string`, and an
52
+ * authored one carries `$schema`/`title`/`description`/`additionalProperties`,
53
+ * so the tighter type would reject both of the normal ways to supply one. */
54
+ cardSchemas?: Record<string, object>;
33
55
  }
34
56
 
35
57
  /** Events fired by `<kai-thread>`. */
@@ -61,9 +83,17 @@ defineWebComponent<Props, Events>('kai-thread', {
61
83
  actionsReveal: 'always',
62
84
  scrollButton: true,
63
85
  class: undefined,
86
+ cardTypes: undefined,
87
+ cardSchemas: undefined,
64
88
  }, (props, { element, dispatch, flag, expose }) => {
65
89
  let controller: ThreadController | undefined;
66
90
 
91
+ // `messages` is an untyped boundary: a consumer can hand it anything at
92
+ // runtime (a pre-0.20.0 `{ id, role, content }` array, in particular). Skip
93
+ // the invalid entries rather than let `groupMessageParts` throw deep inside a
94
+ // render pass, which would blank the whole element instead of one message.
95
+ const validMessages = createMessagesGuard('kai-thread');
96
+
67
97
  // Detect whether the consumer projected `slot="empty"` content, so the built-in
68
98
  // default only renders when they did NOT.
69
99
  const [slots, setSlots] = createSignal<Record<string, boolean>>({});
@@ -89,13 +119,15 @@ defineWebComponent<Props, Events>('kai-thread', {
89
119
  <style>{':host{display:block;height:100%}'}</style>
90
120
  <Thread
91
121
  class={props.class as string | undefined}
92
- messages={(props.messages as ChatMessage[] | undefined) ?? []}
122
+ messages={validMessages(props.messages)}
93
123
  loading={flag('loading')}
94
124
  proseSize={props.proseSize as ProseSize}
95
125
  codeTheme={props.codeTheme as string}
96
126
  codeHighlight={flag('codeHighlight')}
97
127
  actionsReveal={props.actionsReveal as 'always' | 'hover'}
98
128
  scrollButton={props.scrollButton !== false}
129
+ cardTypes={cardComponentsFromTags(props.cardTypes as Record<string, string> | undefined, (props as { theme?: string }).theme)}
130
+ cardSchemas={props.cardSchemas as Record<string, object> | undefined}
99
131
  empty={slots()['empty'] ? <slot name="empty" /> : undefined}
100
132
  onMessageAction={(detail) => dispatch('kai-message-action', detail)}
101
133
  controllerRef={(c) => (controller = c)}
@@ -4,8 +4,9 @@ import { toast as toastStore, type ToastItem } from '../primitives/toast-store';
4
4
 
5
5
  interface Props extends Record<string, unknown> {
6
6
  /** The toasts to render. Newest is shown on top. Set as a JS property (array);
7
- * pass a new array reference to update. */
8
- toasts: ToastItem[];
7
+ * pass a new array reference to update. Omit for an empty region, which is
8
+ * the normal resting state and how the imperative `toast()` API starts. */
9
+ toasts?: ToastItem[];
9
10
  /** Stack anchor: `'top-center'` (default), `'top-right'`, `'bottom-center'`, … */
10
11
  position?: ToastPosition;
11
12
  /** Max simultaneously-visible toasts; the rest queue. Defaults to `3`. */
@@ -13,7 +13,7 @@ interface Props extends Record<string, unknown> {
13
13
  open?: boolean;
14
14
  /** Initial open state on mount (uncontrolled seed). */
15
15
  defaultOpen?: boolean;
16
- /** Gate the disclosure trigger programmatic `show()/hide()/toggle()` still
16
+ /** Gate the disclosure trigger: programmatic `show()/hide()/toggle()` still
17
17
  * work, but the trigger click no longer toggles. */
18
18
  disabled?: boolean;
19
19
  }