@artooi/ag-ui-web-component 0.35.1 → 0.36.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 +65 -1
- package/README.md +61 -15
- package/dist/ag-ui-web-component.bundle.js +37 -37
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +25 -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 +25 -1
- package/dist/core/agui_client.d.ts.map +1 -1
- package/dist/core/tool_outcome.d.ts +27 -0
- package/dist/core/tool_outcome.d.ts.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +86 -14
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
- package/src/constants.ts +26 -0
- package/src/core/ag_ui_chat.ts +30 -6
- package/src/core/agui_client.ts +105 -8
- package/src/core/tool_outcome.ts +36 -0
- package/src/index.ts +2 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,68 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.36.0] — 2026-09-05
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **A tool call that failed can now say so.** `TOOL_CALL_RESULT` may carry an
|
|
15
|
+
optional `outcome` field -- `success`, `failed` or `denied`, read off the new
|
|
16
|
+
`TOOL_OUTCOME` constant -- and the card settles to *done*, *error* or
|
|
17
|
+
*declined* accordingly. **Absent is a success**, so every server written before
|
|
18
|
+
the field existed renders exactly as it did, and so does any value this release
|
|
19
|
+
does not recognise: a card is a claim about what happened, and not knowing a
|
|
20
|
+
word is not grounds for claiming failure.
|
|
21
|
+
|
|
22
|
+
Nothing in `@ag-ui/core` declares the field. AG-UI's event schemas extend a
|
|
23
|
+
`passthrough` base, so an unknown key survives parsing and reaches the
|
|
24
|
+
subscriber -- asserted in `tests/ag_ui_event_contract.test.ts`, because if that
|
|
25
|
+
ever stops being true every card silently goes back to claiming success.
|
|
26
|
+
|
|
27
|
+
`AgUiClientHandlers.onToolResult` gains a third parameter for it, typed
|
|
28
|
+
`unknown` because the protocol does not validate it; `toolStatusFromOutcome`
|
|
29
|
+
does the narrowing. A handler written against the two-parameter form still
|
|
30
|
+
satisfies the interface and still behaves as before. A **frontend** tool states
|
|
31
|
+
its own outcome on the `ToolExecution` it returns, since no server ran it.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- **A refused tool call rendered as a successful one.** Every `TOOL_CALL_RESULT`
|
|
36
|
+
settled its card as *done*, whatever the server said, so a refusal arrived
|
|
37
|
+
green with the reason folded into its result body -- in a sibling demo, a
|
|
38
|
+
booking the server had declined read at a glance as a booking that was made.
|
|
39
|
+
`ERROR` and `DECLINED` existed and the card rendered all three distinctly; they
|
|
40
|
+
were simply unreachable from the server's side.
|
|
41
|
+
|
|
42
|
+
- **A reload turned every tool card green**, which was the same bug reached by a
|
|
43
|
+
second path and needed no server involvement at all: restoring a conversation
|
|
44
|
+
settled *every* historical `tool` message as *done*, so a confirmation the user
|
|
45
|
+
had cancelled came back as an action that went through. The outcome is now
|
|
46
|
+
persisted beside the tool message and read back through the same mapping the
|
|
47
|
+
live path uses.
|
|
48
|
+
|
|
49
|
+
It is written onto the copy handed to the store, never onto `agent.messages` --
|
|
50
|
+
so it does not travel back to the server on the next run -- and a store that
|
|
51
|
+
drops fields it does not know loses only the distinction, falling back to
|
|
52
|
+
*done*. `Message` does not declare the field, exactly as it does not declare
|
|
53
|
+
the `attachments` an upload rides on a user message.
|
|
54
|
+
|
|
55
|
+
## [0.35.2] — 2026-09-05
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
|
|
59
|
+
- **The README's two callouts rendered as code blocks.** This file is the
|
|
60
|
+
documentation -- there is no docs site, so it is what GitHub shows and what npm
|
|
61
|
+
puts on the package page -- and `!!! note` is MkDocs syntax that neither
|
|
62
|
+
understands. The line rendered literally and its indented body became a *code
|
|
63
|
+
block*, so a warning was displayed as something to copy. Both are now GitHub
|
|
64
|
+
callouts.
|
|
65
|
+
|
|
66
|
+
One of the two was 0.35.1's own note about forgetting `defineAgUiChat()`,
|
|
67
|
+
written because that failure is silent. A reader hit the same failure after it
|
|
68
|
+
shipped, which is how the rendering was found: the note was there, was
|
|
69
|
+
correct, and reached nobody. `tests/readme_renders.test.ts` now fails on any
|
|
70
|
+
admonition, and on the registration callout going missing.
|
|
71
|
+
|
|
10
72
|
## [0.35.1] — 2026-09-05
|
|
11
73
|
|
|
12
74
|
### Documentation
|
|
@@ -3415,7 +3477,9 @@ hosts that both arrange the page the way it expects.
|
|
|
3415
3477
|
### Notes
|
|
3416
3478
|
- First release — exercising the automated npm OIDC publish pipeline end-to-end.
|
|
3417
3479
|
|
|
3418
|
-
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.
|
|
3480
|
+
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.36.0...HEAD
|
|
3481
|
+
[0.36.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.35.2...v0.36.0
|
|
3482
|
+
[0.35.2]: https://github.com/Artui/ag-ui-web-component/compare/v0.35.1...v0.35.2
|
|
3419
3483
|
[0.35.1]: https://github.com/Artui/ag-ui-web-component/compare/v0.35.0...v0.35.1
|
|
3420
3484
|
[0.35.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.34.0...v0.35.0
|
|
3421
3485
|
[0.34.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.33.1...v0.34.0
|
package/README.md
CHANGED
|
@@ -149,16 +149,18 @@ Drop the element into your page and register the tools the agent may call:
|
|
|
149
149
|
<ag-ui-chat endpoint="/agent/" title-text="Assistant"></ag-ui-chat>
|
|
150
150
|
```
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
152
|
+
> [!IMPORTANT]
|
|
153
|
+
> **If nothing appears, check that `defineAgUiChat()` ran.** Forgetting it looks
|
|
154
|
+
> like nothing at all. `<ag-ui-chat>` is then an *unknown element*, which every
|
|
155
|
+
> browser renders as an inline 0x0 box, in flow, with no console warning and no
|
|
156
|
+
> error — so the page looks finished and the chat is simply absent. There is
|
|
157
|
+
> nothing to search for.
|
|
158
|
+
>
|
|
159
|
+
> A bare `import "@artooi/ag-ui-web-component"` registers nothing, deliberately:
|
|
160
|
+
> registration is an explicit call so the package stays tree-shakeable.
|
|
161
|
+
>
|
|
162
|
+
> `customElements.get("ag-ui-chat")` in a console answers it in one line.
|
|
163
|
+
> `undefined` means the call did not run.
|
|
162
164
|
|
|
163
165
|
That's the whole integration: an `endpoint` attribute pointing at your AG-UI server, optional
|
|
164
166
|
`headers`, and the tools you want the agent to be able to invoke in the browser. If your API is on
|
|
@@ -553,6 +555,38 @@ card (honouring `data-tool-display`), so server-side output is visible too. The
|
|
|
553
555
|
and context are read **fresh on every run** (`getTools()` / `getContext()`), so they always reflect
|
|
554
556
|
the current page state.
|
|
555
557
|
|
|
558
|
+
#### A tool call that failed
|
|
559
|
+
|
|
560
|
+
A `TOOL_CALL_RESULT` may carry an optional **`outcome`** field saying how the call ended. It takes
|
|
561
|
+
pydantic-ai's own `ToolReturnPart` vocabulary — read the values off `TOOL_OUTCOME`:
|
|
562
|
+
|
|
563
|
+
| `outcome` | Card | Means |
|
|
564
|
+
| --- | --- | --- |
|
|
565
|
+
| *(absent)* | done | A result, said the way every server has always said it. |
|
|
566
|
+
| `success` | done | The same thing, stated. |
|
|
567
|
+
| `failed` | error | The call ran and failed. |
|
|
568
|
+
| `denied` | declined | A person or a guard refused it, so it never ran. |
|
|
569
|
+
|
|
570
|
+
**Absent is a success, and anything unrecognised is too** — including a value from a later protocol
|
|
571
|
+
version, and pydantic-ai's own `interrupted`. A card is a claim about what happened, and refusing to
|
|
572
|
+
recognise a word is not grounds for claiming failure. So no server has to change to keep the
|
|
573
|
+
rendering it has today, and a server that adds the field gets the truth on screen instead of a
|
|
574
|
+
green card with a refusal folded inside it.
|
|
575
|
+
|
|
576
|
+
Nothing in `@ag-ui/core` needs to declare the field: AG-UI's event schemas are zod `passthrough`, so
|
|
577
|
+
an unknown key survives parsing and reaches the subscriber. It arrives on
|
|
578
|
+
`AgUiClientHandlers.onToolResult` as an optional third argument, typed `unknown` because the
|
|
579
|
+
protocol does not validate it; `toolStatusFromOutcome` does the narrowing.
|
|
580
|
+
|
|
581
|
+
A **frontend** tool never streams this event — the client posts its own result — so its outcome is
|
|
582
|
+
recorded on the `ToolExecution` the executor returns (`{ content, outcome: "denied" }`). That covers
|
|
583
|
+
the two refusals the component makes itself: a confirmation card the user declined, and a call
|
|
584
|
+
blocked because the page moved under the round.
|
|
585
|
+
|
|
586
|
+
Either way the outcome is **persisted beside the tool message**, so a reload replays the card as it
|
|
587
|
+
settled rather than as a plain result. See
|
|
588
|
+
[MPA durability](#mpa-durability-surviving-full-page-reloads).
|
|
589
|
+
|
|
556
590
|
The catalog a run advertises is also the set that run can execute. Override `getTools` to scope
|
|
557
591
|
what a page offers — say, exposing `delete_record` only where deleting makes sense — and a call
|
|
558
592
|
naming a tool you withheld is treated exactly as a call naming a tool you never registered: no
|
|
@@ -1668,11 +1702,11 @@ Retry sits on the **last** answer only. Re-running an older turn is branching,
|
|
|
1668
1702
|
and for a page-driving agent editing a past turn is not neutral — those turns
|
|
1669
1703
|
clicked buttons, and re-running turn 3 does not un-save what turn 5 saved.
|
|
1670
1704
|
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1705
|
+
> [!NOTE]
|
|
1706
|
+
> A retried turn **re-runs its tools.** The previous attempt already did what it
|
|
1707
|
+
> did, and this does not undo it. Confirmation still applies, so a destructive
|
|
1708
|
+
> tool asks again — unless the user waived it for this session with
|
|
1709
|
+
> *Always allow*.
|
|
1676
1710
|
|
|
1677
1711
|
A failed run gets the same row, with Retry and Copy and no rating: error text is
|
|
1678
1712
|
what people paste into a bug report, but "the connection dropped" is not a
|
|
@@ -1921,6 +1955,15 @@ On mount the element rehydrates the transcript from the store, so the chat looks
|
|
|
1921
1955
|
including tool-call cards and their results (reconstructed from the persisted `toolCalls` and `tool`
|
|
1922
1956
|
messages), not just the text turns.
|
|
1923
1957
|
|
|
1958
|
+
A tool message is saved with an extra **`outcome`** field when the call did not simply succeed, in
|
|
1959
|
+
the same vocabulary the wire uses (see [A tool call that failed](#a-tool-call-that-failed)), so a
|
|
1960
|
+
failed or declined card replays as failed or declined instead of turning green on reload. `Message`
|
|
1961
|
+
does not declare the field, exactly as it does not declare the `attachments` an upload rides on a
|
|
1962
|
+
user message; the default store round-trips both through `JSON.stringify`. **A store that drops
|
|
1963
|
+
unknown fields loses only the distinction** — the card falls back to *done*, which is what it did
|
|
1964
|
+
before. It is written onto the copy handed to the store and never onto `agent.messages`, so it is
|
|
1965
|
+
not sent back to the server on the next run.
|
|
1966
|
+
|
|
1924
1967
|
**3. Resumable loop (`x-navigates` + `navigationResult`).** A tool whose schema carries
|
|
1925
1968
|
`x-navigates: true` (use `X_NAVIGATES_KEY`; read back by [`isNavigates`](src/tools/is_navigates.ts))
|
|
1926
1969
|
triggers a full reload. Before the handler navigates, the element writes a checkpoint
|
|
@@ -2395,6 +2438,8 @@ re-export point. Internal modules import from leaf paths.
|
|
|
2395
2438
|
| `AgUiClient` | class | Orchestration layer over an AG-UI `AbstractAgent`. |
|
|
2396
2439
|
| `AgUiClientConfig` / `AgUiClientHandlers` / `AgUiRunInputs` | type | Client config, lifecycle handlers, per-run input providers. |
|
|
2397
2440
|
| `AgUiToolCall` / `ToolExecution` / `ExecuteTool` | type | Tool-call shape, execution result, executor signature. |
|
|
2441
|
+
| `ToolOutcome` | type | The `TOOL_OUTCOME` values as a union. |
|
|
2442
|
+
| `toolStatusFromOutcome` | function | Map a wire outcome to the card status it settles into; anything absent or unrecognised is a success. |
|
|
2398
2443
|
| `ConnectionLostError` | class | Raised (→ `onError`) when a run's stream closes with no terminal AG-UI event. |
|
|
2399
2444
|
| `createHttpAgent(options)` | function | Default agent factory (wraps `HttpAgent`). |
|
|
2400
2445
|
| `AgentFactory` / `HttpAgentOptions` | type | Factory signature and its options. |
|
|
@@ -2549,6 +2594,7 @@ re-export point. Internal modules import from leaf paths.
|
|
|
2549
2594
|
| `MESSAGE_ACTIONS` | The message-action tokens `data-message-actions` selects by (`copy` / `retry` / `feedback`). |
|
|
2550
2595
|
| `TOOL_CALL_STATUS` | Tool-call card status constants. |
|
|
2551
2596
|
| `TOOL_DISPLAY` | Tool-call display-mode constants (`inline` / `minimal` / `compact` / `full`). |
|
|
2597
|
+
| `TOOL_OUTCOME` | How a tool call ended, as a server states it on `TOOL_CALL_RESULT` (`success` / `failed` / `denied`). |
|
|
2552
2598
|
| `X_CONFIRM_KEY` | Confirmation-prompt key: on a tool's JSON Schema for a client-side confirmation, and in an AG-UI interrupt's `metadata` for a server-side approval. |
|
|
2553
2599
|
| `X_SUMMARY_KEY` | JSON-Schema key carrying a short tool-card label. |
|
|
2554
2600
|
| `MAX_TOOL_ROUNDS` | Upper bound on tool-call → re-run rounds per send. |
|