@kitn.ai/ui 0.16.0 → 0.18.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 +55 -17
- package/dist/components/artifact.d.ts +39 -1
- package/dist/components/attachment-types.d.ts +12 -0
- package/dist/components/attachments.d.ts +2 -10
- package/dist/components/card.d.ts +27 -0
- package/dist/components/chain-of-thought.d.ts +78 -2
- package/dist/components/chat-scope-picker.d.ts +7 -0
- package/dist/components/chat-thread.d.ts +39 -16
- package/dist/components/choice-card.d.ts +27 -0
- package/dist/components/coachmark.d.ts +49 -0
- package/dist/components/composer-dom.d.ts +35 -0
- package/dist/components/composer-highlight.d.ts +48 -0
- package/dist/components/composer-history.d.ts +34 -0
- package/dist/components/composer.d.ts +86 -0
- package/dist/components/confirm-card.d.ts +17 -0
- package/dist/components/conversation-item.d.ts +9 -0
- package/dist/components/conversation-list.d.ts +36 -1
- package/dist/components/dismissed-stub.d.ts +22 -0
- package/dist/components/file-tree.d.ts +15 -0
- package/dist/components/form.d.ts +34 -0
- package/dist/components/markdown.d.ts +3 -0
- package/dist/components/message.d.ts +71 -2
- package/dist/components/model-switcher.d.ts +7 -0
- package/dist/components/prompt-input.d.ts +13 -4
- package/dist/components/prompt-suggestion.d.ts +9 -1
- package/dist/components/reasoning.d.ts +14 -1
- package/dist/components/response-compare-types.d.ts +66 -0
- package/dist/components/response-compare.d.ts +65 -0
- package/dist/components/screen.d.ts +46 -0
- package/dist/components/tasks-card.d.ts +50 -1
- package/dist/components/toast.d.ts +58 -0
- package/dist/components/tool-types.d.ts +10 -0
- package/dist/components/tool.d.ts +8 -8
- package/dist/components/use-card-resolution.d.ts +10 -6
- package/dist/components/voice-input.d.ts +27 -0
- package/dist/components/voice-output.d.ts +33 -0
- package/dist/core-C8fzo39E.js +12 -0
- package/dist/custom-elements.json +8472 -1691
- package/dist/elements/agent-card.d.ts +1 -0
- package/dist/elements/agent-card.js +1 -0
- package/dist/elements/artifact.js +1 -0
- package/dist/elements/attachments.js +1 -0
- package/dist/elements/autoloader.d.ts +2 -0
- package/dist/elements/autoloader.js +1 -0
- package/dist/elements/avatar.d.ts +1 -0
- package/dist/elements/avatar.js +1 -0
- package/dist/elements/badge.d.ts +1 -0
- package/dist/elements/badge.js +1 -0
- package/dist/elements/button.d.ts +1 -0
- package/dist/elements/button.js +1 -0
- package/dist/elements/card.js +1 -0
- package/dist/elements/cards.d.ts +1 -0
- package/dist/elements/cards.js +1 -0
- package/dist/elements/chain-of-thought.d.ts +0 -12
- package/dist/elements/chain-of-thought.js +1 -0
- package/dist/elements/chat-scope-picker.js +1 -0
- package/dist/elements/chat-types.d.ts +8 -2
- package/dist/elements/chat-workspace.js +1 -0
- package/dist/elements/chat.js +1 -0
- package/dist/elements/checkpoint.js +1 -0
- package/dist/elements/choice.js +1 -0
- package/dist/elements/chunks/Icon-DLLBeLG5.js +1 -0
- package/dist/elements/chunks/action-icons-UB4V5FNq.js +1 -0
- package/dist/elements/chunks/arrow-left-C-gwlUmx.js +1 -0
- package/dist/elements/chunks/attachments-CgbErf1r.js +1 -0
- package/dist/elements/chunks/badge-DTQpgB6N.js +1 -0
- package/dist/elements/chunks/bash-InADTalH.js +1 -0
- package/dist/elements/chunks/button-XDUM6lXs.js +1 -0
- package/dist/elements/chunks/card-CBlFZ-7I.js +1 -0
- package/dist/elements/chunks/card-routing-C986KuUA.js +1 -0
- package/dist/elements/chunks/chat-thread-BIhmqwNL.js +1 -0
- package/dist/elements/chunks/check-hGUoVIKb.js +1 -0
- package/dist/elements/chunks/chevron-down-DDoaSUtO.js +1 -0
- package/dist/elements/chunks/chevron-right-CdGEUakB.js +1 -0
- package/dist/elements/chunks/circle-BKAZdmzb.js +1 -0
- package/dist/elements/chunks/circle-check-CmYG-y3I.js +1 -0
- package/dist/elements/chunks/circle-x-DewgAEym.js +1 -0
- package/dist/elements/chunks/cn-CU7UAWzk.js +1 -0
- package/dist/elements/chunks/code-block-DedwxwFI.js +1 -0
- package/dist/elements/chunks/collapsible-FfgmTHtM.js +1 -0
- package/dist/elements/chunks/composer-Cfbw5HKT.js +65 -0
- package/dist/elements/chunks/context-DwJmxlRE.js +1 -0
- package/dist/elements/chunks/conversation-list-DsCQMfPq.js +1 -0
- package/dist/elements/chunks/core-AYMC6_lb.js +12 -0
- package/dist/elements/chunks/css-M7EaDHN_.js +1 -0
- package/dist/elements/chunks/default-input-BuqsoENC.js +1 -0
- package/dist/elements/chunks/define-rGsaWsLL.js +1 -0
- package/dist/elements/chunks/disclosure-CwoAkpMH.js +1 -0
- package/dist/elements/chunks/download-DJ06G3Bz.js +1 -0
- package/dist/elements/chunks/dropdown-BFg8ri_R.js +1 -0
- package/dist/elements/chunks/ellipsis-dlN6YvGw.js +1 -0
- package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +141 -0
- package/dist/elements/chunks/external-link-DBX2lc_R.js +1 -0
- package/dist/elements/chunks/file-text-HfwUx4F9.js +1 -0
- package/dist/elements/chunks/file-tree-C6Toj71u.js +1 -0
- package/dist/elements/chunks/folder-MYuqa9Xp.js +1 -0
- package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +1 -0
- package/dist/elements/chunks/github-light-JYsPkUQd.js +1 -0
- package/dist/elements/chunks/hover-card-gE7iyXdW.js +1 -0
- package/dist/elements/chunks/html-CPZ3oZQ7.js +1 -0
- package/dist/elements/chunks/icon-Vqz4ivrY.js +1 -0
- package/dist/elements/chunks/index-BCRhi84a.js +1 -0
- package/dist/elements/chunks/info-B_toFS0l.js +1 -0
- package/dist/elements/chunks/input-gzbHYZvQ.js +1 -0
- package/dist/elements/chunks/javascript-C25yR2R2.js +1 -0
- package/dist/elements/chunks/json-DxJze_jm.js +1 -0
- package/dist/elements/chunks/kbd-n49c4KZm.js +1 -0
- package/dist/elements/chunks/link-CKPs9yM0.js +1 -0
- package/dist/elements/chunks/loader-q6MamGus.js +1 -0
- package/dist/elements/chunks/markdown-DBrcqq4S.js +64 -0
- package/dist/elements/chunks/message-CTqaYI0s.js +1 -0
- package/dist/elements/chunks/message-feedback-Cvzm03w0.js +1 -0
- package/dist/elements/chunks/message-square-CUg9eRCi.js +1 -0
- package/dist/elements/chunks/minimize-2-l2klxP6K.js +1 -0
- package/dist/elements/chunks/model-switcher-CmyjiHO1.js +1 -0
- package/dist/elements/chunks/overlay-C8sOYqjT.js +1 -0
- package/dist/elements/chunks/paperclip-42Ia7xHD.js +1 -0
- package/dist/elements/chunks/progress-bar-tzKMWAwO.js +1 -0
- package/dist/elements/chunks/prompt-suggestion-D3F6vP_A.js +1 -0
- package/dist/elements/chunks/reasoning-BJNmmyov.js +1 -0
- package/dist/elements/chunks/resizable-BRsk19qI.js +1 -0
- package/dist/elements/chunks/rotate-cw-BgcggLHC.js +1 -0
- package/dist/elements/chunks/scroll-area-CgGbFFbT.js +1 -0
- package/dist/elements/chunks/separator-8hM4GdHE.js +1 -0
- package/dist/elements/chunks/settings-CaUIYOg-.js +1 -0
- package/dist/elements/chunks/settings-group-CYjOVIZQ.js +1 -0
- package/dist/elements/chunks/share-BTYM3Ddt.js +1 -0
- package/dist/elements/chunks/skeleton-DsTYrPUe.js +1 -0
- package/dist/elements/chunks/slots-DkZ-Cmha.js +1 -0
- package/dist/elements/chunks/star-9R3LBQ9n.js +1 -0
- package/dist/elements/chunks/store-CYl5Y0_u.js +1 -0
- package/dist/elements/chunks/svelte--5p79yCD.js +1 -0
- package/dist/elements/chunks/text-shimmer-CaYGv8Se.js +1 -0
- package/dist/elements/chunks/textarea-NEr2SLcD.js +1 -0
- package/dist/elements/chunks/thumbs-up-DZYZkFfc.js +1 -0
- package/dist/elements/chunks/toast-store-ClxVZRcc.js +1 -0
- package/dist/elements/chunks/tool-CHZOmoe9.js +1 -0
- package/dist/elements/chunks/tooltip-WpHElELC.js +1 -0
- package/dist/elements/chunks/triangle-alert-BlS80PUg.js +1 -0
- package/dist/elements/chunks/tsx-B8rCNbgL.js +1 -0
- package/dist/elements/chunks/typescript-RycA9KXf.js +1 -0
- package/dist/elements/chunks/use-card-resolution-VSVoxDeJ.js +1 -0
- package/dist/elements/chunks/video-DxTPZqT8.js +1 -0
- package/dist/elements/chunks/vue-BmIZj4XD.js +1 -0
- package/dist/elements/chunks/x-C1qtndxn.js +1 -0
- package/dist/elements/coachmark.d.ts +1 -0
- package/dist/elements/coachmark.js +1 -0
- package/dist/elements/code-block.js +1 -0
- package/dist/elements/command.d.ts +1 -0
- package/dist/elements/command.js +1 -0
- package/dist/elements/compare.d.ts +1 -0
- package/dist/elements/compare.js +1 -0
- package/dist/elements/composer.d.ts +1 -0
- package/dist/elements/composer.js +1 -0
- package/dist/elements/confirm-card.js +1 -0
- package/dist/elements/context-meter.js +1 -0
- package/dist/elements/conversation-list.d.ts +1 -11
- package/dist/elements/conversation-list.js +1 -0
- package/dist/elements/default-input.d.ts +20 -9
- package/dist/elements/define.d.ts +11 -0
- package/dist/elements/dialog.d.ts +1 -0
- package/dist/elements/dialog.js +1 -0
- package/dist/elements/disclosure.d.ts +37 -0
- package/dist/elements/editable-label.d.ts +1 -0
- package/dist/elements/editable-label.js +1 -0
- package/dist/elements/embed.js +1 -0
- package/dist/elements/empty.js +1 -0
- package/dist/elements/feedback-bar.js +1 -0
- package/dist/elements/file-tree.js +1 -0
- package/dist/elements/file-upload.js +1 -0
- package/dist/elements/form.js +1 -0
- package/dist/elements/hover-card.d.ts +1 -0
- package/dist/elements/hover-card.js +1 -0
- package/dist/elements/icon.d.ts +1 -0
- package/dist/elements/icon.js +1 -0
- package/dist/elements/image.js +1 -0
- package/dist/elements/input.d.ts +1 -0
- package/dist/elements/input.js +1 -0
- package/dist/elements/kbd.d.ts +1 -0
- package/dist/elements/kbd.js +1 -0
- package/dist/elements/link-preview.js +1 -0
- package/dist/elements/loader.js +1 -0
- package/dist/elements/markdown.js +1 -0
- package/dist/elements/menu.d.ts +1 -0
- package/dist/elements/menu.js +1 -0
- package/dist/elements/message-skills.d.ts +0 -16
- package/dist/elements/message-skills.js +1 -0
- package/dist/elements/message.js +1 -0
- package/dist/elements/model-switcher.d.ts +1 -11
- package/dist/elements/model-switcher.js +1 -0
- package/dist/elements/nav.d.ts +1 -0
- package/dist/elements/nav.js +1 -0
- package/dist/elements/notice.d.ts +1 -0
- package/dist/elements/notice.js +1 -0
- package/dist/elements/pane-group.d.ts +1 -0
- package/dist/elements/pane-group.js +1 -0
- package/dist/elements/pane.d.ts +1 -0
- package/dist/elements/pane.js +1 -0
- package/dist/elements/popover.js +1 -0
- package/dist/elements/progress-bar.d.ts +1 -0
- package/dist/elements/progress-bar.js +1 -0
- package/dist/elements/prompt-dock.d.ts +1 -0
- package/dist/elements/prompt-dock.js +1 -0
- package/dist/elements/prompt-input.d.ts +1 -9
- package/dist/elements/prompt-input.js +1 -0
- package/dist/elements/prompt-suggestions.d.ts +0 -6
- package/dist/elements/prompt-suggestions.js +1 -0
- package/dist/elements/reasoning.js +1 -0
- package/dist/elements/register.d.ts +10 -0
- package/dist/elements/remote.js +1 -0
- package/dist/elements/resizable.d.ts +1 -17
- package/dist/elements/resizable.js +1 -0
- package/dist/elements/response-stream.js +14 -0
- package/dist/elements/screen.d.ts +1 -0
- package/dist/elements/screen.js +1 -0
- package/dist/elements/scroll-area.d.ts +1 -0
- package/dist/elements/scroll-area.js +1 -0
- package/dist/elements/scroll-button.js +1 -0
- package/dist/elements/search.d.ts +1 -0
- package/dist/elements/search.js +1 -0
- package/dist/elements/segmented.d.ts +1 -0
- package/dist/elements/segmented.js +1 -0
- package/dist/elements/separator.d.ts +1 -0
- package/dist/elements/separator.js +1 -0
- package/dist/elements/setting-item.d.ts +1 -0
- package/dist/elements/setting-item.js +1 -0
- package/dist/elements/settings-group.d.ts +1 -0
- package/dist/elements/settings-group.js +1 -0
- package/dist/elements/skeleton.d.ts +1 -0
- package/dist/elements/skeleton.js +1 -0
- package/dist/elements/slots.d.ts +176 -0
- package/dist/elements/source.d.ts +0 -17
- package/dist/elements/source.js +1 -0
- package/dist/elements/status.d.ts +1 -0
- package/dist/elements/status.js +1 -0
- package/dist/elements/switch.js +1 -0
- package/dist/elements/tabs.d.ts +1 -0
- package/dist/elements/tabs.js +1 -0
- package/dist/elements/tasks.js +1 -0
- package/dist/elements/text-shimmer.js +1 -0
- package/dist/elements/thinking-bar.js +1 -0
- package/dist/elements/toast.d.ts +1 -0
- package/dist/elements/toast.js +1 -0
- package/dist/elements/tool.js +1 -0
- package/dist/elements/tooltip.d.ts +1 -0
- package/dist/elements/tooltip.js +1 -0
- package/dist/elements/voice-input.js +1 -0
- package/dist/elements/voice-output.d.ts +1 -0
- package/dist/elements/voice-output.js +1 -0
- package/dist/elements.d.ts +772 -61
- package/dist/engine-javascript-C1x7zo1_.js +141 -0
- package/dist/index.d.ts +15 -2
- package/dist/index.js +14405 -9810
- package/dist/kai.es.js +1 -0
- package/dist/llms/llms-full.txt +1234 -107
- package/dist/llms/llms.txt +4 -4
- package/dist/mcp.es.js +217 -6
- package/dist/primitives/card-contract.d.ts +20 -4
- package/dist/primitives/card-recovery.d.ts +55 -0
- package/dist/primitives/composer-model.d.ts +22 -0
- package/dist/primitives/composer-triggers.d.ts +19 -0
- package/dist/primitives/create-kai-chat.d.ts +38 -0
- package/dist/primitives/message-feedback.d.ts +35 -0
- package/dist/primitives/toast-store.d.ts +118 -0
- package/dist/primitives/use-speech-recognition.d.ts +26 -0
- package/dist/react/index.d.ts +1166 -98
- package/dist/react/runtime.d.ts +9 -2
- package/dist/react/use-kai-chat.d.ts +41 -0
- package/dist/react.js +575 -186
- package/dist/register-impl-CYWGkgbI.js +141 -0
- package/dist/schemas/choice.schema.json +5 -0
- package/dist/schemas/tasks.schema.json +7 -2
- package/dist/state/index.d.ts +4 -0
- package/dist/state/messages.d.ts +11 -0
- package/dist/state/stream.d.ts +22 -0
- package/dist/state/suggestions.d.ts +4 -0
- package/dist/state.js +117 -0
- package/dist/theme.tokens.css +87 -0
- package/dist/types.d.ts +4 -0
- package/dist/ui/agent-card.d.ts +61 -0
- package/dist/ui/button.d.ts +5 -2
- package/dist/ui/card.d.ts +61 -0
- package/dist/ui/collapsible.d.ts +15 -1
- package/dist/ui/command.d.ts +33 -0
- package/dist/ui/dialog.d.ts +42 -0
- package/dist/ui/dropdown.d.ts +95 -1
- package/dist/ui/editable-label.d.ts +26 -0
- package/dist/ui/hover-card.d.ts +13 -1
- package/dist/ui/icon.d.ts +18 -0
- package/dist/ui/input.d.ts +33 -0
- package/dist/ui/kbd.d.ts +21 -0
- package/dist/ui/nav.d.ts +62 -0
- package/dist/ui/notice.d.ts +31 -0
- package/dist/ui/overlay.d.ts +12 -0
- package/dist/ui/pane-grid.d.ts +58 -0
- package/dist/ui/pane-group.d.ts +75 -0
- package/dist/ui/pane.d.ts +78 -0
- package/dist/ui/popover.d.ts +11 -1
- package/dist/ui/progress-bar.d.ts +23 -0
- package/dist/ui/prompt-dock.d.ts +96 -0
- package/dist/ui/resizable.d.ts +12 -0
- package/dist/ui/scroll-area.d.ts +4 -0
- package/dist/ui/segmented.d.ts +28 -0
- package/dist/ui/settings-group.d.ts +32 -0
- package/dist/ui/skeleton.d.ts +12 -0
- package/dist/ui/stat.d.ts +16 -0
- package/dist/ui/status.d.ts +13 -0
- package/dist/ui/switch.d.ts +8 -1
- package/dist/ui/tabs.d.ts +35 -0
- package/dist/ui/tooltip.d.ts +20 -1
- package/frameworks/react/index.tsx +1100 -163
- package/frameworks/react/runtime.tsx +30 -1
- package/frameworks/react/use-kai-chat.tsx +87 -0
- package/llms-full.txt +1234 -107
- package/llms.txt +4 -4
- package/package.json +36 -12
- package/src/agent-tooling/mcp/manifest.ts +14 -0
- package/src/agent-tooling/mcp/tools/debug.ts +194 -6
- package/src/agent-tooling/mcp/tools/reference.ts +32 -0
- package/src/agent-tooling/mcp/tools/scaffold.ts +162 -1
- package/src/components/artifact.tsx +98 -13
- package/src/components/attachment-types.ts +13 -0
- package/src/components/attachments.tsx +4 -14
- package/src/components/card.tsx +109 -15
- package/src/components/chain-of-thought.tsx +210 -1
- package/src/components/chat-scope-picker.tsx +13 -3
- package/src/components/chat-thread.tsx +238 -137
- package/src/components/choice-card.tsx +136 -15
- package/src/components/coachmark.tsx +245 -0
- package/src/components/component-meta.json +921 -108
- package/src/components/composer-dom.ts +159 -0
- package/src/components/composer-highlight.ts +242 -0
- package/src/components/composer-history.ts +82 -0
- package/src/components/composer.tsx +979 -0
- package/src/components/confirm-card.tsx +69 -2
- package/src/components/conversation-item.tsx +69 -7
- package/src/components/conversation-list.tsx +134 -37
- package/src/components/dismissed-stub.tsx +80 -0
- package/src/components/file-tree.tsx +197 -47
- package/src/components/form-widgets.tsx +9 -7
- package/src/components/form.tsx +161 -20
- package/src/components/image.tsx +3 -5
- package/src/components/link-preview.tsx +5 -4
- package/src/components/markdown.tsx +5 -2
- package/src/components/message.tsx +174 -14
- package/src/components/model-switcher.tsx +19 -4
- package/src/components/prompt-input.tsx +46 -75
- package/src/components/prompt-suggestion.tsx +48 -16
- package/src/components/reasoning.tsx +29 -6
- package/src/components/response-compare-types.ts +127 -0
- package/src/components/response-compare.tsx +460 -0
- package/src/components/screen.tsx +176 -0
- package/src/components/tasks-card.tsx +374 -23
- package/src/components/toast.tsx +486 -0
- package/src/components/tool-types.ts +10 -0
- package/src/components/tool.tsx +22 -16
- package/src/components/use-card-resolution.ts +24 -8
- package/src/components/voice-input.tsx +102 -19
- package/src/components/voice-output.tsx +202 -0
- package/src/elements/agent-card.tsx +67 -0
- package/src/elements/artifact.tsx +53 -4
- package/src/elements/attachments.tsx +1 -0
- package/src/elements/autoloader.ts +89 -0
- package/src/elements/avatar.tsx +33 -0
- package/src/elements/badge.tsx +32 -0
- package/src/elements/button.tsx +126 -0
- package/src/elements/card-media.jpg +0 -0
- package/src/elements/card.tsx +124 -31
- package/src/elements/cards.tsx +81 -7
- package/src/elements/chain-of-thought.tsx +77 -32
- package/src/elements/chat-scope-picker.tsx +35 -8
- package/src/elements/chat-types.ts +9 -2
- package/src/elements/chat-workspace.tsx +157 -43
- package/src/elements/chat.tsx +49 -25
- package/src/elements/choice.tsx +71 -19
- package/src/elements/coachmark.tsx +90 -0
- package/src/elements/command.tsx +209 -0
- package/src/elements/compare.tsx +110 -0
- package/src/elements/compiled.css +1 -1
- package/src/elements/composer.tsx +151 -0
- package/src/elements/confirm-card.tsx +36 -11
- package/src/elements/conversation-list.tsx +80 -11
- package/src/elements/default-input.tsx +75 -53
- package/src/elements/define.tsx +47 -6
- package/src/elements/dialog.tsx +98 -0
- package/src/elements/disclosure.ts +73 -0
- package/src/elements/editable-label.tsx +125 -0
- package/src/elements/element-manifest.json +310 -0
- package/src/elements/element-meta.json +5954 -1605
- package/src/elements/element-types.d.ts +771 -60
- package/src/elements/file-tree.tsx +12 -2
- package/src/elements/file-upload.tsx +1 -1
- package/src/elements/form.tsx +54 -11
- package/src/elements/hover-card.tsx +80 -0
- package/src/elements/icon-names.json +48 -0
- package/src/elements/icon.tsx +41 -0
- package/src/elements/input.tsx +203 -0
- package/src/elements/kbd.tsx +45 -0
- package/src/elements/menu.tsx +217 -0
- package/src/elements/message.tsx +84 -55
- package/src/elements/model-switcher.tsx +27 -1
- package/src/elements/nav.tsx +87 -0
- package/src/elements/notice.tsx +53 -0
- package/src/elements/pane-group.tsx +119 -0
- package/src/elements/pane.tsx +129 -0
- package/src/elements/popover.tsx +39 -17
- package/src/elements/progress-bar.tsx +39 -0
- package/src/elements/prompt-dock.tsx +81 -0
- package/src/elements/prompt-input.tsx +112 -63
- package/src/elements/prompt-suggestions.tsx +25 -9
- package/src/elements/reasoning.tsx +30 -9
- package/src/elements/register-impl.ts +41 -3
- package/src/elements/register.ts +20 -3
- package/src/elements/remote.tsx +4 -0
- package/src/elements/resizable.tsx +48 -11
- package/src/elements/screen.tsx +90 -0
- package/src/elements/scroll-area.tsx +33 -0
- package/src/elements/search.tsx +180 -0
- package/src/elements/segmented.tsx +135 -0
- package/src/elements/separator.tsx +36 -0
- package/src/elements/setting-item.tsx +50 -0
- package/src/elements/settings-group.tsx +37 -0
- package/src/elements/skeleton.tsx +45 -0
- package/src/elements/slots.ts +607 -0
- package/src/elements/source.tsx +13 -6
- package/src/elements/status.tsx +42 -0
- package/src/elements/styles.css +19 -0
- package/src/elements/switch.tsx +89 -14
- package/src/elements/tabs.tsx +95 -0
- package/src/elements/tasks.tsx +70 -14
- package/src/elements/toast.tsx +89 -0
- package/src/elements/tool.tsx +43 -9
- package/src/elements/tooltip.tsx +85 -0
- package/src/elements/video-poster.jpg +0 -0
- package/src/elements/voice-input.tsx +66 -16
- package/src/elements/voice-output.tsx +69 -0
- package/src/index.ts +35 -2
- package/src/primitives/card-contract.ts +14 -5
- package/src/primitives/card-recovery.ts +149 -0
- package/src/primitives/card-routing.ts +3 -0
- package/src/primitives/card-schemas/choice.schema.json +5 -0
- package/src/primitives/card-schemas/tasks.schema.json +7 -2
- package/src/primitives/composer-model.ts +49 -0
- package/src/primitives/composer-triggers.ts +35 -0
- package/src/primitives/create-kai-chat.ts +66 -0
- package/src/primitives/message-feedback.ts +123 -0
- package/src/primitives/toast-store.ts +276 -0
- package/src/primitives/use-speech-recognition.ts +135 -0
- package/src/state/index.ts +6 -0
- package/src/state/messages.ts +36 -0
- package/src/state/stream.ts +92 -0
- package/src/state/suggestions.ts +9 -0
- package/src/types.ts +4 -0
- package/src/ui/agent-card.tsx +212 -0
- package/src/ui/button.tsx +16 -5
- package/src/ui/card.tsx +245 -0
- package/src/ui/collapsible.tsx +30 -4
- package/src/ui/command.tsx +99 -0
- package/src/ui/dialog.tsx +217 -0
- package/src/ui/dropdown.tsx +375 -13
- package/src/ui/editable-label.tsx +112 -0
- package/src/ui/hover-card.tsx +28 -5
- package/src/ui/icon.tsx +110 -0
- package/src/ui/input.tsx +132 -0
- package/src/ui/kbd.tsx +118 -0
- package/src/ui/nav.tsx +282 -0
- package/src/ui/notice.tsx +84 -0
- package/src/ui/overlay.tsx +108 -2
- package/src/ui/pane-grid.tsx +116 -0
- package/src/ui/pane-group.tsx +280 -0
- package/src/ui/pane.tsx +193 -0
- package/src/ui/popover.tsx +16 -2
- package/src/ui/progress-bar.tsx +83 -0
- package/src/ui/prompt-dock.tsx +145 -0
- package/src/ui/resizable.tsx +69 -1
- package/src/ui/scroll-area.tsx +14 -3
- package/src/ui/segmented.tsx +109 -0
- package/src/ui/settings-group.tsx +67 -0
- package/src/ui/skeleton.tsx +62 -5
- package/src/ui/stat.tsx +41 -0
- package/src/ui/status.tsx +48 -0
- package/src/ui/switch.tsx +49 -23
- package/src/ui/tabs.tsx +168 -0
- package/src/ui/tooltip.tsx +57 -7
- package/theme.css +113 -0
- package/dist/components/slash-command.d.ts +0 -15
- package/dist/kitn-chat.es.js +0 -1
- package/dist/register-impl-wCsFPoh9.js +0 -77
- package/dist/register-ujhr1nBS.js +0 -1
- package/src/components/slash-command.tsx +0 -232
- package/src/elements/framework-usage.json +0 -563
- /package/dist/{kitn-chat-provider.d.ts → kai-provider.d.ts} +0 -0
- /package/dist/{kitn-chat-provider.es.js → kai-provider.es.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { splitProps, Show, For } from 'solid-js';
|
|
2
2
|
import { cn } from '../utils/cn';
|
|
3
|
-
import { Dropdown, DropdownTrigger, DropdownContent, DropdownItem } from '../ui/dropdown';
|
|
3
|
+
import { Dropdown, DropdownTrigger, DropdownContent, DropdownItem, type DropdownController } from '../ui/dropdown';
|
|
4
4
|
import { Button } from '../ui/button';
|
|
5
5
|
import type { SearchFilters } from '../types';
|
|
6
6
|
|
|
@@ -10,12 +10,22 @@ export interface ChatScopePickerProps {
|
|
|
10
10
|
availableAuthors?: string[];
|
|
11
11
|
availableTags?: string[];
|
|
12
12
|
class?: string;
|
|
13
|
+
/** Initial open state of the dropdown (uncontrolled seed). */
|
|
14
|
+
defaultOpen?: boolean;
|
|
15
|
+
/** Disable the trigger — click/keyboard no longer open the dropdown. */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/** Receive the dropdown's open controller (forwarded from the inner Dropdown). */
|
|
18
|
+
controllerRef?: (api: DropdownController) => void;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
export function ChatScopePicker(props: ChatScopePickerProps) {
|
|
16
|
-
const [local] = splitProps(props, ['currentLabel', 'onScopeChange', 'availableAuthors', 'availableTags', 'class']);
|
|
22
|
+
const [local] = splitProps(props, ['currentLabel', 'onScopeChange', 'availableAuthors', 'availableTags', 'class', 'defaultOpen', 'disabled', 'controllerRef']);
|
|
17
23
|
return (
|
|
18
|
-
<Dropdown
|
|
24
|
+
<Dropdown
|
|
25
|
+
defaultOpen={local.defaultOpen}
|
|
26
|
+
disabled={local.disabled}
|
|
27
|
+
controllerRef={local.controllerRef}
|
|
28
|
+
>
|
|
19
29
|
<DropdownTrigger as={(triggerProps: any) => (
|
|
20
30
|
<Button variant="ghost" size="sm" class={cn('gap-1 text-xs', local.class)} {...triggerProps}>
|
|
21
31
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { createSignal, For, Show } from 'solid-js';
|
|
1
|
+
import { createSignal, createEffect, For, Show, onMount } from 'solid-js';
|
|
2
2
|
import { ChatConfig, useChatConfig } from '../primitives/chat-config';
|
|
3
|
+
import { type ComposerDoc, normalizeValue, serializeToText } from '../primitives/composer-model';
|
|
3
4
|
import { ChatContainer, ChatContainerContent, ChatContainerScrollAnchor } from './chat-container';
|
|
4
|
-
import { Message, MessageAvatar,
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { Attachments, Attachment, AttachmentPreview, AttachmentInfo, type AttachmentData } from './attachments';
|
|
5
|
+
import { Message, MessageAvatar, MessageBody } from './message';
|
|
6
|
+
import { type AttachmentData } from './attachments';
|
|
7
|
+
import { createMessageFeedback, type MessageActionDetail } from '../primitives/message-feedback';
|
|
8
8
|
import { ModelSwitcher } from './model-switcher';
|
|
9
9
|
import { ScrollButton } from './scroll-button';
|
|
10
10
|
import {
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
ContextContentBody, ContextContentFooter, ContextInputUsage, ContextOutputUsage,
|
|
13
13
|
} from './context';
|
|
14
14
|
import { DefaultPromptInput } from '../elements/default-input';
|
|
15
|
-
import type {
|
|
15
|
+
import type { TriggerDef } from './composer';
|
|
16
16
|
import type { ChatMessage } from '../elements/chat-types';
|
|
17
17
|
import type { ProseSize } from '../primitives/chat-config';
|
|
18
18
|
import type { ModelOption } from '../types';
|
|
@@ -32,9 +32,10 @@ export interface ChatThreadProps {
|
|
|
32
32
|
* content, and optional reasoning/tools/attachments/actions. Set as a JS
|
|
33
33
|
* property (`el.messages = [...]`). */
|
|
34
34
|
messages: ChatMessage[];
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
-
|
|
35
|
+
/** Value of the input. A **string** is controlled (the host owns the text and
|
|
36
|
+
* updates it on `kai-value-change`). A **ComposerDoc** is a one-time seed that
|
|
37
|
+
* pre-populates pills; the user then edits freely. Leave unset for uncontrolled. */
|
|
38
|
+
value?: string | ComposerDoc;
|
|
38
39
|
/** Placeholder text shown in the empty input. */
|
|
39
40
|
placeholder?: string;
|
|
40
41
|
/** When true, shows the loading/streaming state and disables submit (use while
|
|
@@ -76,42 +77,97 @@ export interface ChatThreadProps {
|
|
|
76
77
|
headerStart?: boolean;
|
|
77
78
|
/** Whether the host has `slot="header-end"` content (right of the controls). */
|
|
78
79
|
headerEnd?: boolean;
|
|
80
|
+
// ── Composition slots ─────────────────────────────────────────────────────
|
|
81
|
+
// Each flag below is set by the `<kai-chat>` facade when matching light-DOM
|
|
82
|
+
// `slot="…"` content is projected, and gates one composition slot. Two kinds:
|
|
83
|
+
// • INJECT — additive: project YOUR markup into a region (sidebar, footer,
|
|
84
|
+
// composer-actions, header-start/-end).
|
|
85
|
+
// • REPLACE — substitutive: your markup stands in for a whole region
|
|
86
|
+
// (header, empty, composer). A replaced region's projected
|
|
87
|
+
// content owns its own data/events — a slotted (light-DOM) node
|
|
88
|
+
// can't read this component's reactive state. That boundary is
|
|
89
|
+
// the whole reason `messages` stays a data prop, not a slot.
|
|
90
|
+
/** REPLACE — full custom header in place of the built-in title/model/context bar. */
|
|
91
|
+
headerFull?: boolean;
|
|
92
|
+
/** INJECT — left sidebar column (e.g. a conversation list / your own nav). */
|
|
93
|
+
sidebar?: boolean;
|
|
94
|
+
/** REPLACE — custom zero-state rendered in the message area while the thread is empty (replaces the empty message list only; the composer and its suggestions still render). */
|
|
95
|
+
empty?: boolean;
|
|
96
|
+
/** REPLACE — full custom composer in place of the built-in prompt input. The
|
|
97
|
+
* projected content wires its own submit (the data-flow boundary). */
|
|
98
|
+
composer?: boolean;
|
|
99
|
+
/** INJECT — accessory row just above the composer (e.g. extra actions). */
|
|
100
|
+
composerActions?: boolean;
|
|
101
|
+
/** INJECT — footer row below the composer (disclaimers, token meter, …). */
|
|
102
|
+
footer?: boolean;
|
|
79
103
|
/** Show a Search (Globe) button in the input toolbar; fires a `search` event. */
|
|
80
104
|
search?: boolean;
|
|
81
105
|
/** Show a Voice (Mic) button in the input toolbar; fires a `voice` event. */
|
|
82
106
|
voice?: boolean;
|
|
83
|
-
/**
|
|
84
|
-
*
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
slashCompact?: boolean;
|
|
107
|
+
/** Rich entity triggers — each `{ char, kind, items }` opens a caret-anchored
|
|
108
|
+
* menu that inserts an atomic pill (`/` skills, `@` agents/plugins). Set as a
|
|
109
|
+
* JS property; forwarded to the input. */
|
|
110
|
+
triggers?: TriggerDef[];
|
|
111
|
+
/** Default icon per entity kind (kind → image src) for pills/menu items. */
|
|
112
|
+
kindIcons?: Record<string, string>;
|
|
90
113
|
/** Whether each message's action bar is always visible (`'always'`, default)
|
|
91
114
|
* or only revealed on hover of that message row (`'hover'`). */
|
|
92
115
|
actionsReveal?: 'always' | 'hover';
|
|
93
116
|
// callbacks (the facade maps these to dispatch())
|
|
94
117
|
onValueChange?: (value: string) => void;
|
|
95
118
|
onSubmit?: (detail: { value: string; attachments: AttachmentData[] }) => void;
|
|
119
|
+
onAttachmentsChange?: (attachments: AttachmentData[]) => void;
|
|
96
120
|
onSuggestionClick?: (value: string) => void;
|
|
97
121
|
onModelChange?: (modelId: string) => void;
|
|
98
|
-
onMessageAction?: (detail:
|
|
122
|
+
onMessageAction?: (detail: MessageActionDetail) => void;
|
|
99
123
|
onSearch?: () => void;
|
|
100
124
|
onVoice?: () => void;
|
|
101
|
-
|
|
125
|
+
/** Receive the imperative controller once mounted. The kai-chat facade forwards
|
|
126
|
+
* these as element methods (focus/clear/send/scrollToBottom). */
|
|
127
|
+
controllerRef?: (controller: ChatThreadController) => void;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Imperative handle exposed via `controllerRef` — the input half of the chat's
|
|
131
|
+
* interaction surface, forwarded onto `<kai-chat>` as instance methods. */
|
|
132
|
+
export interface ChatThreadController {
|
|
133
|
+
focus(options?: FocusOptions): void;
|
|
134
|
+
clear(): void;
|
|
135
|
+
send(): void;
|
|
136
|
+
scrollToBottom(behavior?: ScrollBehavior): void;
|
|
102
137
|
}
|
|
103
138
|
|
|
104
139
|
export function ChatThread(props: ChatThreadProps) {
|
|
105
140
|
const outer = useChatConfig();
|
|
106
141
|
const reveal = () => (props.actionsReveal === 'hover' ? 'hover' : 'always');
|
|
107
|
-
|
|
142
|
+
// Feedback (copy + vote) state lives ABOVE the per-message <For>, so streaming
|
|
143
|
+
// re-renders (a fresh `messages` array ref per chunk) don't wipe it.
|
|
144
|
+
// The copy/feedback toasts scope to the chat (this thread's root) so they appear
|
|
145
|
+
// in-chat rather than at the page top.
|
|
146
|
+
let rootEl: HTMLElement | undefined;
|
|
147
|
+
const feedback = createMessageFeedback({
|
|
148
|
+
emit: (detail) => props.onMessageAction?.(detail),
|
|
149
|
+
target: () => rootEl,
|
|
150
|
+
});
|
|
151
|
+
const [internal, setInternal] = createSignal<string | ComposerDoc>(props.value ?? '');
|
|
108
152
|
const [attachments, setAttachments] = createSignal<AttachmentData[]>([]);
|
|
109
|
-
|
|
153
|
+
// A string `value` is controlled; a ComposerDoc `value` is a one-time seed that
|
|
154
|
+
// lives in `internal` so the user's (string) edits replace it without a fight.
|
|
155
|
+
const current = (): string | ComposerDoc =>
|
|
156
|
+
typeof props.value === 'string' ? props.value : internal();
|
|
157
|
+
createEffect(() => {
|
|
158
|
+
const v = props.value;
|
|
159
|
+
if (v != null && typeof v !== 'string') setInternal(v);
|
|
160
|
+
});
|
|
110
161
|
const handleChange = (v: string) => { setInternal(v); props.onValueChange?.(v); };
|
|
111
|
-
|
|
162
|
+
// After a send, reset the composer. Clear the internal draft ONLY when the value is
|
|
163
|
+
// uncontrolled (props.value === undefined) — a controlled host owns its own value and
|
|
164
|
+
// clears it itself. This lets the batteries-included hooks (useKaiChat/createKaiChat),
|
|
165
|
+
// whose `bind` does not control `value`, get a clean composer after each submit.
|
|
166
|
+
const afterSubmit = () => { setAttachments([]); if (props.value === undefined) setInternal(''); };
|
|
167
|
+
const handleSubmit = () => { props.onSubmit?.({ value: serializeToText(normalizeValue(current())), attachments: attachments() }); afterSubmit(); };
|
|
112
168
|
const handleSuggestionClick = (v: string) => {
|
|
113
169
|
if ((props.suggestionMode ?? 'submit') === 'fill') { handleChange(v); props.onSuggestionClick?.(v); }
|
|
114
|
-
else { props.onSubmit?.({ value: v, attachments: attachments() });
|
|
170
|
+
else { props.onSubmit?.({ value: v, attachments: attachments() }); afterSubmit(); }
|
|
115
171
|
};
|
|
116
172
|
const showHeader = () => !!(props.chatTitle || props.models || props.context || props.headerStart || props.headerEnd);
|
|
117
173
|
// Suggestions are conversation starters: show only on an empty thread unless
|
|
@@ -120,128 +176,173 @@ export function ChatThread(props: ChatThreadProps) {
|
|
|
120
176
|
props.persistSuggestions || props.messages.length === 0 ? props.suggestions : undefined;
|
|
121
177
|
const showScrollButton = () => props.scrollButton !== false;
|
|
122
178
|
|
|
179
|
+
// Hand the imperative controller to the facade once mounted (rootEl is set).
|
|
180
|
+
onMount(() => {
|
|
181
|
+
props.controllerRef?.({
|
|
182
|
+
focus: (options) =>
|
|
183
|
+
rootEl
|
|
184
|
+
?.querySelector<HTMLElement>('[contenteditable]:not([contenteditable="false"]), textarea')
|
|
185
|
+
?.focus(options),
|
|
186
|
+
clear: () => { setInternal(''); setAttachments([]); props.onValueChange?.(''); },
|
|
187
|
+
send: () => handleSubmit(),
|
|
188
|
+
scrollToBottom: (behavior) => {
|
|
189
|
+
const vp = rootEl?.querySelector<HTMLElement>('.overflow-y-auto');
|
|
190
|
+
vp?.scrollTo({ top: vp.scrollHeight, behavior: behavior ?? 'smooth' });
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
123
195
|
return (
|
|
124
196
|
<ChatConfig proseSize={props.proseSize} codeTheme={props.codeTheme} codeHighlight={props.codeHighlight !== false} portalMount={outer.portalMount()}>
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
<slot name="header-start" />
|
|
133
|
-
<Show when={props.chatTitle}>
|
|
134
|
-
<div class="text-sm font-semibold text-foreground">{props.chatTitle}</div>
|
|
135
|
-
</Show>
|
|
136
|
-
</div>
|
|
137
|
-
<div class="flex items-center gap-2">
|
|
138
|
-
<Show when={props.models}>
|
|
139
|
-
<ModelSwitcher
|
|
140
|
-
models={props.models!}
|
|
141
|
-
currentModelId={props.currentModel ?? props.models![0]?.id ?? ''}
|
|
142
|
-
onModelChange={(modelId) => props.onModelChange?.(modelId)}
|
|
143
|
-
/>
|
|
144
|
-
</Show>
|
|
145
|
-
<Show when={props.context}>
|
|
146
|
-
<Context
|
|
147
|
-
usedTokens={props.context!.usedTokens} maxTokens={props.context!.maxTokens}
|
|
148
|
-
inputTokens={props.context!.inputTokens} outputTokens={props.context!.outputTokens}
|
|
149
|
-
estimatedCost={props.context!.estimatedCost}
|
|
150
|
-
>
|
|
151
|
-
<ContextTrigger />
|
|
152
|
-
<ContextContent>
|
|
153
|
-
<ContextContentHeader />
|
|
154
|
-
<ContextContentBody><div class="space-y-1.5"><ContextInputUsage /><ContextOutputUsage /></div></ContextContentBody>
|
|
155
|
-
<ContextContentFooter />
|
|
156
|
-
</ContextContent>
|
|
157
|
-
</Context>
|
|
158
|
-
</Show>
|
|
159
|
-
{/* Consumer-injected trailing controls (share, settings, …).
|
|
160
|
-
Projects light-DOM `slot="header-end"` children of <kai-chat>. */}
|
|
161
|
-
<slot name="header-end" />
|
|
162
|
-
</div>
|
|
163
|
-
</header>
|
|
197
|
+
{/* The root is a ROW so a `sidebar` slot can sit beside the main column.
|
|
198
|
+
With no sidebar projected it collapses to the original column. */}
|
|
199
|
+
<div ref={(e) => (rootEl = e as HTMLElement)} class={`flex h-full bg-background ${props.class ?? ''}`}>
|
|
200
|
+
<Show when={props.sidebar}>
|
|
201
|
+
<aside part="sidebar" class="flex w-64 shrink-0 flex-col overflow-hidden border-r border-border">
|
|
202
|
+
<slot name="sidebar" />
|
|
203
|
+
</aside>
|
|
164
204
|
</Show>
|
|
165
|
-
<div class="
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
205
|
+
<div class="flex h-full min-w-0 flex-1 flex-col">
|
|
206
|
+
{/* Header: a full `header` slot REPLACES the built-in bar; otherwise the
|
|
207
|
+
built-in header renders, itself carrying the header-start/header-end
|
|
208
|
+
INJECT slots. */}
|
|
209
|
+
<Show
|
|
210
|
+
when={props.headerFull}
|
|
211
|
+
fallback={
|
|
212
|
+
<Show when={showHeader()}>
|
|
213
|
+
<header part="header-bar" class="flex h-14 shrink-0 items-center justify-between border-b border-border px-5">
|
|
214
|
+
<div class="flex items-center gap-2">
|
|
215
|
+
{/* Consumer-injected leading controls (sidebar-toggle, compose, a
|
|
216
|
+
popover title-button). Projects light-DOM `slot="header-start"`
|
|
217
|
+
children of <kai-chat>; inert outside a shadow root. */}
|
|
218
|
+
<slot name="header-start" />
|
|
219
|
+
<Show when={props.chatTitle}>
|
|
220
|
+
<div class="text-sm font-semibold text-foreground">{props.chatTitle}</div>
|
|
221
|
+
</Show>
|
|
222
|
+
</div>
|
|
223
|
+
<div class="flex items-center gap-2">
|
|
224
|
+
<Show when={props.models}>
|
|
225
|
+
<ModelSwitcher
|
|
226
|
+
models={props.models!}
|
|
227
|
+
currentModelId={props.currentModel ?? props.models![0]?.id ?? ''}
|
|
228
|
+
onModelChange={(modelId) => props.onModelChange?.(modelId)}
|
|
229
|
+
/>
|
|
230
|
+
</Show>
|
|
231
|
+
<Show when={props.context}>
|
|
232
|
+
<Context
|
|
233
|
+
usedTokens={props.context!.usedTokens} maxTokens={props.context!.maxTokens}
|
|
234
|
+
inputTokens={props.context!.inputTokens} outputTokens={props.context!.outputTokens}
|
|
235
|
+
estimatedCost={props.context!.estimatedCost}
|
|
236
|
+
>
|
|
237
|
+
<ContextTrigger />
|
|
238
|
+
<ContextContent>
|
|
239
|
+
<ContextContentHeader />
|
|
240
|
+
<ContextContentBody><div class="space-y-1.5"><ContextInputUsage /><ContextOutputUsage /></div></ContextContentBody>
|
|
241
|
+
<ContextContentFooter />
|
|
242
|
+
</ContextContent>
|
|
243
|
+
</Context>
|
|
244
|
+
</Show>
|
|
245
|
+
{/* Consumer-injected trailing controls (share, settings, …).
|
|
246
|
+
Projects light-DOM `slot="header-end"` children of <kai-chat>. */}
|
|
247
|
+
<slot name="header-end" />
|
|
248
|
+
</div>
|
|
249
|
+
</header>
|
|
250
|
+
</Show>
|
|
251
|
+
}
|
|
252
|
+
>
|
|
253
|
+
<header part="header" class="shrink-0"><slot name="header" /></header>
|
|
254
|
+
</Show>
|
|
255
|
+
<div class="relative flex-1 overflow-hidden">
|
|
256
|
+
<ChatContainer class="h-full px-4 py-3">
|
|
257
|
+
<ChatContainerContent class="mx-auto w-full max-w-3xl space-y-4">
|
|
258
|
+
{/* REPLACE — custom empty-state slot, shown only while the thread is
|
|
259
|
+
empty. The component still owns WHEN it shows (data state); the
|
|
260
|
+
consumer owns WHAT it looks like. */}
|
|
261
|
+
<Show when={props.empty && props.messages.length === 0}>
|
|
262
|
+
<slot name="empty" />
|
|
263
|
+
</Show>
|
|
264
|
+
<For each={props.messages}>
|
|
265
|
+
{(m) => {
|
|
266
|
+
const body = (
|
|
267
|
+
<MessageBody
|
|
268
|
+
content={m.content}
|
|
269
|
+
reasoning={m.reasoning}
|
|
270
|
+
tools={m.tools}
|
|
271
|
+
attachments={m.attachments}
|
|
272
|
+
isUser={m.role === 'user'}
|
|
187
273
|
markdown={m.role === 'assistant'}
|
|
188
|
-
|
|
274
|
+
actions={m.actions}
|
|
275
|
+
actionsReveal={reveal()}
|
|
276
|
+
activeFeedback={feedback.resolveFeedback(m)}
|
|
277
|
+
copied={feedback.isCopied(m.id)}
|
|
278
|
+
onAction={(action) => feedback.handleAction(m, action)}
|
|
279
|
+
/>
|
|
280
|
+
);
|
|
281
|
+
const rowGroup = reveal() === 'hover' ? 'group ' : '';
|
|
282
|
+
return (
|
|
283
|
+
<Show
|
|
284
|
+
when={m.avatar}
|
|
285
|
+
fallback={
|
|
286
|
+
<Message class={`${rowGroup}${m.role === 'user' ? 'flex-col items-end' : 'flex-col items-start'}`}>
|
|
287
|
+
{body}
|
|
288
|
+
</Message>
|
|
289
|
+
}
|
|
189
290
|
>
|
|
190
|
-
{
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
291
|
+
{(av) => (
|
|
292
|
+
<Message class={rowGroup}>
|
|
293
|
+
<MessageAvatar src={av().src ?? ''} alt={av().alt ?? ''} fallback={av().fallback} />
|
|
294
|
+
<div class={`flex min-w-0 flex-1 flex-col ${m.role === 'user' ? 'items-end' : 'items-start'}`}>
|
|
295
|
+
{body}
|
|
296
|
+
</div>
|
|
297
|
+
</Message>
|
|
298
|
+
)}
|
|
198
299
|
</Show>
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
slashCommands={props.slashCommands} slashActiveIds={props.slashActiveIds} slashCompact={props.slashCompact === true}
|
|
239
|
-
onValueChange={handleChange} onSubmit={handleSubmit} onSuggestionClick={handleSuggestionClick}
|
|
240
|
-
onAttachmentsChange={setAttachments}
|
|
241
|
-
onSearch={() => props.onSearch?.()} onVoice={() => props.onVoice?.()}
|
|
242
|
-
onSlashSelect={(command) => props.onSlashSelect?.(command)}
|
|
243
|
-
/>
|
|
300
|
+
);
|
|
301
|
+
}}
|
|
302
|
+
</For>
|
|
303
|
+
<ChatContainerScrollAnchor />
|
|
304
|
+
</ChatContainerContent>
|
|
305
|
+
<Show when={showScrollButton()}>
|
|
306
|
+
<div class="absolute bottom-4 left-1/2 flex w-full max-w-3xl -translate-x-1/2 justify-center px-5">
|
|
307
|
+
<ScrollButton class="shadow-sm" />
|
|
308
|
+
</div>
|
|
309
|
+
</Show>
|
|
310
|
+
</ChatContainer>
|
|
311
|
+
</div>
|
|
312
|
+
{/* INJECT — accessory row above the composer (extra actions/toolbar). */}
|
|
313
|
+
<Show when={props.composerActions}>
|
|
314
|
+
<div class="shrink-0 px-4">
|
|
315
|
+
<div class="mx-auto flex max-w-3xl items-center gap-2 pb-2"><slot name="composer-actions" /></div>
|
|
316
|
+
</div>
|
|
317
|
+
</Show>
|
|
318
|
+
<div class="shrink-0 px-4 pb-4">
|
|
319
|
+
<div class="mx-auto max-w-3xl">
|
|
320
|
+
{/* REPLACE — a full `composer` slot stands in for the built-in input.
|
|
321
|
+
The slotted content owns its own submit/loading wiring. */}
|
|
322
|
+
<Show
|
|
323
|
+
when={props.composer}
|
|
324
|
+
fallback={
|
|
325
|
+
<DefaultPromptInput
|
|
326
|
+
value={current()} placeholder={props.placeholder} loading={props.loading === true}
|
|
327
|
+
suggestions={visibleSuggestions()} attachments={attachments()}
|
|
328
|
+
search={props.search === true} voice={props.voice === true}
|
|
329
|
+
triggers={props.triggers} kindIcons={props.kindIcons}
|
|
330
|
+
onValueChange={handleChange} onSubmit={handleSubmit} onSuggestionClick={handleSuggestionClick}
|
|
331
|
+
onAttachmentsChange={(a) => { setAttachments(a); props.onAttachmentsChange?.(a); }}
|
|
332
|
+
onSearch={() => props.onSearch?.()} onVoice={() => props.onVoice?.()}
|
|
333
|
+
/>
|
|
334
|
+
}
|
|
335
|
+
>
|
|
336
|
+
<slot name="composer" />
|
|
337
|
+
</Show>
|
|
338
|
+
</div>
|
|
244
339
|
</div>
|
|
340
|
+
{/* INJECT — footer row below the composer. */}
|
|
341
|
+
<Show when={props.footer}>
|
|
342
|
+
<div part="footer" class="shrink-0 px-4 pb-3">
|
|
343
|
+
<div class="mx-auto max-w-3xl text-center text-xs text-muted-foreground"><slot name="footer" /></div>
|
|
344
|
+
</div>
|
|
345
|
+
</Show>
|
|
245
346
|
</div>
|
|
246
347
|
</div>
|
|
247
348
|
</ChatConfig>
|