@kitn.ai/ui 0.16.0 → 0.17.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 (194) hide show
  1. package/README.md +28 -13
  2. package/dist/components/chat-thread.d.ts +2 -4
  3. package/dist/components/choice-card.d.ts +1 -0
  4. package/dist/components/dismissed-stub.d.ts +22 -0
  5. package/dist/components/message.d.ts +59 -2
  6. package/dist/components/response-compare-types.d.ts +66 -0
  7. package/dist/components/response-compare.d.ts +51 -0
  8. package/dist/components/tasks-card.d.ts +1 -0
  9. package/dist/components/toast.d.ts +48 -0
  10. package/dist/components/use-card-resolution.d.ts +10 -6
  11. package/dist/custom-elements.json +260 -11
  12. package/dist/elements/artifact.js +1 -0
  13. package/dist/elements/attachments.js +1 -0
  14. package/dist/elements/autoloader.d.ts +2 -0
  15. package/dist/elements/autoloader.js +1 -0
  16. package/dist/elements/card.js +1 -0
  17. package/dist/elements/cards.d.ts +1 -0
  18. package/dist/elements/cards.js +1 -0
  19. package/dist/elements/chain-of-thought.d.ts +0 -12
  20. package/dist/elements/chain-of-thought.js +1 -0
  21. package/dist/elements/chat-scope-picker.js +1 -0
  22. package/dist/elements/chat-workspace.js +1 -0
  23. package/dist/elements/chat.js +1 -0
  24. package/dist/elements/checkpoint.js +1 -0
  25. package/dist/elements/choice.js +1 -0
  26. package/dist/elements/chunks/Icon-D_Zmwmwh.js +1 -0
  27. package/dist/elements/chunks/action-icons-PVfIvcuG.js +1 -0
  28. package/dist/elements/chunks/attachments-Dp6vqtrc.js +1 -0
  29. package/dist/elements/chunks/bash-InADTalH.js +1 -0
  30. package/dist/elements/chunks/button-CKyYD9G4.js +1 -0
  31. package/dist/elements/chunks/card-Cjho-PYk.js +1 -0
  32. package/dist/elements/chunks/card-routing-C986KuUA.js +1 -0
  33. package/dist/elements/chunks/chat-thread-RT808iPf.js +1 -0
  34. package/dist/elements/chunks/check-CDYaMYrM.js +1 -0
  35. package/dist/elements/chunks/chevron-down-3SBiq8HF.js +1 -0
  36. package/dist/elements/chunks/chevron-right-k2UFlIVK.js +1 -0
  37. package/dist/elements/chunks/cn-Dogu6PbV.js +1 -0
  38. package/dist/elements/chunks/code-block-BYUmfFSd.js +1 -0
  39. package/dist/elements/chunks/collapsible-BiNwdOn6.js +1 -0
  40. package/dist/elements/chunks/context-18g6oi4J.js +1 -0
  41. package/dist/elements/chunks/conversation-list-D9Y0NVdo.js +1 -0
  42. package/dist/elements/chunks/core-AYMC6_lb.js +12 -0
  43. package/dist/elements/chunks/css-M7EaDHN_.js +1 -0
  44. package/dist/elements/chunks/default-input-CSAoYYMd.js +1 -0
  45. package/dist/elements/chunks/download-D8K0Je8r.js +1 -0
  46. package/dist/elements/chunks/dropdown-bUs2iTia.js +1 -0
  47. package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +141 -0
  48. package/dist/elements/chunks/external-link-6mA0wxab.js +1 -0
  49. package/dist/elements/chunks/file-text-DnaYk3Dm.js +1 -0
  50. package/dist/elements/chunks/file-tree-CgtRLlxK.js +1 -0
  51. package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +1 -0
  52. package/dist/elements/chunks/github-light-JYsPkUQd.js +1 -0
  53. package/dist/elements/chunks/hover-card-CIGw62gP.js +1 -0
  54. package/dist/elements/chunks/html-CPZ3oZQ7.js +1 -0
  55. package/dist/elements/chunks/index-CTBEJeo6.js +1 -0
  56. package/dist/elements/chunks/javascript-C25yR2R2.js +1 -0
  57. package/dist/elements/chunks/json-DxJze_jm.js +1 -0
  58. package/dist/elements/chunks/link-BlGSeoPy.js +1 -0
  59. package/dist/elements/chunks/loader-DvhR4qa0.js +1 -0
  60. package/dist/elements/chunks/markdown-CMTGx9r8.js +64 -0
  61. package/dist/elements/chunks/message-CDZwXjhL.js +1 -0
  62. package/dist/elements/chunks/message-feedback-CYx81QiA.js +1 -0
  63. package/dist/elements/chunks/model-switcher-O_tUhoOT.js +1 -0
  64. package/dist/elements/chunks/overlay-DydXYMQW.js +1 -0
  65. package/dist/elements/chunks/prompt-suggestion-ldlWV5kd.js +1 -0
  66. package/dist/elements/chunks/reasoning-2PUnHlmr.js +1 -0
  67. package/dist/elements/chunks/resizable-B5WNbSeb.js +1 -0
  68. package/dist/elements/chunks/star-t9tI-P0q.js +1 -0
  69. package/dist/elements/chunks/store-C6rIooZz.js +1 -0
  70. package/dist/elements/chunks/svelte--5p79yCD.js +1 -0
  71. package/dist/elements/chunks/text-shimmer-uh9V_KUh.js +1 -0
  72. package/dist/elements/chunks/textarea-3nm6Ia9U.js +1 -0
  73. package/dist/elements/chunks/thumbs-up-BBtguGld.js +1 -0
  74. package/dist/elements/chunks/toast-store-D8cL3fWl.js +1 -0
  75. package/dist/elements/chunks/tool-GJ3vwp1U.js +1 -0
  76. package/dist/elements/chunks/tooltip-DwKAz4XR.js +1 -0
  77. package/dist/elements/chunks/triangle-alert-Ct1zt2JL.js +1 -0
  78. package/dist/elements/chunks/tsx-B8rCNbgL.js +1 -0
  79. package/dist/elements/chunks/typescript-RycA9KXf.js +1 -0
  80. package/dist/elements/chunks/use-card-resolution-D-_0Alzy.js +1 -0
  81. package/dist/elements/chunks/video-mVYiM99-.js +1 -0
  82. package/dist/elements/chunks/vue-BmIZj4XD.js +1 -0
  83. package/dist/elements/chunks/x-CzxL27Ch.js +1 -0
  84. package/dist/elements/code-block.js +1 -0
  85. package/dist/elements/compare.js +1 -0
  86. package/dist/elements/confirm-card.js +1 -0
  87. package/dist/elements/context-meter.js +1 -0
  88. package/dist/elements/conversation-list.d.ts +1 -11
  89. package/dist/elements/conversation-list.js +1 -0
  90. package/dist/elements/embed.js +1 -0
  91. package/dist/elements/empty.js +1 -0
  92. package/dist/elements/feedback-bar.js +1 -0
  93. package/dist/elements/file-tree.js +1 -0
  94. package/dist/elements/file-upload.js +1 -0
  95. package/dist/elements/form.js +1 -0
  96. package/dist/elements/image.js +1 -0
  97. package/dist/elements/link-preview.js +1 -0
  98. package/dist/elements/loader.js +1 -0
  99. package/dist/elements/markdown.js +1 -0
  100. package/dist/elements/message-skills.d.ts +0 -16
  101. package/dist/elements/message-skills.js +1 -0
  102. package/dist/elements/message.js +1 -0
  103. package/dist/elements/model-switcher.d.ts +1 -11
  104. package/dist/elements/model-switcher.js +1 -0
  105. package/dist/elements/popover.js +1 -0
  106. package/dist/elements/prompt-input.d.ts +1 -9
  107. package/dist/elements/prompt-input.js +1 -0
  108. package/dist/elements/prompt-suggestions.d.ts +0 -6
  109. package/dist/elements/prompt-suggestions.js +1 -0
  110. package/dist/elements/reasoning.js +1 -0
  111. package/dist/elements/resizable.d.ts +1 -17
  112. package/dist/elements/resizable.js +1 -0
  113. package/dist/elements/response-stream.js +14 -0
  114. package/dist/elements/scroll-button.js +1 -0
  115. package/dist/elements/source.d.ts +0 -17
  116. package/dist/elements/source.js +1 -0
  117. package/dist/elements/switch.js +1 -0
  118. package/dist/elements/tasks.js +1 -0
  119. package/dist/elements/text-shimmer.js +1 -0
  120. package/dist/elements/thinking-bar.js +1 -0
  121. package/dist/elements/toast.d.ts +1 -0
  122. package/dist/elements/toast.js +1 -0
  123. package/dist/elements/tool.js +1 -0
  124. package/dist/elements/voice-input.js +1 -0
  125. package/dist/elements.d.ts +41 -5
  126. package/dist/index.d.ts +12 -0
  127. package/dist/index.js +11832 -9790
  128. package/dist/kitn-chat.es.js +1 -1
  129. package/dist/llms/llms-full.txt +57 -12
  130. package/dist/llms/llms.txt +3 -3
  131. package/dist/mcp.es.js +157 -1
  132. package/dist/primitives/card-contract.d.ts +20 -4
  133. package/dist/primitives/card-recovery.d.ts +55 -0
  134. package/dist/primitives/message-feedback.d.ts +35 -0
  135. package/dist/primitives/toast-store.d.ts +88 -0
  136. package/dist/react/index.d.ts +83 -3
  137. package/dist/react.js +90 -80
  138. package/dist/register-JyTglR6m.js +1 -0
  139. package/dist/register-impl-C6wlSsts.js +77 -0
  140. package/dist/schemas/choice.schema.json +5 -0
  141. package/dist/schemas/tasks.schema.json +5 -0
  142. package/dist/ui/tooltip.d.ts +1 -0
  143. package/frameworks/react/index.tsx +63 -11
  144. package/llms-full.txt +57 -12
  145. package/llms.txt +3 -3
  146. package/package.json +15 -6
  147. package/src/agent-tooling/mcp/tools/debug.ts +184 -0
  148. package/src/agent-tooling/mcp/tools/scaffold.ts +133 -1
  149. package/src/components/chat-thread.tsx +27 -35
  150. package/src/components/choice-card.tsx +33 -4
  151. package/src/components/component-meta.json +250 -26
  152. package/src/components/confirm-card.tsx +15 -1
  153. package/src/components/dismissed-stub.tsx +80 -0
  154. package/src/components/form.tsx +21 -3
  155. package/src/components/message.tsx +151 -10
  156. package/src/components/response-compare-types.ts +127 -0
  157. package/src/components/response-compare.tsx +431 -0
  158. package/src/components/tasks-card.tsx +33 -3
  159. package/src/components/toast.tsx +398 -0
  160. package/src/components/use-card-resolution.ts +24 -8
  161. package/src/elements/autoloader.ts +89 -0
  162. package/src/elements/chat-types.ts +7 -0
  163. package/src/elements/chat-workspace.tsx +4 -2
  164. package/src/elements/chat.tsx +4 -2
  165. package/src/elements/compare.tsx +88 -0
  166. package/src/elements/compiled.css +1 -1
  167. package/src/elements/element-manifest.json +182 -0
  168. package/src/elements/element-meta.json +191 -68
  169. package/src/elements/element-types.d.ts +41 -5
  170. package/src/elements/framework-usage.json +25 -0
  171. package/src/elements/message.tsx +27 -45
  172. package/src/elements/register-impl.ts +3 -0
  173. package/src/elements/register.ts +9 -0
  174. package/src/elements/remote.tsx +4 -0
  175. package/src/elements/styles.css +19 -0
  176. package/src/elements/toast.tsx +74 -0
  177. package/src/index.ts +30 -0
  178. package/src/primitives/card-contract.ts +14 -5
  179. package/src/primitives/card-recovery.ts +149 -0
  180. package/src/primitives/card-routing.ts +3 -0
  181. package/src/primitives/card-schemas/choice.schema.json +5 -0
  182. package/src/primitives/card-schemas/tasks.schema.json +5 -0
  183. package/src/primitives/message-feedback.ts +123 -0
  184. package/src/primitives/toast-store.ts +235 -0
  185. package/src/ui/tooltip.tsx +8 -2
  186. package/dist/elements/chat-types.d.ts +0 -41
  187. package/dist/elements/css.d.ts +0 -1
  188. package/dist/elements/default-input.d.ts +0 -40
  189. package/dist/elements/define.d.ts +0 -42
  190. package/dist/elements/register-impl.d.ts +0 -0
  191. package/dist/elements/register.d.ts +0 -3
  192. package/dist/register-impl-wCsFPoh9.js +0 -77
  193. package/dist/register-ujhr1nBS.js +0 -1
  194. /package/dist/elements/{remote.d.ts → compare.d.ts} +0 -0
@@ -65,6 +65,11 @@
65
65
  "allowOther": {
66
66
  "description": "Optional free-text escape ('none of these / specify'). `true` appends a final 'Other…' option; an object customizes its `label`/`placeholder`. Selecting it reveals a text input; the shared Submit button then emits `{ kind:'action', action:'__other__', payload:{ text } }`.",
67
67
  "x-kai-control": "allow-other"
68
+ },
69
+ "dismissible": {
70
+ "type": "boolean",
71
+ "default": false,
72
+ "description": "Show a close affordance that emits the `dismiss` verb. The card collapses to a re-openable 'dismissed' stub; the host decides via `onReopen` whether it comes back live or `expired`."
68
73
  }
69
74
  }
70
75
  }
@@ -73,6 +73,11 @@
73
73
  "minimum": 1,
74
74
  "description": "Optional maximum selectable; further toggles are blocked once reached.",
75
75
  "x-kai-select-max": true
76
+ },
77
+ "dismissible": {
78
+ "type": "boolean",
79
+ "default": false,
80
+ "description": "Show a close affordance that emits the `dismiss` verb. The card collapses to a re-openable 'dismissed' stub; the host decides via `onReopen` whether it comes back live or `expired`."
76
81
  }
77
82
  }
78
83
  }
@@ -4,5 +4,6 @@ export interface TooltipProps {
4
4
  children: JSX.Element;
5
5
  class?: string;
6
6
  openDelay?: number;
7
+ dismissOnClick?: boolean;
7
8
  }
8
9
  export declare function Tooltip(props: TooltipProps): JSX.Element;
@@ -100,11 +100,11 @@ export const Card = createWebComponent<CardProps>(
100
100
 
101
101
  export interface CardsProps extends WebComponentProps {
102
102
  /** The stream of card envelopes to render. Set as a JS PROPERTY: `el.cards = [...]`. */
103
- cards?: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } }[];
103
+ 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 } }[];
104
104
  /** 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. */
105
105
  types?: Record<string, string>;
106
106
  /** Optional CardPolicy handling child events. Property: `el.policy`. */
107
- 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; onError?: (cardId: string, message: string) => void; maxSendPromptMode?: "compose" | "send" };
107
+ 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" };
108
108
  }
109
109
 
110
110
  export const Cards = createWebComponent<CardsProps>(
@@ -126,7 +126,7 @@ export const ChainOfThought = createWebComponent<ChainOfThoughtProps>(
126
126
 
127
127
  export interface ChatProps extends WebComponentProps {
128
128
  /** 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 = [...]`). */
129
- 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 } }[];
129
+ 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" }[];
130
130
  /** Controlled value of the input. When set, the host owns the input text and must update it on `kai-value-change`; leave unset for uncontrolled behavior. */
131
131
  value?: string;
132
132
  /** Placeholder text shown in the empty input. */
@@ -171,8 +171,8 @@ export interface ChatProps extends WebComponentProps {
171
171
  slashCompact?: boolean;
172
172
  /** Whether each message's action bar is always visible (`'always'`, default) or only revealed on hover of that message row (`'hover'`). */
173
173
  actionsReveal?: "always" | "hover";
174
- /** An action button on a message was clicked. `action` is the built-in name or custom id. */
175
- onMessageAction?: (event: CustomEvent<{ messageId: string; action: string }>) => void;
174
+ /** 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. */
175
+ onMessageAction?: (event: CustomEvent<{ messageId: string; action: string; state?: undefined | "on" | "off" }>) => void;
176
176
  /** The header model switcher changed. */
177
177
  onModelChange?: (event: CustomEvent<{ modelId: string }>) => void;
178
178
  /** The Search button was clicked. */
@@ -250,6 +250,35 @@ export const CodeBlock = createWebComponent<CodeBlockProps>(
250
250
  { },
251
251
  );
252
252
 
253
+ export interface CompareProps extends WebComponentProps {
254
+ /** The compare definition (prompt + the two candidates). Set as a JS PROPERTY: `el.data = { prompt, candidates: [A, B], collapse? }`. Import `ResponseCompareData` from `@kitn.ai/ui` for the full shape. */
255
+ data?: Record<string, unknown>;
256
+ /** Stable id correlating every emitted event. Attribute: `compare-id`. */
257
+ compareId?: string;
258
+ /** Re-hydrate / control the user's pick. Set as a JS PROPERTY: `el.selection = { chosenId, rejectedIds }`. Renders the collapsed winner. */
259
+ selection?: Record<string, unknown>;
260
+ /** Layout: `'auto'` (default — columns when wide, tabs when narrow, by CONTAINER width) | `'columns'` (side-by-side) | `'tabs'` (pills to switch). Attribute: `layout`. */
261
+ layout?: "auto" | "columns" | "tabs";
262
+ /** Prose/text size for the rendered candidates. Attribute: `prose-size`. */
263
+ proseSize?: "xs" | "sm" | "base" | "lg";
264
+ /** Shiki theme for code blocks in the candidates. Attribute: `code-theme`. */
265
+ codeTheme?: string;
266
+ /** Whether code blocks are syntax-highlighted. Attribute: `code-highlight`. */
267
+ codeHighlight?: boolean;
268
+ /** The user committed a pick. `detail` = `{ chosenId, rejectedIds, at }`. */
269
+ onCompareSelect?: (event: CustomEvent<{ chosenId: string; rejectedIds: string[]; at?: undefined | number }>) => void;
270
+ /** The definition was unusable. */
271
+ onError?: (event: CustomEvent<{ compareId: string; message: string }>) => void;
272
+ /** Both candidates have settled and the pick is live. */
273
+ onReady?: (event: CustomEvent<{ compareId: string }>) => void;
274
+ }
275
+
276
+ export const Compare = createWebComponent<CompareProps>(
277
+ 'kai-compare',
278
+ ["theme","data","compareId","selection","layout","proseSize","codeTheme","codeHighlight"],
279
+ { onCompareSelect: 'kai-compare-select', onError: 'kai-error', onReady: 'kai-ready' },
280
+ );
281
+
253
282
  export interface ConfirmProps extends WebComponentProps {
254
283
  /** 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. */
255
284
  data?: Record<string, unknown>;
@@ -479,7 +508,7 @@ export const Markdown = createWebComponent<MarkdownProps>(
479
508
 
480
509
  export interface MessageProps extends WebComponentProps {
481
510
  /** The full message object. Set as a JS property. */
482
- 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 } };
511
+ 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" };
483
512
  /** Convenience for simple cases when not passing a `message` object. */
484
513
  role?: "user" | "assistant";
485
514
  /** Convenience content (used when `message` is not set). */
@@ -498,8 +527,8 @@ export interface MessageProps extends WebComponentProps {
498
527
  avatarSrc?: string;
499
528
  /** Convenience avatar fallback text (used when `message.avatar` is not set). */
500
529
  avatarFallback?: string;
501
- /** An action button was clicked. `action` is the built-in name or custom id. */
502
- onMessageAction?: (event: CustomEvent<{ messageId: string; action: string }>) => void;
530
+ /** 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. */
531
+ onMessageAction?: (event: CustomEvent<{ messageId: string; action: string; state?: undefined | "on" | "off" }>) => void;
503
532
  }
504
533
 
505
534
  export const Message = createWebComponent<MessageProps>(
@@ -854,6 +883,29 @@ export const ThinkingBar = createWebComponent<ThinkingBarProps>(
854
883
  { onStop: 'kai-stop' },
855
884
  );
856
885
 
886
+ export interface ToastRegionProps extends WebComponentProps {
887
+ /** The toasts to render. Newest is shown on top. Set as a JS property (array); pass a new array reference to update. */
888
+ toasts: { id: string; message: string; variant?: undefined | "neutral" | "success"; action?: undefined | { label: string; onAction: () => void | false }; duration?: undefined | number; dismissible?: undefined | boolean; target?: undefined | HTMLElement }[];
889
+ /** Stack anchor: `'top-center'` (default), `'top-right'`, `'bottom-center'`, … */
890
+ position?: "top-center" | "top-right" | "top-left" | "bottom-center" | "bottom-right" | "bottom-left";
891
+ /** Max simultaneously-visible toasts; the rest queue. Defaults to `3`. */
892
+ max?: number;
893
+ /** Stacking: 'expanded' (default, full column) | 'collapsed' (Sonner-style pile that expands on hover/focus). Attribute: stack. */
894
+ stack?: "expanded" | "collapsed";
895
+ /** Container element to anchor this region to (JS property). Set by the store for a scoped region; unset = the global viewport region. */
896
+ target?: HTMLElement;
897
+ /** A toast's action button was pressed. */
898
+ onAction?: (event: CustomEvent<{ id: string; label: string }>) => void;
899
+ /** A toast left the stack. `reason` is `'timeout' | 'close' | 'action'`. */
900
+ onDismiss?: (event: CustomEvent<{ id: string; reason: "action" | "timeout" | "close" }>) => void;
901
+ }
902
+
903
+ export const ToastRegion = createWebComponent<ToastRegionProps>(
904
+ 'kai-toast-region',
905
+ ["theme","toasts","position","max","stack","target"],
906
+ { onAction: 'kai-action', onDismiss: 'kai-dismiss' },
907
+ );
908
+
857
909
  export interface ToolProps extends WebComponentProps {
858
910
  /** The tool-call to display. Set as a JS property. */
859
911
  tool?: { type: string; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; output?: Record<string, unknown>; toolCallId?: string; errorText?: string };
@@ -892,7 +944,7 @@ export interface WorkspaceProps extends WebComponentProps {
892
944
  /** Id of the open conversation, highlighted in the sidebar. */
893
945
  activeId?: string;
894
946
  /** The active conversation's message thread, newest last. Set as a JS property. */
895
- 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 } }[];
947
+ 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" }[];
896
948
  value?: string;
897
949
  placeholder?: string;
898
950
  loading?: boolean;
@@ -923,8 +975,8 @@ export interface WorkspaceProps extends WebComponentProps {
923
975
  defaultSidebarCollapsed?: boolean;
924
976
  /** A conversation was selected in the sidebar. */
925
977
  onConversationSelect?: (event: CustomEvent<{ id: string }>) => void;
926
- /** An action button on a message was clicked. */
927
- onMessageAction?: (event: CustomEvent<{ messageId: string; action: string }>) => void;
978
+ /** 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. */
979
+ onMessageAction?: (event: CustomEvent<{ messageId: string; action: string; state?: undefined | "on" | "off" }>) => void;
928
980
  /** The header model switcher changed. */
929
981
  onModelChange?: (event: CustomEvent<{ modelId: string }>) => void;
930
982
  /** The "New chat" button was clicked. */
package/llms-full.txt CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # @kitn.ai/ui
5
5
 
6
- > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 44 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
6
+ > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 46 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
7
7
 
8
8
  ## Install
9
9
 
@@ -37,7 +37,7 @@ Drop an element into any framework (React, Vue, plain HTML). Data in via JS prop
37
37
  - `<kai-prompt-input>` — standalone composer with send button.
38
38
 
39
39
  **Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
40
- All 44 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
40
+ All 46 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
41
41
 
42
42
  ## Key rules for the web components
43
43
 
@@ -99,7 +99,7 @@ For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
99
99
 
100
100
  ## Docs
101
101
 
102
- - Full element reference (all 44 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
102
+ - Full element reference (all 46 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
103
103
  - Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
104
104
  - Working examples: https://github.com/kitn-ai/ui/tree/main/examples
105
105
  - Storybook: https://storybook.kitn.dev
@@ -173,7 +173,7 @@ The same rule applies to every array/object property (`models`, `context`, `sugg
173
173
 
174
174
  ---
175
175
 
176
- ## Element reference (44 elements, generated from custom-elements.json)
176
+ ## Element reference (46 elements, generated from custom-elements.json)
177
177
 
178
178
  Every element also accepts the `theme` attribute. Array/object properties are marked with a `—` attribute: they must be set as JS properties.
179
179
 
@@ -253,9 +253,9 @@ _No events._
253
253
 
254
254
  | Property | Attribute | Type | Description |
255
255
  |---|---|---|---|
256
- | `cards` | — | `undefined \| { type: string; id: string; data: unknown; title?: undefined \| string; resolution?: undefined \| { kind: "action"; action: string; payload?: unknown; at?: undefined \| string } \| { kind: "submit"; data: unknown; at?: undefined \| string } }[]` | The stream of card envelopes to render. Set as a JS PROPERTY: `el.cards = [...]`. |
256
+ | `cards` | — | `undefined \| { type: string; id: string; data: unknown; title?: undefined \| string; resolution?: undefined \| { 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 } }[]` | The stream of card envelopes to render. Set as a JS PROPERTY: `el.cards = [...]`. |
257
257
  | `types` | — | `undefined \| Record<string, string>` | 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. |
258
- | `policy` | — | `undefined \| { onSubmit?: undefined \| (cardId: string, data: unknown) => void; onAction?: undefined \| (cardId: string, action: string, payload?: unknown) => void; onSendPrompt?: undefined \| (text: string, opts: { mode: "compose" \| "send"; context?: unknown; }) => void; onOpen?: undefined \| (url: string, target: "tab" \| "artifact") => void; onState?: undefined \| (cardId: string, patch: unknown) => void; onDismiss?: undefined \| (cardId: string) => void; onError?: undefined \| (cardId: string, message: string) => void; maxSendPromptMode?: undefined \| "compose" \| "send" }` | Optional CardPolicy handling child events. Property: `el.policy`. |
258
+ | `policy` | — | `undefined \| { onSubmit?: undefined \| (cardId: string, data: unknown) => void; onAction?: undefined \| (cardId: string, action: string, payload?: unknown) => void; onSendPrompt?: undefined \| (text: string, opts: { mode: "compose" \| "send"; context?: unknown; }) => void; onOpen?: undefined \| (url: string, target: "tab" \| "artifact") => void; onState?: undefined \| (cardId: string, patch: unknown) => void; onDismiss?: undefined \| (cardId: string) => void; onReopen?: undefined \| (cardId: string) => void; onError?: undefined \| (cardId: string, message: string) => void; maxSendPromptMode?: undefined \| "compose" \| "send" }` | Optional CardPolicy handling child events. Property: `el.policy`. |
259
259
 
260
260
  _No events._
261
261
 
@@ -279,7 +279,7 @@ _No events._
279
279
 
280
280
  | Property | Attribute | Type | Description |
281
281
  |---|---|---|---|
282
- | `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 } }[]` | 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 = [...]`). |
282
+ | `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" }[]` | 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 = [...]`). |
283
283
  | `value` | `value` | `undefined \| string` | Controlled value of the input. When set, the host owns the input text and must update it on `kai-value-change`; leave unset for uncontrolled behavior. |
284
284
  | `placeholder` | `placeholder` | `undefined \| string` | Placeholder text shown in the empty input. |
285
285
  | `loading` | `loading` | `undefined \| false \| true` | When true, shows the loading/streaming state and disables submit (use while awaiting the assistant's reply). |
@@ -307,7 +307,7 @@ _No events._
307
307
 
308
308
  | Event | `detail` type | Description |
309
309
  |---|---|---|
310
- | `kai-message-action` | `CustomEvent<{ messageId: string; action: string }>` | An action button on a message was clicked. `action` is the built-in name or custom id. |
310
+ | `kai-message-action` | `CustomEvent<{ messageId: string; action: string; state?: undefined \| "on" \| "off" }>` | 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. |
311
311
  | `kai-model-change` | `CustomEvent<{ modelId: string }>` | The header model switcher changed. |
312
312
  | `kai-search` | `CustomEvent<Record<string, never>>` | The Search button was clicked. |
313
313
  | `kai-slash-select` | `CustomEvent<{ command: { id: string; label: string; description?: undefined \| string; category?: undefined \| string } }>` | A slash command was chosen from the palette. |
@@ -368,6 +368,30 @@ _No events._
368
368
 
369
369
  ---
370
370
 
371
+ ### `kai-compare` / `Compare`
372
+
373
+ **Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
374
+
375
+ | Property | Attribute | Type | Description |
376
+ |---|---|---|---|
377
+ | `data` | — | `undefined \| Record<string, unknown>` | The compare definition (prompt + the two candidates). Set as a JS PROPERTY: `el.data = { prompt, candidates: [A, B], collapse? }`. Import `ResponseCompareData` from `@kitn.ai/ui` for the full shape. |
378
+ | `compareId` | `compare-id` | `undefined \| string` | Stable id correlating every emitted event. Attribute: `compare-id`. |
379
+ | `selection` | — | `undefined \| Record<string, unknown>` | Re-hydrate / control the user's pick. Set as a JS PROPERTY: `el.selection = { chosenId, rejectedIds }`. Renders the collapsed winner. |
380
+ | `layout` | `layout` | `undefined \| "auto" \| "columns" \| "tabs"` | Layout: `'auto'` (default — columns when wide, tabs when narrow, by CONTAINER width) \| `'columns'` (side-by-side) \| `'tabs'` (pills to switch). Attribute: `layout`. |
381
+ | `proseSize` | `prose-size` | `undefined \| "xs" \| "sm" \| "base" \| "lg"` | Prose/text size for the rendered candidates. Attribute: `prose-size`. |
382
+ | `codeTheme` | `code-theme` | `undefined \| string` | Shiki theme for code blocks in the candidates. Attribute: `code-theme`. |
383
+ | `codeHighlight` | `code-highlight` | `undefined \| false \| true` | Whether code blocks are syntax-highlighted. Attribute: `code-highlight`. |
384
+
385
+ **Events** (non-bubbling `CustomEvent`s — listen directly on the element):
386
+
387
+ | Event | `detail` type | Description |
388
+ |---|---|---|
389
+ | `kai-compare-select` | `CustomEvent<{ chosenId: string; rejectedIds: string[]; at?: undefined \| number }>` | The user committed a pick. `detail` = `{ chosenId, rejectedIds, at }`. |
390
+ | `kai-error` | `CustomEvent<{ compareId: string; message: string }>` | The definition was unusable. |
391
+ | `kai-ready` | `CustomEvent<{ compareId: string }>` | Both candidates have settled and the pick is live. |
392
+
393
+ ---
394
+
371
395
  ### `kai-confirm` / `Confirm`
372
396
 
373
397
  **Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
@@ -587,7 +611,7 @@ _No events._
587
611
 
588
612
  | Property | Attribute | Type | Description |
589
613
  |---|---|---|---|
590
- | `message` | — | `undefined \| { 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 } }` | The full message object. Set as a JS property. |
614
+ | `message` | — | `undefined \| { 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" }` | The full message object. Set as a JS property. |
591
615
  | `role` | `role` | `undefined \| "user" \| "assistant"` | Convenience for simple cases when not passing a `message` object. |
592
616
  | `content` | `content` | `undefined \| string` | Convenience content (used when `message` is not set). |
593
617
  | `markdown` | `markdown` | `undefined \| false \| true` | Force markdown on/off. Defaults to on for assistant, off for user. |
@@ -602,7 +626,7 @@ _No events._
602
626
 
603
627
  | Event | `detail` type | Description |
604
628
  |---|---|---|
605
- | `kai-message-action` | `CustomEvent<{ messageId: string; action: string }>` | An action button was clicked. `action` is the built-in name or custom id. |
629
+ | `kai-message-action` | `CustomEvent<{ messageId: string; action: string; state?: undefined \| "on" \| "off" }>` | 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. |
606
630
 
607
631
  ---
608
632
 
@@ -933,6 +957,27 @@ _No events._
933
957
 
934
958
  ---
935
959
 
960
+ ### `kai-toast-region` / `ToastRegion`
961
+
962
+ **Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
963
+
964
+ | Property | Attribute | Type | Description |
965
+ |---|---|---|---|
966
+ | `toasts` | — | `{ id: string; message: string; variant?: undefined \| "neutral" \| "success"; action?: undefined \| { label: string; onAction: () => void \| false }; duration?: undefined \| number; dismissible?: undefined \| false \| true; target?: undefined \| HTMLElement }[]` | The toasts to render. Newest is shown on top. Set as a JS property (array); pass a new array reference to update. |
967
+ | `position` | `position` | `undefined \| "top-center" \| "top-right" \| "top-left" \| "bottom-center" \| "bottom-right" \| "bottom-left"` | Stack anchor: `'top-center'` (default), `'top-right'`, `'bottom-center'`, … |
968
+ | `max` | `max` | `undefined \| number` | Max simultaneously-visible toasts; the rest queue. Defaults to `3`. |
969
+ | `stack` | `stack` | `undefined \| "expanded" \| "collapsed"` | Stacking: 'expanded' (default, full column) \| 'collapsed' (Sonner-style pile that expands on hover/focus). Attribute: stack. |
970
+ | `target` | — | `undefined \| HTMLElement` | Container element to anchor this region to (JS property). Set by the store for a scoped region; unset = the global viewport region. |
971
+
972
+ **Events** (non-bubbling `CustomEvent`s — listen directly on the element):
973
+
974
+ | Event | `detail` type | Description |
975
+ |---|---|---|
976
+ | `kai-action` | `CustomEvent<{ id: string; label: string }>` | A toast's action button was pressed. |
977
+ | `kai-dismiss` | `CustomEvent<{ id: string; reason: "action" \| "timeout" \| "close" }>` | A toast left the stack. `reason` is `'timeout' \| 'close' \| 'action'`. |
978
+
979
+ ---
980
+
936
981
  ### `kai-tool` / `Tool`
937
982
 
938
983
  **Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
@@ -973,7 +1018,7 @@ _No events._
973
1018
  | `groups` | — | `{ id: string; userId?: undefined \| string; teamId?: undefined \| string; name: string; sortOrder: number; createdAt: string }[]` | Pre-bucketed conversation groups for the sidebar. Set as a JS property. |
974
1019
  | `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 }[]` | Flat conversation list (auto-bucketed if `groups` is empty). Set as a JS property. |
975
1020
  | `activeId` | `active-id` | `undefined \| string` | Id of the open conversation, highlighted in the sidebar. |
976
- | `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 } }[]` | The active conversation's message thread, newest last. Set as a JS property. |
1021
+ | `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" }[]` | The active conversation's message thread, newest last. Set as a JS property. |
977
1022
  | `value` | `value` | `undefined \| string` | |
978
1023
  | `placeholder` | `placeholder` | `undefined \| string` | |
979
1024
  | `loading` | `loading` | `undefined \| false \| true` | |
@@ -1003,7 +1048,7 @@ _No events._
1003
1048
  | Event | `detail` type | Description |
1004
1049
  |---|---|---|
1005
1050
  | `kai-conversation-select` | `CustomEvent<{ id: string }>` | A conversation was selected in the sidebar. |
1006
- | `kai-message-action` | `CustomEvent<{ messageId: string; action: string }>` | An action button on a message was clicked. |
1051
+ | `kai-message-action` | `CustomEvent<{ messageId: string; action: string; state?: undefined \| "on" \| "off" }>` | 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. |
1007
1052
  | `kai-model-change` | `CustomEvent<{ modelId: string }>` | The header model switcher changed. |
1008
1053
  | `kai-new-chat` | `CustomEvent<Record<string, never>>` | The "New chat" button was clicked. |
1009
1054
  | `kai-search` | `CustomEvent<Record<string, never>>` | The Search button was clicked. |
package/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  <!-- AUTO-GENERATED by scripts/gen-llms.mjs — do not edit by hand. Run `npm run build`. -->
2
2
  # @kitn.ai/ui
3
3
 
4
- > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 44 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
4
+ > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 46 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
5
5
 
6
6
  ## Install
7
7
 
@@ -35,7 +35,7 @@ Drop an element into any framework (React, Vue, plain HTML). Data in via JS prop
35
35
  - `<kai-prompt-input>` — standalone composer with send button.
36
36
 
37
37
  **Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
38
- All 44 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
38
+ All 46 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
39
39
 
40
40
  ## Key rules for the web components
41
41
 
@@ -97,7 +97,7 @@ For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
97
97
 
98
98
  ## Docs
99
99
 
100
- - Full element reference (all 44 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
100
+ - Full element reference (all 46 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
101
101
  - Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
102
102
  - Working examples: https://github.com/kitn-ai/ui/tree/main/examples
103
103
  - Storybook: https://storybook.kitn.dev
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitn.ai/ui",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "type": "module",
5
5
  "description": "Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. Authored in SolidJS.",
6
6
  "keywords": [
@@ -48,6 +48,14 @@
48
48
  "types": "./dist/elements.d.ts",
49
49
  "default": "./dist/kitn-chat.es.js"
50
50
  },
51
+ "./elements/*": {
52
+ "types": "./dist/elements/*.d.ts",
53
+ "default": "./dist/elements/*.js"
54
+ },
55
+ "./autoloader": {
56
+ "types": "./dist/elements/autoloader.d.ts",
57
+ "default": "./dist/elements/autoloader.js"
58
+ },
51
59
  "./theme.css": "./theme.css",
52
60
  "./theme.tokens.css": "./dist/theme.tokens.css",
53
61
  "./react": {
@@ -76,7 +84,8 @@
76
84
  "scripts": {
77
85
  "prepublishOnly": "npm run build",
78
86
  "prebuild": "npm run build:css",
79
- "build": "vite build --config vite.config.ts && vite build --config vite.config.provider.ts && vite build --config vite.config.react.ts && vite build --config vite.config.barrel.ts && vite build --config vite.config.mcp.ts",
87
+ "build": "vite build --config vite.config.ts && vite build --config vite.config.provider.ts && vite build --config vite.config.react.ts && vite build --config vite.config.barrel.ts && vite build --config vite.config.mcp.ts && npm run build:elements",
88
+ "build:elements": "node scripts/gen-elements-manifest.mjs && vite build --config vite.config.elements.ts && node scripts/gen-element-dts.mjs",
80
89
  "postbuild": "npm run build:theme && npm run build:api && npm run build:schemas",
81
90
  "build:theme": "node scripts/build-theme-tokens.mjs",
82
91
  "build:api": "node scripts/gen-element-api.mjs",
@@ -99,20 +108,19 @@
99
108
  "dependencies": {
100
109
  "@floating-ui/dom": "^1.7.6",
101
110
  "@modelcontextprotocol/sdk": "^1.29.0",
102
- "@shikijs/langs": "^4.2.0",
103
- "@shikijs/themes": "^4.2.0",
104
111
  "class-variance-authority": "^0.7.0",
105
112
  "clsx": "^2.1.0",
106
113
  "lucide-solid": "^0.400.0",
107
114
  "marked": "^18.0.0",
108
- "shiki": "^4.0.2",
109
115
  "solid-element": "^1.9.1",
110
116
  "solid-js": "^1.9.0",
111
- "tailwind-merge": "^2.5.0",
117
+ "tailwind-merge": "^3.0.0",
112
118
  "zod": "^4.4.3"
113
119
  },
114
120
  "devDependencies": {
115
121
  "@playwright/test": "^1.60.0",
122
+ "@shikijs/langs": "^4.2.0",
123
+ "@shikijs/themes": "^4.2.0",
116
124
  "@solidjs/testing-library": "^0.8.0",
117
125
  "@storybook/addon-a11y": "^10.4.2",
118
126
  "@storybook/addon-docs": "^10.3.5",
@@ -137,6 +145,7 @@
137
145
  "react": "^19.2.7",
138
146
  "react-dom": "^19.2.7",
139
147
  "remark-gfm": "^4.0.1",
148
+ "shiki": "^4.0.2",
140
149
  "storybook": "^10.3.5",
141
150
  "storybook-dark-mode": "^5.0.0",
142
151
  "storybook-solidjs-vite": "^10.0.12",