@artooi/ag-ui-web-component 0.16.0 → 0.18.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 CHANGED
@@ -7,6 +7,135 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.18.0] — 2026-08-10
11
+
12
+ ### Added
13
+
14
+ - **A copy button on code blocks in agent answers.** An agent answering with
15
+ code is answering with something the reader means to *use*, and selecting it
16
+ by hand out of a scrolling transcript — inside a shadow root, in a narrow
17
+ sidebar — was the one interaction the chat surface made harder than the page
18
+ around it.
19
+
20
+ Revealed on hover **and keyboard focus** (hidden-until-hover is invisible to a
21
+ keyboard user), styleable via the `code-copy` part, with `copyCode` /
22
+ `copied` / `copyFailed` in `UiStrings`.
23
+
24
+ ⚠ **It reports failure rather than always claiming success.** The Clipboard
25
+ API needs a secure context and is simply absent in some embeddings; a button
26
+ that always says "Copied" sends the reader off to paste stale clipboard
27
+ content and find out somewhere else entirely.
28
+
29
+ ### Fixed
30
+
31
+ - **A bare `data-prompt-chips` or `data-slash-commands` now enables the
32
+ feature**, instead of silently disabling it. Both were compared against the
33
+ string `"true"`, so writing the attribute bare — the spelling every native
34
+ boolean attribute uses, and the one a reader reaches for first — turned off
35
+ the thing it names, with nothing to indicate why the chips never appeared.
36
+ `="false"` still turns them off.
37
+
38
+ - **The checkpoint panel manages focus.** It declared `role="dialog"` and took
39
+ no focus at all, so a keyboard user was left behind an open dialog; the thread
40
+ drawer had done this correctly all along. Focus now moves in on open, is
41
+ restored on close, and Tab is trapped while it is open.
42
+
43
+ ⚠ **With no continuable runs the panel holds no controls**, so the panel
44
+ itself is focusable as the fallback — otherwise "move focus to the first
45
+ control" silently does nothing in exactly the case where the user has least to
46
+ go on.
47
+
48
+ - **The README described a `dist/ag-ui-web-component.bundle.css` that the build
49
+ has never emitted.** The styles are a template literal injected into the
50
+ shadow root, so there is no sidecar to load — and a reader looking for the
51
+ file to override was looking for the wrong seam. Documented as CSS custom
52
+ properties and `part` attributes instead.
53
+
54
+ ## [0.17.0] — 2026-08-10
55
+
56
+ ### Added
57
+
58
+ - **`sendMessage(content, attachments?)`** — send as if the user had typed it:
59
+ user bubble, `ag-ui-submit`, run started. The programmatic half of the
60
+ composer, for an "Ask about this order" button, a command palette, or a
61
+ composer of your own replacing the built-in one. The built-in Send now reads
62
+ the composer, clears it, and calls this, so the two paths cannot drift.
63
+
64
+ It no-ops while a run is in flight — a second concurrent run would orphan the
65
+ first — and for an entirely empty message. ⚠ Unlike the built-in Send it does
66
+ **not** consult the attachment tray: what you pass is what is sent, so a host
67
+ composer stays in charge of its own state.
68
+
69
+ - **`attachFile(file)`** — queue a file into the tray exactly as the picker and
70
+ drag-and-drop do, with the same validation and progress chip. Returns `false`
71
+ when uploads are not configured (no `data-attachments-url`, no
72
+ `uploadHandler`), which is the only way for a host to tell: with no tray there
73
+ is nothing to report through, and silence would read as a queued file that
74
+ never uploads.
75
+
76
+ - **`ag-ui-attachments` event**, dispatched whenever the tray changes — a file
77
+ queued, an upload finishing or failing, a chip removed, the tray cleared after
78
+ a send. `detail` carries `{ attachments, pending }`: the durable refs of
79
+ everything settled, and how many are still in flight.
80
+
81
+ ⭐ **This is what makes `sendMessage` usable with files at all.** The tray only
82
+ ever spoke to the built-in Send button, so a host composer had no way to tell a
83
+ settled upload from one still uploading — the same information the built-in
84
+ Send needs, which was simply not exposed. The tray's `onChange` hook already
85
+ existed and nothing was wired to it.
86
+
87
+ ### Changed
88
+
89
+ - **Assigning a connect-time-only attribute after the element has connected now
90
+ warns**, instead of being silently ignored: `data-attachments-url`,
91
+ `data-attachment-accept`, `data-attachment-max-bytes`, `data-transcribe-url`,
92
+ `data-threads-url`, `data-tools-url`, `data-skills-url`, `data-skills`,
93
+ `data-prompt-chips`, `data-slash-commands`, `data-theme-toggle`,
94
+ `data-strings`, `data-icon-url`.
95
+
96
+ Each is read once while connecting, to decide what chrome exists at all, and
97
+ no later read revisits the decision. ⚠ **The symptom is an affordance that
98
+ simply never appears** — which reads as a broken component rather than a
99
+ mis-timed assignment, and it is the common React/Vue shape: the element mounts
100
+ on the first render pass and the framework patches attributes in on the next.
101
+
102
+ Set them before the element enters the DOM, or remove and re-insert it to
103
+ apply a new value. ⭐ The attributes that genuinely *are* re-read per use —
104
+ `data-runs-url`, `data-page-actions`, `data-text-animation`,
105
+ `data-tool-display`, `endpoint`, and CSS-reactive `theme` / `collapsed` — are
106
+ deliberately excluded, since a late change works there and a warning would be
107
+ wrong.
108
+
109
+ ### Fixed
110
+
111
+ - **The checkpoint panel now follows the theme.** Its rules read `--agui-surface`
112
+ / `--agui-border` / `--agui-hover` — note `--agui-`, not the `--ag-ui-`
113
+ namespace every other rule uses — each with a hardcoded light-mode fallback.
114
+ So the panel ignored `theme="dark"` entirely and rendered light-on-dark unless
115
+ a host happened to set three variables documented nowhere. Now derived from the
116
+ real theme tokens, with a new theme-aware `--ag-ui-hover` defined in every
117
+ theme block. ⭐ The fallbacks are what hid it: they made an unthemed panel look
118
+ deliberate.
119
+
120
+ `checkpoints-title` and `checkpoint-label` also gain `part` attributes — they
121
+ carried classes only, so neither could be styled from outside the shadow root.
122
+
123
+ - **Markdown tables are styled.** `table` / `thead` / `tbody` / `tr` / `th` /
124
+ `td` are all in the sanitizer's `ALLOWED_TAGS`, so an agent emitting a table
125
+ rendered it — completely unstyled, overflowing its bubble. Wide tables now
126
+ scroll inside their own box rather than pushing the layout sideways.
127
+
128
+ - **Sending while a file is still uploading now says so.** `readyRefs()` returns
129
+ only settled uploads and `clearReady()` deliberately keeps the rest for a
130
+ follow-up message — so the file was never lost, but the message went without
131
+ it and nothing indicated that. Attachments are frequently the entire point of
132
+ the message, which is what made the silence the defect. An inline notice now
133
+ names how many are still uploading and that they remain attached.
134
+
135
+ Send is deliberately **not** disabled while uploads are pending: that would
136
+ fight the tray's documented "keep for a follow-up" behaviour and could wedge
137
+ on an upload that never settles.
138
+
10
139
  ## [0.16.0] — 2026-08-09
11
140
 
12
141
  ### Added
@@ -748,7 +877,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
748
877
  ### Notes
749
878
  - First release — exercising the automated npm OIDC publish pipeline end-to-end.
750
879
 
751
- [Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.16.0...HEAD
880
+ [Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.18.0...HEAD
881
+ [0.18.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.17.0...v0.18.0
882
+ [0.17.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.16.0...v0.17.0
752
883
  [0.16.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.15.0...v0.16.0
753
884
  [0.15.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.14.1...v0.15.0
754
885
  [0.14.1]: https://github.com/Artui/ag-ui-web-component/compare/v0.14.0...v0.14.1
package/README.md CHANGED
@@ -150,8 +150,8 @@ That's the whole integration: an `endpoint` attribute pointing at your AG-UI ser
150
150
  | `title-text` | — | Header label; defaults to `"Assistant"`. The only **observed** attribute (live-updates the header). |
151
151
  | `data-tool-display` | `toolDisplay` | Tool-call card detail: `inline` / `minimal` / `compact` / `full` (default `full`). |
152
152
  | `data-text-animation` | — | Incoming-text reveal: `none` (default) / `fade` / `word`. |
153
- | `data-prompt-chips` | — | `"true"` to surface skills as chips. |
154
- | `data-slash-commands` | — | `"true"` to enable the `/`-command palette. |
153
+ | `data-prompt-chips` | — | Present (bare, or any value but `"false"`) to surface skills as chips. |
154
+ | `data-slash-commands` | — | Present (bare, or any value but `"false"`) to enable the `/`-command palette. |
155
155
  | `data-skills` | — | Inline JSON skill catalog. |
156
156
  | `data-skills-url` | — | URL of a JSON skill catalog (fetched with `headers`). |
157
157
  | `data-tools-url` | — | URL of a server tool-label catalog (`[{ name, summary, description? }]`), fetched with `headers`; labels tool-call cards for server-side tools. |
@@ -194,8 +194,39 @@ labels are fetched automatically — per card, `x-summary` → an explicit
194
194
 
195
195
  **Properties** (selected): `sharedState` — AG-UI shared state (documented under Tools & state).
196
196
 
197
- **Methods**: `registerTool`, `registerPageState`, `setSkills`, `appendMessage`, `newChat`,
198
- `setCollapsed`, `toggleCollapsed`.
197
+ Code blocks in an agent's answer carry a **copy button**, revealed on hover or
198
+ keyboard focus and styleable via the `code-copy` part. Override its labels with
199
+ the `copyCode` / `copied` / `copyFailed` strings.
200
+
201
+ **Methods**: `registerTool`, `registerPageState`, `setSkills`, `sendMessage`, `attachFile`,
202
+ `appendMessage`, `newChat`, `setCollapsed`, `toggleCollapsed`.
203
+
204
+ ### Sending from your own UI
205
+
206
+ `sendMessage(content, attachments?)` sends as if the user had typed it — user bubble,
207
+ `ag-ui-submit` event, run started. Use it for an "Ask about this order" button, a command
208
+ palette, or a composer of your own replacing the built-in one. It no-ops while a run is in
209
+ flight and for an entirely empty message, and unlike the built-in Send it does **not** consult
210
+ the attachment tray: what you pass is what is sent, so your composer stays in charge of its
211
+ own state.
212
+
213
+ `attachFile(file)` queues a file into the tray exactly as the picker and drag-and-drop do, with
214
+ the same validation and progress chip. It returns `false` when uploads are not configured
215
+ (no `data-attachments-url` and no `uploadHandler`) — the only way to tell, since with no tray
216
+ there is nothing to report through.
217
+
218
+ Uploading is asynchronous, so watch `ag-ui-attachments` for the result. Its `detail` carries
219
+ `{ attachments, pending }`: the durable refs of everything that has finished, and how many are
220
+ still in flight. Send once `pending` is `0`, or you will leave files behind.
221
+
222
+ ```js
223
+ chat.addEventListener("ag-ui-attachments", (e) => {
224
+ const { attachments, pending } = e.detail;
225
+ sendButton.disabled = pending > 0;
226
+ sendButton.onclick = () => chat.sendMessage(input.value, attachments);
227
+ });
228
+ chat.attachFile(fileInput.files[0]);
229
+ ```
199
230
 
200
231
  A self-contained live playground lives in [`demo/`](demo/) — run `make demo` to serve it against a
201
232
  mock AG-UI server.
@@ -1162,10 +1193,14 @@ This produces, into `dist/`:
1162
1193
  them.
1163
1194
  - `ag-ui-web-component.bundle.js` — the **vendored** ESM bundle, every dependency inlined and
1164
1195
  minified, suitable for direct `<script type="module">` embedding.
1165
- - `ag-ui-web-component.bundle.css` — the extracted CSS sidecar.
1166
1196
  - `index.d.ts` (+ source maps) — type declarations; emitted `.js` import specifiers are preserved
1167
1197
  so consumers resolve types without extra flags.
1168
1198
 
1199
+ There is **no CSS file to load**. The styles are a template literal injected into
1200
+ the shadow root at construction, so they ship inside the JS and cannot leak into
1201
+ the host page. Restyle through the [CSS custom properties](#theming-density-and-placement) and the
1202
+ `part` attributes, not a stylesheet override.
1203
+
1169
1204
  Other workflow targets (all identical in name to the sibling Python packages):
1170
1205
 
1171
1206
  | Target | What it does |