@artooi/ag-ui-web-component 0.44.0 → 0.46.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 +182 -1
- package/README.md +245 -32
- package/dist/ag-ui-web-component.bundle.js +3696 -2798
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +4 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts +28 -8
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/core/read_flag.d.ts +11 -0
- package/dist/core/read_flag.d.ts.map +1 -0
- package/dist/core/read_json_attribute.d.ts +15 -0
- package/dist/core/read_json_attribute.d.ts.map +1 -0
- package/dist/index.js +5084 -3481
- package/dist/index.js.map +4 -4
- package/dist/tools/tool_catalog.d.ts +5 -0
- package/dist/tools/tool_catalog.d.ts.map +1 -1
- package/dist/tools/tool_dispatch.d.ts.map +1 -1
- package/dist/ui/charts/chart_styles.d.ts +2 -0
- package/dist/ui/charts/chart_styles.d.ts.map +1 -0
- package/dist/ui/composer/attachment_styles.d.ts +2 -0
- package/dist/ui/composer/attachment_styles.d.ts.map +1 -0
- package/dist/ui/composer/build_composer.d.ts +30 -0
- package/dist/ui/composer/build_composer.d.ts.map +1 -0
- package/dist/ui/composer/composer_styles.d.ts +2 -0
- package/dist/ui/composer/composer_styles.d.ts.map +1 -0
- package/dist/ui/composer/skill_styles.d.ts +2 -0
- package/dist/ui/composer/skill_styles.d.ts.map +1 -0
- package/dist/ui/history/history_styles.d.ts +2 -0
- package/dist/ui/history/history_styles.d.ts.map +1 -0
- package/dist/ui/interrupts/approval_styles.d.ts +2 -0
- package/dist/ui/interrupts/approval_styles.d.ts.map +1 -0
- package/dist/ui/interrupts/confirmation_styles.d.ts +2 -0
- package/dist/ui/interrupts/confirmation_styles.d.ts.map +1 -0
- package/dist/ui/interrupts/question_styles.d.ts +2 -0
- package/dist/ui/interrupts/question_styles.d.ts.map +1 -0
- package/dist/ui/placement/collapse_styles.d.ts +2 -0
- package/dist/ui/placement/collapse_styles.d.ts.map +1 -0
- package/dist/ui/placement/embedded_styles.d.ts +2 -0
- package/dist/ui/placement/embedded_styles.d.ts.map +1 -0
- package/dist/ui/placement/launcher_styles.d.ts +2 -0
- package/dist/ui/placement/launcher_styles.d.ts.map +1 -0
- package/dist/ui/placement/page_styles.d.ts +2 -0
- package/dist/ui/placement/page_styles.d.ts.map +1 -0
- package/dist/ui/placement/panel_placement.d.ts.map +1 -1
- package/dist/ui/placement/preset_styles.d.ts +2 -0
- package/dist/ui/placement/preset_styles.d.ts.map +1 -0
- package/dist/ui/placement/resize_styles.d.ts +2 -0
- package/dist/ui/placement/resize_styles.d.ts.map +1 -0
- package/dist/ui/placement/sidebar_styles.d.ts +2 -0
- package/dist/ui/placement/sidebar_styles.d.ts.map +1 -0
- package/dist/ui/placement/small_viewport_styles.d.ts +2 -0
- package/dist/ui/placement/small_viewport_styles.d.ts.map +1 -0
- package/dist/ui/placement/surface_for.d.ts +74 -0
- package/dist/ui/placement/surface_for.d.ts.map +1 -0
- package/dist/ui/progress/run_notice_styles.d.ts +2 -0
- package/dist/ui/progress/run_notice_styles.d.ts.map +1 -0
- package/dist/ui/progress/thoughts_styles.d.ts +2 -0
- package/dist/ui/progress/thoughts_styles.d.ts.map +1 -0
- package/dist/ui/progress/tool_call_card.d.ts +8 -0
- package/dist/ui/progress/tool_call_card.d.ts.map +1 -1
- package/dist/ui/progress/tool_group_styles.d.ts +2 -0
- package/dist/ui/progress/tool_group_styles.d.ts.map +1 -0
- package/dist/ui/progress/tool_step_group.d.ts +47 -0
- package/dist/ui/progress/tool_step_group.d.ts.map +1 -0
- package/dist/ui/progress/tool_step_styles.d.ts +2 -0
- package/dist/ui/progress/tool_step_styles.d.ts.map +1 -0
- package/dist/ui/shell/adopt_styles.d.ts +9 -4
- package/dist/ui/shell/adopt_styles.d.ts.map +1 -1
- package/dist/ui/shell/build_header.d.ts +40 -0
- package/dist/ui/shell/build_header.d.ts.map +1 -0
- package/dist/ui/shell/build_launcher.d.ts +20 -0
- package/dist/ui/shell/build_launcher.d.ts.map +1 -0
- package/dist/ui/shell/frame_styles.d.ts +2 -0
- package/dist/ui/shell/frame_styles.d.ts.map +1 -0
- package/dist/ui/shell/theme_styles.d.ts +2 -0
- package/dist/ui/shell/theme_styles.d.ts.map +1 -0
- package/dist/ui/shell/token_styles.d.ts +2 -0
- package/dist/ui/shell/token_styles.d.ts.map +1 -0
- package/dist/ui/styles.d.ts +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/dist/ui/themes/classic_styles.d.ts +2 -0
- package/dist/ui/themes/classic_styles.d.ts.map +1 -0
- package/dist/ui/themes/classic_tokens.d.ts +2 -0
- package/dist/ui/themes/classic_tokens.d.ts.map +1 -0
- package/dist/ui/themes/code_tokens.d.ts +2 -0
- package/dist/ui/themes/code_tokens.d.ts.map +1 -0
- package/dist/ui/themes/ledger_styles.d.ts +2 -0
- package/dist/ui/themes/ledger_styles.d.ts.map +1 -0
- package/dist/ui/themes/ledger_tokens.d.ts +2 -0
- package/dist/ui/themes/ledger_tokens.d.ts.map +1 -0
- package/dist/ui/themes/modern_styles.d.ts +2 -0
- package/dist/ui/themes/modern_styles.d.ts.map +1 -0
- package/dist/ui/themes/quiet_styles.d.ts +2 -0
- package/dist/ui/themes/quiet_styles.d.ts.map +1 -0
- package/dist/ui/themes/scheme_styles.d.ts +2 -0
- package/dist/ui/themes/scheme_styles.d.ts.map +1 -0
- package/dist/ui/themes/soft_styles.d.ts +2 -0
- package/dist/ui/themes/soft_styles.d.ts.map +1 -0
- package/dist/ui/themes/soft_tokens.d.ts +2 -0
- package/dist/ui/themes/soft_tokens.d.ts.map +1 -0
- package/dist/ui/themes/theme_hosts.d.ts +15 -0
- package/dist/ui/themes/theme_hosts.d.ts.map +1 -0
- package/dist/ui/transcript/attachment_chip_styles.d.ts +2 -0
- package/dist/ui/transcript/attachment_chip_styles.d.ts.map +1 -0
- package/dist/ui/transcript/build_transcript.d.ts +21 -0
- package/dist/ui/transcript/build_transcript.d.ts.map +1 -0
- package/dist/ui/transcript/greeting_styles.d.ts +2 -0
- package/dist/ui/transcript/greeting_styles.d.ts.map +1 -0
- package/dist/ui/transcript/groups_tool_steps.d.ts +13 -0
- package/dist/ui/transcript/groups_tool_steps.d.ts.map +1 -0
- package/dist/ui/transcript/message_action_styles.d.ts +2 -0
- package/dist/ui/transcript/message_action_styles.d.ts.map +1 -0
- package/dist/ui/transcript/message_styles.d.ts +2 -0
- package/dist/ui/transcript/message_styles.d.ts.map +1 -0
- package/dist/ui/transcript/transcript.d.ts +16 -1
- package/dist/ui/transcript/transcript.d.ts.map +1 -1
- package/dist/ui/transcript/transcript_styles.d.ts +2 -0
- package/dist/ui/transcript/transcript_styles.d.ts.map +1 -0
- package/dist/ui/ui_strings.d.ts +18 -0
- package/dist/ui/ui_strings.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/constants.ts +4 -1
- package/src/core/ag_ui_chat.ts +164 -299
- package/src/core/read_flag.ts +13 -0
- package/src/core/read_json_attribute.ts +30 -0
- package/src/tools/tool_catalog.ts +23 -10
- package/src/tools/tool_dispatch.ts +26 -11
- package/src/ui/charts/chart_block.ts +9 -9
- package/src/ui/charts/chart_styles.ts +63 -0
- package/src/ui/composer/attachment_styles.ts +71 -0
- package/src/ui/composer/build_composer.ts +112 -0
- package/src/ui/composer/composer_styles.ts +174 -0
- package/src/ui/composer/skill_styles.ts +120 -0
- package/src/ui/history/history_styles.ts +484 -0
- package/src/ui/interrupts/approval_styles.ts +52 -0
- package/src/ui/interrupts/confirmation_styles.ts +114 -0
- package/src/ui/interrupts/question_styles.ts +73 -0
- package/src/ui/placement/collapse_styles.ts +137 -0
- package/src/ui/placement/embedded_styles.ts +14 -0
- package/src/ui/placement/launcher_styles.ts +189 -0
- package/src/ui/placement/page_styles.ts +47 -0
- package/src/ui/placement/panel_placement.ts +3 -12
- package/src/ui/placement/preset_styles.ts +33 -0
- package/src/ui/placement/resize_styles.ts +186 -0
- package/src/ui/placement/sidebar_styles.ts +88 -0
- package/src/ui/placement/small_viewport_styles.ts +56 -0
- package/src/ui/placement/surface_for.ts +135 -0
- package/src/ui/progress/run_notice_styles.ts +52 -0
- package/src/ui/progress/thoughts_styles.ts +65 -0
- package/src/ui/progress/tool_call_card.ts +11 -0
- package/src/ui/progress/tool_group_styles.ts +232 -0
- package/src/ui/progress/tool_step_group.ts +269 -0
- package/src/ui/progress/tool_step_styles.ts +472 -0
- package/src/ui/shell/adopt_styles.ts +11 -5
- package/src/ui/shell/build_header.ts +108 -0
- package/src/ui/shell/build_launcher.ts +50 -0
- package/src/ui/shell/frame_styles.ts +119 -0
- package/src/ui/shell/theme_styles.ts +11 -0
- package/src/ui/shell/token_styles.ts +406 -0
- package/src/ui/styles.ts +104 -3774
- package/src/ui/themes/classic_styles.ts +32 -0
- package/src/ui/themes/classic_tokens.ts +50 -0
- package/src/ui/themes/code_tokens.ts +21 -0
- package/src/ui/themes/ledger_styles.ts +168 -0
- package/src/ui/themes/ledger_tokens.ts +32 -0
- package/src/ui/themes/modern_styles.ts +80 -0
- package/src/ui/themes/quiet_styles.ts +115 -0
- package/src/ui/themes/scheme_styles.ts +17 -0
- package/src/ui/themes/soft_styles.ts +148 -0
- package/src/ui/themes/soft_tokens.ts +28 -0
- package/src/ui/themes/theme_hosts.ts +14 -0
- package/src/ui/transcript/attachment_chip_styles.ts +116 -0
- package/src/ui/transcript/build_transcript.ts +67 -0
- package/src/ui/transcript/greeting_styles.ts +171 -0
- package/src/ui/transcript/groups_tool_steps.ts +16 -0
- package/src/ui/transcript/message_action_styles.ts +155 -0
- package/src/ui/transcript/message_styles.ts +262 -0
- package/src/ui/transcript/transcript.ts +109 -3
- package/src/ui/transcript/transcript_styles.ts +140 -0
- package/src/ui/ui_strings.ts +31 -0
- package/src/version.ts +1 -1
- package/dist/ui/placement/is_collapsible_placement.d.ts +0 -18
- package/dist/ui/placement/is_collapsible_placement.d.ts.map +0 -1
- package/dist/ui/placement/is_draggable_placement.d.ts +0 -9
- package/dist/ui/placement/is_draggable_placement.d.ts.map +0 -1
- package/src/ui/placement/is_collapsible_placement.ts +0 -19
- package/src/ui/placement/is_draggable_placement.ts +0 -23
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,185 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.46.0] — 2026-11-05
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Tool calls fold into a step group by default.** `data-tool-display`
|
|
15
|
+
gains `grouped`, and it is the new default (also for an absent or unknown
|
|
16
|
+
value). A run's consecutive tool calls fold into one quiet row, "Worked
|
|
17
|
+
through 5 steps", with a note such as "1 failed", and the per-call cards one
|
|
18
|
+
click down as `full` cards. Anything else in the turn ends the group, except
|
|
19
|
+
a call's own rendered output. **No
|
|
20
|
+
opt-in is needed, and a host that wants the old per-call cards opts out with
|
|
21
|
+
`data-tool-display="full"`**; `inline`, `minimal`, `compact` and `full`
|
|
22
|
+
render exactly as in 0.45.0. Grouping is the same under every theme; Soft
|
|
23
|
+
draws the row as a tinted pill and Ledger as a monospace heading.
|
|
24
|
+
- The group opens itself while a step waits on the user (a server-side
|
|
25
|
+
approval, which renders inside its card), once per wait; the user can
|
|
26
|
+
fold it again. It opens before the approval is drawn, so the Approve
|
|
27
|
+
button takes focus and scrolls into view, as it does under `full`. A
|
|
28
|
+
client-side confirmation or an `ask_user` question renders beside the
|
|
29
|
+
group and is in view without it opening, and the row reads "waiting for
|
|
30
|
+
you" for as long as one is open rather than "running".
|
|
31
|
+
- A running sub-agent does not open it: the folded row keeps its spinner
|
|
32
|
+
and names the delegation ("Delegated to researcher").
|
|
33
|
+
- Repeated labels are told apart inside a group, "Fill field" then "Fill
|
|
34
|
+
field (2)", in an element of its own; `tool-card-name` is never rewritten.
|
|
35
|
+
- A tool's rendered output (a chart) is placed after the group, in call
|
|
36
|
+
order, so it is never folded away, and a later call still joins the
|
|
37
|
+
group above it.
|
|
38
|
+
- Grouping is decided as each card is built. Switching to `grouped` folds
|
|
39
|
+
only calls drawn afterwards; switching to a card mode flattens existing
|
|
40
|
+
groups by CSS into the cards that mode builds.
|
|
41
|
+
- A restored conversation folds the same way as the live one.
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- Parts `tool-group`, `tool-group-head`, `tool-group-icon`,
|
|
46
|
+
`tool-group-label`, `tool-group-meta`, `tool-group-list`, and
|
|
47
|
+
`tool-card-repeat` on a repeated step.
|
|
48
|
+
- The `--ag-ui-ring` token (the group head's focus outline) and the
|
|
49
|
+
`--ag-ui-ico-chevron` mask image (its disclosure chevron).
|
|
50
|
+
- Strings `toolGroupSteps`, `toolGroupWorking`, `toolGroupWorked`,
|
|
51
|
+
`toolGroupWaiting`, `toolGroupFailed`, `toolGroupDeclined` (`{count}`) and
|
|
52
|
+
`toolStepRepeat` (`{n}`).
|
|
53
|
+
- `TOOL_DISPLAY.GROUPED`.
|
|
54
|
+
- A `data-asking` attribute on a tool-call card while a question or a
|
|
55
|
+
confirmation is open on it. It is internal, read by the step group; the
|
|
56
|
+
card's `data-status` is unchanged.
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- **The wheel scrolls the transcript when the pointer rests on a tool call's
|
|
61
|
+
arguments or result, a code block, the reasoning or a confirmation's
|
|
62
|
+
arguments.** Those blocks swallowed the wheel even when they had nothing
|
|
63
|
+
left to scroll, so the transcript sat still until the pointer moved to plain
|
|
64
|
+
text. They now hand the wheel on to the transcript, including a wheel that
|
|
65
|
+
carries a little sideways motion, as a real mouse or trackpad nearly always
|
|
66
|
+
does. This is long-standing and needs no opt-in.
|
|
67
|
+
|
|
68
|
+
## [0.45.0] — 2026-11-05
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
|
|
72
|
+
- **A theme set.** `theme` is now up to two words in any order, a theme name
|
|
73
|
+
and a scheme, matched as words: `soft`, `soft dark`, `ledger auto`. The
|
|
74
|
+
names are `quiet` (the new default), `soft` (rounded, tinted from the
|
|
75
|
+
accent), `ledger` (dense, serif and monospace) and `classic` (the look
|
|
76
|
+
before this release). The schemes are `light` (the default), `dark` and
|
|
77
|
+
`auto`, which follows `prefers-color-scheme`. A word the component does not
|
|
78
|
+
ship adds no rules, so `theme="acme"` is Quiet and a hook for the host's own
|
|
79
|
+
`[theme~="acme"]` CSS, and `soft acme` starts from Soft.
|
|
80
|
+
- **Three seeds theme everything.** Each theme declares `--ag-ui-bg`,
|
|
81
|
+
`--ag-ui-fg` and `--ag-ui-accent` with `light-dark()`, and every other colour
|
|
82
|
+
is mixed from them in oklch while still reading its own public token first.
|
|
83
|
+
New tokens: `--ag-ui-ink-2`, `--ag-ui-ink-3`, `--ag-ui-line`,
|
|
84
|
+
`--ag-ui-line-strong`, `--ag-ui-wash`, `--ag-ui-accent-ink`, `--ag-ui-tint`,
|
|
85
|
+
`--ag-ui-tint-2`, the type scale `--ag-ui-text-xs` to `--ag-ui-text-lg`,
|
|
86
|
+
`--ag-ui-leading`, `--ag-ui-serif`, `--ag-ui-frame-radius`,
|
|
87
|
+
`--ag-ui-frame-shadow`, and the status masks `--ag-ui-ico-check`,
|
|
88
|
+
`--ag-ui-ico-error` and `--ag-ui-ico-declined`.
|
|
89
|
+
- **`extraStyles` (unstable).** A per-element `CSSStyleSheet[]` adopted after
|
|
90
|
+
the built-in sheet, for structure the tokens and parts cannot reach. It
|
|
91
|
+
works under a strict `style-src` CSP. It reaches class names inside the
|
|
92
|
+
shadow root, which are not a stable API and may change in any minor release.
|
|
93
|
+
- **Text on the accent follows the accent.** Unless `--ag-ui-on-accent` is
|
|
94
|
+
set, it is white or black by the accent's luminance, whichever contrasts
|
|
95
|
+
more, where relative colour syntax is supported (Chrome 119, Firefox 128,
|
|
96
|
+
Safari 18). Firefox 120 to 127 and Safari 17.5 and 17.6 cannot compute it
|
|
97
|
+
and keep a fixed colour: white under `classic` and `code`, as before, and
|
|
98
|
+
the scheme's colour (white light, `#111111` dark) under `quiet`, `soft`
|
|
99
|
+
and `ledger`. Every built-in accent but `code`'s gets the same side either
|
|
100
|
+
way; a host's mid-tone accent there needs `--ag-ui-on-accent` set by hand.
|
|
101
|
+
|
|
102
|
+
### Changed
|
|
103
|
+
|
|
104
|
+
- **The default look changes for every host that sets no `theme`.** The
|
|
105
|
+
default is now Quiet: a neutral panel with the header on the panel itself,
|
|
106
|
+
no bubble for the agent's turn, status as an icon rather than a pill, its
|
|
107
|
+
own font stack instead of the page's, and a 48px launcher. `theme="dark"`
|
|
108
|
+
is Quiet in the dark scheme. **A host that wants the old look must opt in
|
|
109
|
+
with `theme="classic"`** (or `theme="classic dark"`); explicitly set tokens
|
|
110
|
+
keep working under every theme. Set `--ag-ui-font: inherit` to keep the
|
|
111
|
+
page's font under any theme.
|
|
112
|
+
- **A host that sets only `--ag-ui-accent` loses the accent header,
|
|
113
|
+
launcher and tool names.** Quiet draws them in the panel's own colours,
|
|
114
|
+
and its user bubble is the accent at 12% rather than the fixed indigo it
|
|
115
|
+
was. To get them back, opt in with `theme="classic"`, or keep Quiet and
|
|
116
|
+
set `--ag-ui-header-bg`, `--ag-ui-launcher-bg` and `--ag-ui-tool-fg` to
|
|
117
|
+
the accent and `--ag-ui-header-fg` and `--ag-ui-launcher-fg` to the
|
|
118
|
+
colour on it.
|
|
119
|
+
- **One chip row and one action row per answer**, under every theme but
|
|
120
|
+
`classic` and `code`. The skill chips show on the empty state only and,
|
|
121
|
+
once a message is sent, live in the slash palette alone. In an answer
|
|
122
|
+
that spans several bubbles (text, a tool call, more text), only the last
|
|
123
|
+
bubble keeps its copy, retry and feedback row.
|
|
124
|
+
- **`ledger` replaces `code`.** `theme="code"` keeps working but is no
|
|
125
|
+
longer documented; Ledger is the monospace look now. `code` changes in
|
|
126
|
+
two ways: it sets `color-scheme: dark`, so native controls, scrollbars
|
|
127
|
+
and the placeholder draw dark, and text on its green accent (the send
|
|
128
|
+
icon) is black where relative colour syntax is supported, 8.3:1 where
|
|
129
|
+
white was 2.5:1.
|
|
130
|
+
- **The browser floor rises to Chrome 123, Firefox 120 and Safari 17.5**,
|
|
131
|
+
from Chrome 120 and Safari 17. Every theme declares its colours with
|
|
132
|
+
`light-dark()`, which those versions are the first to support, and it is
|
|
133
|
+
used without a fallback: below the floor the colours do not resolve and
|
|
134
|
+
the widget draws without them. There is nothing to opt in to; a host
|
|
135
|
+
that must support an older browser stays on the previous release.
|
|
136
|
+
- **`classic` meets AA contrast.** The status pill's text in both schemes,
|
|
137
|
+
the indigo tool names in the dark scheme (2.38:1) and the dark composer
|
|
138
|
+
placeholder (3.93:1) now clear 4.5:1, and the done mark in the dark scheme
|
|
139
|
+
clears 3:1. Otherwise classic is the old look.
|
|
140
|
+
- **The theme toggle flips only the scheme word**, so `soft` becomes
|
|
141
|
+
`soft dark` and `soft dark` becomes `soft light`. Before, any value but
|
|
142
|
+
`dark` became `dark`, which dropped a theme name. It saves only the scheme
|
|
143
|
+
word, and a load puts the saved scheme beside the markup's own theme name,
|
|
144
|
+
so a scheme chosen on one page never carries that page's theme to
|
|
145
|
+
another. A value saved by an earlier release (`light` or `dark`) restores
|
|
146
|
+
as before.
|
|
147
|
+
- **Chart series read the theme's palette.** `--ag-ui-chart-1` to
|
|
148
|
+
`--ag-ui-chart-6` still win; without them each theme supplies its own first
|
|
149
|
+
two series.
|
|
150
|
+
|
|
151
|
+
- **The shadow stylesheet is split by concern.** `src/ui/styles.ts`, one
|
|
152
|
+
3,774-line string, is now composed from 27 modules, each in the directory of
|
|
153
|
+
the concern it styles: the token defaults and themes under `ui/shell/`, one
|
|
154
|
+
module per placement under `ui/placement/`, and the transcript, composer,
|
|
155
|
+
tool steps, interrupts, history and charts in theirs. The composed sheet is
|
|
156
|
+
the old one with every rule in the same order; only two comments changed
|
|
157
|
+
wording. Nothing a host sees changes, and **no host has to opt in**: tokens,
|
|
158
|
+
parts, attributes and the public type declarations are as they were.
|
|
159
|
+
- **One record per placement.** What each `placement` does on the script side
|
|
160
|
+
-- what it collapses to, whether its launcher can be dragged, which axes it
|
|
161
|
+
resizes on, whether a first mount starts collapsed -- is now one descriptor
|
|
162
|
+
per placement in `src/ui/placement/surface_for.ts`, replacing three separate
|
|
163
|
+
tables that each listed placements. Every placement behaves as before, an
|
|
164
|
+
unknown value included, and **no host has to opt in**.
|
|
165
|
+
- **The element builds its DOM through free functions.** The header, the
|
|
166
|
+
transcript and empty state, the composer and the launcher are each built by
|
|
167
|
+
a function in the directory of their concern (`ui/shell/build_header.ts`,
|
|
168
|
+
`ui/transcript/build_transcript.ts`, `ui/composer/build_composer.ts`,
|
|
169
|
+
`ui/shell/build_launcher.ts`), and the flag and JSON attribute readers are
|
|
170
|
+
free functions under `core/`. Internal restructuring: the DOM, its parts,
|
|
171
|
+
slots and listeners are the same and mount in the same order, the public
|
|
172
|
+
type declarations are unchanged, and **no host has to opt in**.
|
|
173
|
+
- **The sub-agent test fixture is the wire django-ag-ui 0.72.0 writes.** The
|
|
174
|
+
recorded run was a copy from before pydantic-ai 2.63, which django-ag-ui now
|
|
175
|
+
floors. The regenerated one carries `role` on every `TEXT_MESSAGE_START`, a
|
|
176
|
+
`protocolVersion` on `RUN_STARTED`, an `entityId` on the reasoning event
|
|
177
|
+
that records a tool retry (a `REASONING_ENCRYPTED_VALUE`, new to the run),
|
|
178
|
+
and a retry result that no longer ends in pydantic-ai's "Fix the errors and
|
|
179
|
+
try again." prompt. The component reads none of the new keys: it takes message
|
|
180
|
+
ids from the events and builds the card from the `SUBAGENT_*` and
|
|
181
|
+
`ag_ui.subagent` events, and the unit and Chromium sub-agent tests, the
|
|
182
|
+
latter through the element's real `HttpAgent`, pass on the new file unchanged.
|
|
183
|
+
The demo's mock server sends the same retry-free result. A Chromium test now
|
|
184
|
+
asserts the run's closing answer renders past the new event; it fails on a
|
|
185
|
+
fixture whose event is malformed, where every delegation assertion settled
|
|
186
|
+
before it and passed. Test and demo only, nothing shipped changes,
|
|
187
|
+
and **a host owes nothing**.
|
|
188
|
+
|
|
10
189
|
## [0.44.0] — 2026-10-20
|
|
11
190
|
|
|
12
191
|
### Fixed
|
|
@@ -4582,7 +4761,9 @@ hosts that both arrange the page the way it expects.
|
|
|
4582
4761
|
### Notes
|
|
4583
4762
|
- First release — exercising the automated npm OIDC publish pipeline end-to-end.
|
|
4584
4763
|
|
|
4585
|
-
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.
|
|
4764
|
+
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.46.0...HEAD
|
|
4765
|
+
[0.46.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.45.0...v0.46.0
|
|
4766
|
+
[0.45.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.44.0...v0.45.0
|
|
4586
4767
|
[0.44.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.43.0...v0.44.0
|
|
4587
4768
|
[0.43.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.42.0...v0.43.0
|
|
4588
4769
|
[0.42.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.41.3...v0.42.0
|
package/README.md
CHANGED
|
@@ -64,6 +64,7 @@ No framework, no Django, no admin specifics live here. Downstream consumers (e.g
|
|
|
64
64
|
- [Host seams: the SPA story](#host-seams-the-spa-story)
|
|
65
65
|
- [Public API surface](#public-api-surface)
|
|
66
66
|
- [Theming, density, and placement](#theming-density-and-placement)
|
|
67
|
+
- [Themes](#themes)
|
|
67
68
|
- [Internationalization (i18n)](#internationalization-i18n)
|
|
68
69
|
- [Building the bundle](#building-the-bundle)
|
|
69
70
|
- [Compatibility](#compatibility)
|
|
@@ -176,7 +177,7 @@ another origin, add `credentials="include"` too; see
|
|
|
176
177
|
| `endpoint` | `endpoint` | The AG-UI endpoint URL. Required to send: without it a send is refused with a `console.error` naming the missing attribute and a `not-connected` run notice in the transcript. Reflecting getter + setter. |
|
|
177
178
|
| `credentials` | `credentials` | Cookie policy for every request the element makes: `omit` / `same-origin` / `include`. Unset means the browser default (`same-origin`), which sends no cookies cross-origin. See [Authenticating requests](#authenticating-requests). |
|
|
178
179
|
| `title-text` | — | Header label; defaults to `"Assistant"`. Live: writing it after the element connects re-labels the header. See [When each attribute is read](#when-each-attribute-is-read). |
|
|
179
|
-
| `data-tool-display` | `toolDisplay` |
|
|
180
|
+
| `data-tool-display` | `toolDisplay` | How tool calls are drawn: `grouped` (the default: a run's consecutive calls fold into one row) / `inline` / `minimal` / `compact` / `full` (per-call cards; `full` was the default before `grouped`). An unknown value reads as `grouped`. See [Tool-call display modes](#tool-call-display-modes). |
|
|
180
181
|
| `data-text-animation` | — | Incoming-text reveal: `none` (default) / `fade` / `word`. |
|
|
181
182
|
| `data-prompt-chips` | — | Present (bare, or any value but `"false"`) to surface skills as chips. |
|
|
182
183
|
| `data-slash-commands` | — | Present (bare, or any value but `"false"`) to enable the `/`-command palette. |
|
|
@@ -213,7 +214,7 @@ another origin, add `credentials="include"` too; see
|
|
|
213
214
|
| `data-paste-attach` | — | When to turn a long text paste into an attachment instead of composer text: absent for the 5000-character default, `off` to never, or a positive number of characters. Only acts where `data-attachments-url` (or a custom `uploadHandler`) gives it somewhere to go. |
|
|
214
215
|
| `data-starters` | — | JSON array of prompts offered on an empty transcript, e.g. `'["Summarise this page"]'`. Fallback content for `slot="empty"`, so slotting your own replaces them. Shares the four-prompt and 120-character limits with the suggestion chips a run pushes. Read once at connect. |
|
|
215
216
|
| `data-start-open` | — | Mount the panel open on a first visit. The corner placements otherwise rest at their launcher, the way every corner chat does; a stored choice wins over both. The placements that place themselves are unaffected. |
|
|
216
|
-
| `theme` | — | CSS-only: `light` (default) / `dark` / `auto`
|
|
217
|
+
| `theme` | — | CSS-only: an optional theme name (`quiet` (default) / `soft` / `ledger` / `classic`, or a word of your own) and an optional scheme (`light` (default) / `dark` / `auto`), in any order, e.g. `soft dark`. See [Themes](#themes). |
|
|
217
218
|
| `density` | — | CSS-only: `comfortable` (default) / `compact`. |
|
|
218
219
|
| `placement` | — | CSS-only: `floating` (default) / `sidebar` / `page` / `embedded`. |
|
|
219
220
|
|
|
@@ -263,7 +264,7 @@ element after the fact.
|
|
|
263
264
|
`approveWithEdits`, `agentFactory`, `getTools`, `getContext`, `routeMap`, `navigate`, `getPageMap`,
|
|
264
265
|
`autoInjectPageMap`, `conversationStore`, `uploadHandler`, `transcribeHandler`, `navigationResult`,
|
|
265
266
|
`skillContext`, `toolSummaries`, `formatToolPayload`, `formatRelativeTime`, `strings`,
|
|
266
|
-
`resolvePageTarget`, `sharedState`, plus the read-only `unread` and `unhandledActivityTypes`, and
|
|
267
|
+
`resolvePageTarget`, `sharedState`, `extraStyles` ([unstable](#d-extrastyles-the-last-mile)), plus the read-only `unread` and `unhandledActivityTypes`, and
|
|
267
268
|
the attribute mirrors `endpoint` / `userKey` / `userName` / `toolDisplay` / `collapsed` /
|
|
268
269
|
`credentials`.
|
|
269
270
|
|
|
@@ -1182,7 +1183,7 @@ or changing `user-key` clears it with the transcript.
|
|
|
1182
1183
|
|
|
1183
1184
|
### Collapsing to the launcher
|
|
1184
1185
|
|
|
1185
|
-
A collapsed widget shrinks to a
|
|
1186
|
+
A collapsed widget shrinks to a **floating launcher** in the corner it already occupies: the
|
|
1186
1187
|
panel scales down into it and fades, the launcher grows out of the same point, and clicking the
|
|
1187
1188
|
launcher reverses it. Only `transform` and `opacity` animate, so the motion is compositor-only and
|
|
1188
1189
|
never reflows your page. Two placements collapse to something else instead — `sidebar` slides out
|
|
@@ -1204,15 +1205,19 @@ speech bubble.
|
|
|
1204
1205
|
|
|
1205
1206
|
```css
|
|
1206
1207
|
ag-ui-chat {
|
|
1207
|
-
--ag-ui-launcher-size:
|
|
1208
|
-
--ag-ui-launcher-radius:
|
|
1209
|
-
--ag-ui-launcher-bg: #14532d; /* defaults to the
|
|
1210
|
-
--ag-ui-launcher-fg: #ffffff;
|
|
1211
|
-
--ag-ui-launcher-icon-size:
|
|
1208
|
+
--ag-ui-launcher-size: 48px;
|
|
1209
|
+
--ag-ui-launcher-radius: 14px; /* 50% for a circle */
|
|
1210
|
+
--ag-ui-launcher-bg: #14532d; /* defaults to the panel background */
|
|
1211
|
+
--ag-ui-launcher-fg: #ffffff; /* defaults to the text colour */
|
|
1212
|
+
--ag-ui-launcher-icon-size: 22px;
|
|
1212
1213
|
--ag-ui-launcher-inset: auto 0 0 auto; /* which corner of the widget's box */
|
|
1213
1214
|
}
|
|
1214
1215
|
```
|
|
1215
1216
|
|
|
1217
|
+
The sizes and defaults above are Quiet's. The other themes bring their own launcher: `classic`
|
|
1218
|
+
the 56px circle in the header's colours, `soft` a 56px accent tile, and `ledger` a 44px tile in
|
|
1219
|
+
the text colour.
|
|
1220
|
+
|
|
1216
1221
|
> **The collapsed host keeps its box.** Animating the element's own width and height would animate
|
|
1217
1222
|
> layout; instead the box stays put with `pointer-events: none`, and the launcher takes the clicks.
|
|
1218
1223
|
> A host measuring `getBoundingClientRect()` on a collapsed widget still sees the panel's
|
|
@@ -1470,15 +1475,22 @@ is the honest answer to "I pushed a chart and nothing happened".
|
|
|
1470
1475
|
|
|
1471
1476
|
## Tool-call display modes
|
|
1472
1477
|
|
|
1473
|
-
How
|
|
1474
|
-
property), one of `inline` / `minimal` / `compact` / `full` (default `
|
|
1478
|
+
How tool calls are drawn is set via the `data-tool-display` attribute (or `toolDisplay`
|
|
1479
|
+
property), one of `grouped` / `inline` / `minimal` / `compact` / `full` (default `grouped`; an
|
|
1480
|
+
absent or unknown value reads as `grouped`):
|
|
1475
1481
|
|
|
1482
|
+
- `grouped` — the default. A run's consecutive tool calls fold into one quiet row, **"Worked
|
|
1483
|
+
through 5 steps"**, with a note such as **"1 failed"** beside it, and the calls one click down
|
|
1484
|
+
as `full` cards. Anything else in the turn (text, a confirmation, a question) ends the group, and
|
|
1485
|
+
the next call starts a new one; a call's own rendered output does not. A group of one call shows that call's own label. See
|
|
1486
|
+
[The step group](#the-step-group).
|
|
1476
1487
|
- `inline` — the lightest mode: a single status row (icon + summary, no card chrome) with the
|
|
1477
1488
|
result behind its own toggle. Reads as one line of the answer — pairs with [the answer
|
|
1478
1489
|
well](#the-answer-well).
|
|
1479
1490
|
- `minimal` — tool name + status pill only.
|
|
1480
1491
|
- `compact` — name + status, with arguments *and* result behind a single collapsed toggle.
|
|
1481
|
-
- `full` — arguments visible, result behind the toggle
|
|
1492
|
+
- `full` — arguments visible, result behind the toggle. The default before `grouped`: set
|
|
1493
|
+
`data-tool-display="full"` to keep per-call cards.
|
|
1482
1494
|
|
|
1483
1495
|
Whichever mode is on, a settled card's body holds **two labelled regions** — `Arguments` and
|
|
1484
1496
|
`Result` (or `Error` / `Declined`) — each with its own part and each pretty-printed. They are
|
|
@@ -1486,9 +1498,55 @@ never run together into one block, so where the call ends and the answer begins
|
|
|
1486
1498
|
visible. Style them via the `tool-card-args` / `tool-card-result` parts, their headings via
|
|
1487
1499
|
`tool-card-section-label`, and the whole body via `tool-card-body`.
|
|
1488
1500
|
|
|
1489
|
-
**The attribute is live.** Changing `data-tool-display`
|
|
1490
|
-
transcript, the way `data-answer-well` does — the modes are pure visibility
|
|
1491
|
-
selected by the shadow CSS from the host attribute.
|
|
1501
|
+
**The attribute is live.** Changing `data-tool-display` between the four card modes restyles every
|
|
1502
|
+
card already in the transcript, the way `data-answer-well` does — the modes are pure visibility
|
|
1503
|
+
over one DOM shape, selected by the shadow CSS from the host attribute. Grouping is decided as
|
|
1504
|
+
each card is built: switching **to** `grouped` folds only the calls drawn afterwards, and
|
|
1505
|
+
switching **away** from it flattens the groups already drawn, by CSS, into exactly the cards the
|
|
1506
|
+
new mode builds (the group stops generating a box and its row is hidden).
|
|
1507
|
+
|
|
1508
|
+
### The step group
|
|
1509
|
+
|
|
1510
|
+
Under `grouped` the row reads, by state:
|
|
1511
|
+
|
|
1512
|
+
| State (`data-state` on the `tool-group` part) | Label | Mark |
|
|
1513
|
+
| --- | --- | --- |
|
|
1514
|
+
| `running` | "Working through 3 steps", and the running step's label as a note | spinner |
|
|
1515
|
+
| `waiting` | "3 steps", with "1 waiting for you" | accent dot |
|
|
1516
|
+
| `done` | "Worked through 3 steps" | check |
|
|
1517
|
+
| `error` | "Worked through 3 steps", with "1 failed" in the danger colour | error mark |
|
|
1518
|
+
|
|
1519
|
+
"N declined" is added as a note whenever a step was declined. `data-count` carries the number of
|
|
1520
|
+
steps and `data-open` whether the cards are showing; the head is a button with `aria-expanded`.
|
|
1521
|
+
|
|
1522
|
+
- **It opens itself while a step waits on you.** A server-side approval renders inside the gated
|
|
1523
|
+
call's own card, so a folded group would hide the question it is asking: the group opens when a
|
|
1524
|
+
step goes `deferred`, once per wait, and stays folded if you fold it again. It opens before the
|
|
1525
|
+
approval is drawn, so the Approve button takes focus and scrolls into view. A client-side
|
|
1526
|
+
confirmation and an `ask_user` question render in the answer beside the group rather than inside
|
|
1527
|
+
a card, so they are in view without it opening; the row still reads `waiting` ("1 waiting for
|
|
1528
|
+
you") while one is open, as the card carries a `data-asking` flag for the group to read, and its
|
|
1529
|
+
`data-status` stays `pending`.
|
|
1530
|
+
- **A running sub-agent does not open it.** The row keeps its spinner and names the delegation
|
|
1531
|
+
instead, "Delegated to researcher" (the `subAgentDelegatedTo` string).
|
|
1532
|
+
- **Repeated labels are told apart.** Two "Fill field" steps read "Fill field" and "Fill field
|
|
1533
|
+
(2)": the ordinal is an element of its own (part `tool-card-repeat`) beside the card's name, so
|
|
1534
|
+
`tool-card-name` is never rewritten, and a card mode hides the ordinal.
|
|
1535
|
+
- **Rendered output stays in view.** A tool's `render` output is placed after the group, in call
|
|
1536
|
+
order, rather than inside it, so a chart is never one click down. It does not end the group: a
|
|
1537
|
+
later call joins the group above it, which is also how a restored conversation draws the run.
|
|
1538
|
+
|
|
1539
|
+
Parts: `tool-group`, `tool-group-head` (the button), `tool-group-icon`, `tool-group-label`,
|
|
1540
|
+
`tool-group-meta` (holding one `.tool-group-note` per note), `tool-group-list` (the cards), and
|
|
1541
|
+
`tool-card-repeat` on a repeated step. The focus ring is `--ag-ui-ring` and the disclosure chevron
|
|
1542
|
+
`--ag-ui-ico-chevron`. Strings (`strings` / `data-strings`): `toolGroupSteps`,
|
|
1543
|
+
`toolGroupWorking`, `toolGroupWorked` (each with `{count}`, always 2 or more), `toolGroupWaiting`,
|
|
1544
|
+
`toolGroupFailed`, `toolGroupDeclined` (each with `{count}`) and `toolStepRepeat` (with `{n}`).
|
|
1545
|
+
|
|
1546
|
+
```html
|
|
1547
|
+
<!-- Keep per-call cards, as before grouped was the default -->
|
|
1548
|
+
<ag-ui-chat endpoint="/agent/" data-tool-display="full"></ag-ui-chat>
|
|
1549
|
+
```
|
|
1492
1550
|
|
|
1493
1551
|
### Drawing a card's body yourself
|
|
1494
1552
|
|
|
@@ -2873,19 +2931,20 @@ ag-ui-chat { --ag-ui-accent: #b91c1c; } /* one widget */
|
|
|
2873
2931
|
> form did anything and the wrapper form silently did nothing. The defaults now sit behind an
|
|
2874
2932
|
> internal alias, so all three forms work.
|
|
2875
2933
|
|
|
2876
|
-
A few of the knobs:
|
|
2934
|
+
A few of the knobs, at Quiet's light values:
|
|
2877
2935
|
|
|
2878
2936
|
```css
|
|
2879
2937
|
ag-ui-chat {
|
|
2880
|
-
--ag-ui-accent: #
|
|
2881
|
-
--ag-ui-bg: #ffffff;
|
|
2882
|
-
--ag-ui-fg: #
|
|
2938
|
+
--ag-ui-accent: #232326; /* #f0f0f2 in the dark scheme */
|
|
2939
|
+
--ag-ui-bg: #ffffff; /* #161618 */
|
|
2940
|
+
--ag-ui-fg: #1b1b1d; /* #ececee */
|
|
2883
2941
|
--ag-ui-radius: 12px;
|
|
2884
2942
|
--ag-ui-header-btn-size: 30px; /* the header's controls; 44px on touch */
|
|
2885
2943
|
--ag-ui-header-gap: 4px;
|
|
2886
2944
|
|
|
2887
|
-
/* What is drawn on top of the accent and danger fills.
|
|
2888
|
-
the
|
|
2945
|
+
/* What is drawn on top of the accent and danger fills. Unset, the one on
|
|
2946
|
+
the accent is white or black by the accent's luminance (see Text on the
|
|
2947
|
+
accent below); set it to pin a colour of your own. */
|
|
2889
2948
|
--ag-ui-on-accent: #ffffff;
|
|
2890
2949
|
--ag-ui-on-danger: #ffffff;
|
|
2891
2950
|
|
|
@@ -2893,7 +2952,7 @@ ag-ui-chat {
|
|
|
2893
2952
|
--ag-ui-width: 380px;
|
|
2894
2953
|
--ag-ui-height: 560px;
|
|
2895
2954
|
--ag-ui-inset: auto 24px 24px auto;
|
|
2896
|
-
--ag-ui-shadow: 0 12px 32px
|
|
2955
|
+
--ag-ui-shadow: 0 1px 2px rgb(0 0 0 / 0.05), 0 12px 32px -16px rgb(0 0 0 / 0.22);
|
|
2897
2956
|
}
|
|
2898
2957
|
```
|
|
2899
2958
|
|
|
@@ -2902,7 +2961,153 @@ the panel that have no radius of their own: the answer well, the conversation li
|
|
|
2902
2961
|
button and filter field, and the *Undo* on a run notice. The frame is the exception where it meets
|
|
2903
2962
|
the edge of the window. `page` and `sidebar` draw it square, and so does every placement but
|
|
2904
2963
|
`embedded` on a small viewport, while the corners inside keep the theme's radius, since none of them
|
|
2905
|
-
meets that edge. `--ag-ui-panel-radius` sets the frame on its own, in any placement.
|
|
2964
|
+
meets that edge. `--ag-ui-panel-radius` sets the frame on its own, in any placement. Each theme
|
|
2965
|
+
gives the floating frame a radius of its own (`--ag-ui-frame-radius`: 14px in Quiet against 12px
|
|
2966
|
+
inside), and a host's `--ag-ui-radius` still sets both.
|
|
2967
|
+
|
|
2968
|
+
### Themes
|
|
2969
|
+
|
|
2970
|
+
`theme` is up to two words, in any order, matched as words (`~=`):
|
|
2971
|
+
|
|
2972
|
+
```
|
|
2973
|
+
theme = [name] [scheme]
|
|
2974
|
+
name = quiet | soft | ledger | classic | <a word of your own>
|
|
2975
|
+
scheme = light | dark | auto default: light
|
|
2976
|
+
```
|
|
2977
|
+
|
|
2978
|
+
| Value | Result |
|
|
2979
|
+
| --- | --- |
|
|
2980
|
+
| *(absent)* | Quiet, light |
|
|
2981
|
+
| `dark` | Quiet, dark |
|
|
2982
|
+
| `auto` | Quiet, following the system's `prefers-color-scheme` |
|
|
2983
|
+
| `soft`, `soft dark`, `ledger auto` | that theme in that scheme |
|
|
2984
|
+
| `classic`, `classic dark` | the look from before themes, for a host that pins it |
|
|
2985
|
+
| `acme` | a word the component does not ship adds no rules, so this is Quiet, ready for your `[theme~="acme"]` CSS |
|
|
2986
|
+
| `soft acme` | starts from Soft; your `[theme~="acme"]` rules layer on top |
|
|
2987
|
+
|
|
2988
|
+
The built-in themes:
|
|
2989
|
+
|
|
2990
|
+
| Theme | Look |
|
|
2991
|
+
| --- | --- |
|
|
2992
|
+
| `quiet` | The default. Neutral graphite on white, no bubble for the agent's turn, hairlines, status as an icon. Set one brand accent and the user's turn, the send button and the links follow it. |
|
|
2993
|
+
| `soft` | Rounded and tinted: surfaces mixed from the accent, pill chips, a deep frame shadow. Violet by default. |
|
|
2994
|
+
| `ledger` | Dense and editorial: paper and ink, square corners, serif for what the agent says and monospace for the chrome. |
|
|
2995
|
+
| `classic` | The look before themes: the indigo header, the accent user bubble, the status pill and the round launcher. Pin it to keep that look. |
|
|
2996
|
+
|
|
2997
|
+
**The default scheme is `light`, not `auto`**, because the widget sits on your page and only you
|
|
2998
|
+
know that page's scheme. A light admin screen on a machine in dark mode would otherwise get a dark
|
|
2999
|
+
panel on a white page. If your page follows the system, say `auto`.
|
|
3000
|
+
|
|
3001
|
+
Each theme is three seeds, `--ag-ui-bg`, `--ag-ui-fg` and `--ag-ui-accent`, each declared with
|
|
3002
|
+
`light-dark()` so the scheme word picks the half. Every other colour is mixed from them with
|
|
3003
|
+
`color-mix(in oklch, ...)` -- hover, borders, the secondary text inks, washes, the user's turn (the
|
|
3004
|
+
accent at 12% over the background) -- and every derived value still reads its own public token
|
|
3005
|
+
first, so each stays an override point. The tokens the themes add:
|
|
3006
|
+
|
|
3007
|
+
- **Inks and lines:** `--ag-ui-ink-2`, `--ag-ui-ink-3`, `--ag-ui-line`, `--ag-ui-line-strong`.
|
|
3008
|
+
- **Surfaces:** `--ag-ui-wash`, `--ag-ui-accent-ink`, `--ag-ui-tint`, `--ag-ui-tint-2`.
|
|
3009
|
+
- **Type:** `--ag-ui-text-xs`, `--ag-ui-text-sm`, `--ag-ui-text-md`, `--ag-ui-text-lg`,
|
|
3010
|
+
`--ag-ui-leading`, `--ag-ui-serif`.
|
|
3011
|
+
- **Frame:** `--ag-ui-frame-radius`, `--ag-ui-frame-shadow`. These are what a theme sets for the
|
|
3012
|
+
frame; `--ag-ui-panel-radius` and `--ag-ui-shadow` stay the final say, and are what a docked
|
|
3013
|
+
placement squares or flattens.
|
|
3014
|
+
- **Charts:** `--ag-ui-chart-1` to `--ag-ui-chart-6`. A host's value beats the theme's.
|
|
3015
|
+
- **Status marks:** `--ag-ui-ico-check`, `--ag-ui-ico-error`, `--ag-ui-ico-declined`, mask images
|
|
3016
|
+
drawn in the state's colour, and `--ag-ui-ico-chevron`, the step group's disclosure chevron.
|
|
3017
|
+
- **Focus:** `--ag-ui-ring`, the step group head's focus outline (the accent at 55%).
|
|
3018
|
+
|
|
3019
|
+
The font is part of the theme: Quiet, Soft and Ledger set their own stack (Inter, then the system
|
|
3020
|
+
UI font), and Classic inherits the page's font as the component always did. Set
|
|
3021
|
+
`--ag-ui-font: inherit` to take the page's font under any theme.
|
|
3022
|
+
|
|
3023
|
+
#### Text on the accent
|
|
3024
|
+
|
|
3025
|
+
`--ag-ui-on-accent`, unless you set it, is picked from the accent's own luminance: white on an
|
|
3026
|
+
accent darker than WCAG relative luminance 0.179, black on a lighter one, which is the better of
|
|
3027
|
+
the two on every colour (never under 4.58:1). It is computed with relative colour syntax with
|
|
3028
|
+
channel arithmetic, behind `@supports` for that exact expression: Chrome 119, Firefox 128, Safari
|
|
3029
|
+
18.
|
|
3030
|
+
|
|
3031
|
+
**The fallback.** Two browsers at or above the floor cannot compute it: Firefox 120 to 127, which
|
|
3032
|
+
lack relative colour syntax, and Safari 17.5 and 17.6, which shipped an earlier draft that rejects
|
|
3033
|
+
this expression. They keep a fixed colour per theme instead:
|
|
3034
|
+
|
|
3035
|
+
| Theme | Without relative colour syntax |
|
|
3036
|
+
| --- | --- |
|
|
3037
|
+
| `quiet`, `soft`, `ledger` | the scheme's: white in the light scheme, near-black (`#111111`) in the dark one |
|
|
3038
|
+
| `classic`, `code` | white in both schemes, the colour they always drew |
|
|
3039
|
+
|
|
3040
|
+
On every built-in accent but code's the fixed colour is on the same side as the computed one, so
|
|
3041
|
+
those browsers see the same contrast. On code's green the computed pick is black (8.3:1) and the
|
|
3042
|
+
fallback white (2.5:1), as it always was. What they miss is the correction for a host's accent: a
|
|
3043
|
+
mid-tone brand accent can fall under 4.5:1 there, under any theme. If you support those browsers
|
|
3044
|
+
and set a mid-tone accent, set `--ag-ui-on-accent` yourself. There is no script path.
|
|
3045
|
+
|
|
3046
|
+
#### Overriding a theme, lightest layer first
|
|
3047
|
+
|
|
3048
|
+
Four layers, each documented and each lighter than the next. Reach for the first one that does
|
|
3049
|
+
the job.
|
|
3050
|
+
|
|
3051
|
+
##### (a) Tokens
|
|
3052
|
+
|
|
3053
|
+
Any `--ag-ui-*` token, on the element or any ancestor, as above. Per theme, from your own CSS:
|
|
3054
|
+
|
|
3055
|
+
```css
|
|
3056
|
+
body { --ag-ui-accent: #0f766e; } /* accent only: the rest follows */
|
|
3057
|
+
ag-ui-chat[theme~="soft"] { --ag-ui-accent: #c2410c; --ag-ui-frame-radius: 12px; }
|
|
3058
|
+
```
|
|
3059
|
+
|
|
3060
|
+
A page rule always beats the theme's own value, because the theme only ever sets the private
|
|
3061
|
+
alias behind the public token.
|
|
3062
|
+
|
|
3063
|
+
##### (b) Parts
|
|
3064
|
+
|
|
3065
|
+
`::part()` reaches the structural elements, as listed in [Parts and slots](#parts-and-slots):
|
|
3066
|
+
|
|
3067
|
+
```css
|
|
3068
|
+
ag-ui-chat::part(header) { background: linear-gradient(#f2f7f6, transparent); }
|
|
3069
|
+
```
|
|
3070
|
+
|
|
3071
|
+
##### (c) A theme of your own
|
|
3072
|
+
|
|
3073
|
+
Name it, and style the name. An unknown word adds no built-in rules, so it starts from Quiet (or
|
|
3074
|
+
from the built-in theme beside it):
|
|
3075
|
+
|
|
3076
|
+
```html
|
|
3077
|
+
<ag-ui-chat theme="acme dark"></ag-ui-chat>
|
|
3078
|
+
```
|
|
3079
|
+
|
|
3080
|
+
```css
|
|
3081
|
+
ag-ui-chat[theme~="acme"] {
|
|
3082
|
+
--ag-ui-bg: light-dark(#fbfaf7, #10161c);
|
|
3083
|
+
--ag-ui-fg: light-dark(#14212b, #e4ebf0);
|
|
3084
|
+
--ag-ui-accent: light-dark(#0b5cad, #6cb2ff);
|
|
3085
|
+
--ag-ui-frame-radius: 4px;
|
|
3086
|
+
}
|
|
3087
|
+
```
|
|
3088
|
+
|
|
3089
|
+
Use `light-dark()` in the seeds and the scheme word, and the theme toggle, work for your theme
|
|
3090
|
+
too.
|
|
3091
|
+
|
|
3092
|
+
##### (d) `extraStyles`: the last mile
|
|
3093
|
+
|
|
3094
|
+
> **Unstable.** `extraStyles` reaches the class names inside the shadow root, and those are not a
|
|
3095
|
+
> public API: they may change in any minor release. Layers (a) to (c) are the supported ones; use
|
|
3096
|
+
> this for what they cannot reach, and expect to revisit it on upgrade.
|
|
3097
|
+
|
|
3098
|
+
```ts
|
|
3099
|
+
const sheet = new CSSStyleSheet();
|
|
3100
|
+
sheet.replaceSync(`.message--assistant { padding: 10px 12px; border-radius: 10px; }`);
|
|
3101
|
+
chat.extraStyles = [sheet];
|
|
3102
|
+
```
|
|
3103
|
+
|
|
3104
|
+
- `extraStyles: readonly CSSStyleSheet[]`, per element, default `[]`. Two elements can carry
|
|
3105
|
+
different sheets.
|
|
3106
|
+
- Adopted after the built-in sheet, so a rule of equal specificity wins.
|
|
3107
|
+
- Setting it re-adopts at once. The array is copied, so changing the one you passed does nothing
|
|
3108
|
+
until you set it again; changing a sheet's rules does apply, since the sheet itself is shared.
|
|
3109
|
+
- Constructed sheets are not subject to `style-src`, so this works under the same strict CSP as
|
|
3110
|
+
the built-in sheet. There is no string form and no `<style>` injection.
|
|
2906
3111
|
|
|
2907
3112
|
### Small viewports
|
|
2908
3113
|
|
|
@@ -3082,7 +3287,7 @@ highlights too. Without it they fall back to the package indigo.
|
|
|
3082
3287
|
For the common cases there are three CSS-reactive **preset attributes** (no JS API), so you don't
|
|
3083
3288
|
have to hand-tune the variables:
|
|
3084
3289
|
|
|
3085
|
-
- `theme` —
|
|
3290
|
+
- `theme` — a theme name and a scheme; see [Themes](#themes).
|
|
3086
3291
|
- `density` — `comfortable` (default) / `compact`.
|
|
3087
3292
|
- `placement` — `floating` (default) / `sidebar` / `page` / `embedded`. `embedded` drops the
|
|
3088
3293
|
fixed positioning and z-index so the widget sits in normal document flow; `page` is a
|
|
@@ -3109,7 +3314,8 @@ fix belongs to the containing element, not to the widget:
|
|
|
3109
3314
|
<ag-ui-chat endpoint="/agent/" theme="dark" density="compact" placement="sidebar"></ag-ui-chat>
|
|
3110
3315
|
```
|
|
3111
3316
|
|
|
3112
|
-
See [`src/ui/
|
|
3317
|
+
See [`src/ui/shell/token_styles.ts`](src/ui/shell/token_styles.ts) for the full variable list and
|
|
3318
|
+
[`src/ui/placement/`](src/ui/placement/) for the placement presets. The
|
|
3113
3319
|
[`demo/`](demo/) live playground (`node demo/mock-server.mjs`) flips theme, density, placement,
|
|
3114
3320
|
text-animation, tool-display, and the answer well live from a single page, and demos the
|
|
3115
3321
|
streamed thoughts region, the mic, and the header theme toggle.
|
|
@@ -3145,7 +3351,8 @@ component sets, so a new one cannot ship undocumented.
|
|
|
3145
3351
|
| Message actions | `message-actions`, `message-action` (plus `message-action-retry`, `message-action-copy`, `message-action-up`, `message-action-down`), and the icon holder inside each: `message-action-icon` (plus `message-action-icon-retry`, `message-action-icon-copy`, `message-action-icon-up`, `message-action-icon-down`) |
|
|
3146
3352
|
| Queued messages | `queued`, `queued-chip` |
|
|
3147
3353
|
| Run notices | `run-notice` (plus `run-notice-interrupted`, `run-notice-attachment-pending`, `run-notice-compaction`, `run-notice-skill`, `run-notice-history-replaced`, `run-notice-chart-undrawable`, `run-notice-surface`, `run-notice-not-connected`), `run-notice-icon`, `run-notice-text`, `run-notice-undo` |
|
|
3148
|
-
| Tool cards | `tool-card`, `tool-card-head`, `tool-card-icon`, `tool-card-name`, `tool-card-status`, `tool-card-decision`, `tool-card-toggle`, `tool-card-body`, `tool-card-section` (plus `tool-card-args-section`, `tool-card-result-section`), `tool-card-section-label` (plus `tool-card-args-label`, `tool-card-result-label`), `tool-card-args`, `tool-card-result`, `tool-card-approval`, `tool-card-subagent` |
|
|
3354
|
+
| Tool cards | `tool-card`, `tool-card-head`, `tool-card-icon`, `tool-card-name`, `tool-card-status`, `tool-card-decision`, `tool-card-toggle`, `tool-card-body`, `tool-card-section` (plus `tool-card-args-section`, `tool-card-result-section`), `tool-card-section-label` (plus `tool-card-args-label`, `tool-card-result-label`), `tool-card-args`, `tool-card-result`, `tool-card-approval`, `tool-card-subagent`, `tool-card-repeat` |
|
|
3355
|
+
| Tool-step group | `tool-group`, `tool-group-head`, `tool-group-icon`, `tool-group-label`, `tool-group-meta`, `tool-group-list` |
|
|
3149
3356
|
| Delegated sub-agents | `subagent`, `subagent-row`, `subagent-icon`, `subagent-status`, `subagent-steps`, `subagent-step`, `subagent-step-icon`, `subagent-step-name` |
|
|
3150
3357
|
| Client-side confirmation | `confirm`, `confirm-body`, `confirm-args`, `confirm-actions`, `confirm-button` (plus `confirm-confirm`, `confirm-cancel`, `confirm-always`) |
|
|
3151
3358
|
| Server-side approval | `approval`, `approval-body`, `approval-actions`, `approval-button` (plus `approval-approve`, `approval-deny`), `approval-edit`, `approval-args`, `approval-error` |
|
|
@@ -3367,8 +3574,12 @@ mic appears even with no `data-transcribe-url`.
|
|
|
3367
3574
|
|
|
3368
3575
|
`theme` is a plain attribute you can set yourself, and a host can always drop its own switch into
|
|
3369
3576
|
`slot="header-actions"`. For convenience, the boolean `data-theme-toggle` attribute adds a built-in
|
|
3370
|
-
light⇄dark toggle to the header (part `theme-toggle`) that flips `theme` and
|
|
3371
|
-
per tab.
|
|
3577
|
+
light⇄dark toggle to the header (part `theme-toggle`) that flips the scheme word of `theme` and
|
|
3578
|
+
persists the choice per tab. Only the scheme changes: `soft` becomes `soft dark`, `soft dark`
|
|
3579
|
+
becomes `soft light`, and `auto` becomes `dark`, an explicit choice. Only the scheme is saved, too:
|
|
3580
|
+
on the next load it is put beside whatever theme name the markup carries, so `dark` chosen on a
|
|
3581
|
+
`soft` page restores as `classic dark` on a `classic` one. Off by default so it never competes with
|
|
3582
|
+
a host-supplied control.
|
|
3372
3583
|
|
|
3373
3584
|
```html
|
|
3374
3585
|
<ag-ui-chat endpoint="/agent/" data-theme-toggle></ag-ui-chat>
|
|
@@ -3418,7 +3629,7 @@ This produces, into `dist/`:
|
|
|
3418
3629
|
- `index.d.ts` (+ source maps) — type declarations; emitted `.js` import specifiers are preserved
|
|
3419
3630
|
so consumers resolve types without extra flags.
|
|
3420
3631
|
|
|
3421
|
-
There is **no CSS file to load**. The styles are
|
|
3632
|
+
There is **no CSS file to load**. The styles are string constants adopted into
|
|
3422
3633
|
the shadow root at construction, so they ship inside the JS and cannot leak into
|
|
3423
3634
|
the host page. Restyle through the [CSS custom properties](#theming-density-and-placement) and the
|
|
3424
3635
|
`part` attributes, not a stylesheet override.
|
|
@@ -3439,12 +3650,14 @@ Other workflow targets (all identical in name to the sibling Python packages):
|
|
|
3439
3650
|
| Component | Floor | Tested |
|
|
3440
3651
|
| --- | --- | --- |
|
|
3441
3652
|
| Node (tooling/tests only) | 22 | 22, 24 |
|
|
3442
|
-
| Browsers (runtime target) |
|
|
3653
|
+
| Browsers (runtime target) | Chrome 123, Firefox 120, Safari 17.5 | Chromium |
|
|
3443
3654
|
| `@ag-ui/client`, `@ag-ui/core` | 1.0 | 1.0 |
|
|
3444
3655
|
| django-ag-ui (server) | 0.63.0 | — |
|
|
3445
3656
|
|
|
3446
|
-
The shipped artefact targets evergreen browsers (Shadow DOM, Custom Elements v1, ES2022).
|
|
3447
|
-
|
|
3657
|
+
The shipped artefact targets evergreen browsers (Shadow DOM, Custom Elements v1, ES2022). The
|
|
3658
|
+
browser floor is set by `light-dark()`, which every theme declares its colours with: below Chrome
|
|
3659
|
+
123, Firefox 120 or Safari 17.5 those colours do not resolve. Node is only the build/test runtime,
|
|
3660
|
+
not a runtime target.
|
|
3448
3661
|
|
|
3449
3662
|
The server floor is a wire contract rather than a dependency. A tool call's outcome and a user
|
|
3450
3663
|
message's attachment refs travel in `metadata`, since `@ag-ui/client` 1.0 strips every key its
|