@kitn.ai/ui 0.25.2 → 0.27.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 +17 -6
- package/bin/mcp.js +16 -3
- package/bin/route.js +23 -0
- package/bin/route.test.js +58 -0
- package/dist/{elements/chunks/Icon-b5A8hlHs.js → Icon-BnFKqqtY.js} +1 -1
- package/dist/action-icons-CBskfBMz.js +1 -0
- package/dist/arrow-down-Br0qtpsz.js +1 -0
- package/dist/arrow-left-Dj7xgE12.js +1 -0
- package/dist/artifact-CvXEm1lS.js +1 -0
- package/dist/assets/dev-5XzXYR21.js +91 -0
- package/dist/attachments-C43ZegEq.js +1 -0
- package/dist/audio-visualizer-B-79y1Tj.js +1 -0
- package/dist/badge-BpUbq8c0.js +1 -0
- package/dist/bash-InADTalH.js +1 -6
- package/dist/bell-sn17Ip9v.js +1 -0
- package/dist/{elements/chunks/button-B9okqG73.js → button-BH6rN0U-.js} +1 -1
- package/dist/card-renderer-Cb1gQmth.js +1 -0
- package/dist/card-routing-DifQgS7n.js +1 -0
- package/dist/check-DPeeMUYx.js +1 -0
- package/dist/checkbox-Dc9Yov_B.js +1 -0
- package/dist/checkbox-group-B1kDLLYk.js +1 -0
- package/dist/chevron-down-CHSWk7ZT.js +1 -0
- package/dist/chevron-right-B7l_fMgx.js +1 -0
- package/dist/choice-card-BT3c1S8g.js +1 -0
- package/dist/circle-Bb0yOpqM.js +1 -0
- package/dist/circle-check-BGZpCiz7.js +1 -0
- package/dist/circle-x-wobWkoSx.js +1 -0
- package/dist/{elements/chunks/cn-CU7UAWzk.js → cn-DN5AWfiS.js} +1 -1
- package/dist/code-block-CUQ5mtv0.js +1 -0
- package/dist/collapsible-CPJbf6FM.js +1 -0
- package/dist/components/attachment-types.d.ts +53 -1
- package/dist/components/attachments.d.ts +31 -0
- package/dist/components/audio-visualizer/fit-scale.d.ts +50 -0
- package/dist/components/audio-visualizer/index.d.ts +15 -1
- package/dist/components/audio-visualizer/variant-bar.d.ts +24 -1
- package/dist/components/card-renderer.d.ts +13 -0
- package/dist/components/card.d.ts +4 -0
- package/dist/components/chat-thread.d.ts +49 -42
- package/dist/components/code-block.d.ts +22 -0
- package/dist/components/conversation-item.d.ts +66 -1
- package/dist/components/conversation-list.d.ts +77 -0
- package/dist/components/form-widgets.d.ts +67 -2
- package/dist/components/form.d.ts +89 -0
- package/dist/components/message.d.ts +29 -0
- package/dist/components/reasoning.d.ts +6 -0
- package/dist/components/scroll-button.d.ts +11 -0
- package/dist/components/thread.d.ts +5 -0
- package/dist/components/toast.d.ts +2 -1
- package/dist/components/tool-types.d.ts +9 -0
- package/dist/components/voice-input.d.ts +8 -0
- package/dist/components/voice-output.d.ts +12 -1
- package/dist/components/workspace-shell.d.ts +87 -0
- package/dist/composer-CjngLzal.js +106 -0
- package/dist/confirm-card-DCx_A4bU.js +1 -0
- package/dist/construct-cli.es.js +1169 -0
- package/dist/context-BY8V-Nlp.js +1 -0
- package/dist/controllable-D43BKmtX.js +1 -0
- package/dist/conversation-list-D4lLU_yS.js +1 -0
- package/dist/copy-B6DO4PqB.js +1 -0
- package/dist/core-AYMC6_lb.js +12 -5874
- package/dist/{create-tween-CUzOlaMS.js → create-tween-BPzaefTp.js} +1 -1
- package/dist/{create-tween-B5Y4Im8G.js → create-tween-CnMHviKB.js} +1 -1
- package/dist/{create-tween-4z1XYLkR.js → create-tween-D1aiGZZh.js} +1 -1
- package/dist/{elements/chunks/create-tween-CUrM6D_o.js → create-tween-DUSQUKpr.js} +2 -2
- package/dist/css-M7EaDHN_.js +1 -6
- package/dist/custom-elements.json +3468 -1927
- package/dist/default-input-CucQEOqH.js +1 -0
- package/dist/define-CGGX-7Vg.js +1 -0
- package/dist/define.d.ts +4 -0
- package/dist/define.js +510 -0
- package/dist/define.server.d.ts +5 -0
- package/dist/define.server.js +506 -0
- package/dist/diagnostics/hook.d.ts +81 -0
- package/dist/diagnostics/index.d.ts +7 -0
- package/dist/diagnostics/report-request.d.ts +61 -0
- package/dist/diagnostics.d.ts +5 -0
- package/dist/diagnostics.js +209 -0
- package/dist/disclosure-CbLtajUQ.js +1 -0
- package/dist/dropdown-BwhViJFd.js +1 -0
- 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/autoloader.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-scope-picker.js +1 -1
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkbox-group.d.ts +1 -0
- package/dist/elements/checkbox-group.js +1 -0
- package/dist/elements/checkbox.d.ts +1 -0
- package/dist/elements/checkbox.js +1 -0
- 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.d.ts +1 -0
- package/dist/elements/conversation-item.js +1 -0
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/default-input.d.ts +3 -3
- package/dist/elements/define-entry.d.ts +12 -0
- package/dist/elements/define.d.ts +27 -0
- package/dist/elements/diagnostic-events.d.ts +74 -0
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.d.ts +1 -0
- package/dist/elements/dock.js +243 -0
- package/dist/elements/dropdown.d.ts +1 -0
- package/dist/elements/dropdown.js +1 -0
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/element-data-types.d.ts +37 -0
- package/dist/elements/element-diagnostics.d.ts +81 -0
- 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.d.ts +1 -0
- package/dist/elements/pane-grid.js +1 -0
- 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.d.ts +1 -0
- package/dist/elements/radio-group.js +1 -0
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/register.d.ts +2 -0
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +3 -3
- 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.d.ts +1 -0
- package/dist/elements/select.js +1 -0
- 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.d.ts +1 -0
- package/dist/elements/slider.js +1 -0
- package/dist/elements/slots.d.ts +36 -4
- 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 +589 -167
- package/dist/{elements/chunks/ellipsis-CVxqfsDZ.js → ellipsis-DFr4Vqr3.js} +1 -1
- package/dist/embed-5s_vU4J0.js +1 -0
- package/dist/engine-javascript-vq0WuIJl.js +14 -2516
- package/dist/{elements/chunks/external-link-DG2sRdQL.js → external-link-u9d85ORQ.js} +1 -1
- package/dist/file-text-CX7_x42o.js +1 -0
- package/dist/{elements/chunks/file-tree-yGWNK0Js.js → file-tree-D3kBjXI5.js} +1 -1
- package/dist/folder-V-YdIL8f.js +1 -0
- package/dist/form-BRNUMCN2.js +1 -0
- package/dist/github-dark-dimmed-DUshB20C.js +1 -4
- package/dist/github-light-JYsPkUQd.js +1 -4
- package/dist/hover-card-DaeiYrTA.js +1 -0
- package/dist/html-CPZ3oZQ7.js +1 -10
- package/dist/icon-BpixdZNq.js +1 -0
- package/dist/{elements/chunks/index-BCRhi84a.js → index-xu_pdcPi.js} +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +8473 -6470
- package/dist/index.server.js +6495 -4958
- package/dist/info-8mFsIjS3.js +1 -0
- package/dist/input-d1Yuu-hz.js +1 -0
- package/dist/javascript-C25yR2R2.js +1 -6
- package/dist/json-DxJze_jm.js +1 -6
- package/dist/kai-provider.es.js +40 -40
- package/dist/kai.es.js +1 -1
- package/dist/kbd-961zMPFB.js +1 -0
- package/dist/link-DlZZBGaR.js +1 -0
- package/dist/{elements/chunks/link-preview-Cf5KOP-i.js → link-preview-DIIbV2Sd.js} +1 -1
- package/dist/loader-YQszHFaW.js +1 -0
- package/dist/{elements/chunks/markdown-DbozyYqa.js → markdown-CVk1MPsj.js} +1 -1
- package/dist/mcp.es.js +3873 -544
- package/dist/message-CwKVEdZg.js +1 -0
- package/dist/message-DS8lzHc1.js +1 -0
- package/dist/message-circle-Xf8Q-vZp.js +1 -0
- package/dist/message-square-Cxnwgkns.js +1 -0
- package/dist/{elements/chunks/minimize-2-SegJ_oku.js → minimize-2-UEZmP2QT.js} +1 -1
- package/dist/{elements/chunks/model-switcher-D7JrFFHp.js → model-switcher-Kk1jEQ5t.js} +1 -1
- package/dist/{elements/chunks/overlay-CV7z2YuX.js → overlay-C1od6LOz.js} +1 -1
- package/dist/panel-right-ryET0yyn.js +1 -0
- package/dist/paperclip-BDNoZFJP.js +1 -0
- package/dist/play-OFIvYXUQ.js +1 -0
- package/dist/primitives/card-data-types.d.ts +49 -0
- package/dist/primitives/card-routing.d.ts +1 -33
- package/dist/primitives/card-validate.d.ts +2 -2
- package/dist/primitives/chat-config.d.ts +29 -2
- package/dist/primitives/field-mask.d.ts +96 -0
- package/dist/primitives/field-semantics.d.ts +36 -0
- package/dist/primitives/input-mask.d.ts +46 -0
- package/dist/primitives/url-scheme-policy.d.ts +34 -0
- package/dist/primitives/use-resize-observer.d.ts +23 -0
- package/dist/primitives/use-speech-recognition.d.ts +8 -0
- package/dist/primitives/use-text-stream.d.ts +5 -0
- package/dist/progress-bar-BvYX0aoy.js +1 -0
- package/dist/prompt-suggestion-BRFu2lcu.js +1 -0
- package/dist/radio-DcL23cNJ.js +1 -0
- package/dist/react/index.d.ts +306 -283
- package/dist/react.js +309 -247
- package/dist/reasoning-Cackq4Rh.js +1 -0
- package/dist/register-impl-C7rENvPK.js +424 -0
- package/dist/{elements/chunks/resizable-Dpzjlvp4.js → resizable-Cp9HUYih.js} +1 -1
- package/dist/rotate-ccw-0DLRDHH5.js +1 -0
- package/dist/rotate-cw-DOB9IGcU.js +1 -0
- package/dist/schemas/form.schema.json +21 -1
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/tool-defs.d.ts +45 -0
- package/dist/schemas.js +398 -305
- package/dist/scroll-area-emVmWP4K.js +1 -0
- package/dist/scroll-button-CeP_gv1x.js +1 -0
- package/dist/select-CWmu00tS.js +1 -0
- package/dist/{elements/chunks/separator-DH2r_ZSZ.js → separator-CE6vly6z.js} +1 -1
- package/dist/{elements/chunks/settings-BFMOd6yB.js → settings-CE-78SvZ.js} +1 -1
- package/dist/{elements/chunks/settings-group-B3VZKIcz.js → settings-group-ZFWNxFQR.js} +1 -1
- package/dist/{elements/chunks/skeleton-N8BuWYmf.js → skeleton-BebdP4mf.js} +1 -1
- package/dist/slider-BAKRYUlz.js +1 -0
- package/dist/slots-DaNjX0rc.js +1 -0
- package/dist/{solid-BMuDmFo_.js → solid-BE5ui6sy.js} +10672 -8116
- package/dist/{solid-CGYNdLRR.js → solid-DFhsce3O.js} +8137 -6056
- package/dist/solid.d.ts +15 -0
- package/dist/solid.js +248 -235
- package/dist/solid.server.js +248 -235
- package/dist/source-B0FlguSx.js +1 -0
- package/dist/star-CBMZvLuN.js +1 -0
- package/dist/state/index.d.ts +5 -1
- package/dist/state/mock.d.ts +32 -2
- package/dist/state/persistence.d.ts +51 -0
- package/dist/state/stream.d.ts +50 -0
- package/dist/state/threads.d.ts +71 -0
- package/dist/state.js +297 -172
- package/dist/store-7eoadydQ.js +1 -0
- package/dist/svelte--5p79yCD.js +1 -15
- package/dist/switch-CViARZCy.js +1 -0
- package/dist/tasks-card-MjCcOhR_.js +1 -0
- package/dist/text-shimmer-DKlwRF2G.js +1 -0
- package/dist/textarea-3ay2Me2-.js +1 -0
- package/dist/theme.tokens.css +82 -13
- package/dist/{elements/chunks/thumbs-up-DQe0hvkZ.js → thumbs-up-DQcu2HMO.js} +1 -1
- package/dist/toast-store-C6yKOhbk.js +1 -0
- package/dist/{elements/chunks/tool-C1YtxwPu.js → tool-BCYNlfKy.js} +1 -1
- package/dist/{elements/chunks/tooltip-BqwnFWhn.js → tooltip-05zI4hjs.js} +1 -1
- package/dist/trash-2-BR1RxGky.js +1 -0
- package/dist/{elements/chunks/triangle-alert-B6or7F5u.js → triangle-alert-DHohDOCy.js} +1 -1
- package/dist/tsx-B8rCNbgL.js +1 -6
- package/dist/types.d.ts +4 -2
- package/dist/typescript-RycA9KXf.js +1 -6
- package/dist/ui/checkbox-group.d.ts +83 -0
- package/dist/ui/checkbox.d.ts +40 -0
- package/dist/ui/dock.d.ts +131 -0
- package/dist/ui/hover-card.d.ts +44 -0
- package/dist/ui/icon.d.ts +3 -0
- package/dist/ui/input.d.ts +48 -2
- package/dist/ui/radio.d.ts +85 -0
- package/dist/ui/select.d.ts +71 -0
- package/dist/ui/slider.d.ts +65 -0
- package/dist/ui/switch.d.ts +9 -2
- package/dist/upload-BbGW6A_u.js +1 -0
- package/dist/url-scheme-policy-DHpoTJwB.js +1 -0
- package/dist/use-card-resolution-CJW4grFa.js +1 -0
- package/dist/{variant-aurora-DwSOfraQ.js → variant-aurora-BUOVgPOB.js} +27 -27
- package/dist/{variant-aurora-wKvAQ5wp.js → variant-aurora-CUsUJvFI.js} +28 -28
- package/dist/{variant-aurora-XEkPT0_z.js → variant-aurora-CW2i4bfr.js} +2 -2
- package/dist/{elements/chunks/variant-aurora-QXTZPyST.js → variant-aurora-xiMPty8f.js} +2 -2
- package/dist/variant-custom-BQtOnmeO.js +1 -0
- package/dist/{variant-custom-BhS9wIpU.js → variant-custom-CAm9L-E5.js} +65 -65
- package/dist/{variant-custom-eFIg2XWQ.js → variant-custom-CAnzzppW.js} +40 -40
- package/dist/variant-custom-D91HjAKz.js +1 -0
- package/dist/{variant-wave-CUWGx9Bn.js → variant-wave-Ca1Ls4_y.js} +21 -21
- package/dist/{variant-wave-CbVsmgwT.js → variant-wave-CxX39DKd.js} +25 -25
- package/dist/{variant-wave-BwzrHD1s.js → variant-wave-DYyzIIZv.js} +2 -2
- package/dist/{elements/chunks/variant-wave-DDCwhLas.js → variant-wave-uY5crU_K.js} +2 -2
- package/dist/vue-BmIZj4XD.js +1 -33
- package/dist/wire/chunk.d.ts +47 -0
- package/dist/wire/diagnostics.d.ts +575 -0
- package/dist/wire/encode-probe.d.ts +70 -0
- package/dist/wire/encode.d.ts +24 -0
- package/dist/wire/index.d.ts +2 -0
- package/dist/wire/sse.d.ts +10 -2
- package/dist/wire.js +917 -480
- package/dist/x-C5m1JFgi.js +1 -0
- package/frameworks/react/index.tsx +325 -108
- package/llms-full.txt +1354 -82
- package/llms.txt +6 -3
- package/package.json +39 -6
- package/src/agent-tooling/archetypes.ts +41 -9
- package/src/agent-tooling/catalog/README.md +676 -0
- package/src/agent-tooling/catalog/catalog-types.ts +231 -0
- package/src/agent-tooling/catalog/fabrications.ts +96 -0
- package/src/agent-tooling/catalog/invariants.ts +284 -0
- package/src/agent-tooling/catalog/labs-titles.ts +114 -0
- package/src/agent-tooling/catalog/scenarios.ts +87 -0
- package/src/agent-tooling/catalog/surfaces.ts +347 -0
- package/src/agent-tooling/construct/cli-entry.ts +8 -0
- package/src/agent-tooling/construct/cli.ts +131 -0
- package/src/agent-tooling/construct/codegen.ts +1353 -0
- package/src/agent-tooling/construct/construct.v1.schema.json +250 -0
- package/src/agent-tooling/construct/dev.ts +148 -0
- package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +7 -0
- package/src/agent-tooling/construct/fixtures/ops-console.construct.json +44 -0
- package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +23 -0
- package/src/agent-tooling/construct/schema.ts +371 -0
- package/src/agent-tooling/integrations/anthropic.ts +7 -1
- package/src/agent-tooling/integrations/cloudflare.ts +43 -2
- package/src/agent-tooling/integrations/langgraph.ts +7 -1
- package/src/agent-tooling/integrations/mastra.ts +7 -1
- package/src/agent-tooling/integrations/mock.ts +92 -17
- package/src/agent-tooling/integrations/ollama.ts +7 -1
- package/src/agent-tooling/integrations/openai.ts +7 -1
- package/src/agent-tooling/integrations/openrouter.ts +7 -1
- package/src/agent-tooling/integrations/pi.ts +56 -1
- package/src/agent-tooling/integrations/vercel-ai-sdk.ts +7 -1
- package/src/agent-tooling/mcp/css-raw.d.ts +12 -0
- package/src/agent-tooling/mcp/manifest.ts +100 -1
- package/src/agent-tooling/mcp/server.ts +63 -6
- package/src/agent-tooling/mcp/tools/construct.ts +130 -0
- package/src/agent-tooling/mcp/tools/debug.ts +126 -4
- package/src/agent-tooling/mcp/tools/reference.ts +542 -5
- package/src/agent-tooling/mcp/tools/scaffold.ts +1834 -307
- package/src/agent-tooling/mcp/tools/theme.ts +146 -30
- package/src/agent-tooling/mcp/validate-args.ts +141 -0
- package/src/agent-tooling/recipes/composed-thread.ts +714 -0
- package/src/agent-tooling/recipes/index.ts +22 -0
- package/src/agent-tooling/recipes/types.ts +32 -0
- package/src/agent-tooling/registry.ts +24 -7
- package/src/agent-tooling/route-emit.ts +26 -2
- package/src/components/attachment-types.ts +54 -1
- package/src/components/attachments.tsx +169 -22
- package/src/components/audio-visualizer/fit-scale.ts +112 -0
- package/src/components/audio-visualizer/index.tsx +80 -3
- package/src/components/audio-visualizer/variant-aurora.tsx +10 -4
- package/src/components/audio-visualizer/variant-bar.tsx +38 -6
- package/src/components/audio-visualizer/variant-custom.tsx +8 -2
- package/src/components/audio-visualizer/variant-grid.tsx +16 -11
- package/src/components/audio-visualizer/variant-radial.tsx +15 -10
- package/src/components/audio-visualizer/variant-wave.tsx +7 -2
- package/src/components/card-renderer.tsx +39 -8
- package/src/components/card.tsx +10 -2
- package/src/components/chat-container.tsx +4 -1
- package/src/components/chat-scope-picker.tsx +2 -2
- package/src/components/chat-thread.tsx +105 -13
- package/src/components/choice-card.tsx +102 -37
- package/src/components/coachmark.tsx +1 -1
- package/src/components/code-block.tsx +81 -5
- package/src/components/composer.tsx +89 -8
- package/src/components/confirm-card.tsx +20 -4
- package/src/components/conversation-item.tsx +138 -4
- package/src/components/conversation-list.tsx +230 -15
- package/src/components/embed.tsx +4 -0
- package/src/components/empty.tsx +14 -3
- package/src/components/file-tree.tsx +5 -1
- package/src/components/form-widgets.tsx +257 -195
- package/src/components/form.tsx +336 -21
- package/src/components/loader.tsx +12 -5
- package/src/components/message-skills.tsx +1 -1
- package/src/components/message.tsx +142 -12
- package/src/components/prompt-input.tsx +7 -1
- package/src/components/prompt-suggestion.tsx +4 -1
- package/src/components/reasoning.tsx +30 -3
- package/src/components/response-compare.tsx +2 -2
- package/src/components/response-stream.tsx +13 -7
- package/src/components/screen.tsx +5 -0
- package/src/components/scroll-button.tsx +63 -4
- package/src/components/source.tsx +6 -1
- package/src/components/tasks-card.tsx +58 -16
- package/src/components/thread.tsx +10 -1
- package/src/components/toast.tsx +11 -5
- package/src/components/tool-types.ts +9 -0
- package/src/components/voice-input.tsx +35 -3
- package/src/components/voice-output.tsx +46 -6
- package/src/components/workspace-shell.tsx +285 -0
- package/src/diagnostics/hook.ts +352 -0
- package/src/diagnostics/index.ts +82 -0
- package/src/diagnostics/report-request.ts +296 -0
- package/src/elements/attachments.tsx +9 -8
- package/src/elements/audio-visualizer.tsx +48 -4
- package/src/elements/chat-workspace.tsx +159 -287
- package/src/elements/chat.tsx +31 -10
- package/src/elements/checkbox-group.tsx +164 -0
- package/src/elements/checkbox.tsx +134 -0
- package/src/elements/code-block.tsx +19 -1
- package/src/elements/command.tsx +4 -1
- package/src/elements/compiled.css +1 -1
- package/src/elements/composer.tsx +12 -1
- package/src/elements/conversation-item.tsx +120 -0
- package/src/elements/conversation-list.tsx +60 -11
- package/src/elements/default-input.tsx +5 -5
- package/src/elements/define-entry.ts +12 -0
- package/src/elements/define.tsx +168 -8
- package/src/elements/diagnostic-events.ts +114 -0
- package/src/elements/dialog.tsx +47 -0
- package/src/elements/disclosure.ts +34 -12
- package/src/elements/dock.tsx +215 -0
- package/src/elements/dropdown.tsx +123 -0
- package/src/elements/element-data-types.ts +40 -0
- package/src/elements/element-diagnostics.ts +392 -0
- package/src/elements/element-manifest.json +36 -0
- package/src/elements/element-meta.json +1483 -560
- package/src/elements/element-nonscalar.json +185 -0
- package/src/elements/element-types.d.ts +589 -167
- package/src/elements/feedback-bar.tsx +5 -0
- package/src/elements/icon-names.json +29 -0
- package/src/elements/input.tsx +312 -23
- package/src/elements/menu.tsx +13 -0
- package/src/elements/message.tsx +2 -0
- package/src/elements/pane-grid.tsx +111 -0
- package/src/elements/prompt-dock.tsx +2 -1
- package/src/elements/prompt-input.tsx +16 -10
- package/src/elements/radio-group.tsx +129 -0
- package/src/elements/register-impl.ts +52 -0
- package/src/elements/register.ts +28 -0
- package/src/elements/resizable.tsx +52 -25
- package/src/elements/scroll-button.tsx +59 -6
- package/src/elements/select.tsx +165 -0
- package/src/elements/slider.tsx +171 -0
- package/src/elements/slots.ts +108 -13
- package/src/elements/styles.css +119 -9
- package/src/elements/thinking-bar.tsx +16 -7
- package/src/elements/thread.tsx +2 -0
- package/src/elements/toast.tsx +17 -1
- package/src/elements/tool.tsx +26 -5
- package/src/elements/voice-input.tsx +11 -2
- package/src/elements/voice-output.tsx +16 -3
- package/src/index.ts +4 -1
- package/src/primitives/card-data-types.ts +49 -0
- package/src/primitives/card-host.tsx +4 -2
- package/src/primitives/card-routing.ts +7 -56
- package/src/primitives/card-schemas/form.schema.json +21 -1
- package/src/primitives/card-validate.ts +10 -2
- package/src/primitives/chat-config.tsx +33 -6
- package/src/primitives/field-mask.ts +256 -0
- package/src/primitives/field-semantics.ts +115 -0
- package/src/primitives/input-mask.ts +853 -0
- package/src/primitives/toast-store.ts +66 -4
- package/src/primitives/url-scheme-policy.ts +70 -0
- package/src/primitives/use-resize-observer.ts +33 -0
- package/src/primitives/use-speech-recognition.ts +12 -1
- package/src/primitives/use-stick-to-bottom.ts +34 -2
- package/src/primitives/use-text-stream.ts +33 -2
- package/src/remote/provider-runtime.ts +6 -3
- package/src/schemas/index.ts +1 -0
- package/src/schemas/tool-defs.ts +307 -6
- package/src/solid.ts +15 -0
- package/src/state/index.ts +13 -1
- package/src/state/mock.ts +92 -6
- package/src/state/persistence.ts +180 -0
- package/src/state/stream.ts +71 -4
- package/src/state/threads.ts +142 -0
- package/src/types.ts +4 -2
- package/src/ui/agent-card.tsx +2 -2
- package/src/ui/avatar.tsx +1 -1
- package/src/ui/checkbox-group.tsx +153 -0
- package/src/ui/checkbox.tsx +63 -0
- package/src/ui/dialog.tsx +6 -0
- package/src/ui/dock.tsx +584 -0
- package/src/ui/dropdown.tsx +67 -23
- package/src/ui/hover-card.tsx +156 -6
- package/src/ui/icon.tsx +53 -0
- package/src/ui/input.tsx +275 -16
- package/src/ui/kbd.tsx +1 -1
- package/src/ui/nav.tsx +1 -1
- package/src/ui/pane-group.tsx +2 -2
- package/src/ui/radio.tsx +150 -0
- package/src/ui/resizable.tsx +11 -0
- package/src/ui/select.tsx +168 -0
- package/src/ui/slider.tsx +178 -0
- package/src/ui/switch.tsx +49 -18
- package/src/utils/cn.ts +11 -5
- package/src/wire/chunk.ts +47 -0
- package/src/wire/consume.ts +185 -26
- package/src/wire/diagnostics.ts +727 -0
- package/src/wire/encode-probe.ts +214 -0
- package/src/wire/encode.ts +267 -14
- package/src/wire/formats/anthropic.ts +8 -1
- package/src/wire/formats/openai.ts +5 -0
- package/src/wire/index.ts +22 -0
- package/src/wire/read.ts +250 -6
- package/src/wire/sse.ts +16 -3
- package/theme.css +84 -13
- package/dist/elements/chunks/action-icons-DW9muWrY.js +0 -1
- package/dist/elements/chunks/arrow-left-iJVnQmxA.js +0 -1
- package/dist/elements/chunks/artifact-BSuPYFHY.js +0 -1
- package/dist/elements/chunks/attachments-CL6TaqIb.js +0 -1
- package/dist/elements/chunks/audio-visualizer-BuUqQmaO.js +0 -1
- package/dist/elements/chunks/badge-TIMiJFKc.js +0 -1
- package/dist/elements/chunks/bash-InADTalH.js +0 -1
- package/dist/elements/chunks/card-renderer-CSoTL_e1.js +0 -1
- package/dist/elements/chunks/card-routing-BK09BdmL.js +0 -1
- package/dist/elements/chunks/chat-thread-DxoKaStk.js +0 -1
- package/dist/elements/chunks/check-MdLzbxrm.js +0 -1
- package/dist/elements/chunks/chevron-down-MK7IzDqe.js +0 -1
- package/dist/elements/chunks/chevron-right-C5jXhmtV.js +0 -1
- package/dist/elements/chunks/choice-card-CGMc3kek.js +0 -1
- package/dist/elements/chunks/circle-BG7VkPep.js +0 -1
- package/dist/elements/chunks/circle-check-GqvO2UBs.js +0 -1
- package/dist/elements/chunks/circle-x-mhH7pOK2.js +0 -1
- package/dist/elements/chunks/code-block-ClhQO9RW.js +0 -1
- package/dist/elements/chunks/collapsible-DBcBkFPh.js +0 -1
- package/dist/elements/chunks/composer-CZZmtYOT.js +0 -69
- package/dist/elements/chunks/confirm-card-BWjf2-xo.js +0 -1
- package/dist/elements/chunks/context-hKjNqiyQ.js +0 -1
- package/dist/elements/chunks/conversation-list-CsGJjSKG.js +0 -1
- package/dist/elements/chunks/core-AYMC6_lb.js +0 -12
- package/dist/elements/chunks/css-M7EaDHN_.js +0 -1
- package/dist/elements/chunks/default-input-B1Mem5wu.js +0 -1
- package/dist/elements/chunks/define-B_tXMYRm.js +0 -1
- package/dist/elements/chunks/disclosure-DAoYOKew.js +0 -1
- package/dist/elements/chunks/download-DnCyWFJE.js +0 -1
- package/dist/elements/chunks/dropdown-CmNna5lT.js +0 -1
- package/dist/elements/chunks/embed-CjAD2jSi.js +0 -1
- package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +0 -141
- package/dist/elements/chunks/file-text-D0J9F6M7.js +0 -1
- package/dist/elements/chunks/folder-NV1pi_ud.js +0 -1
- package/dist/elements/chunks/form-Cp8Y00Wn.js +0 -1
- package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +0 -1
- package/dist/elements/chunks/github-light-JYsPkUQd.js +0 -1
- package/dist/elements/chunks/hover-card-6KtXpLwT.js +0 -1
- package/dist/elements/chunks/html-CPZ3oZQ7.js +0 -1
- package/dist/elements/chunks/icon-97R8SR2p.js +0 -1
- package/dist/elements/chunks/info-C8r5Q6cc.js +0 -1
- package/dist/elements/chunks/input-DrseEjhp.js +0 -1
- package/dist/elements/chunks/javascript-C25yR2R2.js +0 -1
- package/dist/elements/chunks/json-DxJze_jm.js +0 -1
- package/dist/elements/chunks/kbd-OGJDUT-O.js +0 -1
- package/dist/elements/chunks/link-BdsfLB7b.js +0 -1
- package/dist/elements/chunks/loader-B5QzK_8_.js +0 -1
- package/dist/elements/chunks/message-CE4k-qaj.js +0 -1
- package/dist/elements/chunks/message-DtXKPqiR.js +0 -1
- package/dist/elements/chunks/message-square-C9ovmtOo.js +0 -1
- package/dist/elements/chunks/paperclip-Bg0ITU3b.js +0 -1
- package/dist/elements/chunks/progress-bar-D1_rzt6N.js +0 -1
- package/dist/elements/chunks/prompt-suggestion-D5Sm8xF1.js +0 -1
- package/dist/elements/chunks/reasoning-BrxQfpfI.js +0 -1
- package/dist/elements/chunks/rotate-cw-DzVDJOA1.js +0 -1
- package/dist/elements/chunks/scroll-area-93A1bbeG.js +0 -1
- package/dist/elements/chunks/scroll-button-CrTo7wm4.js +0 -1
- package/dist/elements/chunks/share-DgNbkJKY.js +0 -1
- package/dist/elements/chunks/slots-CIw9RlAe.js +0 -1
- package/dist/elements/chunks/source-w9V0NnBn.js +0 -1
- package/dist/elements/chunks/star-DHvACxtm.js +0 -1
- package/dist/elements/chunks/store-HIPGhNz9.js +0 -1
- package/dist/elements/chunks/svelte--5p79yCD.js +0 -1
- package/dist/elements/chunks/tasks-card-lPxoodlA.js +0 -1
- package/dist/elements/chunks/text-shimmer-BY_rI3s5.js +0 -1
- package/dist/elements/chunks/textarea-DPfuhswM.js +0 -1
- package/dist/elements/chunks/toast-store-VUZZBhzH.js +0 -1
- package/dist/elements/chunks/tsx-B8rCNbgL.js +0 -1
- package/dist/elements/chunks/typescript-RycA9KXf.js +0 -1
- package/dist/elements/chunks/use-card-resolution-DJg32jGH.js +0 -1
- package/dist/elements/chunks/variant-custom-D5ZlmziF.js +0 -1
- package/dist/elements/chunks/video-Bb86fVYI.js +0 -1
- package/dist/elements/chunks/vue-BmIZj4XD.js +0 -1
- package/dist/elements/chunks/x-BOhjBeOd.js +0 -1
- package/dist/llms/llms-full.txt +0 -2834
- package/dist/llms/llms.txt +0 -156
- package/dist/primitives/card-validate-generator.testlib.d.ts +0 -20
- package/dist/register-impl-DGmGzrEM.js +0 -145
- package/dist/ui/stat.d.ts +0 -16
- package/dist/variant-custom-MkTNTycd.js +0 -1
- package/src/primitives/card-validate-generator.testlib.ts +0 -38
- package/src/ui/stat.tsx +0 -41
- /package/dist/{elements/chunks/card-tags-D8lZ-C_U.js → card-tags-D8lZ-C_U.js} +0 -0
- /package/dist/{elements/chunks/link-preview-DNILK391.js → link-preview-DNILK391.js} +0 -0
|
@@ -8,8 +8,19 @@ import { actionIcon, BUILTIN_ACTION_LABEL } from "../ui/action-icons";
|
|
|
8
8
|
import type { ChatMessageAction, CustomAction, FeedbackVote, MessagePart, MessageSource } from "../elements/chat-types";
|
|
9
9
|
import { useChatConfig, textClass } from "../primitives/chat-config";
|
|
10
10
|
import { Reasoning, ReasoningTrigger, ReasoningContent } from "./reasoning";
|
|
11
|
+
import { Loader } from "./loader";
|
|
11
12
|
import { Tool } from "./tool";
|
|
12
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
Attachments,
|
|
15
|
+
Attachment,
|
|
16
|
+
AttachmentPreview,
|
|
17
|
+
AttachmentInfo,
|
|
18
|
+
AttachmentHoverCard,
|
|
19
|
+
AttachmentHoverCardTrigger,
|
|
20
|
+
AttachmentHoverCardContent,
|
|
21
|
+
getAttachmentLabel,
|
|
22
|
+
getMediaCategory,
|
|
23
|
+
} from "./attachments";
|
|
13
24
|
import { Source, SourceTrigger, SourceContent, SourceList } from "./source";
|
|
14
25
|
import { CardRenderer, type CardSchemaMap } from "./card-renderer";
|
|
15
26
|
import type { CardComponentMap } from "../primitives/card-registry";
|
|
@@ -318,6 +329,12 @@ export interface MessageBodyProps {
|
|
|
318
329
|
* the kit checks its own seven built-ins and leaves your own card type
|
|
319
330
|
* unvalidated. A schema here WINS over a built-in of the same name. */
|
|
320
331
|
cardSchemas?: CardSchemaMap;
|
|
332
|
+
/** The custom-element host node to emit card events off when no `CardProvider`
|
|
333
|
+
* is above this body, forwarded to `CardRenderer` as `hostElement`. The
|
|
334
|
+
* `<kai-chat>`/`<kai-message>`/`<kai-thread>` facades pass their own element,
|
|
335
|
+
* so a `card` part's events leave as the bubbling `kai-card` CustomEvent
|
|
336
|
+
* instead of being silently discarded. */
|
|
337
|
+
cardHostElement?: HTMLElement;
|
|
321
338
|
/** Whether this is a user message (right-aligned bubble) vs an assistant
|
|
322
339
|
* message (full-width transparent). */
|
|
323
340
|
isUser: boolean;
|
|
@@ -336,6 +353,29 @@ export interface MessageBodyProps {
|
|
|
336
353
|
activeFeedback?: FeedbackVote;
|
|
337
354
|
/** When true, the copy button shows its "copied" check icon. */
|
|
338
355
|
copied?: boolean;
|
|
356
|
+
/** Whether this message is the one currently streaming. Forwarded to each
|
|
357
|
+
* reasoning part's `<Reasoning>` so the disclosure auto-opens while the
|
|
358
|
+
* model is thinking and settles back once the stream ends. Without it the
|
|
359
|
+
* user watches a static collapsed "Reasoning" label for the whole thinking
|
|
360
|
+
* window. The caller owns the definition of "streaming" — for
|
|
361
|
+
* `ChatThread` that is `loading` + being the last assistant message. */
|
|
362
|
+
isStreaming?: boolean;
|
|
363
|
+
/** How a `reasoning` part renders. `'full'` (default) is the current
|
|
364
|
+
* behavior: the collapsible `<Reasoning>` disclosure, with the "Thinking…"
|
|
365
|
+
* shimmer on its trigger while `isStreaming`. `'compact'` drops the
|
|
366
|
+
* disclosure entirely and shows only a shimmer loader while the part is
|
|
367
|
+
* streaming — nothing once it settles, so there is no expandable detail to
|
|
368
|
+
* open. `'off'` renders the part not at all, in either state. Kit-decides-
|
|
369
|
+
* HOW: this is a display-mode fact about the medium, not a per-message
|
|
370
|
+
* toggle, so it applies uniformly to every reasoning part in the body. */
|
|
371
|
+
reasoningMode?: 'full' | 'compact' | 'off';
|
|
372
|
+
/** Seeds the reasoning disclosure open AND keeps it tracking the stream
|
|
373
|
+
* (open while streaming, closes when it settles): the pre-Task-19f `full`
|
|
374
|
+
* behavior. Default false/absent: the panel starts closed (just the
|
|
375
|
+
* "Thinking" shimmer chip) and only opens on click, the current default
|
|
376
|
+
* (owner ruling, 2026-08-26). Meaningless when `reasoningMode` is
|
|
377
|
+
* `'compact'`/`'off'` (no disclosure exists to open). */
|
|
378
|
+
reasoningDefaultOpen?: boolean;
|
|
339
379
|
/** INJECT slot projected at the TOP of the body — above the reasoning / tools /
|
|
340
380
|
* content. A per-message header: a model-name label, a role + timestamp line.
|
|
341
381
|
* In the `<kai-message>` shadow this is `<slot name="before-body" />`. */
|
|
@@ -477,15 +517,68 @@ function MessageBody(props: MessageBodyProps) {
|
|
|
477
517
|
<Switch fallback={null}>
|
|
478
518
|
<Match when={groupAs(group(), 'files')}>
|
|
479
519
|
{(g) => (
|
|
480
|
-
|
|
520
|
+
/* `grid`, NOT `inline`. The inline chip gives an image a 20x20
|
|
521
|
+
preview — a thumbnail nobody can read — while the 96px tile
|
|
522
|
+
and the hover-card full preview both already existed here and
|
|
523
|
+
the thread used neither.
|
|
524
|
+
|
|
525
|
+
WHY GRID AND NOT LIST, since `list` shows the filename
|
|
526
|
+
outright: `list` stacks (`flex-col`), so a message carrying
|
|
527
|
+
four attachments becomes four full-width rows and pushes the
|
|
528
|
+
conversation off screen. `grid` is `flex-wrap w-fit`, so the
|
|
529
|
+
same four are one 96px-tall row of tiles. Density is what
|
|
530
|
+
keeps a thread readable, and it is the whole reason the
|
|
531
|
+
thread is not the composer's chip strip.
|
|
532
|
+
|
|
533
|
+
A grid tile draws no filename of its own, and hiding one
|
|
534
|
+
behind the hover card is not good enough: that serves a
|
|
535
|
+
pointer and nothing else. So `<AttachmentInfo>` renders a
|
|
536
|
+
VISIBLE truncated caption on every non-image tile — no hover,
|
|
537
|
+
no focus, no tap required — and the hover card is an upgrade
|
|
538
|
+
to the full name and media type rather than the only way to
|
|
539
|
+
get either. */
|
|
540
|
+
<Attachments variant="grid" class={props.isUser ? 'mb-2 ml-auto' : 'mb-2'}>
|
|
481
541
|
{/* Reference-keyed <For> is right HERE: the run's part objects
|
|
482
542
|
are carried over untouched by the folds, and an attachment
|
|
483
543
|
holds no state worth preserving. */}
|
|
484
544
|
<For each={g().parts}>
|
|
485
545
|
{(fp) => (
|
|
486
546
|
<Attachment data={fp.attachment}>
|
|
487
|
-
<
|
|
488
|
-
|
|
547
|
+
<AttachmentHoverCard>
|
|
548
|
+
<AttachmentHoverCardTrigger class="block size-full">
|
|
549
|
+
<AttachmentPreview />
|
|
550
|
+
<AttachmentInfo />
|
|
551
|
+
</AttachmentHoverCardTrigger>
|
|
552
|
+
<AttachmentHoverCardContent>
|
|
553
|
+
{/* An image gets the full preview; everything else
|
|
554
|
+
gets the name and type the tile could not fit. */}
|
|
555
|
+
<Show
|
|
556
|
+
when={
|
|
557
|
+
getMediaCategory(fp.attachment) === 'image' &&
|
|
558
|
+
fp.attachment.type === 'file' &&
|
|
559
|
+
fp.attachment.url
|
|
560
|
+
}
|
|
561
|
+
fallback={
|
|
562
|
+
<>
|
|
563
|
+
<div class="text-body font-medium">
|
|
564
|
+
{getAttachmentLabel(fp.attachment)}
|
|
565
|
+
</div>
|
|
566
|
+
<Show when={fp.attachment.mediaType}>
|
|
567
|
+
<div class="text-muted-foreground text-caption">
|
|
568
|
+
{fp.attachment.mediaType}
|
|
569
|
+
</div>
|
|
570
|
+
</Show>
|
|
571
|
+
</>
|
|
572
|
+
}
|
|
573
|
+
>
|
|
574
|
+
<img
|
|
575
|
+
alt={getAttachmentLabel(fp.attachment)}
|
|
576
|
+
class="block max-h-64 max-w-xs rounded object-contain"
|
|
577
|
+
src={fp.attachment.url}
|
|
578
|
+
/>
|
|
579
|
+
</Show>
|
|
580
|
+
</AttachmentHoverCardContent>
|
|
581
|
+
</AttachmentHoverCard>
|
|
489
582
|
</Attachment>
|
|
490
583
|
)}
|
|
491
584
|
</For>
|
|
@@ -543,7 +636,17 @@ function MessageBody(props: MessageBodyProps) {
|
|
|
543
636
|
part="bubble content"
|
|
544
637
|
markdown={props.markdown}
|
|
545
638
|
class={props.isUser
|
|
546
|
-
|
|
639
|
+
// Content token, not the brand token: `--color-primary`
|
|
640
|
+
// is the documented consumer brand override
|
|
641
|
+
// (theme.css `--kai-color-primary`), so toking message
|
|
642
|
+
// TEXT to it means every consumer that brands primary
|
|
643
|
+
// gets brand-colored message text. `text-foreground` is
|
|
644
|
+
// already `MessageContent`'s base color (matches the
|
|
645
|
+
// assistant path's `bg-transparent p-0`, which carries
|
|
646
|
+
// no color override and falls through to the same
|
|
647
|
+
// base) — dropping `text-primary` here just lets that
|
|
648
|
+
// base apply on the user bubble too.
|
|
649
|
+
? 'bg-muted max-w-[85%] rounded-2xl px-4 py-2'
|
|
547
650
|
: 'bg-transparent p-0'}
|
|
548
651
|
>
|
|
549
652
|
{p().text}
|
|
@@ -552,18 +655,45 @@ function MessageBody(props: MessageBodyProps) {
|
|
|
552
655
|
</Match>
|
|
553
656
|
<Match when={carrierOnly()}>{null}</Match>
|
|
554
657
|
<Match when={shownReasoning()}>
|
|
555
|
-
{(p) =>
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
658
|
+
{(p) => {
|
|
659
|
+
// Default 'full' is the pre-existing DISPLAY MODE byte
|
|
660
|
+
// for byte; the OPEN behavior changed under Task 19f —
|
|
661
|
+
// it no longer auto-opens while streaming by default
|
|
662
|
+
// (owner ruling 2026-08-26). `reasoningDefaultOpen`
|
|
663
|
+
// reproduces the old always-auto-opens behavior when set.
|
|
664
|
+
const mode = () => props.reasoningMode ?? 'full';
|
|
665
|
+
return (
|
|
666
|
+
<Switch fallback={null}>
|
|
667
|
+
<Match when={mode() === 'full'}>
|
|
668
|
+
<Reasoning
|
|
669
|
+
class="mb-2 w-full"
|
|
670
|
+
isStreaming={props.isStreaming}
|
|
671
|
+
defaultOpen={props.reasoningDefaultOpen}
|
|
672
|
+
openOnStream={props.reasoningDefaultOpen}
|
|
673
|
+
>
|
|
674
|
+
<ReasoningTrigger>{p().label ?? 'Reasoning'}</ReasoningTrigger>
|
|
675
|
+
<ReasoningContent markdown>{p().text}</ReasoningContent>
|
|
676
|
+
</Reasoning>
|
|
677
|
+
</Match>
|
|
678
|
+
{/* 'compact': the same "Thinking…" shimmer the full
|
|
679
|
+
disclosure's trigger shows while streaming — no
|
|
680
|
+
<Reasoning>/<ReasoningContent>, so there is no
|
|
681
|
+
expandable detail and nothing left once the part
|
|
682
|
+
settles (isStreaming false → this Match doesn't
|
|
683
|
+
fire, matching 'off'). 'off' never reaches here:
|
|
684
|
+
its Match doesn't fire either. */}
|
|
685
|
+
<Match when={mode() === 'compact' && props.isStreaming}>
|
|
686
|
+
<Loader variant="text-shimmer" text={p().label ?? 'Reasoning'} class="mb-2" />
|
|
687
|
+
</Match>
|
|
688
|
+
</Switch>
|
|
689
|
+
);
|
|
690
|
+
}}
|
|
561
691
|
</Match>
|
|
562
692
|
<Match when={partAs(part(), 'tool')}>
|
|
563
693
|
{(p) => <Tool toolPart={p().tool} class="mb-2 w-full" />}
|
|
564
694
|
</Match>
|
|
565
695
|
<Match when={partAs(part(), 'card')}>
|
|
566
|
-
{(p) => <CardRenderer envelope={p().envelope} types={props.cardTypes} schemas={props.cardSchemas} />}
|
|
696
|
+
{(p) => <CardRenderer envelope={p().envelope} types={props.cardTypes} schemas={props.cardSchemas} hostElement={props.cardHostElement} />}
|
|
567
697
|
</Match>
|
|
568
698
|
{/* No `source` match here on purpose: source parts never
|
|
569
699
|
reach a 'single' group — they are collapsed into a
|
|
@@ -115,9 +115,15 @@ function PromptInputTextarea(props: PromptInputTextareaProps) {
|
|
|
115
115
|
// the contenteditable composer is visually identical. The frame (PromptInput
|
|
116
116
|
// root) still owns radius/bg/padding/focus-ring; auto-grow is native to a
|
|
117
117
|
// contenteditable block (capped via max-height on the editable).
|
|
118
|
+
// `text-start` is a PIN, not a style choice: `text-align` inherits, so any
|
|
119
|
+
// centered ancestor (`Empty`'s root did exactly this) reached in and centered
|
|
120
|
+
// the placeholder AND the typed text. An input control's text alignment is a
|
|
121
|
+
// fact about the control, so it states it rather than inheriting it. LOGICAL
|
|
122
|
+
// (`start`), not `text-left` — in RTL the correct edge is the right one, and
|
|
123
|
+
// pinning the physical value would be a worse bug than the one it fixes.
|
|
118
124
|
const editableClass = () =>
|
|
119
125
|
cn(
|
|
120
|
-
'text-foreground min-h-[44px] w-full bg-transparent shadow-none outline-none focus-visible:ring-0 focus-visible:ring-offset-0 overflow-y-auto whitespace-pre-wrap break-words',
|
|
126
|
+
'text-foreground min-h-[44px] w-full bg-transparent text-start shadow-none outline-none focus-visible:ring-0 focus-visible:ring-offset-0 overflow-y-auto whitespace-pre-wrap break-words',
|
|
121
127
|
textClass(config.proseSize()),
|
|
122
128
|
local.class,
|
|
123
129
|
);
|
|
@@ -136,7 +136,10 @@ function renderHighlighted(text: string, highlight: string) {
|
|
|
136
136
|
<Show when={before}>
|
|
137
137
|
<span class="text-foreground/70 whitespace-pre-wrap">{before}</span>
|
|
138
138
|
</Show>
|
|
139
|
-
|
|
139
|
+
{/* Matched-substring highlight is CONTENT, not a control — was the BRAND
|
|
140
|
+
token. Full-strength `text-foreground` against the `/70`-opacity
|
|
141
|
+
siblings above/below is what actually carries the highlight. */}
|
|
142
|
+
<span class="text-foreground font-medium whitespace-pre-wrap">{matched}</span>
|
|
140
143
|
<Show when={after}>
|
|
141
144
|
<span class="text-foreground/70 whitespace-pre-wrap">{after}</span>
|
|
142
145
|
</Show>
|
|
@@ -3,6 +3,7 @@ import { cn } from '../utils/cn';
|
|
|
3
3
|
import { ChevronDown } from 'lucide-solid';
|
|
4
4
|
import { Markdown } from './markdown';
|
|
5
5
|
import { observeContentHeight } from '../primitives/use-resize-observer';
|
|
6
|
+
import { TextShimmer } from './text-shimmer';
|
|
6
7
|
|
|
7
8
|
interface ReasoningContextValue {
|
|
8
9
|
isOpen: () => boolean;
|
|
@@ -18,6 +19,11 @@ interface ReasoningContextValue {
|
|
|
18
19
|
/** The registered trigger. Deliberately a plain getter over a mutable
|
|
19
20
|
* variable, NOT a signal — registration must not re-run the content effect. */
|
|
20
21
|
trigger: () => HTMLElement | undefined;
|
|
22
|
+
/** Whether the reasoning is currently streaming — read by `ReasoningTrigger`
|
|
23
|
+
* to decide how its own label renders (shimmer while streaming, plain
|
|
24
|
+
* neutral text once settled). Kit-decides-HOW: every consumer gets the same
|
|
25
|
+
* "Thinking…" shimmer behavior for free, with no prop of their own. */
|
|
26
|
+
isStreaming: () => boolean;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
/** Imperative open controller, handed to a parent (the kai-reasoning facade) via
|
|
@@ -49,10 +55,16 @@ export interface ReasoningProps {
|
|
|
49
55
|
disabled?: boolean;
|
|
50
56
|
/** Receive the open controller (open accessor + setOpen) once mounted. */
|
|
51
57
|
controllerRef?: (api: ReasoningController) => void;
|
|
58
|
+
/** Keep auto-opening while streaming and auto-closing when it settles (the
|
|
59
|
+
* pre-Task-19f `full` behavior). Default false: the panel starts per
|
|
60
|
+
* `defaultOpen` and stays exactly where the user leaves it — streaming only
|
|
61
|
+
* changes the trigger's label (shimmer), never the open state, matching the
|
|
62
|
+
* "closed chip, expand on click" default (owner ruling, 2026-08-26). */
|
|
63
|
+
openOnStream?: boolean;
|
|
52
64
|
}
|
|
53
65
|
|
|
54
66
|
function Reasoning(props: ReasoningProps) {
|
|
55
|
-
const [local] = splitProps(props, ['children', 'class', 'open', 'defaultOpen', 'onOpenChange', 'isStreaming', 'disabled', 'controllerRef']);
|
|
67
|
+
const [local] = splitProps(props, ['children', 'class', 'open', 'defaultOpen', 'onOpenChange', 'isStreaming', 'disabled', 'controllerRef', 'openOnStream']);
|
|
56
68
|
const [internalOpen, setInternalOpen] = createSignal(local.defaultOpen ?? false);
|
|
57
69
|
const [wasAutoOpened, setWasAutoOpened] = createSignal(false);
|
|
58
70
|
|
|
@@ -72,6 +84,7 @@ function Reasoning(props: ReasoningProps) {
|
|
|
72
84
|
};
|
|
73
85
|
|
|
74
86
|
createEffect(() => {
|
|
87
|
+
if (!local.openOnStream) return;
|
|
75
88
|
const streaming = local.isStreaming;
|
|
76
89
|
if (streaming && !wasAutoOpened()) {
|
|
77
90
|
if (!isControlled()) setInternalOpen(true);
|
|
@@ -104,6 +117,7 @@ function Reasoning(props: ReasoningProps) {
|
|
|
104
117
|
contentId,
|
|
105
118
|
registerTrigger: (el) => { triggerEl = el; },
|
|
106
119
|
trigger: () => triggerEl,
|
|
120
|
+
isStreaming: () => !!local.isStreaming,
|
|
107
121
|
}}
|
|
108
122
|
>
|
|
109
123
|
<div class={local.class}>{local.children}</div>
|
|
@@ -122,7 +136,7 @@ function ReasoningTrigger(props: ReasoningTriggerProps) {
|
|
|
122
136
|
// to register as the panel's focus-return target, and a spread `ref` would
|
|
123
137
|
// silently replace it. The consumer's ref is forwarded below instead.
|
|
124
138
|
const [local, rest] = splitProps(props, ['children', 'class', 'ref']);
|
|
125
|
-
const { isOpen, onOpenChange, disabled, contentId, registerTrigger } = useReasoningContext();
|
|
139
|
+
const { isOpen, onOpenChange, disabled, contentId, registerTrigger, isStreaming } = useReasoningContext();
|
|
126
140
|
|
|
127
141
|
return (
|
|
128
142
|
// The same disclosure contract as CollapsibleTrigger: an explicit
|
|
@@ -149,7 +163,20 @@ function ReasoningTrigger(props: ReasoningTriggerProps) {
|
|
|
149
163
|
onClick={() => { if (!disabled()) onOpenChange(!isOpen()); }}
|
|
150
164
|
{...rest}
|
|
151
165
|
>
|
|
152
|
-
|
|
166
|
+
{/* Content/chrome, not a control: was `text-primary`, the BRAND token, so
|
|
167
|
+
a consumer's branded --kai-color-primary bled onto the "Thinking"
|
|
168
|
+
label. `text-foreground` matches the sibling `<Tool>` disclosure
|
|
169
|
+
trigger's label (rendered via `Button variant="ghost"`, itself
|
|
170
|
+
`text-foreground`) — the established neutral for a disclosure
|
|
171
|
+
trigger's own label text in this codebase.
|
|
172
|
+
Kit-decides-HOW: while streaming, the label renders with the kit's
|
|
173
|
+
own `TextShimmer` (the common "Thinking…" shimmer, already used by
|
|
174
|
+
`Loader`'s `text-shimmer` variant) instead of static text; once
|
|
175
|
+
settled it's the plain neutral span above. Every consumer gets this
|
|
176
|
+
for free — no prop of their own. */}
|
|
177
|
+
<Show when={isStreaming()} fallback={<span class="text-foreground">{local.children}</span>}>
|
|
178
|
+
<TextShimmer class="font-medium">{local.children}</TextShimmer>
|
|
179
|
+
</Show>
|
|
153
180
|
<div
|
|
154
181
|
class={cn(
|
|
155
182
|
'transform transition-transform',
|
|
@@ -365,7 +365,7 @@ function CompareColumn(props: ColumnProps): JSX.Element {
|
|
|
365
365
|
return (
|
|
366
366
|
<div
|
|
367
367
|
class={cn(
|
|
368
|
-
'flex min-w-0 flex-col gap-3 rounded-lg border border-
|
|
368
|
+
'flex min-w-0 flex-col gap-3 rounded-lg border border-border bg-background/40 p-3',
|
|
369
369
|
props.hiddenClass?.(),
|
|
370
370
|
)}
|
|
371
371
|
>
|
|
@@ -432,7 +432,7 @@ function CollapsedWinner(props: {
|
|
|
432
432
|
}): JSX.Element {
|
|
433
433
|
return (
|
|
434
434
|
<div
|
|
435
|
-
class="flex flex-col gap-2 rounded-lg border border-
|
|
435
|
+
class="flex flex-col gap-2 rounded-lg border border-border bg-accent/40 p-3"
|
|
436
436
|
role={props.optimistic ? 'status' : undefined}
|
|
437
437
|
>
|
|
438
438
|
<div class="flex items-center gap-2 text-sm font-medium text-accent-foreground">
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { splitProps, Show, For, createEffect, on } from 'solid-js';
|
|
2
|
+
import { Dynamic } from 'solid-js/web';
|
|
2
3
|
import { cn } from '../utils/cn';
|
|
3
|
-
import { useTextStream } from '../primitives/use-text-stream';
|
|
4
|
+
import { useTextStream, defaultFadeDuration, defaultSegmentDelay } from '../primitives/use-text-stream';
|
|
4
5
|
|
|
5
6
|
export type Mode = 'typewriter' | 'fade';
|
|
6
7
|
|
|
@@ -30,6 +31,7 @@ function ResponseStream(props: ResponseStreamProps) {
|
|
|
30
31
|
speed: speed(),
|
|
31
32
|
characterChunkSize: local.characterChunkSize,
|
|
32
33
|
fadeDuration: local.fadeDuration,
|
|
34
|
+
segmentDelay: local.segmentDelay,
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
createEffect(on(
|
|
@@ -39,15 +41,20 @@ function ResponseStream(props: ResponseStreamProps) {
|
|
|
39
41
|
}
|
|
40
42
|
));
|
|
41
43
|
|
|
44
|
+
// Deferred: `isComplete` INITIALISES true (nothing has streamed yet), so an
|
|
45
|
+
// undeferred first run would announce completion at mount — the same
|
|
46
|
+
// no-event-on-mount contract kai-tool pins for kai-open-change. Only the
|
|
47
|
+
// false -> true transition of a real stream may call onComplete.
|
|
42
48
|
createEffect(on(
|
|
43
49
|
() => stream.isComplete(),
|
|
44
50
|
(complete) => {
|
|
45
51
|
if (complete) local.onComplete?.();
|
|
46
|
-
}
|
|
52
|
+
},
|
|
53
|
+
{ defer: true }
|
|
47
54
|
));
|
|
48
55
|
|
|
49
56
|
const fadeStyle = () => {
|
|
50
|
-
const dur = local.fadeDuration ??
|
|
57
|
+
const dur = local.fadeDuration ?? defaultFadeDuration(speed());
|
|
51
58
|
return `
|
|
52
59
|
@keyframes fadeIn {
|
|
53
60
|
from { opacity: 0; }
|
|
@@ -66,12 +73,11 @@ function ResponseStream(props: ResponseStreamProps) {
|
|
|
66
73
|
|
|
67
74
|
const segDelay = () => {
|
|
68
75
|
if (typeof local.segmentDelay === 'number') return Math.max(0, local.segmentDelay);
|
|
69
|
-
|
|
70
|
-
return Math.max(1, Math.round(100 / Math.sqrt(normalizedSpeed)));
|
|
76
|
+
return defaultSegmentDelay(speed());
|
|
71
77
|
};
|
|
72
78
|
|
|
73
79
|
return (
|
|
74
|
-
<div class={local.class}>
|
|
80
|
+
<Dynamic component={local.as ?? 'div'} class={local.class}>
|
|
75
81
|
<Show
|
|
76
82
|
when={mode() === 'fade'}
|
|
77
83
|
fallback={<>{stream.displayedText()}</>}
|
|
@@ -96,7 +102,7 @@ function ResponseStream(props: ResponseStreamProps) {
|
|
|
96
102
|
</For>
|
|
97
103
|
</div>
|
|
98
104
|
</Show>
|
|
99
|
-
</
|
|
105
|
+
</Dynamic>
|
|
100
106
|
);
|
|
101
107
|
}
|
|
102
108
|
|
|
@@ -144,6 +144,11 @@ export function Screen(props: ScreenProps) {
|
|
|
144
144
|
data-expanded={presence.state() === 'open' ? '' : undefined}
|
|
145
145
|
data-closed={presence.state() === 'closed' ? '' : undefined}
|
|
146
146
|
onKeyDown={onKeyDown}
|
|
147
|
+
// `outline-none` is DELIBERATE here and must stay: this is the
|
|
148
|
+
// `tabindex="-1"` screen container, focused programmatically on open so
|
|
149
|
+
// keyboard and screen-reader context follows the screen. It is not a
|
|
150
|
+
// tab stop, so a ring around the whole surface would be noise. Its
|
|
151
|
+
// interactive children carry their own.
|
|
147
152
|
class={cn(
|
|
148
153
|
'absolute inset-0 z-40 flex flex-col bg-background text-foreground outline-none',
|
|
149
154
|
'animate-in fade-in-0 slide-in-from-bottom-2 motion-reduce:animate-none',
|
|
@@ -1,24 +1,74 @@
|
|
|
1
|
+
import { Show } from 'solid-js';
|
|
1
2
|
import { cn } from '../utils/cn';
|
|
2
3
|
import { Button } from '../ui/button';
|
|
3
4
|
import { useChatContainer } from './chat-container';
|
|
4
|
-
import {
|
|
5
|
+
import { ArrowDown } from 'lucide-solid';
|
|
6
|
+
|
|
7
|
+
/** The accessible name used when the consumer does not supply one. */
|
|
8
|
+
const DEFAULT_LABEL = 'Scroll to bottom';
|
|
5
9
|
|
|
6
10
|
export interface ScrollButtonProps {
|
|
7
11
|
class?: string;
|
|
8
12
|
variant?: 'outline' | 'ghost' | 'default';
|
|
9
13
|
size?: 'sm' | 'md' | 'lg' | 'icon' | 'icon-sm';
|
|
14
|
+
/**
|
|
15
|
+
* The button's accessible name. Used whether or not the label is visible, so
|
|
16
|
+
* the announced text is always localisable. Defaults to `"Scroll to bottom"`.
|
|
17
|
+
*/
|
|
18
|
+
label?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Also render `label` visibly beside the icon. Defaults to `false` (icon
|
|
21
|
+
* only). When it is visible the text IS the accessible name, so nothing is
|
|
22
|
+
* announced twice.
|
|
23
|
+
*/
|
|
24
|
+
showLabel?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The floating chip surface.
|
|
29
|
+
*
|
|
30
|
+
* The shared `outline` button variant is `bg-muted/50` — half-transparent, so
|
|
31
|
+
* message text showed through a control that floats over scrolling content, and
|
|
32
|
+
* its edge measured 1.05:1 against the thread behind it (SC 1.4.11 wants 3:1).
|
|
33
|
+
* `bg-card` is the same opaque surface popovers, dropdowns and hover cards sit
|
|
34
|
+
* on; `border-input` is the kit's control edge and clears 3:1 in both themes;
|
|
35
|
+
* `kai-elevation` is the shared, themeable float shadow (`--kai-shadow-color`),
|
|
36
|
+
* which is what keeps an opaque button reading as ABOVE the content.
|
|
37
|
+
*
|
|
38
|
+
* `ghost` and `default` are explicit consumer choices about the fill, so they
|
|
39
|
+
* keep theirs; every variant gets the elevation and the rounded-square radius.
|
|
40
|
+
*/
|
|
41
|
+
function surfaceClasses(variant: ScrollButtonProps['variant']) {
|
|
42
|
+
return (variant ?? 'outline') === 'outline'
|
|
43
|
+
? 'border border-input bg-card text-card-foreground kai-elevation'
|
|
44
|
+
: 'kai-elevation';
|
|
10
45
|
}
|
|
11
46
|
|
|
12
47
|
function ScrollButton(props: ScrollButtonProps) {
|
|
13
48
|
const { isAtBottom, scrollToBottom } = useChatContainer();
|
|
49
|
+
const label = () => props.label ?? DEFAULT_LABEL;
|
|
50
|
+
const showLabel = () => props.showLabel === true;
|
|
14
51
|
|
|
15
52
|
return (
|
|
16
53
|
<Button
|
|
17
54
|
variant={props.variant ?? 'outline'}
|
|
18
55
|
size={props.size ?? 'sm'}
|
|
19
|
-
aria-label
|
|
56
|
+
// When the label is visible it IS the accessible name. An aria-label on
|
|
57
|
+
// top of it would override the visible text and leave the two able to
|
|
58
|
+
// disagree, so it is only set for the icon-only case.
|
|
59
|
+
aria-label={showLabel() ? undefined : label()}
|
|
60
|
+
// At the bottom of the thread this button is fully transparent and
|
|
61
|
+
// pointer-inert, but it stayed in the tab order — a keyboard user landed
|
|
62
|
+
// on a control they could not see, with a focus ring painted on nothing.
|
|
63
|
+
// Take it out of the tab order and hide it from assistive tech while it
|
|
64
|
+
// is invisible; both revert the moment it animates back in.
|
|
65
|
+
tabindex={isAtBottom() ? -1 : 0}
|
|
66
|
+
aria-hidden={isAtBottom() ? 'true' : undefined}
|
|
20
67
|
class={cn(
|
|
21
|
-
'
|
|
68
|
+
'rounded-lg transition-all duration-150 ease-out',
|
|
69
|
+
surfaceClasses(props.variant),
|
|
70
|
+
// Square while icon-only; a pill-ish labelled button once the text is in.
|
|
71
|
+
showLabel() ? 'h-10 w-auto gap-1.5 px-3.5 text-sm' : 'h-10 w-10 px-0',
|
|
22
72
|
!isAtBottom()
|
|
23
73
|
? 'translate-y-0 scale-100 opacity-100'
|
|
24
74
|
: 'pointer-events-none translate-y-4 scale-95 opacity-0',
|
|
@@ -26,7 +76,16 @@ function ScrollButton(props: ScrollButtonProps) {
|
|
|
26
76
|
)}
|
|
27
77
|
onClick={() => scrollToBottom()}
|
|
28
78
|
>
|
|
29
|
-
|
|
79
|
+
{/* h-4, not the h-5 the chevron used. A ChevronDown only inks the lower
|
|
80
|
+
part of its 24px viewBox, so at a 20px box its visible mass is small;
|
|
81
|
+
ArrowDown inks the full height (stem + head), and at 20px inside a 40px
|
|
82
|
+
button it read as half the button wide and crowded the padding. 16px
|
|
83
|
+
balances the icon-only square and is the size lucide pairs with
|
|
84
|
+
text-sm, which is what the label renders at. */}
|
|
85
|
+
<ArrowDown class="h-4 w-4 shrink-0" aria-hidden="true" />
|
|
86
|
+
<Show when={showLabel()}>
|
|
87
|
+
<span>{label()}</span>
|
|
88
|
+
</Show>
|
|
30
89
|
</Button>
|
|
31
90
|
);
|
|
32
91
|
}
|
|
@@ -152,7 +152,12 @@ function SourceContent(props: SourceContentProps) {
|
|
|
152
152
|
width={16}
|
|
153
153
|
height={16}
|
|
154
154
|
/>
|
|
155
|
-
|
|
155
|
+
{/* Citation title/domain is CONTENT, not a control — was the BRAND
|
|
156
|
+
token. `text-foreground/80` matches how `SourceTrigger` above
|
|
157
|
+
already renders this same domain text (inherited from its `<a
|
|
158
|
+
class="... text-foreground/80 ...">`), so the hover-card header
|
|
159
|
+
and the trigger chip agree on the same domain's color. */}
|
|
160
|
+
<div class="text-foreground/80 truncate text-sm">
|
|
156
161
|
{ctx.domain.replace('www.', '')}
|
|
157
162
|
</div>
|
|
158
163
|
</div>
|