@kitn.ai/ui 0.30.0 → 0.31.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.
- package/README.md +1 -1
- package/dist/{Icon-BzBET3E-.js → Icon-DJDuE_-x.js} +1 -1
- package/dist/action-icons-xkBBVKkF.js +1 -0
- package/dist/agent-tooling/construct/schema-url.d.ts +9 -0
- package/dist/agent-tooling/construct/schema.d.ts +76 -1
- package/dist/agent-tooling/construct/templates.d.ts +45 -0
- package/dist/arrow-down-DU6wOl-h.js +1 -0
- package/dist/arrow-left-DD46kN17.js +1 -0
- package/dist/{artifact-DGjzHYUT.js → artifact-DoUAr1Fd.js} +1 -1
- package/dist/assets/dev-DwzHsqYD.js +553 -0
- package/dist/{attachments-YvXHlg88.js → attachments-BLWPDiLH.js} +1 -1
- package/dist/{audio-visualizer-9lz5IHsL.js → audio-visualizer-DhHicYvV.js} +1 -1
- package/dist/{badge-Dh_vp8A5.js → badge-BGm7pcwi.js} +1 -1
- package/dist/{bell-CT7_WUwS.js → bell-CMEdSo7A.js} +1 -1
- package/dist/builder-app/App.d.ts +1 -0
- package/dist/builder-app/edit-guard.d.ts +8 -0
- package/dist/builder-app/main.d.ts +0 -0
- package/dist/builder-page/assets/index-C10OF-ur.js +72 -0
- package/dist/builder-page/assets/index-CFyKLBlu.css +1 -0
- package/dist/builder-page/index.html +20 -0
- package/dist/button-BM0YTTDQ.js +1 -0
- package/dist/{card-renderer-DZVaGH2e.js → card-renderer-Ds-wXc6_.js} +1 -1
- package/dist/check-BG1VfYjm.js +1 -0
- package/dist/{checkbox-group-BiryEXPQ.js → checkbox-group-CqXj8ehz.js} +1 -1
- package/dist/{checkbox-Bu2T2e0U.js → checkbox-np_5mKxM.js} +1 -1
- package/dist/chevron-down-CZ4W0hy6.js +1 -0
- package/dist/chevron-right-5gdxkCTF.js +1 -0
- package/dist/{choice-card-CM6IjkmL.js → choice-card-BYBmPAT5.js} +1 -1
- package/dist/circle-C0lwjD2A.js +1 -0
- package/dist/circle-check-BfT1cxQU.js +1 -0
- package/dist/{circle-x-Bk-dA5Wf.js → circle-x-DzUfvRqr.js} +1 -1
- package/dist/{code-block-B26t-Q7q.js → code-block-H6E5Eurc.js} +1 -1
- package/dist/{collapsible-Bhc636Cf.js → collapsible-CBq1Tj6y.js} +1 -1
- package/dist/components/builder-message-actions.d.ts +9 -18
- package/dist/components/builder-panel-derived.d.ts +18 -0
- package/dist/components/builder-panel.d.ts +51 -0
- package/dist/components/builder-start.d.ts +14 -10
- package/dist/components/chat-thread.d.ts +27 -1
- package/dist/components/construct-form-paths.d.ts +54 -0
- package/dist/components/message.d.ts +5 -0
- package/dist/{composer-DMI85B6j.js → composer-B5IvgxAF.js} +1 -1
- package/dist/{confirm-card-B0YIAwXp.js → confirm-card-B63pZIfG.js} +1 -1
- package/dist/construct-cli.es.js +469 -125
- package/dist/construct-templates.d.ts +5 -0
- package/dist/construct-templates.js +266 -0
- package/dist/construct.js +269 -86
- package/dist/{context-DWgfhqWp.js → context-Byqor78j.js} +1 -1
- package/dist/controllable-C4BSt73s.js +1 -0
- package/dist/{conversation-item-BsOsVGmT.js → conversation-item-piXZFRWa.js} +1 -1
- package/dist/{conversation-list-aX3Vtc7L.js → conversation-list-B5yu9cPg.js} +1 -1
- package/dist/{copy-BmEwsNhJ.js → copy-DfI2NYEX.js} +1 -1
- package/dist/{create-tween-CNOAU3Fx.js → create-tween-C4j96_Aj.js} +1 -1
- package/dist/{create-tween-WfqiENls.js → create-tween-CHleHI8m.js} +1 -1
- package/dist/{create-tween-wlFtW9Kh.js → create-tween-DQ6lOhdl.js} +1 -1
- package/dist/{create-tween-zt79ba32.js → create-tween-DyjTgkJi.js} +1 -1
- package/dist/custom-elements.json +40 -5
- package/dist/{default-input-DMV5Eaze.js → default-input-Bwmt8Lai.js} +1 -1
- package/dist/define-B3OpsIDE.js +1 -0
- package/dist/define.js +2 -2
- package/dist/define.server.js +2 -2
- package/dist/{disclosure-NnACBxsC.js → disclosure-ZSAlD4wg.js} +1 -1
- package/dist/{dropdown-DT7G0RGR.js → dropdown-CSRhiMN2.js} +1 -1
- package/dist/elements/agent-card.js +1 -1
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/audio-visualizer.js +1 -1
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/badge.js +1 -1
- package/dist/elements/button.js +1 -1
- package/dist/elements/card.js +1 -1
- package/dist/elements/cards.js +1 -1
- package/dist/elements/chain-of-thought.js +1 -1
- package/dist/elements/chat-actions.d.ts +12 -0
- package/dist/elements/chat-scope-picker.js +1 -1
- package/dist/elements/chat-types.d.ts +7 -2
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkbox-group.js +1 -1
- package/dist/elements/checkbox.js +1 -1
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/coachmark.js +1 -1
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.js +1 -1
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.js +1 -1
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-item.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.js +1 -1
- package/dist/elements/dropdown.js +1 -1
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.js +1 -1
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-grid.js +1 -1
- package/dist/elements/pane-group.js +1 -1
- package/dist/elements/pane.js +1 -1
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.js +1 -1
- package/dist/elements/prompt-dock.js +1 -1
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/radio-group.js +1 -1
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +1 -1
- package/dist/elements/screen.js +1 -1
- package/dist/elements/scroll-area.js +1 -1
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.js +1 -1
- package/dist/elements/segmented.js +1 -1
- package/dist/elements/select.js +1 -1
- package/dist/elements/separator.js +1 -1
- package/dist/elements/setting-item.js +1 -1
- package/dist/elements/settings-group.js +1 -1
- package/dist/elements/skeleton.js +1 -1
- package/dist/elements/slider.js +1 -1
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.js +1 -1
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.js +1 -1
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/thread.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.js +1 -1
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/elements.d.ts +22 -10
- package/dist/{ellipsis-6pJ7SxYT.js → ellipsis-CJ5QIjWo.js} +1 -1
- package/dist/{embed-BMje-nxj.js → embed-6Vji0PfS.js} +1 -1
- package/dist/{external-link-Beh9DKeR.js → external-link-BPTtTdet.js} +1 -1
- package/dist/{file-text-D1GPfZ8Q.js → file-text-eVjcFDrK.js} +1 -1
- package/dist/{file-tree-Dwj2lqg-.js → file-tree-a9tfWYmg.js} +1 -1
- package/dist/{folder-b6D8x1DY.js → folder-DN6Ilq6d.js} +1 -1
- package/dist/{form-DWgdxDXu.js → form-U1cwhcQx.js} +1 -1
- package/dist/{hover-card-CWRkqm40.js → hover-card-C5ptzZOZ.js} +1 -1
- package/dist/{icon-CL0jdhsf.js → icon-BOMrFp0D.js} +1 -1
- package/dist/index.js +1991 -1989
- package/dist/index.server.js +1886 -1884
- package/dist/{info-0cOUherQ.js → info-DxzKsIHn.js} +1 -1
- package/dist/{input-BH6Ru91Q.js → input-aW72PACH.js} +1 -1
- package/dist/kai.es.js +1 -1
- package/dist/{kbd-DRAnVtNX.js → kbd-BP-6MwUs.js} +1 -1
- package/dist/{link-preview-DODgRyV9.js → link-preview-CZaDilMG.js} +1 -1
- package/dist/{link-Dlr0vssB.js → link-rlN11N0B.js} +1 -1
- package/dist/{loader-KvJB6NrT.js → loader-BdFK70fF.js} +1 -1
- package/dist/{markdown-DX9tuJVj.js → markdown-DjEaoNz-.js} +1 -1
- package/dist/mcp.es.js +579 -107
- package/dist/message--Nlbemtp.js +1 -0
- package/dist/message-C88yTu2A.js +1 -0
- package/dist/message-circle-CZeVDN1f.js +1 -0
- package/dist/message-square-BXNBKC6i.js +1 -0
- package/dist/{minimize-2-CyOHJwcN.js → minimize-2-BxLOOSEf.js} +1 -1
- package/dist/{model-switcher-0hrKDiK2.js → model-switcher-BxRvub2A.js} +1 -1
- package/dist/{overlay-DBMFXie6.js → overlay-CDwKJtHN.js} +1 -1
- package/dist/{panel-right-t8SWJL6e.js → panel-right-BovedCwW.js} +1 -1
- package/dist/{paperclip-CdzuOjbU.js → paperclip-D0Xyjja2.js} +1 -1
- package/dist/play-DGJ4MgB2.js +1 -0
- package/dist/primitives/speech.d.ts +35 -0
- package/dist/{progress-bar-CiBtxMWT.js → progress-bar-D-aQfy5h.js} +1 -1
- package/dist/{prompt-suggestion-I_DHP21i.js → prompt-suggestion-C6qLjMEQ.js} +1 -1
- package/dist/{radio-C_p3n39l.js → radio-D1CkXISc.js} +1 -1
- package/dist/react/index.d.ts +22 -6
- package/dist/react.js +13 -13
- package/dist/{reasoning-BDwy_tIe.js → reasoning-DARmbgmE.js} +1 -1
- package/dist/register-impl-WcrdIihK.js +424 -0
- package/dist/{resizable-SYC-fStM.js → resizable-Da6oSO2z.js} +1 -1
- package/dist/{rotate-ccw-B1nwmwuY.js → rotate-ccw-31ed1xK_.js} +1 -1
- package/dist/{rotate-cw-CLAnBcm1.js → rotate-cw-qkl39dw3.js} +1 -1
- package/dist/{scroll-area-zRyXoLhI.js → scroll-area-RrKnLYlA.js} +1 -1
- package/dist/{scroll-button-jzrbYCG9.js → scroll-button--QeNjobK.js} +1 -1
- package/dist/{select-DM-0nEe0.js → select-CS_0mWW3.js} +1 -1
- package/dist/{separator-BToOOoOt.js → separator-fT-zBypW.js} +1 -1
- package/dist/{settings-PaGo_S4U.js → settings-dfkV_WDm.js} +1 -1
- package/dist/{settings-group-BFXGIfXq.js → settings-group-CX694npG.js} +1 -1
- package/dist/{skeleton-DYpmFnnm.js → skeleton-BsqKD9TV.js} +1 -1
- package/dist/{slider-ebutAmkQ.js → slider-_EWfTH9H.js} +1 -1
- package/dist/{solid-15v_3WVL.js → solid-BITWG_VE.js} +3073 -3006
- package/dist/{solid-5P-otgdi.js → solid-CRFYWlBw.js} +3865 -3797
- package/dist/solid.js +1 -1
- package/dist/solid.server.js +1 -1
- package/dist/{source-c1gpRl9h.js → source-Da1TFiuj.js} +1 -1
- package/dist/speech-CjbWuqG2.js +1 -0
- package/dist/{star-pcV_3LqF.js → star-ZvSbbXS6.js} +1 -1
- package/dist/{store-CSgbFFCg.js → store-DE5lcr9q.js} +1 -1
- package/dist/{switch-Bh2OdLV2.js → switch-P_fsHqv3.js} +1 -1
- package/dist/{tasks-card-CbqQAn2S.js → tasks-card-B86qqyZm.js} +1 -1
- package/dist/{text-shimmer-BSzgEnDH.js → text-shimmer-BAkw_65G.js} +1 -1
- package/dist/{textarea-DrYNt_0z.js → textarea-Bkinatpi.js} +1 -1
- package/dist/{thumbs-up-BL3-NenK.js → thumbs-up-CDGW7a4o.js} +1 -1
- package/dist/{toast-store-DkOlYczt.js → toast-store-B94I50AO.js} +1 -1
- package/dist/{tool-CeIWUVUe.js → tool-CUiCeyi1.js} +1 -1
- package/dist/{tooltip-GA-nmg06.js → tooltip-B3wlQSPh.js} +1 -1
- package/dist/{trash-2-CT66QWlm.js → trash-2-Cu8yZmFQ.js} +1 -1
- package/dist/{triangle-alert-CeHLWxhD.js → triangle-alert-CCtDUUmn.js} +1 -1
- package/dist/ui/button-variant-names.d.ts +12 -0
- package/dist/ui/button.d.ts +6 -0
- package/dist/{upload-9Csb0F0J.js → upload-CxotJlLv.js} +1 -1
- package/dist/{use-card-resolution-Zg0a08Z-.js → use-card-resolution-DILUvNyj.js} +1 -1
- package/dist/{variant-aurora-4VBQHIKV.js → variant-aurora-BGaXBBGf.js} +1 -1
- package/dist/{variant-aurora-LE3fqxgw.js → variant-aurora-BLcQmvkd.js} +1 -1
- package/dist/{variant-aurora-DBeCAQNk.js → variant-aurora-DZIfAtx1.js} +2 -2
- package/dist/{variant-aurora-FzHVXHby.js → variant-aurora-DpoIW4ZX.js} +2 -2
- package/dist/{variant-custom-DI5R0rln.js → variant-custom-BhtWdAxE.js} +1 -1
- package/dist/{variant-custom-WWnrrRHS.js → variant-custom-BtApuSyr.js} +2 -2
- package/dist/{variant-custom-BQkNuPpE.js → variant-custom-C-zS4ZtE.js} +2 -2
- package/dist/{variant-custom-AFRGcOBS.js → variant-custom-swi9PXxU.js} +1 -1
- package/dist/{variant-wave-wTP5v_jU.js → variant-wave-7JCIwhpb.js} +1 -1
- package/dist/{variant-wave-nSI2sfII.js → variant-wave-BG4nGr6x.js} +1 -1
- package/dist/{variant-wave-DuQV7DhQ.js → variant-wave-C32lM9G2.js} +2 -2
- package/dist/{variant-wave-DUCbH5oI.js → variant-wave-Dl6jOiK3.js} +2 -2
- package/dist/x-C4niw05N.js +1 -0
- package/frameworks/react/index.tsx +12 -6
- package/llms-full.txt +9 -6
- package/llms.txt +1 -1
- package/package.json +7 -3
- package/solid.css +17 -2
- package/src/elements/element-meta.json +39 -14
- package/dist/action-icons-DaW2pU6m.js +0 -1
- package/dist/arrow-down-D783iMJj.js +0 -1
- package/dist/arrow-left-0VLM5kyg.js +0 -1
- package/dist/assets/dev-5XzXYR21.js +0 -91
- package/dist/button-C_3te6fm.js +0 -1
- package/dist/check-CiEOVnEN.js +0 -1
- package/dist/chevron-down-CSobuZRG.js +0 -1
- package/dist/chevron-right-DR9ZAP-2.js +0 -1
- package/dist/circle-BC66EYF7.js +0 -1
- package/dist/circle-check-BqmahW0O.js +0 -1
- package/dist/controllable-BagRpyHv.js +0 -1
- package/dist/define-CI0y3eE4.js +0 -1
- package/dist/message-BqQ7Ot5q.js +0 -1
- package/dist/message-DkaGfBd8.js +0 -1
- package/dist/message-circle-BPpp5QKv.js +0 -1
- package/dist/message-square-BLbsd9BJ.js +0 -1
- package/dist/play-BXy1u7rW.js +0 -1
- package/dist/register-impl-DvEnhIxx.js +0 -424
- package/dist/x-eiO9V6J6.js +0 -1
|
@@ -361,10 +361,16 @@ export interface ChatProps extends WebComponentProps {
|
|
|
361
361
|
kindIcons?: Record<string, string>;
|
|
362
362
|
/** Whether each message's action bar is always visible (`'always'`, default) or only revealed on hover of that message row (`'hover'`). */
|
|
363
363
|
actionsReveal?: "always" | "hover";
|
|
364
|
+
/** Role-scoped DEFAULT action bars (B-7b): a user message with no `actions` of its own gets `userActions`; an assistant message, `assistantActions`. A per-message `m.actions` OVERRIDES the role default (replace, not merge), so a message that sets `actions: []` renders NO action bar even when a role default is set. Set as JS properties. */
|
|
365
|
+
userActions?: ("copy" | "dislike" | "edit" | "like" | "regenerate" | "speak" | { id: string; label: string; icon?: string; tooltip?: string })[];
|
|
366
|
+
/** See `userActions`, the assistant-role default. */
|
|
367
|
+
assistantActions?: ("copy" | "dislike" | "edit" | "like" | "regenerate" | "speak" | { id: string; label: string; icon?: string; tooltip?: string })[];
|
|
368
|
+
/** Hide the citations row consecutive `source` parts collapse into (`part="citations"`, message.tsx). Named as a HIDE, not `sources: boolean`, so absence-means-default stays unambiguous: absent/false is today's rendering, byte-for-byte (B-8). */
|
|
369
|
+
hideSources?: boolean;
|
|
364
370
|
/** Which attachment media types the user may stage, in HTML `accept` syntax: `<kai-chat accept="image/*,application/pdf">`. A plain string, so unlike `messages` it DOES work as an attribute. Omitted means no filter. MEDIA TYPES ONLY -- exact (`image/png`) or subtype wildcard (`text/*`). HTML allows a file extension here and this does not: `accept=".py"` THROWS with the entry named, rather than silently resolving to a picker that accepts nothing. It can only NARROW what the kit can already encode: `accept="image/*"` resolves to the four image formats both APIs take, not to every image type the OS offers. Pass the SAME string to `toOpenAIMessages(msgs, { accept })` and the picker and the wire cannot disagree -- both resolve it through `resolveMediaPolicy` against one declaration. That declaration is readable as `encodableMediaTypes()` from `@kitn.ai/ui/wire`, if you would rather build your own picker than use this prop. */
|
|
365
371
|
accept?: string;
|
|
366
372
|
/** The full message thread to render, newest last. Each entry carries its role, ordered `parts`, and optional actions/avatar/feedback. Set as a JS property (`el.messages = [...]`); a NEW array reference per streaming chunk re-renders (mutating in place does not). Omit for an empty thread. Re-declared here (rather than inherited from `ChatThreadProps`) because the ELEMENT registers a `[]` default and renders the empty state without it, while the SolidJS `<ChatThread>` component still requires it. The facade hands it a validated array either way. Matches `<kai-thread>`. */
|
|
367
|
-
messages?: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "
|
|
373
|
+
messages?: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "dislike" | "edit" | "like" | "regenerate" | "speak" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" }[];
|
|
368
374
|
/** Optional card type -> custom-element tag overrides/additions for `card` parts (merged over the built-ins). Property: `el.cardTypes`. Typed as a plain string map (not the `CardTagMap` alias) so the generated React wrapper inlines it instead of emitting an unresolved named type. */
|
|
369
375
|
cardTypes?: Record<string, string>;
|
|
370
376
|
/** JSON Schemas for the card types this app renders, keyed by envelope type. The companion of `cardTypes`, which says what DRAWS a card while this says what a VALID one looks like. An OBJECT, so it is a JS property only: `el.cardSchemas = { 'pricing-table': pricingSchema }`, never an attribute. `createCardRegistry(...).validationSchemas` is exactly this shape. Without it the kit validates its own seven built-ins and leaves your own card type, the one your app actually cares about, as the only unchecked thing on screen. A schema here WINS over a built-in of the same name. Typed `Record<string, object>` rather than `Record<string, JsonSchema>` deliberately: an imported `.json` schema widens `"type"` to `string`, and an authored one carries `$schema`/`title`/`description`/`additionalProperties`, so the tighter type would reject both of the normal ways to supply one. */
|
|
@@ -372,7 +378,7 @@ export interface ChatProps extends WebComponentProps {
|
|
|
372
378
|
/** Turns on the prior-conversations list (a list-toggle button in the header, plus a second list view sharing the panel, C-1). Attribute- settable like every other boolean flag on this element: `<kai-chat conversations>`. Requires `store`. A row select, "new conversation," or the visitor's mount-time auto-restore all deliver their messages the same way: listen for `kai-conversation-load` and set `el.messages` from `event.detail.messages` (a fresh array): this element does not update `messages` for you. Set with no `store`, the underlying `ChatThread` decides loudly (one console.error) and stays visually off; this facade always supplies its own internal load handler (the `kai-conversation-load` dispatch below), so the second ChatThread guard, missing `onConversationLoad`, never trips here, even for a consumer who never listens for the event. Default false. */
|
|
373
379
|
conversations?: boolean;
|
|
374
380
|
/** The adapter this thread persists conversations through: an object of three functions (`list`/`load`/`save`; `ConversationStore`, exported from `@kitn.ai/ui`'s `primitives/conversation-store`). A JS PROPERTY ONLY: `el.store = myAdapter`. It can never be an attribute, since a function-bearing object has no HTML string form, the same reasoning that keeps `messages`/`cardSchemas` property-only (the kai- contract: array/object props are JS properties, never attributes). Two built-ins ship: `localStorageStore(name, userId?)` and `fetchStore(url, userId?)`. */
|
|
375
|
-
store?: { list: () => Promise<{ id: string; title: string; groupId?: string; scope?: { type: "document" | "collection"; documentId?: string; filters?: { tags?: string[]; authors?: string[]; contentType?: "transcript" | "markdown"; dateRange?: { from: string; to: string } } }; messageCount: number; lastMessageAt?: string; updatedAt: string; trailing?: string; lastReadAt?: string }[]>; load: (id: string) => Promise<{ id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "
|
|
381
|
+
store?: { list: () => Promise<{ id: string; title: string; groupId?: string; scope?: { type: "document" | "collection"; documentId?: string; filters?: { tags?: string[]; authors?: string[]; contentType?: "transcript" | "markdown"; dateRange?: { from: string; to: string } } }; messageCount: number; lastMessageAt?: string; updatedAt: string; trailing?: string; lastReadAt?: string }[]>; load: (id: string) => Promise<{ id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "dislike" | "edit" | "like" | "regenerate" | "speak" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" }[]>; save: (id: string, messages: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "dislike" | "edit" | "like" | "regenerate" | "speak" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" }[]) => Promise<void>; markRead?: ((id: string) => Promise<void>) };
|
|
376
382
|
/** Turns on the widget home screen (Intercom-pattern): the panel boots into a `home` view, with a greeting, most-recent-conversation card, a "new conversation" CTA, and host-defined links, plus a Home/Messages tab bar for switching back to the thread. An OBJECT, so it is a JS property only: `el.home = { greeting: { title: 'Hey' }, links: [...] }`, never an attribute (the kai- contract: array/object props are JS properties). A `links` entry with no `href` fires `kai-home-link` with that entry when tapped, rather than navigating; one WITH `href` opens it directly (only when the URL passes the kit's own scheme allowlist). Omit for the no-home widget (chat view only, unchanged). */
|
|
377
383
|
home?: { greeting?: { title?: string; subtitle?: string }; recentConversation?: boolean; newConversation?: { label?: string }; links?: { label: string; href?: string; description?: string; icon?: string }[] };
|
|
378
384
|
/** The staged attachments changed (file added or removed). Carries the full current list so a consumer can react in real time. */
|
|
@@ -380,7 +386,7 @@ export interface ChatProps extends WebComponentProps {
|
|
|
380
386
|
/** One or more picked files were refused because `accept` excluded them. The element renders NO message of its own: it reports the facts (name, media type, whether the kit could have sent it) and what the user should see is the application's call. Only ever fires when `accept` is set. */
|
|
381
387
|
onAttachmentsRejected?: (event: CustomEvent<{ rejected: { filename: string; mediaType: string; reason: "filtered" | "unsupported" }[] }>) => void;
|
|
382
388
|
/** A conversation's history loaded: a row tap in the list, "new conversation," or the visitor's own mount-time auto-restore of their most recent thread (only fires when `conversations` is on and a `store` is set). `detail.id` is that conversation's id, `undefined` for the "new conversation" case (no id exists until the first message mints one, C-6). Set `el.messages = event.detail.messages` (already a fresh array) to actually render it, since this element does not do that for you; `messages` stays your own state like everywhere else on this element. */
|
|
383
|
-
onConversationLoad?: (event: CustomEvent<{ id: string | undefined; messages: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: undefined | { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: undefined | string; index?: undefined | number; streamId?: undefined | string; signature?: undefined | string; raw?: undefined | { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: undefined | "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: undefined | Record<string, unknown>; rawInput?: undefined | string; output?: undefined | Record<string, unknown>; toolCallId?: undefined | string; errorText?: undefined | string; raw?: undefined | { source: string; payload: unknown } }; raw?: undefined | { source: string; payload: unknown } } | { type: "card"; envelope: { 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 } }; raw?: undefined | { source: string; payload: unknown } } | { type: "source"; source: { id?: undefined | string; url?: undefined | string; title?: undefined | string; snippet?: undefined | string; index?: undefined | number }; raw?: undefined | { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }; raw?: undefined | { source: string; payload: unknown } })[]; actions?: undefined | ("copy" | "
|
|
389
|
+
onConversationLoad?: (event: CustomEvent<{ id: string | undefined; messages: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: undefined | { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: undefined | string; index?: undefined | number; streamId?: undefined | string; signature?: undefined | string; raw?: undefined | { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: undefined | "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: undefined | Record<string, unknown>; rawInput?: undefined | string; output?: undefined | Record<string, unknown>; toolCallId?: undefined | string; errorText?: undefined | string; raw?: undefined | { source: string; payload: unknown } }; raw?: undefined | { source: string; payload: unknown } } | { type: "card"; envelope: { 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 } }; raw?: undefined | { source: string; payload: unknown } } | { type: "source"; source: { id?: undefined | string; url?: undefined | string; title?: undefined | string; snippet?: undefined | string; index?: undefined | number }; raw?: undefined | { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }; raw?: undefined | { source: string; payload: unknown } })[]; actions?: undefined | ("copy" | "dislike" | "edit" | "like" | "regenerate" | "speak" | { 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" }[] }>) => void;
|
|
384
390
|
/** A `home.links` entry with no `href` was activated (tapped/clicked/Enter). Meaningful only when `home` is set. */
|
|
385
391
|
onHomeLink?: (event: CustomEvent<{ entry: { label: string; href?: undefined | string; description?: undefined | string; icon?: undefined | string } }>) => void;
|
|
386
392
|
/** 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. */
|
|
@@ -401,7 +407,7 @@ export interface ChatProps extends WebComponentProps {
|
|
|
401
407
|
|
|
402
408
|
export const Chat = /*#__PURE__*/ createWebComponent<ChatProps>(
|
|
403
409
|
'kai-chat',
|
|
404
|
-
["theme","value","placeholder","loading","suggestions","suggestionMode","persistSuggestions","proseSize","codeTheme","codeHighlight","reasoning","reasoningOpen","chatTitle","models","currentModel","context","scrollButton","headerStart","headerEnd","headerFull","sidebar","empty","composer","composerActions","footer","attach","webSearch","voice","triggers","kindIcons","actionsReveal","accept","messages","cardTypes","cardSchemas","conversations","store","home"],
|
|
410
|
+
["theme","value","placeholder","loading","suggestions","suggestionMode","persistSuggestions","proseSize","codeTheme","codeHighlight","reasoning","reasoningOpen","chatTitle","models","currentModel","context","scrollButton","headerStart","headerEnd","headerFull","sidebar","empty","composer","composerActions","footer","attach","webSearch","voice","triggers","kindIcons","actionsReveal","userActions","assistantActions","hideSources","accept","messages","cardTypes","cardSchemas","conversations","store","home"],
|
|
405
411
|
{ onAttachmentsChange: 'kai-attachments-change', onAttachmentsRejected: 'kai-attachments-rejected', onConversationLoad: 'kai-conversation-load', onHomeLink: 'kai-home-link', onMessageAction: 'kai-message-action', onModelChange: 'kai-model-change', onSubmit: 'kai-submit', onSuggestionClick: 'kai-suggestion-click', onValueChange: 'kai-value-change', onVoice: 'kai-voice', onWebSearch: 'kai-web-search' },
|
|
406
412
|
() => import('@kitn.ai/ui/elements/chat'),
|
|
407
413
|
);
|
|
@@ -1170,7 +1176,7 @@ export const Menu = /*#__PURE__*/ createWebComponent<MenuProps>(
|
|
|
1170
1176
|
|
|
1171
1177
|
export interface MessageProps extends WebComponentProps {
|
|
1172
1178
|
/** The full message object. Set as a JS property. */
|
|
1173
|
-
message?: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "
|
|
1179
|
+
message?: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "dislike" | "edit" | "like" | "regenerate" | "speak" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" };
|
|
1174
1180
|
/** Who is speaking: `'user'` or `'assistant'`. Convenience for simple cases when not passing a `message` object. This is the SEMANTIC role of the message, not an ARIA role. The name collides with the global ARIA `role` attribute, which is why the facade lifts it off the host (see `liftRoleOffHost`). Neither speaker is a valid ARIA role, so a `role="user"` left on `<kai-message>` is a CRITICAL axe `aria-roles` violation. The accessible role lives on the row inside the shadow root instead: `role="article"` plus an `aria-label` naming the speaker, matching the SolidJS `<Message>` component. */
|
|
1175
1181
|
role?: "user" | "assistant";
|
|
1176
1182
|
/** Force markdown on/off. Defaults to on for assistant, off for user. */
|
|
@@ -2037,7 +2043,7 @@ export const ThinkingBar = /*#__PURE__*/ createWebComponent<ThinkingBarProps>(
|
|
|
2037
2043
|
|
|
2038
2044
|
export interface ThreadProps extends WebComponentProps {
|
|
2039
2045
|
/** The full message thread to render, newest last. Each entry carries its role, ordered `parts`, and optional actions/avatar/feedback. Set as a JS property (`el.messages = [...]`); a NEW array reference per streaming chunk re-renders (mutating in place does not). */
|
|
2040
|
-
messages?: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "
|
|
2046
|
+
messages?: { id: string; role: "user" | "assistant"; parts: ({ type: "text"; text: string; raw?: { source: string; payload: unknown } } | { type: "reasoning"; text: string; label?: string; index?: number; streamId?: string; signature?: string; raw?: { source: string; payload: unknown } } | { type: "tool"; tool: { type: string; kind?: "command" | "file-change" | "search" | "fetch" | "mcp" | "image" | "generic"; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; rawInput?: string; output?: Record<string, unknown>; toolCallId?: string; errorText?: string; raw?: { source: string; payload: unknown } }; raw?: { source: string; payload: unknown } } | { type: "card"; envelope: { type: string; id: string; data: unknown; title?: string; resolution?: { kind: "action"; action: string; payload?: unknown; at?: string } | { kind: "submit"; data: unknown; at?: string } | { kind: "dismissed"; at?: string } | { kind: "expired"; reason?: string; at?: string } }; raw?: { source: string; payload: unknown } } | { type: "source"; source: { id?: string; url?: string; title?: string; snippet?: string; index?: number }; raw?: { source: string; payload: unknown } } | { type: "file"; attachment: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }; raw?: { source: string; payload: unknown } })[]; actions?: ("copy" | "dislike" | "edit" | "like" | "regenerate" | "speak" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" }[];
|
|
2041
2047
|
/** Show a typing indicator on the pending assistant turn. Set it while awaiting the assistant's reply. */
|
|
2042
2048
|
loading?: boolean;
|
|
2043
2049
|
/** Body/prose font scale for rendered markdown (`'xs' | 'sm' | 'base' | 'lg'`). Defaults to `'sm'`. */
|
package/llms-full.txt
CHANGED
|
@@ -58,7 +58,7 @@ interface ChatMessage {
|
|
|
58
58
|
/** The ONLY content channel. Ordered. */
|
|
59
59
|
parts: MessagePart[];
|
|
60
60
|
/** Action buttons under the message. Chrome, not content. */
|
|
61
|
-
actions?: ('copy' | 'like' | 'dislike' | 'regenerate' | 'edit')[];
|
|
61
|
+
actions?: ('copy' | 'like' | 'dislike' | 'regenerate' | 'edit' | 'speak')[];
|
|
62
62
|
avatar?: { src?: string; fallback?: string; alt?: string };
|
|
63
63
|
feedback?: 'like' | 'dislike';
|
|
64
64
|
}
|
|
@@ -1610,12 +1610,15 @@ _No events._
|
|
|
1610
1610
|
| `triggers` | — | `undefined \| { char: string; kind: string; items?: undefined \| { id: string; label: string; icon?: undefined \| string; description?: undefined \| string; group?: undefined \| string; kind?: undefined \| string; promptText?: undefined \| string; data?: undefined \| Record<string, unknown> }[] }[]` | Rich entity triggers. Each `{ char, kind, items }` opens a caret-anchored menu that inserts an atomic pill (`/` skills, `@` agents/plugins). Set as a JS property; forwarded to the input. |
|
|
1611
1611
|
| `kindIcons` | — | `undefined \| Record<string, string>` | Default icon per entity kind (kind → image src) for pills/menu items. |
|
|
1612
1612
|
| `actionsReveal` | `actions-reveal` | `undefined \| "always" \| "hover"` | Whether each message's action bar is always visible (`'always'`, default) or only revealed on hover of that message row (`'hover'`). |
|
|
1613
|
+
| `userActions` | — | `undefined \| ("copy" \| "dislike" \| "edit" \| "like" \| "regenerate" \| "speak" \| { id: string; label: string; icon?: undefined \| string; tooltip?: undefined \| string })[]` | Role-scoped DEFAULT action bars (B-7b): a user message with no `actions` of its own gets `userActions`; an assistant message, `assistantActions`. A per-message `m.actions` OVERRIDES the role default (replace, not merge), so a message that sets `actions: []` renders NO action bar even when a role default is set. Set as JS properties. |
|
|
1614
|
+
| `assistantActions` | — | `undefined \| ("copy" \| "dislike" \| "edit" \| "like" \| "regenerate" \| "speak" \| { id: string; label: string; icon?: undefined \| string; tooltip?: undefined \| string })[]` | See `userActions`, the assistant-role default. |
|
|
1615
|
+
| `hideSources` | `hide-sources` | `undefined \| false \| true` | Hide the citations row consecutive `source` parts collapse into (`part="citations"`, message.tsx). Named as a HIDE, not `sources: boolean`, so absence-means-default stays unambiguous: absent/false is today's rendering, byte-for-byte (B-8). |
|
|
1613
1616
|
| `accept` | `accept` | `undefined \| string` | Which attachment media types the user may stage, in HTML `accept` syntax: `<kai-chat accept="image/*,application/pdf">`. A plain string, so unlike `messages` it DOES work as an attribute. Omitted means no filter. MEDIA TYPES ONLY -- exact (`image/png`) or subtype wildcard (`text/*`). HTML allows a file extension here and this does not: `accept=".py"` THROWS with the entry named, rather than silently resolving to a picker that accepts nothing. It can only NARROW what the kit can already encode: `accept="image/*"` resolves to the four image formats both APIs take, not to every image type the OS offers. Pass the SAME string to `toOpenAIMessages(msgs, { accept })` and the picker and the wire cannot disagree -- both resolve it through `resolveMediaPolicy` against one declaration. That declaration is readable as `encodableMediaTypes()` from `@kitn.ai/ui/wire`, if you would rather build your own picker than use this prop. |
|
|
1614
|
-
| `messages` | — | `undefined \| { id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "
|
|
1617
|
+
| `messages` | — | `undefined \| { id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "dislike" \| "edit" \| "like" \| "regenerate" \| "speak" \| { 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, ordered `parts`, and optional actions/avatar/feedback. Set as a JS property (`el.messages = [...]`); a NEW array reference per streaming chunk re-renders (mutating in place does not). Omit for an empty thread. Re-declared here (rather than inherited from `ChatThreadProps`) because the ELEMENT registers a `[]` default and renders the empty state without it, while the SolidJS `<ChatThread>` component still requires it. The facade hands it a validated array either way. Matches `<kai-thread>`. |
|
|
1615
1618
|
| `cardTypes` | — | `undefined \| Record<string, string>` | Optional card type -> custom-element tag overrides/additions for `card` parts (merged over the built-ins). Property: `el.cardTypes`. Typed as a plain string map (not the `CardTagMap` alias) so the generated React wrapper inlines it instead of emitting an unresolved named type. |
|
|
1616
1619
|
| `cardSchemas` | — | `undefined \| Record<string, object>` | JSON Schemas for the card types this app renders, keyed by envelope type. The companion of `cardTypes`, which says what DRAWS a card while this says what a VALID one looks like. An OBJECT, so it is a JS property only: `el.cardSchemas = { 'pricing-table': pricingSchema }`, never an attribute. `createCardRegistry(...).validationSchemas` is exactly this shape. Without it the kit validates its own seven built-ins and leaves your own card type, the one your app actually cares about, as the only unchecked thing on screen. A schema here WINS over a built-in of the same name. Typed `Record<string, object>` rather than `Record<string, JsonSchema>` deliberately: an imported `.json` schema widens `"type"` to `string`, and an authored one carries `$schema`/`title`/`description`/`additionalProperties`, so the tighter type would reject both of the normal ways to supply one. |
|
|
1617
1620
|
| `conversations` | `conversations` | `undefined \| false \| true` | Turns on the prior-conversations list (a list-toggle button in the header, plus a second list view sharing the panel, C-1). Attribute- settable like every other boolean flag on this element: `<kai-chat conversations>`. Requires `store`. A row select, "new conversation," or the visitor's mount-time auto-restore all deliver their messages the same way: listen for `kai-conversation-load` and set `el.messages` from `event.detail.messages` (a fresh array): this element does not update `messages` for you. Set with no `store`, the underlying `ChatThread` decides loudly (one console.error) and stays visually off; this facade always supplies its own internal load handler (the `kai-conversation-load` dispatch below), so the second ChatThread guard, missing `onConversationLoad`, never trips here, even for a consumer who never listens for the event. Default false. |
|
|
1618
|
-
| `store` | — | `undefined \| { list: () => Promise<{ id: string; title: string; groupId?: undefined \| string; scope?: undefined \| { 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?: undefined \| string; updatedAt: string; trailing?: undefined \| string; lastReadAt?: undefined \| string }[]>; load: (id: string) => Promise<{ id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "
|
|
1621
|
+
| `store` | — | `undefined \| { list: () => Promise<{ id: string; title: string; groupId?: undefined \| string; scope?: undefined \| { 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?: undefined \| string; updatedAt: string; trailing?: undefined \| string; lastReadAt?: undefined \| string }[]>; load: (id: string) => Promise<{ id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "dislike" \| "edit" \| "like" \| "regenerate" \| "speak" \| { 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" }[]>; save: (id: string, messages: { id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "dislike" \| "edit" \| "like" \| "regenerate" \| "speak" \| { 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" }[]) => Promise<void>; markRead?: undefined \| ((id: string) => Promise<void>) }` | The adapter this thread persists conversations through: an object of three functions (`list`/`load`/`save`; `ConversationStore`, exported from `@kitn.ai/ui`'s `primitives/conversation-store`). A JS PROPERTY ONLY: `el.store = myAdapter`. It can never be an attribute, since a function-bearing object has no HTML string form, the same reasoning that keeps `messages`/`cardSchemas` property-only (the kai- contract: array/object props are JS properties, never attributes). Two built-ins ship: `localStorageStore(name, userId?)` and `fetchStore(url, userId?)`. |
|
|
1619
1622
|
| `home` | — | `undefined \| { greeting?: undefined \| { title?: undefined \| string; subtitle?: undefined \| string }; recentConversation?: undefined \| false \| true; newConversation?: undefined \| { label?: undefined \| string }; links?: undefined \| { label: string; href?: undefined \| string; description?: undefined \| string; icon?: undefined \| string }[] }` | Turns on the widget home screen (Intercom-pattern): the panel boots into a `home` view, with a greeting, most-recent-conversation card, a "new conversation" CTA, and host-defined links, plus a Home/Messages tab bar for switching back to the thread. An OBJECT, so it is a JS property only: `el.home = { greeting: { title: 'Hey' }, links: [...] }`, never an attribute (the kai- contract: array/object props are JS properties). A `links` entry with no `href` fires `kai-home-link` with that entry when tapped, rather than navigating; one WITH `href` opens it directly (only when the URL passes the kit's own scheme allowlist). Omit for the no-home widget (chat view only, unchanged). |
|
|
1620
1623
|
|
|
1621
1624
|
**Events** (non-bubbling `CustomEvent`s — listen directly on the element):
|
|
@@ -1624,7 +1627,7 @@ _No events._
|
|
|
1624
1627
|
|---|---|---|
|
|
1625
1628
|
| `kai-attachments-change` | `CustomEvent<{ attachments: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }[] }>` | The staged attachments changed (file added or removed). Carries the full current list so a consumer can react in real time. |
|
|
1626
1629
|
| `kai-attachments-rejected` | `CustomEvent<{ rejected: { filename: string; mediaType: string; reason: "filtered" \| "unsupported" }[] }>` | One or more picked files were refused because `accept` excluded them. The element renders NO message of its own: it reports the facts (name, media type, whether the kit could have sent it) and what the user should see is the application's call. Only ever fires when `accept` is set. |
|
|
1627
|
-
| `kai-conversation-load` | `CustomEvent<{ id: string \| undefined; messages: { id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "
|
|
1630
|
+
| `kai-conversation-load` | `CustomEvent<{ id: string \| undefined; messages: { id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "dislike" \| "edit" \| "like" \| "regenerate" \| "speak" \| { 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" }[] }>` | A conversation's history loaded: a row tap in the list, "new conversation," or the visitor's own mount-time auto-restore of their most recent thread (only fires when `conversations` is on and a `store` is set). `detail.id` is that conversation's id, `undefined` for the "new conversation" case (no id exists until the first message mints one, C-6). Set `el.messages = event.detail.messages` (already a fresh array) to actually render it, since this element does not do that for you; `messages` stays your own state like everywhere else on this element. |
|
|
1628
1631
|
| `kai-home-link` | `CustomEvent<{ entry: { label: string; href?: undefined \| string; description?: undefined \| string; icon?: undefined \| string } }>` | A `home.links` entry with no `href` was activated (tapped/clicked/Enter). Meaningful only when `home` is set. |
|
|
1629
1632
|
| `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. |
|
|
1630
1633
|
| `kai-model-change` | `CustomEvent<{ modelId: string }>` | The header model switcher changed. |
|
|
@@ -2696,7 +2699,7 @@ _No events._
|
|
|
2696
2699
|
| Property | Attribute | Type | Description |
|
|
2697
2700
|
|---|---|---|---|
|
|
2698
2701
|
| `theme` | `theme` | `"light" \| "dark" \| "auto"` | Color mode (`auto` follows prefers-color-scheme). |
|
|
2699
|
-
| `message` | — | `undefined \| { id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "
|
|
2702
|
+
| `message` | — | `undefined \| { id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "dislike" \| "edit" \| "like" \| "regenerate" \| "speak" \| { 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. |
|
|
2700
2703
|
| `role` | `role` | `undefined \| "user" \| "assistant"` | Who is speaking: `'user'` or `'assistant'`. Convenience for simple cases when not passing a `message` object. This is the SEMANTIC role of the message, not an ARIA role. The name collides with the global ARIA `role` attribute, which is why the facade lifts it off the host (see `liftRoleOffHost`). Neither speaker is a valid ARIA role, so a `role="user"` left on `<kai-message>` is a CRITICAL axe `aria-roles` violation. The accessible role lives on the row inside the shadow root instead: `role="article"` plus an `aria-label` naming the speaker, matching the SolidJS `<Message>` component. |
|
|
2701
2704
|
| `markdown` | `markdown` | `undefined \| false \| true` | Force markdown on/off. Defaults to on for assistant, off for user. |
|
|
2702
2705
|
| `proseSize` | `prose-size` | `undefined \| "xs" \| "sm" \| "base" \| "lg"` | Text/markdown sizing for the message body. |
|
|
@@ -3867,7 +3870,7 @@ _No events._
|
|
|
3867
3870
|
| Property | Attribute | Type | Description |
|
|
3868
3871
|
|---|---|---|---|
|
|
3869
3872
|
| `theme` | `theme` | `"light" \| "dark" \| "auto"` | Color mode (`auto` follows prefers-color-scheme). |
|
|
3870
|
-
| `messages` | — | `undefined \| { id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "
|
|
3873
|
+
| `messages` | — | `undefined \| { id: string; role: "user" \| "assistant"; parts: ({ type: "text"; text: string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "reasoning"; text: string; label?: undefined \| string; index?: undefined \| number; streamId?: undefined \| string; signature?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } } \| { type: "tool"; tool: { type: string; kind?: undefined \| "command" \| "file-change" \| "search" \| "fetch" \| "mcp" \| "image" \| "generic"; state: "input-streaming" \| "input-available" \| "output-available" \| "output-error"; input?: undefined \| Record<string, unknown>; rawInput?: undefined \| string; output?: undefined \| Record<string, unknown>; toolCallId?: undefined \| string; errorText?: undefined \| string; raw?: undefined \| { source: string; payload: unknown } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "card"; envelope: { 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 } }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "source"; source: { id?: undefined \| string; url?: undefined \| string; title?: undefined \| string; snippet?: undefined \| string; index?: undefined \| number }; raw?: undefined \| { source: string; payload: unknown } } \| { type: "file"; attachment: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }; raw?: undefined \| { source: string; payload: unknown } })[]; actions?: undefined \| ("copy" \| "dislike" \| "edit" \| "like" \| "regenerate" \| "speak" \| { 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, ordered `parts`, and optional actions/avatar/feedback. Set as a JS property (`el.messages = [...]`); a NEW array reference per streaming chunk re-renders (mutating in place does not). |
|
|
3871
3874
|
| `loading` | `loading` | `undefined \| false \| true` | Show a typing indicator on the pending assistant turn. Set it while awaiting the assistant's reply. |
|
|
3872
3875
|
| `proseSize` | `prose-size` | `undefined \| "xs" \| "sm" \| "base" \| "lg"` | Body/prose font scale for rendered markdown (`'xs' \| 'sm' \| 'base' \| 'lg'`). Defaults to `'sm'`. |
|
|
3873
3876
|
| `codeTheme` | `code-theme` | `undefined \| string` | Shiki theme name for syntax-highlighted code blocks (e.g. `'github-dark-dimmed'`). |
|
package/llms.txt
CHANGED
|
@@ -56,7 +56,7 @@ interface ChatMessage {
|
|
|
56
56
|
/** The ONLY content channel. Ordered. */
|
|
57
57
|
parts: MessagePart[];
|
|
58
58
|
/** Action buttons under the message. Chrome, not content. */
|
|
59
|
-
actions?: ('copy' | 'like' | 'dislike' | 'regenerate' | 'edit')[];
|
|
59
|
+
actions?: ('copy' | 'like' | 'dislike' | 'regenerate' | 'edit' | 'speak')[];
|
|
60
60
|
avatar?: { src?: string; fallback?: string; alt?: string };
|
|
61
61
|
feedback?: 'like' | 'dislike';
|
|
62
62
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitn.ai/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"nx": {
|
|
5
5
|
"name": "ui",
|
|
6
6
|
"targets": {
|
|
@@ -139,6 +139,10 @@
|
|
|
139
139
|
"types": "./dist/agent-tooling/construct/public.d.ts",
|
|
140
140
|
"default": "./dist/construct.js"
|
|
141
141
|
},
|
|
142
|
+
"./construct/templates": {
|
|
143
|
+
"types": "./dist/agent-tooling/construct/templates.d.ts",
|
|
144
|
+
"default": "./dist/construct-templates.js"
|
|
145
|
+
},
|
|
142
146
|
"./provider": {
|
|
143
147
|
"types": "./dist/remote/provider.d.ts",
|
|
144
148
|
"default": "./dist/kai-provider.es.js"
|
|
@@ -172,11 +176,11 @@
|
|
|
172
176
|
"scripts": {
|
|
173
177
|
"prepublishOnly": "npm run build",
|
|
174
178
|
"prebuild": "npm run build:css && npm run build:card-validation",
|
|
175
|
-
"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.barrel.server.ts && vite build --config vite.config.solid.ts && vite build --config vite.config.solid.server.ts && vite build --config vite.config.state.ts && vite build --config vite.config.wire.ts && vite build --config vite.config.define.ts && vite build --config vite.config.define.server.ts && vite build --config vite.config.diagnostics.ts && vite build --config vite.config.schemas.ts && vite build --config vite.config.mcp.ts && vite build --config vite.config.construct-cli.ts && vite build --config vite.config.construct.ts && npm run build:elements && npm run dedupe:shiki && npm run verify:elements-bundle && npm run verify:react-wrappers && npm run verify:shader-lazy",
|
|
179
|
+
"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.barrel.server.ts && vite build --config vite.config.solid.ts && vite build --config vite.config.solid.server.ts && vite build --config vite.config.state.ts && vite build --config vite.config.wire.ts && vite build --config vite.config.define.ts && vite build --config vite.config.define.server.ts && vite build --config vite.config.diagnostics.ts && vite build --config vite.config.schemas.ts && vite build --config vite.config.mcp.ts && vite build --config vite.config.construct-cli.ts && vite build --config vite.config.construct.ts && vite build --config vite.config.construct-templates.ts && vite build --config vite.config.builder-page.ts && npm run build:elements && npm run dedupe:shiki && npm run verify:elements-bundle && npm run verify:react-wrappers && npm run verify:shader-lazy",
|
|
176
180
|
"build:elements": "node scripts/gen-elements-manifest.mjs && vite build --config vite.config.elements.ts && node scripts/gen-element-dts.mjs",
|
|
177
181
|
"postbuild": "npm run build:theme && npm run build:api && npm run build:schemas && npm run build:subpath-dts && npm run verify:dts",
|
|
178
182
|
"build:theme": "node scripts/build-theme-tokens.mjs",
|
|
179
|
-
"build:api": "node scripts/gen-elements-manifest.mjs && node scripts/gen-element-api.mjs && node scripts/gen-element-nonscalar.mjs && node scripts/gen-catalog.mjs && node scripts/gen-construct-schema.mjs",
|
|
183
|
+
"build:api": "node scripts/gen-elements-manifest.mjs && node scripts/gen-element-api.mjs && node scripts/gen-element-nonscalar.mjs && node scripts/gen-catalog.mjs && node scripts/gen-construct-schema.mjs && node scripts/gen-construct-template-fixtures.mjs",
|
|
180
184
|
"build:schemas": "node scripts/copy-card-schemas.mjs",
|
|
181
185
|
"build:card-validation": "node scripts/gen-card-validation-schemas.mjs",
|
|
182
186
|
"build:subpath-dts": "node scripts/emit-subpath-dts.mjs",
|
package/solid.css
CHANGED
|
@@ -26,8 +26,23 @@
|
|
|
26
26
|
the kit styles its own shadow roots. If you only want the tokens, import
|
|
27
27
|
theme.css instead and opt into the rest yourself.
|
|
28
28
|
|
|
29
|
-
Guarded by tests/styles/solid-css-contract.test.ts.
|
|
29
|
+
Guarded by tests/styles/solid-css-contract.test.ts.
|
|
30
|
+
|
|
31
|
+
ORDER IS LOAD-BEARING: every @import must come before any other statement
|
|
32
|
+
(CSS spec, @charset/empty @layer excepted) or it is silently DROPPED — not
|
|
33
|
+
an error, no output difference to eyeball, just gone. @tailwindcss/node's
|
|
34
|
+
own compile() (what the contract test above and the CLI's `tailwindcss`
|
|
35
|
+
binary use to build compiled.css) tolerates an out-of-order @import; a
|
|
36
|
+
plain Vite + @tailwindcss/postcss pipeline (e.g. a light-DOM Solid app's
|
|
37
|
+
own build, or this kit's src/builder-app) does not, and drops it — this
|
|
38
|
+
file used to put @plugin between two @imports, which silently dropped
|
|
39
|
+
theme.css AND kit-base.css from any consumer on that stricter pipeline:
|
|
40
|
+
every --color-* token gone, so anything reading one (a component's own
|
|
41
|
+
inline `style={{ stroke: 'var(--color-border)' }}`, not a Tailwind class —
|
|
42
|
+
Tailwind's dead-CSS-variable elimination doesn't know JS reads it) renders
|
|
43
|
+
as if the variable were never declared. Keep every @import above every
|
|
44
|
+
@plugin/@theme/@source/other statement in this file. */
|
|
30
45
|
@import "tw-animate-css";
|
|
31
|
-
@plugin "@tailwindcss/typography";
|
|
32
46
|
@import "./theme.css";
|
|
33
47
|
@import "./kit-base.css";
|
|
48
|
+
@plugin "@tailwindcss/typography";
|