@artooi/ag-ui-web-component 0.46.0 → 0.47.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 +87 -1
- package/README.md +130 -19
- package/dist/ag-ui-web-component.bundle.js +99 -94
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +10 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts +38 -0
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/core/chat_registry.d.ts +23 -0
- package/dist/core/chat_registry.d.ts.map +1 -0
- package/dist/core/events/run_finished_detail.d.ts +6 -0
- package/dist/core/events/run_finished_detail.d.ts.map +1 -1
- package/dist/core/events/thread_detail.d.ts +27 -0
- package/dist/core/events/thread_detail.d.ts.map +1 -0
- package/dist/core/run_handlers.d.ts +6 -1
- package/dist/core/run_handlers.d.ts.map +1 -1
- package/dist/dom/animations.d.ts +21 -6
- package/dist/dom/animations.d.ts.map +1 -1
- package/dist/dom/highlight_overlay.d.ts +7 -1
- package/dist/dom/highlight_overlay.d.ts.map +1 -1
- package/dist/dom/ring_color.d.ts +14 -0
- package/dist/dom/ring_color.d.ts.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +249 -54
- package/dist/index.js.map +4 -4
- package/dist/ui/history/conversation_history.d.ts +10 -1
- package/dist/ui/history/conversation_history.d.ts.map +1 -1
- package/dist/ui/placement/panel_placement.d.ts +6 -0
- package/dist/ui/placement/panel_placement.d.ts.map +1 -1
- package/dist/ui/placement/small_viewport_styles.d.ts.map +1 -1
- package/dist/ui/progress/tool_call_card.d.ts.map +1 -1
- package/dist/ui/progress/tool_step_group.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +11 -0
- package/src/core/ag_ui_chat.ts +108 -5
- package/src/core/chat_registry.ts +53 -0
- package/src/core/events/run_finished_detail.ts +6 -0
- package/src/core/events/thread_detail.ts +26 -0
- package/src/core/run_handlers.ts +9 -4
- package/src/dom/animations.ts +30 -31
- package/src/dom/highlight_overlay.ts +9 -5
- package/src/dom/ring_color.ts +85 -0
- package/src/index.ts +3 -0
- package/src/ui/history/conversation_history.ts +28 -4
- package/src/ui/placement/embedded_styles.ts +2 -2
- package/src/ui/placement/panel_placement.ts +34 -9
- package/src/ui/placement/preset_styles.ts +1 -1
- package/src/ui/placement/sidebar_styles.ts +1 -1
- package/src/ui/placement/small_viewport_styles.ts +5 -0
- package/src/ui/progress/tool_call_card.ts +18 -8
- package/src/ui/progress/tool_step_group.ts +3 -0
- package/src/ui/shell/token_styles.ts +2 -2
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,91 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.47.0] — 2026-11-07
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Tool cards name their status as a part.** The `tool-card` part gains a
|
|
15
|
+
status modifier beside it, `tool-card-pending`, `tool-card-deferred`,
|
|
16
|
+
`tool-card-done`, `tool-card-error`, `tool-card-declined` or
|
|
17
|
+
`tool-card-interrupted`, and the status pill's `tool-card-status` gains the
|
|
18
|
+
matching `tool-card-status-<status>`. `::part()` takes no attribute selector,
|
|
19
|
+
so a host could not style failures only; now
|
|
20
|
+
`ag-ui-chat::part(tool-card-status-error)` does. The modifier is replaced as
|
|
21
|
+
the status changes. The folded step group does the same with its state:
|
|
22
|
+
`tool-group-waiting`, `tool-group-running`, `tool-group-done` or
|
|
23
|
+
`tool-group-error` beside `tool-group`. **No opt-in is needed**: the base
|
|
24
|
+
parts are unchanged, so an existing `::part(tool-card)` rule still matches,
|
|
25
|
+
and a host that wants the modifiers just writes the selector.
|
|
26
|
+
|
|
27
|
+
- **`resetSize()`.** Drops a dragged size and its stored copy, so the placement's
|
|
28
|
+
size and the host's `--ag-ui-width` / `--ag-ui-height` apply again. For a host
|
|
29
|
+
entering a sized state of its own, which a user's drag would otherwise outrank.
|
|
30
|
+
|
|
31
|
+
- **A public thread API, for a host that lists conversations in its own
|
|
32
|
+
chrome.** `switchThread(threadId)` puts a stored thread on screen and resolves
|
|
33
|
+
once it is replayed; during a run it cancels the run, as the drawer and
|
|
34
|
+
`newChat()` do. `deleteThread(threadId)` deletes one as the drawer row does,
|
|
35
|
+
replacing the thread on screen with a fresh one when it was that thread. The
|
|
36
|
+
read-only `threadId` is the thread on screen and never mints one, unlike
|
|
37
|
+
`conversationStore.threadId()`. The read-only `running` is the composer's own
|
|
38
|
+
state, across tool rounds, a Retry and a checkpoint continuation, reflected as
|
|
39
|
+
`data-running` on the element. A new `ag-ui-thread` event (`THREAD_EVENT`,
|
|
40
|
+
typed `ThreadDetail`) fires once per change of conversation, after the
|
|
41
|
+
transcript is replaced, with `{ threadId, previousThreadId, reason }` and
|
|
42
|
+
`reason` one of `new`, `switch`, `delete`, `restore` (on connect and on
|
|
43
|
+
`reload()`) or `rescope` (a `user-key` change). `ag-ui-run-finished` gains
|
|
44
|
+
`threadId`, the thread the run belonged to. **No opt-in is needed**; all of it
|
|
45
|
+
is additive. A host can now drop a patch that reached the private thread
|
|
46
|
+
switch, an attribute observer that inferred the running state, and reads of
|
|
47
|
+
`conversationStore.threadId()` made only to learn the thread on screen.
|
|
48
|
+
`ag-ui-submit` keeps its meaning: a turn was sent, not a run started.
|
|
49
|
+
|
|
50
|
+
- **An `above-composer` slot.** Light-DOM content with
|
|
51
|
+
`slot="above-composer"` sits directly above the composer, after the skill
|
|
52
|
+
chips, the hint, the queued turns and the attachment tray, in every placement,
|
|
53
|
+
and moves with the composer in the greeting layout. An empty slot takes no
|
|
54
|
+
space. **Opt-in**: a host uses it by slotting content. A host that slotted
|
|
55
|
+
into `footer` and reordered the panel's flex column through `::part(composer)`
|
|
56
|
+
to lift it above the input can slot here instead and drop the reorder.
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
|
|
60
|
+
- **Highlight rings on an unthemed page follow the widget's theme.** Since
|
|
61
|
+
0.45.0 the default accent is Quiet's near-black, but the rings the DOM
|
|
62
|
+
driver draws in the page (`flash`, `focusWithFlash`, `highlightThenClick`,
|
|
63
|
+
`pressThenClick`, `selectOption`, `toggleControl`, `showHighlightOverlay`)
|
|
64
|
+
still fell back to the old indigo. They now take the chat's resolved accent,
|
|
65
|
+
per theme and per scheme. A page that sets `--ag-ui-accent` on `:root`, or
|
|
66
|
+
passes `color`, keeps the rings it has. **No opt-in is needed.**
|
|
67
|
+
- New token `--ag-ui-highlight-ring-color`, beside
|
|
68
|
+
`--ag-ui-highlight-ring-width`. Set on `ag-ui-chat` (or above it) it
|
|
69
|
+
colours every ring with no `color` option, ahead of a target's
|
|
70
|
+
`--ag-ui-accent`; set on the page it reaches the target and wins over the
|
|
71
|
+
chat's.
|
|
72
|
+
- The press and toggle halo is now the ring colour at 40%. A host that
|
|
73
|
+
themes `--ag-ui-accent` had a solid halo in that colour; it is now
|
|
74
|
+
translucent, as the unthemed one always was.
|
|
75
|
+
- The rings read the most recently connected `<ag-ui-chat>`. A page with two
|
|
76
|
+
passes the acting one as the new `chat` option, which every ring-drawing
|
|
77
|
+
primitive and `showHighlightOverlay` take.
|
|
78
|
+
|
|
79
|
+
- **A dragged panel size stays out of the host's tokens and out of the phone
|
|
80
|
+
shape.** The drag, and the size restored before first paint, no longer write
|
|
81
|
+
`--ag-ui-width` / `--ag-ui-height` on the element; they write the private
|
|
82
|
+
`--_drag-width` / `--_drag-height`, still persisted per tab under the same key.
|
|
83
|
+
Above 600px the dragged size beats the host's tokens, `!important` included:
|
|
84
|
+
the private properties are read before the public ones, so a host rule such as
|
|
85
|
+
`ag-ui-chat.expanded { --ag-ui-width: 900px !important }` used to beat a drag
|
|
86
|
+
and now loses to it until `resetSize()` is called. At 600px or less the
|
|
87
|
+
small-viewport block does not read the dragged size, so a persisted or freshly
|
|
88
|
+
dragged size leaves the full-bleed shape alone, including after a window
|
|
89
|
+
narrows. **Who owes what**: a host with no sized state of its own owes nothing.
|
|
90
|
+
A host that enters a sized state (an "expanded" class, a mode switch) and
|
|
91
|
+
relied on `!important` to outrank a user's drag must call `resetSize()` when it
|
|
92
|
+
enters that state. A host that read `--ag-ui-width` back from the element's
|
|
93
|
+
inline style to learn the dragged size must measure the element instead.
|
|
94
|
+
|
|
10
95
|
## [0.46.0] — 2026-11-05
|
|
11
96
|
|
|
12
97
|
### Changed
|
|
@@ -4761,7 +4846,8 @@ hosts that both arrange the page the way it expects.
|
|
|
4761
4846
|
### Notes
|
|
4762
4847
|
- First release — exercising the automated npm OIDC publish pipeline end-to-end.
|
|
4763
4848
|
|
|
4764
|
-
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.
|
|
4849
|
+
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.47.0...HEAD
|
|
4850
|
+
[0.47.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.46.0...v0.47.0
|
|
4765
4851
|
[0.46.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.45.0...v0.46.0
|
|
4766
4852
|
[0.45.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.44.0...v0.45.0
|
|
4767
4853
|
[0.44.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.43.0...v0.44.0
|
package/README.md
CHANGED
|
@@ -210,6 +210,7 @@ another origin, add `credentials="include"` too; see
|
|
|
210
210
|
| `data-expand-corner` | — | **Written by the element, not by you.** It stamps the corner a dragged or agent-moved panel opens from, so the collapse animation starts where the panel actually is. Listed because the element reads its own stamp back; setting it yourself is overwritten on the next move. |
|
|
211
211
|
| `data-greeting` | — | CSS-only: `off` turns the [greeting layout](#the-greeting-on-an-empty-page) off under `placement="page"`, where it is on by default. Any other value turns it on under `placement="embedded"`. No other placement has it. |
|
|
212
212
|
| `data-empty` | — | **Written by the element, not by you.** Present while the conversation has nothing in it, which is when the greeting shows. Public as a styling hook, so the chrome around a full-page chat can react to the same state, e.g. `ag-ui-chat[data-empty] ~ .page-footer { display: none }`. |
|
|
213
|
+
| `data-running` | — | **Written by the element, not by you.** Present while an interaction is in flight, the same state that shows the Stop button (see the `running` property). Public as a styling hook, as `data-empty` is, so the chrome around the chat can react to it, e.g. `ag-ui-chat[data-running] ~ .toolbar button { pointer-events: none }`. |
|
|
213
214
|
| `data-small-viewport` | — | CSS-only: `off` keeps the desktop layout at every width, opting out of the [small-viewport override](#small-viewports). Everything that override sets is a token you can re-state; its trigger is a media query, which is the one thing you cannot. |
|
|
214
215
|
| `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. |
|
|
215
216
|
| `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. |
|
|
@@ -264,7 +265,7 @@ element after the fact.
|
|
|
264
265
|
`approveWithEdits`, `agentFactory`, `getTools`, `getContext`, `routeMap`, `navigate`, `getPageMap`,
|
|
265
266
|
`autoInjectPageMap`, `conversationStore`, `uploadHandler`, `transcribeHandler`, `navigationResult`,
|
|
266
267
|
`skillContext`, `toolSummaries`, `formatToolPayload`, `formatRelativeTime`, `strings`,
|
|
267
|
-
`resolvePageTarget`, `sharedState`, `extraStyles` ([unstable](#d-extrastyles-the-last-mile)), plus the read-only `unread` and `
|
|
268
|
+
`resolvePageTarget`, `sharedState`, `extraStyles` ([unstable](#d-extrastyles-the-last-mile)), plus the read-only `unread`, `unhandledActivityTypes`, `threadId` and `running`, and
|
|
268
269
|
the attribute mirrors `endpoint` / `userKey` / `userName` / `toolDisplay` / `collapsed` /
|
|
269
270
|
`credentials`.
|
|
270
271
|
|
|
@@ -289,7 +290,8 @@ labels are fetched automatically — per card, `x-summary` → an explicit
|
|
|
289
290
|
`sharedState` is AG-UI shared state, documented under
|
|
290
291
|
[the run loop](#the-run-loop-and-the-ag-ui-client); `unread` and `unhandledActivityTypes` are
|
|
291
292
|
read-only counters, covered under [the unread badge](#the-unread-badge) and
|
|
292
|
-
[finding out what arrived](#finding-out-what-arrived)
|
|
293
|
+
[finding out what arrived](#finding-out-what-arrived); `threadId` and `running` are covered under
|
|
294
|
+
[driving the conversation from your own chrome](#driving-the-conversation-from-your-own-chrome).
|
|
293
295
|
|
|
294
296
|
Code blocks in an agent's answer carry a **copy button**, revealed on hover or
|
|
295
297
|
keyboard focus and styleable via the `code-copy` part. Override its labels with
|
|
@@ -298,14 +300,17 @@ the `copyCode` / `copied` / `copyFailed` strings.
|
|
|
298
300
|
**Methods**: `registerTool`, `registerPageState`, `registerActivityRenderer`, `setSkills`,
|
|
299
301
|
`sendMessage`, `attachFile`, `appendMessage`, `retryLastTurn`, `quote`, `offerQuoteInPage`,
|
|
300
302
|
`enableCharts`, `newChat`, `setCollapsed`, `toggleCollapsed`, `describeSurface`, `moveTo`,
|
|
301
|
-
`toggleTheme`, `openThreads`, `closeThreads`,
|
|
303
|
+
`resetSize`, `toggleTheme`, `openThreads`, `closeThreads`, `switchThread`, `deleteThread`,
|
|
302
304
|
`openCheckpoints`, `closeCheckpoints`, `toggleCheckpoints`, `reload`, and the deprecated
|
|
303
305
|
`registerStateHook` (renamed to `registerPageState`).
|
|
304
306
|
|
|
305
307
|
### Sending from your own UI
|
|
306
308
|
|
|
307
309
|
`sendMessage(content, attachments?)` sends as if the user had typed it — user bubble,
|
|
308
|
-
`ag-ui-submit` event, run started.
|
|
310
|
+
`ag-ui-submit` event, run started. `ag-ui-submit` means a turn was sent, not that a run started:
|
|
311
|
+
a Retry and a run continued from the checkpoint panel start runs without one. To know whether
|
|
312
|
+
anything is running, read [`running`](#driving-the-conversation-from-your-own-chrome) or style on
|
|
313
|
+
`data-running`. Use it for an "Ask about this order" button, a command
|
|
309
314
|
palette, a prompt fired when your page mounts the chat, or a composer of your own replacing the
|
|
310
315
|
built-in one.
|
|
311
316
|
|
|
@@ -960,8 +965,8 @@ human-readable speed (configurable; pass small/zero durations in tests):
|
|
|
960
965
|
paints outside the border box and any `overflow: hidden` ancestor sharing the element's box (a
|
|
961
966
|
card, a table cell) clips it away entirely. It holds for **1200 ms** by default and fades out
|
|
962
967
|
over the last third — a 200 ms blink is not long enough to be *found* by someone who does not
|
|
963
|
-
yet know where to look. The colour
|
|
964
|
-
|
|
968
|
+
yet know where to look. The colour is `color` when passed, else — see
|
|
969
|
+
[Ring colour](#ring-colour) — the widget's own accent.
|
|
965
970
|
`flash` leaves focus alone; `focusWithFlash` moves it — see "Flash versus focus" below.
|
|
966
971
|
- `prefersReducedMotion()` — honoured by every primitive that *moves* something: the hold delays
|
|
967
972
|
in `pressThenClick` / `selectOption` / `toggleControl` collapse to instant, `scrollIntoCenterView`
|
|
@@ -999,11 +1004,13 @@ operations a tool handler typically wants:
|
|
|
999
1004
|
**Themed from the element you point at, not from the widget.** The overlay is appended to the
|
|
1000
1005
|
document body so it can escape the clipping it exists to avoid, which means a `var()` in its own
|
|
1001
1006
|
style would resolve against the body — so every token is read from the *target's* computed style
|
|
1002
|
-
instead
|
|
1003
|
-
|
|
1007
|
+
instead. Set them wherever they inherit to the elements the agent touches, usually `:root`. The
|
|
1008
|
+
ring colour is the one exception, read from the widget as well; see
|
|
1009
|
+
[Ring colour](#ring-colour).
|
|
1004
1010
|
|
|
1005
1011
|
```css
|
|
1006
1012
|
:root {
|
|
1013
|
+
--ag-ui-highlight-ring-color: #0f766e; /* also read from ag-ui-chat; see Ring colour */
|
|
1007
1014
|
--ag-ui-highlight-scrim: rgba(15, 15, 25, 0.45);
|
|
1008
1015
|
--ag-ui-highlight-gradient: linear-gradient(115deg, transparent 20%, #4f46e5 50%, transparent 80%);
|
|
1009
1016
|
--ag-ui-highlight-ring-width: 3; /* unitless; px */
|
|
@@ -1047,6 +1054,29 @@ register the change.
|
|
|
1047
1054
|
Each takes an element the caller has already located; host packages wrap them with
|
|
1048
1055
|
environment-aware lookups (e.g. "find `#id_<name>`, then `fillField`").
|
|
1049
1056
|
|
|
1057
|
+
#### Ring colour
|
|
1058
|
+
|
|
1059
|
+
Every ring the driver draws — the flash outline, the overlay ring, the press and toggle halo — is
|
|
1060
|
+
drawn in the host's page, outside the widget, so a token set on `ag-ui-chat` never reaches it
|
|
1061
|
+
through the cascade. The driver reads the widget directly instead, so on a page that themes
|
|
1062
|
+
nothing the rings follow the widget's theme: Quiet's near-black, Soft's violet, the dark half in a
|
|
1063
|
+
dark scheme. When a call passes no `color`, the first of these that is set wins:
|
|
1064
|
+
|
|
1065
|
+
1. `--ag-ui-highlight-ring-color` on the target (so `:root` reaches every ring);
|
|
1066
|
+
2. `--ag-ui-highlight-ring-color` on the chat — on `ag-ui-chat` or anything above it;
|
|
1067
|
+
3. the target's `--ag-ui-accent`, so a page that themes its accent keeps the rings it has;
|
|
1068
|
+
4. the chat's resolved accent, its theme's default included;
|
|
1069
|
+
5. the package indigo, when no chat is on the page at all.
|
|
1070
|
+
|
|
1071
|
+
```css
|
|
1072
|
+
/* Rings in the brand colour, whatever the widget's accent. */
|
|
1073
|
+
ag-ui-chat { --ag-ui-highlight-ring-color: #0f766e; }
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
The halo of `pressThenClick` and `toggleControl` is the chosen colour at 40%. "The chat" is the
|
|
1077
|
+
most recently connected `<ag-ui-chat>`; on a page with two, pass the one acting as the `chat`
|
|
1078
|
+
option (`RingOwnerOptions`, which every ring-drawing primitive and `showHighlightOverlay` take).
|
|
1079
|
+
|
|
1050
1080
|
### Page-action tools
|
|
1051
1081
|
|
|
1052
1082
|
Two built-in client tools let the agent perform common page interactions without every host
|
|
@@ -1138,6 +1168,9 @@ matching JS API:
|
|
|
1138
1168
|
returning whether it went. It takes the axes the same way a user drag does, so the launcher
|
|
1139
1169
|
travels with it and switching placement hands them back. Returns `false` rather than pretending
|
|
1140
1170
|
when the placement owns its position or the panel fills the screen.
|
|
1171
|
+
- `resetSize()` — drop a size the user dragged, and its stored copy, so the placement's own
|
|
1172
|
+
size and your `--ag-ui-width` / `--ag-ui-height` apply again. For a host that enters a sized
|
|
1173
|
+
state of its own (an expanded mode): a user's drag outranks host tokens, so call this first.
|
|
1141
1174
|
- `setCollapsed(collapsed)` / `toggleCollapsed()` — collapse or expand the widget. The state is
|
|
1142
1175
|
reflected as the boolean `collapsed` attribute/property and persisted per-tab in
|
|
1143
1176
|
`sessionStorage`, so it survives a reload.
|
|
@@ -1152,6 +1185,49 @@ chat.toggleCollapsed();
|
|
|
1152
1185
|
chat.addEventListener("ag-ui-toggle", (e) => console.log(e.detail.collapsed));
|
|
1153
1186
|
```
|
|
1154
1187
|
|
|
1188
|
+
### Driving the conversation from your own chrome
|
|
1189
|
+
|
|
1190
|
+
A host that lists conversations in its own bar, rather than in the built-in drawer, drives the
|
|
1191
|
+
one on screen with the drawer's own paths:
|
|
1192
|
+
|
|
1193
|
+
- `switchThread(threadId)` — put a stored thread on screen and replay it, as picking its row in
|
|
1194
|
+
the drawer does. Returns a `Promise<void>` that resolves once the thread is drawn. **A run in
|
|
1195
|
+
flight is cancelled**, as the drawer and `newChat()` cancel it; read `running` first if you
|
|
1196
|
+
would rather wait. Switching to the thread already on screen does nothing, and so does a call
|
|
1197
|
+
before the element connects.
|
|
1198
|
+
- `deleteThread(threadId)` — delete a stored thread, as the drawer row's delete does. Deleting
|
|
1199
|
+
the thread on screen cancels its run and puts a fresh thread in its place; deleting another
|
|
1200
|
+
leaves the screen alone. Prefer it to `conversationStore.clear()`, which deletes the record and
|
|
1201
|
+
nothing else: the run, the transcript and the drawer are left pointing at it.
|
|
1202
|
+
- `threadId` *(read-only)* — the thread on screen, `null` before the element first connects.
|
|
1203
|
+
It only reads. `conversationStore.threadId()` mints and stores a thread when the store points
|
|
1204
|
+
at none, so asking it which conversation is showing can start one.
|
|
1205
|
+
- `running` *(read-only)* — whether an interaction is in flight: the composer's own state, the
|
|
1206
|
+
one it shows Stop for, across every tool round, a Retry and a checkpoint continuation as well
|
|
1207
|
+
as a send. Reflected on the element as the `data-running` attribute, written by the element
|
|
1208
|
+
rather than by you, as `data-empty` is, so the chrome around the chat can style on it.
|
|
1209
|
+
|
|
1210
|
+
Every change of conversation fires one **`ag-ui-thread`** event (the `THREAD_EVENT` constant),
|
|
1211
|
+
after the transcript has been replaced, so a listener reads the conversation it is told about.
|
|
1212
|
+
`detail` is `{ threadId, previousThreadId, reason }` (typed `ThreadDetail`). `previousThreadId`
|
|
1213
|
+
is the thread the previous event reported, `null` before the first, and `reason` is one of:
|
|
1214
|
+
|
|
1215
|
+
| `reason` | When |
|
|
1216
|
+
| --- | --- |
|
|
1217
|
+
| `new` | `newChat()` or the built-in New chat button. |
|
|
1218
|
+
| `switch` | `switchThread()` or a row picked in the drawer. Two switches made before the first had replayed report only the second. |
|
|
1219
|
+
| `delete` | The thread on screen was deleted, and a fresh one took its place. |
|
|
1220
|
+
| `restore` | The stored thread was replayed: when the element connects (`previousThreadId` is `null` the first time), or by `reload()`. |
|
|
1221
|
+
| `rescope` | A `user-key` change handed the element to another principal, live or while it was out of the document. |
|
|
1222
|
+
|
|
1223
|
+
A page reload keeps restoring the thread, as [MPA durability](#mpa-durability-surviving-full-page-reloads) describes, and
|
|
1224
|
+
reports it as `restore`. Ignore a `reason` you do not know: more may be added.
|
|
1225
|
+
|
|
1226
|
+
```js
|
|
1227
|
+
chat.addEventListener("ag-ui-thread", (e) => myBar.markActive(e.detail.threadId));
|
|
1228
|
+
myBar.onPick = (threadId) => chat.switchThread(threadId);
|
|
1229
|
+
```
|
|
1230
|
+
|
|
1155
1231
|
### The composer's own keys
|
|
1156
1232
|
|
|
1157
1233
|
**Enter during a run queues.** A second run cannot start while one is in flight —
|
|
@@ -1498,6 +1574,16 @@ never run together into one block, so where the call ends and the answer begins
|
|
|
1498
1574
|
visible. Style them via the `tool-card-args` / `tool-card-result` parts, their headings via
|
|
1499
1575
|
`tool-card-section-label`, and the whole body via `tool-card-body`.
|
|
1500
1576
|
|
|
1577
|
+
**A card names its status as a part.** `::part()` takes no attribute selector, so a rule on
|
|
1578
|
+
`tool-card-status` reaches every outcome alike. The card and its status pill each carry a modifier
|
|
1579
|
+
beside the base part, one of `pending`, `deferred`, `done`, `error`, `declined` or `interrupted`,
|
|
1580
|
+
and it is replaced whenever the status changes:
|
|
1581
|
+
|
|
1582
|
+
```css
|
|
1583
|
+
ag-ui-chat::part(tool-card-error) { border-color: crimson; }
|
|
1584
|
+
ag-ui-chat::part(tool-card-status-error) { font-weight: 700; }
|
|
1585
|
+
```
|
|
1586
|
+
|
|
1501
1587
|
**The attribute is live.** Changing `data-tool-display` between the four card modes restyles every
|
|
1502
1588
|
card already in the transcript, the way `data-answer-well` does — the modes are pure visibility
|
|
1503
1589
|
over one DOM shape, selected by the shadow CSS from the host attribute. Grouping is decided as
|
|
@@ -1536,7 +1622,8 @@ steps and `data-open` whether the cards are showing; the head is a button with `
|
|
|
1536
1622
|
order, rather than inside it, so a chart is never one click down. It does not end the group: a
|
|
1537
1623
|
later call joins the group above it, which is also how a restored conversation draws the run.
|
|
1538
1624
|
|
|
1539
|
-
Parts: `tool-group
|
|
1625
|
+
Parts: `tool-group` (with the state beside it as `tool-group-waiting`, `tool-group-running`,
|
|
1626
|
+
`tool-group-done` or `tool-group-error`), `tool-group-head` (the button), `tool-group-icon`, `tool-group-label`,
|
|
1540
1627
|
`tool-group-meta` (holding one `.tool-group-note` per note), `tool-group-list` (the cards), and
|
|
1541
1628
|
`tool-card-repeat` on a repeated step. The focus ring is `--ag-ui-ring` and the disclosure chevron
|
|
1542
1629
|
`--ag-ui-ico-chevron`. Strings (`strings` / `data-strings`): `toolGroupSteps`,
|
|
@@ -1722,11 +1809,30 @@ and which grip carries the keyboard.
|
|
|
1722
1809
|
|
|
1723
1810
|
### Sizes, keyboard, and parts
|
|
1724
1811
|
|
|
1725
|
-
A drag writes `--
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1812
|
+
A drag writes the private `--_drag-width` / `--_drag-height` on the host, not
|
|
1813
|
+
your `--ag-ui-width` / `--ag-ui-height` tokens, which stay yours. The precedence
|
|
1814
|
+
is:
|
|
1815
|
+
|
|
1816
|
+
- **Above 600px**, the dragged size beats a host's `--ag-ui-width` /
|
|
1817
|
+
`--ag-ui-height`, `!important` included, so a user who resized the panel keeps
|
|
1818
|
+
their size. A host that enters a sized state of its own (an "expanded" class,
|
|
1819
|
+
a mode switch) calls `resetSize()` when it does, which drops the dragged size
|
|
1820
|
+
and its stored copy and hands control back to the host tokens. A host with no
|
|
1821
|
+
such state needs nothing.
|
|
1822
|
+
- **At 600px or less**, the small-viewport shape ignores the dragged size
|
|
1823
|
+
entirely, for the placements that block covers (`floating`, `bottom-left`,
|
|
1824
|
+
`sidebar`, `side` and the default): the panel is full-bleed whatever was
|
|
1825
|
+
dragged or stored, and a window narrowed after a wide-window drag goes
|
|
1826
|
+
full-bleed too. `page` is already that shape, and `embedded` is left to the
|
|
1827
|
+
host's own box, so neither is touched by the block. `data-small-viewport="off"`
|
|
1828
|
+
keeps a dragged size at every width on the covered placements.
|
|
1829
|
+
|
|
1830
|
+
A dragged size is a private property, so a host should not read it back from
|
|
1831
|
+
the element's inline style; use `getBoundingClientRect()`, or `resetSize()` to
|
|
1832
|
+
clear it.
|
|
1833
|
+
|
|
1834
|
+
**A custom property alone does not leave placement in charge** — an inline custom
|
|
1835
|
+
property still outranks a `:host([placement=…])` rule setting the same property. So the
|
|
1730
1836
|
component enforces the split directly: **a placement owns the axes it fixes**,
|
|
1731
1837
|
and a dragged or persisted size is only ever applied to the ones it leaves free.
|
|
1732
1838
|
Switching placement hands the owned axes back. Without that, a height dragged
|
|
@@ -2450,8 +2556,10 @@ chat.navigate = (path) => router.push(path); // SPA: in-page, no reload
|
|
|
2450
2556
|
Route map + `navigate()` and the reload model are the same feature seen from two ends.
|
|
2451
2557
|
|
|
2452
2558
|
**`ag-ui-run-finished`** *(event)* — an interaction has ended, and here is what ran in it.
|
|
2453
|
-
`detail: { tools: readonly ToolRun[] }` (typed `RunFinishedDetail`), where
|
|
2454
|
-
`{ name, side: "server" | "client" }` in settle order.
|
|
2559
|
+
`detail: { threadId, tools: readonly ToolRun[], invalidated }` (typed `RunFinishedDetail`), where
|
|
2560
|
+
each `ToolRun` is `{ name, side: "server" | "client" }` in settle order. `threadId` is the thread
|
|
2561
|
+
the run belonged to, which is not always the one on screen: a run that a new chat or a thread
|
|
2562
|
+
switch stopped still reports once its request closes.
|
|
2455
2563
|
|
|
2456
2564
|
**This is the seam for a host that renders data the agent can change.** A server-side tool writes
|
|
2457
2565
|
without your page's knowledge: nothing else the element dispatches implies "something may have moved
|
|
@@ -2734,6 +2842,7 @@ re-export point. Internal modules import from leaf paths.
|
|
|
2734
2842
|
| `defineAgUiChat()` | function | Idempotently register the element. |
|
|
2735
2843
|
| `MessageRole` | type | Role of a rendered chat message. |
|
|
2736
2844
|
| `SubmitDetail` | type | `detail` shape of the submit event. |
|
|
2845
|
+
| `ThreadDetail` | type | `detail` shape of the `ag-ui-thread` event (`{ threadId, previousThreadId, reason }`). |
|
|
2737
2846
|
| `ToggleDetail` | type | `detail` shape of the `ag-ui-toggle` event (`{ collapsed }`). |
|
|
2738
2847
|
| `UnreadDetail` | type | `detail` shape of the `ag-ui-unread` event (`{ unread }`). |
|
|
2739
2848
|
| `AttachmentsDetail` | type | `detail` shape of the `ag-ui-attachments` event (`{ attachments, pending }`). |
|
|
@@ -2875,7 +2984,7 @@ re-export point. Internal modules import from leaf paths.
|
|
|
2875
2984
|
| `HighlightOverlayOptions` | type | Options for `showHighlightOverlay`. |
|
|
2876
2985
|
| `fillField` / `clickElement` / `pressButton` / `selectControl` / `setControlValue` / `toggleCheckbox` | function | DOM-driver primitives. |
|
|
2877
2986
|
| `setNativeValue` / `setNativeChecked` | function | Set a control via its native prototype setter (React-controlled inputs). |
|
|
2878
|
-
| `TypeOptions` / `HighlightClickOptions` / `PressOptions` / `SelectOptions` / `ToggleOptions` / `FlashOptions` / `ScrollOptions` / `FillFieldOptions` / `TextLikeElement` | type | Primitive option shapes. |
|
|
2987
|
+
| `TypeOptions` / `HighlightClickOptions` / `PressOptions` / `SelectOptions` / `ToggleOptions` / `FlashOptions` / `ScrollOptions` / `FillFieldOptions` / `TextLikeElement` / `RingOwnerOptions` | type | Primitive option shapes. `RingOwnerOptions` is the `chat` the ring-drawing ones share; see [Ring colour](#ring-colour). |
|
|
2879
2988
|
|
|
2880
2989
|
### Constants
|
|
2881
2990
|
|
|
@@ -2883,6 +2992,7 @@ re-export point. Internal modules import from leaf paths.
|
|
|
2883
2992
|
| --- | --- |
|
|
2884
2993
|
| `ELEMENT_TAG` | The registered tag name (`ag-ui-chat`). |
|
|
2885
2994
|
| `SUBMIT_EVENT` | The submit CustomEvent name. |
|
|
2995
|
+
| `THREAD_EVENT` | The conversation-changed CustomEvent name (`ag-ui-thread`). |
|
|
2886
2996
|
| `TOGGLE_EVENT` | The collapse-toggle CustomEvent name (`ag-ui-toggle`). |
|
|
2887
2997
|
| `UNREAD_EVENT` | The unread-count CustomEvent name (`ag-ui-unread`). |
|
|
2888
2998
|
| `RUN_FINISHED_EVENT` | The interaction-finished CustomEvent name (`ag-ui-run-finished`). |
|
|
@@ -3351,8 +3461,8 @@ component sets, so a new one cannot ship undocumented.
|
|
|
3351
3461
|
| 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`) |
|
|
3352
3462
|
| Queued messages | `queued`, `queued-chip` |
|
|
3353
3463
|
| 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` |
|
|
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` |
|
|
3464
|
+
| Tool cards | `tool-card` (plus one status modifier: `tool-card-pending`, `tool-card-deferred`, `tool-card-done`, `tool-card-error`, `tool-card-declined`, `tool-card-interrupted`), `tool-card-head`, `tool-card-icon`, `tool-card-name`, `tool-card-status` (plus `tool-card-status-pending`, `tool-card-status-deferred`, `tool-card-status-done`, `tool-card-status-error`, `tool-card-status-declined`, `tool-card-status-interrupted`), `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` |
|
|
3465
|
+
| Tool-step group | `tool-group` (plus one state modifier: `tool-group-waiting`, `tool-group-running`, `tool-group-done`, `tool-group-error`), `tool-group-head`, `tool-group-icon`, `tool-group-label`, `tool-group-meta`, `tool-group-list` |
|
|
3356
3466
|
| Delegated sub-agents | `subagent`, `subagent-row`, `subagent-icon`, `subagent-status`, `subagent-steps`, `subagent-step`, `subagent-step-icon`, `subagent-step-name` |
|
|
3357
3467
|
| Client-side confirmation | `confirm`, `confirm-body`, `confirm-args`, `confirm-actions`, `confirm-button` (plus `confirm-confirm`, `confirm-cancel`, `confirm-always`) |
|
|
3358
3468
|
| Server-side approval | `approval`, `approval-body`, `approval-actions`, `approval-button` (plus `approval-approve`, `approval-deny`), `approval-edit`, `approval-args`, `approval-error` |
|
|
@@ -3393,6 +3503,7 @@ with a matching `slot=`):
|
|
|
3393
3503
|
| `header-actions` | Extra controls between the title and the built-in buttons. |
|
|
3394
3504
|
| `greeting` | The greeting's text, above the empty state, where the [greeting layout](#the-greeting-on-an-empty-page) is on. Replaces the text only; `empty` and the starters still render beneath it. |
|
|
3395
3505
|
| `empty` | The empty-state shown before any message. |
|
|
3506
|
+
| `above-composer` | Directly above the composer, below the skill chips, hint, queued turns and attachment tray. Takes no space when empty, and moves with the composer in the [greeting layout](#the-greeting-on-an-empty-page). |
|
|
3396
3507
|
| `footer` | Below the composer. |
|
|
3397
3508
|
| `launcher` | The collapsed widget's mark — the floating launcher, or the sidebar rail. |
|
|
3398
3509
|
| `icon-send` / `icon-stop` | The composer button's two glyphs (idle and mid-run). |
|