@artooi/ag-ui-web-component 0.6.0 → 0.8.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/CHANGELOG.md +73 -1
- package/README.md +180 -9
- package/dist/ag-ui-web-component.bundle.js +268 -47
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts +20 -0
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/core/agui_client.d.ts +16 -0
- package/dist/core/agui_client.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +847 -237
- package/dist/index.js.map +3 -3
- package/dist/tools/page_action_tools.d.ts +31 -0
- package/dist/tools/page_action_tools.d.ts.map +1 -0
- package/dist/ui/attachment_tray.d.ts +3 -0
- package/dist/ui/attachment_tray.d.ts.map +1 -1
- package/dist/ui/confirmation_card.d.ts +4 -1
- package/dist/ui/confirmation_card.d.ts.map +1 -1
- package/dist/ui/relative_time.d.ts +5 -3
- package/dist/ui/relative_time.d.ts.map +1 -1
- package/dist/ui/styles.d.ts +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/dist/ui/thread_drawer.d.ts +7 -1
- package/dist/ui/thread_drawer.d.ts.map +1 -1
- package/dist/ui/tool_call_card.d.ts +19 -8
- package/dist/ui/tool_call_card.d.ts.map +1 -1
- package/dist/ui/ui_strings.d.ts +126 -0
- package/dist/ui/ui_strings.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/constants.ts +5 -0
- package/src/core/ag_ui_chat.ts +267 -46
- package/src/core/agui_client.ts +33 -2
- package/src/index.ts +7 -0
- package/src/tools/page_action_tools.ts +130 -0
- package/src/ui/attachment_tray.ts +13 -7
- package/src/ui/confirmation_card.ts +15 -5
- package/src/ui/relative_time.ts +15 -8
- package/src/ui/styles.ts +221 -0
- package/src/ui/thread_drawer.ts +53 -25
- package/src/ui/tool_call_card.ts +63 -25
- package/src/ui/ui_strings.ts +208 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ClientTool } from "./client_tool_registry.js";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve a page-action target string to a host-page element, or `null` when it
|
|
4
|
+
* matches nothing. The default (`document.querySelector`) treats the string as a
|
|
5
|
+
* CSS selector; a host with a page map overrides it to map its own element ids,
|
|
6
|
+
* the same way host packages wrap the DOM-driver primitives with environment-
|
|
7
|
+
* aware lookups.
|
|
8
|
+
*/
|
|
9
|
+
export type ResolvePageTarget = (target: string) => HTMLElement | null;
|
|
10
|
+
/** The built-in page-action tool tokens, opted in via `data-page-actions`. */
|
|
11
|
+
export declare const PAGE_ACTIONS: {
|
|
12
|
+
readonly SCROLL: "scroll";
|
|
13
|
+
readonly DRAG: "drag";
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The opt-in page-action tools selected by `enabled` (a set of
|
|
17
|
+
* {@link PAGE_ACTIONS} tokens), bound to a {@link ResolvePageTarget}.
|
|
18
|
+
*
|
|
19
|
+
* - `scroll_to` — scroll a target (`top` / `bottom` / a resolver target) into
|
|
20
|
+
* view. Benign; no confirmation.
|
|
21
|
+
* - `drag_and_drop` — drag one element onto another, firing the standard HTML5
|
|
22
|
+
* drag sequence so the host page's own drop handler reacts. Not stamped
|
|
23
|
+
* destructive: a drag rearranges transient state and the durable change
|
|
24
|
+
* happens at the page's explicit commit. A host whose page persists *on drop*
|
|
25
|
+
* gates it with the element's `confirmPredicate`.
|
|
26
|
+
*
|
|
27
|
+
* Both report a clean, model-readable error when a target resolves to nothing,
|
|
28
|
+
* rather than throwing an opaque crash.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createPageActionTools(enabled: ReadonlySet<string>, resolveTarget: ResolvePageTarget): ClientTool[];
|
|
31
|
+
//# sourceMappingURL=page_action_tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page_action_tools.d.ts","sourceRoot":"","sources":["../../src/tools/page_action_tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAC;AAEvE,8EAA8E;AAC9E,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAEX;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAC5B,aAAa,EAAE,iBAAiB,GAC/B,UAAU,EAAE,CASd"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AttachmentRef } from "../core/attachment.js";
|
|
2
2
|
import type { UploadHandler } from "../core/upload_attachment.js";
|
|
3
|
+
import { type UiStrings } from "./ui_strings.js";
|
|
3
4
|
/** Config the host ({@link AgUiChat}) hands the tray. */
|
|
4
5
|
export interface AttachmentTrayConfig {
|
|
5
6
|
/** Upload one file, reporting `0..1` progress; resolves to a durable ref. */
|
|
@@ -10,6 +11,8 @@ export interface AttachmentTrayConfig {
|
|
|
10
11
|
readonly accept: string;
|
|
11
12
|
/** Fired when the set of attachments changes (add / settle / remove). */
|
|
12
13
|
readonly onChange?: () => void;
|
|
14
|
+
/** Localized strings; defaults to the English {@link DEFAULT_UI_STRINGS}. */
|
|
15
|
+
readonly strings?: UiStrings;
|
|
13
16
|
}
|
|
14
17
|
/**
|
|
15
18
|
* The composer's pending-attachments tray: a chip per picked file with a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment_tray.d.ts","sourceRoot":"","sources":["../../src/ui/attachment_tray.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"attachment_tray.d.ts","sourceRoot":"","sources":["../../src/ui/attachment_tray.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAKrE,yDAAyD;AACzD,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;CAC9B;AAYD;;;;;;;;;GASG;AACH,qBAAa,cAAc;;IACzB,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;gBAMrB,MAAM,EAAE,oBAAoB;IASxC,gFAAgF;IAChF,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAuBrB,8DAA8D;IAC9D,SAAS,IAAI,SAAS,aAAa,EAAE;IAUrC,gFAAgF;IAChF,UAAU,IAAI,OAAO;IAIrB,uCAAuC;IACvC,OAAO,IAAI,OAAO;IAIlB,2EAA2E;IAC3E,UAAU,IAAI,IAAI;IAKlB,4CAA4C;IAC5C,KAAK,IAAI,IAAI;CA2Gd"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { type UiStrings } from "./ui_strings.js";
|
|
1
2
|
/** What the inline confirmation card displays. */
|
|
2
3
|
export interface ConfirmationRequest {
|
|
3
4
|
toolName: string;
|
|
4
5
|
args: Record<string, unknown>;
|
|
5
6
|
/**
|
|
6
7
|
* Human-readable prompt (from the tool's `x-confirm` metadata), e.g.
|
|
7
|
-
* "Activate this project?". Falls back to
|
|
8
|
+
* "Activate this project?". Falls back to the generic `confirmRun` template.
|
|
8
9
|
*/
|
|
9
10
|
message?: string;
|
|
10
11
|
}
|
|
@@ -16,6 +17,8 @@ export interface ConfirmationOptions {
|
|
|
16
17
|
* pending confirmation when the user cancels the whole run.
|
|
17
18
|
*/
|
|
18
19
|
signal?: AbortSignal;
|
|
20
|
+
/** Localized strings; defaults to the English {@link DEFAULT_UI_STRINGS}. */
|
|
21
|
+
strings?: UiStrings;
|
|
19
22
|
}
|
|
20
23
|
/**
|
|
21
24
|
* Append an inline confirmation card to ``host`` (the chat message list) and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirmation_card.d.ts","sourceRoot":"","sources":["../../src/ui/confirmation_card.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"confirmation_card.d.ts","sourceRoot":"","sources":["../../src/ui/confirmation_card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAErE,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAYD,+CAA+C;AAC/C,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,GAAG,UAAU,EACvB,OAAO,EAAE,mBAAmB,EAC5B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,OAAO,CAAC,CAqDlB"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { type UiStrings } from "./ui_strings.js";
|
|
1
2
|
/**
|
|
2
3
|
* A compact relative timestamp for a thread row — e.g. `"just now"`, `"5m ago"`,
|
|
3
4
|
* `"3h ago"`, `"2d ago"`, `"4w ago"`.
|
|
4
5
|
*
|
|
5
6
|
* `now` is injectable so callers (and tests) can pin the reference point; it
|
|
6
7
|
* defaults to the current time. A timestamp in the future (clock skew) reads as
|
|
7
|
-
* `"just now"`.
|
|
8
|
-
*
|
|
8
|
+
* `"just now"`. The unit words come from {@link UiStrings} (the `{n}` token is
|
|
9
|
+
* filled in here) so a localized host translates them; the bucketing stays
|
|
10
|
+
* integer-rounded and locale-neutral.
|
|
9
11
|
*/
|
|
10
|
-
export declare function relativeTime(timestamp: number, now?: number): string;
|
|
12
|
+
export declare function relativeTime(timestamp: number, now?: number, strings?: UiStrings): string;
|
|
11
13
|
//# sourceMappingURL=relative_time.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relative_time.d.ts","sourceRoot":"","sources":["../../src/ui/relative_time.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"relative_time.d.ts","sourceRoot":"","sources":["../../src/ui/relative_time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAErE;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAmB,EACxB,OAAO,GAAE,SAA8B,GACtC,MAAM,CAkBR"}
|
package/dist/ui/styles.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const STYLES = "\n:host {\n /* Colors */\n --ag-ui-bg: #ffffff;\n --ag-ui-fg: #1a1a2e;\n --ag-ui-accent: #4f46e5;\n --ag-ui-user-bg: #4f46e5;\n --ag-ui-user-fg: #ffffff;\n --ag-ui-assistant-bg: #f1f1f6;\n --ag-ui-input-bg: var(--ag-ui-bg);\n --ag-ui-tool-bg: var(--ag-ui-assistant-bg);\n --ag-ui-tool-fg: var(--ag-ui-accent);\n --ag-ui-header-bg: var(--ag-ui-accent);\n --ag-ui-header-fg: #ffffff;\n --ag-ui-border: #e2e2ec;\n --ag-ui-radius: 12px;\n\n /* Status accents for tool-call cards. */\n --ag-ui-success: #15803d;\n --ag-ui-danger: #b91c1c;\n --ag-ui-muted: #6b7280;\n\n /* Surface \u2014 set --ag-ui-shadow: none for a flush, embedded panel. */\n --ag-ui-shadow: 0 12px 32px rgba(20, 20, 50, 0.18);\n --ag-ui-font: inherit;\n --ag-ui-font-size: 14px;\n --ag-ui-code-font: ui-monospace, \"SF Mono\", Menlo, monospace;\n\n /* Spacing \u2014 the density preset overrides these. */\n --ag-ui-space: 10px;\n --ag-ui-pad: 16px;\n --ag-ui-msg-pad: 8px 12px;\n --ag-ui-msg-radius: 14px;\n\n /* Layout \u2014 override from outside to dock the widget anywhere.\n Set --ag-ui-position: static (and place this element in your own\n grid/flex layout) to embed it in the page flow instead of floating. */\n --ag-ui-position: fixed;\n --ag-ui-z-index: 2147483000;\n --ag-ui-width: 380px;\n --ag-ui-height: 560px;\n --ag-ui-inset: auto 24px 24px auto;\n --ag-ui-max-width: calc(100vw - 48px);\n --ag-ui-max-height: calc(100vh - 48px);\n\n position: var(--ag-ui-position);\n inset: var(--ag-ui-inset);\n z-index: var(--ag-ui-z-index);\n width: var(--ag-ui-width);\n max-width: var(--ag-ui-max-width);\n height: var(--ag-ui-height);\n max-height: var(--ag-ui-max-height);\n display: flex;\n font-family: var(--ag-ui-font);\n font-size: var(--ag-ui-font-size);\n color: var(--ag-ui-fg);\n}\n\n/* \u2500\u2500 Themes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Themes only re-set the colour variables; layout/spacing are unaffected.\n theme=\"auto\" follows the OS via prefers-color-scheme. */\n:host([theme=\"dark\"]) {\n --ag-ui-bg: #15151f;\n --ag-ui-fg: #e8e8f2;\n --ag-ui-assistant-bg: #25253a;\n --ag-ui-header-bg: #1f1f30;\n --ag-ui-header-fg: #e8e8f2;\n --ag-ui-border: #33334a;\n --ag-ui-muted: #9aa0b4;\n --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);\n}\n\n@media (prefers-color-scheme: dark) {\n :host([theme=\"auto\"]) {\n --ag-ui-bg: #15151f;\n --ag-ui-fg: #e8e8f2;\n --ag-ui-assistant-bg: #25253a;\n --ag-ui-header-bg: #1f1f30;\n --ag-ui-header-fg: #e8e8f2;\n --ag-ui-border: #33334a;\n --ag-ui-muted: #9aa0b4;\n --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);\n }\n}\n\n/* A terminal-flavoured \"code\" theme: dark, monospace, green accent. */\n:host([theme=\"code\"]) {\n --ag-ui-bg: #0d1117;\n --ag-ui-fg: #c9d1d9;\n --ag-ui-accent: #3fb950;\n --ag-ui-user-bg: #238636;\n --ag-ui-assistant-bg: #161b22;\n --ag-ui-header-bg: #010409;\n --ag-ui-header-fg: #c9d1d9;\n --ag-ui-border: #30363d;\n --ag-ui-muted: #8b949e;\n --ag-ui-font: var(--ag-ui-code-font);\n --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);\n}\n\n/* \u2500\u2500 Density \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([density=\"compact\"]) {\n --ag-ui-font-size: 13px;\n --ag-ui-space: 6px;\n --ag-ui-pad: 10px;\n --ag-ui-msg-pad: 5px 9px;\n --ag-ui-msg-radius: 10px;\n}\n\n/* \u2500\u2500 Placement presets \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([placement=\"bottom-left\"]) {\n --ag-ui-inset: auto auto 24px 24px;\n}\n\n:host([placement=\"side\"]) {\n --ag-ui-inset: 0 0 0 auto;\n --ag-ui-width: 420px;\n --ag-ui-height: 100vh;\n --ag-ui-max-height: 100vh;\n --ag-ui-radius: 0;\n}\n\n:host([placement=\"full\"]) {\n --ag-ui-inset: 0;\n --ag-ui-width: 100vw;\n --ag-ui-height: 100vh;\n --ag-ui-max-width: 100vw;\n --ag-ui-max-height: 100vh;\n --ag-ui-radius: 0;\n}\n\n/* Embedded: drop the floating chrome and the high z-index stacking context so\n the widget lives in the host's own layout (fixes overlay/z-index clashes). */\n:host([placement=\"embedded\"]) {\n --ag-ui-position: static;\n --ag-ui-width: 100%;\n --ag-ui-height: 100%;\n --ag-ui-max-width: 100%;\n --ag-ui-max-height: 100%;\n --ag-ui-shadow: none;\n --ag-ui-z-index: auto;\n}\n\n.chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: var(--ag-ui-radius);\n box-shadow: var(--ag-ui-shadow);\n overflow: hidden;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--ag-ui-border);\n background: var(--ag-ui-header-bg);\n color: var(--ag-ui-header-fg);\n}\n\n.header-title {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.header-controls {\n display: flex;\n gap: 2px;\n flex: none;\n}\n\n.header-btn {\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1;\n padding: 4px 7px;\n border-radius: 6px;\n cursor: pointer;\n opacity: 0.85;\n}\n\n.header-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.18);\n}\n\n/* Collapsed: keep just the header bar \u2014 hide the whole body, and let the host\n shrink to the header. (A host can also fully hide the element itself.) */\n:host([collapsed]) {\n height: auto;\n max-height: none;\n}\n\n:host([collapsed]) .messages,\n:host([collapsed]) .input-row,\n:host([collapsed]) .skill-chips,\n:host([collapsed]) .skill-palette,\n:host([collapsed]) .skill-hint {\n display: none;\n}\n\n/* Edge-docked placements pin top *and* bottom, which would otherwise keep the\n panel full-height when collapsed; unpin the bottom so it shrinks to the\n header. (Floating/bottom-left pin only the bottom, so they already shrink.) */\n:host([collapsed][placement=\"side\"]),\n:host([collapsed][placement=\"full\"]) {\n bottom: auto;\n}\n\n.messages {\n flex: 1;\n overflow-y: auto;\n padding: var(--ag-ui-pad);\n display: flex;\n flex-direction: column;\n gap: var(--ag-ui-space);\n}\n\n.message {\n max-width: 80%;\n padding: var(--ag-ui-msg-pad);\n border-radius: var(--ag-ui-msg-radius);\n line-height: 1.4;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* \u2500\u2500 Incoming-text animations (data-text-animation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* .message--restored (rehydrated history) is excluded: entrance animations are\n for freshly-arriving messages, not the whole transcript replaying on reload.\n Word mode is excluded implicitly \u2014 restored bubbles aren't wrapped. */\n:host([data-text-animation=\"fade\"]) .message--assistant:not(.message--restored) {\n animation: ag-ui-msg-fade 0.25s ease both;\n}\n\n@keyframes ag-ui-msg-fade {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: none; }\n}\n\n.message--assistant .word {\n animation: ag-ui-word-in 0.3s ease both;\n animation-delay: calc(var(--ag-ui-word-index, 0) * 35ms);\n}\n\n@keyframes ag-ui-word-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host([data-text-animation=\"fade\"]) .message--assistant,\n .message--assistant .word {\n animation: none;\n }\n}\n\n.message--user {\n align-self: flex-end;\n background: var(--ag-ui-user-bg);\n color: var(--ag-ui-user-fg);\n border-bottom-right-radius: 4px;\n}\n\n.message--assistant {\n align-self: flex-start;\n background: var(--ag-ui-assistant-bg);\n border-bottom-left-radius: 4px;\n /* Assistant bubbles hold rendered markdown/HTML, so collapse the source\n whitespace the renderer leaves between block tags. */\n white-space: normal;\n}\n\n/* Rendered-markdown elements inside an assistant bubble. */\n.message--assistant > :first-child {\n margin-top: 0;\n}\n\n.message--assistant > :last-child {\n margin-bottom: 0;\n}\n\n.message--assistant p,\n.message--assistant ul,\n.message--assistant ol,\n.message--assistant blockquote,\n.message--assistant pre {\n margin: 0.5em 0;\n}\n\n.message--assistant ul,\n.message--assistant ol {\n padding-left: 1.3em;\n}\n\n.message--assistant a {\n color: var(--ag-ui-accent);\n text-decoration: underline;\n}\n\n.message--assistant code {\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n font-size: 0.92em;\n background: rgba(127, 127, 127, 0.16);\n padding: 1px 4px;\n border-radius: 4px;\n}\n\n.message--assistant pre {\n padding: 8px 10px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 6px;\n}\n\n.message--assistant pre code {\n background: none;\n padding: 0;\n}\n\n.message--assistant blockquote {\n padding-left: 10px;\n border-left: 3px solid var(--ag-ui-border);\n color: var(--ag-ui-muted);\n}\n\n.pending {\n align-self: flex-start;\n display: inline-flex;\n gap: 4px;\n align-items: center;\n padding: 12px 14px;\n background: var(--ag-ui-assistant-bg);\n border-radius: 14px;\n border-bottom-left-radius: 4px;\n}\n\n.pending-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--ag-ui-muted);\n animation: ag-ui-pending 1.2s infinite ease-in-out both;\n}\n\n.pending-dot:nth-child(2) {\n animation-delay: 0.16s;\n}\n\n.pending-dot:nth-child(3) {\n animation-delay: 0.32s;\n}\n\n@keyframes ag-ui-pending {\n 0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }\n 40% { opacity: 1; transform: translateY(-3px); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pending-dot {\n animation: none;\n opacity: 0.6;\n }\n}\n\n.tool-call {\n align-self: flex-start;\n max-width: 80%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--ag-ui-tool-bg);\n border: 1px solid var(--ag-ui-border);\n color: var(--ag-ui-tool-fg);\n}\n\n.tool-call-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.tool-call-name {\n font-weight: 600;\n word-break: break-word;\n}\n\n.tool-call-status {\n flex: none;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: rgba(127, 127, 127, 0.16);\n color: var(--ag-ui-muted);\n}\n\n.tool-call[data-status=\"done\"] .tool-call-status {\n color: var(--ag-ui-success);\n}\n\n.tool-call[data-status=\"error\"] .tool-call-status {\n color: var(--ag-ui-danger);\n}\n\n.tool-call[data-status=\"declined\"] .tool-call-status {\n color: var(--ag-ui-muted);\n}\n\n.tool-call-args,\n.tool-call-result {\n margin: 0;\n padding: 6px 8px;\n max-height: 160px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 6px;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--ag-ui-fg);\n}\n\n.tool-call-toggle {\n align-self: flex-start;\n border: none;\n padding: 0;\n background: none;\n font: inherit;\n font-weight: 600;\n color: var(--ag-ui-accent);\n cursor: pointer;\n}\n\n.tool-call-toggle::before {\n content: \"\u25B8 \";\n}\n\n.tool-call-toggle[aria-expanded=\"true\"]::before {\n content: \"\u25BE \";\n}\n\n.input-row {\n display: flex;\n gap: 8px;\n padding: 12px;\n border-top: 1px solid var(--ag-ui-border);\n}\n\n.input {\n flex: 1;\n resize: none;\n background: var(--ag-ui-input-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 8px 10px;\n font: inherit;\n color: inherit;\n outline: none;\n}\n\n.input:focus {\n border-color: var(--ag-ui-accent);\n}\n\n.send {\n border: none;\n border-radius: 8px;\n padding: 0 16px;\n background: var(--ag-ui-accent);\n color: #ffffff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.send:disabled {\n opacity: 0.5;\n cursor: default;\n}\n\n/* The composer button doubles as the Stop control while a run is in flight. */\n.send[data-state=\"running\"] {\n background: var(--ag-ui-muted);\n}\n\n/* \u2500\u2500 File attachments \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* The \uD83D\uDCCE picker button sits left of the input; hidden until data-attachments-url. */\n.attach-btn {\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 0 10px;\n background: var(--ag-ui-input-bg);\n color: inherit;\n font: inherit;\n cursor: pointer;\n}\n\n.attach-btn:hover {\n border-color: var(--ag-ui-accent);\n}\n\n.attach-input {\n display: none;\n}\n\n/* Pending-attachments tray, above the input row; collapses (hidden) when empty. */\n.attachment-slot {\n display: contents;\n}\n\n.attachment-tray {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 12px 0;\n}\n\n.attachment-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 6px;\n}\n\n.attachment-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: 100%;\n padding: 4px 8px;\n border: 1px solid var(--ag-ui-border);\n border-radius: 999px;\n background: var(--ag-ui-assistant-bg);\n font-size: 0.85em;\n position: relative;\n}\n\n.attachment-chip--error {\n border-color: var(--ag-ui-danger);\n color: var(--ag-ui-danger);\n}\n\n.attachment-chip-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 14ch;\n}\n\n.attachment-chip-size {\n color: var(--ag-ui-muted);\n white-space: nowrap;\n}\n\n.attachment-chip--error .attachment-chip-size {\n color: var(--ag-ui-danger);\n}\n\n/* The progress bar fills as the file uploads. */\n.attachment-chip-bar {\n flex-basis: 100%;\n height: 3px;\n border-radius: 2px;\n background: var(--ag-ui-border);\n overflow: hidden;\n}\n\n.attachment-chip-bar-fill {\n height: 100%;\n background: var(--ag-ui-accent);\n transition: width 0.15s ease;\n}\n\n.attachment-chip-remove,\n.attachment-chip-retry {\n border: none;\n background: none;\n color: inherit;\n cursor: pointer;\n padding: 0;\n line-height: 1;\n opacity: 0.7;\n}\n\n.attachment-chip-remove:hover,\n.attachment-chip-retry:hover {\n opacity: 1;\n}\n\n/* A subtle outline while a file is dragged over the shell. */\n.chat--dragover {\n outline: 2px dashed var(--ag-ui-accent);\n outline-offset: -4px;\n}\n\n/* Muted \"\u23F9 Stopped\" line after a cancelled run \u2014 a note, not an error bubble. */\n.stopped-note {\n align-self: flex-start;\n color: var(--ag-ui-muted);\n font-size: 12px;\n padding: 2px 4px;\n}\n\n/* Inline confirmation card \u2014 lives in the transcript, no focus-stealing overlay. */\n.confirm {\n align-self: stretch;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-accent);\n border-radius: 10px;\n}\n\n.confirm[data-resolved] {\n opacity: 0.7;\n border-color: var(--ag-ui-border);\n}\n\n.confirm-body {\n font-weight: 600;\n}\n\n.confirm-args {\n margin: 0;\n padding: 8px 10px;\n max-height: 140px;\n overflow: auto;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n background: var(--ag-ui-assistant-bg);\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n\n.confirm-btn {\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--ag-ui-bg);\n color: var(--ag-ui-fg);\n}\n\n.confirm-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n.confirm-btn--confirm {\n border-color: var(--ag-ui-accent);\n background: var(--ag-ui-accent);\n color: #ffffff;\n}\n\n/* Skills \u2014 chips row + the /-command palette, above the input. */\n.skill-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 10px 12px;\n}\n\n.skill-chip {\n border: 1px solid var(--ag-ui-border);\n border-radius: 999px;\n padding: 4px 12px;\n font: inherit;\n font-size: 0.9em;\n cursor: pointer;\n background: var(--ag-ui-assistant-bg);\n color: var(--ag-ui-fg);\n}\n\n.skill-chip:hover {\n border-color: var(--ag-ui-accent);\n}\n\n.skill-palette {\n margin: 8px 12px 0;\n display: flex;\n flex-direction: column;\n max-height: 220px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(20, 20, 50, 0.16);\n}\n\n.skill-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n align-items: flex-start;\n padding: 8px 12px;\n border: none;\n background: none;\n font: inherit;\n text-align: left;\n cursor: pointer;\n color: var(--ag-ui-fg);\n}\n\n.skill-item[aria-selected=\"true\"] {\n background: var(--ag-ui-assistant-bg);\n}\n\n.skill-item-title {\n font-weight: 600;\n}\n\n.skill-item-desc {\n font-size: 0.85em;\n color: var(--ag-ui-muted);\n}\n\n.skill-hint {\n margin: 8px 12px 0;\n font-size: 0.85em;\n color: var(--ag-ui-danger);\n}\n\n/* Chat-history drawer \u2014 a slide-over within the chat panel. */\n.drawer {\n position: absolute;\n inset: 0;\n z-index: 5;\n display: flex;\n}\n\n.drawer[hidden] {\n display: none;\n}\n\n.drawer-backdrop {\n position: absolute;\n inset: 0;\n background: rgba(20, 20, 50, 0.32);\n}\n\n.drawer-panel {\n position: relative;\n display: flex;\n flex-direction: column;\n width: min(300px, 85%);\n height: 100%;\n background: var(--ag-ui-bg);\n border-right: 1px solid var(--ag-ui-border);\n box-shadow: var(--ag-ui-shadow);\n overflow: hidden;\n}\n\n.drawer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--ag-ui-space);\n padding: var(--ag-ui-pad);\n border-bottom: 1px solid var(--ag-ui-border);\n}\n\n.drawer-title {\n font-weight: 600;\n}\n\n.drawer-new {\n border: 1px solid var(--ag-ui-border);\n border-radius: var(--ag-ui-radius);\n background: var(--ag-ui-bg);\n color: var(--ag-ui-accent);\n padding: 4px 10px;\n font: inherit;\n font-size: 0.85em;\n cursor: pointer;\n}\n\n.drawer-list {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}\n\n.drawer-empty {\n padding: var(--ag-ui-pad);\n font-size: 0.9em;\n color: var(--ag-ui-muted);\n}\n\n.drawer-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--ag-ui-border);\n}\n\n.drawer-row--active {\n background: var(--ag-ui-assistant-bg);\n}\n\n.drawer-row-select {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 8px 12px;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.drawer-row-title {\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.drawer-row-time {\n font-size: 0.72em;\n color: var(--ag-ui-muted);\n}\n\n.drawer-row-preview {\n font-size: 0.8em;\n color: var(--ag-ui-muted);\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.drawer-row-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 6px;\n}\n\n.drawer-row-rename,\n.drawer-row-delete {\n border: none;\n background: none;\n color: var(--ag-ui-muted);\n font-size: 0.9em;\n padding: 4px;\n cursor: pointer;\n}\n\n.drawer-rename-input {\n flex: 1;\n min-width: 0;\n margin: 6px 10px;\n padding: 4px 8px;\n border: 1px solid var(--ag-ui-accent);\n border-radius: 6px;\n background: var(--ag-ui-input-bg);\n color: var(--ag-ui-fg);\n font: inherit;\n}\n\n.drawer-confirm {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n font-size: 0.85em;\n}\n\n.drawer-confirm-label {\n color: var(--ag-ui-danger);\n}\n\n.drawer-confirm-yes {\n border: none;\n border-radius: 6px;\n background: var(--ag-ui-danger);\n color: #ffffff;\n padding: 3px 10px;\n font: inherit;\n cursor: pointer;\n}\n\n.drawer-confirm-no {\n border: 1px solid var(--ag-ui-border);\n border-radius: 6px;\n background: none;\n color: inherit;\n padding: 3px 10px;\n font: inherit;\n cursor: pointer;\n}\n\n/* Embedded placement: an inline, flush side panel rather than a dimmed,\n floating slide-over. */\n:host([placement=\"embedded\"]) .drawer-backdrop {\n background: none;\n}\n\n:host([placement=\"embedded\"]) .drawer-panel {\n width: 100%;\n border-right: none;\n box-shadow: none;\n}\n";
|
|
1
|
+
export declare const STYLES = "\n:host {\n /* Colors */\n --ag-ui-bg: #ffffff;\n --ag-ui-fg: #1a1a2e;\n --ag-ui-accent: #4f46e5;\n --ag-ui-user-bg: #4f46e5;\n --ag-ui-user-fg: #ffffff;\n --ag-ui-assistant-bg: #f1f1f6;\n --ag-ui-input-bg: var(--ag-ui-bg);\n --ag-ui-tool-bg: var(--ag-ui-assistant-bg);\n --ag-ui-tool-fg: var(--ag-ui-accent);\n --ag-ui-header-bg: var(--ag-ui-accent);\n --ag-ui-header-fg: #ffffff;\n --ag-ui-border: #e2e2ec;\n --ag-ui-radius: 12px;\n\n /* Status accents for tool-call cards. */\n --ag-ui-success: #15803d;\n --ag-ui-danger: #b91c1c;\n --ag-ui-muted: #6b7280;\n\n /* Tool-call status icon glyphs (override to re-theme) + spinner speed.\n The pending state is the animated ring; the settled states use these. */\n --ag-ui-tool-icon-done: \"\u2713\";\n --ag-ui-tool-icon-error: \"\u2715\";\n --ag-ui-tool-icon-declined: \"\u2298\";\n --ag-ui-tool-spin-duration: 0.7s;\n\n /* Answer well (opt-in via data-answer-well) \u2014 boxes a whole assistant turn. */\n --ag-ui-well-bg: transparent;\n --ag-ui-well-border: var(--ag-ui-border);\n\n /* Surface \u2014 set --ag-ui-shadow: none for a flush, embedded panel. */\n --ag-ui-shadow: 0 12px 32px rgba(20, 20, 50, 0.18);\n --ag-ui-font: inherit;\n --ag-ui-font-size: 14px;\n --ag-ui-code-font: ui-monospace, \"SF Mono\", Menlo, monospace;\n\n /* Spacing \u2014 the density preset overrides these. */\n --ag-ui-space: 10px;\n --ag-ui-pad: 16px;\n --ag-ui-msg-pad: 8px 12px;\n --ag-ui-msg-radius: 14px;\n\n /* Layout \u2014 override from outside to dock the widget anywhere.\n Set --ag-ui-position: static (and place this element in your own\n grid/flex layout) to embed it in the page flow instead of floating. */\n --ag-ui-position: fixed;\n --ag-ui-z-index: 2147483000;\n --ag-ui-width: 380px;\n --ag-ui-height: 560px;\n --ag-ui-inset: auto 24px 24px auto;\n --ag-ui-max-width: calc(100vw - 48px);\n --ag-ui-max-height: calc(100vh - 48px);\n /* Reading-column width for placement=\"page\" (full-bleed, centred content). */\n --ag-ui-content-max-width: 820px;\n\n position: var(--ag-ui-position);\n inset: var(--ag-ui-inset);\n z-index: var(--ag-ui-z-index);\n width: var(--ag-ui-width);\n max-width: var(--ag-ui-max-width);\n height: var(--ag-ui-height);\n max-height: var(--ag-ui-max-height);\n display: flex;\n font-family: var(--ag-ui-font);\n font-size: var(--ag-ui-font-size);\n color: var(--ag-ui-fg);\n}\n\n/* \u2500\u2500 Themes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Themes only re-set the colour variables; layout/spacing are unaffected.\n theme=\"auto\" follows the OS via prefers-color-scheme. */\n:host([theme=\"dark\"]) {\n --ag-ui-bg: #15151f;\n --ag-ui-fg: #e8e8f2;\n --ag-ui-assistant-bg: #25253a;\n --ag-ui-header-bg: #1f1f30;\n --ag-ui-header-fg: #e8e8f2;\n --ag-ui-border: #33334a;\n --ag-ui-muted: #9aa0b4;\n --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);\n}\n\n@media (prefers-color-scheme: dark) {\n :host([theme=\"auto\"]) {\n --ag-ui-bg: #15151f;\n --ag-ui-fg: #e8e8f2;\n --ag-ui-assistant-bg: #25253a;\n --ag-ui-header-bg: #1f1f30;\n --ag-ui-header-fg: #e8e8f2;\n --ag-ui-border: #33334a;\n --ag-ui-muted: #9aa0b4;\n --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);\n }\n}\n\n/* A terminal-flavoured \"code\" theme: dark, monospace, green accent. */\n:host([theme=\"code\"]) {\n --ag-ui-bg: #0d1117;\n --ag-ui-fg: #c9d1d9;\n --ag-ui-accent: #3fb950;\n --ag-ui-user-bg: #238636;\n --ag-ui-assistant-bg: #161b22;\n --ag-ui-header-bg: #010409;\n --ag-ui-header-fg: #c9d1d9;\n --ag-ui-border: #30363d;\n --ag-ui-muted: #8b949e;\n --ag-ui-font: var(--ag-ui-code-font);\n --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);\n}\n\n/* \u2500\u2500 Density \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([density=\"compact\"]) {\n --ag-ui-font-size: 13px;\n --ag-ui-space: 6px;\n --ag-ui-pad: 10px;\n --ag-ui-msg-pad: 5px 9px;\n --ag-ui-msg-radius: 10px;\n}\n\n/* \u2500\u2500 Placement presets \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([placement=\"bottom-left\"]) {\n --ag-ui-inset: auto auto 24px 24px;\n}\n\n:host([placement=\"side\"]) {\n --ag-ui-inset: 0 0 0 auto;\n --ag-ui-width: 420px;\n --ag-ui-height: 100vh;\n --ag-ui-max-height: 100vh;\n --ag-ui-radius: 0;\n}\n\n:host([placement=\"full\"]) {\n --ag-ui-inset: 0;\n --ag-ui-width: 100vw;\n --ag-ui-height: 100vh;\n --ag-ui-max-width: 100vw;\n --ag-ui-max-height: 100vh;\n --ag-ui-radius: 0;\n}\n\n/* Page (PAGE-1): full-bleed background with a centred reading column. Unlike\n \"full\" (edge-to-edge, left-aligned messages) the content sits in a column\n capped at --ag-ui-content-max-width. The column is produced by symmetric auto\n padding on the scroll area + composer (no per-row wrapper), so user pills\n still right-align and the assistant well spans the column. */\n:host([placement=\"page\"]) {\n --ag-ui-inset: 0;\n --ag-ui-width: 100vw;\n --ag-ui-height: 100vh;\n --ag-ui-max-width: 100vw;\n --ag-ui-max-height: 100vh;\n --ag-ui-radius: 0;\n}\n\n:host([placement=\"page\"]) .messages {\n padding-inline: max(var(--ag-ui-pad), calc((100% - var(--ag-ui-content-max-width)) / 2));\n}\n\n:host([placement=\"page\"]) .input-row {\n padding-inline: max(12px, calc((100% - var(--ag-ui-content-max-width)) / 2));\n}\n\n/* In the reading column the assistant well uses the full width; the user\n message stays a right-aligned pill (its default align-self + max-width). */\n:host([placement=\"page\"]) .message--assistant {\n max-width: 100%;\n}\n\n/* Sidebar (CUST-3): a full-height docked panel that slides open/closed and\n collapses to a slim icon rail (not the floating launcher). Docked right by\n default; data-side=\"left\" docks it left. Overlay by default \u2014 set\n --ag-ui-position: static (and place this element in your own layout) for a\n host-managed push instead. */\n:host([placement=\"sidebar\"]) {\n --ag-ui-inset: 0 0 0 auto;\n --ag-ui-width: 420px;\n --ag-ui-height: 100vh;\n --ag-ui-max-height: 100vh;\n --ag-ui-radius: 0;\n --ag-ui-rail-width: 52px;\n transition: width 0.28s ease;\n}\n\n:host([placement=\"sidebar\"][data-side=\"left\"]) {\n --ag-ui-inset: 0 auto 0 0;\n}\n\n:host([placement=\"sidebar\"]) .chat {\n transition: transform 0.28s ease;\n}\n\n/* Collapsed sidebar: shrink the host to the rail width, hide the panel, and\n reveal the rail. Higher specificity than the generic collapse rules, so it\n wins regardless of source order. */\n:host([placement=\"sidebar\"][collapsed]) {\n width: var(--ag-ui-rail-width);\n height: 100vh;\n max-height: 100vh;\n bottom: 0;\n}\n\n:host([placement=\"sidebar\"][collapsed]) .chat {\n display: none;\n}\n\n/* The rail is a sibling of the panel (so it survives the panel being hidden);\n shown only for a collapsed sidebar. */\n.rail {\n display: none;\n border: none;\n font: inherit;\n}\n\n:host([placement=\"sidebar\"][collapsed]) .rail {\n display: flex;\n position: absolute;\n inset: 0;\n align-items: flex-start;\n justify-content: center;\n padding-top: 16px;\n border: 1px solid var(--ag-ui-border);\n background: var(--ag-ui-header-bg);\n color: var(--ag-ui-header-fg);\n cursor: pointer;\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host([placement=\"sidebar\"]),\n :host([placement=\"sidebar\"]) .chat {\n transition: none;\n }\n}\n\n/* Embedded: drop the floating chrome and the high z-index stacking context so\n the widget lives in the host's own layout (fixes overlay/z-index clashes). */\n:host([placement=\"embedded\"]) {\n --ag-ui-position: static;\n --ag-ui-width: 100%;\n --ag-ui-height: 100%;\n --ag-ui-max-width: 100%;\n --ag-ui-max-height: 100%;\n --ag-ui-shadow: none;\n --ag-ui-z-index: auto;\n}\n\n.chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: var(--ag-ui-radius);\n box-shadow: var(--ag-ui-shadow);\n overflow: hidden;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--ag-ui-border);\n background: var(--ag-ui-header-bg);\n color: var(--ag-ui-header-fg);\n}\n\n.header-title {\n flex: 1;\n min-width: 0;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header / launcher icon holder (CUST-2): a slot, with a data-icon-url <img>\n fallback, sized via --ag-ui-icon-size. */\n.icon-holder {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: var(--ag-ui-icon-size, 22px);\n height: var(--ag-ui-icon-size, 22px);\n line-height: 1;\n}\n\n.icon-img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n border-radius: var(--ag-ui-icon-radius, 4px);\n}\n\n.header-controls {\n display: flex;\n gap: 2px;\n flex: none;\n}\n\n.header-btn {\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1;\n padding: 4px 7px;\n border-radius: 6px;\n cursor: pointer;\n opacity: 0.85;\n}\n\n.header-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.18);\n}\n\n/* Collapsed: keep just the header bar \u2014 hide the whole body, and let the host\n shrink to the header. (A host can also fully hide the element itself.) */\n:host([collapsed]) {\n height: auto;\n max-height: none;\n}\n\n:host([collapsed]) .messages,\n:host([collapsed]) .input-row,\n:host([collapsed]) .skill-chips,\n:host([collapsed]) .skill-palette,\n:host([collapsed]) .skill-hint {\n display: none;\n}\n\n/* Edge-docked placements pin top *and* bottom, which would otherwise keep the\n panel full-height when collapsed; unpin the bottom so it shrinks to the\n header. (Floating/bottom-left pin only the bottom, so they already shrink.) */\n:host([collapsed][placement=\"side\"]),\n:host([collapsed][placement=\"full\"]) {\n bottom: auto;\n}\n\n.messages {\n flex: 1;\n overflow-y: auto;\n padding: var(--ag-ui-pad);\n display: flex;\n flex-direction: column;\n gap: var(--ag-ui-space);\n}\n\n/* Empty-state region (CUST-1 slot): centred while it's the only thing in the\n list, hidden as soon as a message, card, or pending indicator renders. */\n.empty {\n margin: auto;\n text-align: center;\n color: var(--ag-ui-muted);\n}\n\n.empty[hidden] {\n display: none;\n}\n\n/* \u2500\u2500 Answer group / well (WELL-1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n One .answer per assistant turn wraps the streamed text, its tool cards,\n and the pending indicator so a whole answer reads (and can be boxed) as one\n unit. A flex column on the message-list gap, stretched to the list width so\n its children keep their own left/right alignment. data-answer-well opts into\n the bordered \"well\"; without it the layout is today's flat stack. */\n.answer {\n display: flex;\n flex-direction: column;\n gap: var(--ag-ui-space);\n align-self: stretch;\n min-width: 0;\n}\n\n:host([data-answer-well]) .answer {\n padding: var(--ag-ui-pad);\n background: var(--ag-ui-well-bg);\n border: 1px solid var(--ag-ui-well-border);\n border-radius: var(--ag-ui-radius);\n}\n\n.message {\n max-width: 80%;\n padding: var(--ag-ui-msg-pad);\n border-radius: var(--ag-ui-msg-radius);\n line-height: 1.4;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* \u2500\u2500 Incoming-text animations (data-text-animation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* .message--restored (rehydrated history) is excluded: entrance animations are\n for freshly-arriving messages, not the whole transcript replaying on reload.\n Word mode is excluded implicitly \u2014 restored bubbles aren't wrapped. */\n:host([data-text-animation=\"fade\"]) .message--assistant:not(.message--restored) {\n animation: ag-ui-msg-fade 0.25s ease both;\n}\n\n@keyframes ag-ui-msg-fade {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: none; }\n}\n\n.message--assistant .word {\n animation: ag-ui-word-in 0.3s ease both;\n animation-delay: calc(var(--ag-ui-word-index, 0) * 35ms);\n}\n\n@keyframes ag-ui-word-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host([data-text-animation=\"fade\"]) .message--assistant,\n .message--assistant .word {\n animation: none;\n }\n}\n\n.message--user {\n align-self: flex-end;\n background: var(--ag-ui-user-bg);\n color: var(--ag-ui-user-fg);\n border-bottom-right-radius: 4px;\n}\n\n.message--assistant {\n align-self: flex-start;\n background: var(--ag-ui-assistant-bg);\n border-bottom-left-radius: 4px;\n /* Assistant bubbles hold rendered markdown/HTML, so collapse the source\n whitespace the renderer leaves between block tags. */\n white-space: normal;\n}\n\n/* Rendered-markdown elements inside an assistant bubble. */\n.message--assistant > :first-child {\n margin-top: 0;\n}\n\n.message--assistant > :last-child {\n margin-bottom: 0;\n}\n\n.message--assistant p,\n.message--assistant ul,\n.message--assistant ol,\n.message--assistant blockquote,\n.message--assistant pre {\n margin: 0.5em 0;\n}\n\n.message--assistant ul,\n.message--assistant ol {\n padding-left: 1.3em;\n}\n\n.message--assistant a {\n color: var(--ag-ui-accent);\n text-decoration: underline;\n}\n\n.message--assistant code {\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n font-size: 0.92em;\n background: rgba(127, 127, 127, 0.16);\n padding: 1px 4px;\n border-radius: 4px;\n}\n\n.message--assistant pre {\n padding: 8px 10px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 6px;\n}\n\n.message--assistant pre code {\n background: none;\n padding: 0;\n}\n\n.message--assistant blockquote {\n padding-left: 10px;\n border-left: 3px solid var(--ag-ui-border);\n color: var(--ag-ui-muted);\n}\n\n.pending {\n align-self: flex-start;\n display: inline-flex;\n gap: 4px;\n align-items: center;\n padding: 12px 14px;\n background: var(--ag-ui-assistant-bg);\n border-radius: 14px;\n border-bottom-left-radius: 4px;\n}\n\n.pending-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--ag-ui-muted);\n animation: ag-ui-pending 1.2s infinite ease-in-out both;\n}\n\n.pending-dot:nth-child(2) {\n animation-delay: 0.16s;\n}\n\n.pending-dot:nth-child(3) {\n animation-delay: 0.32s;\n}\n\n@keyframes ag-ui-pending {\n 0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }\n 40% { opacity: 1; transform: translateY(-3px); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pending-dot {\n animation: none;\n opacity: 0.6;\n }\n}\n\n.tool-call {\n align-self: flex-start;\n max-width: 80%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--ag-ui-tool-bg);\n border: 1px solid var(--ag-ui-border);\n color: var(--ag-ui-tool-fg);\n}\n\n.tool-call-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.tool-call-name {\n flex: 1;\n min-width: 0;\n font-weight: 600;\n word-break: break-word;\n}\n\n/* Leading status icon (CARD-1). Empty in the DOM \u2014 the glyph/spinner is drawn\n here from the card's data-status, so it stays themeable. */\n.tool-call-icon {\n flex: none;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n font-size: 12px;\n line-height: 1;\n}\n\n/* Pending: a real spinning ring. Speed is tunable; reduced motion stops it. */\n.tool-call[data-status=\"pending\"] .tool-call-icon {\n border: 2px solid var(--ag-ui-muted);\n border-top-color: transparent;\n border-radius: 50%;\n animation: ag-ui-tool-spin var(--ag-ui-tool-spin-duration) linear infinite;\n}\n\n@keyframes ag-ui-tool-spin {\n to { transform: rotate(360deg); }\n}\n\n/* Settled: a themeable glyph coloured by outcome. */\n.tool-call[data-status=\"done\"] .tool-call-icon::before {\n content: var(--ag-ui-tool-icon-done);\n color: var(--ag-ui-success);\n}\n\n.tool-call[data-status=\"error\"] .tool-call-icon::before {\n content: var(--ag-ui-tool-icon-error);\n color: var(--ag-ui-danger);\n}\n\n.tool-call[data-status=\"declined\"] .tool-call-icon::before {\n content: var(--ag-ui-tool-icon-declined);\n color: var(--ag-ui-muted);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .tool-call[data-status=\"pending\"] .tool-call-icon {\n animation: none;\n }\n}\n\n/* Inline display mode (CARD-1): the lightest card \u2014 drop the box chrome so the\n status row reads as one line of the answer; the result toggle still expands\n below it. */\n.tool-call[data-display=\"inline\"] {\n max-width: 100%;\n background: transparent;\n border: none;\n padding: 2px 0;\n gap: 2px;\n}\n\n.tool-call-status {\n flex: none;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: rgba(127, 127, 127, 0.16);\n color: var(--ag-ui-muted);\n}\n\n.tool-call[data-status=\"done\"] .tool-call-status {\n color: var(--ag-ui-success);\n}\n\n.tool-call[data-status=\"error\"] .tool-call-status {\n color: var(--ag-ui-danger);\n}\n\n.tool-call[data-status=\"declined\"] .tool-call-status {\n color: var(--ag-ui-muted);\n}\n\n.tool-call-args,\n.tool-call-result {\n margin: 0;\n padding: 6px 8px;\n max-height: 160px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 6px;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--ag-ui-fg);\n}\n\n.tool-call-toggle {\n align-self: flex-start;\n border: none;\n padding: 0;\n background: none;\n font: inherit;\n font-weight: 600;\n color: var(--ag-ui-accent);\n cursor: pointer;\n}\n\n.tool-call-toggle::before {\n content: \"\u25B8 \";\n}\n\n.tool-call-toggle[aria-expanded=\"true\"]::before {\n content: \"\u25BE \";\n}\n\n.input-row {\n display: flex;\n gap: 8px;\n padding: 12px;\n border-top: 1px solid var(--ag-ui-border);\n}\n\n.input {\n flex: 1;\n resize: none;\n background: var(--ag-ui-input-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 8px 10px;\n font: inherit;\n color: inherit;\n outline: none;\n}\n\n.input:focus {\n border-color: var(--ag-ui-accent);\n}\n\n.send {\n border: none;\n border-radius: 8px;\n padding: 0 16px;\n background: var(--ag-ui-accent);\n color: #ffffff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.send:disabled {\n opacity: 0.5;\n cursor: default;\n}\n\n/* The composer button doubles as the Stop control while a run is in flight. */\n.send[data-state=\"running\"] {\n background: var(--ag-ui-muted);\n}\n\n/* \u2500\u2500 File attachments \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* The \uD83D\uDCCE picker button sits left of the input; hidden until data-attachments-url. */\n.attach-btn {\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 0 10px;\n background: var(--ag-ui-input-bg);\n color: inherit;\n font: inherit;\n cursor: pointer;\n}\n\n.attach-btn:hover {\n border-color: var(--ag-ui-accent);\n}\n\n.attach-input {\n display: none;\n}\n\n/* Pending-attachments tray, above the input row; collapses (hidden) when empty. */\n.attachment-slot {\n display: contents;\n}\n\n.attachment-tray {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 12px 0;\n}\n\n.attachment-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 6px;\n}\n\n.attachment-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: 100%;\n padding: 4px 8px;\n border: 1px solid var(--ag-ui-border);\n border-radius: 999px;\n background: var(--ag-ui-assistant-bg);\n font-size: 0.85em;\n position: relative;\n}\n\n.attachment-chip--error {\n border-color: var(--ag-ui-danger);\n color: var(--ag-ui-danger);\n}\n\n.attachment-chip-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 14ch;\n}\n\n.attachment-chip-size {\n color: var(--ag-ui-muted);\n white-space: nowrap;\n}\n\n.attachment-chip--error .attachment-chip-size {\n color: var(--ag-ui-danger);\n}\n\n/* The progress bar fills as the file uploads. */\n.attachment-chip-bar {\n flex-basis: 100%;\n height: 3px;\n border-radius: 2px;\n background: var(--ag-ui-border);\n overflow: hidden;\n}\n\n.attachment-chip-bar-fill {\n height: 100%;\n background: var(--ag-ui-accent);\n transition: width 0.15s ease;\n}\n\n.attachment-chip-remove,\n.attachment-chip-retry {\n border: none;\n background: none;\n color: inherit;\n cursor: pointer;\n padding: 0;\n line-height: 1;\n opacity: 0.7;\n}\n\n.attachment-chip-remove:hover,\n.attachment-chip-retry:hover {\n opacity: 1;\n}\n\n/* A subtle outline while a file is dragged over the shell. */\n.chat--dragover {\n outline: 2px dashed var(--ag-ui-accent);\n outline-offset: -4px;\n}\n\n/* Muted \"\u23F9 Stopped\" line after a cancelled run \u2014 a note, not an error bubble. */\n.stopped-note {\n align-self: flex-start;\n color: var(--ag-ui-muted);\n font-size: 12px;\n padding: 2px 4px;\n}\n\n/* Inline confirmation card \u2014 lives in the transcript, no focus-stealing overlay. */\n.confirm {\n align-self: stretch;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-accent);\n border-radius: 10px;\n}\n\n.confirm[data-resolved] {\n opacity: 0.7;\n border-color: var(--ag-ui-border);\n}\n\n.confirm-body {\n font-weight: 600;\n}\n\n.confirm-args {\n margin: 0;\n padding: 8px 10px;\n max-height: 140px;\n overflow: auto;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n background: var(--ag-ui-assistant-bg);\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n\n.confirm-btn {\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--ag-ui-bg);\n color: var(--ag-ui-fg);\n}\n\n.confirm-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n.confirm-btn--confirm {\n border-color: var(--ag-ui-accent);\n background: var(--ag-ui-accent);\n color: #ffffff;\n}\n\n/* Skills \u2014 chips row + the /-command palette, above the input. */\n.skill-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 10px 12px;\n}\n\n.skill-chip {\n border: 1px solid var(--ag-ui-border);\n border-radius: 999px;\n padding: 4px 12px;\n font: inherit;\n font-size: 0.9em;\n cursor: pointer;\n background: var(--ag-ui-assistant-bg);\n color: var(--ag-ui-fg);\n}\n\n.skill-chip:hover {\n border-color: var(--ag-ui-accent);\n}\n\n.skill-palette {\n margin: 8px 12px 0;\n display: flex;\n flex-direction: column;\n max-height: 220px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(20, 20, 50, 0.16);\n}\n\n.skill-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n align-items: flex-start;\n padding: 8px 12px;\n border: none;\n background: none;\n font: inherit;\n text-align: left;\n cursor: pointer;\n color: var(--ag-ui-fg);\n}\n\n.skill-item[aria-selected=\"true\"] {\n background: var(--ag-ui-assistant-bg);\n}\n\n.skill-item-title {\n font-weight: 600;\n}\n\n.skill-item-desc {\n font-size: 0.85em;\n color: var(--ag-ui-muted);\n}\n\n.skill-hint {\n margin: 8px 12px 0;\n font-size: 0.85em;\n color: var(--ag-ui-danger);\n}\n\n/* Chat-history drawer \u2014 a slide-over within the chat panel. */\n.drawer {\n position: absolute;\n inset: 0;\n z-index: 5;\n display: flex;\n}\n\n.drawer[hidden] {\n display: none;\n}\n\n.drawer-backdrop {\n position: absolute;\n inset: 0;\n background: rgba(20, 20, 50, 0.32);\n}\n\n.drawer-panel {\n position: relative;\n display: flex;\n flex-direction: column;\n width: min(300px, 85%);\n height: 100%;\n background: var(--ag-ui-bg);\n border-right: 1px solid var(--ag-ui-border);\n box-shadow: var(--ag-ui-shadow);\n overflow: hidden;\n}\n\n.drawer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--ag-ui-space);\n padding: var(--ag-ui-pad);\n border-bottom: 1px solid var(--ag-ui-border);\n}\n\n.drawer-title {\n font-weight: 600;\n}\n\n.drawer-new {\n border: 1px solid var(--ag-ui-border);\n border-radius: var(--ag-ui-radius);\n background: var(--ag-ui-bg);\n color: var(--ag-ui-accent);\n padding: 4px 10px;\n font: inherit;\n font-size: 0.85em;\n cursor: pointer;\n}\n\n.drawer-list {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}\n\n.drawer-empty {\n padding: var(--ag-ui-pad);\n font-size: 0.9em;\n color: var(--ag-ui-muted);\n}\n\n.drawer-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--ag-ui-border);\n}\n\n.drawer-row--active {\n background: var(--ag-ui-assistant-bg);\n}\n\n.drawer-row-select {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 8px 12px;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.drawer-row-title {\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.drawer-row-time {\n font-size: 0.72em;\n color: var(--ag-ui-muted);\n}\n\n.drawer-row-preview {\n font-size: 0.8em;\n color: var(--ag-ui-muted);\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.drawer-row-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 6px;\n}\n\n.drawer-row-rename,\n.drawer-row-delete {\n border: none;\n background: none;\n color: var(--ag-ui-muted);\n font-size: 0.9em;\n padding: 4px;\n cursor: pointer;\n}\n\n.drawer-rename-input {\n flex: 1;\n min-width: 0;\n margin: 6px 10px;\n padding: 4px 8px;\n border: 1px solid var(--ag-ui-accent);\n border-radius: 6px;\n background: var(--ag-ui-input-bg);\n color: var(--ag-ui-fg);\n font: inherit;\n}\n\n.drawer-confirm {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n font-size: 0.85em;\n}\n\n.drawer-confirm-label {\n color: var(--ag-ui-danger);\n}\n\n.drawer-confirm-yes {\n border: none;\n border-radius: 6px;\n background: var(--ag-ui-danger);\n color: #ffffff;\n padding: 3px 10px;\n font: inherit;\n cursor: pointer;\n}\n\n.drawer-confirm-no {\n border: 1px solid var(--ag-ui-border);\n border-radius: 6px;\n background: none;\n color: inherit;\n padding: 3px 10px;\n font: inherit;\n cursor: pointer;\n}\n\n/* Embedded placement: an inline, flush side panel rather than a dimmed,\n floating slide-over. */\n:host([placement=\"embedded\"]) .drawer-backdrop {\n background: none;\n}\n\n:host([placement=\"embedded\"]) .drawer-panel {\n width: 100%;\n border-right: none;\n box-shadow: none;\n}\n";
|
|
2
2
|
//# sourceMappingURL=styles.d.ts.map
|
package/dist/ui/styles.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/ui/styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/ui/styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,MAAM,st4BAqoClB,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ThreadMeta } from "../core/conversation_store.js";
|
|
2
|
+
import { type UiStrings } from "./ui_strings.js";
|
|
2
3
|
/** Actions the host ({@link AgUiChat}) wires to the drawer's rows. */
|
|
3
4
|
export interface ThreadDrawerCallbacks {
|
|
4
5
|
/** A row was picked — load that thread and make it active. */
|
|
@@ -17,12 +18,17 @@ export interface ThreadDrawerCallbacks {
|
|
|
17
18
|
* {@link element}, toggles it, feeds rows via {@link setThreads}, and acts on
|
|
18
19
|
* the callbacks. The drawer is a *view*: it does not mutate the store; after a
|
|
19
20
|
* callback the host updates the store and calls {@link setThreads} to refresh.
|
|
21
|
+
*
|
|
22
|
+
* All visible text comes from {@link UiStrings}; {@link setStrings} re-localizes
|
|
23
|
+
* a drawer the host built before its strings resolved.
|
|
20
24
|
*/
|
|
21
25
|
export declare class ThreadDrawer {
|
|
22
26
|
#private;
|
|
23
27
|
/** The drawer root (backdrop + panel). Append to the chat shell; hidden until opened. */
|
|
24
28
|
readonly element: HTMLDivElement;
|
|
25
|
-
constructor(callbacks: ThreadDrawerCallbacks);
|
|
29
|
+
constructor(callbacks: ThreadDrawerCallbacks, strings?: UiStrings);
|
|
30
|
+
/** Re-localize the drawer's chrome and rows (the host calls this on connect). */
|
|
31
|
+
setStrings(strings: UiStrings): void;
|
|
26
32
|
isOpen(): boolean;
|
|
27
33
|
open(): void;
|
|
28
34
|
close(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread_drawer.d.ts","sourceRoot":"","sources":["../../src/ui/thread_drawer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"thread_drawer.d.ts","sourceRoot":"","sources":["../../src/ui/thread_drawer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAErE,sEAAsE;AACtE,MAAM,WAAW,qBAAqB;IACpC,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;GAUG;AACH,qBAAa,YAAY;;IACvB,yFAAyF;IACzF,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;gBAWrB,SAAS,EAAE,qBAAqB,EAAE,OAAO,GAAE,SAA8B;IA8CrF,iFAAiF;IACjF,UAAU,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI;IAQpC,MAAM,IAAI,OAAO;IAIjB,IAAI,IAAI,IAAI;IAIZ,KAAK,IAAI,IAAI;IAIb,MAAM,IAAI,IAAI;IAId,4EAA4E;IAC5E,UAAU,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAmHnE"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TOOL_CALL_STATUS, TOOL_DISPLAY } from "../constants.js";
|
|
2
|
+
import { type UiStrings } from "./ui_strings.js";
|
|
2
3
|
/** Any state a tool-call card can be in. */
|
|
3
4
|
export type ToolCallStatus = (typeof TOOL_CALL_STATUS)[keyof typeof TOOL_CALL_STATUS];
|
|
4
5
|
/** How much detail a card renders. */
|
|
@@ -8,27 +9,37 @@ export type SettledStatus = Exclude<ToolCallStatus, typeof TOOL_CALL_STATUS.PEND
|
|
|
8
9
|
/**
|
|
9
10
|
* A live tool-call card for the chat transcript.
|
|
10
11
|
*
|
|
11
|
-
* Construction renders the tool name and a `running…` status
|
|
12
|
-
* mode it also shows the pretty-printed arguments inline.
|
|
13
|
-
* flips the pill to the outcome and — depending on the
|
|
14
|
-
* appends a collapsible body:
|
|
12
|
+
* Construction renders a status icon, the tool name, and a `running…` status
|
|
13
|
+
* pill; in `full` mode it also shows the pretty-printed arguments inline.
|
|
14
|
+
* {@link settle} later flips the pill to the outcome and — depending on the
|
|
15
|
+
* {@link ToolDisplayMode} — appends a collapsible body:
|
|
15
16
|
*
|
|
17
|
+
* - `inline` — no args; the result behind its own toggle (like `full` but with
|
|
18
|
+
* the card chrome stripped to a single light row).
|
|
16
19
|
* - `minimal` — pill only; nothing to expand.
|
|
17
20
|
* - `compact` — one "Details" toggle revealing args *and* result together.
|
|
18
21
|
* - `full` — the result (or error / decline message) behind its own toggle.
|
|
19
22
|
*
|
|
23
|
+
* The leading icon carries no text of its own: its glyph/spinner is drawn by
|
|
24
|
+
* the shadow CSS keyed off the card's `data-status`, so a host themes it via
|
|
25
|
+
* the `--ag-ui-tool-icon-*` custom properties (or the `tool-card-icon` part)
|
|
26
|
+
* without the card reaching into the host stylesheet.
|
|
27
|
+
*
|
|
20
28
|
* Pure DOM (no framework); the host appends {@link element} into its shadow
|
|
21
|
-
* root and themes it via the `--ag-ui-*` custom properties
|
|
29
|
+
* root and themes it via the `--ag-ui-*` custom properties or the exposed
|
|
30
|
+
* `tool-card*` `part`s. All visible text is sourced from {@link UiStrings}.
|
|
22
31
|
*/
|
|
23
32
|
export declare class ToolCallCard {
|
|
24
33
|
#private;
|
|
25
34
|
/** The card's root element; append this into the message list. */
|
|
26
35
|
readonly element: HTMLDivElement;
|
|
27
|
-
constructor(name: string, args: Record<string, unknown>, mode?: ToolDisplayMode, summary?: string);
|
|
36
|
+
constructor(name: string, args: Record<string, unknown>, mode?: ToolDisplayMode, summary?: string, strings?: UiStrings);
|
|
37
|
+
/** Whether {@link settle} has already run (so a terminal sweep can skip it). */
|
|
38
|
+
get settled(): boolean;
|
|
28
39
|
/**
|
|
29
40
|
* Flip the status pill to ``status`` and, unless in `minimal` mode, append a
|
|
30
|
-
* collapsed body behind a click-to-expand toggle: the result alone (`full`
|
|
31
|
-
* or the args + result together (`compact`).
|
|
41
|
+
* collapsed body behind a click-to-expand toggle: the result alone (`full` /
|
|
42
|
+
* `inline`), or the args + result together (`compact`).
|
|
32
43
|
*/
|
|
33
44
|
settle(status: SettledStatus, text: string): void;
|
|
34
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool_call_card.d.ts","sourceRoot":"","sources":["../../src/ui/tool_call_card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"tool_call_card.d.ts","sourceRoot":"","sources":["../../src/ui/tool_call_card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAErE,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAEtF,sCAAsC;AACtC,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE/E,0EAA0E;AAC1E,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,EAAE,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAqBrF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,YAAY;;IACvB,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;gBAS/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,GAAE,eAAmC,EACzC,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,GAAE,SAA8B;IAgDzC,gFAAgF;IAChF,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;CAoClD"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The flat table of every user-facing string the chat shell renders — labels,
|
|
3
|
+
* placeholders, `aria-label`s, and `title` tooltips. A localizable seam, not a
|
|
4
|
+
* framework: a host overrides any subset (via the element's `strings` property
|
|
5
|
+
* or its `data-strings` JSON attribute) and the rest fall back to the English
|
|
6
|
+
* defaults.
|
|
7
|
+
*
|
|
8
|
+
* A handful of values are **templates** carrying `{token}` placeholders the call
|
|
9
|
+
* site fills in (e.g. `minutesAgo` → `"{n}m ago"`); the token names are noted on
|
|
10
|
+
* each key. Translators keep the token verbatim.
|
|
11
|
+
*
|
|
12
|
+
* This module is one cohesive unit — the `UiStrings` shape, its `DEFAULT_UI_STRINGS`
|
|
13
|
+
* constant-like backing, and the {@link mergeUiStrings} merge over those defaults —
|
|
14
|
+
* so it bends the one-symbol-per-file rule the way `tool_call_card.ts` (class +
|
|
15
|
+
* its types) and `route_map.ts` (factory + its types) already do.
|
|
16
|
+
*/
|
|
17
|
+
export interface UiStrings {
|
|
18
|
+
/** Default header title (the `title-text` attribute overrides per element). */
|
|
19
|
+
title: string;
|
|
20
|
+
/** History button + drawer dialog label. */
|
|
21
|
+
chatHistory: string;
|
|
22
|
+
/** New-chat button (header + drawer). */
|
|
23
|
+
newChat: string;
|
|
24
|
+
/** Collapse button. */
|
|
25
|
+
collapse: string;
|
|
26
|
+
/** Expand affordance (the sidebar rail toggle). */
|
|
27
|
+
expand: string;
|
|
28
|
+
/** `aria-label` of the scrolling message log. */
|
|
29
|
+
conversation: string;
|
|
30
|
+
/** `aria-label` of the "thinking" pending indicator. */
|
|
31
|
+
thinking: string;
|
|
32
|
+
/** The muted note after a cancelled run. */
|
|
33
|
+
stopped: string;
|
|
34
|
+
/** Error shown when the stream drops without a terminal AG-UI event. */
|
|
35
|
+
connectionLost: string;
|
|
36
|
+
/** Fallback when a tool call produced no result. */
|
|
37
|
+
noResult: string;
|
|
38
|
+
/** Tool-result content when the user declines a confirmed action. */
|
|
39
|
+
declinedAction: string;
|
|
40
|
+
/** A navigating tool's card text while the page reloads. */
|
|
41
|
+
navigating: string;
|
|
42
|
+
/** Missing-placeholder skill hint. Tokens: `{title}`, `{fields}`. */
|
|
43
|
+
skillNeeds: string;
|
|
44
|
+
/** `aria-label` of the message textarea. */
|
|
45
|
+
message: string;
|
|
46
|
+
/** Placeholder of the message textarea. */
|
|
47
|
+
inputPlaceholder: string;
|
|
48
|
+
/** Send button (idle composer). */
|
|
49
|
+
send: string;
|
|
50
|
+
/** Stop button (composer while a run is in flight). */
|
|
51
|
+
stop: string;
|
|
52
|
+
/** Attach-files button. */
|
|
53
|
+
attachFiles: string;
|
|
54
|
+
/** Status pill while the call runs. */
|
|
55
|
+
toolRunning: string;
|
|
56
|
+
/** Status pill on success. */
|
|
57
|
+
toolDone: string;
|
|
58
|
+
/** Status pill on error. */
|
|
59
|
+
toolError: string;
|
|
60
|
+
/** Status pill on a declined call. */
|
|
61
|
+
toolDeclined: string;
|
|
62
|
+
/** Toggle label revealing a successful result (full mode). */
|
|
63
|
+
resultLabel: string;
|
|
64
|
+
/** Toggle label revealing an error (full mode). */
|
|
65
|
+
errorLabel: string;
|
|
66
|
+
/** Toggle label revealing a declined call (full mode). */
|
|
67
|
+
declinedLabel: string;
|
|
68
|
+
/** Toggle label revealing args + result together (compact mode). */
|
|
69
|
+
details: string;
|
|
70
|
+
/** `aria-label` of the inline confirmation card. */
|
|
71
|
+
confirmAction: string;
|
|
72
|
+
/** Generic confirmation prompt when a tool has no `x-confirm`. Token: `{tool}`. */
|
|
73
|
+
confirmRun: string;
|
|
74
|
+
/** Confirm button. */
|
|
75
|
+
confirm: string;
|
|
76
|
+
/** Cancel button (confirmation + delete confirm). */
|
|
77
|
+
cancel: string;
|
|
78
|
+
/** Drawer heading. */
|
|
79
|
+
chats: string;
|
|
80
|
+
/** Empty-state line when there are no threads. */
|
|
81
|
+
noConversations: string;
|
|
82
|
+
/** Rename row button (`title`). */
|
|
83
|
+
rename: string;
|
|
84
|
+
/** Rename row button `aria-label`. */
|
|
85
|
+
renameConversation: string;
|
|
86
|
+
/** Delete row button (`title`) + the inline-confirm action. */
|
|
87
|
+
delete: string;
|
|
88
|
+
/** Delete row button `aria-label`. */
|
|
89
|
+
deleteConversation: string;
|
|
90
|
+
/** Inline delete-confirm prompt. */
|
|
91
|
+
deletePrompt: string;
|
|
92
|
+
/** Oversize rejection. Token: `{size}`. */
|
|
93
|
+
tooLarge: string;
|
|
94
|
+
/** Disallowed-type rejection. */
|
|
95
|
+
fileTypeNotAllowed: string;
|
|
96
|
+
/** Generic upload failure (when the error carries no message). */
|
|
97
|
+
uploadFailed: string;
|
|
98
|
+
/** Retry-upload button (`title`). */
|
|
99
|
+
retry: string;
|
|
100
|
+
/** Retry-upload button `aria-label`. */
|
|
101
|
+
retryUpload: string;
|
|
102
|
+
/** Remove-attachment button (`title`). */
|
|
103
|
+
remove: string;
|
|
104
|
+
/** Remove-attachment button `aria-label`. */
|
|
105
|
+
removeAttachment: string;
|
|
106
|
+
/** Under a minute ago. */
|
|
107
|
+
justNow: string;
|
|
108
|
+
/** Minutes ago. Token: `{n}`. */
|
|
109
|
+
minutesAgo: string;
|
|
110
|
+
/** Hours ago. Token: `{n}`. */
|
|
111
|
+
hoursAgo: string;
|
|
112
|
+
/** Days ago. Token: `{n}`. */
|
|
113
|
+
daysAgo: string;
|
|
114
|
+
/** Weeks ago. Token: `{n}`. */
|
|
115
|
+
weeksAgo: string;
|
|
116
|
+
}
|
|
117
|
+
/** The built-in English strings — the fallback every override merges over. */
|
|
118
|
+
export declare const DEFAULT_UI_STRINGS: UiStrings;
|
|
119
|
+
/**
|
|
120
|
+
* Merge a partial set of overrides over {@link DEFAULT_UI_STRINGS}, yielding a
|
|
121
|
+
* complete {@link UiStrings}. Keys whose override is `undefined` keep the
|
|
122
|
+
* default (so a `data-strings` JSON with only a few keys — or a property carrying
|
|
123
|
+
* explicit `undefined` — leaves the rest English).
|
|
124
|
+
*/
|
|
125
|
+
export declare function mergeUiStrings(overrides: Partial<UiStrings>): UiStrings;
|
|
126
|
+
//# sourceMappingURL=ui_strings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui_strings.d.ts","sourceRoot":"","sources":["../../src/ui/ui_strings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,SAAS;IAExB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IAGf,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IAGnB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,gBAAgB,EAAE,MAAM,CAAC;IACzB,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IAGpB,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAGhB,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,mFAAmF;IACnF,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IAGf,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,eAAe,EAAE,MAAM,CAAC;IACxB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IAGrB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,gBAAgB,EAAE,MAAM,CAAC;IAGzB,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,EAAE,SAyDhC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CASvE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artooi/ag-ui-web-component",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Framework-free <ag-ui-chat> Web Component over the AG-UI protocol. Drop-in chat sidebar with a pluggable client-side tool registry, DOM driver primitives, animations, and destructive-action confirmation modal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
package/src/constants.ts
CHANGED
|
@@ -92,12 +92,17 @@ export const DEFAULT_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;
|
|
|
92
92
|
* How much detail a tool-call card shows. Set via the `data-tool-display`
|
|
93
93
|
* attribute on `<ag-ui-chat>`; defaults to `full` (back-compatible).
|
|
94
94
|
*
|
|
95
|
+
* - `inline` — the lightest mode: a single status row (icon + summary) with no
|
|
96
|
+
* surrounding card chrome, the result tucked behind its own toggle. Reads as
|
|
97
|
+
* one line of the answer rather than a boxed card — pairs with the answer
|
|
98
|
+
* well (page mode).
|
|
95
99
|
* - `minimal` — just the tool name + status pill. No args, no result body.
|
|
96
100
|
* - `compact` — name + status, with args *and* result tucked behind a single
|
|
97
101
|
* collapsed "Details" toggle. The light default for dense UIs.
|
|
98
102
|
* - `full` — args shown inline, result behind its own toggle (the original).
|
|
99
103
|
*/
|
|
100
104
|
export const TOOL_DISPLAY = {
|
|
105
|
+
INLINE: "inline",
|
|
101
106
|
MINIMAL: "minimal",
|
|
102
107
|
COMPACT: "compact",
|
|
103
108
|
FULL: "full",
|