You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
`injectAgent()` MUST be called within an Angular injection context (component constructor or field initializer). Calling it in ngOnInit or any async context throws "NG0203: inject() must be called from an injection context".
`injectAgent()` MUST be called within an Angular injection context (component constructor or field initializer). Calling it in ngOnInit or any async context throws "NG0203: inject() must be called from an injection context".
"description": "Returns a new model with the key at `pointer` removed.\n\nEmpty string and `/` clear the whole model. Missing parent paths leave the\ninput model unchanged.",
"description": "Reads a value from a model using the package's simple slash-separated pointer syntax.\n\nEmpty string and `/` target the root. Segments are not RFC 6901-unescaped;\nnormalize keys before using pointers that would require `~0` or `~1`.",
"description": "Returns true when `value` is an A2UI boolean literal wrapper.",
947
953
"signature": "isLiteralBoolean(value: unknown): value is { literalBoolean: boolean }",
948
954
"params": [
949
955
{
@@ -962,7 +968,7 @@
962
968
{
963
969
"name": "isLiteralNumber",
964
970
"kind": "function",
965
-
"description": "",
971
+
"description": "Returns true when `value` is an A2UI number literal wrapper.",
966
972
"signature": "isLiteralNumber(value: unknown): value is { literalNumber: number }",
967
973
"params": [
968
974
{
@@ -981,7 +987,7 @@
981
987
{
982
988
"name": "isLiteralString",
983
989
"kind": "function",
984
-
"description": "",
990
+
"description": "Returns true when `value` is an A2UI string literal wrapper.",
985
991
"signature": "isLiteralString(value: unknown): value is { literalString: string }",
986
992
"params": [
987
993
{
@@ -1000,7 +1006,7 @@
1000
1006
{
1001
1007
"name": "isPathRef",
1002
1008
"kind": "function",
1003
-
"description": "",
1009
+
"description": "Returns true when `value` is an A2UI dynamic path reference.",
1004
1010
"signature": "isPathRef(value: unknown): value is { path: string }",
1005
1011
"params": [
1006
1012
{
@@ -1019,7 +1025,7 @@
1019
1025
{
1020
1026
"name": "resolveDynamic",
1021
1027
"kind": "function",
1022
-
"description": "",
1028
+
"description": "Resolves an A2UI dynamic value against a client data model.\n\nLiteral wrappers unwrap to their inner values, `{ path }` references read\nfrom the model by JSON-pointer path, arrays resolve recursively, and\nunrecognized plain values pass through unchanged.",
{"surfaceUpdate":{"surfaceId":"booking","components":[{"id":"root","component":{"Column":{"children":{"explicitList":["title","origin","submit"]}}}},{"id":"title","component":{"Text":{"text":"Book a flight","usageHint":"h2"}}},{"id":"origin","component":{"MultipleChoice":{"label":"Origin","options":[{"label":"LAX","value":"LAX"},{"label":"JFK","value":"JFK"}],"selections":{"path":"/origin"},"maxAllowedSelections":1}}},{"id":"submit_label","component":{"Text":{"text":"Search flights"}}},{"id":"submit","component":{"Button":{"child":"submit_label","primary":true,"action":{"name":"bookingSubmit","context":[{"key":"origin","value":{"path":"/origin"}},{"key":"dest","value":{"path":"/dest"}}]}}}}]}}
31
+
{"surfaceUpdate":{"surfaceId":"booking","components":[{"id":"root","component":{"Column":{"children":{"explicitList":["title","origin","submit"]}}}},{"id":"title","component":{"Text":{"text":{"literalString":"Book a flight"},"usageHint":"h2"}}},{"id":"origin","component":{"MultipleChoice":{"label":{"literalString":"Origin"},"options":[{"label":{"literalString":"LAX"},"value":"LAX"},{"label":{"literalString":"JFK"},"value":"JFK"}],"selections":{"path":"/origin"},"maxAllowedSelections":1}}},{"id":"submit_label","component":{"Text":{"text":{"literalString":"Search flights"}}}},{"id":"submit","component":{"Button":{"child":"submit_label","primary":true,"action":{"name":"bookingSubmit","context":[{"key":"origin","value":{"path":"/origin"}},{"key":"dest","value":{"path":"/dest"}}]}}}}]}}
Copy file name to clipboardExpand all lines: apps/website/content/docs/a2ui/guides/message-protocol.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,7 +15,7 @@ Every envelope carries that `surfaceId`. A `dataModelUpdate` for `"booking"` onl
15
15
As an **id-keyed adjacency list**. A `surfaceUpdate` carries a flat `components` array. Each entry has an `id` and a single `component` definition. Parent-child links are by id reference, not by nesting.
16
16
17
17
```json
18
-
{"surfaceUpdate":{"surfaceId":"booking","components":[{"id":"root","component":{"Column":{"children":{"explicitList":["title","origin","submit"]}}}},{"id":"title","component":{"Text":{"text":"Book a flight","usageHint":"h2"}}}]}}
18
+
{"surfaceUpdate":{"surfaceId":"booking","components":[{"id":"root","component":{"Column":{"children":{"explicitList":["title","origin","submit"]}}}},{"id":"title","component":{"Text":{"text":{"literalString":"Book a flight"},"usageHint":"h2"}}}]}}
19
19
```
20
20
21
21
The `component` value is a **keyed union**: a single-key object where the key names the component type and the value holds its props — `{ "<Name>": { props } }`. `{ "Text": { ... } }` is a Text, `{ "Column": { ... } }` is a Column. There's no separate `type` field; the key *is* the type.
@@ -69,7 +69,7 @@ The stream is a sequence of single-key envelope objects. The parser recognizes e
69
69
Defines (or replaces) the components for a surface.
Copy file name to clipboardExpand all lines: apps/website/content/docs/ag-ui/api/api-docs.json
+5-3Lines changed: 5 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -405,7 +405,7 @@
405
405
{
406
406
"name": "AgUiAgent",
407
407
"kind": "interface",
408
-
"description": "The neutral Agent contract, widened with the AG-UI adapter's optional\n`customEvents` signal (the chat composition feature-detects it to enable\nlive a2ui streaming) and the optional `clientTools` capability.\nMirrors langgraph's LangGraphAgent extension.",
408
+
"description": "The neutral Agent contract, widened with the AG-UI adapter's\n`customEvents` signal (the chat composition feature-detects it to enable\nlive a2ui streaming), the browser client-tools capability, and concrete\nACTIVITY-backed `subagents`.\nMirrors langgraph's LangGraphAgent extension where the protocol surfaces\noverlap.",
409
409
"properties": [
410
410
{
411
411
"name": "clientTools",
@@ -620,7 +620,7 @@
620
620
"description": ""
621
621
},
622
622
"examples": [
623
-
"```ts\nTestBed.configureTestingModule({\n providers: [provideFakeAgent({ responses: ['Hello from the fake agent'] })],\n});\n```"
623
+
"```ts\nTestBed.configureTestingModule({\n providers: [provideFakeAgent({ tokens: ['Hello from the fake agent'] })],\n});\n```"
624
624
]
625
625
},
626
626
{
@@ -646,6 +646,8 @@
646
646
"type": "AgUiAgent<>",
647
647
"description": ""
648
648
},
649
-
"examples": []
649
+
"examples": [
650
+
"```ts\nimport { HttpAgent } from '@ag-ui/client';\nimport { toAgent } from '@threadplane/ag-ui';\n\nconst agent = toAgent(new HttpAgent({ url: '/api/agent' }));\n```"
Copy file name to clipboardExpand all lines: apps/website/content/docs/ag-ui/api/inject-agent.mdx
+6-3Lines changed: 6 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -65,19 +65,22 @@ These fields are stable across runtime adapters and are what chat components con
65
65
66
66
## AG-UI-specific surface
67
67
68
-
The AG-UI adapter extends the neutral `Agent` contract with one additional signal:
68
+
The AG-UI adapter extends the neutral `Agent` contract with AG-UI-specific protocol surfaces:
69
69
70
70
| Field | Type | Description |
71
71
|-------|------|-------------|
72
72
|`customEvents()`|`CustomStreamEvent[]`| Custom events emitted by the backend during a run. Accumulates per run; resets on each new `submit()`. |
73
+
|`clientTools`|`ClientToolsCapability`| Browser client-tool catalog, pending calls, and result resolution used by `<chat [clientTools]>`. |
74
+
|`subagents()`|`Map<string, Subagent>`|`ACTIVITY_*` entries with `activityType: 'subagent'`, projected to the neutral subagent contract and keyed by `messageId`. |
73
75
74
-
`injectAgent()` returns the `AgUiAgent` type — the neutral `Agent` contract plus `customEvents`— so the signal is reachable directly, no cast required:
76
+
`injectAgent()` returns the `AgUiAgent` type — the neutral `Agent` contract plus these AG-UI-specific fields — so they are reachable directly, no cast required:
The chat a2ui bridge reads `customEvents` to light up live generative-UI streaming when your backend emits `a2ui-partial` events. The consuming side is documented in chat's [A2UI overview](/docs/chat/a2ui/overview). See the [Custom Events guide](/docs/ag-ui/guides/custom-events) for backend wiring details.
`toAgent()` returns an `AgUiAgent`, which extends the neutral `Agent` contract with one additional signal:
27
+
`toAgent()` returns an `AgUiAgent`, which extends the neutral `Agent` contract with AG-UI-specific protocol surfaces:
28
28
29
29
| Field | Type | Description |
30
30
|-------|------|-------------|
31
31
|`customEvents()`|`Signal<CustomStreamEvent[]>`| Custom events accumulated during a run. Resets at the start of each new run. |
32
+
|`clientTools`|`ClientToolsCapability`| Browser client-tool catalog, pending calls, and result resolution. The chat composition uses this when you pass `<chat [clientTools]>`. |
33
+
|`subagents()`|`Signal<Map<string, Subagent>>`|`ACTIVITY_*` events with `activityType: 'subagent'`, projected to the neutral subagent contract and keyed by `messageId`. |
32
34
33
35
The standard `Agent` signals (`messages`, `status`, `isLoading`, `error`, `toolCalls`, `state`, `interrupt`) and actions (`submit`, `stop`, `regenerate`) are all present.
Copy file name to clipboardExpand all lines: apps/website/content/docs/ag-ui/concepts/architecture.mdx
+12-3Lines changed: 12 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -88,7 +88,9 @@ Every AG-UI event is passed through the reducer. The reducer updates Angular sig
88
88
-`toolCalls` for tool call starts, arguments, results, and completion.
89
89
-`state` for AG-UI state snapshots and JSON Patch deltas.
90
90
-`interrupt` cleared on `RUN_STARTED` and set by the `CUSTOM``on_interrupt` event.
91
-
-`events$` for custom events.
91
+
-`events$` for runtime-neutral custom-event side effects.
92
+
-`customEvents` for accumulated non-`on_interrupt``CUSTOM` events used by live a2ui and app-specific reactive UI.
93
+
-`subagents` for `ACTIVITY_*` events with `activityType: 'subagent'`.
92
94
93
95
When the user submits input, the adapter builds a user message, appends it locally, adds it to the AG-UI source with `source.addMessage()`, then calls `source.runAgent()`.
94
96
@@ -106,6 +108,12 @@ the final tool-call surface; with it, surfaces build up live.
106
108
107
109
The consuming side — how the chat composition turns these events into rendered surfaces — lives in chat's [A2UI overview](/docs/chat/a2ui/overview).
108
110
111
+
## Browser client tools
112
+
113
+
`AgUiAgent.clientTools` is the browser-tool bridge consumed by `<chat [clientTools]>`. The chat composition registers the browser catalog on the agent; the adapter threads that catalog into every `source.runAgent({ tools })` call, exposes unresolved browser-owned tool calls through `clientTools.pending()`, and sends the browser result back as a tool message before continuing the run.
114
+
115
+
See chat's [Client Tools guide](/docs/chat/guides/client-tools) for declaring `action()`, `view()`, and `ask()` tools. With AG-UI, the backend must bind the supplied AG-UI tool specs and finish the turn without emitting `TOOL_CALL_RESULT` for browser-owned tools so the client can resolve them.
116
+
109
117
## Provider choices
110
118
111
119
Use `provideAgent()` when you have a real AG-UI HTTP endpoint.
@@ -188,9 +196,10 @@ The AG-UI adapter currently covers:
188
196
- Tool calls from `TOOL_CALL_*`.
189
197
- Shared state from `STATE_SNAPSHOT` and `STATE_DELTA`.
190
198
- Message replacement from `MESSAGES_SNAPSHOT`.
191
-
- Custom events from `CUSTOM`.
199
+
- Custom events from non-`on_interrupt``CUSTOM` events, surfaced through both `events$` and `customEvents`.
192
200
- Interrupts from `CUSTOM` events named `on_interrupt`.
193
-
- Subagent/activity progress from `ACTIVITY_SNAPSHOT` and `ACTIVITY_DELTA`.
201
+
- Browser client tools via `AgUiAgent.clientTools`.
202
+
- Subagent progress from `ACTIVITY_SNAPSHOT` and `ACTIVITY_DELTA` events whose `activityType` is `subagent`.
194
203
- Citations stored under `state.citations`.
195
204
196
205
These features are intentionally out of scope for the AG-UI adapter today:
`@threadplane/chat` provides the chat UI primitives. `@threadplane/ag-ui` provides the adapter that wires an AG-UI backend into the `Agent` contract those primitives consume.
16
+
`marked` is the required markdown parser peer used by `@threadplane/chat` when assistant messages render through `<chat>`.
0 commit comments