@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
package/src/elements/register.ts
CHANGED
|
@@ -29,6 +29,15 @@ export type { ChatMessage, ChatMessageAction } from './chat-types';
|
|
|
29
29
|
export { configureCodeHighlighting, isCodeHighlightingEnabled } from '../primitives/highlighter';
|
|
30
30
|
export type { CodeHighlightingOptions } from '../primitives/highlighter';
|
|
31
31
|
|
|
32
|
+
// ToolPart.kind's doc comment in the shipped dist/elements.d.ts says "Derive with
|
|
33
|
+
// `classifyTool(type)`", but the function was exported from NO public entry, so a
|
|
34
|
+
// consumer following our own docs hit an unresolvable import. Total, deterministic
|
|
35
|
+
// and always terminating in 'generic' — safe to expose, and needed by anyone
|
|
36
|
+
// rendering tool calls themselves. tool-classify.ts imports nothing, so this stays
|
|
37
|
+
// SSR-safe and adds no weight to the register-all bundle.
|
|
38
|
+
export { classifyTool } from '../components/tool-classify';
|
|
39
|
+
export type { ToolKind } from '../components/tool-classify';
|
|
40
|
+
|
|
32
41
|
// Imperative toast API — usable directly from the elements entry so consumers
|
|
33
42
|
// who only import the web-components bundle still get `toast()`. The store is
|
|
34
43
|
// SSR-safe (no DOM touched until the first toast is raised on the client).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/elements/resizable.globals.d.ts
|
|
2
|
+
// Hand-authored ambient types for the cross-element maximize PROTOCOL — the two
|
|
3
|
+
// raw composed CustomEvents `<kai-artifact>` and `<kai-resizable>`/`<kai-resizable-item>`
|
|
4
|
+
// exchange. The generated element-types.d.ts emits no HTMLElementEventMap entries,
|
|
5
|
+
// so without this `el.addEventListener('kai-maximize-intent', e => e.detail)` is
|
|
6
|
+
// TS2339 on `Event`. NOT regenerated by `npm run build`.
|
|
7
|
+
//
|
|
8
|
+
// THE FILENAME IS LOAD-BEARING and must not go back to `resizable.d.ts`.
|
|
9
|
+
// TypeScript drops a .d.ts when a same-named .ts/.tsx sits beside it, and
|
|
10
|
+
// `resizable.tsx` does. Under the old name this whole file was in NO tsc
|
|
11
|
+
// program, so every augmentation below was inert. Measured on the same probe,
|
|
12
|
+
// `el.addEventListener('kai-maximize-intent', e => e.detail)`:
|
|
13
|
+
// resizable.d.ts TS2339: Property 'detail' does not exist on 'Event'
|
|
14
|
+
// resizable.globals.d.ts clean -- narrowed to CustomEvent<KaiMaximizeIntentDetail>
|
|
15
|
+
//
|
|
16
|
+
// This file used to ALSO declare a global `KaiResizableElement` carrying
|
|
17
|
+
// `maximize`/`restore` plus an HTMLElementTagNameMap entry pointing at it. That
|
|
18
|
+
// half never worked: element-types.d.ts declares its own module-scoped
|
|
19
|
+
// `KaiResizableElement` and maps the tag to THAT, so the two entries collided
|
|
20
|
+
// (TS2717, invisible under the `skipLibCheck: true` every pass sets) and the
|
|
21
|
+
// generated one won — `document.querySelector('kai-resizable').maximize(0)` stayed
|
|
22
|
+
// TS2339. The methods now come from the GENERATOR (resizable.tsx routes them
|
|
23
|
+
// through `ctx.expose`, gen-element-types.mjs emits them onto the element
|
|
24
|
+
// interface), so the duplicate is gone and there is exactly one declaration of
|
|
25
|
+
// each name. Do not reintroduce it: a hand-written interface cannot win against
|
|
26
|
+
// the generated one, and generated files are regenerated.
|
|
27
|
+
import type { KaiMaximizeIntentDetail, KaiMaximizeStateDetail } from './resizable';
|
|
28
|
+
|
|
29
|
+
declare global {
|
|
30
|
+
interface HTMLElementEventMap {
|
|
31
|
+
'kai-maximize-intent': CustomEvent<KaiMaximizeIntentDetail>;
|
|
32
|
+
'kai-maximize-state': CustomEvent<KaiMaximizeStateDetail>;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export {};
|
|
@@ -57,9 +57,9 @@ interface GroupProps extends Record<string, unknown> {
|
|
|
57
57
|
maximizedIndex?: number | null;
|
|
58
58
|
/**
|
|
59
59
|
* Divider affordance drawn inside each draggable handle's 8px grab zone:
|
|
60
|
-
* - `line` (default)
|
|
61
|
-
* - `grip
|
|
62
|
-
* - `none
|
|
60
|
+
* - `line` (default): a 1px hairline, transparent at rest, tinting on hover/drag.
|
|
61
|
+
* - `grip`: a dotted grip handle.
|
|
62
|
+
* - `none`: no visible divider, just the invisible hit-area.
|
|
63
63
|
* The full grab zone and keyboard/ARIA behavior are identical for all three.
|
|
64
64
|
*/
|
|
65
65
|
handle?: 'line' | 'grip' | 'none';
|
|
@@ -70,6 +70,11 @@ interface GroupEvents extends Record<string, unknown> {
|
|
|
70
70
|
'kai-change': { sizes: number[] };
|
|
71
71
|
/** Observe layout maximize state. */
|
|
72
72
|
'kai-maximize-change': { maximized: boolean; index: number | null };
|
|
73
|
+
/** Authoritative maximize state, dispatched as a raw composed CustomEvent (not
|
|
74
|
+
* through `dispatch`) onto the affected `<kai-resizable-item>` and, on restore,
|
|
75
|
+
* onto the group host. A nested element (e.g. `<kai-artifact>`) listens for it
|
|
76
|
+
* to reconcile its own toggle. */
|
|
77
|
+
'kai-maximize-state': { maximized: boolean };
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
/**
|
|
@@ -84,7 +89,7 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
|
|
|
84
89
|
orientation: 'horizontal',
|
|
85
90
|
maximizedIndex: null,
|
|
86
91
|
handle: 'line',
|
|
87
|
-
}, (props, { element, dispatch }) => {
|
|
92
|
+
}, (props, { element, dispatch, expose }) => {
|
|
88
93
|
const [items, setItems] = createSignal<ItemInfo[]>([]);
|
|
89
94
|
const orientation = (): Orientation => (props.orientation === 'vertical' ? 'vertical' : 'horizontal');
|
|
90
95
|
|
|
@@ -405,13 +410,19 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
|
|
|
405
410
|
|
|
406
411
|
// --- Task 3: imperative host methods + declarative maximizedIndex prop ---
|
|
407
412
|
|
|
408
|
-
// Imperative host API
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
413
|
+
// Imperative host API. Routed through `expose()` like every other element's,
|
|
414
|
+
// so gen-element-api.mjs sees it and the generated element interface carries
|
|
415
|
+
// `maximize`/`restore` — a direct assignment onto `element` was invisible to
|
|
416
|
+
// the extractor and needed an `as unknown as` cast to type-check here.
|
|
417
|
+
expose({
|
|
418
|
+
/** Imperatively maximize the item at `index` (thin wrapper over `maximizedIndex`). */
|
|
419
|
+
maximize: (index: number) => {
|
|
420
|
+
const it = items()[index]?.el;
|
|
421
|
+
if (it) maximizeItem(it);
|
|
422
|
+
},
|
|
423
|
+
/** Imperatively restore from the maximized layout. */
|
|
424
|
+
restore: () => restore(),
|
|
425
|
+
});
|
|
415
426
|
|
|
416
427
|
// Declarative maximizedIndex → maximize/restore. Skip the initial null run.
|
|
417
428
|
createEffect(
|
|
@@ -599,8 +610,8 @@ interface ItemProps extends Record<string, unknown> {
|
|
|
599
610
|
/** Hide this panel; its divider is dropped and the rest reflow. */
|
|
600
611
|
hidden?: boolean;
|
|
601
612
|
/**
|
|
602
|
-
* Collapse this panel
|
|
603
|
-
*
|
|
613
|
+
* Collapse this panel. Same layout effect as `hidden` (divider dropped, the rest
|
|
614
|
+
* reflow), but it WORKS as a bare boolean from framework JSX. A plain
|
|
604
615
|
* `<kai-resizable-item collapsed>` in React/Solid/Vue/Svelte collapses the panel
|
|
605
616
|
* at the first render; `hidden` does not, because a JSX boolean sets neither the
|
|
606
617
|
* `hidden` attribute nor the IDL property on a custom element, so the parent never
|
|
@@ -3,7 +3,7 @@ import { ResponseStream, type Mode } from '../components/response-stream';
|
|
|
3
3
|
|
|
4
4
|
interface Props extends Record<string, unknown> {
|
|
5
5
|
/** Text to stream. A string, or an `AsyncIterable<string>` (set as a JS
|
|
6
|
-
* property
|
|
6
|
+
* property, since async iterables can't be HTML attributes). */
|
|
7
7
|
text?: string | AsyncIterable<string>;
|
|
8
8
|
/** Reveal animation. */
|
|
9
9
|
mode?: Mode;
|
|
@@ -19,7 +19,7 @@ interface Props extends Record<string, unknown> {
|
|
|
19
19
|
/** Events fired by `<kai-scroll-button>`. */
|
|
20
20
|
interface Events {
|
|
21
21
|
/** Emitted when the user clicks the button and `scrollToBottom()` is
|
|
22
|
-
* called. Carries no detail
|
|
22
|
+
* called. Carries no detail; consumers use it to know a manual scroll
|
|
23
23
|
* occurred. */
|
|
24
24
|
'kai-scroll': void;
|
|
25
25
|
}
|
package/src/elements/search.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { Loader } from '../components/loader';
|
|
|
6
6
|
import { renderIcon } from '../ui/icon';
|
|
7
7
|
|
|
8
8
|
interface Props extends Record<string, unknown> {
|
|
9
|
-
/** Controlled query
|
|
9
|
+
/** Controlled query. Settable and reflected to the `value` attribute. Read
|
|
10
10
|
* `el.value` for live state. */
|
|
11
11
|
value?: string;
|
|
12
12
|
/** Placeholder. Defaults to `Search…`. */
|
|
@@ -123,7 +123,12 @@ defineWebComponent<Props, Events>('kai-search', {
|
|
|
123
123
|
};
|
|
124
124
|
|
|
125
125
|
expose({
|
|
126
|
+
/** Focus the search input inside the shadow root. A native `focus()` on the
|
|
127
|
+
* host lands on the host itself and never reaches it. */
|
|
126
128
|
focus: () => getInput()?.focus(),
|
|
129
|
+
/** Empty the field and fire `kai-search` with an empty value immediately,
|
|
130
|
+
* cancelling any debounced search still in flight, then return focus to the
|
|
131
|
+
* input. Same path as the trailing clear button. */
|
|
127
132
|
clear,
|
|
128
133
|
});
|
|
129
134
|
|
|
@@ -2,20 +2,14 @@ import { createEffect, createSignal, untrack } from 'solid-js';
|
|
|
2
2
|
import { defineWebComponent } from './define';
|
|
3
3
|
import { Segmented, type SegmentedOption } from '../ui/segmented';
|
|
4
4
|
import { renderIcon } from '../ui/icon';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* glyph via the kit's icon renderer (the same path `kai-button`'s `icon` uses). */
|
|
9
|
-
interface Option {
|
|
10
|
-
value: string;
|
|
11
|
-
label: string;
|
|
12
|
-
icon?: string;
|
|
13
|
-
}
|
|
5
|
+
// Public shape of the `options` prop; lives in ./element-data-types so the ROOT
|
|
6
|
+
// entry can re-export it (see that file's header).
|
|
7
|
+
import type { KaiSegmentedOption } from './element-data-types';
|
|
14
8
|
|
|
15
9
|
interface Props extends Record<string, unknown> {
|
|
16
10
|
/** The selectable segments, left to right. Set as a JS property (array). */
|
|
17
|
-
options:
|
|
18
|
-
/** Controlled selected `value
|
|
11
|
+
options: KaiSegmentedOption[];
|
|
12
|
+
/** Controlled selected `value`. Settable and reflected to the `value`
|
|
19
13
|
* attribute. `el.value = 'preview'` drives it; choosing a segment updates it
|
|
20
14
|
* and fires `kai-change`. Read `el.value` for live state. */
|
|
21
15
|
value?: string;
|
|
@@ -3,7 +3,7 @@ import { defineWebComponent } from './define';
|
|
|
3
3
|
|
|
4
4
|
interface Props extends Record<string, unknown> {
|
|
5
5
|
/** `horizontal` (default, block + full-width) or `vertical` (a rule inside a
|
|
6
|
-
* flex/grid row
|
|
6
|
+
* flex/grid row, stretching to the row height). */
|
|
7
7
|
orientation?: 'horizontal' | 'vertical';
|
|
8
8
|
}
|
|
9
9
|
|
package/src/elements/slots.ts
CHANGED
|
@@ -27,7 +27,7 @@ export const CHAT_SLOTS: SlotDef[] = [
|
|
|
27
27
|
{ name: 'header-end', mode: 'inject', doc: 'Trailing header controls.' },
|
|
28
28
|
{ name: 'header', mode: 'replace', part: true, doc: 'Full custom header; replaces the built-in title/model/context bar.' },
|
|
29
29
|
{ name: 'sidebar', mode: 'inject', part: true, doc: 'Left column (your nav / conversation list). Fixed width; use compose-your-own for resizable.' },
|
|
30
|
-
{ name: 'empty', mode: 'replace', doc: 'Custom zero-state rendered in the message area while the thread is empty. Replaces the empty message list only
|
|
30
|
+
{ name: 'empty', mode: 'replace', doc: 'Custom zero-state rendered in the message area while the thread is empty. Replaces the empty message list only; the composer and any suggestions still render.' },
|
|
31
31
|
{ name: 'composer', mode: 'replace', doc: 'Full custom composer; you own submit + loading, drive the thread via messages.' },
|
|
32
32
|
{ name: 'composer-actions', mode: 'inject', doc: 'Accessory row above the composer.' },
|
|
33
33
|
{ name: 'footer', mode: 'inject', part: true, doc: 'Row below the composer (disclaimers, token meter).' },
|
|
@@ -42,8 +42,8 @@ export const CHAT_SLOTS: SlotDef[] = [
|
|
|
42
42
|
* no outer block slot here. (When the input is nested inside `<kai-chat>`'s shadow,
|
|
43
43
|
* that surrounding hole belongs to `kai-chat` — see `composer-actions`/`footer`.) */
|
|
44
44
|
export const PROMPT_INPUT_SLOTS: SlotDef[] = [
|
|
45
|
-
{ name: 'input-top', mode: 'inject', doc: 'Inside the card, above the textarea (e.g. an inline status strip). For content above/below the whole card, use your own layout
|
|
46
|
-
{ name: 'toolbar-start', mode: 'inject', doc: 'Leading controls in the input toolbar
|
|
45
|
+
{ name: 'input-top', mode: 'inject', doc: 'Inside the card, above the textarea (e.g. an inline status strip). For content above/below the whole card, use your own layout; that is light DOM you control.' },
|
|
46
|
+
{ name: 'toolbar-start', mode: 'inject', doc: 'Leading controls in the input toolbar, where a + menu goes.' },
|
|
47
47
|
{ name: 'toolbar-end', mode: 'inject', doc: 'Trailing controls in the toolbar, before the Send button.' },
|
|
48
48
|
];
|
|
49
49
|
|
|
@@ -52,7 +52,7 @@ export const PROMPT_INPUT_SLOTS: SlotDef[] = [
|
|
|
52
52
|
export const CONVERSATIONS_SLOTS: SlotDef[] = [
|
|
53
53
|
{ name: 'header', mode: 'replace', doc: 'Full custom title bar; replaces the built-in toggle / "Chats" / New-chat row.' },
|
|
54
54
|
{ name: 'empty', mode: 'replace', doc: 'Custom zero-state shown when there are no conversations; replaces the built-in "No conversations yet".' },
|
|
55
|
-
{ name: 'footer', mode: 'inject', doc: 'A row below the list
|
|
55
|
+
{ name: 'footer', mode: 'inject', doc: 'A row below the list: account, settings, or usage.' },
|
|
56
56
|
];
|
|
57
57
|
|
|
58
58
|
/** Styleable `::part`s of `<kai-conversations>`. */
|
|
@@ -69,15 +69,15 @@ export const CONVERSATIONS_PARTS: PartDef[] = [
|
|
|
69
69
|
* REPLACES the built-in avatar rail (pair it with `avatar="none"` to omit the
|
|
70
70
|
* rail entirely). These are the keystone of compose-your-own message lists. */
|
|
71
71
|
export const MESSAGE_SLOTS: SlotDef[] = [
|
|
72
|
-
{ name: 'before-body', mode: 'inject', doc: 'A per-message header at the TOP of the body, above reasoning/tools/content
|
|
73
|
-
{ name: 'after-body', mode: 'inject', doc: 'A row at the BOTTOM of the body, below the action bar
|
|
72
|
+
{ name: 'before-body', mode: 'inject', doc: 'A per-message header at the TOP of the body, above reasoning/tools/content: a model-name label, a role + timestamp line.' },
|
|
73
|
+
{ name: 'after-body', mode: 'inject', doc: 'A row at the BOTTOM of the body, below the action bar: a citation/sources row, a token-cost/latency line.' },
|
|
74
74
|
{ name: 'avatar', mode: 'replace', part: true, doc: 'Replaces the built-in avatar rail with your own node. Use `avatar="none"` to omit the rail and let the body span the full row.' },
|
|
75
75
|
];
|
|
76
76
|
|
|
77
77
|
/** Slots of `<kai-notice>`. The message is the default slot; these are the named seams. */
|
|
78
78
|
export const NOTICE_SLOTS: SlotDef[] = [
|
|
79
|
-
{ name: 'action', mode: 'inject', doc: 'A trailing action beside the message
|
|
80
|
-
{ name: 'icon', mode: 'replace', doc: 'A custom leading icon (any inline SVG, inherits `currentColor`). Overrides the severity default and the `icon` prop
|
|
79
|
+
{ name: 'action', mode: 'inject', doc: 'A trailing action beside the message: a link or button.' },
|
|
80
|
+
{ name: 'icon', mode: 'replace', doc: 'A custom leading icon (any inline SVG, inherits `currentColor`). Overrides the severity default and the `icon` prop, the same escape hatch as `kai-button`.' },
|
|
81
81
|
];
|
|
82
82
|
|
|
83
83
|
/** Slots of `<kai-button>` (the label is the default slot). */
|
|
@@ -124,7 +124,7 @@ export const CHAT_PARTS: PartDef[] = [
|
|
|
124
124
|
export const PROMPT_INPUT_PARTS: PartDef[] = [
|
|
125
125
|
{
|
|
126
126
|
name: 'send',
|
|
127
|
-
doc: 'The send button. Restyle from outside, or hide it entirely (Enter-only)
|
|
127
|
+
doc: 'The send button. Restyle from outside, or hide it entirely (Enter-only). Hiding is pure CSS, which is why there is no `submit="never"`.',
|
|
128
128
|
recipe: 'kai-prompt-input::part(send) { display: none } /* Enter-only; or restyle: background, border-radius, … */',
|
|
129
129
|
},
|
|
130
130
|
];
|
|
@@ -206,13 +206,18 @@ export const MESSAGE_PARTS: PartDef[] = [
|
|
|
206
206
|
doc: 'The action-bar row (copy / like / regenerate …). Restyle its spacing or hide it entirely from outside.',
|
|
207
207
|
recipe: 'kai-message::part(actions) { gap: 0.25rem }',
|
|
208
208
|
},
|
|
209
|
+
{
|
|
210
|
+
name: 'citations',
|
|
211
|
+
doc: 'The citation row rendered from the message’s `source` parts: a wrapped row of chips below the bubble, never inside it. Restyle its spacing or hide it entirely from outside.',
|
|
212
|
+
recipe: 'kai-message::part(citations) { gap: 0.5rem }',
|
|
213
|
+
},
|
|
209
214
|
];
|
|
210
215
|
|
|
211
216
|
/** Styleable `::part`s of `<kai-attachments>`. */
|
|
212
217
|
export const ATTACHMENTS_PARTS: PartDef[] = [
|
|
213
218
|
{
|
|
214
219
|
name: 'preview',
|
|
215
|
-
doc: 'The image shown in an attachment’s hover-card preview. Bounded by default (max ~320×256, aspect preserved) so a large image never blows up the card
|
|
220
|
+
doc: 'The image shown in an attachment’s hover-card preview. Bounded by default (max ~320×256, aspect preserved) so a large image never blows up the card. Raise or lower the cap from outside.',
|
|
216
221
|
recipe: 'kai-attachments::part(preview) { max-width: 32rem; max-height: 24rem }',
|
|
217
222
|
},
|
|
218
223
|
];
|
|
@@ -434,6 +439,17 @@ export const FILE_TREE_PARTS: PartDef[] = [
|
|
|
434
439
|
export interface ElementComposition {
|
|
435
440
|
slots?: SlotDef[];
|
|
436
441
|
parts?: PartDef[];
|
|
442
|
+
/**
|
|
443
|
+
* What the element's DEFAULT (unnamed) `<slot>` projects — i.e. what a consumer
|
|
444
|
+
* puts between the tags. Kept OUT of `slots` on purpose: those arrays are also
|
|
445
|
+
* read at runtime by `readSlots()`, which would query a meaningless `[slot=""]`.
|
|
446
|
+
* scripts/gen-element-api.mjs merges it back in as a slot with the empty name,
|
|
447
|
+
* which is how the Custom Elements Manifest spells the default slot.
|
|
448
|
+
*
|
|
449
|
+
* Every facade that renders a bare `<slot />` needs one; guarded by
|
|
450
|
+
* tests/elements/slot-registry-coverage.test.ts.
|
|
451
|
+
*/
|
|
452
|
+
children?: string;
|
|
437
453
|
}
|
|
438
454
|
|
|
439
455
|
/** Slots + styleable `::part`s of `<kai-prompt-dock>`. */
|
|
@@ -558,6 +574,17 @@ export const THREAD_SLOTS: SlotDef[] = [
|
|
|
558
574
|
{ name: 'empty', mode: 'replace', doc: 'Custom zero-state rendered in the message area while the thread is empty; replaces the built-in default.' },
|
|
559
575
|
];
|
|
560
576
|
|
|
577
|
+
/** Slots of `<kai-empty>`. The body is the default slot; `media` is the named seam. */
|
|
578
|
+
export const EMPTY_SLOTS: SlotDef[] = [
|
|
579
|
+
{ name: 'media', mode: 'replace', doc: 'The leading illustration or icon above the title (any inline SVG or <img>). Replaces the built-in media box.' },
|
|
580
|
+
];
|
|
581
|
+
|
|
582
|
+
/** Slots of `<kai-popover>`. The panel body is the default slot; `trigger` is the
|
|
583
|
+
* control the panel anchors to and opens from. */
|
|
584
|
+
export const POPOVER_SLOTS: SlotDef[] = [
|
|
585
|
+
{ name: 'trigger', mode: 'replace', doc: 'The control that opens the popover (a button, an avatar, …). The panel anchors to it.' },
|
|
586
|
+
];
|
|
587
|
+
|
|
561
588
|
/** Styleable `::part`s of `<kai-audio-visualizer>`. Every DOM variant (`bar`,
|
|
562
589
|
* `grid`, `radial`) shares the `bar`/`cell` markup pattern; the shader variants
|
|
563
590
|
* (`wave`, `aurora`) share the `canvas` part. Lit items ALSO carry the
|
|
@@ -599,38 +626,44 @@ export const ELEMENT_COMPOSITION: Record<string, ElementComposition> = {
|
|
|
599
626
|
'kai-message': { slots: MESSAGE_SLOTS, parts: MESSAGE_PARTS },
|
|
600
627
|
'kai-thread': { slots: THREAD_SLOTS },
|
|
601
628
|
'kai-prompt-input': { slots: PROMPT_INPUT_SLOTS, parts: PROMPT_INPUT_PARTS },
|
|
602
|
-
'kai-button': { slots: BUTTON_SLOTS, parts: BUTTON_PARTS },
|
|
603
|
-
'kai-badge': { parts: BADGE_PARTS },
|
|
629
|
+
'kai-button': { slots: BUTTON_SLOTS, parts: BUTTON_PARTS, children: 'The button\'s label. Omit it for an icon-only button (pair with `aria-label`).' },
|
|
630
|
+
'kai-badge': { parts: BADGE_PARTS, children: 'The badge\'s label: text, or a small inline icon plus text.' },
|
|
604
631
|
'kai-icon': { parts: ICON_PARTS },
|
|
605
632
|
'kai-separator': { parts: SEPARATOR_PARTS },
|
|
606
|
-
'kai-scroll-area': { parts: SCROLL_AREA_PARTS },
|
|
607
|
-
'kai-notice': { slots: NOTICE_SLOTS },
|
|
608
|
-
'kai-hover-card': { slots: HOVER_CARD_SLOTS },
|
|
633
|
+
'kai-scroll-area': { parts: SCROLL_AREA_PARTS, children: 'The scrollable content.' },
|
|
634
|
+
'kai-notice': { slots: NOTICE_SLOTS, children: 'The notice message. `icon` and `action` are the named seams around it.' },
|
|
635
|
+
'kai-hover-card': { slots: HOVER_CARD_SLOTS, children: 'The TRIGGER the card hovers off. The card body is the `card` slot.' },
|
|
609
636
|
'kai-menu': { slots: MENU_SLOTS, parts: MENU_PARTS },
|
|
610
637
|
'kai-skeleton': { parts: SKELETON_PARTS },
|
|
611
638
|
'kai-attachments': { parts: ATTACHMENTS_PARTS },
|
|
612
639
|
'kai-status': { parts: STATUS_PARTS },
|
|
613
640
|
'kai-tabs': { parts: TABS_PARTS },
|
|
614
641
|
'kai-voice-output': { parts: VOICE_OUTPUT_PARTS },
|
|
615
|
-
'kai-screen': { slots: SCREEN_SLOTS, parts: SCREEN_PARTS },
|
|
616
|
-
'kai-card': { slots: CARD_SLOTS, parts: CARD_PARTS },
|
|
642
|
+
'kai-screen': { slots: SCREEN_SLOTS, parts: SCREEN_PARTS, children: 'The screen body, below the title bar.' },
|
|
643
|
+
'kai-card': { slots: CARD_SLOTS, parts: CARD_PARTS, children: 'The card body, below the header/media regions.' },
|
|
617
644
|
'kai-workspace': { slots: WORKSPACE_SLOTS, parts: WORKSPACE_PARTS },
|
|
618
645
|
'kai-nav': { parts: NAV_PARTS },
|
|
619
|
-
'kai-coachmark': { slots: COACHMARK_SLOTS, parts: COACHMARK_PARTS },
|
|
646
|
+
'kai-coachmark': { slots: COACHMARK_SLOTS, parts: COACHMARK_PARTS, children: 'The ANCHOR the coachmark points at: the element it attaches to and positions against. The bubble body is the `content` slot.' },
|
|
620
647
|
'kai-progress-bar': { parts: PROGRESS_BAR_PARTS },
|
|
621
648
|
'kai-file-tree': { parts: FILE_TREE_PARTS },
|
|
622
|
-
'kai-prompt-dock': { slots: PROMPT_DOCK_SLOTS, parts: PROMPT_DOCK_PARTS },
|
|
649
|
+
'kai-prompt-dock': { slots: PROMPT_DOCK_SLOTS, parts: PROMPT_DOCK_PARTS, children: 'The input the dock wraps, typically a `<kai-prompt-input>`. The `top`/`bottom` slots are the lips around it.' },
|
|
623
650
|
'kai-segmented': { parts: SEGMENTED_PARTS },
|
|
624
|
-
'kai-settings-group': { parts: SETTINGS_GROUP_PARTS },
|
|
651
|
+
'kai-settings-group': { parts: SETTINGS_GROUP_PARTS, children: 'The `<kai-setting-item>` rows in this group.' },
|
|
625
652
|
'kai-setting-item': { slots: SETTING_ITEM_SLOTS, parts: SETTING_ITEM_PARTS },
|
|
626
|
-
'kai-pane': { slots: PANE_SLOTS, parts: PANE_PARTS },
|
|
627
|
-
'kai-pane-group': { parts: PANE_GROUP_PARTS },
|
|
653
|
+
'kai-pane': { slots: PANE_SLOTS, parts: PANE_PARTS, children: 'The pane body, below the header row.' },
|
|
654
|
+
'kai-pane-group': { parts: PANE_GROUP_PARTS, children: 'Content shown for every tab. Use it INSTEAD of the per-tab `slot="<tab id>"` seams when you swap the content yourself.' },
|
|
628
655
|
'kai-agent-card': { parts: AGENT_CARD_PARTS },
|
|
629
|
-
'kai-dialog': { slots: DIALOG_SLOTS, parts: DIALOG_PARTS },
|
|
656
|
+
'kai-dialog': { slots: DIALOG_SLOTS, parts: DIALOG_PARTS, children: 'The dialog body, between the `header` and `footer` slots.' },
|
|
630
657
|
'kai-input': { slots: INPUT_SLOTS, parts: INPUT_PARTS },
|
|
631
658
|
'kai-search': { parts: SEARCH_PARTS },
|
|
632
|
-
'kai-kbd': { parts: KBD_PARTS },
|
|
659
|
+
'kai-kbd': { parts: KBD_PARTS, children: 'Literal key text, when you are not using the `keys` prop to render key caps.' },
|
|
633
660
|
'kai-editable-label': { parts: EDITABLE_LABEL_PARTS },
|
|
661
|
+
'kai-empty': { slots: EMPTY_SLOTS, children: 'The empty-state body below the title/description, usually the call to action.' },
|
|
662
|
+
'kai-file-upload': { children: 'Custom dropzone content, replacing the default label (the `label` prop is the fallback).' },
|
|
663
|
+
'kai-popover': { slots: POPOVER_SLOTS, children: 'The popover panel body. The control that opens it is the `trigger` slot.' },
|
|
664
|
+
'kai-resizable': { children: 'The `<kai-resizable-item>` panels, in order. Dividers are inserted between them.' },
|
|
665
|
+
'kai-resizable-item': { children: 'This panel\'s content.' },
|
|
666
|
+
'kai-tooltip': { children: 'The TRIGGER the tooltip describes. The tip text is the `text` prop.' },
|
|
634
667
|
'kai-audio-visualizer': { parts: AUDIO_VISUALIZER_PARTS },
|
|
635
668
|
};
|
|
636
669
|
|
package/src/elements/source.tsx
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { createSignal, For, onCleanup, onMount, Show } from 'solid-js';
|
|
2
2
|
import { defineWebComponent } from './define';
|
|
3
3
|
import { Source, SourceTrigger, SourceContent, SourceList } from '../components/source';
|
|
4
|
+
// Public shape of the `sources` prop; lives in ./element-data-types so the ROOT
|
|
5
|
+
// entry can re-export it (see that file's header).
|
|
6
|
+
import type { KaiSourceItem } from './element-data-types';
|
|
4
7
|
|
|
5
8
|
// --- <kai-source> — a single citation link with hover preview ---
|
|
6
9
|
|
|
@@ -9,8 +12,9 @@ interface SourceProps extends Record<string, unknown> {
|
|
|
9
12
|
href?: string;
|
|
10
13
|
/** Trigger label (defaults to the domain). */
|
|
11
14
|
label?: string;
|
|
12
|
-
/** Hover-card headline. Attribute: `headline` (`title` is avoided
|
|
13
|
-
* global HTML attribute that reflects in a CE constructor and breaks
|
|
15
|
+
/** Hover-card headline. Attribute: `headline` (`title` is avoided because it
|
|
16
|
+
* is a global HTML attribute that reflects in a CE constructor and breaks
|
|
17
|
+
* it). */
|
|
14
18
|
headline?: string;
|
|
15
19
|
/** Hover-card body text describing the source. */
|
|
16
20
|
description?: string;
|
|
@@ -42,17 +46,12 @@ defineWebComponent<SourceProps>('kai-source', {
|
|
|
42
46
|
|
|
43
47
|
// --- <kai-sources> — a wrapped list of citation links ---
|
|
44
48
|
|
|
45
|
-
interface SourceItem {
|
|
46
|
-
href: string;
|
|
47
|
-
title?: string;
|
|
48
|
-
description?: string;
|
|
49
|
-
label?: string;
|
|
50
|
-
showFavicon?: boolean;
|
|
51
|
-
}
|
|
52
49
|
|
|
53
50
|
interface SourceListProps extends Record<string, unknown> {
|
|
54
|
-
/** The sources to render. Set as a JS property.
|
|
55
|
-
|
|
51
|
+
/** The sources to render. Set as a JS property. Omit to supply them as
|
|
52
|
+
* `<kai-source>` light-DOM children instead; when both are present the
|
|
53
|
+
* property's sources come first. */
|
|
54
|
+
sources?: KaiSourceItem[];
|
|
56
55
|
/** Show favicons on all items (per-item `showFavicon` overrides). */
|
|
57
56
|
showFavicon?: boolean;
|
|
58
57
|
/**
|
|
@@ -60,22 +59,22 @@ interface SourceListProps extends Record<string, unknown> {
|
|
|
60
59
|
* merged (prop + declarative-children) list (`[1]`, `[2]`, …) instead of the
|
|
61
60
|
* per-item `label` or domain fallback.
|
|
62
61
|
*
|
|
63
|
-
* HTML attribute: `numbered` (boolean
|
|
64
|
-
* JS property: `el.numbered = true`.
|
|
62
|
+
* HTML attribute: `numbered` (boolean: a bare attribute or
|
|
63
|
+
* `numbered="true"`). JS property: `el.numbered = true`.
|
|
65
64
|
*/
|
|
66
65
|
numbered?: boolean;
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
/** Parse a single light-DOM `<kai-source>` element into a `
|
|
68
|
+
/** Parse a single light-DOM `<kai-source>` element into a `KaiSourceItem` descriptor.
|
|
70
69
|
* Attribute mapping:
|
|
71
|
-
* - `href` →
|
|
72
|
-
* - `label` →
|
|
73
|
-
* - `headline` →
|
|
70
|
+
* - `href` → KaiSourceItem.href
|
|
71
|
+
* - `label` → KaiSourceItem.label
|
|
72
|
+
* - `headline` → KaiSourceItem.title (matches kai-source's prop name; "title" is a
|
|
74
73
|
* reserved HTMLElement attribute so kai-source uses "headline")
|
|
75
|
-
* - `description` →
|
|
76
|
-
* - `show-favicon`→
|
|
74
|
+
* - `description` → KaiSourceItem.description
|
|
75
|
+
* - `show-favicon`→ KaiSourceItem.showFavicon (bare boolean attribute)
|
|
77
76
|
*/
|
|
78
|
-
export function parseKaiSourceElement(n: Element):
|
|
77
|
+
export function parseKaiSourceElement(n: Element): KaiSourceItem {
|
|
79
78
|
return {
|
|
80
79
|
href: n.getAttribute('href') ?? '',
|
|
81
80
|
label: n.getAttribute('label') ?? undefined,
|
|
@@ -92,7 +91,7 @@ defineWebComponent<SourceListProps>('kai-sources', {
|
|
|
92
91
|
}, (props, { element, flag }) => {
|
|
93
92
|
// Read declarative <kai-source> children from light DOM.
|
|
94
93
|
// The shadow root has no <slot> for them, so they are invisible — pure data carriers.
|
|
95
|
-
const [slottedSources, setSlottedSources] = createSignal<
|
|
94
|
+
const [slottedSources, setSlottedSources] = createSignal<KaiSourceItem[]>([]);
|
|
96
95
|
onMount(() => {
|
|
97
96
|
const read = () => {
|
|
98
97
|
const nodes = [...element.querySelectorAll('kai-source')];
|
|
@@ -105,7 +104,7 @@ defineWebComponent<SourceListProps>('kai-sources', {
|
|
|
105
104
|
});
|
|
106
105
|
|
|
107
106
|
// Prop sources take precedence; slotted children are appended after.
|
|
108
|
-
const allSources = () => [...props.sources, ...slottedSources()];
|
|
107
|
+
const allSources = () => [...(props.sources ?? []), ...slottedSources()];
|
|
109
108
|
|
|
110
109
|
const isNumbered = () => flag('numbered');
|
|
111
110
|
|
package/src/elements/switch.tsx
CHANGED
|
@@ -3,9 +3,9 @@ import { defineWebComponent } from './define';
|
|
|
3
3
|
import { Switch } from '../ui/switch';
|
|
4
4
|
|
|
5
5
|
interface Props extends Record<string, unknown> {
|
|
6
|
-
/** Controlled checked state
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
/** Controlled checked state. Settable and reflected to the `checked` attribute.
|
|
7
|
+
* `el.checked = true` (or `<kai-switch checked>`) drives it; the toggle UI updates
|
|
8
|
+
* it and fires `kai-change`. Read `el.checked` for live state. */
|
|
9
9
|
checked?: boolean;
|
|
10
10
|
/** Initial checked state on mount (uncontrolled seed). Bare attribute
|
|
11
11
|
* (`<kai-switch default-checked>`) turns it on. */
|
package/src/elements/tasks.tsx
CHANGED
|
@@ -6,7 +6,7 @@ interface Props extends Record<string, unknown> {
|
|
|
6
6
|
/** The tasks definition (the CardEnvelope.data). Set as a JS PROPERTY:
|
|
7
7
|
* `el.data = { tasks:[…], selectAll, confirmLabel, … }`. Import
|
|
8
8
|
* `TasksCardData` from `@kitn.ai/ui` for the full shape. */
|
|
9
|
-
data?:
|
|
9
|
+
data?: TasksCardData;
|
|
10
10
|
/** Stable card id correlating every emitted CardEvent. Attribute: `card-id`. */
|
|
11
11
|
cardId?: string;
|
|
12
12
|
/** Heading rendered in the card chrome (= CardEnvelope.title). Attribute: `heading`. */
|
|
@@ -29,7 +29,8 @@ interface Props extends Record<string, unknown> {
|
|
|
29
29
|
* contract event — `kai-value-change` is the live selection signal, distinct from
|
|
30
30
|
* the terminal submit.) */
|
|
31
31
|
interface Events {
|
|
32
|
-
/** The selection changed on a toggle
|
|
32
|
+
/** The selection changed on a toggle. Carries the selected ids in input
|
|
33
|
+
* order. */
|
|
33
34
|
'kai-value-change': { value: string[] };
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -72,7 +73,7 @@ defineWebComponent<Props, Events>(
|
|
|
72
73
|
select: (taskIds?: string[]) => controller?.select(taskIds),
|
|
73
74
|
/** Toggle one task by id, honoring the max gate (no `checked` = flip). */
|
|
74
75
|
toggle: (taskId: string, checked?: boolean) => controller?.toggle(taskId, checked),
|
|
75
|
-
/** Confirm the current selection
|
|
76
|
+
/** Confirm the current selection: emits the `submit` CardEvent + resolves
|
|
76
77
|
* (only when the min/max gate passes). Named `send`, not `submit`. */
|
|
77
78
|
send: () => controller?.send(),
|
|
78
79
|
/** Focus the task group (select-all checkbox if shown, else the first row). */
|
|
@@ -85,7 +86,7 @@ defineWebComponent<Props, Events>(
|
|
|
85
86
|
|
|
86
87
|
return (
|
|
87
88
|
<TasksCard
|
|
88
|
-
data={props.data
|
|
89
|
+
data={props.data}
|
|
89
90
|
cardId={props.cardId ?? (element.id || 'kai-tasks')}
|
|
90
91
|
heading={props.heading}
|
|
91
92
|
resolution={props.resolution as CardResolution | undefined}
|
package/src/elements/thread.tsx
CHANGED
|
@@ -2,17 +2,19 @@ import { createSignal, onMount, onCleanup } from 'solid-js';
|
|
|
2
2
|
import { defineWebComponent } from './define';
|
|
3
3
|
import { readSlots, THREAD_SLOTS } from './slots';
|
|
4
4
|
import { Thread, type ThreadController } from '../components/thread';
|
|
5
|
+
import { cardComponentsFromTags } from './message';
|
|
6
|
+
import { createMessagesGuard } from './validate-messages';
|
|
5
7
|
import type { ChatMessage } from './chat-types';
|
|
6
8
|
import type { ProseSize } from '../primitives/chat-config';
|
|
7
9
|
|
|
8
10
|
interface Props extends Record<string, unknown> {
|
|
9
11
|
/** The full message thread to render, newest last. Each entry carries its role,
|
|
10
|
-
*
|
|
12
|
+
* ordered `parts`, and optional actions/avatar/feedback. Set as a JS
|
|
11
13
|
* property (`el.messages = [...]`); a NEW array reference per streaming chunk
|
|
12
14
|
* re-renders (mutating in place does not). */
|
|
13
15
|
messages?: ChatMessage[];
|
|
14
|
-
/** Show a typing indicator on the pending assistant turn
|
|
15
|
-
* the assistant's reply. */
|
|
16
|
+
/** Show a typing indicator on the pending assistant turn. Set it while
|
|
17
|
+
* awaiting the assistant's reply. */
|
|
16
18
|
loading?: boolean;
|
|
17
19
|
/** Body/prose font scale for rendered markdown (`'xs' | 'sm' | 'base' | 'lg'`).
|
|
18
20
|
* Defaults to `'sm'`. */
|
|
@@ -30,6 +32,26 @@ interface Props extends Record<string, unknown> {
|
|
|
30
32
|
scrollButton?: boolean;
|
|
31
33
|
/** Extra classes applied to the thread's inner root. */
|
|
32
34
|
class?: string;
|
|
35
|
+
/** Optional card type -> custom-element tag overrides/additions for `card`
|
|
36
|
+
* parts (merged over the built-ins). Property: `el.cardTypes`. Typed as a
|
|
37
|
+
* plain string map (not the `CardTagMap` alias) so the generated React
|
|
38
|
+
* wrapper inlines it instead of emitting an unresolved named type. */
|
|
39
|
+
cardTypes?: Record<string, string>;
|
|
40
|
+
/** JSON Schemas for the card types this app renders, keyed by envelope type. The
|
|
41
|
+
* companion of `cardTypes`, which says what DRAWS a card while this says what a
|
|
42
|
+
* VALID one looks like. An OBJECT, so it is a JS property only: `el.cardSchemas
|
|
43
|
+
* = { 'pricing-table': pricingSchema }`, never an attribute.
|
|
44
|
+
* `createCardRegistry(...).validationSchemas` is exactly this shape.
|
|
45
|
+
*
|
|
46
|
+
* Without it the kit validates its own seven built-ins and leaves your own card
|
|
47
|
+
* type, the one your app actually cares about, as the only unchecked thing on
|
|
48
|
+
* screen. A schema here WINS over a built-in of the same name.
|
|
49
|
+
*
|
|
50
|
+
* Typed `Record<string, object>` rather than `Record<string, JsonSchema>`
|
|
51
|
+
* deliberately: an imported `.json` schema widens `"type"` to `string`, and an
|
|
52
|
+
* authored one carries `$schema`/`title`/`description`/`additionalProperties`,
|
|
53
|
+
* so the tighter type would reject both of the normal ways to supply one. */
|
|
54
|
+
cardSchemas?: Record<string, object>;
|
|
33
55
|
}
|
|
34
56
|
|
|
35
57
|
/** Events fired by `<kai-thread>`. */
|
|
@@ -61,9 +83,17 @@ defineWebComponent<Props, Events>('kai-thread', {
|
|
|
61
83
|
actionsReveal: 'always',
|
|
62
84
|
scrollButton: true,
|
|
63
85
|
class: undefined,
|
|
86
|
+
cardTypes: undefined,
|
|
87
|
+
cardSchemas: undefined,
|
|
64
88
|
}, (props, { element, dispatch, flag, expose }) => {
|
|
65
89
|
let controller: ThreadController | undefined;
|
|
66
90
|
|
|
91
|
+
// `messages` is an untyped boundary: a consumer can hand it anything at
|
|
92
|
+
// runtime (a pre-0.20.0 `{ id, role, content }` array, in particular). Skip
|
|
93
|
+
// the invalid entries rather than let `groupMessageParts` throw deep inside a
|
|
94
|
+
// render pass, which would blank the whole element instead of one message.
|
|
95
|
+
const validMessages = createMessagesGuard('kai-thread');
|
|
96
|
+
|
|
67
97
|
// Detect whether the consumer projected `slot="empty"` content, so the built-in
|
|
68
98
|
// default only renders when they did NOT.
|
|
69
99
|
const [slots, setSlots] = createSignal<Record<string, boolean>>({});
|
|
@@ -89,13 +119,15 @@ defineWebComponent<Props, Events>('kai-thread', {
|
|
|
89
119
|
<style>{':host{display:block;height:100%}'}</style>
|
|
90
120
|
<Thread
|
|
91
121
|
class={props.class as string | undefined}
|
|
92
|
-
messages={(props.messages
|
|
122
|
+
messages={validMessages(props.messages)}
|
|
93
123
|
loading={flag('loading')}
|
|
94
124
|
proseSize={props.proseSize as ProseSize}
|
|
95
125
|
codeTheme={props.codeTheme as string}
|
|
96
126
|
codeHighlight={flag('codeHighlight')}
|
|
97
127
|
actionsReveal={props.actionsReveal as 'always' | 'hover'}
|
|
98
128
|
scrollButton={props.scrollButton !== false}
|
|
129
|
+
cardTypes={cardComponentsFromTags(props.cardTypes as Record<string, string> | undefined, (props as { theme?: string }).theme)}
|
|
130
|
+
cardSchemas={props.cardSchemas as Record<string, object> | undefined}
|
|
99
131
|
empty={slots()['empty'] ? <slot name="empty" /> : undefined}
|
|
100
132
|
onMessageAction={(detail) => dispatch('kai-message-action', detail)}
|
|
101
133
|
controllerRef={(c) => (controller = c)}
|
package/src/elements/toast.tsx
CHANGED
|
@@ -4,8 +4,9 @@ import { toast as toastStore, type ToastItem } from '../primitives/toast-store';
|
|
|
4
4
|
|
|
5
5
|
interface Props extends Record<string, unknown> {
|
|
6
6
|
/** The toasts to render. Newest is shown on top. Set as a JS property (array);
|
|
7
|
-
* pass a new array reference to update.
|
|
8
|
-
|
|
7
|
+
* pass a new array reference to update. Omit for an empty region, which is
|
|
8
|
+
* the normal resting state and how the imperative `toast()` API starts. */
|
|
9
|
+
toasts?: ToastItem[];
|
|
9
10
|
/** Stack anchor: `'top-center'` (default), `'top-right'`, `'bottom-center'`, … */
|
|
10
11
|
position?: ToastPosition;
|
|
11
12
|
/** Max simultaneously-visible toasts; the rest queue. Defaults to `3`. */
|
package/src/elements/tool.tsx
CHANGED
|
@@ -13,7 +13,7 @@ interface Props extends Record<string, unknown> {
|
|
|
13
13
|
open?: boolean;
|
|
14
14
|
/** Initial open state on mount (uncontrolled seed). */
|
|
15
15
|
defaultOpen?: boolean;
|
|
16
|
-
/** Gate the disclosure trigger
|
|
16
|
+
/** Gate the disclosure trigger: programmatic `show()/hide()/toggle()` still
|
|
17
17
|
* work, but the trigger click no longer toggles. */
|
|
18
18
|
disabled?: boolean;
|
|
19
19
|
}
|