@kitn.ai/ui 0.27.0 → 0.29.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 +10 -2
- package/dist/{Icon-BnFKqqtY.js → Icon-DObhsRtm.js} +1 -1
- package/dist/{action-icons-CBskfBMz.js → action-icons-CcgNN2oT.js} +1 -1
- package/dist/agent-tooling/construct/public.d.ts +15 -0
- package/dist/agent-tooling/construct/schema.d.ts +111 -0
- package/dist/arrow-down-CjRU3JgV.js +1 -0
- package/dist/arrow-left-Bnpb1UEW.js +1 -0
- package/dist/{artifact-CvXEm1lS.js → artifact-Bwt7OgcR.js} +1 -1
- package/dist/{attachments-C43ZegEq.js → attachments-Qr4kg-2b.js} +1 -1
- package/dist/{audio-visualizer-B-79y1Tj.js → audio-visualizer-DToYdfSc.js} +1 -1
- package/dist/{badge-BpUbq8c0.js → badge-CdEu_jn2.js} +1 -1
- package/dist/{bell-sn17Ip9v.js → bell-DQAAOpDz.js} +1 -1
- package/dist/{button-BH6rN0U-.js → button-DkuOnGLy.js} +1 -1
- package/dist/{card-renderer-Cb1gQmth.js → card-renderer-Jx70m6_l.js} +1 -1
- package/dist/{card-routing-DifQgS7n.js → card-routing-0YidER_3.js} +1 -1
- package/dist/check-njkVdZu2.js +1 -0
- package/dist/{checkbox-Dc9Yov_B.js → checkbox-D7iRB3nL.js} +1 -1
- package/dist/{checkbox-group-B1kDLLYk.js → checkbox-group-B2_rpoPM.js} +1 -1
- package/dist/chevron-down-B72s6PXR.js +1 -0
- package/dist/chevron-right-BatuHzUm.js +1 -0
- package/dist/{choice-card-BT3c1S8g.js → choice-card-m0BYqqOK.js} +1 -1
- package/dist/circle-check-B62pODB3.js +1 -0
- package/dist/{circle-x-wobWkoSx.js → circle-x-BPG0iPst.js} +1 -1
- package/dist/circle-zx0ByzY9.js +1 -0
- package/dist/code-block-ClMLKb7C.js +1 -0
- package/dist/{collapsible-CPJbf6FM.js → collapsible-B4DlWicL.js} +1 -1
- package/dist/components/chat-thread.d.ts +89 -1
- package/dist/components/conversation-item.d.ts +16 -0
- package/dist/components/conversation-panel.d.ts +29 -0
- package/dist/components/home-panel.d.ts +34 -0
- package/dist/components/widget-tab-bar.d.ts +16 -0
- package/dist/{composer-CjngLzal.js → composer-sQ0HcvyG.js} +3 -3
- package/dist/{confirm-card-DCx_A4bU.js → confirm-card-rQWDQsnC.js} +1 -1
- package/dist/construct-cli.es.js +185 -17
- package/dist/construct.d.ts +5 -0
- package/dist/construct.js +327 -0
- package/dist/{context-BY8V-Nlp.js → context-0kg4ZX1J.js} +1 -1
- package/dist/controllable-CnGpMF6r.js +1 -0
- package/dist/conversation-item-BxwQLaFJ.js +1 -0
- package/dist/conversation-list-BCfGN1JU.js +1 -0
- package/dist/{copy-B6DO4PqB.js → copy-n9u9rqpi.js} +1 -1
- package/dist/core-C8fzo39E.js +1 -12
- package/dist/{create-tween-CnMHviKB.js → create-tween-C-q-JCM-.js} +1 -1
- package/dist/{create-tween-D1aiGZZh.js → create-tween-CRrJXxBd.js} +1 -1
- package/dist/{create-tween-BPzaefTp.js → create-tween-DZ3RRDHD.js} +1 -1
- package/dist/{create-tween-DUSQUKpr.js → create-tween-uPkArjIG.js} +1 -1
- package/dist/custom-elements.json +51 -2
- package/dist/{default-input-CucQEOqH.js → default-input-CaMrJkgH.js} +1 -1
- package/dist/define-By-uL588.js +1 -0
- package/dist/define.js +2 -2
- package/dist/define.server.js +2 -2
- package/dist/{disclosure-CbLtajUQ.js → disclosure-WUImBbDv.js} +1 -1
- package/dist/{dropdown-BwhViJFd.js → dropdown-wZVeJOMd.js} +1 -1
- package/dist/elements/agent-card.js +1 -1
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/audio-visualizer.js +1 -1
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/badge.js +1 -1
- package/dist/elements/button.js +1 -1
- package/dist/elements/card.js +1 -1
- package/dist/elements/cards.js +1 -1
- package/dist/elements/chain-of-thought.js +1 -1
- package/dist/elements/chat-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.js +1 -1
- package/dist/elements/checkbox.js +1 -1
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/coachmark.js +1 -1
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.js +1 -1
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.js +1 -1
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-item.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.js +3 -3
- package/dist/elements/dropdown.js +1 -1
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.js +1 -1
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-grid.js +1 -1
- package/dist/elements/pane-group.js +1 -1
- package/dist/elements/pane.js +1 -1
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.js +1 -1
- package/dist/elements/prompt-dock.js +1 -1
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/radio-group.js +1 -1
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +1 -1
- package/dist/elements/screen.js +1 -1
- package/dist/elements/scroll-area.js +1 -1
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.js +1 -1
- package/dist/elements/segmented.js +1 -1
- package/dist/elements/select.js +1 -1
- package/dist/elements/separator.js +1 -1
- package/dist/elements/setting-item.js +1 -1
- package/dist/elements/settings-group.js +1 -1
- package/dist/elements/skeleton.js +1 -1
- package/dist/elements/slider.js +1 -1
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.js +1 -1
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.js +1 -1
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/thread.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.js +1 -1
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/elements.d.ts +20 -4
- package/dist/{ellipsis-DFr4Vqr3.js → ellipsis-CbOpJnU3.js} +1 -1
- package/dist/{embed-5s_vU4J0.js → embed-CrfjkbUG.js} +1 -1
- package/dist/engine-javascript-C1x7zo1_.js +1 -141
- package/dist/{external-link-u9d85ORQ.js → external-link-ByXAwBBQ.js} +1 -1
- package/dist/{file-text-CX7_x42o.js → file-text-DMib2qwt.js} +1 -1
- package/dist/{file-tree-D3kBjXI5.js → file-tree-CJqM2aP7.js} +1 -1
- package/dist/{folder-V-YdIL8f.js → folder-_BAb929C.js} +1 -1
- package/dist/{form-BRNUMCN2.js → form-DSZgZQZk.js} +1 -1
- package/dist/{hover-card-DaeiYrTA.js → hover-card-BQbul9eq.js} +1 -1
- package/dist/{icon-BpixdZNq.js → icon-CdcfRhYI.js} +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2842 -2703
- package/dist/index.server.js +2820 -2681
- package/dist/{info-8mFsIjS3.js → info-DsFjGuI_.js} +1 -1
- package/dist/{input-d1Yuu-hz.js → input-DKbmkMos.js} +1 -1
- package/dist/kai.es.js +1 -1
- package/dist/{kbd-961zMPFB.js → kbd-PvdGhX4s.js} +1 -1
- package/dist/{link-preview-DIIbV2Sd.js → link-preview-DbM1866N.js} +1 -1
- package/dist/{link-DlZZBGaR.js → link-zF8PzWfF.js} +1 -1
- package/dist/{loader-YQszHFaW.js → loader-BM4CEz4G.js} +1 -1
- package/dist/{markdown-CVk1MPsj.js → markdown-LMvmAyBk.js} +7 -7
- package/dist/mcp.es.js +79 -5
- package/dist/{message-CwKVEdZg.js → message-BSsgvHvf.js} +1 -1
- package/dist/{message-DS8lzHc1.js → message-BYZECyek.js} +1 -1
- package/dist/message-circle-DruwObfX.js +1 -0
- package/dist/message-square-BG6q6mlm.js +1 -0
- package/dist/{minimize-2-UEZmP2QT.js → minimize-2-BQRoBV1V.js} +1 -1
- package/dist/{model-switcher-Kk1jEQ5t.js → model-switcher-CMpCOYcB.js} +1 -1
- package/dist/{overlay-C1od6LOz.js → overlay-Cb-MkyDa.js} +1 -1
- package/dist/{panel-right-ryET0yyn.js → panel-right-i8warFxT.js} +1 -1
- package/dist/{paperclip-BDNoZFJP.js → paperclip-ByY3UVO6.js} +1 -1
- package/dist/play-BvKKq3fX.js +1 -0
- package/dist/primitives/conversation-store.d.ts +54 -0
- package/dist/{progress-bar-BvYX0aoy.js → progress-bar-jVAHvMUf.js} +1 -1
- package/dist/{prompt-suggestion-BRFu2lcu.js → prompt-suggestion-CD-qtNgC.js} +1 -1
- package/dist/{radio-DcL23cNJ.js → radio-BsoBMhkF.js} +1 -1
- package/dist/react/index.d.ts +393 -0
- package/dist/react.js +20 -20
- package/dist/{reasoning-Cackq4Rh.js → reasoning-4kBPtlTx.js} +1 -1
- package/dist/register-impl-B1hLkrI8.js +424 -0
- package/dist/{resizable-Cp9HUYih.js → resizable-uPmY9VY-.js} +1 -1
- package/dist/{rotate-ccw-0DLRDHH5.js → rotate-ccw-B2xn93py.js} +1 -1
- package/dist/{rotate-cw-DOB9IGcU.js → rotate-cw-CMVLoCyH.js} +1 -1
- package/dist/{scroll-area-emVmWP4K.js → scroll-area-BqLUo8ZZ.js} +1 -1
- package/dist/{scroll-button-CeP_gv1x.js → scroll-button-DslXiJyL.js} +1 -1
- package/dist/{select-CWmu00tS.js → select-2cLRtPGT.js} +1 -1
- package/dist/{separator-CE6vly6z.js → separator-BWQtNJcM.js} +1 -1
- package/dist/{settings-CE-78SvZ.js → settings-BBR63jLg.js} +1 -1
- package/dist/{settings-group-ZFWNxFQR.js → settings-group-B2ciy-Iw.js} +1 -1
- package/dist/{skeleton-BebdP4mf.js → skeleton-CkHI-HgC.js} +1 -1
- package/dist/{slider-BAKRYUlz.js → slider-DDR9U-i0.js} +1 -1
- package/dist/{solid-BE5ui6sy.js → solid-BzCFdL25.js} +7720 -7058
- package/dist/{solid-DFhsce3O.js → solid-DruVOXnf.js} +5864 -5283
- package/dist/solid.d.ts +6 -2
- package/dist/solid.js +217 -210
- package/dist/solid.server.js +217 -210
- package/dist/{source-B0FlguSx.js → source-GEnFF528.js} +1 -1
- package/dist/{star-CBMZvLuN.js → star-CilHq8GP.js} +1 -1
- package/dist/store-Ciyk6eZG.js +1 -0
- package/dist/{switch-CViARZCy.js → switch-KkeQIbuH.js} +1 -1
- package/dist/{tasks-card-MjCcOhR_.js → tasks-card-BrN4bggJ.js} +1 -1
- package/dist/{text-shimmer-DKlwRF2G.js → text-shimmer-Dcj1MHuq.js} +1 -1
- package/dist/{textarea-3ay2Me2-.js → textarea-Dpvbngbg.js} +1 -1
- package/dist/theme.tokens.css +28 -0
- package/dist/{thumbs-up-DQcu2HMO.js → thumbs-up-CsT9Wzb9.js} +1 -1
- package/dist/{toast-store-C6yKOhbk.js → toast-store-tgK6MuMv.js} +1 -1
- package/dist/{tool-BCYNlfKy.js → tool-DzUjIBT8.js} +1 -1
- package/dist/{tooltip-05zI4hjs.js → tooltip-Bkkg_4t0.js} +1 -1
- package/dist/{trash-2-BR1RxGky.js → trash-2-jBKxjGGQ.js} +1 -1
- package/dist/{triangle-alert-DHohDOCy.js → triangle-alert-DlQ68ppf.js} +1 -1
- package/dist/types.d.ts +48 -3
- package/dist/ui/dock.d.ts +29 -0
- package/dist/{upload-BbGW6A_u.js → upload-TcAHXv9W.js} +1 -1
- package/dist/{url-scheme-policy-DHpoTJwB.js → url-scheme-policy-DR5DgvkM.js} +1 -1
- package/dist/{use-card-resolution-CJW4grFa.js → use-card-resolution-DaZqAdWf.js} +1 -1
- package/dist/{variant-aurora-xiMPty8f.js → variant-aurora-BhLuYxJR.js} +1 -1
- package/dist/{variant-aurora-BUOVgPOB.js → variant-aurora-CNmfHhcx.js} +2 -2
- package/dist/{variant-aurora-CUsUJvFI.js → variant-aurora-D6GsdTPA.js} +2 -2
- package/dist/{variant-aurora-CW2i4bfr.js → variant-aurora-DbW_OWL2.js} +1 -1
- package/dist/{variant-custom-D91HjAKz.js → variant-custom-BRvaNHSi.js} +1 -1
- package/dist/{variant-custom-BQtOnmeO.js → variant-custom-BvYHR62b.js} +1 -1
- package/dist/{variant-custom-CAnzzppW.js → variant-custom-DMTrEO5w.js} +2 -2
- package/dist/{variant-custom-CAm9L-E5.js → variant-custom-DV2x254s.js} +2 -2
- package/dist/{variant-wave-Ca1Ls4_y.js → variant-wave-BNMGrDfj.js} +2 -2
- package/dist/{variant-wave-uY5crU_K.js → variant-wave-BpDd8t3Z.js} +1 -1
- package/dist/{variant-wave-CxX39DKd.js → variant-wave-CyBueXj9.js} +2 -2
- package/dist/{variant-wave-DYyzIIZv.js → variant-wave-sp-qwsdI.js} +1 -1
- package/dist/x-Z5UntkIJ.js +1 -0
- package/frameworks/react/index.tsx +14 -4
- package/llms-full.txt +7 -2
- package/package.json +16 -16
- package/src/elements/element-meta.json +49 -6
- package/theme.css +28 -0
- package/bin/route.test.js +0 -58
- package/dist/arrow-down-Br0qtpsz.js +0 -1
- package/dist/arrow-left-Dj7xgE12.js +0 -1
- package/dist/check-DPeeMUYx.js +0 -1
- package/dist/chevron-down-CHSWk7ZT.js +0 -1
- package/dist/chevron-right-B7l_fMgx.js +0 -1
- package/dist/circle-Bb0yOpqM.js +0 -1
- package/dist/circle-check-BGZpCiz7.js +0 -1
- package/dist/code-block-CUQ5mtv0.js +0 -1
- package/dist/controllable-D43BKmtX.js +0 -1
- package/dist/conversation-list-D4lLU_yS.js +0 -1
- package/dist/define-CGGX-7Vg.js +0 -1
- package/dist/message-circle-Xf8Q-vZp.js +0 -1
- package/dist/message-square-Cxnwgkns.js +0 -1
- package/dist/play-OFIvYXUQ.js +0 -1
- package/dist/register-impl-C7rENvPK.js +0 -424
- package/dist/store-7eoadydQ.js +0 -1
- package/dist/x-C5m1JFgi.js +0 -1
- package/src/agent-tooling/archetypes.ts +0 -205
- package/src/agent-tooling/catalog/README.md +0 -676
- package/src/agent-tooling/catalog/catalog-types.ts +0 -231
- package/src/agent-tooling/catalog/fabrications.ts +0 -96
- package/src/agent-tooling/catalog/invariants.ts +0 -284
- package/src/agent-tooling/catalog/labs-titles.ts +0 -114
- package/src/agent-tooling/catalog/scenarios.ts +0 -87
- package/src/agent-tooling/catalog/surfaces.ts +0 -347
- package/src/agent-tooling/construct/cli-entry.ts +0 -8
- package/src/agent-tooling/construct/cli.ts +0 -131
- package/src/agent-tooling/construct/codegen.ts +0 -1353
- package/src/agent-tooling/construct/construct.v1.schema.json +0 -250
- package/src/agent-tooling/construct/dev.ts +0 -148
- package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +0 -7
- package/src/agent-tooling/construct/fixtures/ops-console.construct.json +0 -44
- package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +0 -23
- package/src/agent-tooling/construct/schema.ts +0 -371
- package/src/agent-tooling/integrations/anthropic.ts +0 -442
- package/src/agent-tooling/integrations/cloudflare.ts +0 -218
- package/src/agent-tooling/integrations/langgraph.ts +0 -133
- package/src/agent-tooling/integrations/mastra.ts +0 -182
- package/src/agent-tooling/integrations/mock.ts +0 -148
- package/src/agent-tooling/integrations/ollama.ts +0 -97
- package/src/agent-tooling/integrations/openai.ts +0 -95
- package/src/agent-tooling/integrations/openrouter.ts +0 -82
- package/src/agent-tooling/integrations/pi.ts +0 -176
- package/src/agent-tooling/integrations/pydantic-ai.ts +0 -108
- package/src/agent-tooling/integrations/vercel-ai-sdk.ts +0 -398
- package/src/agent-tooling/mcp/css-raw.d.ts +0 -12
- package/src/agent-tooling/mcp/manifest.ts +0 -422
- package/src/agent-tooling/mcp/server.ts +0 -116
- package/src/agent-tooling/mcp/stdio.ts +0 -18
- package/src/agent-tooling/mcp/tools/construct.ts +0 -130
- package/src/agent-tooling/mcp/tools/debug.ts +0 -621
- package/src/agent-tooling/mcp/tools/reference.ts +0 -980
- package/src/agent-tooling/mcp/tools/scaffold.ts +0 -6708
- package/src/agent-tooling/mcp/tools/theme.ts +0 -456
- package/src/agent-tooling/mcp/tools/types.ts +0 -14
- package/src/agent-tooling/mcp/validate-args.ts +0 -141
- package/src/agent-tooling/recipes/composed-thread.ts +0 -714
- package/src/agent-tooling/recipes/index.ts +0 -22
- package/src/agent-tooling/recipes/types.ts +0 -32
- package/src/agent-tooling/registry.ts +0 -132
- package/src/agent-tooling/route-emit.ts +0 -305
- package/src/agent-tooling/types.ts +0 -390
- package/src/components/artifact-card.tsx +0 -120
- package/src/components/artifact.tsx +0 -914
- package/src/components/attachment-types.ts +0 -66
- package/src/components/attachments.tsx +0 -536
- package/src/components/audio-visualizer/audio-visualizer.voice-fixture.ts +0 -257
- package/src/components/audio-visualizer/aurora.glsl.ts +0 -330
- package/src/components/audio-visualizer/fit-scale.ts +0 -112
- package/src/components/audio-visualizer/index.tsx +0 -528
- package/src/components/audio-visualizer/labs/lab-choreography.ts +0 -187
- package/src/components/audio-visualizer/labs/lab-shaders.ts +0 -363
- package/src/components/audio-visualizer/labs/lab-visualizer.tsx +0 -102
- package/src/components/audio-visualizer/shader-canvas.tsx +0 -876
- package/src/components/audio-visualizer/sizes.ts +0 -54
- package/src/components/audio-visualizer/variant-aurora.tsx +0 -305
- package/src/components/audio-visualizer/variant-bar.tsx +0 -175
- package/src/components/audio-visualizer/variant-custom.tsx +0 -344
- package/src/components/audio-visualizer/variant-grid.tsx +0 -175
- package/src/components/audio-visualizer/variant-radial.tsx +0 -163
- package/src/components/audio-visualizer/variant-wave.tsx +0 -130
- package/src/components/audio-visualizer/wave.glsl.ts +0 -130
- package/src/components/card-fallback.tsx +0 -60
- package/src/components/card-renderer.tsx +0 -220
- package/src/components/card.tsx +0 -212
- package/src/components/chain-of-thought.tsx +0 -348
- package/src/components/chat-container.tsx +0 -89
- package/src/components/chat-scope-picker.tsx +0 -57
- package/src/components/chat-thread.tsx +0 -518
- package/src/components/checkpoint.tsx +0 -88
- package/src/components/choice-card.tsx +0 -743
- package/src/components/coachmark.tsx +0 -249
- package/src/components/code-block.tsx +0 -181
- package/src/components/composer-dom.ts +0 -159
- package/src/components/composer-highlight.ts +0 -242
- package/src/components/composer-history.ts +0 -82
- package/src/components/composer.tsx +0 -1075
- package/src/components/confirm-card.tsx +0 -402
- package/src/components/context.tsx +0 -377
- package/src/components/conversation-item.tsx +0 -218
- package/src/components/conversation-list.tsx +0 -429
- package/src/components/dismissed-stub.tsx +0 -80
- package/src/components/embed.tsx +0 -200
- package/src/components/empty.tsx +0 -177
- package/src/components/feedback-bar.tsx +0 -166
- package/src/components/file-tree.tsx +0 -530
- package/src/components/file-upload.tsx +0 -167
- package/src/components/form-widgets.tsx +0 -525
- package/src/components/form.tsx +0 -1296
- package/src/components/image.tsx +0 -65
- package/src/components/link-preview.tsx +0 -195
- package/src/components/loader.tsx +0 -367
- package/src/components/markdown.tsx +0 -162
- package/src/components/message-skills.tsx +0 -40
- package/src/components/message.tsx +0 -765
- package/src/components/model-switcher.tsx +0 -132
- package/src/components/prompt-input.tsx +0 -188
- package/src/components/prompt-suggestion.tsx +0 -150
- package/src/components/reasoning.tsx +0 -293
- package/src/components/response-compare-types.ts +0 -152
- package/src/components/response-compare.tsx +0 -455
- package/src/components/response-stream.tsx +0 -109
- package/src/components/screen.tsx +0 -181
- package/src/components/scroll-button.tsx +0 -93
- package/src/components/source.tsx +0 -192
- package/src/components/tasks-card.tsx +0 -801
- package/src/components/text-shimmer.tsx +0 -37
- package/src/components/thinking-bar.tsx +0 -50
- package/src/components/thread.tsx +0 -228
- package/src/components/toast.tsx +0 -503
- package/src/components/tool-classify.ts +0 -26
- package/src/components/tool-types.ts +0 -49
- package/src/components/tool.tsx +0 -190
- package/src/components/use-card-resolution.ts +0 -44
- package/src/components/voice-input.tsx +0 -222
- package/src/components/voice-output.tsx +0 -242
- package/src/components/workspace-shell.tsx +0 -285
- package/src/diagnostics/hook.ts +0 -352
- package/src/diagnostics/index.ts +0 -82
- package/src/diagnostics/report-request.ts +0 -296
- package/src/elements/agent-card.tsx +0 -67
- package/src/elements/artifact.tsx +0 -194
- package/src/elements/attachments.tsx +0 -140
- package/src/elements/audio-visualizer.tsx +0 -227
- package/src/elements/autoloader.ts +0 -89
- package/src/elements/avatar.tsx +0 -33
- package/src/elements/badge.tsx +0 -32
- package/src/elements/button.tsx +0 -149
- package/src/elements/card.tsx +0 -133
- package/src/elements/cards.tsx +0 -266
- package/src/elements/chain-of-thought.tsx +0 -141
- package/src/elements/chat-scope-picker.tsx +0 -65
- package/src/elements/chat-types.ts +0 -102
- package/src/elements/chat-workspace.tsx +0 -188
- package/src/elements/chat.tsx +0 -212
- package/src/elements/checkbox-group.tsx +0 -164
- package/src/elements/checkbox.tsx +0 -134
- package/src/elements/checkpoint.tsx +0 -47
- package/src/elements/choice.tsx +0 -100
- package/src/elements/coachmark.tsx +0 -90
- package/src/elements/code-block.tsx +0 -60
- package/src/elements/command.tsx +0 -197
- package/src/elements/compare.tsx +0 -111
- package/src/elements/compiled.css +0 -2
- package/src/elements/composer.tsx +0 -162
- package/src/elements/confirm-card.tsx +0 -76
- package/src/elements/context-meter.tsx +0 -107
- package/src/elements/conversation-item.tsx +0 -120
- package/src/elements/conversation-list.tsx +0 -203
- package/src/elements/css.ts +0 -5
- package/src/elements/default-input.tsx +0 -392
- package/src/elements/define-entry.ts +0 -12
- package/src/elements/define.tsx +0 -563
- package/src/elements/diagnostic-events.ts +0 -114
- package/src/elements/dialog.tsx +0 -145
- package/src/elements/disclosure.ts +0 -95
- package/src/elements/dock.tsx +0 -215
- package/src/elements/dropdown.tsx +0 -123
- package/src/elements/editable-label.tsx +0 -140
- package/src/elements/element-data-types.ts +0 -152
- package/src/elements/element-diagnostics.ts +0 -392
- package/src/elements/element-manifest.json +0 -354
- package/src/elements/element-nonscalar.json +0 -185
- package/src/elements/element-types.d.ts +0 -4337
- package/src/elements/embed.tsx +0 -35
- package/src/elements/empty.tsx +0 -29
- package/src/elements/feedback-bar.tsx +0 -66
- package/src/elements/file-tree.tsx +0 -62
- package/src/elements/file-upload.tsx +0 -44
- package/src/elements/form.tsx +0 -94
- package/src/elements/hover-card.tsx +0 -80
- package/src/elements/icon.tsx +0 -41
- package/src/elements/image.tsx +0 -32
- package/src/elements/input.tsx +0 -492
- package/src/elements/kbd.tsx +0 -45
- package/src/elements/link-preview.tsx +0 -34
- package/src/elements/loader.tsx +0 -25
- package/src/elements/markdown.tsx +0 -38
- package/src/elements/menu.tsx +0 -241
- package/src/elements/message-skills.tsx +0 -83
- package/src/elements/message.tsx +0 -361
- package/src/elements/model-switcher.tsx +0 -121
- package/src/elements/nav.tsx +0 -87
- package/src/elements/notice.tsx +0 -53
- package/src/elements/pane-grid.tsx +0 -111
- package/src/elements/pane-group.tsx +0 -119
- package/src/elements/pane.tsx +0 -129
- package/src/elements/popover.tsx +0 -81
- package/src/elements/progress-bar.tsx +0 -39
- package/src/elements/prompt-dock.tsx +0 -82
- package/src/elements/prompt-input.tsx +0 -240
- package/src/elements/prompt-suggestions.tsx +0 -113
- package/src/elements/radio-group.tsx +0 -129
- package/src/elements/reasoning.tsx +0 -71
- package/src/elements/register-impl.ts +0 -148
- package/src/elements/register.ts +0 -76
- package/src/elements/remote.tsx +0 -225
- package/src/elements/resizable.globals.d.ts +0 -36
- package/src/elements/resizable.tsx +0 -704
- package/src/elements/response-stream.tsx +0 -40
- package/src/elements/screen.tsx +0 -90
- package/src/elements/scroll-area.tsx +0 -33
- package/src/elements/scroll-button.tsx +0 -179
- package/src/elements/search.tsx +0 -185
- package/src/elements/segmented.tsx +0 -129
- package/src/elements/select.tsx +0 -165
- package/src/elements/separator.tsx +0 -36
- package/src/elements/setting-item.tsx +0 -50
- package/src/elements/settings-group.tsx +0 -37
- package/src/elements/skeleton.tsx +0 -45
- package/src/elements/slider.tsx +0 -171
- package/src/elements/slot-text.ts +0 -73
- package/src/elements/slots.ts +0 -787
- package/src/elements/source.tsx +0 -126
- package/src/elements/status.tsx +0 -42
- package/src/elements/styles.css +0 -328
- package/src/elements/switch.tsx +0 -118
- package/src/elements/tabs.tsx +0 -95
- package/src/elements/tasks.tsx +0 -103
- package/src/elements/text-shimmer.tsx +0 -28
- package/src/elements/thinking-bar.tsx +0 -43
- package/src/elements/thread.tsx +0 -139
- package/src/elements/toast.tsx +0 -106
- package/src/elements/tool.tsx +0 -78
- package/src/elements/tooltip.tsx +0 -85
- package/src/elements/validate-messages.ts +0 -76
- package/src/elements/voice-input.tsx +0 -100
- package/src/elements/voice-output.tsx +0 -82
- package/src/index.ts +0 -428
- package/src/primitives/audio-bands.ts +0 -174
- package/src/primitives/card-component-types.ts +0 -63
- package/src/primitives/card-contract.ts +0 -80
- package/src/primitives/card-data-types.ts +0 -361
- package/src/primitives/card-host.tsx +0 -37
- package/src/primitives/card-recovery.ts +0 -160
- package/src/primitives/card-registry.tsx +0 -78
- package/src/primitives/card-resolution.ts +0 -36
- package/src/primitives/card-routing.ts +0 -85
- package/src/primitives/card-schemas/artifact.schema.json +0 -92
- package/src/primitives/card-schemas/card-envelope.schema.json +0 -14
- package/src/primitives/card-schemas/card-event.schema.json +0 -12
- package/src/primitives/card-schemas/choice.schema.json +0 -75
- package/src/primitives/card-schemas/confirm.schema.json +0 -65
- package/src/primitives/card-schemas/embed.schema.json +0 -63
- package/src/primitives/card-schemas/form.result.schema.json +0 -7
- package/src/primitives/card-schemas/form.schema.json +0 -53
- package/src/primitives/card-schemas/link.schema.json +0 -54
- package/src/primitives/card-schemas/tasks.result.schema.json +0 -16
- package/src/primitives/card-schemas/tasks.schema.json +0 -83
- package/src/primitives/card-tags.ts +0 -61
- package/src/primitives/card-validate-cards.ts +0 -255
- package/src/primitives/card-validate-schemas.ts +0 -58
- package/src/primitives/card-validate.ts +0 -131
- package/src/primitives/chat-config.tsx +0 -103
- package/src/primitives/composer-model.ts +0 -49
- package/src/primitives/composer-triggers.ts +0 -35
- package/src/primitives/controllable.ts +0 -21
- package/src/primitives/create-kai-chat.ts +0 -66
- package/src/primitives/create-tween.ts +0 -266
- package/src/primitives/embed-providers.ts +0 -254
- package/src/primitives/field-mask.ts +0 -256
- package/src/primitives/field-semantics.ts +0 -115
- package/src/primitives/highlighter.ts +0 -157
- package/src/primitives/input-mask.ts +0 -853
- package/src/primitives/link-preview.ts +0 -87
- package/src/primitives/message-feedback.ts +0 -124
- package/src/primitives/pdf-preview.ts +0 -121
- package/src/primitives/toast-store.ts +0 -338
- package/src/primitives/url-scheme-policy.ts +0 -70
- package/src/primitives/use-audio-analysis.ts +0 -340
- package/src/primitives/use-auto-resize.ts +0 -31
- package/src/primitives/use-resize-observer.ts +0 -45
- package/src/primitives/use-sequencer.ts +0 -72
- package/src/primitives/use-speech-recognition.ts +0 -146
- package/src/primitives/use-stick-to-bottom.ts +0 -75
- package/src/primitives/use-text-stream.ts +0 -143
- package/src/primitives/use-voice-recorder.ts +0 -62
- package/src/primitives/visualizer-sequences.ts +0 -350
- package/src/remote/host-embed.ts +0 -345
- package/src/remote/index.ts +0 -2
- package/src/remote/origin.ts +0 -30
- package/src/remote/provider-runtime.ts +0 -262
- package/src/remote/provider.ts +0 -2
- package/src/remote/validate.ts +0 -22
- package/src/remote/version.ts +0 -12
- package/src/remote/wire.ts +0 -48
- package/src/schemas/from-tool-call.ts +0 -151
- package/src/schemas/index.ts +0 -341
- package/src/schemas/provider-subsets.ts +0 -538
- package/src/schemas/registry.ts +0 -355
- package/src/schemas/tool-defs.ts +0 -793
- package/src/solid.ts +0 -165
- package/src/state/index.ts +0 -44
- package/src/state/messages.ts +0 -53
- package/src/state/mock.ts +0 -297
- package/src/state/parts.ts +0 -295
- package/src/state/persistence.ts +0 -180
- package/src/state/stream.ts +0 -246
- package/src/state/suggestions.ts +0 -9
- package/src/state/threads.ts +0 -142
- package/src/test-utils/fake-clock.ts +0 -88
- package/src/types.ts +0 -53
- package/src/ui/action-icons.ts +0 -53
- package/src/ui/agent-card.tsx +0 -218
- package/src/ui/avatar.tsx +0 -23
- package/src/ui/badge.tsx +0 -21
- package/src/ui/button.tsx +0 -49
- package/src/ui/card.tsx +0 -245
- package/src/ui/checkbox-group.tsx +0 -153
- package/src/ui/checkbox.tsx +0 -63
- package/src/ui/collapsible.tsx +0 -163
- package/src/ui/command.tsx +0 -103
- package/src/ui/dialog.tsx +0 -223
- package/src/ui/dock.tsx +0 -584
- package/src/ui/dropdown.tsx +0 -636
- package/src/ui/editable-label.tsx +0 -112
- package/src/ui/hover-card.tsx +0 -345
- package/src/ui/icon.tsx +0 -167
- package/src/ui/input.tsx +0 -391
- package/src/ui/kbd.tsx +0 -118
- package/src/ui/nav.tsx +0 -282
- package/src/ui/notice.tsx +0 -84
- package/src/ui/overlay.tsx +0 -277
- package/src/ui/pane-grid.tsx +0 -117
- package/src/ui/pane-group.tsx +0 -291
- package/src/ui/pane.tsx +0 -193
- package/src/ui/popover.tsx +0 -106
- package/src/ui/progress-bar.tsx +0 -83
- package/src/ui/prompt-dock.tsx +0 -145
- package/src/ui/radio.tsx +0 -150
- package/src/ui/resizable.tsx +0 -693
- package/src/ui/scroll-area.tsx +0 -26
- package/src/ui/segmented.tsx +0 -109
- package/src/ui/select.tsx +0 -168
- package/src/ui/separator.tsx +0 -10
- package/src/ui/settings-group.tsx +0 -67
- package/src/ui/skeleton.tsx +0 -73
- package/src/ui/slider.tsx +0 -178
- package/src/ui/status.tsx +0 -48
- package/src/ui/switch.tsx +0 -119
- package/src/ui/tabs.tsx +0 -168
- package/src/ui/textarea.tsx +0 -21
- package/src/ui/tooltip.tsx +0 -118
- package/src/utils/cn.ts +0 -30
- package/src/wire/chunk.ts +0 -248
- package/src/wire/consume.ts +0 -599
- package/src/wire/diagnostics.ts +0 -727
- package/src/wire/encode-probe.ts +0 -214
- package/src/wire/encode.ts +0 -947
- package/src/wire/files.ts +0 -342
- package/src/wire/formats/anthropic.ts +0 -274
- package/src/wire/formats/openai.ts +0 -228
- package/src/wire/index.ts +0 -95
- package/src/wire/media-types.ts +0 -344
- package/src/wire/read.ts +0 -396
- package/src/wire/sink-helpers.ts +0 -50
- package/src/wire/sse.ts +0 -153
|
@@ -1,518 +0,0 @@
|
|
|
1
|
-
import { createSignal, createEffect, createMemo, For, Show, onMount } from 'solid-js';
|
|
2
|
-
import { ChatConfig, useChatConfig } from '../primitives/chat-config';
|
|
3
|
-
import { type ComposerDoc, normalizeValue, serializeToText } from '../primitives/composer-model';
|
|
4
|
-
import { ChatContainer, ChatContainerContent, ChatContainerScrollAnchor } from './chat-container';
|
|
5
|
-
import { Message, MessageAvatar, MessageBody } from './message';
|
|
6
|
-
import { type AttachmentData } from './attachments';
|
|
7
|
-
import { createMessageFeedback, type MessageActionDetail } from '../primitives/message-feedback';
|
|
8
|
-
import { ModelSwitcher } from './model-switcher';
|
|
9
|
-
import { ScrollButton } from './scroll-button';
|
|
10
|
-
import {
|
|
11
|
-
Context, ContextTrigger, ContextContent, ContextContentHeader,
|
|
12
|
-
ContextContentBody, ContextContentFooter, ContextInputUsage, ContextOutputUsage,
|
|
13
|
-
} from './context';
|
|
14
|
-
import { DefaultPromptInput, type RejectedAttachment } from '../elements/default-input';
|
|
15
|
-
import type { MediaTypeFilter } from '../wire/media-types';
|
|
16
|
-
import type { TriggerDef } from './composer';
|
|
17
|
-
import type { ChatMessage } from '../elements/chat-types';
|
|
18
|
-
import type { ProseSize } from '../primitives/chat-config';
|
|
19
|
-
import type { ModelOption } from '../types';
|
|
20
|
-
import type { CardComponentMap } from '../primitives/card-registry';
|
|
21
|
-
import type { CardSchemaMap } from './card-renderer';
|
|
22
|
-
import type { JSX } from 'solid-js';
|
|
23
|
-
|
|
24
|
-
export interface ChatThreadContextUsage {
|
|
25
|
-
usedTokens: number;
|
|
26
|
-
maxTokens: number;
|
|
27
|
-
inputTokens?: number;
|
|
28
|
-
outputTokens?: number;
|
|
29
|
-
estimatedCost?: number;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface ChatThreadProps {
|
|
33
|
-
/** Extra classes for the thread root (e.g. `h-full`). */
|
|
34
|
-
class?: string;
|
|
35
|
-
/** The full message thread to render, newest last. Each entry carries its role,
|
|
36
|
-
* ordered `parts`, and optional actions/avatar/feedback. Set as a JS property
|
|
37
|
-
* (`el.messages = [...]`). */
|
|
38
|
-
messages: ChatMessage[];
|
|
39
|
-
/** Add/override card type -> component entries, forwarded to `CardRenderer`
|
|
40
|
-
* for `card` parts. */
|
|
41
|
-
cardTypes?: CardComponentMap;
|
|
42
|
-
/** JSON Schemas for the card types this app renders, keyed by envelope type,
|
|
43
|
-
* forwarded to `CardRenderer` for `card` parts. The companion of `cardTypes`:
|
|
44
|
-
* that says what DRAWS a card, this says what a VALID one looks like.
|
|
45
|
-
* `createCardRegistry(...).validationSchemas` is exactly this shape. Without it
|
|
46
|
-
* the kit checks its own seven built-ins and leaves your own card type
|
|
47
|
-
* unvalidated. A schema here WINS over a built-in of the same name. */
|
|
48
|
-
cardSchemas?: CardSchemaMap;
|
|
49
|
-
/** The custom-element host node to emit card events off when no `CardProvider`
|
|
50
|
-
* is present, forwarded through `MessageBody` to `CardRenderer`. The
|
|
51
|
-
* element facades pass their own host element so card events leave as the
|
|
52
|
-
* bubbling `kai-card` CustomEvent. */
|
|
53
|
-
cardHostElement?: HTMLElement;
|
|
54
|
-
/** Value of the input. A **string** is controlled (the host owns the text and
|
|
55
|
-
* updates it on `kai-value-change`). A **ComposerDoc** is a one-time seed that
|
|
56
|
-
* pre-populates pills; the user then edits freely. Leave unset for uncontrolled. */
|
|
57
|
-
value?: string | ComposerDoc;
|
|
58
|
-
/** Placeholder text shown in the empty input. */
|
|
59
|
-
placeholder?: string;
|
|
60
|
-
/** When true, shows the loading/streaming state and disables submit (use while
|
|
61
|
-
* awaiting the assistant's reply). */
|
|
62
|
-
loading?: boolean;
|
|
63
|
-
/** Starter prompts shown above the input when the thread is empty. Clicking one
|
|
64
|
-
* follows `suggestionMode`. Set as a JS property. */
|
|
65
|
-
suggestions?: string[];
|
|
66
|
-
/** What clicking a suggestion does: `'submit'` (default) sends it immediately
|
|
67
|
-
* as if typed and submitted; `'fill'` just places it in the input. */
|
|
68
|
-
suggestionMode?: 'submit' | 'fill';
|
|
69
|
-
/** Keep suggestions visible after the conversation starts. By default
|
|
70
|
-
* suggestions are conversation starters and hide once `messages` is
|
|
71
|
-
* non-empty; set this to keep them always shown. Default false. */
|
|
72
|
-
persistSuggestions?: boolean;
|
|
73
|
-
/** Body/prose font scale for rendered markdown (`'xs' | 'sm' | 'base' | 'lg'`).
|
|
74
|
-
* Defaults to `'sm'`. */
|
|
75
|
-
proseSize?: ProseSize;
|
|
76
|
-
/** Shiki theme name for syntax-highlighted code blocks (e.g.
|
|
77
|
-
* `'github-dark-dimmed'`). */
|
|
78
|
-
codeTheme?: string;
|
|
79
|
-
/** Enable Shiki syntax highlighting in code blocks. Turn off to render plain
|
|
80
|
-
* `<pre>` blocks (lighter, no highlighter load). Default true. */
|
|
81
|
-
codeHighlight?: boolean;
|
|
82
|
-
/** How `reasoning` parts render across the thread. `'full'` (default) is the
|
|
83
|
-
* current collapsible-disclosure behavior; `'compact'` shows only a shimmer
|
|
84
|
-
* loader while a reasoning part streams and nothing once it settles (no
|
|
85
|
-
* expandable detail); `'off'` renders reasoning parts not at all. Forwarded
|
|
86
|
-
* to every `MessageBody` as `reasoningMode`. */
|
|
87
|
-
reasoning?: 'full' | 'compact' | 'off';
|
|
88
|
-
/** Seeds the reasoning disclosure open AND keeps it tracking the stream
|
|
89
|
-
* (open while streaming, closes when it settles): the pre-Task-19f `full`
|
|
90
|
-
* behavior. Default false/absent: the panel starts closed (just the
|
|
91
|
-
* "Thinking" shimmer chip) and only opens on click, the current default
|
|
92
|
-
* (owner ruling, 2026-08-26). Meaningless when `reasoning` is `'compact'`
|
|
93
|
-
* or `'off'`. Forwarded to every `MessageBody` as `reasoningDefaultOpen`. */
|
|
94
|
-
reasoningOpen?: boolean;
|
|
95
|
-
/** Optional header title shown on the left of the header. */
|
|
96
|
-
chatTitle?: string;
|
|
97
|
-
/** Optional model list. When set (>1 model) a ModelSwitcher is shown in the
|
|
98
|
-
* header and a `kai-model-change` event fires on selection. */
|
|
99
|
-
models?: ModelOption[];
|
|
100
|
-
/** The currently selected model id (pairs with `models`). */
|
|
101
|
-
currentModel?: string;
|
|
102
|
-
/** Optional context-window token usage. When set, a Context token meter is
|
|
103
|
-
* shown in the header. */
|
|
104
|
-
context?: ChatThreadContextUsage;
|
|
105
|
-
/** Show the scroll-to-bottom button inside the scroll area. Default true. */
|
|
106
|
-
scrollButton?: boolean;
|
|
107
|
-
/** Whether the host has `slot="header-start"` content (left of the title). Set
|
|
108
|
-
* by the `<kai-chat>` facade so a custom control forces the header open. */
|
|
109
|
-
headerStart?: boolean;
|
|
110
|
-
/** Whether the host has `slot="header-end"` content (right of the controls). */
|
|
111
|
-
headerEnd?: boolean;
|
|
112
|
-
/** Extra content rendered in the header-end region, AFTER `slot="header-end"`.
|
|
113
|
-
* This is a JSX escape hatch for a caller composing `ChatThread` directly as a
|
|
114
|
-
* Solid component (no shadow-DOM host, so there is no light-DOM node to slot) —
|
|
115
|
-
* the `kai-dock`-docked construct widget is the motivating case: it needs its
|
|
116
|
-
* own close affordance to sit IN the header row, sharing it with the title
|
|
117
|
-
* instead of floating as a second control with no visible relationship to the
|
|
118
|
-
* chat surface. Renders alongside the named slot rather than replacing it, so a
|
|
119
|
-
* real `slot="header-end"` consumer and this prop can both be present. Counts
|
|
120
|
-
* toward `showHeader()` the same as `headerEnd`, so a construct with no title
|
|
121
|
-
* and only this content still gets a header row to sit in. */
|
|
122
|
-
headerEndContent?: JSX.Element;
|
|
123
|
-
// ── Composition slots ─────────────────────────────────────────────────────
|
|
124
|
-
// Each flag below is set by the `<kai-chat>` facade when matching light-DOM
|
|
125
|
-
// `slot="…"` content is projected, and gates one composition slot. Two kinds:
|
|
126
|
-
// • INJECT — additive: project YOUR markup into a region (sidebar, footer,
|
|
127
|
-
// composer-actions, header-start/-end).
|
|
128
|
-
// • REPLACE — substitutive: your markup stands in for a whole region
|
|
129
|
-
// (header, empty, composer). A replaced region's projected
|
|
130
|
-
// content owns its own data/events — a slotted (light-DOM) node
|
|
131
|
-
// can't read this component's reactive state. That boundary is
|
|
132
|
-
// the whole reason `messages` stays a data prop, not a slot.
|
|
133
|
-
/** REPLACE: full custom header in place of the built-in title/model/context bar. */
|
|
134
|
-
headerFull?: boolean;
|
|
135
|
-
/** INJECT: left sidebar column (e.g. a conversation list / your own nav). */
|
|
136
|
-
sidebar?: boolean;
|
|
137
|
-
/** 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). */
|
|
138
|
-
empty?: boolean;
|
|
139
|
-
/** REPLACE, JSX form: the empty-state content itself, for a caller composing
|
|
140
|
-
* `ChatThread` directly as a Solid component rather than through the `<kai-chat>`
|
|
141
|
-
* shadow-DOM boundary that `empty`/`slot="empty"` targets. Renders INSIDE this
|
|
142
|
-
* component's own tree — so a caller passing the kit's own `<Empty>` composition
|
|
143
|
-
* (`components/empty.tsx`) gets it fully styled by the adopted stylesheet, unlike
|
|
144
|
-
* `slot="empty"`: that slot only ever receives LIGHT-DOM children of the shadow
|
|
145
|
-
* HOST, and light-DOM nodes are outside the shadow root's adopted stylesheets, so
|
|
146
|
-
* Tailwind-utility-class content projected there renders bare. Takes priority
|
|
147
|
-
* over `empty`/`slot="empty"` when both are set — the two are alternate delivery
|
|
148
|
-
* mechanisms for the same region, not additive like `headerEndContent`. */
|
|
149
|
-
emptyContent?: JSX.Element;
|
|
150
|
-
/** REPLACE: full custom composer in place of the built-in prompt input. The
|
|
151
|
-
* projected content wires its own submit (the data-flow boundary). */
|
|
152
|
-
composer?: boolean;
|
|
153
|
-
/** INJECT: accessory row just above the composer (e.g. extra actions). */
|
|
154
|
-
composerActions?: boolean;
|
|
155
|
-
/** INJECT: footer row below the composer (disclaimers, token meter, …). */
|
|
156
|
-
footer?: boolean;
|
|
157
|
-
/** Which attachment media types the user may stage, in HTML `accept` syntax
|
|
158
|
-
* (`'image/*,application/pdf'`). Omitted means no filter. Narrowed by what the
|
|
159
|
-
* encoders can actually send — the same string, and the same resolver, as
|
|
160
|
-
* `toOpenAIMessages(msgs, { accept })`. */
|
|
161
|
-
accept?: MediaTypeFilter;
|
|
162
|
-
/** Files the composer refused because `accept` excluded them. */
|
|
163
|
-
onAttachmentsRejected?: (rejected: RejectedAttachment[]) => void;
|
|
164
|
-
/** When `false`, hides the built-in paperclip attach button. Defaults to
|
|
165
|
-
* `true` (undeclared keeps today's behavior: attach visible), matching
|
|
166
|
-
* `DefaultPromptInput`'s own default: only an explicit `false` hides it. */
|
|
167
|
-
attach?: boolean;
|
|
168
|
-
/** Show a web-search (Globe) button in the input toolbar; calls `onWebSearch`. */
|
|
169
|
-
webSearch?: boolean;
|
|
170
|
-
/** Show a Voice (Mic) button in the input toolbar; fires a `voice` event. */
|
|
171
|
-
voice?: boolean;
|
|
172
|
-
/** Rich entity triggers. Each `{ char, kind, items }` opens a caret-anchored
|
|
173
|
-
* menu that inserts an atomic pill (`/` skills, `@` agents/plugins). Set as a
|
|
174
|
-
* JS property; forwarded to the input. */
|
|
175
|
-
triggers?: TriggerDef[];
|
|
176
|
-
/** Default icon per entity kind (kind → image src) for pills/menu items. */
|
|
177
|
-
kindIcons?: Record<string, string>;
|
|
178
|
-
/** Whether each message's action bar is always visible (`'always'`, default)
|
|
179
|
-
* or only revealed on hover of that message row (`'hover'`). */
|
|
180
|
-
actionsReveal?: 'always' | 'hover';
|
|
181
|
-
// callbacks (the facade maps these to dispatch())
|
|
182
|
-
onValueChange?: (value: string) => void;
|
|
183
|
-
onSubmit?: (detail: { value: string; attachments: AttachmentData[] }) => void;
|
|
184
|
-
onAttachmentsChange?: (attachments: AttachmentData[]) => void;
|
|
185
|
-
onSuggestionClick?: (value: string) => void;
|
|
186
|
-
onModelChange?: (modelId: string) => void;
|
|
187
|
-
onMessageAction?: (detail: MessageActionDetail) => void;
|
|
188
|
-
onWebSearch?: () => void;
|
|
189
|
-
onVoice?: () => void;
|
|
190
|
-
/** Receive the imperative controller once mounted. The kai-chat facade forwards
|
|
191
|
-
* these as element methods (focus/clear/send/scrollToBottom). */
|
|
192
|
-
controllerRef?: (controller: ChatThreadController) => void;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/** Imperative handle exposed via `controllerRef` — the input half of the chat's
|
|
196
|
-
* interaction surface, forwarded onto `<kai-chat>` as instance methods. */
|
|
197
|
-
export interface ChatThreadController {
|
|
198
|
-
focus(options?: FocusOptions): void;
|
|
199
|
-
clear(): void;
|
|
200
|
-
send(): void;
|
|
201
|
-
scrollToBottom(behavior?: ScrollBehavior): void;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* THE MESSAGE LIST'S KEY, and the reason it is not the message object. This is
|
|
206
|
-
* the canonical note; `thread.tsx` keys its identical list the same way and
|
|
207
|
-
* points here.
|
|
208
|
-
*
|
|
209
|
-
* `<For>` is REFERENCE-keyed, and a streaming assistant message gets a brand
|
|
210
|
-
* new object identity on every delta — `createAssistantStream` rebuilds it as
|
|
211
|
-
* `{ ...prev[i], parts: next }` because a new reference IS the re-render
|
|
212
|
-
* signal. Keyed on the objects, every chunk therefore looks like an entirely
|
|
213
|
-
* new list: the whole message row is torn down and rebuilt, and everything the
|
|
214
|
-
* user did inside it dies with it. Expanding a tool or reasoning panel
|
|
215
|
-
* mid-stream did nothing at all — the disclosure opened and was discarded
|
|
216
|
-
* microseconds later by the next token. (`MessageBody` keys its PARTS by
|
|
217
|
-
* position for exactly this reason; that fix was dead while its parent kept
|
|
218
|
-
* destroying the subtree above it.)
|
|
219
|
-
*
|
|
220
|
-
* So key on `message.id`, which is stable across the object churn: `<For>` over
|
|
221
|
-
* the id array diffs by string value, a delta produces an identical id list,
|
|
222
|
-
* and no row moves. The row then reads its message through `messages[i()]` —
|
|
223
|
-
* `<For>`'s index accessor, which it keeps current across inserts, removals and
|
|
224
|
-
* moves — so the CONTENT keeps updating through accessors while the DOM stays
|
|
225
|
-
* put.
|
|
226
|
-
*
|
|
227
|
-
* WHY NOT `<Index>`, the other way to survive the churn: `<Index>` keys by
|
|
228
|
-
* POSITION, so a row's local state (an open panel, a half-filled form card)
|
|
229
|
-
* belongs to the slot rather than to the message. Appends and tail truncations
|
|
230
|
-
* (regenerate/edit) are fine, but prepending older turns — load-earlier-history,
|
|
231
|
-
* which every real chat grows — shifts every row, and each open disclosure
|
|
232
|
-
* stays behind with the wrong message. Position IS a valid key inside a
|
|
233
|
-
* message, where the folds only ever append or patch a part in place; it is not
|
|
234
|
-
* one for the message list, where the host owns the array and splices it.
|
|
235
|
-
* Both approaches require the row to read through accessors — that is inherent
|
|
236
|
-
* in keeping a row mounted while its object is replaced, not a cost unique to
|
|
237
|
-
* either.
|
|
238
|
-
*
|
|
239
|
-
* Contract: `id` must be unique per message. It already had to be — the
|
|
240
|
-
* feedback/copy state above this list is keyed by it.
|
|
241
|
-
*/
|
|
242
|
-
/** How an ASSISTANT row aligns its parts across the column (K-D11).
|
|
243
|
-
*
|
|
244
|
-
* `stretch`, not `start`. An assistant turn is a `flex flex-col` box, so under
|
|
245
|
-
* `items-start` every part is a flex item with a fit-content cross size —
|
|
246
|
-
* `min(max-content, column)`. Prose is wider than the column so a text bubble
|
|
247
|
-
* looked right, and a generative-UI card was as wide as its widest button: the
|
|
248
|
-
* ops-console parameters form measured 285px inside a 768px column while the
|
|
249
|
-
* approval card beside it filled all 768. A card in a chat thread filling its
|
|
250
|
-
* column is a fact about the medium, and no consumer can reach it — the card
|
|
251
|
-
* element is created inside `<kai-chat>`'s shadow root.
|
|
252
|
-
*
|
|
253
|
-
* Stretch rather than `w-full` on the cards, for two reasons: it is one lever
|
|
254
|
-
* instead of one per card surface (the Solid `Card` root AND every `kai-*`
|
|
255
|
-
* card host, whose shadow wrapper is `display: contents`), and stretching only
|
|
256
|
-
* applies where the cross size is `auto`, so a part that states its own width
|
|
257
|
-
* is untouched — `Attachments variant="grid"` stays `w-fit`. `Tool` and
|
|
258
|
-
* `Reasoning` already asked for `w-full` explicitly; this is the same
|
|
259
|
-
* intention, applied once.
|
|
260
|
-
*
|
|
261
|
-
* USER rows keep `items-end`: their bubble is `max-w-[85%]` and right aligned,
|
|
262
|
-
* and stretching it would break both.
|
|
263
|
-
*/
|
|
264
|
-
const ASSISTANT_ALIGN = 'items-stretch';
|
|
265
|
-
|
|
266
|
-
export function ChatThread(props: ChatThreadProps) {
|
|
267
|
-
const outer = useChatConfig();
|
|
268
|
-
const reveal = () => (props.actionsReveal === 'hover' ? 'hover' : 'always');
|
|
269
|
-
const messageKeys = createMemo(() => props.messages.map((m) => m.id));
|
|
270
|
-
// Feedback (copy + vote) state lives ABOVE the per-message <For>, so streaming
|
|
271
|
-
// re-renders (a fresh `messages` array ref per chunk) don't wipe it.
|
|
272
|
-
// The copy/feedback toasts scope to the chat (this thread's root) so they appear
|
|
273
|
-
// in-chat rather than at the page top.
|
|
274
|
-
let rootEl: HTMLElement | undefined;
|
|
275
|
-
const feedback = createMessageFeedback({
|
|
276
|
-
emit: (detail) => props.onMessageAction?.(detail),
|
|
277
|
-
target: () => rootEl,
|
|
278
|
-
});
|
|
279
|
-
const [internal, setInternal] = createSignal<string | ComposerDoc>(props.value ?? '');
|
|
280
|
-
const [attachments, setAttachments] = createSignal<AttachmentData[]>([]);
|
|
281
|
-
// A string `value` is controlled; a ComposerDoc `value` is a one-time seed that
|
|
282
|
-
// lives in `internal` so the user's (string) edits replace it without a fight.
|
|
283
|
-
const current = (): string | ComposerDoc =>
|
|
284
|
-
typeof props.value === 'string' ? props.value : internal();
|
|
285
|
-
createEffect(() => {
|
|
286
|
-
const v = props.value;
|
|
287
|
-
if (v != null && typeof v !== 'string') setInternal(v);
|
|
288
|
-
});
|
|
289
|
-
const handleChange = (v: string) => { setInternal(v); props.onValueChange?.(v); };
|
|
290
|
-
// After a send, reset the composer. Clear the internal draft ONLY when the value is
|
|
291
|
-
// uncontrolled (props.value === undefined) — a controlled host owns its own value and
|
|
292
|
-
// clears it itself. This lets the batteries-included hooks (useKaiChat/createKaiChat),
|
|
293
|
-
// whose `bind` does not control `value`, get a clean composer after each submit.
|
|
294
|
-
const afterSubmit = () => { setAttachments([]); if (props.value === undefined) setInternal(''); };
|
|
295
|
-
const handleSubmit = () => { props.onSubmit?.({ value: serializeToText(normalizeValue(current())), attachments: attachments() }); afterSubmit(); };
|
|
296
|
-
const handleSuggestionClick = (v: string) => {
|
|
297
|
-
if ((props.suggestionMode ?? 'submit') === 'fill') { handleChange(v); props.onSuggestionClick?.(v); }
|
|
298
|
-
else { props.onSubmit?.({ value: v, attachments: attachments() }); afterSubmit(); }
|
|
299
|
-
};
|
|
300
|
-
const showHeader = () => !!(props.chatTitle || props.models || props.context || props.headerStart || props.headerEnd || props.headerEndContent);
|
|
301
|
-
// Suggestions are conversation starters: show only on an empty thread unless
|
|
302
|
-
// the host opts into persisting them.
|
|
303
|
-
const visibleSuggestions = () =>
|
|
304
|
-
props.persistSuggestions || props.messages.length === 0 ? props.suggestions : undefined;
|
|
305
|
-
const showScrollButton = () => props.scrollButton !== false;
|
|
306
|
-
|
|
307
|
-
// Hand the imperative controller to the facade once mounted (rootEl is set).
|
|
308
|
-
onMount(() => {
|
|
309
|
-
props.controllerRef?.({
|
|
310
|
-
focus: (options) =>
|
|
311
|
-
rootEl
|
|
312
|
-
?.querySelector<HTMLElement>('[contenteditable]:not([contenteditable="false"]), textarea')
|
|
313
|
-
?.focus(options),
|
|
314
|
-
clear: () => { setInternal(''); setAttachments([]); props.onValueChange?.(''); },
|
|
315
|
-
send: () => handleSubmit(),
|
|
316
|
-
scrollToBottom: (behavior) => {
|
|
317
|
-
const vp = rootEl?.querySelector<HTMLElement>('.overflow-y-auto');
|
|
318
|
-
vp?.scrollTo({ top: vp.scrollHeight, behavior: behavior ?? 'smooth' });
|
|
319
|
-
},
|
|
320
|
-
});
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
return (
|
|
324
|
-
<ChatConfig proseSize={props.proseSize} codeTheme={props.codeTheme} codeHighlight={props.codeHighlight !== false} portalMount={outer.portalMount()}>
|
|
325
|
-
{/* The root is a ROW so a `sidebar` slot can sit beside the main column.
|
|
326
|
-
With no sidebar projected it collapses to the original column. */}
|
|
327
|
-
<div ref={(e) => (rootEl = e as HTMLElement)} class={`flex h-full bg-background ${props.class ?? ''}`}>
|
|
328
|
-
<Show when={props.sidebar}>
|
|
329
|
-
<aside part="sidebar" class="flex w-64 shrink-0 flex-col overflow-hidden border-r border-border">
|
|
330
|
-
<slot name="sidebar" />
|
|
331
|
-
</aside>
|
|
332
|
-
</Show>
|
|
333
|
-
<div class="flex h-full min-w-0 flex-1 flex-col">
|
|
334
|
-
{/* Header: a full `header` slot REPLACES the built-in bar; otherwise the
|
|
335
|
-
built-in header renders, itself carrying the header-start/header-end
|
|
336
|
-
INJECT slots. */}
|
|
337
|
-
<Show
|
|
338
|
-
when={props.headerFull}
|
|
339
|
-
fallback={
|
|
340
|
-
<Show when={showHeader()}>
|
|
341
|
-
<header part="header-bar" class="flex h-14 shrink-0 items-center justify-between border-b border-border px-5">
|
|
342
|
-
<div class="flex items-center gap-2">
|
|
343
|
-
{/* Consumer-injected leading controls (sidebar-toggle, compose, a
|
|
344
|
-
popover title-button). Projects light-DOM `slot="header-start"`
|
|
345
|
-
children of <kai-chat>; inert outside a shadow root. */}
|
|
346
|
-
<slot name="header-start" />
|
|
347
|
-
<Show when={props.chatTitle}>
|
|
348
|
-
<div class="text-sm font-semibold text-foreground">{props.chatTitle}</div>
|
|
349
|
-
</Show>
|
|
350
|
-
</div>
|
|
351
|
-
<div class="flex items-center gap-2">
|
|
352
|
-
<Show when={props.models}>
|
|
353
|
-
<ModelSwitcher
|
|
354
|
-
models={props.models!}
|
|
355
|
-
currentModelId={props.currentModel ?? props.models![0]?.id ?? ''}
|
|
356
|
-
onModelChange={(modelId) => props.onModelChange?.(modelId)}
|
|
357
|
-
/>
|
|
358
|
-
</Show>
|
|
359
|
-
<Show when={props.context}>
|
|
360
|
-
<Context
|
|
361
|
-
usedTokens={props.context!.usedTokens} maxTokens={props.context!.maxTokens}
|
|
362
|
-
inputTokens={props.context!.inputTokens} outputTokens={props.context!.outputTokens}
|
|
363
|
-
estimatedCost={props.context!.estimatedCost}
|
|
364
|
-
>
|
|
365
|
-
<ContextTrigger />
|
|
366
|
-
<ContextContent>
|
|
367
|
-
<ContextContentHeader />
|
|
368
|
-
<ContextContentBody><div class="space-y-1.5"><ContextInputUsage /><ContextOutputUsage /></div></ContextContentBody>
|
|
369
|
-
<ContextContentFooter />
|
|
370
|
-
</ContextContent>
|
|
371
|
-
</Context>
|
|
372
|
-
</Show>
|
|
373
|
-
{/* Consumer-injected trailing controls (share, settings, …).
|
|
374
|
-
Projects light-DOM `slot="header-end"` children of <kai-chat>. */}
|
|
375
|
-
<slot name="header-end" />
|
|
376
|
-
{/* JSX escape hatch for a Solid-composed caller with no shadow-DOM
|
|
377
|
-
host to slot into (see the prop doc) — a docked widget's own
|
|
378
|
-
close affordance is the motivating case, sharing this row with
|
|
379
|
-
the title instead of floating as an unrelated second control. */}
|
|
380
|
-
{props.headerEndContent}
|
|
381
|
-
</div>
|
|
382
|
-
</header>
|
|
383
|
-
</Show>
|
|
384
|
-
}
|
|
385
|
-
>
|
|
386
|
-
<header part="header" class="shrink-0"><slot name="header" /></header>
|
|
387
|
-
</Show>
|
|
388
|
-
<div class="relative flex-1 overflow-hidden">
|
|
389
|
-
<ChatContainer class="h-full px-4 py-3">
|
|
390
|
-
<ChatContainerContent class="mx-auto w-full max-w-3xl space-y-4">
|
|
391
|
-
{/* REPLACE — custom empty-state content, shown only while the thread is
|
|
392
|
-
empty. The component still owns WHEN it shows (data state); the
|
|
393
|
-
consumer owns WHAT it looks like. `emptyContent` (JSX, rendered
|
|
394
|
-
in-tree and fully styled) wins over `empty`/`slot="empty"`
|
|
395
|
-
(light-DOM projection) when both are set — see the prop doc. */}
|
|
396
|
-
<Show when={(props.empty || props.emptyContent) && props.messages.length === 0}>
|
|
397
|
-
<Show when={props.emptyContent} fallback={<slot name="empty" />}>
|
|
398
|
-
{props.emptyContent}
|
|
399
|
-
</Show>
|
|
400
|
-
</Show>
|
|
401
|
-
{/* Keyed by message id (see the note above this component), so a
|
|
402
|
-
streaming delta updates the row instead of replacing it. */}
|
|
403
|
-
<For each={messageKeys()}>
|
|
404
|
-
{(_id, i) => (
|
|
405
|
-
// The row reads its message through <For>'s index accessor,
|
|
406
|
-
// never through a captured value: the row outlives the delta
|
|
407
|
-
// that replaced its object, so every read below has to go
|
|
408
|
-
// through `m()` for the new content to land. <Show> supplies
|
|
409
|
-
// the non-null accessor and covers the frame where a removal
|
|
410
|
-
// has shortened the array.
|
|
411
|
-
<Show when={props.messages[i()]}>
|
|
412
|
-
{(m) => {
|
|
413
|
-
const body = (
|
|
414
|
-
<MessageBody
|
|
415
|
-
parts={m().parts}
|
|
416
|
-
/* F-21: streaming-ness = the thread's ONE existing
|
|
417
|
-
loading signal + being the last message and an
|
|
418
|
-
assistant turn. No second streaming source. The
|
|
419
|
-
reasoning disclosure no longer auto-opens on it
|
|
420
|
-
by default (Task 19f, owner ruling 2026-08-26) —
|
|
421
|
-
only the trigger's shimmer reflects streaming
|
|
422
|
-
unless `reasoningOpen` opts back in. */
|
|
423
|
-
isStreaming={props.loading === true && m().role === 'assistant' && i() === props.messages.length - 1}
|
|
424
|
-
reasoningMode={props.reasoning}
|
|
425
|
-
reasoningDefaultOpen={props.reasoningOpen}
|
|
426
|
-
cardTypes={props.cardTypes}
|
|
427
|
-
cardSchemas={props.cardSchemas}
|
|
428
|
-
cardHostElement={props.cardHostElement}
|
|
429
|
-
isUser={m().role === 'user'}
|
|
430
|
-
markdown={m().role === 'assistant'}
|
|
431
|
-
actions={m().actions}
|
|
432
|
-
actionsReveal={reveal()}
|
|
433
|
-
activeFeedback={feedback.resolveFeedback(m())}
|
|
434
|
-
copied={feedback.isCopied(m().id)}
|
|
435
|
-
onAction={(action) => feedback.handleAction(m(), action)}
|
|
436
|
-
/>
|
|
437
|
-
);
|
|
438
|
-
const rowGroup = () => (reveal() === 'hover' ? 'group ' : '');
|
|
439
|
-
return (
|
|
440
|
-
// `role` is the SPEAKER, forwarded on BOTH branches —
|
|
441
|
-
// see the same note in thread.tsx. `Message` turns it
|
|
442
|
-
// into `role="article"` + an `aria-label`; without it the
|
|
443
|
-
// row is a bare div chromium prunes from the
|
|
444
|
-
// accessibility tree as "uninteresting".
|
|
445
|
-
<Show
|
|
446
|
-
when={m().avatar}
|
|
447
|
-
fallback={
|
|
448
|
-
<Message role={m().role} class={`${rowGroup()}${m().role === 'user' ? 'flex-col items-end' : `flex-col ${ASSISTANT_ALIGN}`}`}>
|
|
449
|
-
{body}
|
|
450
|
-
</Message>
|
|
451
|
-
}
|
|
452
|
-
>
|
|
453
|
-
{(av) => (
|
|
454
|
-
<Message role={m().role} class={rowGroup()}>
|
|
455
|
-
<MessageAvatar src={av().src ?? ''} alt={av().alt ?? ''} fallback={av().fallback} />
|
|
456
|
-
<div class={`flex min-w-0 flex-1 flex-col ${m().role === 'user' ? 'items-end' : ASSISTANT_ALIGN}`}>
|
|
457
|
-
{body}
|
|
458
|
-
</div>
|
|
459
|
-
</Message>
|
|
460
|
-
)}
|
|
461
|
-
</Show>
|
|
462
|
-
);
|
|
463
|
-
}}
|
|
464
|
-
</Show>
|
|
465
|
-
)}
|
|
466
|
-
</For>
|
|
467
|
-
<ChatContainerScrollAnchor />
|
|
468
|
-
</ChatContainerContent>
|
|
469
|
-
<Show when={showScrollButton()}>
|
|
470
|
-
<div class="absolute bottom-4 left-1/2 flex w-full max-w-3xl -translate-x-1/2 justify-center px-5">
|
|
471
|
-
{/* The button now owns its elevation (kai-elevation); a `shadow-sm`
|
|
472
|
-
here would set box-shadow a second time and the winner would
|
|
473
|
-
be stylesheet order, not this call site. */}
|
|
474
|
-
<ScrollButton />
|
|
475
|
-
</div>
|
|
476
|
-
</Show>
|
|
477
|
-
</ChatContainer>
|
|
478
|
-
</div>
|
|
479
|
-
{/* INJECT — accessory row above the composer (extra actions/toolbar). */}
|
|
480
|
-
<Show when={props.composerActions}>
|
|
481
|
-
<div class="shrink-0 px-4">
|
|
482
|
-
<div class="mx-auto flex max-w-3xl items-center gap-2 pb-2"><slot name="composer-actions" /></div>
|
|
483
|
-
</div>
|
|
484
|
-
</Show>
|
|
485
|
-
<div class="shrink-0 px-4 pb-4">
|
|
486
|
-
<div class="mx-auto max-w-3xl">
|
|
487
|
-
{/* REPLACE — a full `composer` slot stands in for the built-in input.
|
|
488
|
-
The slotted content owns its own submit/loading wiring. */}
|
|
489
|
-
<Show
|
|
490
|
-
when={props.composer}
|
|
491
|
-
fallback={
|
|
492
|
-
<DefaultPromptInput
|
|
493
|
-
value={current()} placeholder={props.placeholder} loading={props.loading === true}
|
|
494
|
-
suggestions={visibleSuggestions()} attachments={attachments()}
|
|
495
|
-
accept={props.accept} onAttachmentsRejected={props.onAttachmentsRejected}
|
|
496
|
-
attach={props.attach} webSearch={props.webSearch === true} voice={props.voice === true}
|
|
497
|
-
triggers={props.triggers} kindIcons={props.kindIcons}
|
|
498
|
-
onValueChange={handleChange} onSubmit={handleSubmit} onSuggestionClick={handleSuggestionClick}
|
|
499
|
-
onAttachmentsChange={(a) => { setAttachments(a); props.onAttachmentsChange?.(a); }}
|
|
500
|
-
onWebSearch={() => props.onWebSearch?.()} onVoice={() => props.onVoice?.()}
|
|
501
|
-
/>
|
|
502
|
-
}
|
|
503
|
-
>
|
|
504
|
-
<slot name="composer" />
|
|
505
|
-
</Show>
|
|
506
|
-
</div>
|
|
507
|
-
</div>
|
|
508
|
-
{/* INJECT: footer row below the composer. */}
|
|
509
|
-
<Show when={props.footer}>
|
|
510
|
-
<div part="footer" class="shrink-0 px-4 pb-3">
|
|
511
|
-
<div class="mx-auto max-w-3xl text-center text-xs text-muted-foreground"><slot name="footer" /></div>
|
|
512
|
-
</div>
|
|
513
|
-
</Show>
|
|
514
|
-
</div>
|
|
515
|
-
</div>
|
|
516
|
-
</ChatConfig>
|
|
517
|
-
);
|
|
518
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { type JSX, Show, splitProps } from 'solid-js';
|
|
2
|
-
import { cn } from '../utils/cn';
|
|
3
|
-
import { Button } from '../ui/button';
|
|
4
|
-
import { Tooltip } from '../ui/tooltip';
|
|
5
|
-
import { Separator } from '../ui/separator';
|
|
6
|
-
|
|
7
|
-
export interface CheckpointProps extends JSX.HTMLAttributes<HTMLDivElement> {}
|
|
8
|
-
|
|
9
|
-
export function Checkpoint(props: CheckpointProps) {
|
|
10
|
-
const [local, rest] = splitProps(props, ['class', 'children']);
|
|
11
|
-
return (
|
|
12
|
-
<div
|
|
13
|
-
class={cn(
|
|
14
|
-
'flex items-center gap-0.5 overflow-hidden text-muted-foreground',
|
|
15
|
-
local.class
|
|
16
|
-
)}
|
|
17
|
-
{...rest}
|
|
18
|
-
>
|
|
19
|
-
{local.children}
|
|
20
|
-
<Separator />
|
|
21
|
-
</div>
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface CheckpointIconProps {
|
|
26
|
-
class?: string;
|
|
27
|
-
children?: JSX.Element;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function CheckpointIcon(props: CheckpointIconProps) {
|
|
31
|
-
return (
|
|
32
|
-
<Show
|
|
33
|
-
when={!props.children}
|
|
34
|
-
fallback={props.children}
|
|
35
|
-
>
|
|
36
|
-
<svg
|
|
37
|
-
width="16"
|
|
38
|
-
height="16"
|
|
39
|
-
viewBox="0 0 24 24"
|
|
40
|
-
fill="none"
|
|
41
|
-
stroke="currentColor"
|
|
42
|
-
stroke-width="2"
|
|
43
|
-
class={cn('size-4 shrink-0', props.class)}
|
|
44
|
-
>
|
|
45
|
-
<path d="M19 21l-7-5-7 5V5a2 2 0 012-2h10a2 2 0 012 2z" />
|
|
46
|
-
</svg>
|
|
47
|
-
</Show>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface CheckpointTriggerProps {
|
|
52
|
-
tooltip?: string;
|
|
53
|
-
/** Accessible name for the button — required when it has no visible text (icon-only). */
|
|
54
|
-
'aria-label'?: string;
|
|
55
|
-
onClick?: () => void;
|
|
56
|
-
children?: JSX.Element;
|
|
57
|
-
class?: string;
|
|
58
|
-
variant?: 'ghost' | 'default' | 'outline';
|
|
59
|
-
size?: 'sm' | 'md' | 'lg' | 'icon' | 'icon-sm';
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function CheckpointTrigger(props: CheckpointTriggerProps) {
|
|
63
|
-
const variant = () => props.variant ?? 'ghost';
|
|
64
|
-
const size = () => props.size ?? 'sm';
|
|
65
|
-
|
|
66
|
-
// A factory (not a single shared node): the Show fallback and the Tooltip
|
|
67
|
-
// child each need their OWN element instance, otherwise Solid reuses one DOM
|
|
68
|
-
// node across both branches and throws HierarchyRequestError when the tooltip
|
|
69
|
-
// branch mounts it.
|
|
70
|
-
const renderButton = () => (
|
|
71
|
-
<Button
|
|
72
|
-
variant={variant()}
|
|
73
|
-
size={size()}
|
|
74
|
-
type="button"
|
|
75
|
-
aria-label={props['aria-label']}
|
|
76
|
-
onClick={props.onClick}
|
|
77
|
-
class={props.class}
|
|
78
|
-
>
|
|
79
|
-
{props.children}
|
|
80
|
-
</Button>
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
return (
|
|
84
|
-
<Show when={props.tooltip} fallback={renderButton()}>
|
|
85
|
-
<Tooltip content={props.tooltip!}>{renderButton()}</Tooltip>
|
|
86
|
-
</Show>
|
|
87
|
-
);
|
|
88
|
-
}
|