@artooi/ag-ui-web-component 0.46.0 → 0.48.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +221 -1
  2. package/README.md +298 -31
  3. package/dist/ag-ui-web-component.bundle.js +597 -177
  4. package/dist/ag-ui-web-component.bundle.js.map +4 -4
  5. package/dist/constants.d.ts +37 -2
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/core/ag_ui_chat.d.ts +73 -2
  8. package/dist/core/ag_ui_chat.d.ts.map +1 -1
  9. package/dist/core/chat_registry.d.ts +23 -0
  10. package/dist/core/chat_registry.d.ts.map +1 -0
  11. package/dist/core/events/bar_height_detail.d.ts +6 -0
  12. package/dist/core/events/bar_height_detail.d.ts.map +1 -0
  13. package/dist/core/events/run_finished_detail.d.ts +6 -0
  14. package/dist/core/events/run_finished_detail.d.ts.map +1 -1
  15. package/dist/core/events/thread_detail.d.ts +27 -0
  16. package/dist/core/events/thread_detail.d.ts.map +1 -0
  17. package/dist/core/run_handlers.d.ts +6 -1
  18. package/dist/core/run_handlers.d.ts.map +1 -1
  19. package/dist/dom/animations.d.ts +21 -6
  20. package/dist/dom/animations.d.ts.map +1 -1
  21. package/dist/dom/highlight_overlay.d.ts +8 -1
  22. package/dist/dom/highlight_overlay.d.ts.map +1 -1
  23. package/dist/dom/ring_color.d.ts +22 -0
  24. package/dist/dom/ring_color.d.ts.map +1 -0
  25. package/dist/index.d.ts +4 -2
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1164 -95
  28. package/dist/index.js.map +4 -4
  29. package/dist/tools/chat_surface_tools.d.ts +8 -1
  30. package/dist/tools/chat_surface_tools.d.ts.map +1 -1
  31. package/dist/ui/history/conversation_history.d.ts +24 -2
  32. package/dist/ui/history/conversation_history.d.ts.map +1 -1
  33. package/dist/ui/placement/collapse_styles.d.ts.map +1 -1
  34. package/dist/ui/placement/dock_styles.d.ts +2 -0
  35. package/dist/ui/placement/dock_styles.d.ts.map +1 -0
  36. package/dist/ui/placement/panel_placement.d.ts +17 -0
  37. package/dist/ui/placement/panel_placement.d.ts.map +1 -1
  38. package/dist/ui/placement/small_viewport_styles.d.ts.map +1 -1
  39. package/dist/ui/placement/surface_for.d.ts +21 -17
  40. package/dist/ui/placement/surface_for.d.ts.map +1 -1
  41. package/dist/ui/progress/tool_call_card.d.ts.map +1 -1
  42. package/dist/ui/progress/tool_group_styles.d.ts.map +1 -1
  43. package/dist/ui/progress/tool_step_group.d.ts.map +1 -1
  44. package/dist/ui/progress/tool_step_styles.d.ts.map +1 -1
  45. package/dist/ui/shell/build_launcher.d.ts +15 -4
  46. package/dist/ui/shell/build_launcher.d.ts.map +1 -1
  47. package/dist/ui/shell/token_styles.d.ts.map +1 -1
  48. package/dist/ui/styles.d.ts.map +1 -1
  49. package/dist/ui/themes/scheme_styles.d.ts.map +1 -1
  50. package/package.json +1 -1
  51. package/src/constants.ts +41 -2
  52. package/src/core/ag_ui_chat.ts +430 -27
  53. package/src/core/chat_registry.ts +53 -0
  54. package/src/core/events/bar_height_detail.ts +5 -0
  55. package/src/core/events/run_finished_detail.ts +6 -0
  56. package/src/core/events/thread_detail.ts +26 -0
  57. package/src/core/run_handlers.ts +9 -4
  58. package/src/dom/animations.ts +30 -31
  59. package/src/dom/highlight_overlay.ts +10 -5
  60. package/src/dom/ring_color.ts +222 -0
  61. package/src/index.ts +7 -0
  62. package/src/tools/chat_surface_tools.ts +18 -8
  63. package/src/ui/history/conversation_history.ts +75 -7
  64. package/src/ui/placement/collapse_styles.ts +248 -2
  65. package/src/ui/placement/dock_styles.ts +91 -0
  66. package/src/ui/placement/embedded_styles.ts +2 -2
  67. package/src/ui/placement/panel_placement.ts +105 -12
  68. package/src/ui/placement/preset_styles.ts +1 -1
  69. package/src/ui/placement/sidebar_styles.ts +1 -1
  70. package/src/ui/placement/small_viewport_styles.ts +14 -0
  71. package/src/ui/placement/surface_for.ts +29 -18
  72. package/src/ui/progress/tool_call_card.ts +18 -8
  73. package/src/ui/progress/tool_group_styles.ts +49 -0
  74. package/src/ui/progress/tool_step_group.ts +3 -0
  75. package/src/ui/progress/tool_step_styles.ts +5 -3
  76. package/src/ui/shell/build_launcher.ts +32 -5
  77. package/src/ui/shell/token_styles.ts +30 -3
  78. package/src/ui/styles.ts +4 -0
  79. package/src/ui/themes/scheme_styles.ts +10 -1
  80. package/src/version.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,224 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.48.0] — 2026-11-07
11
+
12
+ ### Added
13
+
14
+ - **Choose how a step group draws its calls.** A new `data-tool-group-display`
15
+ attribute and `toolGroupDisplay` property, one of `full`, `compact`,
16
+ `minimal` or `inline`, set how an opened group draws its calls under
17
+ `grouped`. Each draws the regions the flat card of that mode draws, as a row
18
+ of the group. It is read only under `grouped`, is live, and leaves an
19
+ approval's arguments and buttons on screen in every mode. Exported as
20
+ `TOOL_GROUP_DISPLAY` with the `ToolGroupDisplayMode` type. **Opt-in**: an
21
+ absent or unknown value reads as `full`, which is what a group drew before,
22
+ so a host sees no change until it sets the attribute.
23
+ - **Collapse into a bottom bar.** A new live `collapse-to` attribute chooses
24
+ what a collapsed panel becomes. `bar` draws a strip along the bottom edge in
25
+ place of the round launcher, with the title, the unread badge, a running
26
+ mark and a history button that opens and closes the conversation list as a
27
+ popover;
28
+ the panel rises from the bar's right end. `none` hides the collapsed widget
29
+ so the host's own toolbar drives it, and the `anchor` attribute or property
30
+ names the host element the panel rises from. Under both, the panel's height
31
+ stops at the bar or the anchor, so `--ag-ui-inset` is not needed, and a
32
+ docked panel can be resized but not moved. The read-only `barHeight`
33
+ property and the `ag-ui-bar-height` event (`BAR_HEIGHT_EVENT`, detail
34
+ `BarHeightDetail`) give the host the height to pad its page by. Under
35
+ `none` the element dispatches `ag-ui-toggle` once at connect with the state
36
+ it mounted in. On a phone the open panel stays full-bleed and the bar shows
37
+ only while collapsed. New parts `bar` and `bar-history`, and
38
+ `describeSurface()` reports `collapseTo`. **Opt-in**: absent,
39
+ `collapse-to` reads as `auto`, which leaves every placement as it was.
40
+ - **Clear a host toolbar under `collapse-to="none"`.** The new
41
+ `--ag-ui-anchor-gap` token sets the gap between the panel and the anchor it
42
+ rises from, for a host whose button sits inside a taller toolbar; a gap
43
+ wider than the gutter also comes off the panel's max height, so a tall panel
44
+ stays on screen. **Opt-in**: absent, the gap stays 8px.
45
+
46
+ ### Changed
47
+
48
+ - **The chat surface tools describe every collapsed shape.** With
49
+ `data-page-actions` including `chat`, the `minimise_chat` tool no longer
50
+ promises a launcher: its description names the launcher, the rail, the
51
+ bottom bar or the page's own control, and its refusal on a placement with no
52
+ collapsed state no longer mentions a launcher. The report `describeSurface()`
53
+ returns, and so `read_chat_surface`, gains `collapseTo`, and a move
54
+ refused on a docked panel says it is docked. This reaches every host that
55
+ enables the chat tools, whatever `collapse-to` is: an agent prompt that
56
+ quoted the old wording sees new text. No host action is needed.
57
+ - **Tested against `@ag-ui/client` and `@ag-ui/core` 1.0.4.** The lockfile moves
58
+ from 1.0.3, and the declared range (`>=1.0.0 <2`) is unchanged, so a fresh
59
+ install of 0.47.0 already resolved 1.0.4. The element passes `threadId` to
60
+ the agent rather than reading the one 1.0.4 now creates on first read, and it
61
+ never edits a message the agent emits, which 1.0.4 now documents as
62
+ read-only. `zod` stays an undeclared peer of `@ag-ui/core`, as it was in
63
+ 1.0.3. **No opt-in** and no behavioural change.
64
+
65
+ - **The demo shows the 0.47.0 additions.** The playground gains a card under
66
+ the form with a control and a readout for each: the `above-composer` slot
67
+ (also a checkbox on the full-page route, where it travels with the centred
68
+ composer), the thread API (`threadId`, `newChat()`, `switchThread()` and a
69
+ log of `ag-ui-thread` events), the `tool-card-status-*` and `tool-group-*`
70
+ parts (drawn in one colour each, with a census of the parts in the
71
+ transcript) and the `--ag-ui-ring` token. Demo only, nothing shipped
72
+ changes, and **a host owes nothing**.
73
+
74
+ ### Fixed
75
+
76
+ - **A collapsed embedded chat no longer shows the above-composer slot.** The
77
+ collapse hid the composer and its stack but not the `above-composer` slot, so
78
+ a host's row stayed on screen under the header bar. The slot is hidden with
79
+ the composer and returns on expand. No opt-in: a host that kept content in
80
+ that slot to stay visible while collapsed should use the footer slot, which
81
+ collapse leaves alone.
82
+
83
+ - **`switchThread()` keeps the old thread when the store's load rejects.** The element
84
+ used to point at the new thread id, show an empty transcript and fire no
85
+ `ag-ui-thread`, so it named a thread it was not showing. It now stays on the thread
86
+ it was on, draws it again without an event, and the returned promise rejects with
87
+ the store's error. A second `switchThread()` for the thread still loading now
88
+ settles with that load, after the replay, instead of resolving at once. No host
89
+ opt-in.
90
+ - **`newChat()` before the element connects waits for the connect.** It used to mint a
91
+ thread in the unscoped store and fire `ag-ui-thread` for a chat that was not yet
92
+ shown, leaving `threadId` non-null against the README. Now `threadId` is `null` and
93
+ nothing fires until the element connects, which starts the new chat and fires one
94
+ `ag-ui-thread` with reason `new`. A host that called `newChat()` early and relied on
95
+ the immediate event or thread id reads them after connect instead.
96
+
97
+ - **Rings hold 3:1 against what they are drawn on.** The step group head's
98
+ focus ring was the accent at 55% over transparent, so a light host accent
99
+ fell to 1.6:1 on the default light panel (Django admin's `#79aec8`). Unset,
100
+ `--ag-ui-ring` is now two parts accent to three parts ink, which holds 3:1
101
+ against the panel for any accent in every theme and scheme; Quiet's ring
102
+ turns from a translucent grey to near-ink. The field highlight ring, when it
103
+ falls back to the chat's own accent, is now held to 3:1 against the surface
104
+ behind the target: a dark widget on a light page drew its near-white accent
105
+ at 1.1:1, and now draws the light half of its accent pair, or the accent
106
+ stepped toward black or white. **No opt-in is needed**, and a host's
107
+ `--ag-ui-ring`, `--ag-ui-highlight-ring-color` or page `--ag-ui-accent` is
108
+ still drawn exactly as given.
109
+
110
+ - **The docs no longer advise `--ag-ui-font: inherit`.** The README and the
111
+ 0.45.0 entry said it would keep the page's font under any theme. It does
112
+ nothing: a CSS-wide keyword in a custom property applies to the custom
113
+ property itself, so it takes the parent's `--ag-ui-font`, which nothing sets,
114
+ and the theme's stack wins. Set `--ag-ui-font` to the page's family or to a
115
+ page token instead, for example `--ag-ui-font: var(--body-font)`. A host that
116
+ followed the old advice has to change it to get the page's font.
117
+
118
+ - **A chat never dragged no longer inherits a dragged size.** The size a drag
119
+ writes inline on the host was left undeclared on every other chat, so a chat
120
+ slotted into a dragged one, or under any page rule naming the private
121
+ property, came out at that size. It is now declared on `:host` like every
122
+ other private property. **No opt-in is needed.**
123
+
124
+ - **Picking a thread from the history drawer no longer leaves an unhandled
125
+ rejection when the store cannot load it.** The drawer's pick dropped the promise
126
+ `switchThread()` returns, so a store whose load rejected surfaced as an unhandled
127
+ rejection on the page. The pick now ends that rejection itself, and the thread on
128
+ screen stays as it was. No host opt-in.
129
+
130
+ - **A gated call with no arguments no longer draws an empty arguments box.** Under
131
+ `data-tool-display="compact"` and `"inline"`, the rule that shows a deferred call's
132
+ arguments outranked the `hidden` attribute the card sets when there are none, so an
133
+ empty box sat above the Approve button. The rule now skips a hidden section. No host
134
+ opt-in.
135
+
136
+ - **The theme toggle flips the scheme the panel is drawn in.** With no `light` or
137
+ `dark` word in `theme`, as under `auto` on a dark system or when a host rule sets
138
+ the element's `color-scheme`, the first press wrote `dark` over a panel that was
139
+ already dark, and the glyph offered dark. The toggle and its glyph now read the
140
+ drawn scheme. A `light` or `dark` word also now holds against a host rule that
141
+ sets `color-scheme` on the element, which used to win over it. No host opt-in.
142
+
143
+ ## [0.47.0] — 2026-11-07
144
+
145
+ ### Added
146
+
147
+ - **Tool cards name their status as a part.** The `tool-card` part gains a
148
+ status modifier beside it, `tool-card-pending`, `tool-card-deferred`,
149
+ `tool-card-done`, `tool-card-error`, `tool-card-declined` or
150
+ `tool-card-interrupted`, and the status pill's `tool-card-status` gains the
151
+ matching `tool-card-status-<status>`. `::part()` takes no attribute selector,
152
+ so a host could not style failures only; now
153
+ `ag-ui-chat::part(tool-card-status-error)` does. The modifier is replaced as
154
+ the status changes. The folded step group does the same with its state:
155
+ `tool-group-waiting`, `tool-group-running`, `tool-group-done` or
156
+ `tool-group-error` beside `tool-group`. **No opt-in is needed**: the base
157
+ parts are unchanged, so an existing `::part(tool-card)` rule still matches,
158
+ and a host that wants the modifiers just writes the selector.
159
+
160
+ - **`resetSize()`.** Drops a dragged size and its stored copy, so the placement's
161
+ size and the host's `--ag-ui-width` / `--ag-ui-height` apply again. For a host
162
+ entering a sized state of its own, which a user's drag would otherwise outrank.
163
+
164
+ - **A public thread API, for a host that lists conversations in its own
165
+ chrome.** `switchThread(threadId)` puts a stored thread on screen and resolves
166
+ once it is replayed; during a run it cancels the run, as the drawer and
167
+ `newChat()` do. `deleteThread(threadId)` deletes one as the drawer row does,
168
+ replacing the thread on screen with a fresh one when it was that thread. The
169
+ read-only `threadId` is the thread on screen and never mints one, unlike
170
+ `conversationStore.threadId()`. The read-only `running` is the composer's own
171
+ state, across tool rounds, a Retry and a checkpoint continuation, reflected as
172
+ `data-running` on the element. A new `ag-ui-thread` event (`THREAD_EVENT`,
173
+ typed `ThreadDetail`) fires once per change of conversation, after the
174
+ transcript is replaced, with `{ threadId, previousThreadId, reason }` and
175
+ `reason` one of `new`, `switch`, `delete`, `restore` (on connect and on
176
+ `reload()`) or `rescope` (a `user-key` change). `ag-ui-run-finished` gains
177
+ `threadId`, the thread the run belonged to. **No opt-in is needed**; all of it
178
+ is additive. A host can now drop a patch that reached the private thread
179
+ switch, an attribute observer that inferred the running state, and reads of
180
+ `conversationStore.threadId()` made only to learn the thread on screen.
181
+ `ag-ui-submit` keeps its meaning: a turn was sent, not a run started.
182
+
183
+ - **An `above-composer` slot.** Light-DOM content with
184
+ `slot="above-composer"` sits directly above the composer, after the skill
185
+ chips, the hint, the queued turns and the attachment tray, in every placement,
186
+ and moves with the composer in the greeting layout. An empty slot takes no
187
+ space. **Opt-in**: a host uses it by slotting content. A host that slotted
188
+ into `footer` and reordered the panel's flex column through `::part(composer)`
189
+ to lift it above the input can slot here instead and drop the reorder.
190
+
191
+ ### Changed
192
+
193
+ - **Highlight rings on an unthemed page follow the widget's theme.** Since
194
+ 0.45.0 the default accent is Quiet's near-black, but the rings the DOM
195
+ driver draws in the page (`flash`, `focusWithFlash`, `highlightThenClick`,
196
+ `pressThenClick`, `selectOption`, `toggleControl`, `showHighlightOverlay`)
197
+ still fell back to the old indigo. They now take the chat's resolved accent,
198
+ per theme and per scheme. A page that sets `--ag-ui-accent` on `:root`, or
199
+ passes `color`, keeps the rings it has. **No opt-in is needed.**
200
+ - New token `--ag-ui-highlight-ring-color`, beside
201
+ `--ag-ui-highlight-ring-width`. Set on `ag-ui-chat` (or above it) it
202
+ colours every ring with no `color` option, ahead of a target's
203
+ `--ag-ui-accent`; set on the page it reaches the target and wins over the
204
+ chat's.
205
+ - The press and toggle halo is now the ring colour at 40%. A host that
206
+ themes `--ag-ui-accent` had a solid halo in that colour; it is now
207
+ translucent, as the unthemed one always was.
208
+ - The rings read the most recently connected `<ag-ui-chat>`. A page with two
209
+ passes the acting one as the new `chat` option, which every ring-drawing
210
+ primitive and `showHighlightOverlay` take.
211
+
212
+ - **A dragged panel size stays out of the host's tokens and out of the phone
213
+ shape.** The drag, and the size restored before first paint, no longer write
214
+ `--ag-ui-width` / `--ag-ui-height` on the element; they write the private
215
+ `--_drag-width` / `--_drag-height`, still persisted per tab under the same key.
216
+ Above 600px the dragged size beats the host's tokens, `!important` included:
217
+ the private properties are read before the public ones, so a host rule such as
218
+ `ag-ui-chat.expanded { --ag-ui-width: 900px !important }` used to beat a drag
219
+ and now loses to it until `resetSize()` is called. At 600px or less the
220
+ small-viewport block does not read the dragged size, so a persisted or freshly
221
+ dragged size leaves the full-bleed shape alone, including after a window
222
+ narrows. **Who owes what**: a host with no sized state of its own owes nothing.
223
+ A host that enters a sized state (an "expanded" class, a mode switch) and
224
+ relied on `!important` to outrank a user's drag must call `resetSize()` when it
225
+ enters that state. A host that read `--ag-ui-width` back from the element's
226
+ inline style to learn the dragged size must measure the element instead.
227
+
10
228
  ## [0.46.0] — 2026-11-05
11
229
 
12
230
  ### Changed
@@ -4761,7 +4979,9 @@ hosts that both arrange the page the way it expects.
4761
4979
  ### Notes
4762
4980
  - First release — exercising the automated npm OIDC publish pipeline end-to-end.
4763
4981
 
4764
- [Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.46.0...HEAD
4982
+ [Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.48.0...HEAD
4983
+ [0.48.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.47.0...v0.48.0
4984
+ [0.47.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.46.0...v0.47.0
4765
4985
  [0.46.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.45.0...v0.46.0
4766
4986
  [0.45.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.44.0...v0.45.0
4767
4987
  [0.44.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.43.0...v0.44.0