agentic-ui-kit 0.5.0 → 0.6.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/dist/core.js +3 -3
- package/dist/index.js +333 -23
- package/dist/{ui-markup-CG9Lednh.js → src-D01l3nBc.js} +44 -4
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +1 -1
- package/dist/types/core/src/events.d.ts +2 -0
- package/dist/types/core/src/index.d.ts +2 -1
- package/dist/types/core/src/replaces.d.ts +10 -2
- package/dist/types/core/src/ui-markup.d.ts +1 -1
- package/dist/types/core/src/ui-tree.d.ts +1 -1
- package/dist/types/core/src/visualize.d.ts +3 -3
- package/dist/types/core/src/widget-loader.d.ts +19 -0
- package/dist/types/react/src/components/composer.d.ts +7 -1
- package/dist/types/react/src/components/dictation.d.ts +73 -0
- package/dist/types/react/src/components/effort-slider.d.ts +1 -1
- package/dist/types/react/src/components/widget-frame.d.ts +7 -2
- package/dist/types/react/src/index.d.ts +2 -0
- package/dist/types/react/src/primitives/icons.d.ts +6 -0
- package/dist/types/react/src/primitives/labels.d.ts +10 -0
- package/dist/types/react/src/primitives/segmented-control.d.ts +1 -1
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as awaitingToolCalls, C as widgetLoaderMessages, D as toBlocks, E as isActivityPart, F as settleToolCall, I as parsePartialJson, L as salvageJson, M as outputTokens, N as reduceEvents, O as activityTokens, P as resolveEffort, S as widgetFrameLoader, T as readEventStream, _ as replacedId, a as readUiValue, b as resolveReplaces, c as uiMarkupGuide, d as isStateRef, f as matchesSchema, g as uiActionSchema, h as schemaErrors, i as parseUiMarkup, j as estimateTokens, k as applyEvent, l as uiMarkupLanguage, m as renderUiToolName, n as checkUiMarkupCode, o as showUiTool, p as renderUiTool, r as findUiBlocks, s as showUiToolName, t as checkUiMarkup, u as checkUiTree, v as replacesGuide, w as formatEvent, x as withCallId, y as replacesProperty } from "./src-D01l3nBc.js";
|
|
2
2
|
// ../core/src/visualize.ts
|
|
3
3
|
/**
|
|
4
|
-
* The visualize preset: a tool the model calls to draw an interactive visual inline (
|
|
4
|
+
* The visualize preset: a tool the model calls to draw an interactive visual inline (similar to claude.ai's
|
|
5
5
|
* visualize tool), and the design guide to put in the system prompt. The kit's `show_widget` tool view feeds
|
|
6
6
|
* the streaming `widget_code` into a sandboxed WidgetFrame. The backend runs the tool as a no-op ("shown").
|
|
7
7
|
*/
|
|
@@ -100,4 +100,4 @@ function checkWidgetCode(html, allow = {}, toolName = visualizeTool.name) {
|
|
|
100
100
|
feedback: ok && !warnings.length ? "Shown to the user." : ok ? `Shown to the user, and it works: do not draw it again now. Next time, to fit the chat better:\n${lines}` : `Shown, but it will not work as written. Fix these and call ${toolName} again with "replaces" set to this call's id, without remarking on the fix to the user:\n${lines}`
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
export { activityTokens, applyEvent, awaitingToolCalls, checkUiMarkup, checkUiMarkupCode, checkUiTree, checkWidgetCode, estimateTokens, findUiBlocks, formatEvent, isActivityPart, isStateRef, matchesSchema, outputTokens, parsePartialJson, parseUiMarkup, readEventStream, readUiValue, reduceEvents, renderUiTool, renderUiToolName, replacedId, replacesGuide, replacesProperty, resolveEffort, salvageJson, schemaErrors, settleToolCall, showUiTool, showUiToolName, toBlocks, uiActionSchema, uiMarkupGuide, uiMarkupLanguage, visualizeGuide, visualizeTool };
|
|
103
|
+
export { activityTokens, applyEvent, awaitingToolCalls, checkUiMarkup, checkUiMarkupCode, checkUiTree, checkWidgetCode, estimateTokens, findUiBlocks, formatEvent, isActivityPart, isStateRef, matchesSchema, outputTokens, parsePartialJson, parseUiMarkup, readEventStream, readUiValue, reduceEvents, renderUiTool, renderUiToolName, replacedId, replacesGuide, replacesProperty, resolveEffort, resolveReplaces, salvageJson, schemaErrors, settleToolCall, showUiTool, showUiToolName, toBlocks, uiActionSchema, uiMarkupGuide, uiMarkupLanguage, visualizeGuide, visualizeTool, widgetFrameLoader, widgetLoaderMessages, withCallId };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { C as toBlocks,
|
|
2
|
+
import { A as awaitingToolCalls, C as widgetLoaderMessages, D as toBlocks, F as settleToolCall, L as salvageJson, O as activityTokens, T as readEventStream, _ as replacedId, b as resolveReplaces, d as isStateRef, f as matchesSchema, g as uiActionSchema, i as parseUiMarkup, k as applyEvent } from "./src-D01l3nBc.js";
|
|
3
3
|
import { clsx } from "clsx";
|
|
4
4
|
import { Autocomplete, Button as Button$1, Dialog, DialogTrigger, Disclosure as Disclosure$1, DisclosurePanel, Focusable, Header, Heading, Input, Keyboard, Link, Menu as Menu$1, MenuItem as MenuItem$1, MenuSection as MenuSection$1, MenuTrigger, MenuTrigger as MenuTrigger$1, Modal as Modal$1, ModalOverlay, Popover as Popover$1, SearchField, Separator, SubmenuTrigger, Text, ToggleButton, ToggleButtonGroup, Tooltip as Tooltip$1, TooltipTrigger, useFilter } from "react-aria-components";
|
|
5
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { Component, Fragment as Fragment$1, createContext, createElement, memo, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
7
|
-
import { AlertTriangle, ArrowDown, ArrowUp, Check, ChevronDown, ChevronRight, ChevronsUpDown, Copy, FileText, Folder, FolderOpen, FolderPlus, Globe, Info, MoreHorizontal, PanelLeft, Pencil, Pin, PinOff, Plus, RefreshCw, Share, ShieldQuestion, Square, ThumbsDown, ThumbsUp, Trash2, Volume2, X } from "lucide-react";
|
|
7
|
+
import { AlertTriangle, ArrowDown, ArrowUp, Check, ChevronDown, ChevronRight, ChevronsUpDown, Copy, FileText, Folder, FolderOpen, FolderPlus, Globe, Info, Mic, MoreHorizontal, PanelLeft, Pencil, Pin, PinOff, Plus, RefreshCw, Share, ShieldQuestion, Square, ThumbsDown, ThumbsUp, Trash2, Volume2, X } from "lucide-react";
|
|
8
8
|
import { UNSAFE_PortalProvider } from "react-aria";
|
|
9
9
|
import { createMathPlugin } from "@streamdown/math";
|
|
10
10
|
import { Streamdown, defaultRehypePlugins } from "streamdown";
|
|
@@ -97,6 +97,9 @@ const defaultIcons = {
|
|
|
97
97
|
send: /* @__PURE__ */ jsx(ArrowUp, {}),
|
|
98
98
|
stop: /* @__PURE__ */ jsx(Square, {}),
|
|
99
99
|
attach: /* @__PURE__ */ jsx(Plus, {}),
|
|
100
|
+
mic: /* @__PURE__ */ jsx(Mic, {}),
|
|
101
|
+
dictationCancel: /* @__PURE__ */ jsx(X, {}),
|
|
102
|
+
dictationAccept: /* @__PURE__ */ jsx(Check, {}),
|
|
100
103
|
scrollToBottom: /* @__PURE__ */ jsx(ArrowDown, {}),
|
|
101
104
|
tokens: /* @__PURE__ */ jsx(ArrowDown, {}),
|
|
102
105
|
sidebar: /* @__PURE__ */ jsx(PanelLeft, {}),
|
|
@@ -200,6 +203,11 @@ const defaultLabels = {
|
|
|
200
203
|
message: "Message",
|
|
201
204
|
stop: "Stop",
|
|
202
205
|
send: "Send",
|
|
206
|
+
listening: "Listening…",
|
|
207
|
+
transcribing: "Transcribing…",
|
|
208
|
+
dictate: "Dictate",
|
|
209
|
+
dictationCancel: "Cancel dictation",
|
|
210
|
+
dictationAccept: "Use dictation",
|
|
203
211
|
addFiles: "Add files and more",
|
|
204
212
|
attachments: "Attachments",
|
|
205
213
|
editPastedText: "Edit pasted text",
|
|
@@ -292,7 +300,7 @@ function CopyButton({ text, className }) {
|
|
|
292
300
|
}
|
|
293
301
|
// src/primitives/segmented-control.tsx
|
|
294
302
|
/**
|
|
295
|
-
* One of a few options, side by side on a track,
|
|
303
|
+
* One of a few options, side by side on a track, similar to claude.ai's Chat / Cowork switch. Themed with
|
|
296
304
|
* `--chat-segment-track` (default: a shade darker than the surface it sits on) and `--chat-segment-selected`
|
|
297
305
|
* (default `--chat-raised`).
|
|
298
306
|
*/
|
|
@@ -1282,12 +1290,34 @@ const useSidebar = () => useContext(SidebarContext);
|
|
|
1282
1290
|
const isReady = (p) => p.status !== "streaming" && p.status !== "input" && p.status !== "error";
|
|
1283
1291
|
const callsOf = (m) => m.parts.filter((p) => p.type === "tool_call");
|
|
1284
1292
|
const replaces = (p) => replacedId(p.input ?? p.partialInput);
|
|
1293
|
+
const titleOf = (p) => {
|
|
1294
|
+
const t = (p.input ?? p.partialInput)?.title;
|
|
1295
|
+
return typeof t === "string" && t ? t : void 0;
|
|
1296
|
+
};
|
|
1297
|
+
/** Ids and titles of the calls seen so far, to resolve `replaces` (an id, or a title as a fallback). */
|
|
1298
|
+
function seen() {
|
|
1299
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1300
|
+
const titles = /* @__PURE__ */ new Map();
|
|
1301
|
+
return {
|
|
1302
|
+
resolve: (call) => {
|
|
1303
|
+
const r = replaces(call);
|
|
1304
|
+
return r === void 0 ? void 0 : resolveReplaces(r, ids, titles);
|
|
1305
|
+
},
|
|
1306
|
+
add: (call) => {
|
|
1307
|
+
ids.add(call.id);
|
|
1308
|
+
const t = titleOf(call);
|
|
1309
|
+
if (t) titles.set(t, call.id);
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1285
1313
|
/** One reply's chains: each call's first call (where the chain is drawn) and each first call's chain, in order. */
|
|
1286
1314
|
function chainsOf(message) {
|
|
1287
1315
|
const first = /* @__PURE__ */ new Map();
|
|
1288
1316
|
const chains = /* @__PURE__ */ new Map();
|
|
1317
|
+
const known = seen();
|
|
1289
1318
|
for (const call of callsOf(message)) {
|
|
1290
|
-
const r =
|
|
1319
|
+
const r = known.resolve(call);
|
|
1320
|
+
known.add(call);
|
|
1291
1321
|
const root = r !== void 0 && first.has(r) ? first.get(r) : call.id;
|
|
1292
1322
|
first.set(call.id, root);
|
|
1293
1323
|
chains.set(root, [...chains.get(root) ?? [], call]);
|
|
@@ -1300,13 +1330,16 @@ function chainsOf(message) {
|
|
|
1300
1330
|
/** Calls replaced by a finished call in a later reply: replaced id → the newest such call. */
|
|
1301
1331
|
function laterReplacements(messages) {
|
|
1302
1332
|
const later = /* @__PURE__ */ new Map();
|
|
1333
|
+
const known = seen();
|
|
1303
1334
|
for (const m of messages) {
|
|
1304
1335
|
if (m.role !== "assistant") continue;
|
|
1305
|
-
const
|
|
1306
|
-
|
|
1307
|
-
|
|
1336
|
+
const calls = callsOf(m);
|
|
1337
|
+
const own = new Set(calls.map((c) => c.id));
|
|
1338
|
+
for (const call of calls) {
|
|
1339
|
+
const r = known.resolve(call);
|
|
1308
1340
|
if (r !== void 0 && !own.has(r) && isReady(call)) later.set(r, call);
|
|
1309
1341
|
}
|
|
1342
|
+
calls.forEach(known.add);
|
|
1310
1343
|
}
|
|
1311
1344
|
return later;
|
|
1312
1345
|
}
|
|
@@ -1524,8 +1557,10 @@ function watchTheme(el, onChange) {
|
|
|
1524
1557
|
media?.removeEventListener?.("change", onChange);
|
|
1525
1558
|
};
|
|
1526
1559
|
}
|
|
1527
|
-
function WidgetFrame({ html, document: isDocument = false, streaming = false, title, loadingMessages, allow, csp: request, onPrompt, onOpenLink, onCallTool, onError, toolInput, toolResult, cancelled, className }) {
|
|
1560
|
+
function WidgetFrame({ html, document: isDocument = false, streaming = false, title, loadingMessages, allow, csp: request, onPrompt, onOpenLink, onCallTool, onError, toolInput, toolResult, cancelled, frameUrl: ownFrameUrl, className }) {
|
|
1528
1561
|
const labels = useLabels();
|
|
1562
|
+
const hostFrameUrl = useWidgetHost().frameUrl;
|
|
1563
|
+
const frameUrl = ownFrameUrl ?? hostFrameUrl;
|
|
1529
1564
|
const frame = useRef(null);
|
|
1530
1565
|
const host = useRef(null);
|
|
1531
1566
|
const [ready, setReady] = useState(false);
|
|
@@ -1547,7 +1582,8 @@ function WidgetFrame({ html, document: isDocument = false, streaming = false, ti
|
|
|
1547
1582
|
onCallTool,
|
|
1548
1583
|
onError,
|
|
1549
1584
|
policy,
|
|
1550
|
-
effective
|
|
1585
|
+
effective,
|
|
1586
|
+
doc
|
|
1551
1587
|
});
|
|
1552
1588
|
latest.current = {
|
|
1553
1589
|
onPrompt,
|
|
@@ -1555,7 +1591,16 @@ function WidgetFrame({ html, document: isDocument = false, streaming = false, ti
|
|
|
1555
1591
|
onCallTool,
|
|
1556
1592
|
onError,
|
|
1557
1593
|
policy,
|
|
1558
|
-
effective
|
|
1594
|
+
effective,
|
|
1595
|
+
doc
|
|
1596
|
+
};
|
|
1597
|
+
const generation = useRef({
|
|
1598
|
+
doc,
|
|
1599
|
+
n: 0
|
|
1600
|
+
});
|
|
1601
|
+
if (generation.current.doc !== doc) generation.current = {
|
|
1602
|
+
doc,
|
|
1603
|
+
n: generation.current.n + 1
|
|
1559
1604
|
};
|
|
1560
1605
|
const send = (message) => frame.current?.contentWindow?.postMessage({
|
|
1561
1606
|
jsonrpc: "2.0",
|
|
@@ -1605,6 +1650,14 @@ function WidgetFrame({ html, document: isDocument = false, streaming = false, ti
|
|
|
1605
1650
|
});
|
|
1606
1651
|
const onMessage = async (e) => {
|
|
1607
1652
|
if (!frame.current || e.source !== frame.current.contentWindow) return;
|
|
1653
|
+
if (e.data?.type === widgetLoaderMessages.ready) {
|
|
1654
|
+
const html = latest.current.doc;
|
|
1655
|
+
if (html) frame.current.contentWindow?.postMessage({
|
|
1656
|
+
type: widgetLoaderMessages.document,
|
|
1657
|
+
html
|
|
1658
|
+
}, "*");
|
|
1659
|
+
return;
|
|
1660
|
+
}
|
|
1608
1661
|
const m = e.data ?? {};
|
|
1609
1662
|
if (typeof m !== "object" || typeof m.method !== "string") return;
|
|
1610
1663
|
const { onPrompt, onOpenLink, onCallTool, effective } = latest.current;
|
|
@@ -1723,13 +1776,13 @@ function WidgetFrame({ html, document: isDocument = false, streaming = false, ti
|
|
|
1723
1776
|
ref: frame,
|
|
1724
1777
|
title: title ?? labels.widget,
|
|
1725
1778
|
sandbox: "allow-scripts",
|
|
1726
|
-
srcDoc: doc,
|
|
1779
|
+
...frameUrl ? { src: frameUrl } : { srcDoc: doc },
|
|
1727
1780
|
style: {
|
|
1728
1781
|
height: height || (streaming ? 120 : 0),
|
|
1729
1782
|
transition: "height 150ms ease-out"
|
|
1730
1783
|
},
|
|
1731
1784
|
className: "block w-full border-0 bg-transparent"
|
|
1732
|
-
})]
|
|
1785
|
+
}, frameUrl ? generation.current.n : "srcdoc")]
|
|
1733
1786
|
});
|
|
1734
1787
|
}
|
|
1735
1788
|
/** Pulls the host's abilities from context into frame props. */
|
|
@@ -3221,11 +3274,248 @@ function GroupList({ group }) {
|
|
|
3221
3274
|
function formatShare(fraction) {
|
|
3222
3275
|
return `${(fraction * 100).toFixed(1)}%`;
|
|
3223
3276
|
}
|
|
3277
|
+
// src/components/dictation.tsx
|
|
3278
|
+
/**
|
|
3279
|
+
* Voice dictation in the composer, similar to claude.ai's: while listening the words fill the box as they are
|
|
3280
|
+
* heard ("Listening…" before the first), a dotted meter follows the voice, and ✕ / ✓ take the send button's
|
|
3281
|
+
* place. The kit draws the state and records; the words come from a transcription model the host plugs in
|
|
3282
|
+
* (`useDictation({ transcribe })`), or from the browser's speech recognition without one.
|
|
3283
|
+
*/
|
|
3284
|
+
/** A row of dots that grow into bars with the voice; flat dots when it is quiet. */
|
|
3285
|
+
function VoiceMeter({ levels, count = 16, className }) {
|
|
3286
|
+
const recent = levels.slice(-count);
|
|
3287
|
+
const dots = [...Array(count - recent.length).fill(0), ...recent];
|
|
3288
|
+
return /* @__PURE__ */ jsx("div", {
|
|
3289
|
+
"aria-hidden": true,
|
|
3290
|
+
className: clsx("flex h-6 items-center gap-[3px] px-1", className),
|
|
3291
|
+
children: dots.map((level, i) => /* @__PURE__ */ jsx("span", {
|
|
3292
|
+
className: "chat-voice-dot w-[3px] rounded-full bg-chat-subtle transition-[height] duration-75",
|
|
3293
|
+
style: { height: `${Math.max(3, Math.min(1, level) * 20)}px` }
|
|
3294
|
+
}, i))
|
|
3295
|
+
});
|
|
3296
|
+
}
|
|
3297
|
+
/** The mic button that starts dictation; put it in the composer's `trailing`. */
|
|
3298
|
+
function DictationButton({ onPress, isDisabled, className }) {
|
|
3299
|
+
const icons = useIcons();
|
|
3300
|
+
const labels = useLabels();
|
|
3301
|
+
return /* @__PURE__ */ jsx(IconButton, {
|
|
3302
|
+
label: labels.dictate,
|
|
3303
|
+
onPress,
|
|
3304
|
+
...isDisabled && { isDisabled },
|
|
3305
|
+
...className && { className },
|
|
3306
|
+
children: icons.mic
|
|
3307
|
+
});
|
|
3308
|
+
}
|
|
3309
|
+
/** The meter, ✕ and ✓: what the composer shows in place of send while dictating. */
|
|
3310
|
+
function DictationControls({ dictation, onAccept, finishing }) {
|
|
3311
|
+
const icons = useIcons();
|
|
3312
|
+
const labels = useLabels();
|
|
3313
|
+
const square = "rounded-[var(--chat-send-radius,var(--chat-radius-md))]! bg-chat-raised border border-chat-border";
|
|
3314
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3315
|
+
className: "flex items-center gap-1",
|
|
3316
|
+
children: [
|
|
3317
|
+
/* @__PURE__ */ jsx(VoiceMeter, { levels: dictation.levels }),
|
|
3318
|
+
/* @__PURE__ */ jsx(IconButton, {
|
|
3319
|
+
label: labels.dictationCancel,
|
|
3320
|
+
onPress: dictation.onCancel,
|
|
3321
|
+
className: square,
|
|
3322
|
+
children: icons.dictationCancel
|
|
3323
|
+
}),
|
|
3324
|
+
/* @__PURE__ */ jsx(IconButton, {
|
|
3325
|
+
label: labels.dictationAccept,
|
|
3326
|
+
onPress: onAccept,
|
|
3327
|
+
isDisabled: finishing,
|
|
3328
|
+
className: square,
|
|
3329
|
+
children: icons.dictationAccept
|
|
3330
|
+
})
|
|
3331
|
+
]
|
|
3332
|
+
});
|
|
3333
|
+
}
|
|
3334
|
+
const recognitionClass = () => {
|
|
3335
|
+
if (typeof window === "undefined") return void 0;
|
|
3336
|
+
const w = window;
|
|
3337
|
+
return w.SpeechRecognition ?? w.webkitSpeechRecognition;
|
|
3338
|
+
};
|
|
3339
|
+
/** Encodes mono samples as 16-bit PCM WAV. */
|
|
3340
|
+
function encodeWav(samples, sampleRate) {
|
|
3341
|
+
const view = /* @__PURE__ */ new DataView(/* @__PURE__ */ new ArrayBuffer(44 + samples.length * 2));
|
|
3342
|
+
const text = (at, s) => [...s].forEach((c, i) => view.setUint8(at + i, c.charCodeAt(0)));
|
|
3343
|
+
text(0, "RIFF");
|
|
3344
|
+
view.setUint32(4, 36 + samples.length * 2, true);
|
|
3345
|
+
text(8, "WAVE");
|
|
3346
|
+
text(12, "fmt ");
|
|
3347
|
+
view.setUint32(16, 16, true);
|
|
3348
|
+
view.setUint16(20, 1, true);
|
|
3349
|
+
view.setUint16(22, 1, true);
|
|
3350
|
+
view.setUint32(24, sampleRate, true);
|
|
3351
|
+
view.setUint32(28, sampleRate * 2, true);
|
|
3352
|
+
view.setUint16(32, 2, true);
|
|
3353
|
+
view.setUint16(34, 16, true);
|
|
3354
|
+
text(36, "data");
|
|
3355
|
+
view.setUint32(40, samples.length * 2, true);
|
|
3356
|
+
samples.forEach((v, i) => view.setInt16(44 + i * 2, Math.max(-1, Math.min(1, v)) * 32767, true));
|
|
3357
|
+
return new Blob([view.buffer], { type: "audio/wav" });
|
|
3358
|
+
}
|
|
3359
|
+
/** A recording (whatever MediaRecorder made) as 16 kHz mono WAV, the format transcription APIs all take. */
|
|
3360
|
+
async function toWav(recording) {
|
|
3361
|
+
const decoder = new AudioContext();
|
|
3362
|
+
try {
|
|
3363
|
+
const decoded = await decoder.decodeAudioData(await recording.arrayBuffer());
|
|
3364
|
+
const rate = 16e3;
|
|
3365
|
+
const offline = new OfflineAudioContext(1, Math.max(1, Math.ceil(decoded.duration * rate)), rate);
|
|
3366
|
+
const source = offline.createBufferSource();
|
|
3367
|
+
source.buffer = decoded;
|
|
3368
|
+
source.connect(offline.destination);
|
|
3369
|
+
source.start();
|
|
3370
|
+
return encodeWav((await offline.startRendering()).getChannelData(0), rate);
|
|
3371
|
+
} finally {
|
|
3372
|
+
decoder.close();
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
/**
|
|
3376
|
+
* Dictation for the composer: records the mic, draws its level, and fills the box with the words as they
|
|
3377
|
+
* are heard. Plug in your transcription model with `transcribe`; a streaming model can instead drive
|
|
3378
|
+
* `DictationState` directly.
|
|
3379
|
+
*/
|
|
3380
|
+
function useDictation({ transcribe, format = "wav", partialEvery = 1500, lang, onError } = {}) {
|
|
3381
|
+
const [active, setActive] = useState(false);
|
|
3382
|
+
const [transcript, setTranscript] = useState("");
|
|
3383
|
+
const [levels, setLevels] = useState([]);
|
|
3384
|
+
const session = useRef(void 0);
|
|
3385
|
+
const latest = useRef({
|
|
3386
|
+
transcribe,
|
|
3387
|
+
format,
|
|
3388
|
+
partialEvery,
|
|
3389
|
+
lang,
|
|
3390
|
+
onError
|
|
3391
|
+
});
|
|
3392
|
+
latest.current = {
|
|
3393
|
+
transcribe,
|
|
3394
|
+
format,
|
|
3395
|
+
partialEvery,
|
|
3396
|
+
lang,
|
|
3397
|
+
onError
|
|
3398
|
+
};
|
|
3399
|
+
const reset = useCallback(() => {
|
|
3400
|
+
session.current?.stop();
|
|
3401
|
+
session.current = void 0;
|
|
3402
|
+
setActive(false);
|
|
3403
|
+
setTranscript("");
|
|
3404
|
+
setLevels([]);
|
|
3405
|
+
}, []);
|
|
3406
|
+
useEffect(() => reset, [reset]);
|
|
3407
|
+
const start = useCallback(() => {
|
|
3408
|
+
if (session.current || typeof navigator === "undefined" || !navigator.mediaDevices) return;
|
|
3409
|
+
const { transcribe, format, partialEvery, lang, onError } = latest.current;
|
|
3410
|
+
const audioOf = (blob) => format === "wav" ? toWav(blob) : Promise.resolve(blob);
|
|
3411
|
+
const Recognition = transcribe ? void 0 : recognitionClass();
|
|
3412
|
+
if (!transcribe && !Recognition) return;
|
|
3413
|
+
const abort = new AbortController();
|
|
3414
|
+
const cleanups = [() => abort.abort()];
|
|
3415
|
+
const stop = () => cleanups.splice(0).forEach((f) => f());
|
|
3416
|
+
let heard = "";
|
|
3417
|
+
const fail = (error) => {
|
|
3418
|
+
if (abort.signal.aborted) return;
|
|
3419
|
+
onError?.(error);
|
|
3420
|
+
reset();
|
|
3421
|
+
};
|
|
3422
|
+
let recognition;
|
|
3423
|
+
if (Recognition) {
|
|
3424
|
+
recognition = new Recognition();
|
|
3425
|
+
const r = recognition;
|
|
3426
|
+
r.continuous = true;
|
|
3427
|
+
r.interimResults = true;
|
|
3428
|
+
r.lang = lang ?? document.documentElement.lang;
|
|
3429
|
+
r.onresult = (e) => setTranscript(heard = Array.from(e.results, (x) => x[0]?.transcript ?? "").join("").trim());
|
|
3430
|
+
r.onerror = (e) => e.error !== "no-speech" && e.error !== "aborted" && fail(new Error(e.error));
|
|
3431
|
+
r.onend = () => !abort.signal.aborted && r.start();
|
|
3432
|
+
r.start();
|
|
3433
|
+
cleanups.push(() => (r.onend = null, r.abort()));
|
|
3434
|
+
}
|
|
3435
|
+
const chunks = [];
|
|
3436
|
+
let recorder;
|
|
3437
|
+
const ready = navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
|
|
3438
|
+
if (abort.signal.aborted) return stream.getTracks().forEach((t) => t.stop());
|
|
3439
|
+
cleanups.push(() => stream.getTracks().forEach((t) => t.stop()));
|
|
3440
|
+
const audio = new AudioContext();
|
|
3441
|
+
cleanups.push(() => void audio.close());
|
|
3442
|
+
const analyser = audio.createAnalyser();
|
|
3443
|
+
analyser.fftSize = 512;
|
|
3444
|
+
audio.createMediaStreamSource(stream).connect(analyser);
|
|
3445
|
+
const samples = new Float32Array(analyser.fftSize);
|
|
3446
|
+
let last = 0;
|
|
3447
|
+
let frame = requestAnimationFrame(function tick(now) {
|
|
3448
|
+
frame = requestAnimationFrame(tick);
|
|
3449
|
+
if (now - last < 70) return;
|
|
3450
|
+
last = now;
|
|
3451
|
+
analyser.getFloatTimeDomainData(samples);
|
|
3452
|
+
let sum = 0;
|
|
3453
|
+
for (const v of samples) sum += v * v;
|
|
3454
|
+
setLevels((l) => [...l.slice(-31), Math.min(1, Math.sqrt(sum / samples.length) * 6)]);
|
|
3455
|
+
});
|
|
3456
|
+
cleanups.push(() => cancelAnimationFrame(frame));
|
|
3457
|
+
if (!transcribe) return;
|
|
3458
|
+
const r = new MediaRecorder(stream);
|
|
3459
|
+
recorder = r;
|
|
3460
|
+
r.ondataavailable = (e) => e.data.size && chunks.push(e.data);
|
|
3461
|
+
r.start(250);
|
|
3462
|
+
cleanups.push(() => r.state !== "inactive" && r.stop());
|
|
3463
|
+
if (partialEvery > 0) {
|
|
3464
|
+
let busy = false;
|
|
3465
|
+
const timer = setInterval(() => {
|
|
3466
|
+
if (busy || !chunks.length) return;
|
|
3467
|
+
busy = true;
|
|
3468
|
+
audioOf(new Blob(chunks, { type: r.mimeType })).then((wav) => transcribe(wav, abort.signal)).then((text) => !abort.signal.aborted && setTranscript(heard = text.trim())).catch(() => {}).finally(() => busy = false);
|
|
3469
|
+
}, partialEvery);
|
|
3470
|
+
cleanups.push(() => clearInterval(timer));
|
|
3471
|
+
}
|
|
3472
|
+
}, fail);
|
|
3473
|
+
session.current = {
|
|
3474
|
+
stop,
|
|
3475
|
+
finish: async () => {
|
|
3476
|
+
if (!transcribe) return stop(), heard;
|
|
3477
|
+
await ready;
|
|
3478
|
+
const r = recorder;
|
|
3479
|
+
if (r && r.state !== "inactive") await new Promise((done) => {
|
|
3480
|
+
r.addEventListener("stop", () => done(), { once: true });
|
|
3481
|
+
r.stop();
|
|
3482
|
+
});
|
|
3483
|
+
if (!chunks.length) return stop(), heard;
|
|
3484
|
+
const text = await transcribe(await audioOf(new Blob(chunks, { type: r?.mimeType })), abort.signal);
|
|
3485
|
+
stop();
|
|
3486
|
+
return text.trim();
|
|
3487
|
+
}
|
|
3488
|
+
};
|
|
3489
|
+
setActive(true);
|
|
3490
|
+
}, [reset]);
|
|
3491
|
+
const accept = useCallback(async () => {
|
|
3492
|
+
const s = session.current;
|
|
3493
|
+
if (!s) return;
|
|
3494
|
+
try {
|
|
3495
|
+
return await s.finish();
|
|
3496
|
+
} catch (error) {
|
|
3497
|
+
latest.current.onError?.(error);
|
|
3498
|
+
return;
|
|
3499
|
+
} finally {
|
|
3500
|
+
if (session.current === s) reset();
|
|
3501
|
+
}
|
|
3502
|
+
}, [reset]);
|
|
3503
|
+
return {
|
|
3504
|
+
supported: typeof navigator !== "undefined" && !!navigator.mediaDevices && (!!transcribe || recognitionClass() !== void 0),
|
|
3505
|
+
start,
|
|
3506
|
+
state: active ? {
|
|
3507
|
+
levels,
|
|
3508
|
+
transcript,
|
|
3509
|
+
onCancel: reset,
|
|
3510
|
+
onAccept: accept
|
|
3511
|
+
} : void 0
|
|
3512
|
+
};
|
|
3513
|
+
}
|
|
3224
3514
|
// src/components/composer.tsx
|
|
3225
3515
|
/** Touch keyboards have no easy Shift+Enter, so there Enter adds a line and the button sends. */
|
|
3226
3516
|
const coarsePointer = () => typeof window !== "undefined" && window.matchMedia?.("(pointer: coarse)").matches;
|
|
3227
3517
|
/** The chat box: growing textarea, toolbar slots, send / stop. Enter sends, Shift+Enter adds a line. */
|
|
3228
|
-
function Composer({ onSubmit, onStop, busy = false, value, onChange, placeholder, variant = "docked", leading, trailing, above, onFiles, onLongPaste, longPasteChars = 2e3, allowEmpty = false, submitDisabled = false, isDisabled = false, autoFocus, className }) {
|
|
3518
|
+
function Composer({ onSubmit, onStop, busy = false, value, onChange, placeholder, variant = "docked", leading, trailing, above, onFiles, onLongPaste, longPasteChars = 2e3, allowEmpty = false, submitDisabled = false, isDisabled = false, dictation, autoFocus, className }) {
|
|
3229
3519
|
const icons = useIcons();
|
|
3230
3520
|
const labels = useLabels();
|
|
3231
3521
|
const [own, setOwn] = useState("");
|
|
@@ -3257,8 +3547,22 @@ function Composer({ onSubmit, onStop, busy = false, value, onChange, placeholder
|
|
|
3257
3547
|
observer.observe(el);
|
|
3258
3548
|
return () => observer.disconnect();
|
|
3259
3549
|
}, [fit]);
|
|
3550
|
+
const [finishing, setFinishing] = useState(false);
|
|
3551
|
+
const joined = (words) => words ? text.trim() ? `${text.replace(/\s+$/, "")} ${words}` : words : text;
|
|
3552
|
+
const acceptDictation = async () => {
|
|
3553
|
+
if (!dictation || finishing) return;
|
|
3554
|
+
const heard = dictation.transcript;
|
|
3555
|
+
setFinishing(true);
|
|
3556
|
+
try {
|
|
3557
|
+
const words = await dictation.onAccept();
|
|
3558
|
+
setText(joined(typeof words === "string" ? words : heard));
|
|
3559
|
+
} finally {
|
|
3560
|
+
setFinishing(false);
|
|
3561
|
+
area.current?.focus();
|
|
3562
|
+
}
|
|
3563
|
+
};
|
|
3260
3564
|
const [dragging, setDragging] = useState(false);
|
|
3261
|
-
const canSend = !busy && !isDisabled && !submitDisabled && (allowEmpty || text.trim().length > 0);
|
|
3565
|
+
const canSend = !dictation && !busy && !isDisabled && !submitDisabled && (allowEmpty || text.trim().length > 0);
|
|
3262
3566
|
const submit = () => {
|
|
3263
3567
|
if (!canSend) return;
|
|
3264
3568
|
onSubmit(text);
|
|
@@ -3299,7 +3603,11 @@ function Composer({ onSubmit, onStop, busy = false, value, onChange, placeholder
|
|
|
3299
3603
|
}
|
|
3300
3604
|
};
|
|
3301
3605
|
const compact = variant === "compact";
|
|
3302
|
-
const action =
|
|
3606
|
+
const action = dictation ? /* @__PURE__ */ jsx(DictationControls, {
|
|
3607
|
+
dictation,
|
|
3608
|
+
onAccept: () => void acceptDictation(),
|
|
3609
|
+
finishing
|
|
3610
|
+
}) : busy ? /* @__PURE__ */ jsx(IconButton, {
|
|
3303
3611
|
label: labels.stop,
|
|
3304
3612
|
variant: "primary",
|
|
3305
3613
|
onPress: onStop,
|
|
@@ -3329,11 +3637,12 @@ function Composer({ onSubmit, onStop, busy = false, value, onChange, placeholder
|
|
|
3329
3637
|
/* @__PURE__ */ jsx("textarea", {
|
|
3330
3638
|
ref: area,
|
|
3331
3639
|
rows: 1,
|
|
3332
|
-
value: text,
|
|
3640
|
+
value: dictation ? joined(dictation.transcript) : text,
|
|
3641
|
+
readOnly: !!dictation,
|
|
3333
3642
|
onChange: (e) => setText(e.target.value),
|
|
3334
3643
|
onKeyDown,
|
|
3335
3644
|
onPaste,
|
|
3336
|
-
placeholder: placeholder ?? labels.replyPlaceholder,
|
|
3645
|
+
placeholder: dictation ? finishing ? labels.transcribing : labels.listening : placeholder ?? labels.replyPlaceholder,
|
|
3337
3646
|
"aria-label": labels.message,
|
|
3338
3647
|
disabled: isDisabled,
|
|
3339
3648
|
autoFocus,
|
|
@@ -3341,7 +3650,7 @@ function Composer({ onSubmit, onStop, busy = false, value, onChange, placeholder
|
|
|
3341
3650
|
}),
|
|
3342
3651
|
compact ? /* @__PURE__ */ jsxs("div", {
|
|
3343
3652
|
className: "flex shrink-0 items-center gap-1",
|
|
3344
|
-
children: [trailing, action]
|
|
3653
|
+
children: [!dictation && trailing, action]
|
|
3345
3654
|
}) : /* @__PURE__ */ jsxs("div", {
|
|
3346
3655
|
className: "flex items-center gap-1",
|
|
3347
3656
|
children: [
|
|
@@ -3349,7 +3658,7 @@ function Composer({ onSubmit, onStop, busy = false, value, onChange, placeholder
|
|
|
3349
3658
|
className: "flex min-w-0 flex-1 items-center gap-1",
|
|
3350
3659
|
children: leading
|
|
3351
3660
|
}),
|
|
3352
|
-
trailing,
|
|
3661
|
+
!dictation && trailing,
|
|
3353
3662
|
action
|
|
3354
3663
|
]
|
|
3355
3664
|
})
|
|
@@ -3460,7 +3769,7 @@ function EffortSlider({ efforts, value, onChange, label, className }) {
|
|
|
3460
3769
|
]
|
|
3461
3770
|
});
|
|
3462
3771
|
}
|
|
3463
|
-
/** A composer pill ("◎ Medium") that opens the effort slider above it,
|
|
3772
|
+
/** A composer pill ("◎ Medium") that opens the effort slider above it, similar to chatgpt.com's Think button. */
|
|
3464
3773
|
function EffortButton({ icon, children, className, ...slider }) {
|
|
3465
3774
|
const current = slider.efforts.find((e) => e.id === slider.value) ?? slider.efforts[0];
|
|
3466
3775
|
const labels = useLabels();
|
|
@@ -4079,12 +4388,13 @@ function ChatTranscript({ messages, renderPart, widgets, header, notice, footer,
|
|
|
4079
4388
|
...contentPadding && { "--chat-content-padding": contentPadding }
|
|
4080
4389
|
};
|
|
4081
4390
|
const host = useMemo(() => {
|
|
4082
|
-
const { allow, readResource } = { ...widgets };
|
|
4391
|
+
const { allow, readResource, frameUrl } = { ...widgets };
|
|
4083
4392
|
const onOpenLink = widgets && "onOpenLink" in widgets ? widgets.onOpenLink : openInNewTab;
|
|
4084
4393
|
return {
|
|
4085
4394
|
...allow && { allow },
|
|
4086
4395
|
...onOpenLink && { onOpenLink },
|
|
4087
|
-
...readResource && { readResource }
|
|
4396
|
+
...readResource && { readResource },
|
|
4397
|
+
...frameUrl && { frameUrl }
|
|
4088
4398
|
};
|
|
4089
4399
|
}, [widgets]);
|
|
4090
4400
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -4299,4 +4609,4 @@ function SidebarUser({ name, detail, avatarUrl, menu }) {
|
|
|
4299
4609
|
children: menu
|
|
4300
4610
|
})] });
|
|
4301
4611
|
}
|
|
4302
|
-
export { ActivityGroup, AgentProvider, AgentRegistry, AppShell, ApprovalCard, AssistantMessage, AttachButton, AttachmentCard, AttachmentRow, Badge, Button, Caret, ChatHeader, ChatList, ChatNotice, ChatTheme, ChatTitleMenu, ChatTranscript, ChatView, CodeBlock, Composer, ContextMenu, ContextPanel, CopyButton, DRAWER_QUERY, Disclosure, Drawer, EffortButton, EffortSlider, EmptyState, IconButton, Markdown, MarkdownLinksProvider, Menu, MenuItem, MenuNote, MenuSearch, MenuSection, MenuSeparator, MenuTrigger, MessageList, Modal, ModelPicker, Panel, PastedTextDialog, Popover, SegmentedControl, Sidebar, SidebarItem, SidebarToggle, SidebarUser, SubmenuTrigger, TokenCounter, ToolViewsProvider, Tooltip, UiComponentsProvider, UiMarkupBlock, UiTree, UserMessage, WIDGET_MAX_HEIGHT, WidgetFrame, WidgetHostProvider, WidgetPartView, activityHeading, activityLabel, commandTool, defaultIcons, defaultLabels, defaultToolViews, formatDuration, formatRelativeTime, formatTokens, htmlComponent, intersectAllow, memoryTool, messageText, openInNewTab, readTreeInput, readVisualizeInput, sseTransport, uiMarkupToolView, uiTreeToolView, useAgentContext, useAgentRegistry, useAgentSnapshot, useAgentTool, useAttachments, useChat, useChatTool, useCountUp, useIcons, useLabels, useMediaQuery, useSidebar, useSmoothText, useToolView, useToolViews, useUiAction, useUiMarkupLanguage, useUiState, useWidgetHost, userMessage, webFetchTool, webSearchTool, widgetCsp, widgetToolView };
|
|
4612
|
+
export { ActivityGroup, AgentProvider, AgentRegistry, AppShell, ApprovalCard, AssistantMessage, AttachButton, AttachmentCard, AttachmentRow, Badge, Button, Caret, ChatHeader, ChatList, ChatNotice, ChatTheme, ChatTitleMenu, ChatTranscript, ChatView, CodeBlock, Composer, ContextMenu, ContextPanel, CopyButton, DRAWER_QUERY, DictationButton, DictationControls, Disclosure, Drawer, EffortButton, EffortSlider, EmptyState, IconButton, Markdown, MarkdownLinksProvider, Menu, MenuItem, MenuNote, MenuSearch, MenuSection, MenuSeparator, MenuTrigger, MessageList, Modal, ModelPicker, Panel, PastedTextDialog, Popover, SegmentedControl, Sidebar, SidebarItem, SidebarToggle, SidebarUser, SubmenuTrigger, TokenCounter, ToolViewsProvider, Tooltip, UiComponentsProvider, UiMarkupBlock, UiTree, UserMessage, VoiceMeter, WIDGET_MAX_HEIGHT, WidgetFrame, WidgetHostProvider, WidgetPartView, activityHeading, activityLabel, commandTool, defaultIcons, defaultLabels, defaultToolViews, encodeWav, formatDuration, formatRelativeTime, formatTokens, htmlComponent, intersectAllow, memoryTool, messageText, openInNewTab, readTreeInput, readVisualizeInput, sseTransport, uiMarkupToolView, uiTreeToolView, useAgentContext, useAgentRegistry, useAgentSnapshot, useAgentTool, useAttachments, useChat, useChatTool, useCountUp, useDictation, useIcons, useLabels, useMediaQuery, useSidebar, useSmoothText, useToolView, useToolViews, useUiAction, useUiMarkupLanguage, useUiState, useWidgetHost, userMessage, webFetchTool, webSearchTool, widgetCsp, widgetToolView };
|
|
@@ -231,7 +231,7 @@ function applyFields(part, fields) {
|
|
|
231
231
|
const next = {
|
|
232
232
|
...part,
|
|
233
233
|
...status,
|
|
234
|
-
...pick("title", "subtitle", "durationMs", "input", "result", "data", "error")
|
|
234
|
+
...pick("title", "subtitle", "durationMs", "input", "result", "data", "error", "needsApproval")
|
|
235
235
|
};
|
|
236
236
|
return next.status === "input" || next.status === "streaming" ? next : withParsedInput(next);
|
|
237
237
|
}
|
|
@@ -422,6 +422,34 @@ function parseMessage(text) {
|
|
|
422
422
|
if (data.length === 0) return void 0;
|
|
423
423
|
return JSON.parse(data.join("\n"));
|
|
424
424
|
}
|
|
425
|
+
// ../core/src/widget-loader.ts
|
|
426
|
+
/**
|
|
427
|
+
* The frame page for `WidgetHost.frameUrl`. Serve this HTML from your own origin (e.g. at /widget-frame.html)
|
|
428
|
+
* when your app's CSP blocks inline scripts: an `srcdoc` frame inherits the page's CSP, a frame loaded from
|
|
429
|
+
* a URL gets the CSP of its own response. The kit loads it sandboxed (opaque origin, no access to your app),
|
|
430
|
+
* posts the widget's document to it, and the loader writes it in. The kit's CSP <meta> inside that document
|
|
431
|
+
* still limits what the widget may load.
|
|
432
|
+
*
|
|
433
|
+
* Its response needs a CSP that lets the loader and the widget run, and no stricter than the kit's, e.g.
|
|
434
|
+
* `Content-Security-Policy: default-src 'none'; script-src 'unsafe-inline' https:; style-src 'unsafe-inline' https:; img-src data: blob: https:; font-src data: https:; connect-src https:`
|
|
435
|
+
* (or no CSP header on that path). Don't set X-Frame-Options or frame-ancestors that exclude your app.
|
|
436
|
+
*/
|
|
437
|
+
/** Message types between the kit and the loader. */
|
|
438
|
+
const widgetLoaderMessages = {
|
|
439
|
+
/** Loader → kit: ready for the document. */
|
|
440
|
+
ready: "agentic-ui-kit:frame-ready",
|
|
441
|
+
/** Kit → loader: `{ type, html }`, the widget's whole document. */
|
|
442
|
+
document: "agentic-ui-kit:frame-document"
|
|
443
|
+
};
|
|
444
|
+
const widgetFrameLoader = `<!doctype html><html><head><meta charset="utf-8"></head><body><script>
|
|
445
|
+
addEventListener("message", function load(e) {
|
|
446
|
+
if (e.source !== parent || !e.data || e.data.type !== "${widgetLoaderMessages.document}" || typeof e.data.html !== "string") return;
|
|
447
|
+
removeEventListener("message", load);
|
|
448
|
+
document.open(); document.write(e.data.html); document.close();
|
|
449
|
+
});
|
|
450
|
+
parent.postMessage({ type: "${widgetLoaderMessages.ready}" }, "*");
|
|
451
|
+
<\/script></body></html>
|
|
452
|
+
`;
|
|
425
453
|
// ../core/src/replaces.ts
|
|
426
454
|
/**
|
|
427
455
|
* Updating a visual in place: the drawing tools (show_widget, show_ui, render_ui) take an optional
|
|
@@ -432,15 +460,27 @@ function parseMessage(text) {
|
|
|
432
460
|
/** The `replaces` input property, shared by the drawing tools. */
|
|
433
461
|
const replacesProperty = {
|
|
434
462
|
type: "string",
|
|
435
|
-
description: "
|
|
463
|
+
description: "The id (or title) of an earlier visual of this tool that this one updates in place: after a fix, or when the user asks for a change. Its tool result says \"Drawn as <id>\". Leave it out for a new visual."
|
|
436
464
|
};
|
|
437
465
|
/** One line for a drawing tool's description or guide. */
|
|
438
|
-
const replacesGuide = "To change a visual you already drew (a fix, or the user asks for a change), call the tool again with `replaces` set to that
|
|
466
|
+
const replacesGuide = "To change a visual you already drew (a fix, or the user asks for a change), call the tool again with `replaces` set to that visual's id (its tool result says Drawn as <id>): it is redrawn in place. Never draw a second copy without it.";
|
|
439
467
|
/** The id a drawing tool call replaces, from its (streaming) input; undefined if none. */
|
|
440
468
|
function replacedId(input) {
|
|
441
469
|
const r = input?.replaces;
|
|
442
470
|
return typeof r === "string" && r ? r : void 0;
|
|
443
471
|
}
|
|
472
|
+
/**
|
|
473
|
+
* The tool result for a drawing call: the check's feedback, prefixed with the call's id, so the model can
|
|
474
|
+
* pass it as `replaces` later. Use it when the model may not see tool call ids (many chat templates drop
|
|
475
|
+
* them): `withCallId(call.id, checkWidgetCode(...).feedback)`.
|
|
476
|
+
*/
|
|
477
|
+
function withCallId(id, feedback) {
|
|
478
|
+
return `Drawn as ${id}. ${feedback}`;
|
|
479
|
+
}
|
|
480
|
+
/** What `replaces` points at: the id of a call, or else the title of the latest call with that title. */
|
|
481
|
+
function resolveReplaces(ref, ids, titles) {
|
|
482
|
+
return ids.has(ref) ? ref : titles.get(ref);
|
|
483
|
+
}
|
|
444
484
|
// ../core/src/ui-tree.ts
|
|
445
485
|
/**
|
|
446
486
|
* Host-registered components: instead of HTML, the model writes a small tree of components the host
|
|
@@ -1103,4 +1143,4 @@ When a visual helps more than text (options to compare, a plan, a checklist, num
|
|
|
1103
1143
|
${markupRules(components)}
|
|
1104
1144
|
- Keep explaining in text around the block. One block per answer, unless the user asks for more.`;
|
|
1105
1145
|
}
|
|
1106
|
-
export {
|
|
1146
|
+
export { awaitingToolCalls as A, widgetLoaderMessages as C, toBlocks as D, isActivityPart as E, settleToolCall as F, parsePartialJson as I, salvageJson as L, outputTokens as M, reduceEvents as N, activityTokens as O, resolveEffort as P, widgetFrameLoader as S, readEventStream as T, replacedId as _, readUiValue as a, resolveReplaces as b, uiMarkupGuide as c, isStateRef as d, matchesSchema as f, uiActionSchema as g, schemaErrors as h, parseUiMarkup as i, estimateTokens as j, applyEvent as k, uiMarkupLanguage as l, renderUiToolName as m, checkUiMarkupCode as n, showUiTool as o, renderUiTool as p, findUiBlocks as r, showUiToolName as s, checkUiMarkup as t, checkUiTree as u, replacesGuide as v, formatEvent as w, withCallId as x, replacesProperty as y };
|
package/dist/styles.css
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
@import "katex/dist/katex.min.css";
|
|
2
2
|
/*! tailwindcss v4.3.4 | MIT License | https://tailwindcss.com */
|
|
3
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:block))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-mask-linear:linear-gradient(#fff, #fff);--tw-mask-radial:linear-gradient(#fff, #fff);--tw-mask-conic:linear-gradient(#fff, #fff);--tw-mask-left:linear-gradient(#fff, #fff);--tw-mask-right:linear-gradient(#fff, #fff);--tw-mask-bottom:linear-gradient(#fff, #fff);--tw-mask-top:linear-gradient(#fff, #fff);--tw-mask-bottom-from-position:0%;--tw-mask-bottom-to-position:100%;--tw-mask-bottom-from-color:black;--tw-mask-bottom-to-color:transparent;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-serif:ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--container-2xl:42rem;--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-normal:400;--font-weight-medium:500;--tracking-wide:.025em;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:.25rem;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root,[data-chat-theme=claude-dark]{color-scheme:dark;--chat-bg:#191919;--chat-sidebar:#1f1f1f;--chat-surface:#303030;--chat-raised:#3a3a3a;--chat-hover:#3d3d3d;--chat-selected:#4a4a4a;--chat-bubble:#2a2a2a;--chat-popover:#303030;--chat-popover-border:#383838;--chat-popover-hover:#4f4f4f;--chat-border:#303030;--chat-border-strong:#454545;--chat-divider:#222;--chat-code-bg:#1c1c1c;--chat-code-border:#252525;--chat-inline-code:#2e2e2e;--chat-fg:#ecebe6;--chat-muted:#a3a29e;--chat-subtle:#75746f;--chat-accent:#d97757;--chat-accent-fg:#fff;--chat-check:#6c9cf0;--chat-warning:#e8b04b;--chat-warning-bg:#4a3b1c;--chat-danger:#e5675c;--chat-focus:#6c9cf0;--chat-backdrop:#00000080;--chat-font-sans:"Inter", ui-sans-serif, system-ui, sans-serif;--chat-font-serif:"Source Serif 4", ui-serif, Georgia, serif;--chat-font-mono:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;--chat-radius-sm:6px;--chat-radius-md:10px;--chat-radius-lg:16px;--chat-radius-popover:12px;--chat-shadow-popover:0 8px 24px #00000080;--chat-content-width:48rem;--chat-content-padding:1.5rem;--chat-message-font-size:1.0625rem;--chat-code-font-size:.8125rem;--chat-message-line-height:1.65;--chat-ui-font-size:.875rem;--chat-ui-font-size-sm:.75rem;--chat-bubble-font-size:.9375rem;--chat-activity-font-size:.9375rem}}@layer components{.chat-markdown{font-family:var(--chat-font-message,var(--chat-font-serif));font-size:var(--chat-message-font-size);line-height:var(--chat-message-line-height);color:var(--chat-fg);overflow-wrap:anywhere}.chat-markdown>div>*+*{margin-top:.75em}.chat-markdown :is(h1,h2,h3,h4){margin-top:1.25em;font-weight:600;line-height:1.3}.chat-markdown h1{font-size:1.5em}.chat-markdown h2{font-size:1.3em}.chat-markdown h3{font-size:1.12em}.chat-markdown :is(strong,[data-streamdown=strong]){font-weight:650}.chat-markdown :is(ul,ol){padding-left:1.6em}.chat-markdown ul{list-style:outside}.chat-markdown ol{list-style:decimal}.chat-markdown li+li,.chat-markdown li>:is(ul,ol){margin-top:.3em}.chat-markdown .chat-ui-tree{font-family:var(--chat-font-sans);font-size:var(--chat-ui-font-size);line-height:1.5}.chat-markdown .chat-ui-tree :is(ul,ol){padding-left:0;list-style:none}.chat-markdown .chat-ui-tree li+li{margin-top:0}.chat-markdown .chat-ui-tree :is(h1,h2,h3,h4){font-size:inherit;margin-top:0}.chat-markdown a{color:var(--chat-fg);text-decoration:underline;-webkit-text-decoration-color:var(--chat-subtle);-webkit-text-decoration-color:var(--chat-subtle);text-decoration-color:var(--chat-subtle);text-underline-offset:3px}.chat-markdown a:hover{-webkit-text-decoration-color:var(--chat-fg);-webkit-text-decoration-color:var(--chat-fg);text-decoration-color:var(--chat-fg)}.chat-markdown blockquote{border-left:3px solid var(--chat-border-strong);color:var(--chat-muted);padding-left:1em}.chat-markdown hr{border-color:var(--chat-border);margin-block:1.5em}.chat-markdown [data-chat-inline-code]{font-family:var(--chat-font-mono);background:var(--chat-inline-code);border-radius:5px;padding:.12em .35em;font-size:.82em}.chat-markdown [data-streamdown=table-wrapper]{margin-block:1em;overflow-x:auto}.chat-markdown table{border-collapse:collapse;font-family:var(--chat-font-sans);font-size:var(--chat-ui-font-size)}.chat-markdown :is(th,td){border-bottom:1px solid var(--chat-border);text-align:left;padding:.45em .9em .45em 0}.chat-markdown th{font-weight:600}.chat-markdown .katex-display{margin-block:1em;overflow:auto hidden}.chat-markdown .katex{font-size:1.08em}.chat-markdown.chat-fade .chat-word{animation:chat-word-in var(--chat-fade-duration,.7s) ease-out both}.chat-view{container:chat/inline-size}.chat-view-body{--chat-gutter:var(--chat-content-padding);container:chat-body/size}@container chat (max-width:34rem){.chat-view-body{--chat-gutter:min(var(--chat-content-padding), .75rem)}}@container chat (max-width:24rem){.chat-picker-detail{display:none}}@container chat-body (max-height:24rem){.chat-empty-greeting{display:none}}.chat-code-token{color:light-dark(var(--shiki-light),var(--shiki-dark))}.chat-shimmer{background-image:linear-gradient(90deg, var(--chat-muted) 0%, var(--chat-muted) 35%, var(--chat-fg) 50%, var(--chat-muted) 65%, var(--chat-muted) 100%);color:#0000;animation:chat-shimmer var(--chat-shimmer-duration,2s) linear infinite;background-repeat:repeat-x;background-size:20em 100%;-webkit-background-clip:text;background-clip:text}.chat-markdown.chat-thinking{font-family:var(--chat-font-sans);font-size:var(--chat-activity-font-size);color:var(--chat-muted);line-height:1.6}.chat-shimmer-surface:after{content:"";background:linear-gradient(100deg, transparent 30%, var(--chat-fg) 50%, transparent 70%) 0 0 / 300% 100%;position:absolute;inset:0}@supports (color:color-mix(in lab, red, red)){.chat-shimmer-surface:after{background:linear-gradient(100deg, transparent 30%, color-mix(in srgb, var(--chat-fg) 12%, transparent) 50%, transparent 70%) 0 0 / 300% 100%}}.chat-shimmer-surface:after{pointer-events:none;animation:1.6s linear infinite chat-shimmer-surface}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.-inset-x-2{inset-inline:calc(var(--spacing) * -2)}.inset-x-2{inset-inline:calc(var(--spacing) * 2)}.inset-y-0{inset-block:0}.-top-2{top:calc(var(--spacing) * -2)}.top-1\/2{top:50%}.-right-2{right:calc(var(--spacing) * -2)}.right-0{right:0}.right-1{right:var(--spacing)}.bottom-0{bottom:0}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-\[min\(10rem\,40\%\)\]{bottom:min(10rem,40%)}.left-0{left:0}.left-1\/2{left:50%}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.-mx-1\.5{margin-inline:calc(var(--spacing) * -1.5)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-5{margin-inline:calc(var(--spacing) * 5)}.mx-auto{margin-inline:auto}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-4{margin-block:calc(var(--spacing) * 4)}.-mt-1\.5{margin-top:calc(var(--spacing) * -1.5)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.-mr-2{margin-right:calc(var(--spacing) * -2)}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.-ml-1\.5{margin-left:calc(var(--spacing) * -1.5)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-auto{margin-left:auto}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.size-0{width:0;height:0}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-24{width:calc(var(--spacing) * 24);height:calc(var(--spacing) * 24)}.size-30{width:calc(var(--spacing) * 30);height:calc(var(--spacing) * 30)}.size-\[1\.15em\]{width:1.15em;height:1.15em}.size-full{width:100%;height:100%}.h-1{height:var(--spacing)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-dvh{height:100dvh}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-56{max-height:calc(var(--spacing) * 56)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[85dvh\]{max-height:85dvh}.max-h-\[inherit\]{max-height:inherit}.max-h-\[min\(10rem\,30cqh\)\]{max-height:min(10rem,30cqh)}.max-h-\[min\(18rem\,35cqh\)\]{max-height:min(18rem,35cqh)}.max-h-\[min\(24rem\,45cqh\)\]{max-height:min(24rem,45cqh)}.min-h-0{min-height:0}.min-h-2{min-height:calc(var(--spacing) * 2)}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-7{min-height:calc(var(--spacing) * 7)}.min-h-12{min-height:calc(var(--spacing) * 12)}.min-h-64{min-height:calc(var(--spacing) * 64)}.min-h-full{min-height:100%}.w-\(--chat-sidebar-width\,18rem\){width:var(--chat-sidebar-width,18rem)}.w-7{width:calc(var(--spacing) * 7)}.w-9{width:calc(var(--spacing) * 9)}.w-12{width:calc(var(--spacing) * 12)}.w-13{width:calc(var(--spacing) * 13)}.w-14{width:calc(var(--spacing) * 14)}.w-60{width:calc(var(--spacing) * 60)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-\[calc\(100\%\+1rem\)\]{width:calc(100% + 1rem)}.w-\[min\(20rem\,85vw\)\]{width:min(20rem,85vw)}.w-\[min\(36rem\,calc\(100vw-2rem\)\)\]{width:min(36rem,100vw - 2rem)}.w-full{width:100%}.max-w-\(--chat-content-width\){max-width:var(--chat-content-width)}.max-w-2xl{max-width:var(--container-2xl)}.max-w-\[85\%\]{max-width:85%}.max-w-\[calc\(var\(--chat-content-width\)\+2\*var\(--chat-gutter\,var\(--chat-content-padding\)\)\)\]{max-width:calc(var(--chat-content-width) + 2 * var(--chat-gutter,var(--chat-content-padding)))}.max-w-full{max-width:100%}.min-w-0{min-width:0}.min-w-44{min-width:calc(var(--spacing) * 44)}.min-w-52{min-width:calc(var(--spacing) * 52)}.min-w-\[2px\]{min-width:2px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.animate-pulse{animation:var(--animate-pulse)}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.\[scrollbar-width\:thin\]{scrollbar-width:thin}.\[scrollbar-color\:var\(--chat-border-strong\)_transparent\]{scrollbar-color:var(--chat-border-strong) transparent}.\[scrollbar-gutter\:stable\]{scrollbar-gutter:stable}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-px{gap:1px}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-chat-divider>:not(:last-child)){border-color:var(--chat-divider)}.self-center{align-self:center}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded-\[0\.3rem\]{border-radius:.3rem}.rounded-\[2px\]{border-radius:2px}.rounded-\[calc\(var\(--chat-radius-md\)-2px\)\]{border-radius:calc(var(--chat-radius-md) - 2px)}.rounded-\[inherit\]{border-radius:inherit}.rounded-\[var\(--chat-composer-radius\,1\.25rem\)\]{border-radius:var(--chat-composer-radius,1.25rem)}.rounded-\[var\(--chat-send-radius\,var\(--chat-radius-md\)\)\]\!{border-radius:var(--chat-send-radius,var(--chat-radius-md))!important}.rounded-chat-lg{border-radius:var(--chat-radius-lg)}.rounded-chat-md{border-radius:var(--chat-radius-md)}.rounded-chat-popover{border-radius:var(--chat-radius-popover)}.rounded-chat-sm{border-radius:var(--chat-radius-sm)}.rounded-full{border-radius:2147483647px}.rounded-sm{border-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\(--chat-notice-border\,var\(--chat-border\)\){border-color:var(--chat-notice-border,var(--chat-border))}.border-chat-accent{border-color:var(--chat-accent)}.border-chat-accent\!{border-color:var(--chat-accent)!important}.border-chat-border{border-color:var(--chat-border)}.border-chat-border-strong{border-color:var(--chat-border-strong)}.border-chat-code-border{border-color:var(--chat-code-border)}.border-chat-danger{border-color:var(--chat-danger)}.border-chat-divider{border-color:var(--chat-divider)}.border-chat-popover-border{border-color:var(--chat-popover-border)}.bg-\(--chat-backdrop\){background-color:var(--chat-backdrop)}.bg-\(--chat-notice-bg\,transparent\){background-color:var(--chat-notice-bg,transparent)}.bg-\[var\(--chat-danger-bg\,color-mix\(in_srgb\,var\(--chat-danger\)_70\%\,black\)\)\]{background-color:var(--chat-danger-bg,var(--chat-danger))}@supports (color:color-mix(in lab, red, red)){.bg-\[var\(--chat-danger-bg\,color-mix\(in_srgb\,var\(--chat-danger\)_70\%\,black\)\)\]{background-color:var(--chat-danger-bg,color-mix(in srgb,var(--chat-danger) 70%,black))}}.bg-\[var\(--chat-segment-track\,color-mix\(in_srgb\,var\(--chat-bg\)_55\%\,transparent\)\)\]{background-color:var(--chat-segment-track,var(--chat-bg))}@supports (color:color-mix(in lab, red, red)){.bg-\[var\(--chat-segment-track\,color-mix\(in_srgb\,var\(--chat-bg\)_55\%\,transparent\)\)\]{background-color:var(--chat-segment-track,color-mix(in srgb,var(--chat-bg) 55%,transparent))}}.bg-chat-accent{background-color:var(--chat-accent)}.bg-chat-accent-fg\/70{background-color:var(--chat-accent-fg)}@supports (color:color-mix(in lab, red, red)){.bg-chat-accent-fg\/70{background-color:color-mix(in oklab, var(--chat-accent-fg) 70%, transparent)}}.bg-chat-bg{background-color:var(--chat-bg)}.bg-chat-border-strong{background-color:var(--chat-border-strong)}.bg-chat-bubble{background-color:var(--chat-bubble)}.bg-chat-check{background-color:var(--chat-check)}.bg-chat-code-bg{background-color:var(--chat-code-bg)}.bg-chat-fg{background-color:var(--chat-fg)}.bg-chat-popover{background-color:var(--chat-popover)}.bg-chat-raised{background-color:var(--chat-raised)}.bg-chat-selected{background-color:var(--chat-selected)}.bg-chat-sidebar{background-color:var(--chat-sidebar)}.bg-chat-subtle{background-color:var(--chat-subtle)}.bg-chat-surface{background-color:var(--chat-surface)}.bg-chat-warning-bg{background-color:var(--chat-warning-bg)}.bg-transparent{background-color:#0000}.bg-linear-to-t{--tw-gradient-position:to top}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-t{--tw-gradient-position:to top in oklab}}.bg-linear-to-t{background-image:linear-gradient(var(--tw-gradient-stops))}.from-chat-bg{--tw-gradient-from:var(--chat-bg);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-70\%{--tw-gradient-from-position:70%}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.mask-b-from-60\%{-webkit-mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);-webkit-mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);--tw-mask-linear:var(--tw-mask-left), var(--tw-mask-right), var(--tw-mask-bottom), var(--tw-mask-top);--tw-mask-bottom:linear-gradient(to bottom, var(--tw-mask-bottom-from-color) var(--tw-mask-bottom-from-position), var(--tw-mask-bottom-to-color) var(--tw-mask-bottom-to-position));--tw-mask-bottom-from-position:60%;-webkit-mask-composite:source-in;-webkit-mask-composite:source-in;mask-composite:intersect}.mask-b-to-100\%{-webkit-mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);-webkit-mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);--tw-mask-linear:var(--tw-mask-left), var(--tw-mask-right), var(--tw-mask-bottom), var(--tw-mask-top);--tw-mask-bottom:linear-gradient(to bottom, var(--tw-mask-bottom-from-color) var(--tw-mask-bottom-from-position), var(--tw-mask-bottom-to-color) var(--tw-mask-bottom-to-position));--tw-mask-bottom-to-position:100%;-webkit-mask-composite:source-in;-webkit-mask-composite:source-in;mask-composite:intersect}.\[mask-image\:linear-gradient\(to_bottom\,black_45\%\,transparent_72\%\)\]{-webkit-mask-image:linear-gradient(#000 45%,#0000 72%);mask-image:linear-gradient(#000 45%,#0000 72%)}.fill-current{fill:currentColor}.object-cover{object-fit:cover}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-\(--chat-gutter\){padding-inline:var(--chat-gutter)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-\[var\(--chat-gutter\,var\(--chat-content-padding\)\)\]{padding-inline:var(--chat-gutter,var(--chat-content-padding))}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-px{padding-block:1px}.pt-1{padding-top:var(--spacing)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pr-1{padding-right:var(--spacing)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-1{padding-bottom:var(--spacing)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-9{padding-bottom:calc(var(--spacing) * 9)}.pb-\[10cqh\]{padding-bottom:10cqh}.pb-\[max\(0\.5rem\,env\(safe-area-inset-bottom\)\)\]{padding-bottom:max(.5rem, env(safe-area-inset-bottom))}.pb-\[max\(0\.25rem\,env\(safe-area-inset-bottom\)\)\]{padding-bottom:max(.25rem, env(safe-area-inset-bottom))}.pb-\[max\(1rem\,env\(safe-area-inset-bottom\)\)\]{padding-bottom:max(1rem, env(safe-area-inset-bottom))}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-6{padding-left:calc(var(--spacing) * 6)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-chat-mono{font-family:var(--chat-font-mono)}.font-chat-sans{font-family:var(--chat-font-sans)}.font-chat-serif{font-family:var(--chat-font-serif)}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.font-serif{font-family:var(--font-serif)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-\(length\:--chat-activity-font-size\){font-size:var(--chat-activity-font-size)}.text-\(length\:--chat-bubble-font-size\){font-size:var(--chat-bubble-font-size)}.text-\(length\:--chat-code-font-size\){font-size:var(--chat-code-font-size)}.text-\(length\:--chat-ui-font-size\){font-size:var(--chat-ui-font-size)}.text-\(length\:--chat-ui-font-size-sm\){font-size:var(--chat-ui-font-size-sm)}.text-\[0\.625rem\]{font-size:.625rem}.text-\[0\.5625rem\]{font-size:.5625rem}.text-\[clamp\(1\.5rem\,6cqw\,2\.5rem\)\]{font-size:clamp(1.5rem,6cqw,2.5rem)}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-\[1\.75\]{--tw-leading:1.75;line-height:1.75}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[var\(--chat-danger-fg\,\#fff\)\]{color:var(--chat-danger-fg,#fff)}.text-\[var\(--chat-empty-icon\,var\(--chat-accent\)\)\]{color:var(--chat-empty-icon,var(--chat-accent))}.text-chat-accent{color:var(--chat-accent)}.text-chat-accent-fg{color:var(--chat-accent-fg)}.text-chat-bg{color:var(--chat-bg)}.text-chat-check{color:var(--chat-check)}.text-chat-danger{color:var(--chat-danger)}.text-chat-fg{color:var(--chat-fg)}.text-chat-muted{color:var(--chat-muted)}.text-chat-subtle{color:var(--chat-subtle)}.text-chat-warning{color:var(--chat-warning)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, )}.underline{text-decoration-line:underline}.decoration-chat-subtle{-webkit-text-decoration-color:var(--chat-subtle);-webkit-text-decoration-color:var(--chat-subtle);text-decoration-color:var(--chat-subtle)}.decoration-dotted{text-decoration-style:dotted}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-100{opacity:1}.shadow-chat-popover{--tw-shadow:var(--chat-shadow-popover);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, )}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}:is(:where(.group\/card):focus-within .group-focus-within\/card\:opacity-100){opacity:1}:is(:where(.group\/item):focus-within .group-focus-within\/item\:pr-8){padding-right:calc(var(--spacing) * 8)}:is(:where(.group\/item):focus-within .group-focus-within\/item\:opacity-100),:is(:where(.group\/message):focus-within .group-focus-within\/message\:opacity-100){opacity:1}@media (hover:hover){:is(:where(.group\/card):hover .group-hover\/card\:opacity-100){opacity:1}:is(:where(.group\/item):hover .group-hover\/item\:pr-8){padding-right:calc(var(--spacing) * 8)}:is(:where(.group\/item):hover .group-hover\/item\:opacity-100),:is(:where(.group\/message):hover .group-hover\/message\:opacity-100),:is(:where(.group\/section):hover .group-hover\/section\:opacity-100){opacity:1}}:is(:where(.group\/trigger)[aria-expanded=true] .group-aria-expanded\/trigger\:rotate-90){rotate:90deg}:is(:where(.group\/trigger)[data-focus-visible] .group-data-focus-visible\/trigger\:opacity-100),:is(:where(.group)[data-hovered] .group-data-hovered\:opacity-100){opacity:1}:is(:where(.peer):focus-visible~.peer-focus-visible\:ring-2){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.placeholder\:text-chat-subtle::placeholder{color:var(--chat-subtle)}.focus-within\:border-chat-border-strong:focus-within{border-color:var(--chat-border-strong)}@media (hover:hover){.hover\:text-chat-fg:hover{color:var(--chat-fg)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-chat-border-strong:focus{border-color:var(--chat-border-strong)}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-chat-focus:focus-visible{--tw-ring-color:var(--chat-focus)}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-chat-focus:focus-visible{outline-color:var(--chat-focus)}.data-disabled\:cursor-default[data-disabled]{cursor:default}.data-disabled\:opacity-40[data-disabled]{opacity:.4}.data-entering\:animate-chat-drawer-in[data-entering]{animation:.22s cubic-bezier(.2,.8,.2,1) chat-drawer-in}.data-entering\:animate-chat-drawer-in-right[data-entering]{animation:.22s cubic-bezier(.2,.8,.2,1) chat-drawer-in-right}.data-entering\:animate-chat-fade-in[data-entering]{animation:.2s ease-out chat-fade-in}.data-entering\:animate-chat-in[data-entering]{animation:.12s ease-out chat-in}.data-exiting\:animate-chat-drawer-out[data-exiting]{animation:.16s ease-in reverse forwards chat-drawer-in}.data-exiting\:animate-chat-drawer-out-right[data-exiting]{animation:.16s ease-in reverse forwards chat-drawer-in-right}.data-exiting\:animate-chat-fade-out[data-exiting]{animation:.15s ease-in reverse forwards chat-fade-in}.data-exiting\:animate-chat-out[data-exiting]{animation:90ms ease-in forwards chat-out}.data-focus-visible\:opacity-100[data-focus-visible]{opacity:1}.data-focus-visible\:ring-2[data-focus-visible]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-focus-visible\:ring-chat-focus[data-focus-visible]{--tw-ring-color:var(--chat-focus)}.data-focus-visible\:ring-inset[data-focus-visible]{--tw-ring-inset:inset}.data-focused\:bg-chat-popover-hover[data-focused]{background-color:var(--chat-popover-hover)}.data-hovered\:bg-chat-hover[data-hovered]{background-color:var(--chat-hover)}.data-hovered\:text-chat-fg[data-hovered]{color:var(--chat-fg)}.data-hovered\:text-chat-muted[data-hovered]{color:var(--chat-muted)}.data-hovered\:brightness-110[data-hovered]{--tw-brightness:brightness(110%);filter:var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, )}.data-open\:bg-chat-popover-hover[data-open]{background-color:var(--chat-popover-hover)}.data-pressed\:bg-chat-selected[data-pressed]{background-color:var(--chat-selected)}.data-pressed\:brightness-95[data-pressed]{--tw-brightness:brightness(95%);filter:var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, )}.data-selected\:bg-\[var\(--chat-segment-selected\,var\(--chat-raised\)\)\][data-selected]{background-color:var(--chat-segment-selected,var(--chat-raised))}.data-selected\:text-chat-fg[data-selected]{color:var(--chat-fg)}.data-selected\:shadow-\[inset_0_0_0_1px_var\(--chat-border-strong\)\][data-selected]{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,var(--chat-border-strong));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}@media (prefers-reduced-motion:no-preference){.motion-safe\:data-entering\:animate-chat-in[data-entering]{animation:.12s ease-out chat-in}.motion-safe\:data-exiting\:animate-chat-out[data-exiting]{animation:90ms ease-in forwards chat-out}}@media (prefers-reduced-motion:reduce){.motion-reduce\:animate-none{animation:none}.motion-reduce\:transition-none{transition-property:none}}.\[\&_svg\]\:size-3 svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&_svg\]\:size-3\.5 svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:size-5 svg{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.\[\&_svg\]\:size-\[1em\] svg{width:1em;height:1em}.\[\&_svg\]\:size-full svg{width:100%;height:100%}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\]\:fill-current svg{fill:currentColor}.\[\&\:\:-webkit-slider-thumb\]\:opacity-0::-webkit-slider-thumb{opacity:0}.\[\&\:not\(\:first-child\)\]\:mt-1:not(:first-child){margin-top:var(--spacing)}@media (hover:none){.\[\@media\(hover\:none\)\]\:pr-10{padding-right:calc(var(--spacing) * 10)}.\[\@media\(hover\:none\)\]\:opacity-100{opacity:1}}@media (pointer:coarse){.\[\@media\(pointer\:coarse\)\]\:size-7\!{width:calc(var(--spacing) * 7)!important;height:calc(var(--spacing) * 7)!important}.\[\@media\(pointer\:coarse\)\]\:size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.\[\@media\(pointer\:coarse\)\]\:size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.\[\@media\(pointer\:coarse\)\]\:size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.\[\@media\(pointer\:coarse\)\]\:h-9{height:calc(var(--spacing) * 9)}.\[\@media\(pointer\:coarse\)\]\:h-10{height:calc(var(--spacing) * 10)}.\[\@media\(pointer\:coarse\)\]\:h-11{height:calc(var(--spacing) * 11)}.\[\@media\(pointer\:coarse\)\]\:w-10{width:calc(var(--spacing) * 10)}}}@keyframes chat-word-in{0%{opacity:0}}[data-chat-code-bg=theme]{background-color:light-dark(var(--shiki-light-bg),var(--shiki-dark-bg))}[data-chat-code-bg=theme] pre{color:light-dark(var(--shiki-light),var(--shiki-dark))}@keyframes chat-shimmer-surface{0%{background-position:150% 0}to{background-position:-50% 0}}@keyframes chat-shimmer{0%{background-position:-20em 0}to{background-position:0 0}}@media (prefers-reduced-motion:reduce){.chat-markdown.chat-fade .chat-word:not([data-chat-motion=full] *){animation:none}.chat-shimmer-surface:not([data-chat-motion=full] *):after{background:var(--chat-fg);animation:none}@supports (color:color-mix(in lab, red, red)){.chat-shimmer-surface:not([data-chat-motion=full] *):after{background:color-mix(in srgb, var(--chat-fg) 6%, transparent)}}.chat-shimmer:not([data-chat-motion=full] *){color:var(--chat-muted);background:0 0;animation:none}[data-entering]:not([data-chat-motion=full] *),[data-exiting]:not([data-chat-motion=full] *){animation-duration:1ms!important}}[data-chat-motion=reduce] .chat-markdown.chat-fade .chat-word{animation:none}[data-chat-motion=reduce] .chat-shimmer-surface:after{background:var(--chat-fg);animation:none}@supports (color:color-mix(in lab, red, red)){[data-chat-motion=reduce] .chat-shimmer-surface:after{background:color-mix(in srgb, var(--chat-fg) 6%, transparent)}}[data-chat-motion=reduce] .chat-shimmer{color:var(--chat-muted);background:0 0;animation:none}[data-chat-motion=reduce] [data-entering],[data-chat-motion=reduce] [data-exiting]{animation-duration:1ms!important}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-mask-linear{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-radial{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-conic{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-left{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-right{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-bottom{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-top{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-bottom-from-position{syntax:"*";inherits:false;initial-value:0%}@property --tw-mask-bottom-to-position{syntax:"*";inherits:false;initial-value:100%}@property --tw-mask-bottom-from-color{syntax:"*";inherits:false;initial-value:black}@property --tw-mask-bottom-to-color{syntax:"*";inherits:false;initial-value:transparent}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}@keyframes chat-drawer-in-right{0%{transform:translate(100%)}}@keyframes chat-fade-in{0%{opacity:0}}@keyframes chat-drawer-in{0%{transform:translate(-100%)}}@keyframes chat-in{0%{opacity:0;transform:scale(.98)}}@keyframes chat-out{to{opacity:0;transform:scale(.98)}}
|
|
3
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:block))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-mask-linear:linear-gradient(#fff, #fff);--tw-mask-radial:linear-gradient(#fff, #fff);--tw-mask-conic:linear-gradient(#fff, #fff);--tw-mask-left:linear-gradient(#fff, #fff);--tw-mask-right:linear-gradient(#fff, #fff);--tw-mask-bottom:linear-gradient(#fff, #fff);--tw-mask-top:linear-gradient(#fff, #fff);--tw-mask-bottom-from-position:0%;--tw-mask-bottom-to-position:100%;--tw-mask-bottom-from-color:black;--tw-mask-bottom-to-color:transparent;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-serif:ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--container-2xl:42rem;--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-normal:400;--font-weight-medium:500;--tracking-wide:.025em;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:.25rem;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root,[data-chat-theme=claude-dark]{color-scheme:dark;--chat-bg:#191919;--chat-sidebar:#1f1f1f;--chat-surface:#303030;--chat-raised:#3a3a3a;--chat-hover:#3d3d3d;--chat-selected:#4a4a4a;--chat-bubble:#2a2a2a;--chat-popover:#303030;--chat-popover-border:#383838;--chat-popover-hover:#4f4f4f;--chat-border:#303030;--chat-border-strong:#454545;--chat-divider:#222;--chat-code-bg:#1c1c1c;--chat-code-border:#252525;--chat-inline-code:#2e2e2e;--chat-fg:#ecebe6;--chat-muted:#a3a29e;--chat-subtle:#75746f;--chat-accent:#d97757;--chat-accent-fg:#fff;--chat-check:#6c9cf0;--chat-warning:#e8b04b;--chat-warning-bg:#4a3b1c;--chat-danger:#e5675c;--chat-focus:#6c9cf0;--chat-backdrop:#00000080;--chat-font-sans:"Inter", ui-sans-serif, system-ui, sans-serif;--chat-font-serif:"Source Serif 4", ui-serif, Georgia, serif;--chat-font-mono:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;--chat-radius-sm:6px;--chat-radius-md:10px;--chat-radius-lg:16px;--chat-radius-popover:12px;--chat-shadow-popover:0 8px 24px #00000080;--chat-content-width:48rem;--chat-content-padding:1.5rem;--chat-message-font-size:1.0625rem;--chat-code-font-size:.8125rem;--chat-message-line-height:1.65;--chat-ui-font-size:.875rem;--chat-ui-font-size-sm:.75rem;--chat-bubble-font-size:.9375rem;--chat-activity-font-size:.9375rem}}@layer components{.chat-markdown{font-family:var(--chat-font-message,var(--chat-font-serif));font-size:var(--chat-message-font-size);line-height:var(--chat-message-line-height);color:var(--chat-fg);overflow-wrap:anywhere}.chat-markdown>div>*+*{margin-top:.75em}.chat-markdown :is(h1,h2,h3,h4){margin-top:1.25em;font-weight:600;line-height:1.3}.chat-markdown h1{font-size:1.5em}.chat-markdown h2{font-size:1.3em}.chat-markdown h3{font-size:1.12em}.chat-markdown :is(strong,[data-streamdown=strong]){font-weight:650}.chat-markdown :is(ul,ol){padding-left:1.6em}.chat-markdown ul{list-style:outside}.chat-markdown ol{list-style:decimal}.chat-markdown li+li,.chat-markdown li>:is(ul,ol){margin-top:.3em}.chat-markdown .chat-ui-tree{font-family:var(--chat-font-sans);font-size:var(--chat-ui-font-size);line-height:1.5}.chat-markdown .chat-ui-tree :is(ul,ol){padding-left:0;list-style:none}.chat-markdown .chat-ui-tree li+li{margin-top:0}.chat-markdown .chat-ui-tree :is(h1,h2,h3,h4){font-size:inherit;margin-top:0}.chat-markdown a{color:var(--chat-fg);text-decoration:underline;-webkit-text-decoration-color:var(--chat-subtle);-webkit-text-decoration-color:var(--chat-subtle);text-decoration-color:var(--chat-subtle);text-underline-offset:3px}.chat-markdown a:hover{-webkit-text-decoration-color:var(--chat-fg);-webkit-text-decoration-color:var(--chat-fg);text-decoration-color:var(--chat-fg)}.chat-markdown blockquote{border-left:3px solid var(--chat-border-strong);color:var(--chat-muted);padding-left:1em}.chat-markdown hr{border-color:var(--chat-border);margin-block:1.5em}.chat-markdown [data-chat-inline-code]{font-family:var(--chat-font-mono);background:var(--chat-inline-code);border-radius:5px;padding:.12em .35em;font-size:.82em}.chat-markdown [data-streamdown=table-wrapper]{margin-block:1em;overflow-x:auto}.chat-markdown table{border-collapse:collapse;font-family:var(--chat-font-sans);font-size:var(--chat-ui-font-size)}.chat-markdown :is(th,td){border-bottom:1px solid var(--chat-border);text-align:left;padding:.45em .9em .45em 0}.chat-markdown th{font-weight:600}.chat-markdown .katex-display{margin-block:1em;overflow:auto hidden}.chat-markdown .katex{font-size:1.08em}.chat-markdown.chat-fade .chat-word{animation:chat-word-in var(--chat-fade-duration,.7s) ease-out both}.chat-view{container:chat/inline-size}.chat-view-body{--chat-gutter:var(--chat-content-padding);container:chat-body/size}@container chat (max-width:34rem){.chat-view-body{--chat-gutter:min(var(--chat-content-padding), .75rem)}}@container chat (max-width:24rem){.chat-picker-detail{display:none}}@container chat-body (max-height:24rem){.chat-empty-greeting{display:none}}.chat-code-token{color:light-dark(var(--shiki-light),var(--shiki-dark))}.chat-shimmer{background-image:linear-gradient(90deg, var(--chat-muted) 0%, var(--chat-muted) 35%, var(--chat-fg) 50%, var(--chat-muted) 65%, var(--chat-muted) 100%);color:#0000;animation:chat-shimmer var(--chat-shimmer-duration,2s) linear infinite;background-repeat:repeat-x;background-size:20em 100%;-webkit-background-clip:text;background-clip:text}.chat-markdown.chat-thinking{font-family:var(--chat-font-sans);font-size:var(--chat-activity-font-size);color:var(--chat-muted);line-height:1.6}.chat-shimmer-surface:after{content:"";background:linear-gradient(100deg, transparent 30%, var(--chat-fg) 50%, transparent 70%) 0 0 / 300% 100%;position:absolute;inset:0}@supports (color:color-mix(in lab, red, red)){.chat-shimmer-surface:after{background:linear-gradient(100deg, transparent 30%, color-mix(in srgb, var(--chat-fg) 12%, transparent) 50%, transparent 70%) 0 0 / 300% 100%}}.chat-shimmer-surface:after{pointer-events:none;animation:1.6s linear infinite chat-shimmer-surface}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.-inset-x-2{inset-inline:calc(var(--spacing) * -2)}.inset-x-2{inset-inline:calc(var(--spacing) * 2)}.inset-y-0{inset-block:0}.-top-2{top:calc(var(--spacing) * -2)}.top-1\/2{top:50%}.-right-2{right:calc(var(--spacing) * -2)}.right-0{right:0}.right-1{right:var(--spacing)}.bottom-0{bottom:0}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-\[min\(10rem\,40\%\)\]{bottom:min(10rem,40%)}.left-0{left:0}.left-1\/2{left:50%}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.-mx-1\.5{margin-inline:calc(var(--spacing) * -1.5)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-5{margin-inline:calc(var(--spacing) * 5)}.mx-auto{margin-inline:auto}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-4{margin-block:calc(var(--spacing) * 4)}.-mt-1\.5{margin-top:calc(var(--spacing) * -1.5)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.-mr-2{margin-right:calc(var(--spacing) * -2)}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.-ml-1\.5{margin-left:calc(var(--spacing) * -1.5)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-auto{margin-left:auto}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.size-0{width:0;height:0}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-24{width:calc(var(--spacing) * 24);height:calc(var(--spacing) * 24)}.size-30{width:calc(var(--spacing) * 30);height:calc(var(--spacing) * 30)}.size-\[1\.15em\]{width:1.15em;height:1.15em}.size-full{width:100%;height:100%}.h-1{height:var(--spacing)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-dvh{height:100dvh}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-56{max-height:calc(var(--spacing) * 56)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[85dvh\]{max-height:85dvh}.max-h-\[inherit\]{max-height:inherit}.max-h-\[min\(10rem\,30cqh\)\]{max-height:min(10rem,30cqh)}.max-h-\[min\(18rem\,35cqh\)\]{max-height:min(18rem,35cqh)}.max-h-\[min\(24rem\,45cqh\)\]{max-height:min(24rem,45cqh)}.min-h-0{min-height:0}.min-h-2{min-height:calc(var(--spacing) * 2)}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-7{min-height:calc(var(--spacing) * 7)}.min-h-12{min-height:calc(var(--spacing) * 12)}.min-h-64{min-height:calc(var(--spacing) * 64)}.min-h-full{min-height:100%}.w-\(--chat-sidebar-width\,18rem\){width:var(--chat-sidebar-width,18rem)}.w-7{width:calc(var(--spacing) * 7)}.w-9{width:calc(var(--spacing) * 9)}.w-12{width:calc(var(--spacing) * 12)}.w-13{width:calc(var(--spacing) * 13)}.w-14{width:calc(var(--spacing) * 14)}.w-60{width:calc(var(--spacing) * 60)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-\[3px\]{width:3px}.w-\[calc\(100\%\+1rem\)\]{width:calc(100% + 1rem)}.w-\[min\(20rem\,85vw\)\]{width:min(20rem,85vw)}.w-\[min\(36rem\,calc\(100vw-2rem\)\)\]{width:min(36rem,100vw - 2rem)}.w-full{width:100%}.max-w-\(--chat-content-width\){max-width:var(--chat-content-width)}.max-w-2xl{max-width:var(--container-2xl)}.max-w-\[85\%\]{max-width:85%}.max-w-\[calc\(var\(--chat-content-width\)\+2\*var\(--chat-gutter\,var\(--chat-content-padding\)\)\)\]{max-width:calc(var(--chat-content-width) + 2 * var(--chat-gutter,var(--chat-content-padding)))}.max-w-full{max-width:100%}.min-w-0{min-width:0}.min-w-44{min-width:calc(var(--spacing) * 44)}.min-w-52{min-width:calc(var(--spacing) * 52)}.min-w-\[2px\]{min-width:2px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.animate-pulse{animation:var(--animate-pulse)}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.\[scrollbar-width\:thin\]{scrollbar-width:thin}.\[scrollbar-color\:var\(--chat-border-strong\)_transparent\]{scrollbar-color:var(--chat-border-strong) transparent}.\[scrollbar-gutter\:stable\]{scrollbar-gutter:stable}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-\[3px\]{gap:3px}.gap-px{gap:1px}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-chat-divider>:not(:last-child)){border-color:var(--chat-divider)}.self-center{align-self:center}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded-\[0\.3rem\]{border-radius:.3rem}.rounded-\[2px\]{border-radius:2px}.rounded-\[calc\(var\(--chat-radius-md\)-2px\)\]{border-radius:calc(var(--chat-radius-md) - 2px)}.rounded-\[inherit\]{border-radius:inherit}.rounded-\[var\(--chat-composer-radius\,1\.25rem\)\]{border-radius:var(--chat-composer-radius,1.25rem)}.rounded-\[var\(--chat-send-radius\,var\(--chat-radius-md\)\)\]\!{border-radius:var(--chat-send-radius,var(--chat-radius-md))!important}.rounded-chat-lg{border-radius:var(--chat-radius-lg)}.rounded-chat-md{border-radius:var(--chat-radius-md)}.rounded-chat-popover{border-radius:var(--chat-radius-popover)}.rounded-chat-sm{border-radius:var(--chat-radius-sm)}.rounded-full{border-radius:2147483647px}.rounded-sm{border-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\(--chat-notice-border\,var\(--chat-border\)\){border-color:var(--chat-notice-border,var(--chat-border))}.border-chat-accent{border-color:var(--chat-accent)}.border-chat-accent\!{border-color:var(--chat-accent)!important}.border-chat-border{border-color:var(--chat-border)}.border-chat-border-strong{border-color:var(--chat-border-strong)}.border-chat-code-border{border-color:var(--chat-code-border)}.border-chat-danger{border-color:var(--chat-danger)}.border-chat-divider{border-color:var(--chat-divider)}.border-chat-popover-border{border-color:var(--chat-popover-border)}.bg-\(--chat-backdrop\){background-color:var(--chat-backdrop)}.bg-\(--chat-notice-bg\,transparent\){background-color:var(--chat-notice-bg,transparent)}.bg-\[var\(--chat-danger-bg\,color-mix\(in_srgb\,var\(--chat-danger\)_70\%\,black\)\)\]{background-color:var(--chat-danger-bg,var(--chat-danger))}@supports (color:color-mix(in lab, red, red)){.bg-\[var\(--chat-danger-bg\,color-mix\(in_srgb\,var\(--chat-danger\)_70\%\,black\)\)\]{background-color:var(--chat-danger-bg,color-mix(in srgb,var(--chat-danger) 70%,black))}}.bg-\[var\(--chat-segment-track\,color-mix\(in_srgb\,var\(--chat-bg\)_55\%\,transparent\)\)\]{background-color:var(--chat-segment-track,var(--chat-bg))}@supports (color:color-mix(in lab, red, red)){.bg-\[var\(--chat-segment-track\,color-mix\(in_srgb\,var\(--chat-bg\)_55\%\,transparent\)\)\]{background-color:var(--chat-segment-track,color-mix(in srgb,var(--chat-bg) 55%,transparent))}}.bg-chat-accent{background-color:var(--chat-accent)}.bg-chat-accent-fg\/70{background-color:var(--chat-accent-fg)}@supports (color:color-mix(in lab, red, red)){.bg-chat-accent-fg\/70{background-color:color-mix(in oklab, var(--chat-accent-fg) 70%, transparent)}}.bg-chat-bg{background-color:var(--chat-bg)}.bg-chat-border-strong{background-color:var(--chat-border-strong)}.bg-chat-bubble{background-color:var(--chat-bubble)}.bg-chat-check{background-color:var(--chat-check)}.bg-chat-code-bg{background-color:var(--chat-code-bg)}.bg-chat-fg{background-color:var(--chat-fg)}.bg-chat-popover{background-color:var(--chat-popover)}.bg-chat-raised{background-color:var(--chat-raised)}.bg-chat-selected{background-color:var(--chat-selected)}.bg-chat-sidebar{background-color:var(--chat-sidebar)}.bg-chat-subtle{background-color:var(--chat-subtle)}.bg-chat-surface{background-color:var(--chat-surface)}.bg-chat-warning-bg{background-color:var(--chat-warning-bg)}.bg-transparent{background-color:#0000}.bg-linear-to-t{--tw-gradient-position:to top}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-t{--tw-gradient-position:to top in oklab}}.bg-linear-to-t{background-image:linear-gradient(var(--tw-gradient-stops))}.from-chat-bg{--tw-gradient-from:var(--chat-bg);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-70\%{--tw-gradient-from-position:70%}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.mask-b-from-60\%{-webkit-mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);-webkit-mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);--tw-mask-linear:var(--tw-mask-left), var(--tw-mask-right), var(--tw-mask-bottom), var(--tw-mask-top);--tw-mask-bottom:linear-gradient(to bottom, var(--tw-mask-bottom-from-color) var(--tw-mask-bottom-from-position), var(--tw-mask-bottom-to-color) var(--tw-mask-bottom-to-position));--tw-mask-bottom-from-position:60%;-webkit-mask-composite:source-in;-webkit-mask-composite:source-in;mask-composite:intersect}.mask-b-to-100\%{-webkit-mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);-webkit-mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);mask-image:var(--tw-mask-linear), var(--tw-mask-radial), var(--tw-mask-conic);--tw-mask-linear:var(--tw-mask-left), var(--tw-mask-right), var(--tw-mask-bottom), var(--tw-mask-top);--tw-mask-bottom:linear-gradient(to bottom, var(--tw-mask-bottom-from-color) var(--tw-mask-bottom-from-position), var(--tw-mask-bottom-to-color) var(--tw-mask-bottom-to-position));--tw-mask-bottom-to-position:100%;-webkit-mask-composite:source-in;-webkit-mask-composite:source-in;mask-composite:intersect}.\[mask-image\:linear-gradient\(to_bottom\,black_45\%\,transparent_72\%\)\]{-webkit-mask-image:linear-gradient(#000 45%,#0000 72%);mask-image:linear-gradient(#000 45%,#0000 72%)}.fill-current{fill:currentColor}.object-cover{object-fit:cover}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-\(--chat-gutter\){padding-inline:var(--chat-gutter)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-\[var\(--chat-gutter\,var\(--chat-content-padding\)\)\]{padding-inline:var(--chat-gutter,var(--chat-content-padding))}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-px{padding-block:1px}.pt-1{padding-top:var(--spacing)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pr-1{padding-right:var(--spacing)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-1{padding-bottom:var(--spacing)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-9{padding-bottom:calc(var(--spacing) * 9)}.pb-\[10cqh\]{padding-bottom:10cqh}.pb-\[max\(0\.5rem\,env\(safe-area-inset-bottom\)\)\]{padding-bottom:max(.5rem, env(safe-area-inset-bottom))}.pb-\[max\(0\.25rem\,env\(safe-area-inset-bottom\)\)\]{padding-bottom:max(.25rem, env(safe-area-inset-bottom))}.pb-\[max\(1rem\,env\(safe-area-inset-bottom\)\)\]{padding-bottom:max(1rem, env(safe-area-inset-bottom))}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-6{padding-left:calc(var(--spacing) * 6)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-chat-mono{font-family:var(--chat-font-mono)}.font-chat-sans{font-family:var(--chat-font-sans)}.font-chat-serif{font-family:var(--chat-font-serif)}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.font-serif{font-family:var(--font-serif)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-\(length\:--chat-activity-font-size\){font-size:var(--chat-activity-font-size)}.text-\(length\:--chat-bubble-font-size\){font-size:var(--chat-bubble-font-size)}.text-\(length\:--chat-code-font-size\){font-size:var(--chat-code-font-size)}.text-\(length\:--chat-ui-font-size\){font-size:var(--chat-ui-font-size)}.text-\(length\:--chat-ui-font-size-sm\){font-size:var(--chat-ui-font-size-sm)}.text-\[0\.625rem\]{font-size:.625rem}.text-\[0\.5625rem\]{font-size:.5625rem}.text-\[clamp\(1\.5rem\,6cqw\,2\.5rem\)\]{font-size:clamp(1.5rem,6cqw,2.5rem)}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-\[1\.75\]{--tw-leading:1.75;line-height:1.75}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[var\(--chat-danger-fg\,\#fff\)\]{color:var(--chat-danger-fg,#fff)}.text-\[var\(--chat-empty-icon\,var\(--chat-accent\)\)\]{color:var(--chat-empty-icon,var(--chat-accent))}.text-chat-accent{color:var(--chat-accent)}.text-chat-accent-fg{color:var(--chat-accent-fg)}.text-chat-bg{color:var(--chat-bg)}.text-chat-check{color:var(--chat-check)}.text-chat-danger{color:var(--chat-danger)}.text-chat-fg{color:var(--chat-fg)}.text-chat-muted{color:var(--chat-muted)}.text-chat-subtle{color:var(--chat-subtle)}.text-chat-warning{color:var(--chat-warning)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, )}.underline{text-decoration-line:underline}.decoration-chat-subtle{-webkit-text-decoration-color:var(--chat-subtle);-webkit-text-decoration-color:var(--chat-subtle);text-decoration-color:var(--chat-subtle)}.decoration-dotted{text-decoration-style:dotted}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-100{opacity:1}.shadow-chat-popover{--tw-shadow:var(--chat-shadow-popover);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, )}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[height\]{transition-property:height;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-75{--tw-duration:75ms;transition-duration:75ms}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}:is(:where(.group\/card):focus-within .group-focus-within\/card\:opacity-100){opacity:1}:is(:where(.group\/item):focus-within .group-focus-within\/item\:pr-8){padding-right:calc(var(--spacing) * 8)}:is(:where(.group\/item):focus-within .group-focus-within\/item\:opacity-100),:is(:where(.group\/message):focus-within .group-focus-within\/message\:opacity-100){opacity:1}@media (hover:hover){:is(:where(.group\/card):hover .group-hover\/card\:opacity-100){opacity:1}:is(:where(.group\/item):hover .group-hover\/item\:pr-8){padding-right:calc(var(--spacing) * 8)}:is(:where(.group\/item):hover .group-hover\/item\:opacity-100),:is(:where(.group\/message):hover .group-hover\/message\:opacity-100),:is(:where(.group\/section):hover .group-hover\/section\:opacity-100){opacity:1}}:is(:where(.group\/trigger)[aria-expanded=true] .group-aria-expanded\/trigger\:rotate-90){rotate:90deg}:is(:where(.group\/trigger)[data-focus-visible] .group-data-focus-visible\/trigger\:opacity-100),:is(:where(.group)[data-hovered] .group-data-hovered\:opacity-100){opacity:1}:is(:where(.peer):focus-visible~.peer-focus-visible\:ring-2){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.placeholder\:text-chat-subtle::placeholder{color:var(--chat-subtle)}.focus-within\:border-chat-border-strong:focus-within{border-color:var(--chat-border-strong)}@media (hover:hover){.hover\:text-chat-fg:hover{color:var(--chat-fg)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-chat-border-strong:focus{border-color:var(--chat-border-strong)}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-chat-focus:focus-visible{--tw-ring-color:var(--chat-focus)}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-chat-focus:focus-visible{outline-color:var(--chat-focus)}.data-disabled\:cursor-default[data-disabled]{cursor:default}.data-disabled\:opacity-40[data-disabled]{opacity:.4}.data-entering\:animate-chat-drawer-in[data-entering]{animation:.22s cubic-bezier(.2,.8,.2,1) chat-drawer-in}.data-entering\:animate-chat-drawer-in-right[data-entering]{animation:.22s cubic-bezier(.2,.8,.2,1) chat-drawer-in-right}.data-entering\:animate-chat-fade-in[data-entering]{animation:.2s ease-out chat-fade-in}.data-entering\:animate-chat-in[data-entering]{animation:.12s ease-out chat-in}.data-exiting\:animate-chat-drawer-out[data-exiting]{animation:.16s ease-in reverse forwards chat-drawer-in}.data-exiting\:animate-chat-drawer-out-right[data-exiting]{animation:.16s ease-in reverse forwards chat-drawer-in-right}.data-exiting\:animate-chat-fade-out[data-exiting]{animation:.15s ease-in reverse forwards chat-fade-in}.data-exiting\:animate-chat-out[data-exiting]{animation:90ms ease-in forwards chat-out}.data-focus-visible\:opacity-100[data-focus-visible]{opacity:1}.data-focus-visible\:ring-2[data-focus-visible]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-focus-visible\:ring-chat-focus[data-focus-visible]{--tw-ring-color:var(--chat-focus)}.data-focus-visible\:ring-inset[data-focus-visible]{--tw-ring-inset:inset}.data-focused\:bg-chat-popover-hover[data-focused]{background-color:var(--chat-popover-hover)}.data-hovered\:bg-chat-hover[data-hovered]{background-color:var(--chat-hover)}.data-hovered\:text-chat-fg[data-hovered]{color:var(--chat-fg)}.data-hovered\:text-chat-muted[data-hovered]{color:var(--chat-muted)}.data-hovered\:brightness-110[data-hovered]{--tw-brightness:brightness(110%);filter:var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, )}.data-open\:bg-chat-popover-hover[data-open]{background-color:var(--chat-popover-hover)}.data-pressed\:bg-chat-selected[data-pressed]{background-color:var(--chat-selected)}.data-pressed\:brightness-95[data-pressed]{--tw-brightness:brightness(95%);filter:var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, )}.data-selected\:bg-\[var\(--chat-segment-selected\,var\(--chat-raised\)\)\][data-selected]{background-color:var(--chat-segment-selected,var(--chat-raised))}.data-selected\:text-chat-fg[data-selected]{color:var(--chat-fg)}.data-selected\:shadow-\[inset_0_0_0_1px_var\(--chat-border-strong\)\][data-selected]{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,var(--chat-border-strong));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}@media (prefers-reduced-motion:no-preference){.motion-safe\:data-entering\:animate-chat-in[data-entering]{animation:.12s ease-out chat-in}.motion-safe\:data-exiting\:animate-chat-out[data-exiting]{animation:90ms ease-in forwards chat-out}}@media (prefers-reduced-motion:reduce){.motion-reduce\:animate-none{animation:none}.motion-reduce\:transition-none{transition-property:none}}.\[\&_svg\]\:size-3 svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&_svg\]\:size-3\.5 svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:size-5 svg{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.\[\&_svg\]\:size-\[1em\] svg{width:1em;height:1em}.\[\&_svg\]\:size-full svg{width:100%;height:100%}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\]\:fill-current svg{fill:currentColor}.\[\&\:\:-webkit-slider-thumb\]\:opacity-0::-webkit-slider-thumb{opacity:0}.\[\&\:not\(\:first-child\)\]\:mt-1:not(:first-child){margin-top:var(--spacing)}@media (hover:none){.\[\@media\(hover\:none\)\]\:pr-10{padding-right:calc(var(--spacing) * 10)}.\[\@media\(hover\:none\)\]\:opacity-100{opacity:1}}@media (pointer:coarse){.\[\@media\(pointer\:coarse\)\]\:size-7\!{width:calc(var(--spacing) * 7)!important;height:calc(var(--spacing) * 7)!important}.\[\@media\(pointer\:coarse\)\]\:size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.\[\@media\(pointer\:coarse\)\]\:size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.\[\@media\(pointer\:coarse\)\]\:size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.\[\@media\(pointer\:coarse\)\]\:h-9{height:calc(var(--spacing) * 9)}.\[\@media\(pointer\:coarse\)\]\:h-10{height:calc(var(--spacing) * 10)}.\[\@media\(pointer\:coarse\)\]\:h-11{height:calc(var(--spacing) * 11)}.\[\@media\(pointer\:coarse\)\]\:w-10{width:calc(var(--spacing) * 10)}}}@keyframes chat-word-in{0%{opacity:0}}[data-chat-code-bg=theme]{background-color:light-dark(var(--shiki-light-bg),var(--shiki-dark-bg))}[data-chat-code-bg=theme] pre{color:light-dark(var(--shiki-light),var(--shiki-dark))}@keyframes chat-shimmer-surface{0%{background-position:150% 0}to{background-position:-50% 0}}@keyframes chat-shimmer{0%{background-position:-20em 0}to{background-position:0 0}}@media (prefers-reduced-motion:reduce){.chat-markdown.chat-fade .chat-word:not([data-chat-motion=full] *){animation:none}.chat-shimmer-surface:not([data-chat-motion=full] *):after{background:var(--chat-fg);animation:none}@supports (color:color-mix(in lab, red, red)){.chat-shimmer-surface:not([data-chat-motion=full] *):after{background:color-mix(in srgb, var(--chat-fg) 6%, transparent)}}.chat-shimmer:not([data-chat-motion=full] *){color:var(--chat-muted);background:0 0;animation:none}[data-entering]:not([data-chat-motion=full] *),[data-exiting]:not([data-chat-motion=full] *){animation-duration:1ms!important}}[data-chat-motion=reduce] .chat-markdown.chat-fade .chat-word{animation:none}[data-chat-motion=reduce] .chat-shimmer-surface:after{background:var(--chat-fg);animation:none}@supports (color:color-mix(in lab, red, red)){[data-chat-motion=reduce] .chat-shimmer-surface:after{background:color-mix(in srgb, var(--chat-fg) 6%, transparent)}}[data-chat-motion=reduce] .chat-shimmer{color:var(--chat-muted);background:0 0;animation:none}[data-chat-motion=reduce] [data-entering],[data-chat-motion=reduce] [data-exiting]{animation-duration:1ms!important}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-mask-linear{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-radial{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-conic{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-left{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-right{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-bottom{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-top{syntax:"*";inherits:false;initial-value:linear-gradient(#fff, #fff)}@property --tw-mask-bottom-from-position{syntax:"*";inherits:false;initial-value:0%}@property --tw-mask-bottom-to-position{syntax:"*";inherits:false;initial-value:100%}@property --tw-mask-bottom-from-color{syntax:"*";inherits:false;initial-value:black}@property --tw-mask-bottom-to-color{syntax:"*";inherits:false;initial-value:transparent}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}@keyframes chat-drawer-in-right{0%{transform:translate(100%)}}@keyframes chat-fade-in{0%{opacity:0}}@keyframes chat-drawer-in{0%{transform:translate(-100%)}}@keyframes chat-in{0%{opacity:0;transform:scale(.98)}}@keyframes chat-out{to{opacity:0;transform:scale(.98)}}
|
package/dist/tailwind.css
CHANGED
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
--chat-font-serif: "Source Serif 4", ui-serif, Georgia, serif;
|
|
137
137
|
--chat-font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
|
|
138
138
|
/*
|
|
139
|
-
* --chat-font-message (unset): assistant message text. Falls back to the serif,
|
|
139
|
+
* --chat-font-message (unset): assistant message text. Falls back to the serif, similar to claude.ai; hosts
|
|
140
140
|
* with sans UIs set it to var(--chat-font-sans). Left unset here so it follows a nested theme's fonts.
|
|
141
141
|
*/
|
|
142
142
|
|
|
@@ -44,6 +44,8 @@ export interface PartFields {
|
|
|
44
44
|
data?: unknown;
|
|
45
45
|
url?: string;
|
|
46
46
|
resourceUri?: string;
|
|
47
|
+
/** Tool calls: ask the user before it runs, e.g. when an agent's permission request arrives after the call started. */
|
|
48
|
+
needsApproval?: boolean;
|
|
47
49
|
}
|
|
48
50
|
/** Sets fields while the part is still open, e.g. a tool call moving from input to running. */
|
|
49
51
|
export interface PartUpdate extends Base, PartFields {
|
|
@@ -5,7 +5,8 @@ export { toBlocks, isActivityPart } from "./blocks";
|
|
|
5
5
|
export type { Block, ActivityPart } from "./blocks";
|
|
6
6
|
export { readEventStream, formatEvent } from "./sse";
|
|
7
7
|
export { parsePartialJson, salvageJson } from "./partial-json";
|
|
8
|
-
export {
|
|
8
|
+
export { widgetFrameLoader, widgetLoaderMessages } from "./widget-loader";
|
|
9
|
+
export { replacesProperty, replacesGuide, replacedId, resolveReplaces, withCallId } from "./replaces";
|
|
9
10
|
export { visualizeTool, visualizeGuide, checkWidgetCode } from "./visualize";
|
|
10
11
|
export type { VisualizeInput, WidgetCodeCheck } from "./visualize";
|
|
11
12
|
export { matchesSchema, schemaErrors, checkUiTree, isStateRef, renderUiTool, renderUiToolName, uiActionSchema } from "./ui-tree";
|
|
@@ -7,9 +7,17 @@
|
|
|
7
7
|
/** The `replaces` input property, shared by the drawing tools. */
|
|
8
8
|
export declare const replacesProperty: {
|
|
9
9
|
readonly type: "string";
|
|
10
|
-
readonly description: "
|
|
10
|
+
readonly description: "The id (or title) of an earlier visual of this tool that this one updates in place: after a fix, or when the user asks for a change. Its tool result says \"Drawn as <id>\". Leave it out for a new visual.";
|
|
11
11
|
};
|
|
12
12
|
/** One line for a drawing tool's description or guide. */
|
|
13
|
-
export declare const replacesGuide = "To change a visual you already drew (a fix, or the user asks for a change), call the tool again with `replaces` set to that
|
|
13
|
+
export declare const replacesGuide = "To change a visual you already drew (a fix, or the user asks for a change), call the tool again with `replaces` set to that visual's id (its tool result says Drawn as <id>): it is redrawn in place. Never draw a second copy without it.";
|
|
14
14
|
/** The id a drawing tool call replaces, from its (streaming) input; undefined if none. */
|
|
15
15
|
export declare function replacedId(input: unknown): string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* The tool result for a drawing call: the check's feedback, prefixed with the call's id, so the model can
|
|
18
|
+
* pass it as `replaces` later. Use it when the model may not see tool call ids (many chat templates drop
|
|
19
|
+
* them): `withCallId(call.id, checkWidgetCode(...).feedback)`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function withCallId(id: string, feedback: string): string;
|
|
22
|
+
/** What `replaces` points at: the id of a call, or else the title of the latest call with that title. */
|
|
23
|
+
export declare function resolveReplaces(ref: string, ids: ReadonlySet<string>, titles: ReadonlyMap<string, string>): string | undefined;
|
|
@@ -80,7 +80,7 @@ export declare function showUiTool(components: readonly UiComponentSpec[], name?
|
|
|
80
80
|
};
|
|
81
81
|
readonly replaces: {
|
|
82
82
|
readonly type: "string";
|
|
83
|
-
readonly description: "
|
|
83
|
+
readonly description: "The id (or title) of an earlier visual of this tool that this one updates in place: after a fix, or when the user asks for a change. Its tool result says \"Drawn as <id>\". Leave it out for a new visual.";
|
|
84
84
|
};
|
|
85
85
|
};
|
|
86
86
|
readonly required: readonly ["markup"];
|
|
@@ -87,7 +87,7 @@ export declare function renderUiTool(components: readonly UiComponentSpec[]): {
|
|
|
87
87
|
};
|
|
88
88
|
replaces: {
|
|
89
89
|
readonly type: "string";
|
|
90
|
-
readonly description: "
|
|
90
|
+
readonly description: "The id (or title) of an earlier visual of this tool that this one updates in place: after a fix, or when the user asks for a change. Its tool result says \"Drawn as <id>\". Leave it out for a new visual.";
|
|
91
91
|
};
|
|
92
92
|
};
|
|
93
93
|
required: string[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The visualize preset: a tool the model calls to draw an interactive visual inline (
|
|
2
|
+
* The visualize preset: a tool the model calls to draw an interactive visual inline (similar to claude.ai's
|
|
3
3
|
* visualize tool), and the design guide to put in the system prompt. The kit's `show_widget` tool view feeds
|
|
4
4
|
* the streaming `widget_code` into a sandboxed WidgetFrame. The backend runs the tool as a no-op ("shown").
|
|
5
5
|
*/
|
|
@@ -37,14 +37,14 @@ export declare const visualizeTool: {
|
|
|
37
37
|
};
|
|
38
38
|
readonly replaces: {
|
|
39
39
|
readonly type: "string";
|
|
40
|
-
readonly description: "
|
|
40
|
+
readonly description: "The id (or title) of an earlier visual of this tool that this one updates in place: after a fix, or when the user asks for a change. Its tool result says \"Drawn as <id>\". Leave it out for a new visual.";
|
|
41
41
|
};
|
|
42
42
|
};
|
|
43
43
|
readonly required: readonly ["widget_code"];
|
|
44
44
|
};
|
|
45
45
|
};
|
|
46
46
|
/** Design guide for the system prompt when the visualize tool is on. */
|
|
47
|
-
export declare const visualizeGuide = "## Visuals (show_widget)\nUse show_widget when a visual says it better than text: data to compare, a plan to adjust, a place to see, a\nprocess to step through. Keep explaining in text around it; the widget is not the whole answer.\n\nHow the frame works\n- widget_code is a fragment: no <!doctype>, <html>, <head> or <body>. Put <style> first, then markup, then <script>.\n- It renders while you write it; scripts run once it is complete, in order. Put scripts last.\n- No network unless the host allows it: no fetch, no external images or fonts. Inline your data.\n- The background is transparent and the frame sizes itself to your content. Add no outer margin or padding,\n no outer border or card around the whole widget, and no fixed height on the root.\n- Two globals: sendPrompt(text) sends a message as the user (for \"Add these to my calendar\", \"Explain this\"),\n openLink(url) opens an http(s) link. Prefer local state (JavaScript in the widget) over round trips: filter,\n toggle, recalculate and animate in place; use sendPrompt only for what needs you.\n- To change a visual you already drew (a fix, or the user asks for a change), call the tool again with `replaces` set to that
|
|
47
|
+
export declare const visualizeGuide = "## Visuals (show_widget)\nUse show_widget when a visual says it better than text: data to compare, a plan to adjust, a place to see, a\nprocess to step through. Keep explaining in text around it; the widget is not the whole answer.\n\nHow the frame works\n- widget_code is a fragment: no <!doctype>, <html>, <head> or <body>. Put <style> first, then markup, then <script>.\n- It renders while you write it; scripts run once it is complete, in order. Put scripts last.\n- No network unless the host allows it: no fetch, no external images or fonts. Inline your data.\n- The background is transparent and the frame sizes itself to your content. Add no outer margin or padding,\n no outer border or card around the whole widget, and no fixed height on the root.\n- Two globals: sendPrompt(text) sends a message as the user (for \"Add these to my calendar\", \"Explain this\"),\n openLink(url) opens an http(s) link. Prefer local state (JavaScript in the widget) over round trips: filter,\n toggle, recalculate and animate in place; use sendPrompt only for what needs you.\n- To change a visual you already drew (a fix, or the user asks for a change), call the tool again with `replaces` set to that visual's id (its tool result says Drawn as <id>): it is redrawn in place. Never draw a second copy without it.\n\nLook\n- Use the chat's theme variables, never hard-coded colors or fonts: var(--chat-fg) text, var(--chat-muted) and\n var(--chat-subtle) secondary text, var(--chat-surface) and var(--chat-raised) fills, var(--chat-border) and\n var(--chat-divider) lines, var(--chat-hover) hover, var(--chat-accent) with var(--chat-accent-fg) for the one\n thing that matters most, var(--chat-check) good, var(--chat-warning), var(--chat-danger) bad;\n var(--chat-font-sans), var(--chat-font-mono); var(--chat-ui-font-size), var(--chat-ui-font-size-sm);\n var(--chat-radius-sm), var(--chat-radius-md), var(--chat-radius-lg).\n- Quiet by default: thin borders, few fills, one accent. Readable labels, aligned numbers, no decoration.\n- Set apart what you added or changed from what was already there: your proposals in the accent with a small\n \"New\" (or \"Changed\") tag, existing data quiet. The user must see at a glance what is yours.\n- Make it work on a narrow screen (down to 320px wide) and with a keyboard: real <button>s, visible focus.";
|
|
48
48
|
/** What `checkWidgetCode` found. */
|
|
49
49
|
export interface WidgetCodeCheck {
|
|
50
50
|
/** Nothing will break: no errors (warnings may remain). */
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The frame page for `WidgetHost.frameUrl`. Serve this HTML from your own origin (e.g. at /widget-frame.html)
|
|
3
|
+
* when your app's CSP blocks inline scripts: an `srcdoc` frame inherits the page's CSP, a frame loaded from
|
|
4
|
+
* a URL gets the CSP of its own response. The kit loads it sandboxed (opaque origin, no access to your app),
|
|
5
|
+
* posts the widget's document to it, and the loader writes it in. The kit's CSP <meta> inside that document
|
|
6
|
+
* still limits what the widget may load.
|
|
7
|
+
*
|
|
8
|
+
* Its response needs a CSP that lets the loader and the widget run, and no stricter than the kit's, e.g.
|
|
9
|
+
* `Content-Security-Policy: default-src 'none'; script-src 'unsafe-inline' https:; style-src 'unsafe-inline' https:; img-src data: blob: https:; font-src data: https:; connect-src https:`
|
|
10
|
+
* (or no CSP header on that path). Don't set X-Frame-Options or frame-ancestors that exclude your app.
|
|
11
|
+
*/
|
|
12
|
+
/** Message types between the kit and the loader. */
|
|
13
|
+
export declare const widgetLoaderMessages: {
|
|
14
|
+
/** Loader → kit: ready for the document. */
|
|
15
|
+
readonly ready: "agentic-ui-kit:frame-ready";
|
|
16
|
+
/** Kit → loader: `{ type, html }`, the widget's whole document. */
|
|
17
|
+
readonly document: "agentic-ui-kit:frame-document";
|
|
18
|
+
};
|
|
19
|
+
export declare const widgetFrameLoader: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import type React from "react";
|
|
3
|
+
import { type DictationState } from "./dictation";
|
|
3
4
|
export interface ComposerProps {
|
|
4
5
|
onSubmit: (text: string) => void;
|
|
5
6
|
/** Shown as a stop button while `busy`. */
|
|
@@ -31,11 +32,16 @@ export interface ComposerProps {
|
|
|
31
32
|
/** Holds sending back, e.g. while a file uploads. */
|
|
32
33
|
submitDisabled?: boolean;
|
|
33
34
|
isDisabled?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Set while the user dictates (from `useDictation().state`): the words fill the box as they are heard,
|
|
37
|
+
* and a level meter, cancel and accept replace `trailing` and send.
|
|
38
|
+
*/
|
|
39
|
+
dictation?: DictationState;
|
|
34
40
|
autoFocus?: boolean;
|
|
35
41
|
className?: string;
|
|
36
42
|
}
|
|
37
43
|
/** The chat box: growing textarea, toolbar slots, send / stop. Enter sends, Shift+Enter adds a line. */
|
|
38
|
-
export declare function Composer({ onSubmit, onStop, busy, value, onChange, placeholder, variant, leading, trailing, above, onFiles, onLongPaste, longPasteChars, allowEmpty, submitDisabled, isDisabled, autoFocus, className, }: ComposerProps): React.JSX.Element;
|
|
44
|
+
export declare function Composer({ onSubmit, onStop, busy, value, onChange, placeholder, variant, leading, trailing, above, onFiles, onLongPaste, longPasteChars, allowEmpty, submitDisabled, isDisabled, dictation, autoFocus, className, }: ComposerProps): React.JSX.Element;
|
|
39
45
|
export interface AttachButtonProps {
|
|
40
46
|
/** The menu, e.g. `<Menu aria-label="Add">…</Menu>`. */
|
|
41
47
|
children: ReactNode;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** What the composer shows while dictating. Pass it as `Composer`'s `dictation`; leave it unset otherwise. */
|
|
2
|
+
export interface DictationState {
|
|
3
|
+
/** Input levels from 0 to 1, oldest first. The meter shows the newest ones. */
|
|
4
|
+
levels: readonly number[];
|
|
5
|
+
/** The words heard so far, shown in the box. Empty or unset: the "Listening…" placeholder. */
|
|
6
|
+
transcript?: string;
|
|
7
|
+
/** ✕: stop and drop the words. */
|
|
8
|
+
onCancel: () => void;
|
|
9
|
+
/**
|
|
10
|
+
* ✓: stop and return the final words, which the composer adds to its text. Return nothing to use
|
|
11
|
+
* `transcript`; return a promise to finish transcribing (the box reads "Transcribing…" meanwhile).
|
|
12
|
+
*/
|
|
13
|
+
onAccept: () => void | string | Promise<string | void>;
|
|
14
|
+
}
|
|
15
|
+
export interface VoiceMeterProps {
|
|
16
|
+
levels: readonly number[];
|
|
17
|
+
/** How many dots. */
|
|
18
|
+
count?: number;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
/** A row of dots that grow into bars with the voice; flat dots when it is quiet. */
|
|
22
|
+
export declare function VoiceMeter({ levels, count, className }: VoiceMeterProps): import("react").JSX.Element;
|
|
23
|
+
export interface DictationButtonProps {
|
|
24
|
+
onPress: () => void;
|
|
25
|
+
isDisabled?: boolean;
|
|
26
|
+
className?: string;
|
|
27
|
+
}
|
|
28
|
+
/** The mic button that starts dictation; put it in the composer's `trailing`. */
|
|
29
|
+
export declare function DictationButton({ onPress, isDisabled, className }: DictationButtonProps): import("react").JSX.Element;
|
|
30
|
+
/** The meter, ✕ and ✓: what the composer shows in place of send while dictating. */
|
|
31
|
+
export declare function DictationControls({ dictation, onAccept, finishing }: {
|
|
32
|
+
dictation: DictationState;
|
|
33
|
+
onAccept: () => void;
|
|
34
|
+
finishing?: boolean;
|
|
35
|
+
}): import("react").JSX.Element;
|
|
36
|
+
export interface UseDictationOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Your transcription model: gets the recording (see `format`), returns its text. Without it the
|
|
39
|
+
* browser's speech recognition is used where there is one (in Chrome that sends audio to Google).
|
|
40
|
+
*/
|
|
41
|
+
transcribe?: (audio: Blob, signal: AbortSignal) => Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* What `transcribe` gets. "wav" (default): 16 kHz mono WAV, which every transcription API takes.
|
|
44
|
+
* "recorded": the browser's own recording (webm/opus in Chrome and Firefox, mp4 in Safari), smaller,
|
|
45
|
+
* for APIs that take it.
|
|
46
|
+
*/
|
|
47
|
+
format?: "wav" | "recorded";
|
|
48
|
+
/**
|
|
49
|
+
* With `transcribe`: while the user talks, transcribe what is recorded so far this often (ms) so the
|
|
50
|
+
* words fill the box live, even with a model that does not stream. 0 transcribes only on ✓. Default 1500.
|
|
51
|
+
*/
|
|
52
|
+
partialEvery?: number;
|
|
53
|
+
/** BCP 47 language for the browser's recognition, e.g. "en-US". Defaults to the page's language. */
|
|
54
|
+
lang?: string;
|
|
55
|
+
/** The mic was refused, recording or transcribing failed. */
|
|
56
|
+
onError?: (error: unknown) => void;
|
|
57
|
+
}
|
|
58
|
+
export interface Dictation {
|
|
59
|
+
/** Dictation can work here (a mic, and `transcribe` or the browser's recognition). Hide the mic otherwise. */
|
|
60
|
+
supported: boolean;
|
|
61
|
+
/** Start listening. */
|
|
62
|
+
start: () => void;
|
|
63
|
+
/** Pass to the composer's `dictation`; undefined when not listening. */
|
|
64
|
+
state: DictationState | undefined;
|
|
65
|
+
}
|
|
66
|
+
/** Encodes mono samples as 16-bit PCM WAV. */
|
|
67
|
+
export declare function encodeWav(samples: Float32Array, sampleRate: number): Blob;
|
|
68
|
+
/**
|
|
69
|
+
* Dictation for the composer: records the mic, draws its level, and fills the box with the words as they
|
|
70
|
+
* are heard. Plug in your transcription model with `transcribe`; a streaming model can instead drive
|
|
71
|
+
* `DictationState` directly.
|
|
72
|
+
*/
|
|
73
|
+
export declare function useDictation({ transcribe, format, partialEvery, lang, onError }?: UseDictationOptions): Dictation;
|
|
@@ -20,5 +20,5 @@ export interface EffortButtonProps extends EffortSliderProps {
|
|
|
20
20
|
/** What the button reads. Default: the current level's label. */
|
|
21
21
|
children?: ReactNode;
|
|
22
22
|
}
|
|
23
|
-
/** A composer pill ("◎ Medium") that opens the effort slider above it,
|
|
23
|
+
/** A composer pill ("◎ Medium") that opens the effort slider above it, similar to chatgpt.com's Think button. */
|
|
24
24
|
export declare function EffortButton({ icon, children, className, ...slider }: EffortButtonProps): import("react").JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ToolCallPart, type WidgetPart } from "../../../core/src/index.js";
|
|
2
2
|
import { type ReactNode } from "react";
|
|
3
3
|
/** Origins a widget may load from, e.g. "https://unpkg.com". Entries that are not plain origins are dropped. */
|
|
4
4
|
export interface WidgetAllow {
|
|
@@ -34,6 +34,11 @@ export interface WidgetHost {
|
|
|
34
34
|
partId: string;
|
|
35
35
|
message: string;
|
|
36
36
|
}) => void) | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Load widgets from this page (core's `widgetFrameLoader`, served by you) instead of `srcdoc`. Set it when
|
|
39
|
+
* your page's CSP blocks inline scripts: srcdoc frames inherit that CSP, so widget scripts would not run.
|
|
40
|
+
*/
|
|
41
|
+
frameUrl?: string;
|
|
37
42
|
}
|
|
38
43
|
/** Sets what widgets below may do. ChatView and ChatTranscript set it from their `widgets` prop. */
|
|
39
44
|
export declare function WidgetHostProvider({ host, children }: {
|
|
@@ -69,7 +74,7 @@ export declare const WIDGET_MAX_HEIGHT = 2000;
|
|
|
69
74
|
export declare function intersectAllow(request: WidgetAllow, allow?: WidgetAllow): WidgetAllow;
|
|
70
75
|
/** The Content-Security-Policy of a widget's document. */
|
|
71
76
|
export declare function widgetCsp(allow?: WidgetAllow): string;
|
|
72
|
-
export declare function WidgetFrame({ html, document: isDocument, streaming, title, loadingMessages, allow, csp: request, onPrompt, onOpenLink, onCallTool, onError, toolInput, toolResult, cancelled, className, }: WidgetFrameProps): import("react").JSX.Element;
|
|
77
|
+
export declare function WidgetFrame({ html, document: isDocument, streaming, title, loadingMessages, allow, csp: request, onPrompt, onOpenLink, onCallTool, onError, toolInput, toolResult, cancelled, frameUrl: ownFrameUrl, className, }: WidgetFrameProps): import("react").JSX.Element;
|
|
73
78
|
/** The default look of a `widget` part: inline html, or an app UI the host reads from `resourceUri`. */
|
|
74
79
|
export declare function WidgetPartView({ part }: {
|
|
75
80
|
part: WidgetPart;
|
|
@@ -54,6 +54,8 @@ export type { TokenCounterProps } from "./components/token-counter";
|
|
|
54
54
|
export { ContextPanel } from "./components/context-panel";
|
|
55
55
|
export type { ContextPanelProps } from "./components/context-panel";
|
|
56
56
|
export { Composer, AttachButton } from "./components/composer";
|
|
57
|
+
export { DictationButton, DictationControls, VoiceMeter, encodeWav, useDictation } from "./components/dictation";
|
|
58
|
+
export type { Dictation, DictationButtonProps, DictationState, UseDictationOptions, VoiceMeterProps } from "./components/dictation";
|
|
57
59
|
export { EffortSlider, EffortButton } from "./components/effort-slider";
|
|
58
60
|
export type { EffortSliderProps, EffortButtonProps } from "./components/effort-slider";
|
|
59
61
|
export type { ComposerProps, AttachButtonProps } from "./components/composer";
|
|
@@ -25,6 +25,12 @@ export interface ChatIcons {
|
|
|
25
25
|
stop: ReactNode;
|
|
26
26
|
/** Open the attach menu in the composer. */
|
|
27
27
|
attach: ReactNode;
|
|
28
|
+
/** Start dictation in the composer. */
|
|
29
|
+
mic: ReactNode;
|
|
30
|
+
/** Cancel dictation. */
|
|
31
|
+
dictationCancel: ReactNode;
|
|
32
|
+
/** Accept dictation: put the transcript in the box. */
|
|
33
|
+
dictationAccept: ReactNode;
|
|
28
34
|
/** Jump to the newest message. */
|
|
29
35
|
scrollToBottom: ReactNode;
|
|
30
36
|
/** Prefix of the token counter. */
|
|
@@ -81,6 +81,16 @@ export interface ChatLabels {
|
|
|
81
81
|
stop: string;
|
|
82
82
|
/** Send button. */
|
|
83
83
|
send: string;
|
|
84
|
+
/** Composer placeholder while dictating. */
|
|
85
|
+
listening: string;
|
|
86
|
+
/** Composer placeholder while the last words are transcribed. */
|
|
87
|
+
transcribing: string;
|
|
88
|
+
/** The mic button. */
|
|
89
|
+
dictate: string;
|
|
90
|
+
/** Dictation's cancel button. */
|
|
91
|
+
dictationCancel: string;
|
|
92
|
+
/** Dictation's accept button. */
|
|
93
|
+
dictationAccept: string;
|
|
84
94
|
/** The `+` button of the composer. */
|
|
85
95
|
addFiles: string;
|
|
86
96
|
/** Accessible name of an attachment list. */
|
|
@@ -15,7 +15,7 @@ export interface SegmentedControlProps<T extends string = string> {
|
|
|
15
15
|
className?: string;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
-
* One of a few options, side by side on a track,
|
|
18
|
+
* One of a few options, side by side on a track, similar to claude.ai's Chat / Cowork switch. Themed with
|
|
19
19
|
* `--chat-segment-track` (default: a shade darker than the surface it sits on) and `--chat-segment-selected`
|
|
20
20
|
* (default `--chat-raised`).
|
|
21
21
|
*/
|
package/package.json
CHANGED