@artooi/ag-ui-web-component 0.20.1 → 0.22.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 +192 -1
- package/README.md +404 -28
- package/dist/ag-ui-web-component.bundle.js +781 -451
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +29 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts +93 -1
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/core/create_http_agent.d.ts +9 -0
- package/dist/core/create_http_agent.d.ts.map +1 -1
- package/dist/core/remote_conversation_store.d.ts +8 -1
- package/dist/core/remote_conversation_store.d.ts.map +1 -1
- package/dist/core/run_index.d.ts +8 -1
- package/dist/core/run_index.d.ts.map +1 -1
- package/dist/core/transcribe_audio.d.ts +7 -0
- package/dist/core/transcribe_audio.d.ts.map +1 -1
- package/dist/core/upload_attachment.d.ts +9 -0
- package/dist/core/upload_attachment.d.ts.map +1 -1
- package/dist/core/utils.d.ts +12 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/dom/animations.d.ts +51 -11
- package/dist/dom/animations.d.ts.map +1 -1
- package/dist/dom/dom_driver.d.ts +12 -7
- package/dist/dom/dom_driver.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1275 -520
- package/dist/index.js.map +3 -3
- package/dist/ui/styles.d.ts +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/dist/ui/ui_strings.d.ts +8 -1
- package/dist/ui/ui_strings.d.ts.map +1 -1
- package/dist/ui/voice_input.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +35 -0
- package/src/core/ag_ui_chat.ts +452 -55
- package/src/core/create_http_agent.ts +14 -3
- package/src/core/remote_conversation_store.ts +25 -6
- package/src/core/run_index.ts +27 -5
- package/src/core/transcribe_audio.ts +20 -5
- package/src/core/upload_attachment.ts +13 -0
- package/src/core/utils.ts +18 -0
- package/src/dom/animations.ts +175 -31
- package/src/dom/dom_driver.ts +18 -12
- package/src/index.ts +4 -0
- package/src/ui/styles.ts +751 -421
- package/src/ui/ui_strings.ts +9 -1
- package/src/ui/voice_input.ts +7 -1
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,195 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.22.0] — 2026-08-11
|
|
11
|
+
|
|
12
|
+
Two complaints about how the widget *feels*, and both turned out to be structural
|
|
13
|
+
rather than cosmetic.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **The composer is one surface, not four boxes.** The input row was a flat flex
|
|
18
|
+
row — attach, mic, textarea, send — with every sibling stretched to the
|
|
19
|
+
textarea's two-row height. That gave a paperclip the same visual weight as the
|
|
20
|
+
field it sits next to and made Send a full-height filled slab. The border,
|
|
21
|
+
background and focus ring now belong to a wrapping `composer-surface`: the
|
|
22
|
+
field is borderless and **grows with what is typed** (from one row up to
|
|
23
|
+
`--ag-ui-composer-max-height`, then scrolls), and a `composer-tools` row
|
|
24
|
+
underneath carries the paperclip and mic as quiet icon buttons with a circular
|
|
25
|
+
Send closing the right-hand end.
|
|
26
|
+
|
|
27
|
+
Send is now icon-only. Its accessible name still comes from the `send` /
|
|
28
|
+
`stop` strings (`aria-label` + `title`), and the run state swaps its glyph
|
|
29
|
+
rather than its text, so nothing moves when a run starts. A host that sized
|
|
30
|
+
`::part(send)` by its padding should switch to `--ag-ui-send-size`.
|
|
31
|
+
|
|
32
|
+
- **Collapsing goes to a round floating launcher.** `collapsed` used to leave the
|
|
33
|
+
full-width header bar sitting on the page, which is most of a chat widget's
|
|
34
|
+
footprint for none of its use. The panel now scales down into a launcher in the
|
|
35
|
+
corner it already occupies and the launcher grows back out of that point;
|
|
36
|
+
`transform` and `opacity` are all that animate, so the morph is
|
|
37
|
+
compositor-only and cannot reflow the host page. `placement="sidebar"` keeps
|
|
38
|
+
its edge rail (and now genuinely *slides* out through the edge it docks
|
|
39
|
+
against — the transition was declared but never wired to a transform), and
|
|
40
|
+
`embedded` / `page` keep the header bar, being host-laid-out and full-screen
|
|
41
|
+
respectively.
|
|
42
|
+
|
|
43
|
+
This changes what an existing floating embed looks like when collapsed. The
|
|
44
|
+
collapsed host keeps its box with `pointer-events: none`, so the page beneath
|
|
45
|
+
stays interactive and the launcher takes the clicks.
|
|
46
|
+
|
|
47
|
+
- **The chat-history drawer and the checkpoints panel slide.** Both were toggled
|
|
48
|
+
with `hidden` alone, which snaps. They now keep their box and hide with
|
|
49
|
+
`visibility`, which is what lets a surface animate *in and out* — an element
|
|
50
|
+
that was never rendered has no before-change style to animate from, and one
|
|
51
|
+
whose `display` flips to `none` cannot animate at all.
|
|
52
|
+
|
|
53
|
+
- **The chrome's glyphs are inline SVG** (send, stop, paperclip, mic, launcher)
|
|
54
|
+
rather than emoji, each in a slot with the mark as its fallback:
|
|
55
|
+
`icon-send`, `icon-stop`, `icon-attach`, `icon-voice`, `launcher`.
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
|
|
59
|
+
- **An unread badge on the launcher.** A collapsed widget is the one state where
|
|
60
|
+
an answer can arrive with nothing on screen to say so, so the launcher now
|
|
61
|
+
counts the answers that finished while it was closed (capped at `9+`) and
|
|
62
|
+
expanding marks them read. It is the only affordance here that is **on by
|
|
63
|
+
default**; `data-unread-badge="false"` turns the badge off, and the count keeps
|
|
64
|
+
running so a host chrome can render its own from the new `ag-ui-unread` event
|
|
65
|
+
(`UNREAD_EVENT` / `UnreadDetail`, plus a `chat.unread` getter). The count is
|
|
66
|
+
also the launcher's accessible name — a coloured dot says nothing to a screen
|
|
67
|
+
reader — via the new `expandUnread` string. Tokens:
|
|
68
|
+
`--ag-ui-badge-{bg,fg,size,font-size}`; part `launcher-badge`.
|
|
69
|
+
|
|
70
|
+
- **`data-launcher-icon-url`** — an icon for the collapsed launcher when it should
|
|
71
|
+
differ from the header's. Falls back to `data-icon-url`, so one attribute still
|
|
72
|
+
feeds both.
|
|
73
|
+
|
|
74
|
+
- **Motion tokens** — `--ag-ui-motion`, `--ag-ui-ease`, `--ag-ui-ease-pop`. One
|
|
75
|
+
duration and two curves drive every collapse, expand and slide-over. Under
|
|
76
|
+
`prefers-reduced-motion` the duration collapses to a frame; `--ag-ui-motion: 0s`
|
|
77
|
+
switches the animation off outright.
|
|
78
|
+
|
|
79
|
+
- **Launcher and composer tokens** — `--ag-ui-launcher-{size,bg,fg,radius,icon-size,inset}`,
|
|
80
|
+
`--ag-ui-composer-{radius,max-height}`, `--ag-ui-send-size`, `--ag-ui-tool-btn-size`,
|
|
81
|
+
`--ag-ui-glyph-{size,stroke}`; parts `composer-surface` and `composer-tools`.
|
|
82
|
+
|
|
83
|
+
- **Motion tests that run in a real browser.** happy-dom runs no transitions, so
|
|
84
|
+
every assertion about this would pass on a stylesheet where nothing animates.
|
|
85
|
+
The Chromium project now asserts on `getAnimations()` — that the browser
|
|
86
|
+
actually *started* the transitions a collapse, an expand and a drawer open are
|
|
87
|
+
supposed to start.
|
|
88
|
+
|
|
89
|
+
## [0.21.0] — 2026-08-11
|
|
90
|
+
|
|
91
|
+
Ten findings from a real embed — a cross-origin, cookie-authenticated React host.
|
|
92
|
+
Six of them are one defect: **the component assumed it owned the page.** It had
|
|
93
|
+
only ever been embedded in its own playground and in `django-admin-agent`, two
|
|
94
|
+
hosts that both arrange the page the way it expects.
|
|
95
|
+
|
|
96
|
+
### Added
|
|
97
|
+
|
|
98
|
+
- **`getHeaders`** — a function consulted immediately before **every** request, so
|
|
99
|
+
a rotating credential (a short-lived JWT, a re-issued CSRF token) reaches the
|
|
100
|
+
request that needs it. `headers` was a plain field the element never wrote to,
|
|
101
|
+
read at ten sites; configuring auth through `agentFactory` therefore
|
|
102
|
+
authenticated the run and nothing else, and thread history, attachments and the
|
|
103
|
+
catalogs went out anonymous and 401'd — which reads as a backend fault. The two
|
|
104
|
+
compose, merged per key with `getHeaders` winning, so adding a rotating header
|
|
105
|
+
cannot silently drop a static one.
|
|
106
|
+
|
|
107
|
+
- **`credentials`** (attribute and property) — `omit` / `same-origin` / `include`,
|
|
108
|
+
applied to every request. There was previously no occurrence of `credentials`
|
|
109
|
+
anywhere in the source, so every request used the browser default and a host
|
|
110
|
+
serving its SPA and API from different subdomains sent no cookies, with **no way
|
|
111
|
+
to express the fix** short of replacing the transport. An unknown value is
|
|
112
|
+
rejected where it was written (the property throws; the attribute logs and stays
|
|
113
|
+
inert) rather than becoming a 401 later.
|
|
114
|
+
|
|
115
|
+
- **`flash(el, options)`** — ring an element without moving focus.
|
|
116
|
+
`focusWithFlash` calls `el.focus()`, which for a helper named "flash" is
|
|
117
|
+
surprising: it takes focus off the composer, can fire blur validation on
|
|
118
|
+
whatever the user was mid-edit in, and can close a menu. Both now accept an
|
|
119
|
+
explicit `focus` option, and `focusWithFlash` focuses with `preventScroll: true`
|
|
120
|
+
so it no longer fights the scroll it just started.
|
|
121
|
+
|
|
122
|
+
- **`openThreads()` / `openCheckpoints()` / `reload()`.** The header's controls all
|
|
123
|
+
live inside `::part(header)`, so a host rendering its own title bar and hiding it
|
|
124
|
+
lost thread switching entirely. The built-in buttons call exactly these methods,
|
|
125
|
+
so the two routes cannot drift. `reload()` re-runs the startup fetches once
|
|
126
|
+
credentials that arrive late have landed.
|
|
127
|
+
|
|
128
|
+
- **`ScrollOptions`**, and `scrollIntoCenterView` now returns a promise that
|
|
129
|
+
resolves when the scroll has settled (`scrollend` where available, a short probe
|
|
130
|
+
when nothing moved, a 600 ms cap otherwise). Every DOM-driver primitive awaits it.
|
|
131
|
+
|
|
132
|
+
### Changed
|
|
133
|
+
|
|
134
|
+
- **CSS custom properties now work from an ancestor**, which is what the README
|
|
135
|
+
always described and the one thing that could not work: every `--ag-ui-*` default
|
|
136
|
+
was declared on `:host`, which sets the property *on the element*, and an
|
|
137
|
+
element's own value beats anything inherited. A consumer ran the full token map
|
|
138
|
+
on a wrapper for an entire build and concluded they had the names wrong. The
|
|
139
|
+
defaults now sit behind private aliases, so `:root`, a wrapper, the element and
|
|
140
|
+
an inline style all work and resolve in the usual order. **One vocabulary — the
|
|
141
|
+
public `--ag-ui-*` names are unchanged**, and a built-in `theme` / `density` /
|
|
142
|
+
`placement` preset still loses to an explicit page rule.
|
|
143
|
+
|
|
144
|
+
- **The flash is an `outline`, not a `box-shadow`**, and holds for **1200 ms** with
|
|
145
|
+
a fade rather than 200 ms. A shadow paints outside the border box, so any
|
|
146
|
+
`overflow: hidden` ancestor sharing the element's box — a card, a table cell —
|
|
147
|
+
clipped it entirely while the tool reported success. And 200 ms is below the
|
|
148
|
+
threshold at which someone who does not know where to look notices anything.
|
|
149
|
+
⭐ Neither our tests nor the consumer's could have found the second one:
|
|
150
|
+
headless Chromium hides the scroll race, and no automated check has an opinion
|
|
151
|
+
about whether a human sees a 200 ms ring.
|
|
152
|
+
|
|
153
|
+
- **The flash colour comes from the target's `--ag-ui-accent`** rather than a
|
|
154
|
+
hardcoded indigo, so a themed page is flashed in its own colour.
|
|
155
|
+
|
|
156
|
+
- **`prefersReducedMotion()` is now honoured where the README already claimed it
|
|
157
|
+
was.** The flash ignored it entirely while the docs said the preference was
|
|
158
|
+
"honoured throughout"; a consumer investigated reduced motion as the cause of an
|
|
159
|
+
invisible highlight on the strength of that sentence. Under reduced motion the
|
|
160
|
+
ring drops its fade but keeps its full hold — reduced motion asks for no
|
|
161
|
+
animation, not for no feedback. `typeInto` and `highlightThenClick` keep their
|
|
162
|
+
explicit-duration contract, and the docs now say so instead of overclaiming.
|
|
163
|
+
|
|
164
|
+
- **The tool and skill catalog fetches are deferred by one microtask**, so a React
|
|
165
|
+
`ref` assigned in the same commit as insertion is honoured. ⚠ The thread-history
|
|
166
|
+
request is deliberately **not** deferred: a deferred replay can land after a
|
|
167
|
+
`sendMessage()` and duplicate the transcript. Configure before you insert, or
|
|
168
|
+
call `reload()`; the new React recipe in the README shows both.
|
|
169
|
+
|
|
170
|
+
### Fixed
|
|
171
|
+
|
|
172
|
+
- **The resize grip now sits on the corner that actually moves.** The element
|
|
173
|
+
measures which edges its host's layout holds still and stamps them as
|
|
174
|
+
`data-resize-anchor="<y>-<x>"`, but the rules meant to read it were written as
|
|
175
|
+
`[data-resize-anchor~="left"]` — and `~=` matches whitespace-separated words
|
|
176
|
+
while the stamped value is a single hyphenated token, so they could never
|
|
177
|
+
match. ⚠ **The cursor rules used `=` and did match**, so the pointer followed
|
|
178
|
+
the measurement while the grip stayed where `placement` had guessed: for any
|
|
179
|
+
host that aligns the panel the other way, the cursor promised a diagonal the
|
|
180
|
+
grip was not on, and the grip sat on the corner that stays put.
|
|
181
|
+
|
|
182
|
+
Each anchor rule now sets **both** sides of its axis. One that flipped a
|
|
183
|
+
single way could not undo a placement guess that had flipped the other, which
|
|
184
|
+
put the grip back on the anchored corner for an embedded panel its host
|
|
185
|
+
right-aligns.
|
|
186
|
+
|
|
187
|
+
- **`placement="page"` gutters its composer to the same reading column as its
|
|
188
|
+
messages.** The rule was unscoped, which tied it on specificity with the base
|
|
189
|
+
`.input-row` rule that sets the `padding` shorthand later in the stylesheet;
|
|
190
|
+
source order decided and the shorthand won. ⇒ *No placement ever got the
|
|
191
|
+
gutter* — least of all the one it was written for, where the messages sat in a
|
|
192
|
+
centred column and the composer spanned the full width.
|
|
193
|
+
|
|
194
|
+
A duplicated copy of the whole resize block also sat earlier in the file,
|
|
195
|
+
welded to the preceding rule by a comment left between a selector and its
|
|
196
|
+
subject; it parsed as `:host([placement="page"]) .resize-handle`, scoping the
|
|
197
|
+
grip's base positioning to the one placement that hides it.
|
|
198
|
+
|
|
10
199
|
## [0.20.1] — 2026-08-11
|
|
11
200
|
|
|
12
201
|
### Fixed
|
|
@@ -1061,7 +1250,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1061
1250
|
### Notes
|
|
1062
1251
|
- First release — exercising the automated npm OIDC publish pipeline end-to-end.
|
|
1063
1252
|
|
|
1064
|
-
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.
|
|
1253
|
+
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.22.0...HEAD
|
|
1254
|
+
[0.22.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.21.0...v0.22.0
|
|
1255
|
+
[0.21.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.20.1...v0.21.0
|
|
1065
1256
|
[0.20.1]: https://github.com/Artui/ag-ui-web-component/compare/v0.20.0...v0.20.1
|
|
1066
1257
|
[0.20.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.19.0...v0.20.0
|
|
1067
1258
|
[0.19.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.18.0...v0.19.0
|