@kitn.ai/ui 0.27.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/dist/{Icon-BnFKqqtY.js → Icon-DObhsRtm.js} +1 -1
- package/dist/{action-icons-CBskfBMz.js → action-icons-CcgNN2oT.js} +1 -1
- package/dist/arrow-down-CjRU3JgV.js +1 -0
- package/dist/arrow-left-Bnpb1UEW.js +1 -0
- package/dist/{artifact-CvXEm1lS.js → artifact-Bwt7OgcR.js} +1 -1
- package/dist/{attachments-C43ZegEq.js → attachments-Qr4kg-2b.js} +1 -1
- package/dist/{audio-visualizer-B-79y1Tj.js → audio-visualizer-DToYdfSc.js} +1 -1
- package/dist/{badge-BpUbq8c0.js → badge-CdEu_jn2.js} +1 -1
- package/dist/{bell-sn17Ip9v.js → bell-DQAAOpDz.js} +1 -1
- package/dist/{button-BH6rN0U-.js → button-DkuOnGLy.js} +1 -1
- package/dist/{card-renderer-Cb1gQmth.js → card-renderer-Jx70m6_l.js} +1 -1
- package/dist/{card-routing-DifQgS7n.js → card-routing-0YidER_3.js} +1 -1
- package/dist/check-njkVdZu2.js +1 -0
- package/dist/{checkbox-Dc9Yov_B.js → checkbox-D7iRB3nL.js} +1 -1
- package/dist/{checkbox-group-B1kDLLYk.js → checkbox-group-B2_rpoPM.js} +1 -1
- package/dist/chevron-down-B72s6PXR.js +1 -0
- package/dist/chevron-right-BatuHzUm.js +1 -0
- package/dist/{choice-card-BT3c1S8g.js → choice-card-m0BYqqOK.js} +1 -1
- package/dist/circle-check-B62pODB3.js +1 -0
- package/dist/{circle-x-wobWkoSx.js → circle-x-BPG0iPst.js} +1 -1
- package/dist/circle-zx0ByzY9.js +1 -0
- package/dist/code-block-ClMLKb7C.js +1 -0
- package/dist/{collapsible-CPJbf6FM.js → collapsible-B4DlWicL.js} +1 -1
- package/dist/components/chat-thread.d.ts +89 -1
- package/dist/components/conversation-item.d.ts +16 -0
- package/dist/components/conversation-panel.d.ts +29 -0
- package/dist/components/home-panel.d.ts +34 -0
- package/dist/components/widget-tab-bar.d.ts +16 -0
- package/dist/{composer-CjngLzal.js → composer-sQ0HcvyG.js} +3 -3
- package/dist/{confirm-card-DCx_A4bU.js → confirm-card-rQWDQsnC.js} +1 -1
- package/dist/construct-cli.es.js +182 -14
- package/dist/{context-BY8V-Nlp.js → context-0kg4ZX1J.js} +1 -1
- package/dist/controllable-CnGpMF6r.js +1 -0
- package/dist/conversation-item-BxwQLaFJ.js +1 -0
- package/dist/conversation-list-BCfGN1JU.js +1 -0
- package/dist/{copy-B6DO4PqB.js → copy-n9u9rqpi.js} +1 -1
- package/dist/{create-tween-CnMHviKB.js → create-tween-C-q-JCM-.js} +1 -1
- package/dist/{create-tween-D1aiGZZh.js → create-tween-CRrJXxBd.js} +1 -1
- package/dist/{create-tween-BPzaefTp.js → create-tween-DZ3RRDHD.js} +1 -1
- package/dist/{create-tween-DUSQUKpr.js → create-tween-uPkArjIG.js} +1 -1
- package/dist/custom-elements.json +51 -2
- package/dist/{default-input-CucQEOqH.js → default-input-CaMrJkgH.js} +1 -1
- package/dist/define-By-uL588.js +1 -0
- package/dist/define.js +2 -2
- package/dist/define.server.js +2 -2
- package/dist/{disclosure-CbLtajUQ.js → disclosure-WUImBbDv.js} +1 -1
- package/dist/{dropdown-BwhViJFd.js → dropdown-wZVeJOMd.js} +1 -1
- package/dist/elements/agent-card.js +1 -1
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/audio-visualizer.js +1 -1
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/badge.js +1 -1
- package/dist/elements/button.js +1 -1
- package/dist/elements/card.js +1 -1
- package/dist/elements/cards.js +1 -1
- package/dist/elements/chain-of-thought.js +1 -1
- package/dist/elements/chat-scope-picker.js +1 -1
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkbox-group.js +1 -1
- package/dist/elements/checkbox.js +1 -1
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/coachmark.js +1 -1
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.js +1 -1
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.js +1 -1
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-item.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.js +3 -3
- package/dist/elements/dropdown.js +1 -1
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.js +1 -1
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-grid.js +1 -1
- package/dist/elements/pane-group.js +1 -1
- package/dist/elements/pane.js +1 -1
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.js +1 -1
- package/dist/elements/prompt-dock.js +1 -1
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/radio-group.js +1 -1
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +1 -1
- package/dist/elements/screen.js +1 -1
- package/dist/elements/scroll-area.js +1 -1
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.js +1 -1
- package/dist/elements/segmented.js +1 -1
- package/dist/elements/select.js +1 -1
- package/dist/elements/separator.js +1 -1
- package/dist/elements/setting-item.js +1 -1
- package/dist/elements/settings-group.js +1 -1
- package/dist/elements/skeleton.js +1 -1
- package/dist/elements/slider.js +1 -1
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.js +1 -1
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.js +1 -1
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/thread.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.js +1 -1
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/elements.d.ts +20 -4
- package/dist/{ellipsis-DFr4Vqr3.js → ellipsis-CbOpJnU3.js} +1 -1
- package/dist/{embed-5s_vU4J0.js → embed-CrfjkbUG.js} +1 -1
- package/dist/{external-link-u9d85ORQ.js → external-link-ByXAwBBQ.js} +1 -1
- package/dist/{file-text-CX7_x42o.js → file-text-DMib2qwt.js} +1 -1
- package/dist/{file-tree-D3kBjXI5.js → file-tree-CJqM2aP7.js} +1 -1
- package/dist/{folder-V-YdIL8f.js → folder-_BAb929C.js} +1 -1
- package/dist/{form-BRNUMCN2.js → form-DSZgZQZk.js} +1 -1
- package/dist/{hover-card-DaeiYrTA.js → hover-card-BQbul9eq.js} +1 -1
- package/dist/{icon-BpixdZNq.js → icon-CdcfRhYI.js} +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2842 -2703
- package/dist/index.server.js +2820 -2681
- package/dist/{info-8mFsIjS3.js → info-DsFjGuI_.js} +1 -1
- package/dist/{input-d1Yuu-hz.js → input-DKbmkMos.js} +1 -1
- package/dist/kai.es.js +1 -1
- package/dist/{kbd-961zMPFB.js → kbd-PvdGhX4s.js} +1 -1
- package/dist/{link-preview-DIIbV2Sd.js → link-preview-DbM1866N.js} +1 -1
- package/dist/{link-DlZZBGaR.js → link-zF8PzWfF.js} +1 -1
- package/dist/{loader-YQszHFaW.js → loader-BM4CEz4G.js} +1 -1
- package/dist/{markdown-CVk1MPsj.js → markdown-LMvmAyBk.js} +7 -7
- package/dist/mcp.es.js +78 -4
- package/dist/{message-CwKVEdZg.js → message-BSsgvHvf.js} +1 -1
- package/dist/{message-DS8lzHc1.js → message-BYZECyek.js} +1 -1
- package/dist/message-circle-DruwObfX.js +1 -0
- package/dist/message-square-BG6q6mlm.js +1 -0
- package/dist/{minimize-2-UEZmP2QT.js → minimize-2-BQRoBV1V.js} +1 -1
- package/dist/{model-switcher-Kk1jEQ5t.js → model-switcher-CMpCOYcB.js} +1 -1
- package/dist/{overlay-C1od6LOz.js → overlay-Cb-MkyDa.js} +1 -1
- package/dist/{panel-right-ryET0yyn.js → panel-right-i8warFxT.js} +1 -1
- package/dist/{paperclip-BDNoZFJP.js → paperclip-ByY3UVO6.js} +1 -1
- package/dist/play-BvKKq3fX.js +1 -0
- package/dist/primitives/conversation-store.d.ts +54 -0
- package/dist/{progress-bar-BvYX0aoy.js → progress-bar-jVAHvMUf.js} +1 -1
- package/dist/{prompt-suggestion-BRFu2lcu.js → prompt-suggestion-CD-qtNgC.js} +1 -1
- package/dist/{radio-DcL23cNJ.js → radio-BsoBMhkF.js} +1 -1
- package/dist/react/index.d.ts +393 -0
- package/dist/react.js +20 -20
- package/dist/{reasoning-Cackq4Rh.js → reasoning-4kBPtlTx.js} +1 -1
- package/dist/register-impl-B1hLkrI8.js +424 -0
- package/dist/{resizable-Cp9HUYih.js → resizable-uPmY9VY-.js} +1 -1
- package/dist/{rotate-ccw-0DLRDHH5.js → rotate-ccw-B2xn93py.js} +1 -1
- package/dist/{rotate-cw-DOB9IGcU.js → rotate-cw-CMVLoCyH.js} +1 -1
- package/dist/{scroll-area-emVmWP4K.js → scroll-area-BqLUo8ZZ.js} +1 -1
- package/dist/{scroll-button-CeP_gv1x.js → scroll-button-DslXiJyL.js} +1 -1
- package/dist/{select-CWmu00tS.js → select-2cLRtPGT.js} +1 -1
- package/dist/{separator-CE6vly6z.js → separator-BWQtNJcM.js} +1 -1
- package/dist/{settings-CE-78SvZ.js → settings-BBR63jLg.js} +1 -1
- package/dist/{settings-group-ZFWNxFQR.js → settings-group-B2ciy-Iw.js} +1 -1
- package/dist/{skeleton-BebdP4mf.js → skeleton-CkHI-HgC.js} +1 -1
- package/dist/{slider-BAKRYUlz.js → slider-DDR9U-i0.js} +1 -1
- package/dist/{solid-BE5ui6sy.js → solid-BzCFdL25.js} +7720 -7058
- package/dist/{solid-DFhsce3O.js → solid-DruVOXnf.js} +5864 -5283
- package/dist/solid.d.ts +6 -2
- package/dist/solid.js +217 -210
- package/dist/solid.server.js +217 -210
- package/dist/{source-B0FlguSx.js → source-GEnFF528.js} +1 -1
- package/dist/{star-CBMZvLuN.js → star-CilHq8GP.js} +1 -1
- package/dist/store-Ciyk6eZG.js +1 -0
- package/dist/{switch-CViARZCy.js → switch-KkeQIbuH.js} +1 -1
- package/dist/{tasks-card-MjCcOhR_.js → tasks-card-BrN4bggJ.js} +1 -1
- package/dist/{text-shimmer-DKlwRF2G.js → text-shimmer-Dcj1MHuq.js} +1 -1
- package/dist/{textarea-3ay2Me2-.js → textarea-Dpvbngbg.js} +1 -1
- package/dist/theme.tokens.css +28 -0
- package/dist/{thumbs-up-DQcu2HMO.js → thumbs-up-CsT9Wzb9.js} +1 -1
- package/dist/{toast-store-C6yKOhbk.js → toast-store-tgK6MuMv.js} +1 -1
- package/dist/{tool-BCYNlfKy.js → tool-DzUjIBT8.js} +1 -1
- package/dist/{tooltip-05zI4hjs.js → tooltip-Bkkg_4t0.js} +1 -1
- package/dist/{trash-2-BR1RxGky.js → trash-2-jBKxjGGQ.js} +1 -1
- package/dist/{triangle-alert-DHohDOCy.js → triangle-alert-DlQ68ppf.js} +1 -1
- package/dist/types.d.ts +48 -3
- package/dist/ui/dock.d.ts +29 -0
- package/dist/{upload-BbGW6A_u.js → upload-TcAHXv9W.js} +1 -1
- package/dist/{url-scheme-policy-DHpoTJwB.js → url-scheme-policy-DR5DgvkM.js} +1 -1
- package/dist/{use-card-resolution-CJW4grFa.js → use-card-resolution-DaZqAdWf.js} +1 -1
- package/dist/{variant-aurora-xiMPty8f.js → variant-aurora-BhLuYxJR.js} +1 -1
- package/dist/{variant-aurora-BUOVgPOB.js → variant-aurora-CNmfHhcx.js} +2 -2
- package/dist/{variant-aurora-CUsUJvFI.js → variant-aurora-D6GsdTPA.js} +2 -2
- package/dist/{variant-aurora-CW2i4bfr.js → variant-aurora-DbW_OWL2.js} +1 -1
- package/dist/{variant-custom-D91HjAKz.js → variant-custom-BRvaNHSi.js} +1 -1
- package/dist/{variant-custom-BQtOnmeO.js → variant-custom-BvYHR62b.js} +1 -1
- package/dist/{variant-custom-CAnzzppW.js → variant-custom-DMTrEO5w.js} +2 -2
- package/dist/{variant-custom-CAm9L-E5.js → variant-custom-DV2x254s.js} +2 -2
- package/dist/{variant-wave-Ca1Ls4_y.js → variant-wave-BNMGrDfj.js} +2 -2
- package/dist/{variant-wave-uY5crU_K.js → variant-wave-BpDd8t3Z.js} +1 -1
- package/dist/{variant-wave-CxX39DKd.js → variant-wave-CyBueXj9.js} +2 -2
- package/dist/{variant-wave-DYyzIIZv.js → variant-wave-sp-qwsdI.js} +1 -1
- package/dist/x-Z5UntkIJ.js +1 -0
- package/frameworks/react/index.tsx +14 -4
- package/llms-full.txt +7 -2
- package/package.json +1 -1
- package/src/agent-tooling/README.md +192 -0
- package/src/agent-tooling/catalog/invariants.ts +2 -2
- package/src/agent-tooling/construct/cli.ts +16 -0
- package/src/agent-tooling/construct/codegen.ts +309 -27
- package/src/agent-tooling/construct/construct.v1.schema.json +69 -0
- package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +11 -2
- package/src/agent-tooling/construct/schema.ts +81 -0
- package/src/components/chat-thread.tsx +532 -36
- package/src/components/conversation-item.tsx +23 -0
- package/src/components/conversation-panel.tsx +118 -0
- package/src/components/home-panel.tsx +159 -0
- package/src/components/widget-tab-bar.tsx +73 -0
- package/src/elements/chat.tsx +94 -2
- package/src/elements/compiled.css +1 -1
- package/src/elements/element-meta.json +49 -6
- package/src/elements/element-nonscalar.json +2 -0
- package/src/elements/element-types.d.ts +20 -4
- package/src/index.ts +3 -1
- package/src/primitives/conversation-store.ts +248 -0
- package/src/solid.ts +10 -2
- package/src/types.ts +45 -3
- package/src/ui/dock.tsx +47 -1
- package/theme.css +28 -0
- package/dist/arrow-down-Br0qtpsz.js +0 -1
- package/dist/arrow-left-Dj7xgE12.js +0 -1
- package/dist/check-DPeeMUYx.js +0 -1
- package/dist/chevron-down-CHSWk7ZT.js +0 -1
- package/dist/chevron-right-B7l_fMgx.js +0 -1
- package/dist/circle-Bb0yOpqM.js +0 -1
- package/dist/circle-check-BGZpCiz7.js +0 -1
- package/dist/code-block-CUQ5mtv0.js +0 -1
- package/dist/controllable-D43BKmtX.js +0 -1
- package/dist/conversation-list-D4lLU_yS.js +0 -1
- package/dist/define-CGGX-7Vg.js +0 -1
- package/dist/message-circle-Xf8Q-vZp.js +0 -1
- package/dist/message-square-Cxnwgkns.js +0 -1
- package/dist/play-OFIvYXUQ.js +0 -1
- package/dist/register-impl-C7rENvPK.js +0 -424
- package/dist/store-7eoadydQ.js +0 -1
- package/dist/x-C5m1JFgi.js +0 -1
package/dist/construct-cli.es.js
CHANGED
|
@@ -57,6 +57,21 @@ const ConstructSchema = z.object({
|
|
|
57
57
|
theme: z.object({
|
|
58
58
|
/** Any CSS color; becomes --kai-color-primary on the host. */
|
|
59
59
|
accent: z.string().optional(),
|
|
60
|
+
/** Any CSS color; becomes --kai-color-unread on the host (owner
|
|
61
|
+
* ruling, 2026-08-26 — the unread-indicator round). Same treatment
|
|
62
|
+
* as `accent` in every way that matters for safety: construct-
|
|
63
|
+
* authored/untrusted text, carried to the emitted facade via
|
|
64
|
+
* `ctx.element.style.setProperty('--kai-color-unread',
|
|
65
|
+
* JSON.stringify(...))` — never string-interpolated into CSS
|
|
66
|
+
* text — so it can never break out into a new declaration or rule
|
|
67
|
+
* (see emitElement's doc on why `accent` uses setProperty at all).
|
|
68
|
+
* Unlike `accent`, this has no paired -foreground to compute: the
|
|
69
|
+
* three surfaces that read --color-unread (the conversation-list
|
|
70
|
+
* row dot, the header toggle's badge, Dock's own closed-launcher
|
|
71
|
+
* badge) are all small filled dots with no text sitting ON them, so
|
|
72
|
+
* there is nothing to contrast-pair — the value is set and used
|
|
73
|
+
* as-is. */
|
|
74
|
+
unreadColor: z.string().optional(),
|
|
60
75
|
mode: z.enum(["light", "dark", "system"]).default("system")
|
|
61
76
|
}).strict().optional(),
|
|
62
77
|
/** Construct-wide header chrome, valid on every layout (not layout-scoped
|
|
@@ -90,6 +105,30 @@ const ConstructSchema = z.object({
|
|
|
90
105
|
description: z.string().min(1).optional(),
|
|
91
106
|
icon: z.string().min(1).optional()
|
|
92
107
|
}).strict().optional(),
|
|
108
|
+
/** Home screen (spec 2026-08-27, H-1..H-5): Intercom-style landing view behind
|
|
109
|
+
* a Home/Messages tab bar. PRESENCE of `home` enables the tab chrome (H-4) —
|
|
110
|
+
* no `enabled` boolean, like `header`/`empty`. Every sub-key optional;
|
|
111
|
+
* `home: {}` still means "tabs on, defaults". Never requires another
|
|
112
|
+
* capability (H-3): the recent card simply renders nothing without
|
|
113
|
+
* `capabilities.conversations` (the CLI warns — see cli.ts). All strings are
|
|
114
|
+
* construct-authored/untrusted: JSON.stringify'd at every emit site; hrefs
|
|
115
|
+
* and URL-shaped icons through isSafeUrl in superRefine below. */
|
|
116
|
+
home: z.object({
|
|
117
|
+
greeting: z.object({ title: z.string().min(1).optional(), subtitle: z.string().min(1).optional() }).strict().optional(),
|
|
118
|
+
recentConversation: z.literal(true).optional(),
|
|
119
|
+
newConversation: z.object({ label: z.string().min(1).optional() }).strict().optional(),
|
|
120
|
+
links: z.array(
|
|
121
|
+
z.object({
|
|
122
|
+
label: z.string().min(1),
|
|
123
|
+
href: z.string().min(1).optional(),
|
|
124
|
+
description: z.string().min(1).optional(),
|
|
125
|
+
/** renderIcon name (e.g. 'book-open') or a safe URL — the icon NAME
|
|
126
|
+
* list is renderIcon's own vocabulary, never restated here; unknown
|
|
127
|
+
* names warn loudly at DEV runtime. */
|
|
128
|
+
icon: z.string().min(1).optional()
|
|
129
|
+
}).strict()
|
|
130
|
+
).optional()
|
|
131
|
+
}).strict().optional(),
|
|
93
132
|
// Capability vocabulary, widened one field at a time by later tasks.
|
|
94
133
|
capabilities: z.object({
|
|
95
134
|
/** Starter prompts shown on the empty thread; clicking one sends it.
|
|
@@ -143,7 +182,18 @@ const ConstructSchema = z.object({
|
|
|
143
182
|
* Meaningless when `reasoning` is `'compact'` (no expandable
|
|
144
183
|
* content exists) or `'off'` (nothing renders); rejected on both,
|
|
145
184
|
* loudly, below. */
|
|
146
|
-
reasoningOpen: z.boolean().optional()
|
|
185
|
+
reasoningOpen: z.boolean().optional(),
|
|
186
|
+
/** Turns on the prior-conversations list (C-1..C-9 of the
|
|
187
|
+
* conversations design). `true` only — there is no `false` form,
|
|
188
|
+
* matching this schema's other presence-only capability flags.
|
|
189
|
+
* Requires `capabilities.history.persistence` to be `local` or
|
|
190
|
+
* `endpoint` (superRefine below, loud): a conversation list with
|
|
191
|
+
* nowhere to persist conversations is not a coherent construct.
|
|
192
|
+
* WHAT persists (this field, plus history) stays construct
|
|
193
|
+
* vocabulary; HOW it persists (the ConversationStore adapter,
|
|
194
|
+
* localStorage vs. a fetch endpoint) is codegen's call, never
|
|
195
|
+
* vocabulary here (C-3 — no transport-layer vocabulary). */
|
|
196
|
+
conversations: z.literal(true).optional()
|
|
147
197
|
}).strict().optional(),
|
|
148
198
|
/** Named generative-UI card definitions the model can emit as tool calls,
|
|
149
199
|
* rendered in the thread. Top-level (not a capability): a card is
|
|
@@ -253,6 +303,30 @@ const ConstructSchema = z.object({
|
|
|
253
303
|
});
|
|
254
304
|
}
|
|
255
305
|
const history = construct.capabilities?.history;
|
|
306
|
+
if (construct.capabilities?.conversations && (!history || history.persistence === "none")) {
|
|
307
|
+
ctx.addIssue({
|
|
308
|
+
code: z.ZodIssueCode.custom,
|
|
309
|
+
path: ["capabilities", "conversations"],
|
|
310
|
+
message: '"conversations" requires capabilities.history.persistence to be "local" or "endpoint" — a conversation list needs somewhere to persist conversations'
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
const URL_SHAPED = /^[a-zA-Z][a-zA-Z0-9+.-]*:|^\/\//;
|
|
314
|
+
for (const [i, link] of (construct.home?.links ?? []).entries()) {
|
|
315
|
+
if (link.href && !isSafeUrl(link.href)) {
|
|
316
|
+
ctx.addIssue({
|
|
317
|
+
code: z.ZodIssueCode.custom,
|
|
318
|
+
path: ["home", "links", i, "href"],
|
|
319
|
+
message: "href must be an http(s)/mailto or relative URL — no javascript:/data: schemes"
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
if (link.icon && URL_SHAPED.test(link.icon) && !isSafeUrl(link.icon)) {
|
|
323
|
+
ctx.addIssue({
|
|
324
|
+
code: z.ZodIssueCode.custom,
|
|
325
|
+
path: ["home", "links", i, "icon"],
|
|
326
|
+
message: "icon must be a kit icon name or an http(s)/relative URL — no javascript:/data: schemes"
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}
|
|
256
330
|
if (!history) return;
|
|
257
331
|
if (history.persistence === "endpoint" && !history.url) {
|
|
258
332
|
ctx.addIssue({
|
|
@@ -564,11 +638,26 @@ function emitIndexHtml(c) {
|
|
|
564
638
|
}
|
|
565
639
|
function emitElement(c) {
|
|
566
640
|
const accent = c.theme?.accent;
|
|
567
|
-
|
|
641
|
+
const unreadColor = c.theme?.unreadColor;
|
|
642
|
+
if (!accent && !unreadColor) {
|
|
568
643
|
const facade2 = "() => <App />";
|
|
569
644
|
return `import { defineWebComponent } from '@kitn.ai/ui/define';
|
|
570
645
|
import { App } from './App';
|
|
571
646
|
|
|
647
|
+
// The one facade. Interior stays pure Solid (no nested element registrations);
|
|
648
|
+
// the kit CSS is injected into the shadow root by defineWebComponent itself.
|
|
649
|
+
defineWebComponent('${c.name}', { theme: '${themeMode(c)}' as 'light' | 'dark' | 'auto' }, ${facade2});
|
|
650
|
+
`;
|
|
651
|
+
}
|
|
652
|
+
const unreadColorSetProperty = unreadColor ? `
|
|
653
|
+
ctx.element.style.setProperty('--kai-color-unread', ${JSON.stringify(unreadColor)});` : "";
|
|
654
|
+
if (!accent) {
|
|
655
|
+
const facade2 = `(_props, ctx) => {${unreadColorSetProperty}
|
|
656
|
+
return <App />;
|
|
657
|
+
}`;
|
|
658
|
+
return `import { defineWebComponent } from '@kitn.ai/ui/define';
|
|
659
|
+
import { App } from './App';
|
|
660
|
+
|
|
572
661
|
// The one facade. Interior stays pure Solid (no nested element registrations);
|
|
573
662
|
// the kit CSS is injected into the shadow root by defineWebComponent itself.
|
|
574
663
|
defineWebComponent('${c.name}', { theme: '${themeMode(c)}' as 'light' | 'dark' | 'auto' }, ${facade2});
|
|
@@ -589,7 +678,7 @@ defineWebComponent('${c.name}', { theme: '${themeMode(c)}' as 'light' | 'dark' |
|
|
|
589
678
|
:host { --kai-color-primary-foreground: contrast-color(var(--kai-color-primary)); }
|
|
590
679
|
}`;
|
|
591
680
|
const facade = `(_props, ctx) => {
|
|
592
|
-
ctx.element.style.setProperty('--kai-color-primary', ${JSON.stringify(accent)})
|
|
681
|
+
ctx.element.style.setProperty('--kai-color-primary', ${JSON.stringify(accent)});${unreadColorSetProperty}
|
|
593
682
|
return (
|
|
594
683
|
<>
|
|
595
684
|
<style>{${JSON.stringify(styleText)}}</style>
|
|
@@ -607,10 +696,11 @@ defineWebComponent('${c.name}', { theme: '${themeMode(c)}' as 'light' | 'dark' |
|
|
|
607
696
|
}
|
|
608
697
|
function emitApp(c) {
|
|
609
698
|
if (c.layout === "custom") return emitCustomApp(c);
|
|
610
|
-
return `${emitSolidJsImport(c)}import { ChatThread, createKaiChat${emitLayoutImport(c)}${emitCardComponentImport(c)}${emitEmptyComponentImport(c)}${emitHeaderCloseImport(c)} } from '@kitn.ai/ui/solid';
|
|
611
|
-
import type { AttachmentData${emitHistoryTypeImport(c)} } from '@kitn.ai/ui/solid';
|
|
699
|
+
return `${emitSolidJsImport(c)}${emitConversationsSignalsImport(c)}import { ChatThread, createKaiChat${emitLayoutImport(c)}${emitCardComponentImport(c)}${emitEmptyComponentImport(c)}${emitHeaderCloseImport(c)} } from '@kitn.ai/ui/solid';
|
|
700
|
+
import type { AttachmentData${emitHistoryTypeImport(c)}${emitConversationsResetTypeImport(c)} } from '@kitn.ai/ui/solid';
|
|
612
701
|
${emitProviderImports(c)}
|
|
613
702
|
${emitCardsImport(c)}
|
|
703
|
+
${emitConversationsImport(c)}
|
|
614
704
|
|
|
615
705
|
${emitProviderSetup(c)}
|
|
616
706
|
${emitHistorySetup(c)}
|
|
@@ -679,9 +769,26 @@ ${emitHistorySetup(c)}
|
|
|
679
769
|
// emitDockCloseVar/emitHeaderEndContentProp's docs. No header means no
|
|
680
770
|
// row for it to sit in, so that case is untouched and Dock's own built-in
|
|
681
771
|
// mobile X keeps covering it.
|
|
772
|
+
// - conversations (Task 5): gated via ChatThread's own \`conversations\`/
|
|
773
|
+
// \`store\` props (kit-owned end to end — the prior-conversations list,
|
|
774
|
+
// list/load/save, autosave on every \`chat.messages()\` change). Requires
|
|
775
|
+
// capabilities.history persistence \`local\` or \`endpoint\` (schema
|
|
776
|
+
// superRefine, C-4) and SUBSUMES this file's hand-rolled history effect
|
|
777
|
+
// when on — see emitHistorySetup's own doc for the persistence-ownership
|
|
778
|
+
// decision: the store prop is the ONLY persistence mechanism emitted,
|
|
779
|
+
// never both. ChatThread never mutates \`messages\` itself, so
|
|
780
|
+
// \`onConversationLoad\` is ALSO wired here (\`chat.setMessages(() =>
|
|
781
|
+
// messages)\`) — without it, select/new/mount-restore all update
|
|
782
|
+
// ChatThread's own internal view/list state while the rendered thread
|
|
783
|
+
// never changes (see emitConversationsProps's own doc for the Task 6
|
|
784
|
+
// live-browser bug this fixes).
|
|
785
|
+
// - conversations + widget (owner follow-up): closing the widget while its
|
|
786
|
+
// list view is open must not leave it there for the next open — see
|
|
787
|
+
// widgetHasConversationsChrome/emitDockOnOpenChangeProp's docs. Wired only
|
|
788
|
+
// for \`widget\`, the one layout with something that closes/reopens at all.
|
|
682
789
|
export function App() {
|
|
683
|
-
${emitDockCloseVar(c, " ")} return (
|
|
684
|
-
${emitLayoutOpen(c)}${emitSlots(c.slots, " ")} <ChatThread messages={chat.messages()} loading={chat.loading()} placeholder="Ask anything" onSubmit={submit} webSearch={false} voice={false}${emitHeaderProp(c)}${emitHeaderEndContentProp(c)}${emitAttachProps(c)}${emitStartersProp(c)}${emitReasoningProp(c)}${emitReasoningOpenProp(c)}${emitEmptyContentProp(c)}${emitCardTypesProp(c)} />
|
|
790
|
+
${emitDockCloseVar(c, " ")}${emitChatControllerVar(c, " ")}${emitConversationsSignalsVar(c, " ")} return (
|
|
791
|
+
${emitLayoutOpen(c)}${emitSlots(c.slots, " ")} <ChatThread messages={chat.messages()} loading={chat.loading()} placeholder="Ask anything" onSubmit={submit} webSearch={false} voice={false}${emitHeaderProp(c)}${emitHeaderEndContentProp(c)}${emitAttachProps(c)}${emitStartersProp(c)}${emitReasoningProp(c)}${emitReasoningOpenProp(c)}${emitEmptyContentProp(c)}${emitCardTypesProp(c)}${emitHomeProp(c)}${emitConversationsProps(c)}${emitChatControllerRefProp(c)}${emitChatThreadUnreadProps(c)} />
|
|
685
792
|
${emitLayoutClose(c)} );
|
|
686
793
|
}
|
|
687
794
|
`;
|
|
@@ -703,8 +810,8 @@ ${emitHistorySetup(c)}
|
|
|
703
810
|
// layout: custom — minimal chrome, no ChatThread/Dock/PaneGroup. The bare
|
|
704
811
|
// spine (Thread + PromptInput) plus the declared slots, positioned by hand so
|
|
705
812
|
// YOU own the surrounding DOM. Capabilities beyond the spine (starters,
|
|
706
|
-
// attachments, reasoning display-mode, reasoningOpen, header.title, empty
|
|
707
|
-
// are NOT wired here in v1 — this file is the eject artifact; add them the
|
|
813
|
+
// attachments, reasoning display-mode, reasoningOpen, header.title, empty,
|
|
814
|
+
// conversations) are NOT wired here in v1 — this file is the eject artifact; add them the
|
|
708
815
|
// way ChatThread composes them (components/chat-thread.tsx in the kit's own
|
|
709
816
|
// source) if this construct needs them on a custom layout.
|
|
710
817
|
export function App() {
|
|
@@ -757,6 +864,40 @@ function emitEmptyComponentImport(c) {
|
|
|
757
864
|
function widgetHasHeaderClose(c) {
|
|
758
865
|
return c.layout === "widget" && !!c.header?.title;
|
|
759
866
|
}
|
|
867
|
+
function widgetHasConversationsChrome(c) {
|
|
868
|
+
return c.layout === "widget" && (!!c.capabilities?.conversations || !!c.home);
|
|
869
|
+
}
|
|
870
|
+
function emitChatControllerVar(c, indent) {
|
|
871
|
+
return widgetHasConversationsChrome(c) ? `${indent}let chatController: ChatThreadController | undefined;
|
|
872
|
+
` : "";
|
|
873
|
+
}
|
|
874
|
+
function emitChatControllerRefProp(c) {
|
|
875
|
+
return widgetHasConversationsChrome(c) ? " controllerRef={(api) => (chatController = api)}" : "";
|
|
876
|
+
}
|
|
877
|
+
function emitDockOnOpenChangeProp(c) {
|
|
878
|
+
return widgetHasConversationsChrome(c) ? " onOpenChange={(open) => { setDockOpen(open); if (!open) chatController?.closeConversationsList(); }}" : "";
|
|
879
|
+
}
|
|
880
|
+
function emitConversationsResetTypeImport(c) {
|
|
881
|
+
return widgetHasConversationsChrome(c) ? ", ChatThreadController" : "";
|
|
882
|
+
}
|
|
883
|
+
function emitConversationsSignalsImport(c) {
|
|
884
|
+
return widgetHasConversationsChrome(c) ? `import { createSignal } from 'solid-js';
|
|
885
|
+
` : "";
|
|
886
|
+
}
|
|
887
|
+
function emitConversationsSignalsVar(c, indent) {
|
|
888
|
+
if (!widgetHasConversationsChrome(c)) return "";
|
|
889
|
+
const w = c.layout === "widget" ? c.widget : void 0;
|
|
890
|
+
const defaultOpen = w?.defaultOpen === true ? "true" : "false";
|
|
891
|
+
return `${indent}const [dockOpen, setDockOpen] = createSignal(${defaultOpen});
|
|
892
|
+
${indent}const [anyUnread, setAnyUnread] = createSignal(false);
|
|
893
|
+
`;
|
|
894
|
+
}
|
|
895
|
+
function emitChatThreadUnreadProps(c) {
|
|
896
|
+
return widgetHasConversationsChrome(c) ? " hostOpen={dockOpen()} onUnreadChange={setAnyUnread}" : "";
|
|
897
|
+
}
|
|
898
|
+
function emitDockUnreadProp(c) {
|
|
899
|
+
return widgetHasConversationsChrome(c) ? " unread={anyUnread()}" : "";
|
|
900
|
+
}
|
|
760
901
|
function emitDockCloseVar(c, indent) {
|
|
761
902
|
return widgetHasHeaderClose(c) ? `${indent}let dockClose: (() => void) | undefined;
|
|
762
903
|
` : "";
|
|
@@ -792,15 +933,30 @@ function emitReasoningProp(c) {
|
|
|
792
933
|
function emitReasoningOpenProp(c) {
|
|
793
934
|
return c.capabilities?.reasoningOpen === true ? " reasoningOpen={true}" : "";
|
|
794
935
|
}
|
|
936
|
+
function emitHomeProp(c) {
|
|
937
|
+
if (!c.home) return "";
|
|
938
|
+
return ` home={${JSON.stringify(c.home)}}`;
|
|
939
|
+
}
|
|
940
|
+
function emitConversationsProps(c) {
|
|
941
|
+
if (!c.capabilities?.conversations) return "";
|
|
942
|
+
const history = c.capabilities.history;
|
|
943
|
+
const storeCall = history?.persistence === "endpoint" ? `fetchStore(${JSON.stringify(history.url)}${c.userId ? `, ${JSON.stringify(c.userId)}` : ""})` : `localStorageStore('${c.name}'${c.userId ? `, ${JSON.stringify(c.userId)}` : ""})`;
|
|
944
|
+
return ` conversations={true} store={${storeCall}} onConversationLoad={(messages) => chat.setMessages(() => messages)}`;
|
|
945
|
+
}
|
|
946
|
+
function emitConversationsImport(c) {
|
|
947
|
+
if (!c.capabilities?.conversations) return "";
|
|
948
|
+
const name = c.capabilities.history?.persistence === "endpoint" ? "fetchStore" : "localStorageStore";
|
|
949
|
+
return `import { ${name} } from '@kitn.ai/ui/solid';`;
|
|
950
|
+
}
|
|
795
951
|
function emitSolidJsImport(c) {
|
|
796
952
|
const history = c.capabilities?.history;
|
|
797
|
-
if (!history || history.persistence === "none") return "";
|
|
953
|
+
if (!history || history.persistence === "none" || c.layout !== "custom" && c.capabilities?.conversations) return "";
|
|
798
954
|
return `import { createEffect } from 'solid-js';
|
|
799
955
|
`;
|
|
800
956
|
}
|
|
801
957
|
function emitHistoryTypeImport(c) {
|
|
802
958
|
const history = c.capabilities?.history;
|
|
803
|
-
if (!history || history.persistence === "none") return "";
|
|
959
|
+
if (!history || history.persistence === "none" || c.layout !== "custom" && c.capabilities?.conversations) return "";
|
|
804
960
|
return ", ChatMessage";
|
|
805
961
|
}
|
|
806
962
|
function emitUserIdHeaderEntry(c) {
|
|
@@ -809,6 +965,7 @@ function emitUserIdHeaderEntry(c) {
|
|
|
809
965
|
function emitHistorySetup(c) {
|
|
810
966
|
const history = c.capabilities?.history;
|
|
811
967
|
if (!history || history.persistence === "none") return "";
|
|
968
|
+
if (c.layout !== "custom" && c.capabilities?.conversations) return "";
|
|
812
969
|
if (history.persistence === "local") {
|
|
813
970
|
const key = JSON.stringify(c.userId ? `kai:${c.name}:${c.userId}:thread` : `kai:${c.name}:thread`);
|
|
814
971
|
return `
|
|
@@ -947,7 +1104,7 @@ async function submit(detail: { value: string; attachments: AttachmentData[] })
|
|
|
947
1104
|
function emitLayoutImport(c) {
|
|
948
1105
|
switch (c.layout) {
|
|
949
1106
|
case "widget":
|
|
950
|
-
return ",
|
|
1107
|
+
return `, Dock${hasLauncherIcon(c) ? ", DockLauncherImage" : ""}`;
|
|
951
1108
|
case "split":
|
|
952
1109
|
return ", WorkspaceShell";
|
|
953
1110
|
case "fullscreen":
|
|
@@ -966,10 +1123,13 @@ function emitDockPosition(c) {
|
|
|
966
1123
|
const w = c.layout === "widget" ? c.widget : void 0;
|
|
967
1124
|
return w?.position ? ` position="${w.position}"` : "";
|
|
968
1125
|
}
|
|
1126
|
+
function hasLauncherIcon(c) {
|
|
1127
|
+
return c.layout === "widget" && !!c.widget?.launcherIcon;
|
|
1128
|
+
}
|
|
969
1129
|
function emitDockLauncher(c) {
|
|
970
1130
|
const w = c.layout === "widget" ? c.widget : void 0;
|
|
971
1131
|
if (!w?.launcherIcon) return "";
|
|
972
|
-
return ` launcher={<
|
|
1132
|
+
return ` launcher={<DockLauncherImage src={${JSON.stringify(w.launcherIcon)}} />}`;
|
|
973
1133
|
}
|
|
974
1134
|
function emitDockDefaultOpen(c) {
|
|
975
1135
|
const w = c.layout === "widget" ? c.widget : void 0;
|
|
@@ -978,7 +1138,7 @@ function emitDockDefaultOpen(c) {
|
|
|
978
1138
|
function emitLayoutOpen(c) {
|
|
979
1139
|
switch (c.layout) {
|
|
980
1140
|
case "widget":
|
|
981
|
-
return ` <Dock label="${c.name}"${emitDockPosition(c)}${emitDockLauncher(c)}${emitDockDefaultOpen(c)}${emitDockHideClose(c)}${emitDockControllerRef(c)}>
|
|
1141
|
+
return ` <Dock label="${c.name}"${emitDockPosition(c)}${emitDockLauncher(c)}${emitDockDefaultOpen(c)}${emitDockHideClose(c)}${emitDockControllerRef(c)}${emitDockOnOpenChangeProp(c)}${emitDockUnreadProp(c)}>
|
|
982
1142
|
`;
|
|
983
1143
|
case "fullscreen":
|
|
984
1144
|
return ` <div style={{ height: '100dvh', display: 'flex', 'flex-direction': 'column' }}>
|
|
@@ -1058,6 +1218,12 @@ const USAGE = `usage: kai <command>
|
|
|
1058
1218
|
kai dev <construct.json> live preview with reload-on-edit (Task 5)
|
|
1059
1219
|
kai compile <construct.json> [outDir] one self-registering .js (Task 6)
|
|
1060
1220
|
`;
|
|
1221
|
+
function homeRecentConversationWarning(construct) {
|
|
1222
|
+
if (construct.home?.recentConversation && !construct.capabilities?.conversations) {
|
|
1223
|
+
return "warning: home.recentConversation is set but capabilities.conversations is not — the recent-conversation card will render nothing without it.";
|
|
1224
|
+
}
|
|
1225
|
+
return null;
|
|
1226
|
+
}
|
|
1061
1227
|
function loadConstruct(path, io) {
|
|
1062
1228
|
const abs = resolve(path);
|
|
1063
1229
|
let raw;
|
|
@@ -1095,6 +1261,8 @@ async function runCli(argv, io = defaultIo) {
|
|
|
1095
1261
|
const construct = loadConstruct(rest[0] ?? "", io);
|
|
1096
1262
|
if (!construct) return 1;
|
|
1097
1263
|
io.log(`valid construct: <${construct.name}> (layout: ${construct.layout}, provider: ${construct.provider.mode})`);
|
|
1264
|
+
const warning = homeRecentConversationWarning(construct);
|
|
1265
|
+
if (warning) io.log(warning);
|
|
1098
1266
|
return 0;
|
|
1099
1267
|
}
|
|
1100
1268
|
case "eject": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{k as o,c as n,S as a,i as s,a as d,b as f,
|
|
1
|
+
import{k as o,c as n,S as a,i as s,a as d,b as f,G as N,H as P,t as u,d as j,m as B}from"./define-By-uL588.js";import{H,a as M,b as $}from"./hover-card-BQbul9eq.js";import{c as h}from"./cn-DN5AWfiS.js";import{B as E}from"./button-DkuOnGLy.js";import{P as G}from"./progress-bar-jVAHvMUf.js";var O=u('<svg aria-label="Model context usage"height=20 role=img viewBox="0 0 24 24"width=20 style=color:currentcolor><circle cx=12 cy=12 fill=none opacity=0.25 r=10 stroke=currentColor stroke-width=2></circle><circle cx=12 cy=12 fill=none opacity=0.7 r=10 stroke=currentColor stroke-linecap=round stroke-width=2 style=transform:rotate(-90deg);transform-origin:center>'),R=u('<span class="font-medium text-muted-foreground">'),q=u('<div class="flex items-center justify-between gap-3 text-xs"><p></p><p class="font-mono text-muted-foreground"> / '),z=u("<div class=space-y-2>"),T=u("<div>"),A=u("<span class=text-muted-foreground>Total cost"),S=u("<span>"),J=u("<div><span class=text-muted-foreground>Input"),K=u("<div><span class=text-muted-foreground>Output"),L=u("<div><span class=text-muted-foreground>Reasoning"),Q=u("<div><span class=text-muted-foreground>Cache");const V=10,v=.7,b=.9;function W(e,t=v,r=b){return e>r?"danger":e>t?"warn":"ok"}const I=N();function g(){const e=P(I);if(!e)throw new Error("Context components must be used within Context");return e}const y=new Intl.NumberFormat("en-US",{notation:"compact"}),D=new Intl.NumberFormat("en-US",{maximumFractionDigits:1,style:"percent"}),_=new Intl.NumberFormat("en-US",{currency:"USD",style:"currency"});function X(e){const t=o(()=>({usedTokens:e.usedTokens,maxTokens:e.maxTokens,inputTokens:e.inputTokens,outputTokens:e.outputTokens,reasoningTokens:e.reasoningTokens,cacheTokens:e.cacheTokens,estimatedCost:e.estimatedCost,warnThreshold:e.warnThreshold??v,dangerThreshold:e.dangerThreshold??b}));return n(I.Provider,{get value(){return t()},get children(){return n(H,{openDelay:0,get children(){return e.children}})}})}function Y(){const e=g(),t=2*Math.PI*V,r=o(()=>e.usedTokens/e.maxTokens),c=o(()=>t*(1-r()));return(()=>{var i=O(),p=i.firstChild,k=p.nextSibling;return j(k,"stroke-dasharray",`${t} ${t}`),d(()=>j(k,"stroke-dashoffset",c())),i})()}function Z(e){const t=g(),r=o(()=>t.usedTokens/t.maxTokens),c=o(()=>D.format(r()));return n(M,{get children(){return n(a,{get when(){return!e.children},get fallback(){return e.children},get children(){return n(E,{type:"button",variant:"ghost",get class(){return e.class},get children(){return[(()=>{var i=R();return s(i,c),i})(),n(Y,{})]}})}})}})}function ee(e){return n($,{get class(){return h("min-w-60 divide-y divide-border overflow-hidden",e.class)},get children(){return e.children}})}function te(e){const t=g(),r=o(()=>t.usedTokens/t.maxTokens),c=o(()=>D.format(r())),i=o(()=>y.format(t.usedTokens)),p=o(()=>y.format(t.maxTokens)),k=o(()=>{const l=r();return l>t.dangerThreshold?"danger":l>t.warnThreshold?"warn":"ok"}),F=o(()=>{const l=k();return l==="danger"?"error":l==="warn"?"warning":"primary"});return(()=>{var l=T();return s(l,n(a,{get when(){return!e.children},get fallback(){return e.children},get children(){return[(()=>{var m=q(),C=m.firstChild,w=C.nextSibling,U=w.firstChild;return s(C,c),s(w,i,U),s(w,p,null),m})(),(()=>{var m=z();return s(m,n(G,{get value(){return t.usedTokens},get max(){return t.maxTokens},get tone(){return F()},"aria-label":"Context usage"})),m})()]}})),d(()=>f(l,h("w-full space-y-2 p-3",e.class))),l})()}function re(e){return(()=>{var t=T();return s(t,()=>e.children),d(()=>f(t,h("w-full p-3",e.class))),t})()}function ne(e){const t=g(),r=o(()=>_.format(t.estimatedCost??0));return(()=>{var c=T();return s(c,n(a,{get when(){return!e.children},get fallback(){return e.children},get children(){return[A(),(()=>{var i=S();return s(i,r),i})()]}})),d(()=>f(c,h("flex w-full items-center justify-between gap-3 bg-muted p-3 text-xs",e.class))),c})()}function x(e){return(()=>{var t=S();return s(t,(()=>{var r=B(()=>e.tokens===void 0);return()=>r()?"\u2014":y.format(e.tokens)})()),t})()}function se(e){const t=g();return n(a,{get when(){return e.children||t.inputTokens},get children(){return n(a,{get when(){return!e.children},get fallback(){return e.children},get children(){var r=J();return r.firstChild,s(r,n(x,{get tokens(){return t.inputTokens}}),null),d(()=>f(r,h("flex items-center justify-between text-xs",e.class))),r}})}})}function oe(e){const t=g();return n(a,{get when(){return e.children||t.outputTokens},get children(){return n(a,{get when(){return!e.children},get fallback(){return e.children},get children(){var r=K();return r.firstChild,s(r,n(x,{get tokens(){return t.outputTokens}}),null),d(()=>f(r,h("flex items-center justify-between text-xs",e.class))),r}})}})}function ae(e){const t=g();return n(a,{get when(){return e.children||t.reasoningTokens},get children(){return n(a,{get when(){return!e.children},get fallback(){return e.children},get children(){var r=L();return r.firstChild,s(r,n(x,{get tokens(){return t.reasoningTokens}}),null),d(()=>f(r,h("flex items-center justify-between text-xs",e.class))),r}})}})}function ue(e){const t=g();return n(a,{get when(){return e.children||t.cacheTokens},get children(){return n(a,{get when(){return!e.children},get fallback(){return e.children},get children(){var r=Q();return r.firstChild,s(r,n(x,{get tokens(){return t.cacheTokens}}),null),d(()=>f(r,h("flex items-center justify-between text-xs",e.class))),r}})}})}export{X as C,v as D,Z as a,ee as b,te as c,re as d,se as e,oe as f,ne as g,W as h,ae as i,ue as j,b as k};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{g as c}from"./define-By-uL588.js";function i(t,o){const[r,n]=c(o);return[()=>t()??r(),a=>n(a)]}export{i as c};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{s as k,i as o,c as u,S as v,a as g,d,b as m,t as c,k as $,e as C}from"./define-By-uL588.js";import{c as l}from"./cn-DN5AWfiS.js";import{m as M}from"./message-square-BG6q6mlm.js";var S=c('<span part=leading class="flex shrink-0 items-center text-muted-foreground">'),D=c('<div part=meta class="mt-0.5 truncate text-xs text-muted-foreground">'),I=c('<span part=menu data-kai-item-menu class="ml-auto flex shrink-0 items-center">'),R=c('<div part=row><div part=body role=button data-kai-item-body class="flex min-w-0 flex-1 cursor-pointer items-center gap-2.5 rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"><div class="min-w-0 flex-1"><div part=title>'),y=c('<span part=trailing class="ml-auto shrink-0 text-xs text-muted-foreground">'),j=c('<div class="flex items-center gap-2.5"><span>'),E=c("<button>"),q=c('<div class="flex items-center gap-2"><div>'),z=c("<div> messages");function N(s,t=Date.now()){if(!s)return"";const n=Date.parse(s);if(Number.isNaN(n))return"";const i=Math.max(0,Math.round((t-n)/1e3));if(i<60)return"just now";const r=Math.floor(i/60);if(r<60)return`${r}m ago`;const a=Math.floor(r/60);return a<24?`${a}h ago`:`${Math.floor(a/24)}d ago`}function B(s){if(!s.lastReadAt)return!1;const t=Date.parse(s.updatedAt),n=Date.parse(s.lastReadAt);return Number.isNaN(t)||Number.isNaN(n)?!1:t>n}function F(s){const[t]=k(s,["conversationId","active","compact","leading","meta","menu","children","hostSemantics","onActivate","class"]);return(()=>{var n=R(),i=n.firstChild,r=i.firstChild,a=r.firstChild;return i.$$keydown=e=>{t.onActivate&&(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),t.onActivate())},i.$$click=()=>{var e;return(e=t.onActivate)==null?void 0:e.call(t)},o(i,u(v,{get when(){return t.leading},get children(){var e=S();return o(e,()=>t.leading),e}}),r),o(a,()=>t.children),o(r,u(v,{get when(){return t.meta},get children(){var e=D();return o(e,()=>t.meta),e}}),null),o(n,u(v,{get when(){return t.menu},get children(){var e=I();return o(e,()=>t.menu),e}}),null),g(e=>{var f=t.hostSemantics?"presentation":"listitem",x=t.active?"":void 0,p=t.conversationId,h=l("flex w-full items-center gap-2.5 rounded-lg text-left transition-colors",t.compact?"px-2.5 py-1.5":"px-2.5 py-2",t.active?"bg-muted":"hover:bg-muted/50",t.class),b=t.active?"true":"false",w=t.onActivate?0:void 0,A=l("truncate text-sm",t.active?"font-medium text-foreground":"text-foreground/80");return f!==e.e&&d(n,"role",e.e=f),x!==e.t&&d(n,"data-active",e.t=x),p!==e.a&&d(n,"data-conversation-id",e.a=p),h!==e.o&&m(n,e.o=h),b!==e.i&&d(i,"aria-current",e.i=b),w!==e.n&&d(i,"tabindex",e.n=w),A!==e.s&&m(a,e.s=A),e},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0}),n})()}function U(s){const[t]=k(s,["conversation","isActive","onSelect","compact","class"]),n=$(()=>t.conversation.trailing??N(t.conversation.updatedAt??t.conversation.lastMessageAt));return(()=>{var i=E();return i.$$click=()=>t.onSelect(t.conversation.id),o(i,u(v,{get when(){return t.compact},get fallback(){return[(()=>{var r=q(),a=r.firstChild;return o(a,()=>t.conversation.title),o(r,u(v,{get when(){return n()},get children(){var e=y();return o(e,n),e}}),null),g(()=>m(a,l("min-w-0 flex-1 truncate text-sm",t.isActive?"font-medium text-foreground":"text-foreground/80"))),r})(),(()=>{var r=z(),a=r.firstChild;return o(r,()=>t.conversation.messageCount,a),g(()=>m(r,l("mt-0.5 truncate text-xs",t.isActive?"text-foreground/70":"text-muted-foreground"))),r})()]},get children(){var r=j(),a=r.firstChild;return o(r,u(M,{get class(){return l("size-3.5 shrink-0",t.isActive?"text-foreground":"text-muted-foreground")}}),a),o(a,()=>t.conversation.title),o(r,u(v,{get when(){return n()},get children(){var e=y();return o(e,n),e}}),null),g(()=>m(a,l("min-w-0 flex-1 truncate text-sm",t.isActive?"font-medium text-foreground":"text-foreground/80"))),r}})),g(r=>{var a=t.conversation.id,e=t.isActive?"true":void 0,f=l("w-full rounded-lg text-left transition-colors",t.compact?"px-2.5 py-1.5":"px-2.5 py-2",t.isActive?"bg-muted":"hover:bg-muted/50",t.class);return a!==r.e&&d(i,"data-conversation-id",r.e=a),e!==r.t&&d(i,"aria-current",r.t=e),f!==r.a&&m(i,r.a=f),r},{e:void 0,t:void 0,a:void 0}),i})()}C(["click","keydown"]);export{U as C,F as S,B as i,N as r};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as a,q as M,s as z,g as N,k as x,o as O,i as h,S as f,u as T,a as k,F as C,m as j,b as q,t as d,d as K,e as L}from"./define-By-uL588.js";import{c as S}from"./cn-DN5AWfiS.js";import{a as P,b as R,C as U}from"./collapsible-B4DlWicL.js";import{B as I}from"./button-DkuOnGLy.js";import{B as F}from"./badge-CdEu_jn2.js";import{S as B}from"./scroll-area-BqLUo8ZZ.js";import{C as D}from"./conversation-item-BxwQLaFJ.js";import{I as H}from"./Icon-DObhsRtm.js";var G=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M9 3v18",key:"fh3hqa"}],["path",{d:"m14 9 3 3-3 3",key:"8010ee"}]],J=i=>a(H,M(i,{name:"PanelLeftOpen",iconNode:G})),Q=J,V=d('<div class="px-3 pb-2"><div class="flex items-center gap-2 rounded-md bg-surface-strong px-2.5 py-1.5"><svg width=13 height=13 viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 class=text-muted-foreground><circle cx=11 cy=11 r=8></circle><line x1=21 y1=21 x2=16.65 y2=16.65></line></svg><input type=text placeholder="Search chats..."aria-label="Search chats"class="bg-transparent text-compact text-foreground placeholder:text-muted-foreground rounded-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring w-full">'),W=d('<div role=list aria-label=Conversations part=items class="space-y-0.5 py-1">'),X=d('<div class="flex flex-1 flex-col items-center justify-center gap-1 p-6 text-center text-sm text-muted-foreground">No conversations match your search'),Y=d('<div class="space-y-0.5 py-1">'),Z=d('<div class="shrink-0 border-t border-border">'),_=d("<div>"),ee=d('<svg width=16 height=16 viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2><line x1=3 y1=12 x2=21 y2=12></line><line x1=3 y1=6 x2=21 y2=6></line><line x1=3 y1=18 x2=21 y2=18>'),te=d('<svg width=16 height=16 viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2><line x1=12 y1=5 x2=12 y2=19></line><line x1=5 y1=12 x2=19 y2=12>'),re=d('<div class="flex items-center justify-between p-3 pb-2"><div class="flex items-center gap-2"><span class="text-sm font-semibold text-foreground">Chats'),ne=d('<div class="flex flex-1 flex-col items-center justify-center gap-1 p-6 text-center text-sm text-muted-foreground">No conversations yet'),oe=d('<svg width=10 height=10 viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2><polyline points="6 9 12 15 18 9">'),ae=d("<span>"),ie=d('<div class="pl-2 mt-0.5 space-y-0.5">');function le(i){return a(I,{variant:"ghost",size:"icon-sm","aria-label":"Open sidebar",get class(){return S("rounded-full bg-card/80 shadow-sm backdrop-blur",i.class)},get onClick(){return i.onExpand},get children(){return a(Q,{class:"size-4"})}})}function w(i){const e=i.conversationId;return typeof e=="string"&&e?e:i.getAttribute("conversation-id")??i.id}function ce(i){var e;return((e=i.parentElement)==null?void 0:e.localName)!=="kai-conversations"}function se(i){const e=n=>{const r=i.getItems();return n.composedPath().find(c=>r.includes(c))},p=n=>{var r;return((r=n.shadowRoot)==null?void 0:r.querySelector("[data-kai-item-body]"))??n},u=n=>n.composedPath().some(r=>r instanceof Element&&(r.hasAttribute("data-kai-item-menu")||r.getAttribute("slot")==="menu")),m=(n,r,c)=>{n.getAttribute(r)!==c&&n.setAttribute(r,c)},y=n=>{const r=new Map;for(const c of n){const s=p(c);s===c&&c.localName.includes("-")||r.set(c,s)}return r},v=(n,r)=>{for(const[c,s]of y(n))m(s,"tabindex",c===r?"0":"-1")};return{sync:()=>{const n=i.getItems(),r=i.getActiveId(),c=y(n);let s;for(const[o,t]of c){const l=r!==void 0&&w(o)===r;t.hasAttribute("role")||t.setAttribute("role","button"),m(t,"aria-current",l?"true":"false");const g=o;g.active!==l&&(g.active=l),l&&(s=o)}v(n,s??c.keys().next().value)},handleClick(n){const r=e(n);!r||u(n)||i.onSelect(w(r))},handleKeyDown(n){const r=i.getItems();if(r.length===0)return;const c=e(n);if(n.key==="Enter"||n.key===" "){if(!c||u(n))return;n.preventDefault(),i.onSelect(w(c));return}let s;const o=c?r.indexOf(c):r.findIndex(t=>p(t).getAttribute("tabindex")==="0");n.key==="ArrowDown"?s=r[Math.min(o+1,r.length-1)]:n.key==="ArrowUp"?s=r[Math.max(o-1,0)]:n.key==="Home"?s=r[0]:n.key==="End"&&(s=r[r.length-1]),s&&(n.preventDefault(),v(r,s),p(s).focus())}}}function ue(i){const[e]=z(i,["groups","conversations","activeId","onSelect","onNewChat","onToggleSidebar","header","footer","empty","compact","onSearchChange","controllerRef","items","itemsKeyDown","itemsClick","class"]),[p,u]=N(""),m=x(()=>e.items!=null),y=x(()=>e.conversations.length===0);let v;const n=o=>{var t;u(o),(t=e.onSearchChange)==null||t.call(e,o)};O(()=>{var o;(o=e.controllerRef)==null||o.call(e,{focus:t=>v?.focus(t),clearSearch:()=>n("")})});const r=x(()=>{const o=p().toLowerCase();return o?e.conversations.filter(t=>t.title.toLowerCase().includes(o)):e.conversations}),c=x(()=>{const o=new Map;for(const t of r()){const l=t.groupId;o.has(l)||o.set(l,[]),o.get(l).push(t)}return o}),s=x(()=>{const o=new Set((e.groups??[]).map(t=>t.id));return r().filter(t=>t.groupId==null||!o.has(t.groupId))});return(()=>{var o=_();return h(o,a(f,{get when(){return e.header},get fallback(){return(()=>{var t=re(),l=t.firstChild,g=l.firstChild;return h(l,a(I,{variant:"ghost",size:"icon-sm","aria-label":"Toggle sidebar",get onClick(){return e.onToggleSidebar},get children(){return ee()}}),g),h(t,a(I,{variant:"ghost",size:"icon-sm","aria-label":"New chat",get onClick(){return e.onNewChat},get children(){return te()}}),null),t})()},get children(){return e.header}}),null),h(o,a(f,{get when(){return m()||!y()},get children(){var t=V(),l=t.firstChild,g=l.firstChild,b=g.nextSibling;b.$$input=E=>n(E.currentTarget.value);var A=v;return typeof A=="function"?T(A,b):v=b,k(()=>b.value=p()),t}}),null),h(o,a(f,{get when(){return m()},get children(){return a(B,{class:"flex-1 px-2",get children(){var t=W();return t.$$click=l=>{var g;return(g=e.itemsClick)==null?void 0:g.call(e,l)},t.$$keydown=l=>{var g;return(g=e.itemsKeyDown)==null?void 0:g.call(e,l)},h(t,()=>e.items),t}})}}),null),h(o,a(f,{get when(){return j(()=>!m())()&&!y()},get fallback(){return a(f,{get when(){return!m()},get children(){return a(f,{get when(){return e.empty},get fallback(){return ne()},get children(){return e.empty}})}})},get children(){return[a(f,{get when(){return r().length===0},get children(){return X()}}),a(f,{get when(){return r().length>0},get children(){return a(B,{class:"flex-1 px-2",get children(){return[a(C,{get each(){return e.groups},children:t=>{const l=x(()=>c().get(t.id)??[]);return a(f,{get when(){return l().length>0},get children(){return a($,{get name(){return t.name},get count(){return l().length},get conversations(){return l()},get activeId(){return e.activeId},get onSelect(){return e.onSelect},get compact(){return e.compact}})}})}}),a(f,{get when(){return s().length>0},get children(){return a(f,{get when(){return e.compact},get fallback(){return a($,{name:"Ungrouped",get count(){return s().length},get conversations(){return s()},get activeId(){return e.activeId},get onSelect(){return e.onSelect}})},get children(){var t=Y();return h(t,a(C,{get each(){return s()},children:l=>a(D,{conversation:l,get isActive(){return l.id===e.activeId},get onSelect(){return e.onSelect},compact:!0})})),t}})}})]}})}})]}}),null),h(o,a(f,{get when(){return e.footer},get children(){var t=Z();return h(t,()=>e.footer),t}}),null),k(()=>q(o,S("flex flex-col h-full bg-sidebar",e.class))),o})()}function $(i){const[e,p]=N(!0);return a(U,{get open(){return e()},onOpenChange:p,get children(){return[a(P,{class:"flex items-center gap-1.5 w-full px-1.5 py-1 rounded-md text-compact text-muted-foreground font-medium hover:bg-muted/30 transition-colors cursor-pointer mt-1.5",get children(){return[(()=>{var u=oe();return k(()=>K(u,"class",S("transition-transform",!e()&&"-rotate-90"))),u})(),(()=>{var u=ae();return h(u,()=>i.name),u})(),a(F,{variant:"count",class:"ml-auto text-caption",get children(){return i.count}})]}}),a(R,{get children(){var u=ie();return h(u,a(C,{get each(){return i.conversations},children:m=>a(D,{conversation:m,get isActive(){return m.id===i.activeId},get onSelect(){return i.onSelect},get compact(){return i.compact}})})),u}})]}})}L(["input","keydown","click"]);export{ue as C,le as a,se as c,ce as i,w as r};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{I as a}from"./Icon-
|
|
1
|
+
import{I as a}from"./Icon-DObhsRtm.js";import{c as o,q as c}from"./define-By-uL588.js";var e=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],t=r=>o(a,c(r,{name:"Copy",iconNode:e})),i=t;export{i as c};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ssr as Le, ssrAttribute as we, escape as ye } from "solid-js/web";
|
|
2
2
|
import { createMemo as U, onCleanup as G, createEffect as ue, untrack as ve, createSignal as le } from "solid-js";
|
|
3
|
-
import { c as Re } from "./solid-
|
|
3
|
+
import { c as Re } from "./solid-DruVOXnf.js";
|
|
4
4
|
var _e = ['<canvas part="canvas"', "></canvas>"];
|
|
5
5
|
const Ce = "#1FD5F9";
|
|
6
6
|
function Ie(e) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { effect as Le, className as ye, template as we, use as Re } from "solid-js/web";
|
|
2
2
|
import { createMemo as U, onCleanup as z, createEffect as ue, untrack as ve, createSignal as le } from "solid-js";
|
|
3
|
-
import { c as _e } from "./solid-
|
|
3
|
+
import { c as _e } from "./solid-BzCFdL25.js";
|
|
4
4
|
var Ce = /* @__PURE__ */ we("<canvas part=canvas>");
|
|
5
5
|
const Ie = "#1FD5F9";
|
|
6
6
|
function Te(e) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as ye,u as Le,c as Re,f as Ie}from"./register-impl-
|
|
1
|
+
import{t as ye,u as Le,c as Re,f as Ie}from"./register-impl-B1hLkrI8.js";import{c as N,o as j,h as ce,u as fe,d as _e,i as ue}from"./kai.es.js";var Pe=ye("<canvas part=canvas>");const me="#1FD5F9";function ve(e){const n=e.trim().match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);if(!n)return ve(me);const[,o,i,l]=n;return[parseInt(o,16)/255,parseInt(i,16)/255,parseInt(l,16)/255]}const Ce={"1f":"float","1i":"int","1fv":"float","2f":"vec2","3f":"vec3","3fv":"vec3","4f":"vec4","4fv":"vec4",Matrix2fv:"mat2",Matrix3fv:"mat3",Matrix4fv:"mat4"},Te={"1fv":1,"3fv":3,"4fv":4,Matrix2fv:4,Matrix3fv:9,Matrix4fv:16};function ke(e){const n=Te[e.type];if(!n||!Array.isArray(e.value))return;const o=e.value.length/n;return o>1&&Number.isInteger(o)?o:void 0}function he(e){return e.arraySize??ke(e)}const Oe=["uniform float iTime;","uniform vec2 iResolution;","uniform vec4 iMouse;","uniform int iFrame;","uniform vec4 iDate;"].join(`
|
|
2
2
|
`),De=`
|
|
3
3
|
attribute vec3 aVertexPosition;
|
|
4
4
|
void main() { gl_Position = vec4(aVertexPosition, 1.0); }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{k as N,h as U,j as ce,z as fe,a as ye,b as Le,t as Re,u as Ie,g as ue}from"./define-
|
|
1
|
+
import{k as N,h as U,j as ce,z as fe,a as ye,b as Le,t as Re,u as Ie,g as ue}from"./define-By-uL588.js";import{c as _e}from"./cn-DN5AWfiS.js";var Pe=Re("<canvas part=canvas>");const me="#1FD5F9";function ve(e){const n=e.trim().match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);if(!n)return ve(me);const[,o,a,l]=n;return[parseInt(o,16)/255,parseInt(a,16)/255,parseInt(l,16)/255]}const ke={"1f":"float","1i":"int","1fv":"float","2f":"vec2","3f":"vec3","3fv":"vec3","4f":"vec4","4fv":"vec4",Matrix2fv:"mat2",Matrix3fv:"mat3",Matrix4fv:"mat4"},Ce={"1fv":1,"3fv":3,"4fv":4,Matrix2fv:4,Matrix3fv:9,Matrix4fv:16};function Te(e){const n=Ce[e.type];if(!n||!Array.isArray(e.value))return;const o=e.value.length/n;return o>1&&Number.isInteger(o)?o:void 0}function he(e){return e.arraySize??Te(e)}const Oe=["uniform float iTime;","uniform vec2 iResolution;","uniform vec4 iMouse;","uniform int iFrame;","uniform vec4 iDate;"].join(`
|
|
2
2
|
`),De=`
|
|
3
3
|
attribute vec3 aVertexPosition;
|
|
4
4
|
void main() { gl_Position = vec4(aVertexPosition, 1.0); }
|
|
@@ -1761,7 +1761,7 @@
|
|
|
1761
1761
|
"kind": "field",
|
|
1762
1762
|
"name": "policy",
|
|
1763
1763
|
"type": {
|
|
1764
|
-
"text": "undefined | { onSubmit?: undefined | ((cardId: string, data: unknown) => void); onAction?: undefined | ((cardId: string, action: string, payload?: unknown) => void); onSendPrompt?: undefined | ((text: string, opts: { mode: \"compose\" | \"send\"; context?: unknown
|
|
1764
|
+
"text": "undefined | { onSubmit?: undefined | ((cardId: string, data: unknown) => void); onAction?: undefined | ((cardId: string, action: string, payload?: unknown) => void); onSendPrompt?: undefined | ((text: string, opts: { mode: \"compose\" | \"send\"; context?: unknown }) => void); onOpen?: undefined | ((url: string, target: \"tab\" | \"artifact\") => void); onState?: undefined | ((cardId: string, patch: unknown) => void); onDismiss?: undefined | ((cardId: string) => void); onReopen?: undefined | ((cardId: string) => void); onError?: undefined | ((cardId: string, message: string) => void); maxSendPromptMode?: undefined | \"compose\" | \"send\" }"
|
|
1765
1765
|
},
|
|
1766
1766
|
"description": "Optional CardPolicy handling child events. Property: `el.policy`.",
|
|
1767
1767
|
"privacy": "public"
|
|
@@ -2320,6 +2320,33 @@
|
|
|
2320
2320
|
"description": "JSON Schemas for the card types this app renders, keyed by envelope type. The companion of `cardTypes`, which says what DRAWS a card while this says what a VALID one looks like. An OBJECT, so it is a JS property only: `el.cardSchemas = { 'pricing-table': pricingSchema }`, never an attribute. `createCardRegistry(...).validationSchemas` is exactly this shape. Without it the kit validates its own seven built-ins and leaves your own card type, the one your app actually cares about, as the only unchecked thing on screen. A schema here WINS over a built-in of the same name. Typed `Record<string, object>` rather than `Record<string, JsonSchema>` deliberately: an imported `.json` schema widens `\"type\"` to `string`, and an authored one carries `$schema`/`title`/`description`/`additionalProperties`, so the tighter type would reject both of the normal ways to supply one.",
|
|
2321
2321
|
"privacy": "public"
|
|
2322
2322
|
},
|
|
2323
|
+
{
|
|
2324
|
+
"kind": "field",
|
|
2325
|
+
"name": "conversations",
|
|
2326
|
+
"type": {
|
|
2327
|
+
"text": "undefined | false | true"
|
|
2328
|
+
},
|
|
2329
|
+
"description": "Turns on the prior-conversations list (a list-toggle button in the header, plus a second list view sharing the panel, C-1). Attribute- settable like every other boolean flag on this element: `<kai-chat conversations>`. Requires `store`. A row select, \"new conversation,\" or the visitor's mount-time auto-restore all deliver their messages the same way: listen for `kai-conversation-load` and set `el.messages` from `event.detail.messages` (a fresh array): this element does not update `messages` for you. Set with no `store`, the underlying `ChatThread` decides loudly (one console.error) and stays visually off; this facade always supplies its own internal load handler (the `kai-conversation-load` dispatch below), so the second ChatThread guard, missing `onConversationLoad`, never trips here, even for a consumer who never listens for the event. Default false.",
|
|
2330
|
+
"privacy": "public"
|
|
2331
|
+
},
|
|
2332
|
+
{
|
|
2333
|
+
"kind": "field",
|
|
2334
|
+
"name": "store",
|
|
2335
|
+
"type": {
|
|
2336
|
+
"text": "undefined | { list: () => Promise<{ id: string; title: string; groupId?: undefined | string; scope?: undefined | { type: \"document\" | \"collection\"; documentId?: undefined | string; filters?: undefined | { tags?: undefined | string[]; authors?: undefined | string[]; contentType?: undefined | \"transcript\" | \"markdown\"; dateRange?: undefined | { from: string; to: string } } }; messageCount: number; lastMessageAt?: undefined | string; updatedAt: string; trailing?: undefined | string; lastReadAt?: undefined | string }[]>; load: (id: string) => Promise<{ id: string; role: \"user\" | \"assistant\"; parts: ({ type: \"text\"; text: string; raw?: undefined | { source: string; payload: unknown } } | { type: \"reasoning\"; text: string; label?: undefined | string; index?: undefined | number; streamId?: undefined | string; signature?: undefined | string; raw?: undefined | { source: string; payload: unknown } } | { type: \"tool\"; tool: { type: string; kind?: undefined | \"command\" | \"file-change\" | \"search\" | \"fetch\" | \"mcp\" | \"image\" | \"generic\"; state: \"input-streaming\" | \"input-available\" | \"output-available\" | \"output-error\"; input?: undefined | Record<string, unknown>; rawInput?: undefined | string; output?: undefined | Record<string, unknown>; toolCallId?: undefined | string; errorText?: undefined | string; raw?: undefined | { source: string; payload: unknown } }; raw?: undefined | { source: string; payload: unknown } } | { type: \"card\"; envelope: { type: string; id: string; data: unknown; title?: undefined | string; resolution?: undefined | { kind: \"action\"; action: string; payload?: unknown; at?: undefined | string } | { kind: \"submit\"; data: unknown; at?: undefined | string } | { kind: \"dismissed\"; at?: undefined | string } | { kind: \"expired\"; reason?: undefined | string; at?: undefined | string } }; raw?: undefined | { source: string; payload: unknown } } | { type: \"source\"; source: { id?: undefined | string; url?: undefined | string; title?: undefined | string; snippet?: undefined | string; index?: undefined | number }; raw?: undefined | { source: string; payload: unknown } } | { type: \"file\"; attachment: { id: string; type: \"file\" | \"source-document\"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }; raw?: undefined | { source: string; payload: unknown } })[]; actions?: undefined | (\"copy\" | \"like\" | \"dislike\" | \"regenerate\" | \"edit\" | { id: string; label: string; icon?: undefined | string; tooltip?: undefined | string })[]; avatar?: undefined | { src?: undefined | string; fallback?: undefined | string; alt?: undefined | string }; feedback?: undefined | \"like\" | \"dislike\" }[]>; save: (id: string, messages: { id: string; role: \"user\" | \"assistant\"; parts: ({ type: \"text\"; text: string; raw?: undefined | { source: string; payload: unknown } } | { type: \"reasoning\"; text: string; label?: undefined | string; index?: undefined | number; streamId?: undefined | string; signature?: undefined | string; raw?: undefined | { source: string; payload: unknown } } | { type: \"tool\"; tool: { type: string; kind?: undefined | \"command\" | \"file-change\" | \"search\" | \"fetch\" | \"mcp\" | \"image\" | \"generic\"; state: \"input-streaming\" | \"input-available\" | \"output-available\" | \"output-error\"; input?: undefined | Record<string, unknown>; rawInput?: undefined | string; output?: undefined | Record<string, unknown>; toolCallId?: undefined | string; errorText?: undefined | string; raw?: undefined | { source: string; payload: unknown } }; raw?: undefined | { source: string; payload: unknown } } | { type: \"card\"; envelope: { type: string; id: string; data: unknown; title?: undefined | string; resolution?: undefined | { kind: \"action\"; action: string; payload?: unknown; at?: undefined | string } | { kind: \"submit\"; data: unknown; at?: undefined | string } | { kind: \"dismissed\"; at?: undefined | string } | { kind: \"expired\"; reason?: undefined | string; at?: undefined | string } }; raw?: undefined | { source: string; payload: unknown } } | { type: \"source\"; source: { id?: undefined | string; url?: undefined | string; title?: undefined | string; snippet?: undefined | string; index?: undefined | number }; raw?: undefined | { source: string; payload: unknown } } | { type: \"file\"; attachment: { id: string; type: \"file\" | \"source-document\"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }; raw?: undefined | { source: string; payload: unknown } })[]; actions?: undefined | (\"copy\" | \"like\" | \"dislike\" | \"regenerate\" | \"edit\" | { id: string; label: string; icon?: undefined | string; tooltip?: undefined | string })[]; avatar?: undefined | { src?: undefined | string; fallback?: undefined | string; alt?: undefined | string }; feedback?: undefined | \"like\" | \"dislike\" }[]) => Promise<void>; markRead?: undefined | ((id: string) => Promise<void>) }"
|
|
2337
|
+
},
|
|
2338
|
+
"description": "The adapter this thread persists conversations through: an object of three functions (`list`/`load`/`save`; `ConversationStore`, exported from `@kitn.ai/ui`'s `primitives/conversation-store`). A JS PROPERTY ONLY: `el.store = myAdapter`. It can never be an attribute, since a function-bearing object has no HTML string form, the same reasoning that keeps `messages`/`cardSchemas` property-only (the kai- contract: array/object props are JS properties, never attributes). Two built-ins ship: `localStorageStore(name, userId?)` and `fetchStore(url, userId?)`.",
|
|
2339
|
+
"privacy": "public"
|
|
2340
|
+
},
|
|
2341
|
+
{
|
|
2342
|
+
"kind": "field",
|
|
2343
|
+
"name": "home",
|
|
2344
|
+
"type": {
|
|
2345
|
+
"text": "undefined | { greeting?: undefined | { title?: undefined | string; subtitle?: undefined | string }; recentConversation?: undefined | false | true; newConversation?: undefined | { label?: undefined | string }; links?: undefined | { label: string; href?: undefined | string; description?: undefined | string; icon?: undefined | string }[] }"
|
|
2346
|
+
},
|
|
2347
|
+
"description": "Turns on the widget home screen (Intercom-pattern): the panel boots into a `home` view, with a greeting, most-recent-conversation card, a \"new conversation\" CTA, and host-defined links, plus a Home/Messages tab bar for switching back to the thread. An OBJECT, so it is a JS property only: `el.home = { greeting: { title: 'Hey' }, links: [...] }`, never an attribute (the kai- contract: array/object props are JS properties). A `links` entry with no `href` fires `kai-home-link` with that entry when tapped, rather than navigating; one WITH `href` opens it directly (only when the URL passes the kit's own scheme allowlist). Omit for the no-home widget (chat view only, unchanged).",
|
|
2348
|
+
"privacy": "public"
|
|
2349
|
+
},
|
|
2323
2350
|
{
|
|
2324
2351
|
"kind": "method",
|
|
2325
2352
|
"name": "focus",
|
|
@@ -2594,6 +2621,14 @@
|
|
|
2594
2621
|
"text": "undefined | string"
|
|
2595
2622
|
},
|
|
2596
2623
|
"description": "Which attachment media types the user may stage, in HTML `accept` syntax: `<kai-chat accept=\"image/*,application/pdf\">`. A plain string, so unlike `messages` it DOES work as an attribute. Omitted means no filter. MEDIA TYPES ONLY -- exact (`image/png`) or subtype wildcard (`text/*`). HTML allows a file extension here and this does not: `accept=\".py\"` THROWS with the entry named, rather than silently resolving to a picker that accepts nothing. It can only NARROW what the kit can already encode: `accept=\"image/*\"` resolves to the four image formats both APIs take, not to every image type the OS offers. Pass the SAME string to `toOpenAIMessages(msgs, { accept })` and the picker and the wire cannot disagree -- both resolve it through `resolveMediaPolicy` against one declaration. That declaration is readable as `encodableMediaTypes()` from `@kitn.ai/ui/wire`, if you would rather build your own picker than use this prop."
|
|
2624
|
+
},
|
|
2625
|
+
{
|
|
2626
|
+
"name": "conversations",
|
|
2627
|
+
"fieldName": "conversations",
|
|
2628
|
+
"type": {
|
|
2629
|
+
"text": "undefined | false | true"
|
|
2630
|
+
},
|
|
2631
|
+
"description": "Turns on the prior-conversations list (a list-toggle button in the header, plus a second list view sharing the panel, C-1). Attribute- settable like every other boolean flag on this element: `<kai-chat conversations>`. Requires `store`. A row select, \"new conversation,\" or the visitor's mount-time auto-restore all deliver their messages the same way: listen for `kai-conversation-load` and set `el.messages` from `event.detail.messages` (a fresh array): this element does not update `messages` for you. Set with no `store`, the underlying `ChatThread` decides loudly (one console.error) and stays visually off; this facade always supplies its own internal load handler (the `kai-conversation-load` dispatch below), so the second ChatThread guard, missing `onConversationLoad`, never trips here, even for a consumer who never listens for the event. Default false."
|
|
2597
2632
|
}
|
|
2598
2633
|
],
|
|
2599
2634
|
"events": [
|
|
@@ -2611,6 +2646,20 @@
|
|
|
2611
2646
|
},
|
|
2612
2647
|
"description": "One or more picked files were refused because `accept` excluded them. The element renders NO message of its own: it reports the facts (name, media type, whether the kit could have sent it) and what the user should see is the application's call. Only ever fires when `accept` is set."
|
|
2613
2648
|
},
|
|
2649
|
+
{
|
|
2650
|
+
"name": "kai-conversation-load",
|
|
2651
|
+
"type": {
|
|
2652
|
+
"text": "CustomEvent<{ id: string | undefined; messages: { id: string; role: \"user\" | \"assistant\"; parts: ({ type: \"text\"; text: string; raw?: undefined | { source: string; payload: unknown } } | { type: \"reasoning\"; text: string; label?: undefined | string; index?: undefined | number; streamId?: undefined | string; signature?: undefined | string; raw?: undefined | { source: string; payload: unknown } } | { type: \"tool\"; tool: { type: string; kind?: undefined | \"command\" | \"file-change\" | \"search\" | \"fetch\" | \"mcp\" | \"image\" | \"generic\"; state: \"input-streaming\" | \"input-available\" | \"output-available\" | \"output-error\"; input?: undefined | Record<string, unknown>; rawInput?: undefined | string; output?: undefined | Record<string, unknown>; toolCallId?: undefined | string; errorText?: undefined | string; raw?: undefined | { source: string; payload: unknown } }; raw?: undefined | { source: string; payload: unknown } } | { type: \"card\"; envelope: { type: string; id: string; data: unknown; title?: undefined | string; resolution?: undefined | { kind: \"action\"; action: string; payload?: unknown; at?: undefined | string } | { kind: \"submit\"; data: unknown; at?: undefined | string } | { kind: \"dismissed\"; at?: undefined | string } | { kind: \"expired\"; reason?: undefined | string; at?: undefined | string } }; raw?: undefined | { source: string; payload: unknown } } | { type: \"source\"; source: { id?: undefined | string; url?: undefined | string; title?: undefined | string; snippet?: undefined | string; index?: undefined | number }; raw?: undefined | { source: string; payload: unknown } } | { type: \"file\"; attachment: { id: string; type: \"file\" | \"source-document\"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }; raw?: undefined | { source: string; payload: unknown } })[]; actions?: undefined | (\"copy\" | \"like\" | \"dislike\" | \"regenerate\" | \"edit\" | { id: string; label: string; icon?: undefined | string; tooltip?: undefined | string })[]; avatar?: undefined | { src?: undefined | string; fallback?: undefined | string; alt?: undefined | string }; feedback?: undefined | \"like\" | \"dislike\" }[] }>"
|
|
2653
|
+
},
|
|
2654
|
+
"description": "A conversation's history loaded: a row tap in the list, \"new conversation,\" or the visitor's own mount-time auto-restore of their most recent thread (only fires when `conversations` is on and a `store` is set). `detail.id` is that conversation's id, `undefined` for the \"new conversation\" case (no id exists until the first message mints one, C-6). Set `el.messages = event.detail.messages` (already a fresh array) to actually render it, since this element does not do that for you; `messages` stays your own state like everywhere else on this element."
|
|
2655
|
+
},
|
|
2656
|
+
{
|
|
2657
|
+
"name": "kai-home-link",
|
|
2658
|
+
"type": {
|
|
2659
|
+
"text": "CustomEvent<{ entry: { label: string; href?: undefined | string; description?: undefined | string; icon?: undefined | string } }>"
|
|
2660
|
+
},
|
|
2661
|
+
"description": "A `home.links` entry with no `href` was activated (tapped/clicked/Enter). Meaningful only when `home` is set."
|
|
2662
|
+
},
|
|
2614
2663
|
{
|
|
2615
2664
|
"name": "kai-message-action",
|
|
2616
2665
|
"type": {
|
|
@@ -4748,7 +4797,7 @@
|
|
|
4748
4797
|
"kind": "field",
|
|
4749
4798
|
"name": "conversations",
|
|
4750
4799
|
"type": {
|
|
4751
|
-
"text": "undefined | { id: string; title: string; groupId?: undefined | string; scope?: undefined | { type: \"document\" | \"collection\"; documentId?: undefined | string; filters?: undefined | { tags?: undefined | string[]; authors?: undefined | string[]; contentType?: undefined | \"transcript\" | \"markdown\"; dateRange?: undefined | { from: string; to: string } } }; messageCount: number; lastMessageAt?: undefined | string; updatedAt: string; trailing?: undefined | string }[]"
|
|
4800
|
+
"text": "undefined | { id: string; title: string; groupId?: undefined | string; scope?: undefined | { type: \"document\" | \"collection\"; documentId?: undefined | string; filters?: undefined | { tags?: undefined | string[]; authors?: undefined | string[]; contentType?: undefined | \"transcript\" | \"markdown\"; dateRange?: undefined | { from: string; to: string } } }; messageCount: number; lastMessageAt?: undefined | string; updatedAt: string; trailing?: undefined | string; lastReadAt?: undefined | string }[]"
|
|
4752
4801
|
},
|
|
4753
4802
|
"description": "Every conversation the list renders, flat. Each one is filed under the group whose `id` equals its `groupId`; one with no `groupId`, or with a `groupId` matching no entry in `groups`, falls into a trailing \"Ungrouped\" section, so nothing you pass in is ever dropped. There is no recency bucketing. Set as a JS property. Omit to supply them as `<kai-conversation>` light-DOM children instead, or for the empty state. A search query that matches nothing shows a visible \"No conversations match your search\" state, distinct from the zero-conversations empty state. Slotted `<kai-conversation-item>` children switch the list into item mode instead: your own rows win and this array is not rendered.",
|
|
4754
4803
|
"privacy": "public"
|