@kitn.ai/ui 0.20.0 → 0.21.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 +44 -45
- package/dist/components/artifact-card.d.ts +51 -0
- package/dist/components/artifact.d.ts +1 -1
- package/dist/components/attachments.d.ts +2 -2
- package/dist/components/audio-visualizer/index.d.ts +3 -3
- package/dist/components/audio-visualizer/labs/lab-choreography.d.ts +59 -0
- package/dist/components/audio-visualizer/labs/lab-shaders.d.ts +22 -0
- package/dist/components/audio-visualizer/labs/lab-visualizer.d.ts +18 -0
- package/dist/components/audio-visualizer/variant-aurora.d.ts +2 -2
- package/dist/components/audio-visualizer/variant-bar.d.ts +2 -2
- package/dist/components/audio-visualizer/variant-custom.d.ts +2 -2
- package/dist/components/audio-visualizer/variant-grid.d.ts +1 -1
- package/dist/components/audio-visualizer/variant-radial.d.ts +1 -1
- package/dist/components/audio-visualizer/variant-wave.d.ts +1 -1
- package/dist/components/card-fallback.d.ts +12 -2
- package/dist/components/card-renderer.d.ts +63 -2
- package/dist/components/chat-container.d.ts +3 -0
- package/dist/components/chat-scope-picker.d.ts +2 -2
- package/dist/components/chat-thread.d.ts +68 -18
- package/dist/components/choice-card.d.ts +3 -28
- package/dist/components/composer-dom.d.ts +1 -1
- package/dist/components/composer-highlight.d.ts +1 -1
- package/dist/components/composer-history.d.ts +1 -1
- package/dist/components/composer.d.ts +1 -1
- package/dist/components/confirm-card.d.ts +3 -18
- package/dist/components/context.d.ts +8 -4
- package/dist/components/conversation-item.d.ts +1 -1
- package/dist/components/conversation-list.d.ts +4 -3
- package/dist/components/embed.d.ts +3 -3
- package/dist/components/file-tree.d.ts +11 -22
- package/dist/components/form-widgets.d.ts +1 -1
- package/dist/components/form.d.ts +3 -44
- package/dist/components/link-preview.d.ts +3 -3
- package/dist/components/loader.d.ts +30 -48
- package/dist/components/message-skills.d.ts +4 -0
- package/dist/components/message.d.ts +84 -21
- package/dist/components/model-switcher.d.ts +2 -2
- package/dist/components/prompt-input.d.ts +2 -2
- package/dist/components/response-compare-types.d.ts +11 -2
- package/dist/components/response-compare.d.ts +3 -3
- package/dist/components/source.d.ts +12 -3
- package/dist/components/tasks-card.d.ts +3 -31
- package/dist/components/thread.d.ts +17 -5
- package/dist/components/toast.d.ts +2 -2
- package/dist/components/tool-classify.d.ts +8 -0
- package/dist/components/tool-types.d.ts +29 -1
- package/dist/components/tool.d.ts +3 -3
- package/dist/components/use-card-resolution.d.ts +1 -1
- package/dist/create-tween-D3Y5qiij.js +338 -0
- package/dist/create-tween-DGKY1FDY.js +341 -0
- package/dist/create-tween-paho5Rh-.js +7 -0
- package/dist/custom-elements.json +1681 -454
- 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-types.d.ts +70 -10
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/chunks/{Icon-Tj58ES_d.js → Icon-C-2LvGDG.js} +1 -1
- package/dist/elements/chunks/{action-icons-ns1Fnedj.js → action-icons-CaYoImEk.js} +1 -1
- package/dist/elements/chunks/arrow-left-Bb46H7w9.js +1 -0
- package/dist/elements/chunks/artifact-BBIscOxJ.js +1 -0
- package/dist/elements/chunks/{attachments-mCB5F1Fq.js → attachments-BB56zoji.js} +1 -1
- package/dist/elements/chunks/audio-visualizer-BxOx4THz.js +1 -0
- package/dist/elements/chunks/{badge-B4Zuajl2.js → badge-SxLSZ19R.js} +1 -1
- package/dist/elements/chunks/{button-ZWNif3--.js → button-CmkUkz6c.js} +1 -1
- package/dist/elements/chunks/card-renderer-Db4ffkWv.js +1 -0
- package/dist/elements/chunks/card-tags-D8lZ-C_U.js +1 -0
- package/dist/elements/chunks/chat-thread-B3Ks-cKr.js +1 -0
- package/dist/elements/chunks/check-C8desc_h.js +1 -0
- package/dist/elements/chunks/chevron-down-DKtc2HNB.js +1 -0
- package/dist/elements/chunks/chevron-right-Dw4GPhwL.js +1 -0
- package/dist/elements/chunks/choice-card-Q9cYYDyM.js +1 -0
- package/dist/elements/chunks/circle-BeokBsvB.js +1 -0
- package/dist/elements/chunks/circle-check-wJSqt859.js +1 -0
- package/dist/elements/chunks/{circle-x-B7faJFlY.js → circle-x-D0MEfxOM.js} +1 -1
- package/dist/elements/chunks/code-block-C8VzAraE.js +1 -0
- package/dist/elements/chunks/{collapsible-DM1Ckd4e.js → collapsible-Cvj61obE.js} +1 -1
- package/dist/elements/chunks/{composer-BguS0QL_.js → composer-D86ztyL0.js} +2 -2
- package/dist/elements/chunks/confirm-card-BdyDAGLw.js +1 -0
- package/dist/elements/chunks/context-WHDl-xSx.js +1 -0
- package/dist/elements/chunks/conversation-list-CdR14_Y4.js +1 -0
- package/dist/elements/chunks/create-tween-C_A_B638.js +7 -0
- package/dist/elements/chunks/{default-input-Cqqilg9t.js → default-input-CSZqUM81.js} +1 -1
- package/dist/elements/chunks/define-BzPnNsXg.js +1 -0
- package/dist/elements/chunks/{disclosure-CIZ5c8nO.js → disclosure-DVKsoc1F.js} +1 -1
- package/dist/elements/chunks/{download-Dsbg3ste.js → download-BjA54IMJ.js} +1 -1
- package/dist/elements/chunks/{dropdown-BDd1-Zgi.js → dropdown-BjVVHWXH.js} +1 -1
- package/dist/elements/chunks/{ellipsis-Dw6qrss-.js → ellipsis-BNedmqfi.js} +1 -1
- package/dist/elements/chunks/embed-DQsl4XEq.js +1 -0
- package/dist/elements/chunks/{external-link-Vt74zAoL.js → external-link-Di-dw2CU.js} +1 -1
- package/dist/elements/chunks/{file-text-CZrZF6_v.js → file-text-B3sAODCV.js} +1 -1
- package/dist/elements/chunks/{file-tree-DF4okKyo.js → file-tree-Dgto-bMn.js} +1 -1
- package/dist/elements/chunks/{folder-glP5rha4.js → folder-D6rMadFV.js} +1 -1
- package/dist/elements/chunks/form-CILxvhQ7.js +1 -0
- package/dist/elements/chunks/hover-card-BtiF4XiU.js +1 -0
- package/dist/elements/chunks/{icon-BLb8beoi.js → icon-DKkmze3y.js} +1 -1
- package/dist/elements/chunks/{info-CIsv92JK.js → info-CWRjZkuy.js} +1 -1
- package/dist/elements/chunks/{input-Dds1kFyt.js → input--QJBK6BA.js} +1 -1
- package/dist/elements/chunks/{kbd-De_xbgi9.js → kbd-C3zuKh8R.js} +1 -1
- package/dist/elements/chunks/{link-i4r_k7z4.js → link-BL5JA7Q0.js} +1 -1
- package/dist/elements/chunks/link-preview-CU37bbXh.js +1 -0
- package/dist/elements/chunks/{loader-BmQH4s3V.js → loader-XmpyxyRH.js} +1 -1
- package/dist/elements/chunks/{markdown-Zi21WhUz.js → markdown-3Gv5UZ_o.js} +1 -1
- package/dist/elements/chunks/message-CnBA2OUt.js +1 -0
- package/dist/elements/chunks/message-X5NZbq-W.js +1 -0
- package/dist/elements/chunks/message-square-CnpAm_P0.js +1 -0
- package/dist/elements/chunks/{minimize-2--ifeCGrl.js → minimize-2-DwyrUTcM.js} +1 -1
- package/dist/elements/chunks/{model-switcher-B94YAKsM.js → model-switcher-CclaJEHt.js} +1 -1
- package/dist/elements/chunks/{overlay-kD8dwRv_.js → overlay-Cepd-KcS.js} +1 -1
- package/dist/elements/chunks/{paperclip-q21dYOSK.js → paperclip-CdwKjrlu.js} +1 -1
- package/dist/elements/chunks/{progress-bar-BrAIIaaJ.js → progress-bar-DMVXBD3b.js} +1 -1
- package/dist/elements/chunks/{prompt-suggestion-Bjn2K-fR.js → prompt-suggestion-Di_WZE_5.js} +1 -1
- package/dist/elements/chunks/reasoning-D0jMch5u.js +1 -0
- package/dist/elements/chunks/{resizable-Dp4JExql.js → resizable-1znbL1Gv.js} +1 -1
- package/dist/elements/chunks/{rotate-cw-CFWWkpj2.js → rotate-cw-DVhhgx8n.js} +1 -1
- package/dist/elements/chunks/{scroll-area-Bb0kHH1j.js → scroll-area-Bs4bFS1P.js} +1 -1
- package/dist/elements/chunks/scroll-button-Bet5NLc4.js +1 -0
- package/dist/elements/chunks/{separator-9kRgr1X9.js → separator-C5Gh8qGC.js} +1 -1
- package/dist/elements/chunks/{settings-B8lmec4D.js → settings-5vmEFg0K.js} +1 -1
- package/dist/elements/chunks/{settings-group-I0hEuXiN.js → settings-group-BWLB38kz.js} +1 -1
- package/dist/elements/chunks/{share-C3lTiYGt.js → share-BZ3G_DaB.js} +1 -1
- package/dist/elements/chunks/skeleton-DafPJQTp.js +1 -0
- package/dist/elements/chunks/slots-CIw9RlAe.js +1 -0
- package/dist/elements/chunks/source-D_qj_6uJ.js +1 -0
- package/dist/elements/chunks/{star-CSJtGxgv.js → star-Cuv7j2IE.js} +1 -1
- package/dist/elements/chunks/{store-CHyW95TP.js → store-C1StPHfW.js} +1 -1
- package/dist/elements/chunks/tasks-card-EyoBZfpA.js +1 -0
- package/dist/elements/chunks/{text-shimmer-Cn9TmNpI.js → text-shimmer-D9gRSh34.js} +1 -1
- package/dist/elements/chunks/textarea-DuhtHfcm.js +1 -0
- package/dist/elements/chunks/{thumbs-up-PNVVThEF.js → thumbs-up-B9hwv43w.js} +1 -1
- package/dist/elements/chunks/{toast-store-DKbQn3Wn.js → toast-store-Bm3DUEDe.js} +1 -1
- package/dist/elements/chunks/{tool-DjTRpIpl.js → tool-CDtW7L0z.js} +1 -1
- package/dist/elements/chunks/tooltip-eB226mGK.js +1 -0
- package/dist/elements/chunks/{triangle-alert-DsHTHCPm.js → triangle-alert-C1SNzTqK.js} +1 -1
- package/dist/elements/chunks/use-card-resolution-YZh2MvI5.js +1 -0
- package/dist/elements/chunks/{variant-aurora-Dc4nQUia.js → variant-aurora-Cj1F7D0l.js} +2 -2
- package/dist/elements/chunks/{variant-custom-y_3kVQhS.js → variant-custom-T9gpt7QE.js} +1 -1
- package/dist/elements/chunks/{variant-wave-D5OR1-9Z.js → variant-wave-CxU9z-TE.js} +2 -2
- package/dist/elements/chunks/{video-B7vmenoC.js → video-CK4R7Rus.js} +1 -1
- package/dist/elements/chunks/x-D1qx0aLd.js +1 -0
- 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-list.js +1 -1
- package/dist/elements/default-input.d.ts +7 -7
- package/dist/elements/define.d.ts +1 -0
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/disclosure.d.ts +1 -1
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/element-data-types.d.ts +107 -0
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.js +1 -1
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-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/reasoning.js +1 -1
- package/dist/elements/register.d.ts +8 -6
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +2 -2
- 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/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/slots.d.ts +16 -0
- 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/validate-messages.d.ts +25 -0
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/elements.d.ts +2725 -214
- package/dist/index.d.ts +163 -125
- package/dist/index.js +6336 -5802
- package/dist/index.server.d.ts +5 -0
- package/dist/index.server.js +16913 -0
- package/dist/kai-provider.es.d.ts +5 -0
- package/dist/kai-provider.es.js +79 -77
- package/dist/kai.es.d.ts +5 -0
- package/dist/kai.es.js +1 -1
- package/dist/llms/llms-full.txt +762 -148
- package/dist/llms/llms.txt +57 -5
- package/dist/mcp.es.js +4010 -770
- package/dist/primitives/card-component-types.d.ts +11 -0
- package/dist/primitives/card-data-types.d.ts +196 -0
- package/dist/primitives/card-host.d.ts +1 -1
- package/dist/primitives/card-recovery.d.ts +3 -3
- package/dist/primitives/card-registry.d.ts +4 -14
- package/dist/primitives/card-resolution.d.ts +1 -1
- package/dist/primitives/card-routing.d.ts +1 -1
- package/dist/primitives/card-tags.d.ts +11 -0
- package/dist/primitives/card-validate-cards.d.ts +57 -0
- package/dist/primitives/card-validate-generator.testlib.d.ts +20 -0
- package/dist/primitives/card-validate-schemas.d.ts +17 -0
- package/dist/primitives/card-validate.d.ts +24 -0
- package/dist/primitives/create-kai-chat.d.ts +3 -3
- package/dist/primitives/embed-providers.d.ts +1 -1
- package/dist/primitives/link-preview.d.ts +1 -1
- package/dist/primitives/message-feedback.d.ts +2 -2
- package/dist/primitives/toast-store.d.ts +1 -1
- package/dist/react/index.d.ts +717 -299
- package/dist/react/use-kai-chat.d.ts +8 -4
- package/dist/react.d.ts +5 -0
- package/dist/react.js +417 -316
- package/dist/register-impl-bzrZ44ft.js +145 -0
- package/dist/remote/host-embed.d.ts +1 -1
- package/dist/remote/index.d.ts +2 -2
- package/dist/remote/provider-runtime.d.ts +2 -2
- package/dist/remote/provider.d.ts +2 -2
- package/dist/remote/validate.d.ts +1 -1
- package/dist/remote/wire.d.ts +1 -1
- package/dist/schemas/artifact.schema.json +92 -0
- package/dist/schemas/embed.schema.json +0 -2
- package/dist/schemas/from-tool-call.d.ts +48 -0
- package/dist/schemas/index.d.ts +48 -0
- package/dist/schemas/link.schema.json +0 -2
- package/dist/schemas/provider-subsets.d.ts +136 -0
- package/dist/schemas/registry.d.ts +140 -0
- package/dist/schemas/tool-defs.d.ts +121 -0
- package/dist/schemas.d.ts +5 -0
- package/dist/schemas.js +717 -0
- package/dist/solid-BCJUQqwS.js +22750 -0
- package/dist/solid-BdENBcEq.js +20108 -0
- package/dist/solid.d.ts +66 -0
- package/dist/solid.js +261 -0
- package/dist/solid.server.d.ts +5 -0
- package/dist/solid.server.js +261 -0
- package/dist/state/index.d.ts +14 -4
- package/dist/state/messages.d.ts +8 -3
- package/dist/state/mock.d.ts +46 -0
- package/dist/state/parts.d.ts +85 -0
- package/dist/state/stream.d.ts +15 -9
- package/dist/state.d.ts +5 -0
- package/dist/state.js +253 -84
- package/dist/ui/action-icons.d.ts +1 -1
- package/dist/ui/collapsible.d.ts +11 -6
- package/dist/ui/dropdown.d.ts +47 -42
- package/dist/ui/pane-group.d.ts +1 -1
- package/dist/variant-aurora-1wMcXRUS.js +381 -0
- package/dist/variant-aurora-BKHHiOgL.js +391 -0
- package/dist/{variant-aurora-DVtGqVH6.js → variant-aurora-DOb_o4pC.js} +1 -1
- package/dist/{variant-custom-Dif-IV4u.js → variant-custom-CJGB0Kbw.js} +1 -1
- package/dist/variant-custom-Co0CkXJF.js +200 -0
- package/dist/variant-custom-DWSSgmd2.js +170 -0
- package/dist/variant-wave-C3-45cL6.js +218 -0
- package/dist/{variant-wave-DbfNdvSi.js → variant-wave-CEODq-9q.js} +1 -1
- package/dist/variant-wave-jdXBnCUZ.js +208 -0
- package/dist/wire/chunk.d.ts +171 -0
- package/dist/wire/consume.d.ts +26 -0
- package/dist/wire/encode.d.ts +148 -0
- package/dist/wire/formats/anthropic.d.ts +2 -0
- package/dist/wire/formats/openai.d.ts +5 -0
- package/dist/wire/index.d.ts +14 -0
- package/dist/wire/read.d.ts +26 -0
- package/dist/wire/sink-helpers.d.ts +21 -0
- package/dist/wire/sse.d.ts +33 -0
- package/dist/wire.d.ts +5 -53
- package/dist/wire.js +898 -0
- package/frameworks/react/index.tsx +183 -154
- package/frameworks/react/runtime.tsx +21 -1
- package/frameworks/react/use-kai-chat.tsx +11 -1
- package/llms-full.txt +762 -148
- package/llms.txt +57 -5
- package/package.json +65 -7
- package/src/agent-tooling/archetypes.ts +96 -0
- package/src/agent-tooling/integrations/anthropic.ts +412 -0
- package/src/agent-tooling/integrations/cloudflare.ts +136 -52
- package/src/agent-tooling/integrations/langgraph.ts +67 -13
- package/src/agent-tooling/integrations/mastra.ts +120 -12
- package/src/agent-tooling/integrations/mock.ts +43 -8
- package/src/agent-tooling/integrations/ollama.ts +61 -24
- package/src/agent-tooling/integrations/openai.ts +87 -0
- package/src/agent-tooling/integrations/openrouter.ts +56 -8
- package/src/agent-tooling/integrations/pi.ts +79 -23
- package/src/agent-tooling/integrations/pydantic-ai.ts +24 -2
- package/src/agent-tooling/integrations/vercel-ai-sdk.ts +84 -13
- package/src/agent-tooling/mcp/manifest.ts +206 -25
- package/src/agent-tooling/mcp/tools/debug.ts +13 -7
- package/src/agent-tooling/mcp/tools/reference.ts +285 -6
- package/src/agent-tooling/mcp/tools/scaffold.ts +3345 -675
- package/src/agent-tooling/registry.ts +17 -0
- package/src/agent-tooling/types.ts +229 -1
- package/src/components/artifact-card.tsx +120 -0
- package/src/components/audio-visualizer/index.tsx +9 -0
- package/src/components/audio-visualizer/labs/lab-choreography.ts +187 -0
- package/src/components/audio-visualizer/labs/lab-shaders.ts +363 -0
- package/src/components/audio-visualizer/labs/lab-visualizer.tsx +102 -0
- package/src/components/audio-visualizer/shader-canvas.tsx +31 -1
- package/src/components/card-fallback.tsx +42 -10
- package/src/components/card-renderer.tsx +146 -9
- package/src/components/chat-container.tsx +4 -0
- package/src/components/chat-thread.tsx +118 -51
- package/src/components/choice-card.tsx +17 -29
- package/src/components/composer.tsx +12 -2
- package/src/components/confirm-card.tsx +24 -20
- package/src/components/context.tsx +12 -4
- package/src/components/conversation-list.tsx +18 -2
- package/src/components/file-tree.tsx +11 -22
- package/src/components/file-upload.tsx +14 -8
- package/src/components/form.tsx +14 -47
- package/src/components/loader.tsx +39 -12
- package/src/components/message-skills.tsx +4 -0
- package/src/components/message.tsx +294 -46
- package/src/components/reasoning.tsx +92 -5
- package/src/components/response-compare-types.ts +25 -0
- package/src/components/response-compare.tsx +4 -9
- package/src/components/source.tsx +50 -24
- package/src/components/tasks-card.tsx +10 -33
- package/src/components/thread.tsx +84 -42
- package/src/components/toast.tsx +11 -5
- package/src/components/tool-classify.ts +26 -0
- package/src/components/tool-types.ts +31 -1
- package/src/elements/agent-card.tsx +11 -11
- package/src/elements/artifact.tsx +15 -7
- package/src/elements/attachments.tsx +6 -4
- package/src/elements/avatar.tsx +1 -1
- package/src/elements/button.tsx +3 -3
- package/src/elements/card.tsx +2 -2
- package/src/elements/cards.tsx +109 -14
- package/src/elements/chain-of-thought.tsx +14 -10
- package/src/elements/chat-scope-picker.tsx +9 -7
- package/src/elements/chat-types.ts +59 -6
- package/src/elements/chat-workspace.tsx +50 -9
- package/src/elements/chat.tsx +64 -3
- package/src/elements/choice.tsx +8 -8
- package/src/elements/coachmark.tsx +1 -1
- package/src/elements/command.tsx +8 -23
- package/src/elements/compare.tsx +7 -6
- package/src/elements/compiled.css +1 -1
- package/src/elements/composer.tsx +8 -8
- package/src/elements/confirm-card.tsx +9 -9
- package/src/elements/context-meter.tsx +4 -18
- package/src/elements/conversation-list.tsx +14 -9
- package/src/elements/default-input.tsx +3 -3
- package/src/elements/define.tsx +178 -43
- package/src/elements/editable-label.tsx +17 -2
- package/src/elements/element-data-types.ts +112 -0
- package/src/elements/element-meta.json +1596 -304
- package/src/elements/element-types.d.ts +2636 -211
- package/src/elements/feedback-bar.tsx +1 -1
- package/src/elements/file-tree.tsx +1 -1
- package/src/elements/file-upload.tsx +1 -1
- package/src/elements/form.tsx +14 -6
- package/src/elements/input.tsx +1 -1
- package/src/elements/kbd.tsx +1 -1
- package/src/elements/menu.tsx +10 -29
- package/src/elements/message-skills.tsx +7 -9
- package/src/elements/message.tsx +200 -32
- package/src/elements/model-switcher.tsx +5 -3
- package/src/elements/pane.tsx +1 -1
- package/src/elements/prompt-dock.tsx +8 -8
- package/src/elements/prompt-input.tsx +10 -10
- package/src/elements/prompt-suggestions.tsx +7 -4
- package/src/elements/reasoning.tsx +1 -1
- package/src/elements/register.ts +9 -0
- package/src/elements/resizable.globals.d.ts +36 -0
- package/src/elements/resizable.tsx +24 -13
- package/src/elements/response-stream.tsx +1 -1
- package/src/elements/scroll-button.tsx +1 -1
- package/src/elements/search.tsx +6 -1
- package/src/elements/segmented.tsx +5 -11
- package/src/elements/separator.tsx +1 -1
- package/src/elements/slots.ts +57 -24
- package/src/elements/source.tsx +21 -22
- package/src/elements/switch.tsx +3 -3
- package/src/elements/tasks.tsx +5 -4
- package/src/elements/thread.tsx +36 -4
- package/src/elements/toast.tsx +3 -2
- package/src/elements/tool.tsx +1 -1
- package/src/elements/validate-messages.ts +76 -0
- package/src/elements/voice-input.tsx +7 -7
- package/src/elements/voice-output.tsx +4 -4
- package/src/index.ts +141 -6
- package/src/primitives/card-component-types.ts +63 -0
- package/src/primitives/card-data-types.ts +312 -0
- package/src/primitives/card-recovery.ts +13 -2
- package/src/primitives/card-registry.tsx +34 -23
- package/src/primitives/card-schemas/artifact.schema.json +92 -0
- package/src/primitives/card-schemas/embed.schema.json +0 -2
- package/src/primitives/card-schemas/link.schema.json +0 -2
- package/src/primitives/card-tags.ts +61 -0
- package/src/primitives/card-validate-cards.ts +255 -0
- package/src/primitives/card-validate-generator.testlib.ts +38 -0
- package/src/primitives/card-validate-schemas.ts +58 -0
- package/src/primitives/card-validate.ts +48 -20
- package/src/primitives/create-tween.ts +54 -2
- package/src/primitives/message-feedback.ts +3 -2
- package/src/primitives/use-audio-analysis.ts +20 -1
- package/src/primitives/use-sequencer.ts +20 -1
- package/src/schemas/from-tool-call.ts +151 -0
- package/src/schemas/index.ts +340 -0
- package/src/schemas/provider-subsets.ts +538 -0
- package/src/schemas/registry.ts +355 -0
- package/src/schemas/tool-defs.ts +492 -0
- package/src/solid.ts +150 -0
- package/src/state/index.ts +27 -1
- package/src/state/messages.ts +21 -4
- package/src/state/mock.ts +211 -0
- package/src/state/parts.ts +295 -0
- package/src/state/stream.ts +56 -58
- package/src/ui/collapsible.tsx +17 -5
- package/src/ui/dropdown.tsx +46 -12
- package/src/ui/overlay.tsx +10 -4
- package/src/wire/chunk.ts +201 -0
- package/src/wire/consume.ts +440 -0
- package/src/wire/encode.ts +474 -0
- package/src/wire/formats/anthropic.ts +267 -0
- package/src/wire/formats/openai.ts +187 -0
- package/src/wire/index.ts +52 -0
- package/src/wire/read.ts +152 -0
- package/src/wire/sink-helpers.ts +50 -0
- package/src/wire/sse.ts +140 -0
- package/dist/create-tween-hvpmSuwW.js +0 -7
- package/dist/elements/chunks/arrow-left-DQocUFvy.js +0 -1
- package/dist/elements/chunks/audio-visualizer-BqNy7dfm.js +0 -1
- package/dist/elements/chunks/card-BkHbp4BA.js +0 -1
- package/dist/elements/chunks/chat-thread-CkRN6pZ7.js +0 -1
- package/dist/elements/chunks/check-B9-gn6SS.js +0 -1
- package/dist/elements/chunks/chevron-down-BNsxc2hk.js +0 -1
- package/dist/elements/chunks/chevron-right-Hv00StBO.js +0 -1
- package/dist/elements/chunks/circle-0e3KJTDr.js +0 -1
- package/dist/elements/chunks/circle-check-BNAS0JEy.js +0 -1
- package/dist/elements/chunks/code-block-BFUHn6Va.js +0 -1
- package/dist/elements/chunks/context-Cb7k4F-v.js +0 -1
- package/dist/elements/chunks/conversation-list-CvoAkWhN.js +0 -1
- package/dist/elements/chunks/create-tween-oVvAIG8r.js +0 -7
- package/dist/elements/chunks/define-D1din7Ld.js +0 -1
- package/dist/elements/chunks/hover-card-Cmm6Q53m.js +0 -1
- package/dist/elements/chunks/message-BqyXDN3-.js +0 -1
- package/dist/elements/chunks/message-feedback-Djr3z6Yb.js +0 -1
- package/dist/elements/chunks/message-square-vFAgbDaX.js +0 -1
- package/dist/elements/chunks/reasoning-DTpCGtnY.js +0 -1
- package/dist/elements/chunks/scroll-button-B0cH5fXf.js +0 -1
- package/dist/elements/chunks/skeleton-DSXW5Yya.js +0 -1
- package/dist/elements/chunks/slots--V19HwUb.js +0 -1
- package/dist/elements/chunks/textarea-CUwqAX0G.js +0 -1
- package/dist/elements/chunks/tooltip-CgBZCVKp.js +0 -1
- package/dist/elements/chunks/use-card-resolution-BSu_XHjH.js +0 -1
- package/dist/elements/chunks/x-GRUeeQFT.js +0 -1
- package/dist/host-embed.d.ts +0 -33
- package/dist/kai-provider.d.ts +0 -2
- package/dist/origin.d.ts +0 -5
- package/dist/provider-runtime.d.ts +0 -27
- package/dist/register-impl-DQyejdfb.js +0 -145
- package/dist/validate.d.ts +0 -4
- package/dist/version.d.ts +0 -4
- package/src/components/component-meta.json +0 -4550
- package/src/elements/card-media.jpg +0 -0
- package/src/elements/resizable.d.ts +0 -27
- package/src/elements/video-poster.jpg +0 -0
|
@@ -20,21 +20,29 @@ function useSourceContext() {
|
|
|
20
20
|
// --- Source (Root) ---
|
|
21
21
|
|
|
22
22
|
export interface SourceProps {
|
|
23
|
-
|
|
23
|
+
/** The citation's URL. OPTIONAL: every field of a model-produced citation is,
|
|
24
|
+
* so a source can arrive with a title and no url. In that case the chip
|
|
25
|
+
* renders as a plain, inert `<a>` with NO `href` attribute — which is valid
|
|
26
|
+
* HTML and simply not a link — rather than `<a href="">`, which would
|
|
27
|
+
* navigate to the current page. */
|
|
28
|
+
href?: string;
|
|
24
29
|
children: JSX.Element;
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
function Source(props: SourceProps) {
|
|
33
|
+
const href = () => props.href ?? '';
|
|
28
34
|
const domain = () => {
|
|
35
|
+
const h = href();
|
|
36
|
+
if (!h) return '';
|
|
29
37
|
try {
|
|
30
|
-
return new URL(
|
|
38
|
+
return new URL(h).hostname;
|
|
31
39
|
} catch {
|
|
32
|
-
return
|
|
40
|
+
return h.split('/').pop() || h;
|
|
33
41
|
}
|
|
34
42
|
};
|
|
35
43
|
|
|
36
44
|
return (
|
|
37
|
-
<SourceContext.Provider value={{ get href() { return
|
|
45
|
+
<SourceContext.Provider value={{ get href() { return href(); }, get domain() { return domain(); } }}>
|
|
38
46
|
<HoverCardRoot openDelay={150}>
|
|
39
47
|
{props.children}
|
|
40
48
|
</HoverCardRoot>
|
|
@@ -57,7 +65,8 @@ function SourceTrigger(props: SourceTriggerProps) {
|
|
|
57
65
|
return (
|
|
58
66
|
<HoverCardTrigger>
|
|
59
67
|
<a
|
|
60
|
-
href
|
|
68
|
+
// `undefined` OMITS the attribute — see SourceProps.href.
|
|
69
|
+
href={ctx.href || undefined}
|
|
61
70
|
target="_blank"
|
|
62
71
|
rel="noopener noreferrer"
|
|
63
72
|
class={cn(
|
|
@@ -66,7 +75,8 @@ function SourceTrigger(props: SourceTriggerProps) {
|
|
|
66
75
|
props.class
|
|
67
76
|
)}
|
|
68
77
|
>
|
|
69
|
-
|
|
78
|
+
{/* No url, no favicon to look up. */}
|
|
79
|
+
<Show when={props.showFavicon && ctx.href}>
|
|
70
80
|
<img
|
|
71
81
|
src={`https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(ctx.href)}`}
|
|
72
82
|
alt="favicon"
|
|
@@ -94,27 +104,35 @@ function SourceContent(props: SourceContentProps) {
|
|
|
94
104
|
return (
|
|
95
105
|
<HoverCardContent class={cn('w-80 p-0 shadow-xs', props.class)}>
|
|
96
106
|
<a
|
|
97
|
-
href
|
|
107
|
+
// `undefined` OMITS the attribute — see SourceProps.href.
|
|
108
|
+
href={ctx.href || undefined}
|
|
98
109
|
target="_blank"
|
|
99
110
|
rel="noopener noreferrer"
|
|
100
111
|
class="flex flex-col gap-2 p-3"
|
|
101
112
|
>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
113
|
+
{/* The domain header row only means anything when there IS a url. */}
|
|
114
|
+
<Show when={ctx.href}>
|
|
115
|
+
<div class="flex items-center gap-1.5">
|
|
116
|
+
<img
|
|
117
|
+
src={`https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(ctx.href)}`}
|
|
118
|
+
alt="favicon"
|
|
119
|
+
class="size-4 rounded-full"
|
|
120
|
+
width={16}
|
|
121
|
+
height={16}
|
|
122
|
+
/>
|
|
123
|
+
<div class="text-primary truncate text-sm">
|
|
124
|
+
{ctx.domain.replace('www.', '')}
|
|
125
|
+
</div>
|
|
112
126
|
</div>
|
|
113
|
-
</
|
|
114
|
-
<
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
127
|
+
</Show>
|
|
128
|
+
<Show when={props.title}>
|
|
129
|
+
<div class="line-clamp-2 text-sm font-medium">{props.title}</div>
|
|
130
|
+
</Show>
|
|
131
|
+
<Show when={props.description}>
|
|
132
|
+
<div class="text-muted-foreground line-clamp-2 text-sm">
|
|
133
|
+
{props.description}
|
|
134
|
+
</div>
|
|
135
|
+
</Show>
|
|
118
136
|
</a>
|
|
119
137
|
</HoverCardContent>
|
|
120
138
|
);
|
|
@@ -122,8 +140,16 @@ function SourceContent(props: SourceContentProps) {
|
|
|
122
140
|
|
|
123
141
|
// --- SourceList (convenience) ---
|
|
124
142
|
|
|
125
|
-
|
|
126
|
-
|
|
143
|
+
export interface SourceListProps {
|
|
144
|
+
children: JSX.Element;
|
|
145
|
+
class?: string;
|
|
146
|
+
/** `::part` name(s) exposed on the row. The message body passes `"citations"`
|
|
147
|
+
* so consumers can target the citation row from outside the shadow boundary. */
|
|
148
|
+
part?: string;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function SourceList(props: SourceListProps) {
|
|
152
|
+
return <div part={props.part} class={cn('flex flex-wrap gap-1.5 mt-3', props.class)}>{props.children}</div>;
|
|
127
153
|
}
|
|
128
154
|
|
|
129
155
|
export { Source, SourceTrigger, SourceContent, SourceList };
|
|
@@ -24,42 +24,19 @@ import { useCardHost } from '../primitives/card-host';
|
|
|
24
24
|
import { Check, Circle, CircleCheck, X } from 'lucide-solid';
|
|
25
25
|
|
|
26
26
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
27
|
-
// Types (tasks.schema.json) —
|
|
27
|
+
// Types (tasks.schema.json) — AUTHORED IN ../primitives/card-data-types.ts.
|
|
28
|
+
// See the note in confirm-card.tsx, or that file's header, for why they left a
|
|
29
|
+
// `.tsx` and why they are `type` aliases. Re-exported here unchanged.
|
|
28
30
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
id: string;
|
|
32
|
-
label: string;
|
|
33
|
-
description?: string;
|
|
34
|
-
checked?: boolean;
|
|
35
|
-
disabled?: boolean;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface TasksCardData {
|
|
39
|
-
/**
|
|
40
|
-
* `select` (default) = checkbox rows + a confirm button that emits the contract
|
|
41
|
-
* `submit`. `progress` = an onboarding/checklist look: a header `done / total`
|
|
42
|
-
* count, circular indicators, per-item title + muted description, and NO confirm
|
|
43
|
-
* button (checking a row is itself the terminal action). Both share the same
|
|
44
|
-
* selection model (toggle by id, the `max` gate, `kai-value-change`); `progress`
|
|
45
|
-
* is purely a presentational variant.
|
|
46
|
-
*/
|
|
47
|
-
mode?: 'select' | 'progress';
|
|
48
|
-
heading?: string;
|
|
49
|
-
tasks: TasksTask[]; // >=1
|
|
50
|
-
selectAll?: boolean;
|
|
51
|
-
confirmLabel?: string;
|
|
52
|
-
allowEmpty?: boolean;
|
|
53
|
-
min?: number;
|
|
54
|
-
max?: number;
|
|
55
|
-
dismissible?: boolean; // show a close affordance that emits `dismiss`
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface TasksCardResult {
|
|
59
|
-
selected: string[];
|
|
60
|
-
}
|
|
32
|
+
import type { TasksCardData, TasksCardResult, TasksTask } from '../primitives/card-data-types';
|
|
61
33
|
|
|
62
|
-
export type
|
|
34
|
+
export type {
|
|
35
|
+
TasksCardData,
|
|
36
|
+
TasksCardEnvelope,
|
|
37
|
+
TasksCardResult,
|
|
38
|
+
TasksTask,
|
|
39
|
+
} from '../primitives/card-data-types';
|
|
63
40
|
|
|
64
41
|
export const TASKS_CARD_TYPE = 'tasks' as const;
|
|
65
42
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { For, Show, onMount, type JSX } from 'solid-js';
|
|
1
|
+
import { For, Show, createMemo, onMount, type JSX } from 'solid-js';
|
|
2
2
|
import { ChatConfig, useChatConfig } from '../primitives/chat-config';
|
|
3
3
|
import { ChatContainer, ChatContainerContent, ChatContainerScrollAnchor } from './chat-container';
|
|
4
4
|
import { Message, MessageAvatar, MessageBody } from './message';
|
|
@@ -7,6 +7,8 @@ import { ScrollButton } from './scroll-button';
|
|
|
7
7
|
import { Loader } from './loader';
|
|
8
8
|
import type { ChatMessage } from '../elements/chat-types';
|
|
9
9
|
import type { ProseSize } from '../primitives/chat-config';
|
|
10
|
+
import type { CardComponentMap } from '../primitives/card-registry';
|
|
11
|
+
import type { CardSchemaMap } from './card-renderer';
|
|
10
12
|
|
|
11
13
|
/** Imperative handle exposed via `controllerRef` — the thread's scroll control,
|
|
12
14
|
* forwarded onto `<kai-thread>` as the `scrollToBottom()` instance method. */
|
|
@@ -19,9 +21,19 @@ export interface ThreadProps {
|
|
|
19
21
|
/** Extra classes for the thread root (e.g. `rounded-xl`). */
|
|
20
22
|
class?: string;
|
|
21
23
|
/** The full message thread to render, newest last. Each entry carries its role,
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
+
* ordered `parts`, and optional actions/avatar/feedback. A new array reference
|
|
25
|
+
* per streaming chunk re-renders (mutating in place does not). */
|
|
24
26
|
messages: ChatMessage[];
|
|
27
|
+
/** Add/override card type -> component entries, forwarded to `CardRenderer`
|
|
28
|
+
* for `card` parts. */
|
|
29
|
+
cardTypes?: CardComponentMap;
|
|
30
|
+
/** JSON Schemas for the card types this app renders, keyed by envelope type,
|
|
31
|
+
* forwarded to `CardRenderer` for `card` parts. The companion of `cardTypes`:
|
|
32
|
+
* that says what DRAWS a card, this says what a VALID one looks like.
|
|
33
|
+
* `createCardRegistry(...).validationSchemas` is exactly this shape. Without it
|
|
34
|
+
* the kit checks its own seven built-ins and leaves your own card type
|
|
35
|
+
* unvalidated. A schema here WINS over a built-in of the same name. */
|
|
36
|
+
cardSchemas?: CardSchemaMap;
|
|
25
37
|
/** Show a typing indicator on the pending assistant turn — use while awaiting
|
|
26
38
|
* the assistant's reply. */
|
|
27
39
|
loading?: boolean;
|
|
@@ -85,6 +97,11 @@ export function Thread(props: ThreadProps) {
|
|
|
85
97
|
});
|
|
86
98
|
const showScrollButton = () => props.scrollButton !== false;
|
|
87
99
|
const showEmpty = () => props.messages.length === 0 && !props.loading;
|
|
100
|
+
// Keyed by message id, NOT by object reference: a streaming message is a new
|
|
101
|
+
// object every delta, and a reference-keyed <For> rebuilds the whole row for
|
|
102
|
+
// each one — which is why expanding a tool/reasoning panel mid-stream used to
|
|
103
|
+
// do nothing. Full rationale (and why not `<Index>`) in `chat-thread.tsx`.
|
|
104
|
+
const messageKeys = createMemo(() => props.messages.map((m) => m.id));
|
|
88
105
|
|
|
89
106
|
// Hand the imperative controller to the facade once mounted (rootEl is set).
|
|
90
107
|
onMount(() => {
|
|
@@ -116,46 +133,71 @@ export function Thread(props: ThreadProps) {
|
|
|
116
133
|
{props.empty}
|
|
117
134
|
</Show>
|
|
118
135
|
</Show>
|
|
119
|
-
<For each={
|
|
120
|
-
{(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
136
|
+
<For each={messageKeys()}>
|
|
137
|
+
{(_id, i) => (
|
|
138
|
+
// Read the message through <For>'s index accessor, never through
|
|
139
|
+
// a captured value — the row outlives the delta that replaced its
|
|
140
|
+
// object. <Show> supplies the non-null accessor and covers the
|
|
141
|
+
// frame where a removal has shortened the array.
|
|
142
|
+
<Show when={props.messages[i()]}>
|
|
143
|
+
{(m) => {
|
|
144
|
+
const body = (
|
|
145
|
+
<MessageBody
|
|
146
|
+
parts={m().parts}
|
|
147
|
+
cardTypes={props.cardTypes}
|
|
148
|
+
cardSchemas={props.cardSchemas}
|
|
149
|
+
isUser={m().role === 'user'}
|
|
150
|
+
markdown={m().role === 'assistant'}
|
|
151
|
+
actions={m().actions}
|
|
152
|
+
actionsReveal={reveal()}
|
|
153
|
+
activeFeedback={feedback.resolveFeedback(m())}
|
|
154
|
+
copied={feedback.isCopied(m().id)}
|
|
155
|
+
onAction={(action) => feedback.handleAction(m(), action)}
|
|
156
|
+
/>
|
|
157
|
+
);
|
|
158
|
+
const rowGroup = () => (reveal() === 'hover' ? 'group ' : '');
|
|
159
|
+
return (
|
|
160
|
+
// `role` is the SPEAKER, and it has to be forwarded on BOTH
|
|
161
|
+
// branches. `Message` turns it into `role="article"` + an
|
|
162
|
+
// `aria-label` naming the speaker; without it the row is a
|
|
163
|
+
// bare div that chromium prunes from the accessibility tree
|
|
164
|
+
// as "uninteresting", so a screen reader gets no speaker at
|
|
165
|
+
// all. Every other read of `m().role` here is cosmetic
|
|
166
|
+
// (alignment, markdown), which is exactly how it went
|
|
167
|
+
// missing: the value was in hand and used for styling while
|
|
168
|
+
// being dropped for semantics.
|
|
169
|
+
<Show
|
|
170
|
+
when={m().avatar}
|
|
171
|
+
fallback={
|
|
172
|
+
<Message role={m().role} class={`${rowGroup()}${m().role === 'user' ? 'flex-col items-end' : 'flex-col items-start'}`}>
|
|
173
|
+
{body}
|
|
174
|
+
</Message>
|
|
175
|
+
}
|
|
176
|
+
>
|
|
177
|
+
{(av) => (
|
|
178
|
+
<Message role={m().role} class={rowGroup()}>
|
|
179
|
+
<MessageAvatar src={av().src ?? ''} alt={av().alt ?? ''} fallback={av().fallback} />
|
|
180
|
+
<div class={`flex min-w-0 flex-1 flex-col ${m().role === 'user' ? 'items-end' : 'items-start'}`}>
|
|
181
|
+
{body}
|
|
182
|
+
</div>
|
|
183
|
+
</Message>
|
|
184
|
+
)}
|
|
185
|
+
</Show>
|
|
186
|
+
);
|
|
187
|
+
}}
|
|
188
|
+
</Show>
|
|
189
|
+
)}
|
|
157
190
|
</For>
|
|
158
|
-
{/* Typing indicator on the pending assistant turn.
|
|
191
|
+
{/* Typing indicator on the pending assistant turn.
|
|
192
|
+
DELIBERATELY role-less, unlike the rows above — this is not an
|
|
193
|
+
oversight of the same kind. There is no message here yet, so
|
|
194
|
+
`role="assistant"` would announce an empty article named
|
|
195
|
+
"Assistant message". What a pending indicator needs instead is a
|
|
196
|
+
live region, so its ARRIVAL and departure are announced. The
|
|
197
|
+
Loader already carries an accessible name — an sr-only "Loading"
|
|
198
|
+
on all nine shape variants — and what it lacks is the
|
|
199
|
+
`role="status"` / aria-live wrapper around it. A real but
|
|
200
|
+
SEPARATE gap, and it lives in loader.tsx. Filed, not fixed here. */}
|
|
159
201
|
<Show when={props.loading}>
|
|
160
202
|
<Message class="flex-col items-start">
|
|
161
203
|
<div class="rounded-lg px-1 py-2">
|
package/src/components/toast.tsx
CHANGED
|
@@ -59,7 +59,7 @@ function usePrefersReducedMotion() {
|
|
|
59
59
|
|
|
60
60
|
// ── Single toast pill ────────────────────────────────────────────────────────
|
|
61
61
|
|
|
62
|
-
interface ToastProps {
|
|
62
|
+
export interface ToastProps {
|
|
63
63
|
item: ToastItem;
|
|
64
64
|
onDismiss: (reason: ToastDismissReason) => void;
|
|
65
65
|
onAction?: (label: string) => void;
|
|
@@ -388,6 +388,12 @@ export function ToastRegion(props: ToastRegionProps) {
|
|
|
388
388
|
createEffect(() => {
|
|
389
389
|
const t = props.target;
|
|
390
390
|
if (!t || typeof window === 'undefined') { setAnchor(null); return; }
|
|
391
|
+
// Captured at SETUP and closed over, never re-resolved as a global inside
|
|
392
|
+
// `onCleanup`: cleanup can run after the host removed the DOM globals (a
|
|
393
|
+
// `kai-*` release is deferred one microtask past detachment, so an
|
|
394
|
+
// environment teardown gets in between), and a bare `window` there throws.
|
|
395
|
+
// See tests/components/teardown-without-dom-globals.test.tsx.
|
|
396
|
+
const win = window;
|
|
391
397
|
const update = () => {
|
|
392
398
|
const r = t.getBoundingClientRect();
|
|
393
399
|
setAnchor({ top: r.top, left: r.left, right: r.right, bottom: r.bottom, width: r.width });
|
|
@@ -395,12 +401,12 @@ export function ToastRegion(props: ToastRegionProps) {
|
|
|
395
401
|
update();
|
|
396
402
|
const ro = new ResizeObserver(update);
|
|
397
403
|
ro.observe(t);
|
|
398
|
-
|
|
399
|
-
|
|
404
|
+
win.addEventListener('scroll', update, true);
|
|
405
|
+
win.addEventListener('resize', update);
|
|
400
406
|
onCleanup(() => {
|
|
401
407
|
ro.disconnect();
|
|
402
|
-
|
|
403
|
-
|
|
408
|
+
win.removeEventListener('scroll', update, true);
|
|
409
|
+
win.removeEventListener('resize', update);
|
|
404
410
|
});
|
|
405
411
|
});
|
|
406
412
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Semantic classification of a tool call, used to pick a rendering. Derived from
|
|
2
|
+
* the provider-chosen tool NAME, which is arbitrary, so this stays conservative and
|
|
3
|
+
* prefers 'generic' over a confident wrong answer. */
|
|
4
|
+
export type ToolKind =
|
|
5
|
+
| 'command'
|
|
6
|
+
| 'file-change'
|
|
7
|
+
| 'search'
|
|
8
|
+
| 'fetch'
|
|
9
|
+
| 'mcp'
|
|
10
|
+
| 'image'
|
|
11
|
+
| 'generic';
|
|
12
|
+
|
|
13
|
+
/** Total, deterministic, side-effect free. ALWAYS terminates in 'generic' so an
|
|
14
|
+
* unrecognized tool still renders a panel instead of a blank. Order matters:
|
|
15
|
+
* 'search' is tested before 'fetch' so `web_search` classifies as a search. */
|
|
16
|
+
export function classifyTool(name: string): ToolKind {
|
|
17
|
+
const n = name.toLowerCase();
|
|
18
|
+
if (!n) return 'generic';
|
|
19
|
+
if (n.includes('bash') || n.includes('command') || n.includes('shell') || n.includes('terminal') || n.includes('exec')) return 'command';
|
|
20
|
+
if (n.includes('edit') || n.includes('write') || n.includes('patch') || n.includes('replace') || n.includes('delete')) return 'file-change';
|
|
21
|
+
if (n.includes('search') || n.includes('grep') || n.includes('glob') || n.includes('find')) return 'search';
|
|
22
|
+
if (n.includes('fetch') || n.includes('http') || n.includes('browse') || n.includes('crawl')) return 'fetch';
|
|
23
|
+
if (n.includes('mcp')) return 'mcp';
|
|
24
|
+
if (n.includes('image') || n.includes('screenshot') || n.includes('vision')) return 'image';
|
|
25
|
+
return 'generic';
|
|
26
|
+
}
|
|
@@ -1,10 +1,40 @@
|
|
|
1
|
+
import type { ToolKind } from './tool-classify';
|
|
2
|
+
|
|
3
|
+
/** The untranslated provider payload a part was normalized from.
|
|
4
|
+
*
|
|
5
|
+
* Optional in the type but REQUIRED in practice for round-trip fidelity. Anthropic
|
|
6
|
+
* returns a 400 invalid_request_error if `thinking` blocks are modified, reordered,
|
|
7
|
+
* filtered or RECONSTRUCTED, so an encoder must send `raw.payload` back verbatim
|
|
8
|
+
* rather than rebuilding a block from `text` + `signature`. */
|
|
9
|
+
export interface RawOrigin {
|
|
10
|
+
/** Tagged origin, e.g. 'anthropic.content_block', 'openai.delta', `custom.${string}`. */
|
|
11
|
+
source: string;
|
|
12
|
+
payload: unknown;
|
|
13
|
+
}
|
|
14
|
+
|
|
1
15
|
/** A tool-call part rendered by <Tool>. Pure type — kept JSX-free so it can be
|
|
2
|
-
* imported by the framework-neutral state core and the React typecheck pass.
|
|
16
|
+
* imported by the framework-neutral state core and the React typecheck pass.
|
|
17
|
+
*
|
|
18
|
+
* Adding a field here also requires adding it to `TOOL_KEYS` (and a comparator
|
|
19
|
+
* in `TOOL_COMPARATORS`) in `state/parts.ts`, or `tsc` fails to compile: those
|
|
20
|
+
* drive `upsertToolPart`'s dedupe check, and a field missing from them would
|
|
21
|
+
* silently make that check ignore the new field, keeping a stale array
|
|
22
|
+
* reference alive when only that field changed. */
|
|
3
23
|
export interface ToolPart {
|
|
24
|
+
/** The tool name exactly as the provider reported it. */
|
|
4
25
|
type: string;
|
|
26
|
+
/** Semantic classification for rendering. Derive with classifyTool(type). */
|
|
27
|
+
kind?: ToolKind;
|
|
5
28
|
state: 'input-streaming' | 'input-available' | 'output-available' | 'output-error';
|
|
29
|
+
/** Last VALID parsed snapshot, fingerprint-deduped. The primary channel: this is
|
|
30
|
+
* what the kit renders. */
|
|
6
31
|
input?: Record<string, unknown>;
|
|
32
|
+
/** Raw accumulated argument fragments, for consumers wanting character-level
|
|
33
|
+
* streaming. Most consumers should read `input` instead. */
|
|
34
|
+
rawInput?: string;
|
|
7
35
|
output?: Record<string, unknown>;
|
|
8
36
|
toolCallId?: string;
|
|
9
37
|
errorText?: string;
|
|
38
|
+
/** The untranslated provider payload this was normalized from. */
|
|
39
|
+
raw?: RawOrigin;
|
|
10
40
|
}
|
|
@@ -2,26 +2,26 @@ import { defineWebComponent } from './define';
|
|
|
2
2
|
import { AgentCard, type AgentStatus } from '../ui/agent-card';
|
|
3
3
|
|
|
4
4
|
interface Props extends Record<string, unknown> {
|
|
5
|
-
/** The agent's name
|
|
5
|
+
/** The agent's name, the primary label. Attribute: `name`. */
|
|
6
6
|
name?: string;
|
|
7
7
|
/** Selected / focused state: highlighted border + surface. Attribute: `active`. */
|
|
8
8
|
active?: boolean;
|
|
9
|
-
/** Raise a prominent "Needs you" pill plus a glowing amber edge
|
|
10
|
-
* attention-routing signal that pulls focus to this agent.
|
|
11
|
-
* `needs-attention`. */
|
|
9
|
+
/** Raise a prominent "Needs you" pill plus a glowing amber edge. This
|
|
10
|
+
* is the attention-routing signal that pulls focus to this agent.
|
|
11
|
+
* Attribute: `needs-attention`. */
|
|
12
12
|
needsAttention?: boolean;
|
|
13
|
-
/** Run status
|
|
14
|
-
*
|
|
15
|
-
* `
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
/** Run status. A JS PROPERTY (object), not an attribute. Shape: `{ tone,
|
|
14
|
+
* label?, pulse? }`, where `tone` is one of `working` | `idle` | `done` |
|
|
15
|
+
* `error` | `blocked` (maps to the kit's tool hues), `label` is an optional
|
|
16
|
+
* short string beside the dot, and `pulse` animates the dot. Set it with
|
|
17
|
+
* `el.status = { tone: 'working', label: 'Working', pulse: true }`. */
|
|
18
18
|
status?: AgentStatus;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/** Events fired by `<kai-agent-card>`. */
|
|
22
22
|
interface Events {
|
|
23
|
-
/** The card was activated
|
|
24
|
-
* this agent back to focus. */
|
|
23
|
+
/** The card was activated by a click, or by Enter / Space while focused.
|
|
24
|
+
* Promote this agent back to focus. */
|
|
25
25
|
'kai-activate': void;
|
|
26
26
|
/** The trailing "..." kebab was clicked. The consumer opens its own menu; the
|
|
27
27
|
* card only surfaces the affordance (the click does not also activate the card). */
|
|
@@ -5,8 +5,10 @@ import { Artifact, type ArtifactController, type ArtifactFile, type ArtifactTab
|
|
|
5
5
|
interface Props extends Record<string, unknown> {
|
|
6
6
|
/** URL the preview iframe frames. Consumer-controlled. */
|
|
7
7
|
src?: string;
|
|
8
|
-
/** Files for the Code tab tree + each file's preview `url`.
|
|
9
|
-
|
|
8
|
+
/** Files for the Code tab tree + each file's preview `url`. Omit for a
|
|
9
|
+
* preview-only artifact (the Code tab then has nothing to show; pair it with
|
|
10
|
+
* `no-tabs` to hide the toggle). Set as a JS property (array). */
|
|
11
|
+
files?: ArtifactFile[];
|
|
10
12
|
/** Controlled active tab: `preview` or `code`. When set, the artifact follows it
|
|
11
13
|
* (re-asserted on change). Leave unset for an uncontrolled tab (see `defaultTab`). */
|
|
12
14
|
tab?: ArtifactTab;
|
|
@@ -14,7 +16,7 @@ interface Props extends Record<string, unknown> {
|
|
|
14
16
|
* Seeds the starting tab; the user can then switch freely without the consumer
|
|
15
17
|
* re-asserting a controlled `tab`. */
|
|
16
18
|
defaultTab?: ArtifactTab;
|
|
17
|
-
/** Selected file path
|
|
19
|
+
/** Selected file path. Syncs the tree highlight, Code source, and preview. */
|
|
18
20
|
activeFile?: string;
|
|
19
21
|
/** iframe `sandbox` override. Secure default `allow-scripts allow-forms` (NOT `allow-same-origin`). */
|
|
20
22
|
sandbox?: string;
|
|
@@ -56,6 +58,12 @@ interface Events extends Record<string, unknown> {
|
|
|
56
58
|
'kai-file-select': { path: string };
|
|
57
59
|
/** Artifact's own maximize button toggled (consumer-observable; non-bubbling). */
|
|
58
60
|
'kai-maximize-change': { maximized: boolean };
|
|
61
|
+
/** The maximize PROTOCOL intent, raised as a raw bubbling + composed CustomEvent
|
|
62
|
+
* (not through `dispatch`) so an enclosing `<kai-resizable>` can catch it and
|
|
63
|
+
* maximize the containing panel. Declared here so it is typed and reaches the
|
|
64
|
+
* generated API. Listen for it to drive maximize from your own chrome, or
|
|
65
|
+
* re-emit it to trigger one. */
|
|
66
|
+
'kai-maximize-intent': { requested: boolean };
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
/**
|
|
@@ -106,17 +114,17 @@ defineWebComponent<Props, Events>('kai-artifact', {
|
|
|
106
114
|
reload: () => controller?.reload(),
|
|
107
115
|
/** Navigate to the `src` home url (no-op when there's no `src`). */
|
|
108
116
|
home: () => controller?.home(),
|
|
109
|
-
/** Push + load a url in the preview
|
|
117
|
+
/** Push + load a url in the preview, the path-field submit path (fires kai-navigate). */
|
|
110
118
|
navigate: (url: string) => controller?.navigate(url),
|
|
111
119
|
/** Select a file by path: highlights the tree, shows its source, navigates the
|
|
112
120
|
* preview (fires kai-file-select + kai-navigate). Named selectFile to avoid the
|
|
113
121
|
* `activeFile` prop. */
|
|
114
122
|
selectFile: (path: string) => controller?.selectFile(path),
|
|
115
123
|
/** Open the current url in a new browser tab (no-op when there's no concrete url).
|
|
116
|
-
* Named openExternal, NOT openInTab
|
|
124
|
+
* Named openExternal, NOT openInTab, which is a prop (toolbar button visibility). */
|
|
117
125
|
openExternal: () => controller?.openExternal(),
|
|
118
126
|
/** Enter the maximized view-state (fires kai-maximize-change{maximized:true}).
|
|
119
|
-
* Named maximize, NOT maximized
|
|
127
|
+
* Named maximize, NOT maximized, which is a prop. */
|
|
120
128
|
maximize: () => controller?.maximize(),
|
|
121
129
|
/** Exit the maximized view-state (fires kai-maximize-change{maximized:false}). */
|
|
122
130
|
restore: () => controller?.restore(),
|
|
@@ -157,7 +165,7 @@ defineWebComponent<Props, Events>('kai-artifact', {
|
|
|
157
165
|
>
|
|
158
166
|
<Artifact
|
|
159
167
|
src={props.src}
|
|
160
|
-
files={props.files}
|
|
168
|
+
files={props.files ?? []}
|
|
161
169
|
tab={props.tab}
|
|
162
170
|
defaultTab={props.defaultTab}
|
|
163
171
|
activeFile={props.activeFile}
|
|
@@ -17,8 +17,10 @@ import {
|
|
|
17
17
|
} from '../components/attachments';
|
|
18
18
|
|
|
19
19
|
interface Props extends Record<string, unknown> {
|
|
20
|
-
/** The attachments to render.
|
|
21
|
-
|
|
20
|
+
/** The attachments to render. Omit (or pass an empty array) for the empty
|
|
21
|
+
* state, which shows `emptyText` if set and nothing otherwise. Set as a JS
|
|
22
|
+
* property (array). */
|
|
23
|
+
items?: AttachmentData[];
|
|
22
24
|
/** Layout: `grid` = visual tiles, `inline` = icon + label chips, `list` = rows. */
|
|
23
25
|
variant?: AttachmentVariant;
|
|
24
26
|
/** Wrap each item in a hover card that previews its details. */
|
|
@@ -67,11 +69,11 @@ defineWebComponent<Props, Events>('kai-attachments', {
|
|
|
67
69
|
|
|
68
70
|
return (
|
|
69
71
|
<Show
|
|
70
|
-
when={props.items
|
|
72
|
+
when={props.items?.length}
|
|
71
73
|
fallback={<Show when={props.emptyText}><AttachmentEmpty>{props.emptyText}</AttachmentEmpty></Show>}
|
|
72
74
|
>
|
|
73
75
|
<Attachments variant={variant()}>
|
|
74
|
-
<For each={props.items}>
|
|
76
|
+
<For each={props.items ?? []}>
|
|
75
77
|
{(item) => (
|
|
76
78
|
<Attachment
|
|
77
79
|
data={item}
|
package/src/elements/avatar.tsx
CHANGED
|
@@ -6,7 +6,7 @@ interface Props extends Record<string, unknown> {
|
|
|
6
6
|
src?: string;
|
|
7
7
|
/** Alt text for the image. Defaults to `fallback`. */
|
|
8
8
|
alt?: string;
|
|
9
|
-
/** Short text shown when there's no image
|
|
9
|
+
/** Short text shown when there's no image, usually initials (e.g. "JD", "AI"). */
|
|
10
10
|
fallback?: string;
|
|
11
11
|
/** Size token: `sm` | `md` (default) | `lg`. */
|
|
12
12
|
size?: 'sm' | 'md' | 'lg';
|
package/src/elements/button.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { renderIcon } from '../ui/icon';
|
|
|
4
4
|
import { defineWebComponent } from './define';
|
|
5
5
|
|
|
6
6
|
interface Props extends Record<string, unknown> {
|
|
7
|
-
/** Visual style. `default` (filled), `subtle` (muted text, hover tint
|
|
7
|
+
/** Visual style. `default` (filled), `subtle` (muted text, hover tint, the
|
|
8
8
|
* toolbar icon look), `ghost` (transparent, hover fill), `outline`, or
|
|
9
9
|
* `destructive`. Defaults to `default`. */
|
|
10
10
|
variant?: 'default' | 'subtle' | 'ghost' | 'outline' | 'destructive';
|
|
@@ -21,7 +21,7 @@ interface Props extends Record<string, unknown> {
|
|
|
21
21
|
label?: string;
|
|
22
22
|
/** Disable the button (non-interactive, dimmed). */
|
|
23
23
|
disabled?: boolean;
|
|
24
|
-
/** Stretch the button to the full width of its container (a block button)
|
|
24
|
+
/** Stretch the button to the full width of its container (a block button),
|
|
25
25
|
* e.g. a card CTA or a stacked action. Attribute: `full`. */
|
|
26
26
|
full?: boolean;
|
|
27
27
|
/** Justify the button's content: `start`, `center` (default), or `end`.
|
|
@@ -82,7 +82,7 @@ defineWebComponent<Props, Events>('kai-button', {
|
|
|
82
82
|
element.shadowRoot?.querySelector('button')?.focus(options),
|
|
83
83
|
/** Blur the inner `<button>`. */
|
|
84
84
|
blur: () => element.shadowRoot?.querySelector('button')?.blur(),
|
|
85
|
-
/** Programmatically activate the button
|
|
85
|
+
/** Programmatically activate the button. Runs the same path as a user
|
|
86
86
|
* click and fires kai-click. Forwarding to the inner button means
|
|
87
87
|
* `disabled` is respected automatically. */
|
|
88
88
|
click: () => element.shadowRoot?.querySelector('button')?.click(),
|
package/src/elements/card.tsx
CHANGED
|
@@ -7,8 +7,8 @@ interface Props extends Record<string, unknown> {
|
|
|
7
7
|
* Attribute: `appearance`. */
|
|
8
8
|
appearance?: CardAppearance;
|
|
9
9
|
/** `vertical` (default, media on top) | `horizontal` (media at the start) |
|
|
10
|
-
* `responsive` (horizontal when the card's container is wide enough, else
|
|
11
|
-
*
|
|
10
|
+
* `responsive` (horizontal when the card's container is wide enough, else vertical,
|
|
11
|
+
* via a container query on the card's own width). Attribute: `orientation`. */
|
|
12
12
|
orientation?: CardOrientation;
|
|
13
13
|
/** The card width below which a `responsive` card collapses to vertical and the
|
|
14
14
|
* footer actions stack. A CSS length; default `28rem`. Attribute: `collapse`. */
|