@kitn.ai/ui 0.28.0 → 0.30.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 +11 -7
- package/dist/{Icon-DObhsRtm.js → Icon-BzBET3E-.js} +1 -1
- package/dist/{action-icons-CcgNN2oT.js → action-icons-DaW2pU6m.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-D783iMJj.js +1 -0
- package/dist/arrow-left-0VLM5kyg.js +1 -0
- package/dist/artifact-DGjzHYUT.js +1 -0
- package/dist/{attachments-Qr4kg-2b.js → attachments-YvXHlg88.js} +1 -1
- package/dist/{audio-visualizer-DToYdfSc.js → audio-visualizer-9lz5IHsL.js} +1 -1
- package/dist/{badge-CdEu_jn2.js → badge-Dh_vp8A5.js} +1 -1
- package/dist/{bell-DQAAOpDz.js → bell-CT7_WUwS.js} +1 -1
- package/dist/{button-DkuOnGLy.js → button-C_3te6fm.js} +1 -1
- package/dist/{card-renderer-Jx70m6_l.js → card-renderer-DZVaGH2e.js} +1 -1
- package/dist/check-CiEOVnEN.js +1 -0
- package/dist/{checkbox-D7iRB3nL.js → checkbox-Bu2T2e0U.js} +1 -1
- package/dist/{checkbox-group-B2_rpoPM.js → checkbox-group-BiryEXPQ.js} +1 -1
- package/dist/chevron-down-CSobuZRG.js +1 -0
- package/dist/chevron-right-DR9ZAP-2.js +1 -0
- package/dist/{choice-card-m0BYqqOK.js → choice-card-CM6IjkmL.js} +1 -1
- package/dist/circle-BC66EYF7.js +1 -0
- package/dist/circle-check-BqmahW0O.js +1 -0
- package/dist/{circle-x-BPG0iPst.js → circle-x-Bk-dA5Wf.js} +1 -1
- package/dist/{code-block-ClMLKb7C.js → code-block-B26t-Q7q.js} +1 -1
- package/dist/{collapsible-B4DlWicL.js → collapsible-Bhc636Cf.js} +1 -1
- package/dist/components/builder-composer-triggers.d.ts +62 -0
- package/dist/components/builder-layout.d.ts +54 -0
- package/dist/components/builder-message-actions.d.ts +72 -0
- package/dist/components/builder-panel.d.ts +189 -0
- package/dist/components/builder-preview.d.ts +11 -0
- package/dist/components/builder-shell-controls.d.ts +69 -0
- package/dist/components/builder-skeleton.d.ts +58 -0
- package/dist/components/builder-start.d.ts +75 -0
- package/dist/components/builder-workspace-variants.d.ts +23 -0
- package/dist/components/captions.d.ts +66 -0
- package/dist/{composer-sQ0HcvyG.js → composer-DMI85B6j.js} +1 -1
- package/dist/{confirm-card-rQWDQsnC.js → confirm-card-B0YIAwXp.js} +1 -1
- package/dist/construct-cli.es.js +3 -3
- package/dist/construct.d.ts +5 -0
- package/dist/construct.js +327 -0
- package/dist/{context-0kg4ZX1J.js → context-DWgfhqWp.js} +1 -1
- package/dist/controllable-BagRpyHv.js +1 -0
- package/dist/{conversation-item-BxwQLaFJ.js → conversation-item-BsOsVGmT.js} +1 -1
- package/dist/{conversation-list-BCfGN1JU.js → conversation-list-aX3Vtc7L.js} +1 -1
- package/dist/{copy-n9u9rqpi.js → copy-BmEwsNhJ.js} +1 -1
- package/dist/core-C8fzo39E.js +1 -12
- package/dist/{create-tween-uPkArjIG.js → create-tween-CNOAU3Fx.js} +1 -1
- package/dist/{create-tween-C-q-JCM-.js → create-tween-WfqiENls.js} +1 -1
- package/dist/{create-tween-CRrJXxBd.js → create-tween-wlFtW9Kh.js} +1 -1
- package/dist/{create-tween-DZ3RRDHD.js → create-tween-zt79ba32.js} +1 -1
- package/dist/{default-input-CaMrJkgH.js → default-input-DMV5Eaze.js} +1 -1
- package/dist/define-CI0y3eE4.js +1 -0
- package/dist/define.js +40 -40
- package/dist/define.server.js +45 -45
- package/dist/{disclosure-WUImBbDv.js → disclosure-NnACBxsC.js} +1 -1
- package/dist/{dropdown-wZVeJOMd.js → dropdown-DT7G0RGR.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 +1 -1
- package/dist/elements/dropdown.js +1 -1
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.js +1 -1
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-grid.js +1 -1
- package/dist/elements/pane-group.js +1 -1
- package/dist/elements/pane.js +1 -1
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.js +1 -1
- package/dist/elements/prompt-dock.js +1 -1
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/radio-group.js +1 -1
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +1 -1
- package/dist/elements/screen.js +1 -1
- package/dist/elements/scroll-area.js +1 -1
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.js +1 -1
- package/dist/elements/segmented.js +1 -1
- package/dist/elements/select.js +1 -1
- package/dist/elements/separator.js +1 -1
- package/dist/elements/setting-item.js +1 -1
- package/dist/elements/settings-group.js +1 -1
- package/dist/elements/skeleton.js +1 -1
- package/dist/elements/slider.js +1 -1
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.js +1 -1
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.js +1 -1
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/thread.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.js +1 -1
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/{ellipsis-CbOpJnU3.js → ellipsis-6pJ7SxYT.js} +1 -1
- package/dist/{embed-CrfjkbUG.js → embed-BMje-nxj.js} +1 -1
- package/dist/engine-javascript-C1x7zo1_.js +1 -141
- package/dist/{external-link-ByXAwBBQ.js → external-link-Beh9DKeR.js} +1 -1
- package/dist/{file-text-DMib2qwt.js → file-text-D1GPfZ8Q.js} +1 -1
- package/dist/{file-tree-CJqM2aP7.js → file-tree-Dwj2lqg-.js} +1 -1
- package/dist/{folder-_BAb929C.js → folder-b6D8x1DY.js} +1 -1
- package/dist/{form-DSZgZQZk.js → form-DWgdxDXu.js} +1 -1
- package/dist/{hover-card-BQbul9eq.js → hover-card-CWRkqm40.js} +1 -1
- package/dist/{icon-CdcfRhYI.js → icon-CL0jdhsf.js} +1 -1
- package/dist/index.js +1741 -1725
- package/dist/index.server.js +1582 -1566
- package/dist/{info-DsFjGuI_.js → info-0cOUherQ.js} +1 -1
- package/dist/{input-DKbmkMos.js → input-BH6Ru91Q.js} +1 -1
- package/dist/kai.es.js +1 -1
- package/dist/{kbd-PvdGhX4s.js → kbd-DRAnVtNX.js} +1 -1
- package/dist/{link-zF8PzWfF.js → link-Dlr0vssB.js} +1 -1
- package/dist/{link-preview-DbM1866N.js → link-preview-DODgRyV9.js} +1 -1
- package/dist/loader-KvJB6NrT.js +1 -0
- package/dist/{markdown-LMvmAyBk.js → markdown-DX9tuJVj.js} +1 -1
- package/dist/mcp.es.js +9 -5
- package/dist/{message-BYZECyek.js → message-BqQ7Ot5q.js} +1 -1
- package/dist/{message-BSsgvHvf.js → message-DkaGfBd8.js} +1 -1
- package/dist/message-circle-BPpp5QKv.js +1 -0
- package/dist/message-square-BLbsd9BJ.js +1 -0
- package/dist/{minimize-2-BQRoBV1V.js → minimize-2-CyOHJwcN.js} +1 -1
- package/dist/{model-switcher-CMpCOYcB.js → model-switcher-0hrKDiK2.js} +1 -1
- package/dist/{overlay-Cb-MkyDa.js → overlay-DBMFXie6.js} +1 -1
- package/dist/{panel-right-i8warFxT.js → panel-right-t8SWJL6e.js} +1 -1
- package/dist/{paperclip-ByY3UVO6.js → paperclip-CdzuOjbU.js} +1 -1
- package/dist/play-BXy1u7rW.js +1 -0
- package/dist/primitives/use-auto-resize.d.ts +11 -0
- package/dist/{progress-bar-jVAHvMUf.js → progress-bar-CiBtxMWT.js} +1 -1
- package/dist/{prompt-suggestion-CD-qtNgC.js → prompt-suggestion-I_DHP21i.js} +1 -1
- package/dist/{radio-BsoBMhkF.js → radio-C_p3n39l.js} +1 -1
- package/dist/{reasoning-4kBPtlTx.js → reasoning-BDwy_tIe.js} +1 -1
- package/dist/register-impl-DvEnhIxx.js +424 -0
- package/dist/{resizable-uPmY9VY-.js → resizable-SYC-fStM.js} +1 -1
- package/dist/{rotate-ccw-B2xn93py.js → rotate-ccw-B1nwmwuY.js} +1 -1
- package/dist/{rotate-cw-CMVLoCyH.js → rotate-cw-CLAnBcm1.js} +1 -1
- package/dist/{scroll-area-BqLUo8ZZ.js → scroll-area-zRyXoLhI.js} +1 -1
- package/dist/{scroll-button-DslXiJyL.js → scroll-button-jzrbYCG9.js} +1 -1
- package/dist/{select-2cLRtPGT.js → select-DM-0nEe0.js} +1 -1
- package/dist/{separator-BWQtNJcM.js → separator-BToOOoOt.js} +1 -1
- package/dist/{settings-BBR63jLg.js → settings-PaGo_S4U.js} +1 -1
- package/dist/{settings-group-B2ciy-Iw.js → settings-group-BFXGIfXq.js} +1 -1
- package/dist/{skeleton-CkHI-HgC.js → skeleton-DYpmFnnm.js} +1 -1
- package/dist/{slider-DDR9U-i0.js → slider-ebutAmkQ.js} +1 -1
- package/dist/{solid-DruVOXnf.js → solid-15v_3WVL.js} +3563 -3412
- package/dist/{solid-BzCFdL25.js → solid-5P-otgdi.js} +4502 -4296
- package/dist/solid.d.ts +6 -0
- package/dist/solid.js +259 -254
- package/dist/solid.server.js +259 -254
- package/dist/{source-GEnFF528.js → source-c1gpRl9h.js} +1 -1
- package/dist/{star-CilHq8GP.js → star-pcV_3LqF.js} +1 -1
- package/dist/{store-Ciyk6eZG.js → store-CSgbFFCg.js} +1 -1
- package/dist/{switch-KkeQIbuH.js → switch-Bh2OdLV2.js} +1 -1
- package/dist/{tasks-card-BrN4bggJ.js → tasks-card-CbqQAn2S.js} +1 -1
- package/dist/text-shimmer-BSzgEnDH.js +1 -0
- package/dist/textarea-DrYNt_0z.js +1 -0
- package/dist/theme.tokens.css +22 -21
- package/dist/{thumbs-up-CsT9Wzb9.js → thumbs-up-BL3-NenK.js} +1 -1
- package/dist/{toast-store-tgK6MuMv.js → toast-store-DkOlYczt.js} +1 -1
- package/dist/{tool-DzUjIBT8.js → tool-CeIWUVUe.js} +1 -1
- package/dist/{tooltip-Bkkg_4t0.js → tooltip-GA-nmg06.js} +1 -1
- package/dist/{trash-2-jBKxjGGQ.js → trash-2-CT66QWlm.js} +1 -1
- package/dist/{triangle-alert-DlQ68ppf.js → triangle-alert-CeHLWxhD.js} +1 -1
- package/dist/ui/color-field.d.ts +48 -0
- package/dist/ui/textarea.d.ts +4 -0
- package/dist/ui/toggle-chip.d.ts +40 -0
- package/dist/{upload-TcAHXv9W.js → upload-9Csb0F0J.js} +1 -1
- package/dist/{use-card-resolution-DaZqAdWf.js → use-card-resolution-Zg0a08Z-.js} +1 -1
- package/dist/{variant-aurora-DbW_OWL2.js → variant-aurora-4VBQHIKV.js} +1 -1
- package/dist/{variant-aurora-CNmfHhcx.js → variant-aurora-DBeCAQNk.js} +2 -2
- package/dist/{variant-aurora-D6GsdTPA.js → variant-aurora-FzHVXHby.js} +2 -2
- package/dist/{variant-aurora-BhLuYxJR.js → variant-aurora-LE3fqxgw.js} +1 -1
- package/dist/{variant-custom-BvYHR62b.js → variant-custom-AFRGcOBS.js} +1 -1
- package/dist/{variant-custom-DV2x254s.js → variant-custom-BQkNuPpE.js} +2 -2
- package/dist/{variant-custom-BRvaNHSi.js → variant-custom-DI5R0rln.js} +1 -1
- package/dist/{variant-custom-DMTrEO5w.js → variant-custom-WWnrrRHS.js} +2 -2
- package/dist/{variant-wave-CyBueXj9.js → variant-wave-DUCbH5oI.js} +2 -2
- package/dist/{variant-wave-BNMGrDfj.js → variant-wave-DuQV7DhQ.js} +2 -2
- package/dist/{variant-wave-BpDd8t3Z.js → variant-wave-nSI2sfII.js} +1 -1
- package/dist/{variant-wave-sp-qwsdI.js → variant-wave-wTP5v_jU.js} +1 -1
- package/dist/x-eiO9V6J6.js +1 -0
- package/{src/elements/styles.css → kit-base.css} +27 -44
- package/package.json +32 -17
- package/solid.css +33 -0
- package/theme.css +39 -23
- package/bin/route.test.js +0 -58
- package/dist/arrow-down-CjRU3JgV.js +0 -1
- package/dist/arrow-left-Bnpb1UEW.js +0 -1
- package/dist/artifact-Bwt7OgcR.js +0 -1
- package/dist/check-njkVdZu2.js +0 -1
- package/dist/chevron-down-B72s6PXR.js +0 -1
- package/dist/chevron-right-BatuHzUm.js +0 -1
- package/dist/circle-check-B62pODB3.js +0 -1
- package/dist/circle-zx0ByzY9.js +0 -1
- package/dist/controllable-CnGpMF6r.js +0 -1
- package/dist/define-By-uL588.js +0 -1
- package/dist/loader-BM4CEz4G.js +0 -1
- package/dist/message-circle-DruwObfX.js +0 -1
- package/dist/message-square-BG6q6mlm.js +0 -1
- package/dist/play-BvKKq3fX.js +0 -1
- package/dist/register-impl-B1hLkrI8.js +0 -424
- package/dist/text-shimmer-Dcj1MHuq.js +0 -1
- package/dist/textarea-Dpvbngbg.js +0 -1
- package/dist/x-Z5UntkIJ.js +0 -1
- package/src/agent-tooling/README.md +0 -192
- 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 -147
- package/src/agent-tooling/construct/codegen.ts +0 -1635
- package/src/agent-tooling/construct/construct.v1.schema.json +0 -319
- 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 -32
- package/src/agent-tooling/construct/schema.ts +0 -452
- 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 -1014
- 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 -241
- package/src/components/conversation-list.tsx +0 -429
- package/src/components/conversation-panel.tsx +0 -118
- 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/home-panel.tsx +0 -159
- 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/widget-tab-bar.tsx +0 -73
- 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 -304
- 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 -187
- package/src/elements/element-types.d.ts +0 -4353
- 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/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 -430
- 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/conversation-store.ts +0 -248
- 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 -173
- 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 -95
- 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 -630
- 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,455 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type JSX,
|
|
3
|
-
type Accessor,
|
|
4
|
-
Show,
|
|
5
|
-
Index,
|
|
6
|
-
splitProps,
|
|
7
|
-
mergeProps,
|
|
8
|
-
createSignal,
|
|
9
|
-
createMemo,
|
|
10
|
-
createEffect,
|
|
11
|
-
on,
|
|
12
|
-
ErrorBoundary,
|
|
13
|
-
createUniqueId,
|
|
14
|
-
} from 'solid-js';
|
|
15
|
-
import { cn } from '../utils/cn';
|
|
16
|
-
import { Button } from '../ui/button';
|
|
17
|
-
import { Card } from './card';
|
|
18
|
-
import { MessageBody } from './message';
|
|
19
|
-
import { TextShimmer } from './text-shimmer';
|
|
20
|
-
import { Check } from 'lucide-solid';
|
|
21
|
-
import {
|
|
22
|
-
type CompareCandidate,
|
|
23
|
-
type ComparePair,
|
|
24
|
-
type CompareSelection,
|
|
25
|
-
type ResponseCompareData,
|
|
26
|
-
buildSelection,
|
|
27
|
-
candidateToParts,
|
|
28
|
-
isAnyStreaming,
|
|
29
|
-
normalizeCandidates,
|
|
30
|
-
} from './response-compare-types';
|
|
31
|
-
|
|
32
|
-
// Re-export the data types + pure helpers so consumers (and the `<kai-compare>`
|
|
33
|
-
// facade) can import everything from a single `response-compare` module.
|
|
34
|
-
export type {
|
|
35
|
-
CompareCandidate,
|
|
36
|
-
ComparePair,
|
|
37
|
-
CompareCollapse,
|
|
38
|
-
ResponseCompareData,
|
|
39
|
-
CompareSelection,
|
|
40
|
-
} from './response-compare-types';
|
|
41
|
-
export { normalizeCandidates, buildSelection, isAnyStreaming, candidateToParts } from './response-compare-types';
|
|
42
|
-
|
|
43
|
-
export type CompareLayout = 'auto' | 'columns' | 'tabs';
|
|
44
|
-
|
|
45
|
-
/** Imperative handle exposed via `controllerRef` — surfaces the compare's latent
|
|
46
|
-
* capabilities (commit a pick by candidate id, focus the roving tab stop) so the
|
|
47
|
-
* `<kai-compare>` facade can forward them as instance methods (Pattern C). */
|
|
48
|
-
export interface ResponseCompareController {
|
|
49
|
-
/** Commit a pick by candidate id — same path as the "Pick this" button: emits
|
|
50
|
-
* onSelect + optimistically collapses (single-shot; inert while streaming or
|
|
51
|
-
* already resolved). No-op for an unknown id. */
|
|
52
|
-
select(candidateId: string): void;
|
|
53
|
-
/** Focus the current roving tab stop (the focused candidate's "Pick this" radio). */
|
|
54
|
-
focus(options?: FocusOptions): void;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
58
|
-
// Resolution controller — a sibling of `useCardResolution` for `CompareSelection`,
|
|
59
|
-
// which has no `kind` field (so it can't satisfy `R extends CardResolution`). Same
|
|
60
|
-
// precedence: prop (host-driven / re-hydrated) > local optimistic flip > none. A
|
|
61
|
-
// fresh `data` identity clears the local flip, but an explicit prop keeps it
|
|
62
|
-
// resolved. `isOptimistic` is true only for a flip made THIS session (announced via
|
|
63
|
-
// role="status"; silent on re-hydrate).
|
|
64
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
65
|
-
|
|
66
|
-
export interface ResolvedController<T> {
|
|
67
|
-
value: Accessor<T | undefined>;
|
|
68
|
-
isResolved: Accessor<boolean>;
|
|
69
|
-
isOptimistic: Accessor<boolean>;
|
|
70
|
-
setLocal: (v: T) => void;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function useResolved<T>(opts: {
|
|
74
|
-
prop: Accessor<T | undefined>;
|
|
75
|
-
data: Accessor<unknown>;
|
|
76
|
-
}): ResolvedController<T> {
|
|
77
|
-
const [local, setLocal] = createSignal<T | undefined>(undefined);
|
|
78
|
-
// Clear the optimistic flip on a NEW data identity (deferred so mount doesn't
|
|
79
|
-
// clobber an initial prop). The prop still wins via the memo below.
|
|
80
|
-
createEffect(on(opts.data, () => setLocal(undefined), { defer: true }));
|
|
81
|
-
const value = createMemo(() => opts.prop() ?? local());
|
|
82
|
-
const isResolved = createMemo(() => value() !== undefined);
|
|
83
|
-
const isOptimistic = createMemo(() => opts.prop() === undefined && local() !== undefined);
|
|
84
|
-
return { value, isResolved, isOptimistic, setLocal };
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
88
|
-
// The <ResponseCompare> component.
|
|
89
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
90
|
-
|
|
91
|
-
export interface ResponseCompareProps {
|
|
92
|
-
/** The compare definition (prompt + the two candidates). */
|
|
93
|
-
data?: ResponseCompareData;
|
|
94
|
-
/** Stable id correlating every emitted event. */
|
|
95
|
-
compareId?: string;
|
|
96
|
-
/** Re-hydrate / control the selection. Renders the collapsed winner. Set as a
|
|
97
|
-
* JS property: `el.selection = { chosenId, rejectedIds }`. */
|
|
98
|
-
selection?: CompareSelection;
|
|
99
|
-
/** Layout. `'columns'` = side-by-side; `'tabs'` = one candidate at a time with
|
|
100
|
-
* pills to switch; `'auto'` (default) uses a CONTAINER query — columns when the
|
|
101
|
-
* component is ≥640px wide, tabs when narrower (e.g. on a phone). */
|
|
102
|
-
layout?: CompareLayout;
|
|
103
|
-
class?: string;
|
|
104
|
-
/** Receive the imperative controller once mounted. The `<kai-compare>` facade
|
|
105
|
-
* forwards these as element methods (select/focus). */
|
|
106
|
-
controllerRef?: (controller: ResponseCompareController) => void;
|
|
107
|
-
/** Fired when the user commits a pick. */
|
|
108
|
-
onSelect?: (sel: CompareSelection) => void;
|
|
109
|
-
/** Fired once both candidates have settled (stopped streaming) and a valid
|
|
110
|
-
* definition is shown. */
|
|
111
|
-
onReady?: () => void;
|
|
112
|
-
/** Fired for an unusable definition (inline error state). */
|
|
113
|
-
onError?: (message: string) => void;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* `ResponseCompare` — a dual-response comparison. Two assistant candidates for the
|
|
118
|
-
* same prompt render side-by-side (or as tabs), each via `MessageBody` so a
|
|
119
|
-
* candidate reads exactly like an assistant message (reasoning + tools +
|
|
120
|
-
* attachments + markdown). The pick is a COMMIT, not a Submit: clicking "Pick this"
|
|
121
|
-
* (or Enter on the focused column) computes `{ chosenId, rejectedIds:[other], at }`,
|
|
122
|
-
* optimistically collapses to the chosen candidate's body, and calls `onSelect` for
|
|
123
|
-
* the consumer to send a `(prompt, chosen, rejected)` preference pair. Single-shot.
|
|
124
|
-
*
|
|
125
|
-
* While EITHER candidate is `streaming`, both pick controls are disabled and the
|
|
126
|
-
* streaming column shows a `TextShimmer`; `onReady` fires once both settle. The two
|
|
127
|
-
* columns are a WAI-ARIA radiogroup with roving tabindex (Arrow keys move A↔B,
|
|
128
|
-
* Enter/Space picks). Emits `onError` for a malformed definition.
|
|
129
|
-
*/
|
|
130
|
-
export function ResponseCompare(props: ResponseCompareProps): JSX.Element {
|
|
131
|
-
const merged = mergeProps({ compareId: 'kai-compare', layout: 'auto' as CompareLayout }, props);
|
|
132
|
-
const [local] = splitProps(merged, [
|
|
133
|
-
'data',
|
|
134
|
-
'compareId',
|
|
135
|
-
'selection',
|
|
136
|
-
'layout',
|
|
137
|
-
'class',
|
|
138
|
-
'controllerRef',
|
|
139
|
-
'onSelect',
|
|
140
|
-
'onReady',
|
|
141
|
-
'onError',
|
|
142
|
-
]);
|
|
143
|
-
|
|
144
|
-
const uid = createUniqueId();
|
|
145
|
-
|
|
146
|
-
const normalized = createMemo(() => normalizeCandidates(local.data?.candidates));
|
|
147
|
-
const valid = createMemo(() => normalized().candidates !== null);
|
|
148
|
-
const errorMessage = createMemo(() => normalized().error ?? '');
|
|
149
|
-
const pair = createMemo<ComparePair | null>(() => normalized().candidates);
|
|
150
|
-
|
|
151
|
-
const res = useResolved<CompareSelection>({
|
|
152
|
-
prop: () => local.selection,
|
|
153
|
-
data: () => local.data,
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
// Both candidates settled → enable the pick + announce ready.
|
|
157
|
-
const streaming = createMemo(() => isAnyStreaming(pair()));
|
|
158
|
-
|
|
159
|
-
const [focusIndex, setFocusIndex] = createSignal(0);
|
|
160
|
-
// In tabs mode (and auto when the container is narrow) only one candidate shows
|
|
161
|
-
// at a time; `active` is which. Ignored in columns mode where both render.
|
|
162
|
-
const [active, setActive] = createSignal(0);
|
|
163
|
-
let groupRef: HTMLDivElement | undefined;
|
|
164
|
-
|
|
165
|
-
// Reset the roving tab stop + active tab whenever a NEW definition arrives.
|
|
166
|
-
createEffect(on(() => local.data, () => { setFocusIndex(0); setActive(0); }));
|
|
167
|
-
|
|
168
|
-
// ready / error lifecycle: error on an unusable definition, ready once both
|
|
169
|
-
// candidates have settled (so consumers know the pick is now live).
|
|
170
|
-
createEffect(
|
|
171
|
-
on([valid, streaming], ([ok, isStreaming]) => {
|
|
172
|
-
if (!ok) {
|
|
173
|
-
local.onError?.(errorMessage());
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
if (!isStreaming) local.onReady?.();
|
|
177
|
-
}),
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
const chosenId = createMemo(() => res.value()?.chosenId);
|
|
181
|
-
const chosenCandidate = createMemo<CompareCandidate | undefined>(() => {
|
|
182
|
-
const id = chosenId();
|
|
183
|
-
return id === undefined ? undefined : pair()?.find((c) => c.id === id);
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// Commit a pick: emit + optimistically flip (single-shot; inert once resolved
|
|
187
|
-
// or while still streaming).
|
|
188
|
-
const pick = (candidate: CompareCandidate): void => {
|
|
189
|
-
if (res.isResolved()) return;
|
|
190
|
-
if (streaming()) return;
|
|
191
|
-
const p = pair();
|
|
192
|
-
if (!p) return;
|
|
193
|
-
const sel = buildSelection(p, candidate.id);
|
|
194
|
-
local.onSelect?.(sel);
|
|
195
|
-
res.setLocal(sel);
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
const focusColumn = (index: number, options?: FocusOptions): void => {
|
|
199
|
-
const cols = groupRef?.querySelectorAll<HTMLElement>('[role="radio"]');
|
|
200
|
-
cols?.[index]?.focus(options);
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
// Imperative controller (Pattern C): hand the facade a handle over the latent
|
|
204
|
-
// pick + roving-focus capabilities. `pick`/`focusColumn` are already wired
|
|
205
|
-
// internally — this just surfaces them. `select` looks the candidate up by id
|
|
206
|
-
// (the public surface is id-based; `pick` is candidate-based internally) and
|
|
207
|
-
// is a no-op for an unknown id, while streaming, or once resolved (via pick()).
|
|
208
|
-
local.controllerRef?.({
|
|
209
|
-
select: (candidateId: string) => {
|
|
210
|
-
const cand = pair()?.find((c) => c.id === candidateId);
|
|
211
|
-
if (cand) pick(cand);
|
|
212
|
-
},
|
|
213
|
-
focus: (options?: FocusOptions) => focusColumn(focusIndex(), options),
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
// Two-item roving tabindex (A↔B). Arrows toggle the focused column; Enter/Space
|
|
217
|
-
// picks it. No-op once resolved.
|
|
218
|
-
const onGroupKeyDown = (e: KeyboardEvent): void => {
|
|
219
|
-
if (res.isResolved()) return;
|
|
220
|
-
const p = pair();
|
|
221
|
-
if (!p) return;
|
|
222
|
-
const move = (next: number) => { setFocusIndex(next); setActive(next); focusColumn(next); };
|
|
223
|
-
if (e.key === 'ArrowRight' || e.key === 'ArrowDown' || e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
|
|
224
|
-
e.preventDefault();
|
|
225
|
-
move(focusIndex() === 0 ? 1 : 0);
|
|
226
|
-
} else if (e.key === 'Home') {
|
|
227
|
-
e.preventDefault();
|
|
228
|
-
move(0);
|
|
229
|
-
} else if (e.key === 'End') {
|
|
230
|
-
e.preventDefault();
|
|
231
|
-
move(1);
|
|
232
|
-
} else if (e.key === ' ' || e.key === 'Enter') {
|
|
233
|
-
e.preventDefault();
|
|
234
|
-
const cand = p[focusIndex()];
|
|
235
|
-
if (cand) pick(cand);
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
// `auto` switches by CONTAINER width (Tailwind v4 `@container` + `@[640px]`
|
|
240
|
-
// variants); `@container/compare` lives on the OUTER wrapper (below) so the
|
|
241
|
-
// pill bar + columns both respond to it.
|
|
242
|
-
const wrapperClass = createMemo(() => {
|
|
243
|
-
const l = local.layout;
|
|
244
|
-
if (l === 'columns') return 'grid grid-cols-2 gap-3';
|
|
245
|
-
if (l === 'tabs') return 'grid grid-cols-1 gap-3';
|
|
246
|
-
return 'grid grid-cols-1 gap-3 @[640px]/compare:grid-cols-2'; // auto
|
|
247
|
-
});
|
|
248
|
-
// The tab-pill bar shows in tabs mode, and in auto only while the container is narrow.
|
|
249
|
-
const showTabs = () => local.layout === 'tabs' || local.layout === 'auto';
|
|
250
|
-
const tabBarClass = () => (local.layout === 'auto' ? '@[640px]/compare:hidden' : '');
|
|
251
|
-
// A non-active candidate is hidden in tabs (always) and auto (only while narrow);
|
|
252
|
-
// the active one — and both in columns mode — always render.
|
|
253
|
-
const columnHiddenClass = (index: number): string => {
|
|
254
|
-
const l = local.layout;
|
|
255
|
-
if (l === 'columns' || index === active()) return '';
|
|
256
|
-
return l === 'tabs' ? 'hidden' : 'hidden @[640px]/compare:block';
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
const promptId = `kai-compare-prompt-${uid}`;
|
|
260
|
-
const groupLabel = (): string => local.data?.prompt ?? 'Compare two responses';
|
|
261
|
-
|
|
262
|
-
return (
|
|
263
|
-
<Show
|
|
264
|
-
when={valid()}
|
|
265
|
-
fallback={<Card errorMessage={errorMessage() || "This comparison couldn't be displayed."} />}
|
|
266
|
-
>
|
|
267
|
-
<ErrorBoundary
|
|
268
|
-
fallback={() => {
|
|
269
|
-
local.onError?.('The comparison failed to render.');
|
|
270
|
-
return <Card errorMessage="The comparison failed to render." />;
|
|
271
|
-
}}
|
|
272
|
-
>
|
|
273
|
-
<div class={cn('flex flex-col gap-3', local.layout === 'auto' && '@container/compare', local.class)}>
|
|
274
|
-
<Show when={local.data?.prompt}>
|
|
275
|
-
<p id={promptId} class="text-sm text-foreground">
|
|
276
|
-
{local.data?.prompt}
|
|
277
|
-
</p>
|
|
278
|
-
</Show>
|
|
279
|
-
|
|
280
|
-
<Show
|
|
281
|
-
when={!res.isResolved()}
|
|
282
|
-
fallback={
|
|
283
|
-
<CollapsedWinner
|
|
284
|
-
candidate={chosenCandidate()}
|
|
285
|
-
optimistic={res.isOptimistic()}
|
|
286
|
-
/>
|
|
287
|
-
}
|
|
288
|
-
>
|
|
289
|
-
{/* Tab pills — switch the visible candidate in tabs / auto-narrow mode. */}
|
|
290
|
-
<Show when={showTabs()}>
|
|
291
|
-
<div role="tablist" aria-label="Switch response" class={cn('flex gap-1', tabBarClass())}>
|
|
292
|
-
<Index each={pair() ?? []}>
|
|
293
|
-
{(candidate, index) => (
|
|
294
|
-
<button
|
|
295
|
-
type="button"
|
|
296
|
-
role="tab"
|
|
297
|
-
aria-selected={active() === index}
|
|
298
|
-
class={cn(
|
|
299
|
-
'rounded-md px-3 py-1 text-xs font-medium transition-colors',
|
|
300
|
-
active() === index
|
|
301
|
-
? 'bg-muted text-foreground'
|
|
302
|
-
: 'text-muted-foreground hover:text-foreground',
|
|
303
|
-
)}
|
|
304
|
-
onClick={() => { setActive(index); setFocusIndex(index); }}
|
|
305
|
-
>
|
|
306
|
-
{candidate().label ?? `Response ${candidate().id}`}
|
|
307
|
-
</button>
|
|
308
|
-
)}
|
|
309
|
-
</Index>
|
|
310
|
-
</div>
|
|
311
|
-
</Show>
|
|
312
|
-
|
|
313
|
-
<div
|
|
314
|
-
ref={groupRef}
|
|
315
|
-
role="radiogroup"
|
|
316
|
-
aria-label={groupLabel()}
|
|
317
|
-
aria-describedby={local.data?.prompt ? promptId : undefined}
|
|
318
|
-
class={wrapperClass()}
|
|
319
|
-
onKeyDown={onGroupKeyDown}
|
|
320
|
-
>
|
|
321
|
-
<Index each={pair() ?? []}>
|
|
322
|
-
{(candidate, index) => (
|
|
323
|
-
<CompareColumn
|
|
324
|
-
candidate={candidate()}
|
|
325
|
-
tabStop={index === focusIndex()}
|
|
326
|
-
disabled={streaming()}
|
|
327
|
-
hiddenClass={() => columnHiddenClass(index)}
|
|
328
|
-
onFocus={() => setFocusIndex(index)}
|
|
329
|
-
onPick={() => {
|
|
330
|
-
setFocusIndex(index);
|
|
331
|
-
pick(candidate());
|
|
332
|
-
}}
|
|
333
|
-
/>
|
|
334
|
-
)}
|
|
335
|
-
</Index>
|
|
336
|
-
</div>
|
|
337
|
-
</Show>
|
|
338
|
-
</div>
|
|
339
|
-
</ErrorBoundary>
|
|
340
|
-
</Show>
|
|
341
|
-
);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
345
|
-
// One candidate column — a plain container with the assistant-styled body and a
|
|
346
|
-
// "Pick this" button that IS the radio (the radiogroup option). Keeping the radio
|
|
347
|
-
// on the button, not the wrapping div, avoids nesting interactive controls (the
|
|
348
|
-
// body itself can contain interactive bits like reasoning/tool toggles).
|
|
349
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
350
|
-
|
|
351
|
-
interface ColumnProps {
|
|
352
|
-
candidate: CompareCandidate;
|
|
353
|
-
tabStop: boolean;
|
|
354
|
-
disabled: boolean;
|
|
355
|
-
/** Extra (reactive) class controlling tabs/auto visibility — hidden when this
|
|
356
|
-
* is the non-active candidate in tabs / auto-narrow mode. */
|
|
357
|
-
hiddenClass?: () => string;
|
|
358
|
-
onFocus: () => void;
|
|
359
|
-
onPick: () => void;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function CompareColumn(props: ColumnProps): JSX.Element {
|
|
363
|
-
const labelText = (): string =>
|
|
364
|
-
props.candidate.label ?? props.candidate.model ?? props.candidate.id;
|
|
365
|
-
return (
|
|
366
|
-
<div
|
|
367
|
-
class={cn(
|
|
368
|
-
'flex min-w-0 flex-col gap-3 rounded-lg border border-border bg-background/40 p-3',
|
|
369
|
-
props.hiddenClass?.(),
|
|
370
|
-
)}
|
|
371
|
-
>
|
|
372
|
-
<Show when={props.candidate.label || props.candidate.model}>
|
|
373
|
-
<div class="flex items-center gap-2">
|
|
374
|
-
<Show when={props.candidate.label}>
|
|
375
|
-
<span class="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
|
|
376
|
-
{props.candidate.label}
|
|
377
|
-
</span>
|
|
378
|
-
</Show>
|
|
379
|
-
<Show when={props.candidate.model}>
|
|
380
|
-
<span class="text-xs text-muted-foreground">{props.candidate.model}</span>
|
|
381
|
-
</Show>
|
|
382
|
-
</div>
|
|
383
|
-
</Show>
|
|
384
|
-
|
|
385
|
-
<div class="min-w-0 flex-1">
|
|
386
|
-
<Show
|
|
387
|
-
when={props.candidate.streaming}
|
|
388
|
-
fallback={
|
|
389
|
-
<MessageBody
|
|
390
|
-
parts={candidateToParts(props.candidate)}
|
|
391
|
-
isUser={false}
|
|
392
|
-
markdown={true}
|
|
393
|
-
/>
|
|
394
|
-
}
|
|
395
|
-
>
|
|
396
|
-
<TextShimmer class="text-sm">Generating response…</TextShimmer>
|
|
397
|
-
</Show>
|
|
398
|
-
</div>
|
|
399
|
-
|
|
400
|
-
<Button
|
|
401
|
-
type="button"
|
|
402
|
-
role="radio"
|
|
403
|
-
aria-checked={false}
|
|
404
|
-
aria-label={`Pick ${labelText()}`}
|
|
405
|
-
data-candidate-id={props.candidate.id}
|
|
406
|
-
variant="outline"
|
|
407
|
-
size="sm"
|
|
408
|
-
class="mt-auto w-full"
|
|
409
|
-
disabled={props.disabled}
|
|
410
|
-
tabindex={props.tabStop ? 0 : -1}
|
|
411
|
-
onFocus={props.onFocus}
|
|
412
|
-
onClick={(e) => {
|
|
413
|
-
e.stopPropagation();
|
|
414
|
-
props.onPick();
|
|
415
|
-
}}
|
|
416
|
-
>
|
|
417
|
-
Pick this
|
|
418
|
-
</Button>
|
|
419
|
-
</div>
|
|
420
|
-
);
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
424
|
-
// CollapsedWinner — the read-only view after a pick: the chosen candidate's body
|
|
425
|
-
// (reasoning + tools + attachments + markdown), with a "Selected" affordance.
|
|
426
|
-
// role="status" only for an optimistic flip made this session.
|
|
427
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
428
|
-
|
|
429
|
-
function CollapsedWinner(props: {
|
|
430
|
-
candidate: CompareCandidate | undefined;
|
|
431
|
-
optimistic: boolean;
|
|
432
|
-
}): JSX.Element {
|
|
433
|
-
return (
|
|
434
|
-
<div
|
|
435
|
-
class="flex flex-col gap-2 rounded-lg border border-border bg-accent/40 p-3"
|
|
436
|
-
role={props.optimistic ? 'status' : undefined}
|
|
437
|
-
>
|
|
438
|
-
<div class="flex items-center gap-2 text-sm font-medium text-accent-foreground">
|
|
439
|
-
<Check size={16} aria-hidden="true" />
|
|
440
|
-
<span>Selected{props.candidate?.label ? `: ${props.candidate.label}` : ''}</span>
|
|
441
|
-
</div>
|
|
442
|
-
<Show when={props.candidate} fallback={<p class="text-sm text-muted-foreground">Response selected.</p>}>
|
|
443
|
-
{(c) => (
|
|
444
|
-
<div class="min-w-0">
|
|
445
|
-
<MessageBody
|
|
446
|
-
parts={candidateToParts(c())}
|
|
447
|
-
isUser={false}
|
|
448
|
-
markdown={true}
|
|
449
|
-
/>
|
|
450
|
-
</div>
|
|
451
|
-
)}
|
|
452
|
-
</Show>
|
|
453
|
-
</div>
|
|
454
|
-
);
|
|
455
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { splitProps, Show, For, createEffect, on } from 'solid-js';
|
|
2
|
-
import { Dynamic } from 'solid-js/web';
|
|
3
|
-
import { cn } from '../utils/cn';
|
|
4
|
-
import { useTextStream, defaultFadeDuration, defaultSegmentDelay } from '../primitives/use-text-stream';
|
|
5
|
-
|
|
6
|
-
export type Mode = 'typewriter' | 'fade';
|
|
7
|
-
|
|
8
|
-
export interface ResponseStreamProps {
|
|
9
|
-
textStream: string | AsyncIterable<string>;
|
|
10
|
-
mode?: Mode;
|
|
11
|
-
speed?: number;
|
|
12
|
-
class?: string;
|
|
13
|
-
onComplete?: () => void;
|
|
14
|
-
as?: string;
|
|
15
|
-
fadeDuration?: number;
|
|
16
|
-
segmentDelay?: number;
|
|
17
|
-
characterChunkSize?: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function ResponseStream(props: ResponseStreamProps) {
|
|
21
|
-
const [local] = splitProps(props, [
|
|
22
|
-
'textStream', 'mode', 'speed', 'class', 'onComplete',
|
|
23
|
-
'as', 'fadeDuration', 'segmentDelay', 'characterChunkSize',
|
|
24
|
-
]);
|
|
25
|
-
|
|
26
|
-
const mode = () => local.mode ?? 'typewriter';
|
|
27
|
-
const speed = () => local.speed ?? 20;
|
|
28
|
-
|
|
29
|
-
const stream = useTextStream({
|
|
30
|
-
mode: mode(),
|
|
31
|
-
speed: speed(),
|
|
32
|
-
characterChunkSize: local.characterChunkSize,
|
|
33
|
-
fadeDuration: local.fadeDuration,
|
|
34
|
-
segmentDelay: local.segmentDelay,
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
createEffect(on(
|
|
38
|
-
() => local.textStream,
|
|
39
|
-
(source) => {
|
|
40
|
-
if (source) stream.startStreaming(source);
|
|
41
|
-
}
|
|
42
|
-
));
|
|
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.
|
|
48
|
-
createEffect(on(
|
|
49
|
-
() => stream.isComplete(),
|
|
50
|
-
(complete) => {
|
|
51
|
-
if (complete) local.onComplete?.();
|
|
52
|
-
},
|
|
53
|
-
{ defer: true }
|
|
54
|
-
));
|
|
55
|
-
|
|
56
|
-
const fadeStyle = () => {
|
|
57
|
-
const dur = local.fadeDuration ?? defaultFadeDuration(speed());
|
|
58
|
-
return `
|
|
59
|
-
@keyframes fadeIn {
|
|
60
|
-
from { opacity: 0; }
|
|
61
|
-
to { opacity: 1; }
|
|
62
|
-
}
|
|
63
|
-
.fade-segment {
|
|
64
|
-
display: inline-block;
|
|
65
|
-
opacity: 0;
|
|
66
|
-
animation: fadeIn ${dur}ms ease-out forwards;
|
|
67
|
-
}
|
|
68
|
-
.fade-segment-space {
|
|
69
|
-
white-space: pre;
|
|
70
|
-
}
|
|
71
|
-
`;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const segDelay = () => {
|
|
75
|
-
if (typeof local.segmentDelay === 'number') return Math.max(0, local.segmentDelay);
|
|
76
|
-
return defaultSegmentDelay(speed());
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
<Dynamic component={local.as ?? 'div'} class={local.class}>
|
|
81
|
-
<Show
|
|
82
|
-
when={mode() === 'fade'}
|
|
83
|
-
fallback={<>{stream.displayedText()}</>}
|
|
84
|
-
>
|
|
85
|
-
<style>{fadeStyle()}</style>
|
|
86
|
-
<div class="relative">
|
|
87
|
-
<For each={stream.segments()}>
|
|
88
|
-
{(segment, idx) => {
|
|
89
|
-
const isWhitespace = () => /^\s+$/.test(segment.text);
|
|
90
|
-
return (
|
|
91
|
-
<span
|
|
92
|
-
class={cn(
|
|
93
|
-
'fade-segment',
|
|
94
|
-
isWhitespace() && 'fade-segment-space'
|
|
95
|
-
)}
|
|
96
|
-
style={{ 'animation-delay': `${idx() * segDelay()}ms` }}
|
|
97
|
-
>
|
|
98
|
-
{segment.text}
|
|
99
|
-
</span>
|
|
100
|
-
);
|
|
101
|
-
}}
|
|
102
|
-
</For>
|
|
103
|
-
</div>
|
|
104
|
-
</Show>
|
|
105
|
-
</Dynamic>
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export { ResponseStream };
|