@artooi/ag-ui-web-component 0.14.1 → 0.16.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 +105 -1
- package/README.md +13 -2
- package/dist/ag-ui-web-component.bundle.js +60 -59
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/core/agui_client.d.ts.map +1 -1
- package/dist/core/conversation_store.d.ts.map +1 -1
- package/dist/core/remote_conversation_store.d.ts.map +1 -1
- package/dist/core/run_index.d.ts.map +1 -1
- package/dist/index.js +890 -493
- package/dist/index.js.map +4 -4
- package/dist/tools/client_tool_registry.d.ts.map +1 -1
- package/dist/tools/page_action_tools.d.ts.map +1 -1
- package/dist/tools/route_map.d.ts.map +1 -1
- package/dist/ui/attachment_tray.d.ts.map +1 -1
- package/dist/ui/checkpoint_menu.d.ts.map +1 -1
- package/dist/ui/render_markdown.d.ts.map +1 -1
- package/dist/ui/skills_menu.d.ts.map +1 -1
- package/dist/ui/thoughts_block.d.ts.map +1 -1
- package/dist/ui/thread_drawer.d.ts.map +1 -1
- package/dist/ui/tool_call_card.d.ts.map +1 -1
- package/dist/ui/ui_strings.d.ts +4 -0
- package/dist/ui/ui_strings.d.ts.map +1 -1
- package/dist/ui/voice_input.d.ts.map +1 -1
- package/package.json +11 -8
- package/src/constants.ts +10 -0
- package/src/core/ag_ui_chat.ts +86 -3
- package/src/core/remote_conversation_store.ts +2 -2
- package/src/tools/route_map.ts +5 -8
- package/src/ui/render_markdown.ts +29 -9
- package/src/ui/ui_strings.ts +7 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,108 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.16.0] — 2026-08-09
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **A stale-page guard on frontend tool calls.** A round's context records the
|
|
15
|
+
page it describes; if the page moves before the agent's tool call arrives, the
|
|
16
|
+
call is refused with a result telling the agent to call `read_page` and retry,
|
|
17
|
+
instead of running the handler. Most stale calls would simply miss and report
|
|
18
|
+
a failure — the case this prevents is the other one, where a same-named
|
|
19
|
+
control on the *new* page matches and the agent silently acts on the wrong
|
|
20
|
+
page. `read_page` itself and tools marked `x-navigates` are exempt, and the
|
|
21
|
+
guard is inert unless a `getPageMap` provider is set.
|
|
22
|
+
- **New `UiStrings` keys `runInterrupted` and `pageMoved`**, both overridable
|
|
23
|
+
like every other string.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **Toolchain majors: Vitest 3 → 4 and TypeScript 5.9 → 7**, plus `marked`
|
|
28
|
+
18.0.9, Biome 2.5.7, `@types/node` 26.1.2. All development dependencies — the
|
|
29
|
+
emitted `.d.ts` files are **byte-identical** to the 5.9 output (verified by
|
|
30
|
+
building both and diffing; only the source maps move), so consumers see no
|
|
31
|
+
change.
|
|
32
|
+
|
|
33
|
+
⚠ **Vitest 4 takes a provider *instance*, not the string `"playwright"`.**
|
|
34
|
+
The provider moved to its own package (`@vitest/browser-playwright`) and, with
|
|
35
|
+
v8 coverage, the old string form is a hard error rather than a deprecation.
|
|
36
|
+
|
|
37
|
+
⚠ **TypeScript 7 requires `rootDir` explicitly** (TS5011) instead of
|
|
38
|
+
inferring it from the common source directory. Set to the value 5.x inferred,
|
|
39
|
+
so the published layout is unchanged.
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- **A run interrupted by navigation no longer vanishes silently.** If the page
|
|
44
|
+
navigates or reloads while a run is in flight — routine in an MPA — the
|
|
45
|
+
element is destroyed with it, and on the next mount the transcript replayed
|
|
46
|
+
with the answer simply missing and no indication anything had gone wrong. The
|
|
47
|
+
element now reports it as an inline notice. Detected from the shape of the
|
|
48
|
+
transcript (`send()` persists the user turn *before* starting the run, so a
|
|
49
|
+
history ending on that turn means nothing came back), which is why it needs no
|
|
50
|
+
`ClientConversationStore` change and no `pagehide` listener — neither of which
|
|
51
|
+
would fire on a crash or a force-quit anyway.
|
|
52
|
+
|
|
53
|
+
It is deliberately **a notice, not a resume**: AG-UI has no
|
|
54
|
+
resume-an-aborted-run primitive, so re-sending the accumulated messages is
|
|
55
|
+
semantically a new run and would re-execute any server-side tool the agent had
|
|
56
|
+
already performed. The agent-initiated case is unaffected — a navigating tool
|
|
57
|
+
still checkpoints and resumes exactly as before.
|
|
58
|
+
|
|
59
|
+
- **Six branches that were never actually covered.** Vitest 4's v8 provider
|
|
60
|
+
remaps coverage more precisely, and the 100% gate stopped being satisfiable —
|
|
61
|
+
not because anything regressed, but because v3 had been crediting six
|
|
62
|
+
branches and three callbacks that no test reached. Each is now genuinely
|
|
63
|
+
tested: the paperclip button opening the file picker, the built-in
|
|
64
|
+
transcription handler (every prior voice test supplied its own), a page-action
|
|
65
|
+
tool resolving through `resolvePageTarget`, a non-`Enter` keystroke in a
|
|
66
|
+
question card, a submit click with no answer, a non-string `error` in a
|
|
67
|
+
transcription error body, and a restored history message with an unrecognised
|
|
68
|
+
role.
|
|
69
|
+
|
|
70
|
+
⭐ **One was a flaw in the test harness, not a missing test.** `makeFakeAgent`
|
|
71
|
+
ended a clean run by calling `onRunFinalized` alone, so the client's
|
|
72
|
+
`RUN_FINISHED` path could only ever be reached through `emit.interrupt()` —
|
|
73
|
+
the ordinary success outcome every real run carries was never exercised. The
|
|
74
|
+
fake now emits both events, in the order a real agent does.
|
|
75
|
+
|
|
76
|
+
`route_map`'s unreachable guard was restructured away rather than tested: its
|
|
77
|
+
regex capture group is mandatory, so the `undefined` case existed only to
|
|
78
|
+
satisfy `noUncheckedIndexedAccess` and no test could ever have reached it.
|
|
79
|
+
|
|
80
|
+
## [0.15.0] — 2026-08-08
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
|
|
84
|
+
- **Sanitisation is now tested in a real browser.** `vitest.config.ts` defines
|
|
85
|
+
two projects: **happy-dom** for the bulk of the suite, and **Chromium**
|
|
86
|
+
(Playwright) for the tests whose subject is sanitisation. Coverage stays
|
|
87
|
+
unified at 100% across both.
|
|
88
|
+
|
|
89
|
+
⚠ **A correctness requirement, not an optimisation.** DOMPurify 3.4.8+
|
|
90
|
+
silently stops sanitising under happy-dom — `<script>` and `<img>` pass
|
|
91
|
+
straight through, and ordinary markdown loses its `<p>` wrapper. A
|
|
92
|
+
happy-dom-only suite can therefore go green while this component ships no
|
|
93
|
+
sanitisation at all, which is the one failure it must never ship.
|
|
94
|
+
|
|
95
|
+
⭐ **The experiment settles what the pin never could**: dompurify 3.4.13
|
|
96
|
+
sanitises correctly in Chromium. The defect is happy-dom's DOM emulation, not
|
|
97
|
+
a DOMPurify regression — so **consumers were never exposed**, and the risk was
|
|
98
|
+
confined to the test environment the whole time.
|
|
99
|
+
|
|
100
|
+
The browser run also *removes* a workaround instead of carrying it: happy-dom
|
|
101
|
+
eagerly **executed** inline `<script>` while DOMPurify parsed into its scratch
|
|
102
|
+
document, so the suite had to stub `alert`. A real browser parses into an
|
|
103
|
+
inert context.
|
|
104
|
+
|
|
105
|
+
### Security
|
|
106
|
+
|
|
107
|
+
- **`dompurify` is a normal caret range again** (`^3.4.13`), lifting the
|
|
108
|
+
exact-version pin — and with it the **five advisories** that pin was holding
|
|
109
|
+
open (three LOW, two MEDIUM). The browser project is what made that safe, and
|
|
110
|
+
is the standing acceptance check.
|
|
111
|
+
|
|
10
112
|
## [0.14.1] — 2026-08-07
|
|
11
113
|
|
|
12
114
|
### Security
|
|
@@ -646,7 +748,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
646
748
|
### Notes
|
|
647
749
|
- First release — exercising the automated npm OIDC publish pipeline end-to-end.
|
|
648
750
|
|
|
649
|
-
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.
|
|
751
|
+
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.16.0...HEAD
|
|
752
|
+
[0.16.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.15.0...v0.16.0
|
|
753
|
+
[0.15.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.14.1...v0.15.0
|
|
650
754
|
[0.14.1]: https://github.com/Artui/ag-ui-web-component/compare/v0.14.0...v0.14.1
|
|
651
755
|
[0.14.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.13.0...v0.14.0
|
|
652
756
|
[0.13.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.12.0...v0.13.0
|
package/README.md
CHANGED
|
@@ -648,13 +648,24 @@ chat.routeMap = [
|
|
|
648
648
|
|
|
649
649
|
**`getPageMap(): PageMap`** — a per-run provider returning the current page's compact actionable
|
|
650
650
|
surface (field names/types/labels, button labels+handles — *not* values). It is auto-injected into
|
|
651
|
-
each run's `context` as a `page_map` entry (toggle with `autoInjectPageMap`)
|
|
652
|
-
so it reflects the page the agent is currently looking at:
|
|
651
|
+
each run's `context` as a `page_map` entry (toggle with `autoInjectPageMap`):
|
|
653
652
|
|
|
654
653
|
```js
|
|
655
654
|
chat.getPageMap = () => ({ fields: introspectForm(), buttons: visibleButtons() });
|
|
656
655
|
```
|
|
657
656
|
|
|
657
|
+
It is recomputed at the top of **every tool round**, not once per `send()` — so after the agent
|
|
658
|
+
acts, the next round already sees the resulting page. Within a round the agent can pull a fresh
|
|
659
|
+
view at any time with the built-in `read_page` tool, which is registered whenever this provider is
|
|
660
|
+
set.
|
|
661
|
+
|
|
662
|
+
That leaves one window: the page can move *after* a round's context was built but *before* the
|
|
663
|
+
agent's tool call arrives — the user clicks a link, or presses back. Calls landing in that window
|
|
664
|
+
are **refused** with a result telling the agent to call `read_page` and retry. Most would have
|
|
665
|
+
missed anyway; the guard exists for the case where a same-named control on the new page matches and
|
|
666
|
+
the agent would otherwise act on the wrong page without either side noticing. `read_page` and tools
|
|
667
|
+
marked `x-navigates` are exempt, and the guard is inert when no `getPageMap` is set.
|
|
668
|
+
|
|
658
669
|
**`registerPageState({ name, read, write?, schema? })`** — ergonomic sugar over `registerTool` for
|
|
659
670
|
SPA app state (Redux/Zustand/signals). It auto-generates a `read_<name>` (read-only) tool and, when
|
|
660
671
|
`write` is supplied, a `set_<name>` tool stamped `x-destructive`:
|