@assistant-ui/mcp-docs-server 0.1.30 → 0.1.31
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/.docs/organized/code-examples/waterfall.md +1 -1
- package/.docs/organized/code-examples/with-a2a.md +2 -2
- package/.docs/organized/code-examples/with-ag-ui.md +3 -3
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +5 -5
- package/.docs/organized/code-examples/with-artifacts.md +5 -5
- package/.docs/organized/code-examples/with-assistant-transport.md +3 -3
- package/.docs/organized/code-examples/with-chain-of-thought.md +79 -50
- package/.docs/organized/code-examples/with-cloud-standalone.md +4 -4
- package/.docs/organized/code-examples/with-cloud.md +4 -4
- package/.docs/organized/code-examples/with-custom-thread-list.md +56 -11
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +7 -7
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +7 -7
- package/.docs/organized/code-examples/with-expo.md +16 -16
- package/.docs/organized/code-examples/with-external-store.md +2 -2
- package/.docs/organized/code-examples/with-ffmpeg.md +5 -5
- package/.docs/organized/code-examples/with-generative-ui.md +5 -5
- package/.docs/organized/code-examples/with-google-adk.md +4 -4
- package/.docs/organized/code-examples/with-heat-graph.md +1 -1
- package/.docs/organized/code-examples/with-interactables.md +5 -5
- package/.docs/organized/code-examples/with-langchain.md +3 -3
- package/.docs/organized/code-examples/with-langgraph.md +3 -3
- package/.docs/organized/code-examples/with-livekit.md +8 -8
- package/.docs/organized/code-examples/with-opencode.md +99 -54
- package/.docs/organized/code-examples/with-parent-id-grouping.md +4 -4
- package/.docs/organized/code-examples/with-react-hook-form.md +5 -5
- package/.docs/organized/code-examples/with-react-ink.md +1 -1
- package/.docs/organized/code-examples/with-react-router.md +8 -8
- package/.docs/organized/code-examples/with-store.md +1 -1
- package/.docs/organized/code-examples/with-tanstack.md +5 -5
- package/.docs/organized/code-examples/with-tap-runtime.md +2 -2
- package/.docs/raw/docs/(docs)/cli.mdx +2 -1
- package/.docs/raw/docs/(docs)/copilots/assistant-frame.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +10 -3
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +8 -3
- package/.docs/raw/docs/(docs)/copilots/make-assistant-visible.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/motivation.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/use-assistant-instructions.mdx +1 -0
- package/.docs/raw/docs/(docs)/devtools.mdx +1 -0
- package/.docs/raw/docs/(docs)/index.mdx +1 -0
- package/.docs/raw/docs/(docs)/installation.mdx +1 -0
- package/.docs/raw/docs/(docs)/rtl.mdx +1 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +34 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/feedback-speech.mdx +41 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +26 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +34 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +31 -0
- package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +20 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +26 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +72 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +41 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +48 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +30 -0
- package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +23 -0
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +21 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +7 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +65 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +50 -6
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +15 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +36 -1
- package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +38 -0
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +5 -0
- package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +144 -6
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +230 -2
- package/.docs/raw/docs/cloud/ai-sdk.mdx +221 -3
- package/.docs/raw/docs/cloud/langgraph.mdx +274 -2
- package/.docs/raw/docs/{(docs)/guides → guides}/attachments.mdx +41 -36
- package/.docs/raw/docs/guides/branching.mdx +76 -0
- package/.docs/raw/docs/guides/chain-of-thought.mdx +166 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/context-api.mdx +50 -22
- package/.docs/raw/docs/{(docs)/guides → guides}/dictation.mdx +2 -0
- package/.docs/raw/docs/guides/editing.mdx +102 -0
- package/.docs/raw/docs/guides/index.mdx +103 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/interactables.mdx +49 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/latex.mdx +51 -8
- package/.docs/raw/docs/{(docs)/guides → guides}/mentions.mdx +61 -86
- package/.docs/raw/docs/{(docs)/guides → guides}/message-timing.mdx +8 -2
- package/.docs/raw/docs/{(docs)/guides → guides}/multi-agent.mdx +64 -4
- package/.docs/raw/docs/{(docs)/guides → guides}/quoting.mdx +10 -17
- package/.docs/raw/docs/{(docs)/guides → guides}/slash-commands.mdx +103 -37
- package/.docs/raw/docs/guides/speech.mdx +156 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/suggestions.mdx +21 -83
- package/.docs/raw/docs/{(docs)/guides → guides}/tool-ui.mdx +108 -36
- package/.docs/raw/docs/{(docs)/guides → guides}/tools.mdx +131 -35
- package/.docs/raw/docs/{(docs)/guides → guides}/voice.mdx +39 -0
- package/.docs/raw/docs/ink/index.mdx +1 -3
- package/.docs/raw/docs/ink/migration.mdx +1 -3
- package/.docs/raw/docs/ink/primitives.mdx +37 -1
- package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +520 -0
- package/.docs/raw/docs/integrations/auth/better-auth.mdx +191 -0
- package/.docs/raw/docs/integrations/auth/clerk.mdx +172 -0
- package/.docs/raw/docs/integrations/auth/next-auth.mdx +196 -0
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +79 -0
- package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +188 -0
- package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +57 -0
- package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +201 -0
- package/.docs/raw/docs/integrations/gateways/index.mdx +157 -0
- package/.docs/raw/docs/integrations/index.mdx +173 -0
- package/.docs/raw/docs/integrations/observability/helicone.mdx +130 -0
- package/.docs/raw/docs/integrations/observability/langfuse.mdx +156 -0
- package/.docs/raw/docs/integrations/observability/langsmith.mdx +146 -0
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +712 -0
- package/.docs/raw/docs/integrations/tools/mcp.mdx +267 -0
- package/.docs/raw/docs/primitives/action-bar.mdx +1 -0
- package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -0
- package/.docs/raw/docs/primitives/attachment.mdx +1 -0
- package/.docs/raw/docs/primitives/branch-picker.mdx +1 -0
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +90 -85
- package/.docs/raw/docs/primitives/composer.mdx +2 -1
- package/.docs/raw/docs/primitives/error.mdx +1 -0
- package/.docs/raw/docs/primitives/index.mdx +2 -1
- package/.docs/raw/docs/primitives/message.mdx +68 -5
- package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -0
- package/.docs/raw/docs/primitives/suggestion.mdx +1 -0
- package/.docs/raw/docs/primitives/thread-list.mdx +39 -0
- package/.docs/raw/docs/primitives/thread.mdx +16 -13
- package/.docs/raw/docs/react-native/index.mdx +1 -3
- package/.docs/raw/docs/react-native/migration.mdx +1 -3
- package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +396 -0
- package/.docs/raw/docs/runtimes/a2a/overview.mdx +60 -0
- package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +216 -0
- package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +70 -0
- package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +243 -0
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +123 -0
- package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +52 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +71 -131
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +69 -63
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +330 -123
- package/.docs/raw/docs/runtimes/concepts/adapters.mdx +265 -0
- package/.docs/raw/docs/runtimes/concepts/architecture.mdx +125 -0
- package/.docs/raw/docs/runtimes/concepts/stability.mdx +67 -0
- package/.docs/raw/docs/runtimes/concepts/threads.mdx +428 -0
- package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +703 -0
- package/.docs/raw/docs/runtimes/custom/data-stream.mdx +323 -0
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +253 -1236
- package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +746 -0
- package/.docs/raw/docs/runtimes/custom/overview.mdx +71 -0
- package/.docs/raw/docs/runtimes/google-adk/api.mdx +256 -0
- package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +717 -0
- package/.docs/raw/docs/runtimes/google-adk/overview.mdx +69 -0
- package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +229 -0
- package/.docs/raw/docs/runtimes/langchain.mdx +533 -0
- package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +305 -0
- package/.docs/raw/docs/runtimes/langgraph/interrupts.mdx +104 -0
- package/.docs/raw/docs/runtimes/langgraph/overview.mdx +84 -0
- package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +496 -0
- package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +127 -0
- package/.docs/raw/docs/runtimes/langgraph/threads.mdx +113 -0
- package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +3 -3
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +0 -23
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +1 -1
- package/.docs/raw/docs/runtimes/opencode/hooks.mdx +191 -0
- package/.docs/raw/docs/runtimes/opencode/overview.mdx +48 -0
- package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +119 -0
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +71 -203
- package/.docs/raw/docs/ui/accordion.mdx +1 -0
- package/.docs/raw/docs/ui/assistant-modal.mdx +1 -0
- package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -0
- package/.docs/raw/docs/ui/attachment.mdx +1 -0
- package/.docs/raw/docs/ui/badge.mdx +1 -0
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +1 -0
- package/.docs/raw/docs/ui/context-display.mdx +1 -0
- package/.docs/raw/docs/ui/diff-viewer.mdx +1 -0
- package/.docs/raw/docs/ui/directive-text.mdx +1 -0
- package/.docs/raw/docs/ui/file.mdx +1 -0
- package/.docs/raw/docs/ui/image.mdx +1 -0
- package/.docs/raw/docs/ui/markdown.mdx +2 -14
- package/.docs/raw/docs/ui/mermaid.mdx +1 -0
- package/.docs/raw/docs/ui/message-timing.mdx +3 -2
- package/.docs/raw/docs/ui/model-selector.mdx +1 -0
- package/.docs/raw/docs/ui/part-grouping.mdx +325 -313
- package/.docs/raw/docs/ui/quote.mdx +1 -0
- package/.docs/raw/docs/ui/reasoning.mdx +66 -33
- package/.docs/raw/docs/ui/scrollbar.mdx +1 -0
- package/.docs/raw/docs/ui/select.mdx +1 -0
- package/.docs/raw/docs/ui/sources.mdx +1 -0
- package/.docs/raw/docs/ui/streamdown.mdx +1 -0
- package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -0
- package/.docs/raw/docs/ui/tabs.mdx +1 -0
- package/.docs/raw/docs/ui/thread-list.mdx +17 -0
- package/.docs/raw/docs/ui/thread.mdx +56 -1
- package/.docs/raw/docs/ui/tool-fallback.mdx +1 -0
- package/.docs/raw/docs/ui/tool-group.mdx +39 -11
- package/.docs/raw/docs/ui/voice.mdx +1 -0
- package/.docs/raw/docs/utilities/heat-graph.mdx +1 -0
- package/.docs/raw/docs/utilities/react-o11y.mdx +278 -0
- package/.docs/raw/docs/utilities/tw-shimmer.mdx +1 -0
- package/package.json +3 -3
- package/src/tools/tests/path-traversal.test.ts +1 -1
- package/.docs/raw/docs/(docs)/guides/branching.mdx +0 -65
- package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +0 -164
- package/.docs/raw/docs/(docs)/guides/editing.mdx +0 -66
- package/.docs/raw/docs/(docs)/guides/speech.mdx +0 -38
- package/.docs/raw/docs/runtimes/a2a/index.mdx +0 -298
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +0 -1033
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +0 -314
- package/.docs/raw/docs/runtimes/custom/local.mdx +0 -1464
- package/.docs/raw/docs/runtimes/data-stream.mdx +0 -422
- package/.docs/raw/docs/runtimes/google-adk/index.mdx +0 -686
- package/.docs/raw/docs/runtimes/helicone.mdx +0 -61
- package/.docs/raw/docs/runtimes/langchain/comparison.mdx +0 -60
- package/.docs/raw/docs/runtimes/langchain/index.mdx +0 -210
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +0 -699
- package/.docs/raw/docs/runtimes/langgraph/tutorial/index.mdx +0 -12
- package/.docs/raw/docs/runtimes/langserve.mdx +0 -116
- package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +0 -218
- package/.docs/raw/docs/runtimes/mastra/overview.mdx +0 -18
- package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +0 -217
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Message
|
|
3
3
|
description: Build custom message rendering with content parts, attachments, and hover state.
|
|
4
|
+
platforms: ["react"]
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
import { MessagePrimitiveSample } from "@/components/docs/samples/message-primitive";
|
|
@@ -108,7 +109,7 @@ Runtime setup: primitives require runtime context. Wrap your UI in `AssistantRun
|
|
|
108
109
|
```
|
|
109
110
|
|
|
110
111
|
<Callout type="info">
|
|
111
|
-
For most new `MessagePrimitive.Parts`
|
|
112
|
+
For most new code, prefer `MessagePrimitive.Parts` with a `children` render function. When you need adjacent grouping, use `MessagePrimitive.GroupedParts`.
|
|
112
113
|
</Callout>
|
|
113
114
|
|
|
114
115
|
### Tool Resolution
|
|
@@ -145,7 +146,7 @@ Returning `null` still allows registered tool UIs and data renderer UIs to rende
|
|
|
145
146
|
|
|
146
147
|
- `ToolGroup` wraps consecutive tool-call parts
|
|
147
148
|
- `ReasoningGroup` wraps consecutive reasoning parts
|
|
148
|
-
- `components.ChainOfThought` takes over all reasoning and tool-call rendering (mutually exclusive with `ToolGroup`, `ReasoningGroup`, `tools`, and `Reasoning`).
|
|
149
|
+
- `components.ChainOfThought` takes over all reasoning and tool-call rendering (mutually exclusive with `ToolGroup`, `ReasoningGroup`, `tools`, and `Reasoning`). This legacy path is deprecated; use `MessagePrimitive.GroupedParts` for grouped Chain of Thought in new code.
|
|
149
150
|
- `data.by_name` and `data.Fallback` let you route custom data part types
|
|
150
151
|
- `Quote` renders quoted message references from metadata
|
|
151
152
|
- `Empty` and `Unstable_Audio` are available for edge and experimental rendering paths
|
|
@@ -187,7 +188,7 @@ Returning `null` still allows registered tool UIs and data renderer UIs to rende
|
|
|
187
188
|
/>
|
|
188
189
|
```
|
|
189
190
|
|
|
190
|
-
For new code, use the `children` render function instead.
|
|
191
|
+
For new code, use the `children` render function or `GroupedParts` instead.
|
|
191
192
|
|
|
192
193
|
### Hover State
|
|
193
194
|
|
|
@@ -247,6 +248,45 @@ Renders each content part with type-based component resolution.
|
|
|
247
248
|
|
|
248
249
|
<PrimitivesTypeTable type="MessagePrimitivePartsProps" parameters={MessagePrimitiveDocs.Parts.props} />
|
|
249
250
|
|
|
251
|
+
### GroupedParts
|
|
252
|
+
|
|
253
|
+
Groups adjacent message parts into a nested tree. Use `groupBy` to return group keys for parts that should be grouped, then switch on `part.type` in the render function. Group cases render `children`; leaf cases render their own UI.
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
<MessagePrimitive.GroupedParts
|
|
257
|
+
groupBy={(part) => {
|
|
258
|
+
if (part.type === "reasoning")
|
|
259
|
+
return ["group-chainOfThought", "group-reasoning"];
|
|
260
|
+
if (part.type === "tool-call")
|
|
261
|
+
return ["group-chainOfThought", "group-tool"];
|
|
262
|
+
return null;
|
|
263
|
+
}}
|
|
264
|
+
>
|
|
265
|
+
{({ part, children }) => {
|
|
266
|
+
switch (part.type) {
|
|
267
|
+
case "group-chainOfThought":
|
|
268
|
+
return <div>{children}</div>;
|
|
269
|
+
case "group-reasoning":
|
|
270
|
+
return <ReasoningRoot>{children}</ReasoningRoot>;
|
|
271
|
+
case "group-tool":
|
|
272
|
+
return <ToolGroupRoot>{children}</ToolGroupRoot>;
|
|
273
|
+
case "text":
|
|
274
|
+
return <MarkdownText />;
|
|
275
|
+
case "reasoning":
|
|
276
|
+
return <Reasoning {...part} />;
|
|
277
|
+
case "tool-call":
|
|
278
|
+
return part.toolUI ?? <ToolFallback {...part} />;
|
|
279
|
+
case "data":
|
|
280
|
+
return part.dataRendererUI;
|
|
281
|
+
default:
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
}}
|
|
285
|
+
</MessagePrimitive.GroupedParts>
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
<PrimitivesTypeTable type="MessagePrimitiveGroupedPartsProps" parameters={MessagePrimitiveDocs.GroupedParts.props} />
|
|
289
|
+
|
|
250
290
|
### Content
|
|
251
291
|
|
|
252
292
|
Legacy alias for `Parts`.
|
|
@@ -340,7 +380,7 @@ Renders quote metadata when the current message includes a quote. Place it above
|
|
|
340
380
|
|
|
341
381
|
### Unstable_PartsGrouped
|
|
342
382
|
|
|
343
|
-
Groups
|
|
383
|
+
Groups parts by a custom grouping function *(unstable; use `GroupedParts` for adjacent grouping)*.
|
|
344
384
|
|
|
345
385
|
```tsx
|
|
346
386
|
<MessagePrimitive.Unstable_PartsGrouped
|
|
@@ -453,9 +493,32 @@ import { ErrorPrimitive, MessagePrimitive } from "@assistant-ui/react";
|
|
|
453
493
|
|
|
454
494
|
`ErrorPrimitive.Root` renders a `<div>` container with `role="alert"` and `ErrorPrimitive.Message` renders a `<span>` that displays the error text. `Root` always renders. Only `Message` conditionally returns `null` when there is no error. Wrap in `<MessagePrimitive.Error>` if you want the entire block to be conditional. See the [ErrorPrimitive API Reference](/docs/api-reference/primitives/error) for full details.
|
|
455
495
|
|
|
496
|
+
### Render After Stream Completes
|
|
497
|
+
|
|
498
|
+
To render content only once the assistant message has finished streaming (a follow-up card, a feedback prompt, a generated component that should not flicker through partial states), gate it with [`AuiIf`](/docs/api-reference/primitives/assistant-if) on `s.message.status`:
|
|
499
|
+
|
|
500
|
+
```tsx
|
|
501
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
502
|
+
|
|
503
|
+
<MessagePrimitive.Root>
|
|
504
|
+
<MessagePrimitive.Parts />
|
|
505
|
+
|
|
506
|
+
<AuiIf
|
|
507
|
+
condition={(s) =>
|
|
508
|
+
s.message.role === "assistant" &&
|
|
509
|
+
s.message.status?.type === "complete"
|
|
510
|
+
}
|
|
511
|
+
>
|
|
512
|
+
<FollowUpCard />
|
|
513
|
+
</AuiIf>
|
|
514
|
+
</MessagePrimitive.Root>;
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
`s.message.status` is a discriminated union of `running | requires-action | complete | incomplete`, defined only on assistant messages. The `role === "assistant"` guard keeps the predicate type-safe. For tool-call-driven generative UI that defers rendering inside the part itself, see [Deferred Rendering](/docs/guides/tool-ui#deferred-rendering) in the Generative UI guide.
|
|
518
|
+
|
|
456
519
|
### Legacy and Unstable APIs
|
|
457
520
|
|
|
458
|
-
- `MessagePrimitive.Unstable_PartsGrouped` and `MessagePrimitive.Unstable_PartsGroupedByParentId` are unstable APIs for custom grouping.
|
|
521
|
+
- `MessagePrimitive.Unstable_PartsGrouped` and `MessagePrimitive.Unstable_PartsGroupedByParentId` are unstable APIs for non-adjacent custom grouping.
|
|
459
522
|
- `Unstable_PartsGroupedByParentId` is deprecated in favor of `Unstable_PartsGrouped`.
|
|
460
523
|
|
|
461
524
|
### Role-Based Styling
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: ThreadList
|
|
3
3
|
description: Multi-thread management for listing, creating, switching, archiving, and deleting conversations.
|
|
4
|
+
platforms: ["react"]
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
import { ThreadListPrimitiveSample } from "@/components/docs/samples/thread-list-primitive";
|
|
@@ -218,6 +219,44 @@ Renders a single thread at a specific index.
|
|
|
218
219
|
|
|
219
220
|
<PrimitivesTypeTable type="ThreadListPrimitiveItemByIndexProps" parameters={ThreadListPrimitiveDocs.ItemByIndex.props} />
|
|
220
221
|
|
|
222
|
+
#### LoadMore
|
|
223
|
+
|
|
224
|
+
Button that appends the next page of threads. Renders a `<button>` element unless `asChild` is set, and is automatically disabled when the runtime is loading or when the adapter's last `list()` did not return a `nextCursor`. See [Threads concepts](/docs/runtimes/concepts/threads#paginating-the-thread-list) for the adapter contract.
|
|
225
|
+
|
|
226
|
+
```tsx
|
|
227
|
+
<ThreadListPrimitive.LoadMore className="rounded-lg border px-3 py-2 text-sm">
|
|
228
|
+
Load more
|
|
229
|
+
</ThreadListPrimitive.LoadMore>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
For scroll-driven loading, wrap `aui.threads().loadMore()` in your own `IntersectionObserver` at the application layer; assistant-ui ships the explicit button to keep the primitive surface predictable.
|
|
233
|
+
|
|
234
|
+
```tsx
|
|
235
|
+
import { useAui, useAuiState } from "@assistant-ui/react";
|
|
236
|
+
import { useEffect, useRef } from "react";
|
|
237
|
+
|
|
238
|
+
function LoadMoreSentinel() {
|
|
239
|
+
const aui = useAui();
|
|
240
|
+
const disabled = useAuiState(
|
|
241
|
+
(s) =>
|
|
242
|
+
!s.threads.hasMore || s.threads.isLoading || s.threads.isLoadingMore,
|
|
243
|
+
);
|
|
244
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
245
|
+
|
|
246
|
+
useEffect(() => {
|
|
247
|
+
const el = ref.current;
|
|
248
|
+
if (!el || disabled) return;
|
|
249
|
+
const observer = new IntersectionObserver(([entry]) => {
|
|
250
|
+
if (entry?.isIntersecting) aui.threads().loadMore();
|
|
251
|
+
});
|
|
252
|
+
observer.observe(el);
|
|
253
|
+
return () => observer.disconnect();
|
|
254
|
+
}, [aui, disabled]);
|
|
255
|
+
|
|
256
|
+
return disabled ? null : <div ref={ref} className="h-9" />;
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
221
260
|
### ThreadListItemPrimitive
|
|
222
261
|
|
|
223
262
|
#### Root
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Thread
|
|
3
3
|
description: Build custom scrollable message containers with auto-scroll, empty states, and message rendering.
|
|
4
|
+
platforms: ["react"]
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
import { ThreadPrimitiveSample } from "@/components/docs/samples/thread-primitive";
|
|
@@ -123,7 +124,18 @@ By default, new messages appear at the bottom and scroll down. With `turnAnchor=
|
|
|
123
124
|
</ThreadPrimitive.Viewport>
|
|
124
125
|
```
|
|
125
126
|
|
|
126
|
-
|
|
127
|
+
When `turnAnchor="top"` is set, `MessagePrimitive.Root` automatically registers the latest assistant message as the top-anchor target and the preceding user message as the anchor — no additional component is required. The viewport itself manages a stable reserve element that provides the missing scroll range while the assistant response grows. This is the behavior used by the [Thread](/docs/ui/thread) component by default.
|
|
128
|
+
|
|
129
|
+
Use `topAnchorMessageClamp` to control how much of a long user message remains visible when `turnAnchor="top"`. Messages up to `tallerThan` stay fully visible. For messages taller than that, `visibleHeight` controls how much of the message's bottom edge remains visible above the assistant response:
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
<ThreadPrimitive.Viewport
|
|
133
|
+
turnAnchor="top"
|
|
134
|
+
topAnchorMessageClamp={{ tallerThan: "10em", visibleHeight: "6em" }}
|
|
135
|
+
>
|
|
136
|
+
{/* messages */}
|
|
137
|
+
</ThreadPrimitive.Viewport>
|
|
138
|
+
```
|
|
127
139
|
|
|
128
140
|
### Viewport Scroll Options
|
|
129
141
|
|
|
@@ -274,18 +286,9 @@ Provides viewport context without rendering a scrollable element. Use this when
|
|
|
274
286
|
|
|
275
287
|
### ViewportSlack
|
|
276
288
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
<MessagePrimitive.Root>
|
|
281
|
-
<MessagePrimitive.Parts />
|
|
282
|
-
<ThreadPrimitive.ViewportSlack>
|
|
283
|
-
<div className="min-h-[40vh]" />
|
|
284
|
-
</ThreadPrimitive.ViewportSlack>
|
|
285
|
-
</MessagePrimitive.Root>
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
Props: `fillClampThreshold` and `fillClampOffset` control how the slack height is calculated. `children` is required.
|
|
289
|
+
<Callout type="warn">
|
|
290
|
+
`ThreadPrimitive.ViewportSlack` has been removed from the public API. Top-anchor target registration is handled automatically by `MessagePrimitive.Root` when `turnAnchor="top"`. Remove `ViewportSlack` from your tree; if you customized `fillClampThreshold` or `fillClampOffset` on `ViewportSlack` or `MessagePrimitive.Root`, replace those props with `topAnchorMessageClamp` on `ThreadPrimitive.Viewport`.
|
|
291
|
+
</Callout>
|
|
289
292
|
|
|
290
293
|
### Messages
|
|
291
294
|
|
|
@@ -49,9 +49,7 @@ If you prefer to add assistant-ui to an existing Expo project, follow these step
|
|
|
49
49
|
|
|
50
50
|
### Install dependencies
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
npx expo install @assistant-ui/react-native @assistant-ui/react-ai-sdk
|
|
54
|
-
```
|
|
52
|
+
<InstallCommand expo={["@assistant-ui/react-native", "@assistant-ui/react-ai-sdk"]} />
|
|
55
53
|
|
|
56
54
|
</Step>
|
|
57
55
|
<Step>
|
|
@@ -29,9 +29,7 @@ If you already have an assistant-ui web app, most of your code transfers directl
|
|
|
29
29
|
|
|
30
30
|
### Install the React Native package
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
npx expo install @assistant-ui/react-native
|
|
34
|
-
```
|
|
32
|
+
<InstallCommand expo={["@assistant-ui/react-native"]} />
|
|
35
33
|
|
|
36
34
|
</Step>
|
|
37
35
|
<Step>
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Client and hooks
|
|
3
|
+
description: A2AClient, useA2ARuntime options, hooks, task states, artifacts, errors.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
import { Network } from "lucide-react";
|
|
7
|
+
|
|
8
|
+
Deep dive on the runtime's API surface. Start with [overview](/docs/runtimes/a2a) and [quickstart](/docs/runtimes/a2a/quickstart) if you have not already.
|
|
9
|
+
|
|
10
|
+
## A2AClient
|
|
11
|
+
|
|
12
|
+
The built-in `A2AClient` handles all communication with the A2A server: JSON serialization, SSE streaming, ProtoJSON enum normalization, and structured error handling.
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { A2AClient } from "@assistant-ui/react-a2a";
|
|
16
|
+
|
|
17
|
+
const client = new A2AClient({
|
|
18
|
+
baseUrl: "https://my-agent.example.com",
|
|
19
|
+
headers: { Authorization: "Bearer <token>" },
|
|
20
|
+
tenant: "my-org",
|
|
21
|
+
extensions: ["urn:a2a:ext:my-extension"],
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Pass a pre-built client to `useA2ARuntime`:
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
const runtime = useA2ARuntime({ client });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Client options
|
|
32
|
+
|
|
33
|
+
| Option | Type | Description |
|
|
34
|
+
| --- | --- | --- |
|
|
35
|
+
| `baseUrl` | `string` | Base URL of the A2A server. |
|
|
36
|
+
| `basePath` | `string` | Optional path prefix for API endpoints (e.g. `"/v1"`). Does not affect agent card discovery. |
|
|
37
|
+
| `headers` | `Record<string, string>` or `() => Record<string, string>` | Static or dynamic headers (e.g. for auth tokens). |
|
|
38
|
+
| `tenant` | `string` | Tenant ID for multi-tenant servers (prepended to URL paths). |
|
|
39
|
+
| `extensions` | `string[]` | Extension URIs to negotiate via `A2A-Extensions` header. |
|
|
40
|
+
|
|
41
|
+
### Client methods
|
|
42
|
+
|
|
43
|
+
| Method | Description |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| `sendMessage(message, configuration?, metadata?)` | Send a message (non-streaming). |
|
|
46
|
+
| `streamMessage(message, configuration?, metadata?)` | Send a message with SSE streaming. |
|
|
47
|
+
| `getTask(taskId, historyLength?)` | Get a task by ID. |
|
|
48
|
+
| `listTasks(request?)` | List tasks with filtering and pagination. |
|
|
49
|
+
| `cancelTask(taskId, metadata?)` | Cancel an in-progress task. |
|
|
50
|
+
| `subscribeToTask(taskId)` | Subscribe to SSE updates for a task. |
|
|
51
|
+
| `getAgentCard()` | Fetch the agent card from `/.well-known/agent-card.json`. |
|
|
52
|
+
| `getExtendedAgentCard()` | Fetch the extended (authenticated) agent card. |
|
|
53
|
+
| `createTaskPushNotificationConfig(config)` | Create a push notification config. |
|
|
54
|
+
| `getTaskPushNotificationConfig(taskId, configId)` | Get a push notification config. |
|
|
55
|
+
| `listTaskPushNotificationConfigs(taskId)` | List push notification configs. |
|
|
56
|
+
| `deleteTaskPushNotificationConfig(taskId, configId)` | Delete a push notification config. |
|
|
57
|
+
|
|
58
|
+
## useA2ARuntime options
|
|
59
|
+
|
|
60
|
+
Pass either a pre-built `client` or a `baseUrl` (the runtime creates a client for you). Other options layer on top.
|
|
61
|
+
|
|
62
|
+
| Option | Type | Description |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `client` | `A2AClient` | Pre-built A2A client instance (provide this OR `baseUrl`). |
|
|
65
|
+
| `baseUrl` | `string` | A2A server URL (creates a client automatically). |
|
|
66
|
+
| `basePath` | `string` | Path prefix for API endpoints. Only used with `baseUrl`. |
|
|
67
|
+
| `tenant` | `string` | Tenant ID for multi-tenant servers. Only used with `baseUrl`. |
|
|
68
|
+
| `headers` | `Record<string, string>` or `() => Record<string, string>` | Headers for the auto-created client. |
|
|
69
|
+
| `extensions` | `string[]` | Extension URIs to negotiate. Only used with `baseUrl`. |
|
|
70
|
+
| `contextId` | `string` | Initial context ID for the conversation. |
|
|
71
|
+
| `configuration` | `A2ASendMessageConfiguration` | Default send message configuration. |
|
|
72
|
+
| `onError` | `(error: Error) => void` | Error callback. |
|
|
73
|
+
| `onCancel` | `() => void` | Cancellation callback. |
|
|
74
|
+
| `onArtifactComplete` | `(artifact: A2AArtifact) => void` | Fired when an incremental artifact finishes. |
|
|
75
|
+
| `adapters.attachments` | `AttachmentAdapter` | Custom attachment handling. See [adapters](/docs/runtimes/concepts/adapters#attachment-adapter). |
|
|
76
|
+
| `adapters.speech` | `SpeechSynthesisAdapter` | Text-to-speech. See [adapters](/docs/runtimes/concepts/adapters#speech-adapter). |
|
|
77
|
+
| `adapters.feedback` | `FeedbackAdapter` | Feedback collection. See [adapters](/docs/runtimes/concepts/adapters#feedback-adapter). |
|
|
78
|
+
| `adapters.history` | `ThreadHistoryAdapter` | Message persistence. See [adapters](/docs/runtimes/concepts/adapters#history-adapter). |
|
|
79
|
+
| `adapters.threadList` | `UseA2AThreadListAdapter` | Thread switching. See [threads](/docs/runtimes/concepts/threads). |
|
|
80
|
+
|
|
81
|
+
## Hooks
|
|
82
|
+
|
|
83
|
+
### Task state
|
|
84
|
+
|
|
85
|
+
`useA2ATask` returns the current A2A task object, including task state and status message.
|
|
86
|
+
|
|
87
|
+
<PlatformTabs>
|
|
88
|
+
<Tab value="React">
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import { useA2ATask } from "@assistant-ui/react-a2a";
|
|
92
|
+
|
|
93
|
+
function TaskStatus() {
|
|
94
|
+
const task = useA2ATask();
|
|
95
|
+
if (!task) return null;
|
|
96
|
+
return (
|
|
97
|
+
<div>
|
|
98
|
+
Task {task.id}: {task.status.state}
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
</Tab>
|
|
105
|
+
<Tab value="React Native">
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { useA2ATask } from "@assistant-ui/react-a2a";
|
|
109
|
+
import { Text, View } from "react-native";
|
|
110
|
+
|
|
111
|
+
function TaskStatus() {
|
|
112
|
+
const task = useA2ATask();
|
|
113
|
+
if (!task) return null;
|
|
114
|
+
return (
|
|
115
|
+
<View>
|
|
116
|
+
<Text>
|
|
117
|
+
Task {task.id}: {task.status.state}
|
|
118
|
+
</Text>
|
|
119
|
+
</View>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
</Tab>
|
|
125
|
+
<Tab value="React Ink">
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
import { useA2ATask } from "@assistant-ui/react-a2a";
|
|
129
|
+
import { Text } from "ink";
|
|
130
|
+
|
|
131
|
+
function TaskStatus() {
|
|
132
|
+
const task = useA2ATask();
|
|
133
|
+
if (!task) return null;
|
|
134
|
+
return (
|
|
135
|
+
<Text>
|
|
136
|
+
Task {task.id}: {task.status.state}
|
|
137
|
+
</Text>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
</Tab>
|
|
143
|
+
</PlatformTabs>
|
|
144
|
+
|
|
145
|
+
### Artifacts list
|
|
146
|
+
|
|
147
|
+
`useA2AArtifacts` returns the artifacts generated by the current task.
|
|
148
|
+
|
|
149
|
+
<PlatformTabs>
|
|
150
|
+
<Tab value="React">
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
import { useA2AArtifacts } from "@assistant-ui/react-a2a";
|
|
154
|
+
|
|
155
|
+
function ArtifactList() {
|
|
156
|
+
const artifacts = useA2AArtifacts();
|
|
157
|
+
return (
|
|
158
|
+
<ul>
|
|
159
|
+
{artifacts.map((artifact) => (
|
|
160
|
+
<li key={artifact.artifactId}>
|
|
161
|
+
{artifact.name}: {artifact.parts.length} parts
|
|
162
|
+
</li>
|
|
163
|
+
))}
|
|
164
|
+
</ul>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
</Tab>
|
|
170
|
+
<Tab value="React Native">
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
import { useA2AArtifacts } from "@assistant-ui/react-a2a";
|
|
174
|
+
import { Text, View } from "react-native";
|
|
175
|
+
|
|
176
|
+
function ArtifactList() {
|
|
177
|
+
const artifacts = useA2AArtifacts();
|
|
178
|
+
return (
|
|
179
|
+
<View>
|
|
180
|
+
{artifacts.map((artifact) => (
|
|
181
|
+
<Text key={artifact.artifactId}>
|
|
182
|
+
{artifact.name}: {artifact.parts.length} parts
|
|
183
|
+
</Text>
|
|
184
|
+
))}
|
|
185
|
+
</View>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
</Tab>
|
|
191
|
+
<Tab value="React Ink">
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
import { useA2AArtifacts } from "@assistant-ui/react-a2a";
|
|
195
|
+
import { Box, Text } from "ink";
|
|
196
|
+
|
|
197
|
+
function ArtifactList() {
|
|
198
|
+
const artifacts = useA2AArtifacts();
|
|
199
|
+
return (
|
|
200
|
+
<Box flexDirection="column">
|
|
201
|
+
{artifacts.map((artifact) => (
|
|
202
|
+
<Text key={artifact.artifactId}>
|
|
203
|
+
{artifact.name}: {artifact.parts.length} parts
|
|
204
|
+
</Text>
|
|
205
|
+
))}
|
|
206
|
+
</Box>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
</Tab>
|
|
212
|
+
</PlatformTabs>
|
|
213
|
+
|
|
214
|
+
### Agent card
|
|
215
|
+
|
|
216
|
+
`useA2AAgentCard` returns the agent card fetched from the server on initialization.
|
|
217
|
+
|
|
218
|
+
<PlatformTabs>
|
|
219
|
+
<Tab value="React">
|
|
220
|
+
|
|
221
|
+
```tsx
|
|
222
|
+
import { useA2AAgentCard } from "@assistant-ui/react-a2a";
|
|
223
|
+
|
|
224
|
+
function AgentInfo() {
|
|
225
|
+
const card = useA2AAgentCard();
|
|
226
|
+
if (!card) return null;
|
|
227
|
+
return (
|
|
228
|
+
<div>
|
|
229
|
+
<h3>{card.name}</h3>
|
|
230
|
+
<p>{card.description}</p>
|
|
231
|
+
<div>Skills: {card.skills.map((s) => s.name).join(", ")}</div>
|
|
232
|
+
</div>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
</Tab>
|
|
238
|
+
<Tab value="React Native">
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
import { useA2AAgentCard } from "@assistant-ui/react-a2a";
|
|
242
|
+
import { Text, View } from "react-native";
|
|
243
|
+
|
|
244
|
+
function AgentInfo() {
|
|
245
|
+
const card = useA2AAgentCard();
|
|
246
|
+
if (!card) return null;
|
|
247
|
+
return (
|
|
248
|
+
<View>
|
|
249
|
+
<Text>{card.name}</Text>
|
|
250
|
+
<Text>{card.description}</Text>
|
|
251
|
+
<Text>Skills: {card.skills.map((s) => s.name).join(", ")}</Text>
|
|
252
|
+
</View>
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
</Tab>
|
|
258
|
+
<Tab value="React Ink">
|
|
259
|
+
|
|
260
|
+
```tsx
|
|
261
|
+
import { useA2AAgentCard } from "@assistant-ui/react-a2a";
|
|
262
|
+
import { Box, Text } from "ink";
|
|
263
|
+
|
|
264
|
+
function AgentInfo() {
|
|
265
|
+
const card = useA2AAgentCard();
|
|
266
|
+
if (!card) return null;
|
|
267
|
+
return (
|
|
268
|
+
<Box flexDirection="column">
|
|
269
|
+
<Text bold>{card.name}</Text>
|
|
270
|
+
<Text>{card.description}</Text>
|
|
271
|
+
<Text>Skills: {card.skills.map((s) => s.name).join(", ")}</Text>
|
|
272
|
+
</Box>
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
</Tab>
|
|
278
|
+
</PlatformTabs>
|
|
279
|
+
|
|
280
|
+
## Task states
|
|
281
|
+
|
|
282
|
+
The A2A protocol defines 9 task states. The runtime maps them to assistant-ui message statuses:
|
|
283
|
+
|
|
284
|
+
| A2A task state | Description | Message status |
|
|
285
|
+
| --- | --- | --- |
|
|
286
|
+
| `unspecified` | Unknown or default state. | `running` |
|
|
287
|
+
| `submitted` | Task acknowledged. | `running` |
|
|
288
|
+
| `working` | Task in progress. | `running` |
|
|
289
|
+
| `completed` | Task finished. | `complete` |
|
|
290
|
+
| `failed` | Task errored. | `incomplete (error)` |
|
|
291
|
+
| `canceled` | Task cancelled. | `incomplete (cancelled)` |
|
|
292
|
+
| `rejected` | Agent declined task. | `incomplete (error)` |
|
|
293
|
+
| `input_required` | Agent needs user input. | `requires-action` |
|
|
294
|
+
| `auth_required` | Authentication needed. | `requires-action` |
|
|
295
|
+
|
|
296
|
+
<Callout type="info">
|
|
297
|
+
When a task enters `input_required`, the user can continue the conversation normally. The runtime sends the next message with the same `taskId` to resume the task.
|
|
298
|
+
</Callout>
|
|
299
|
+
|
|
300
|
+
## Artifacts
|
|
301
|
+
|
|
302
|
+
A2A agents can produce artifacts (files, code, data) alongside their responses. Artifacts are accumulated during streaming and accessible via `useA2AArtifacts`.
|
|
303
|
+
|
|
304
|
+
The runtime supports:
|
|
305
|
+
|
|
306
|
+
- **Incremental artifact streaming** via `append` mode.
|
|
307
|
+
- **Artifact completion notification** via the `onArtifactComplete` callback.
|
|
308
|
+
- **Automatic reset** of artifacts on each new run.
|
|
309
|
+
|
|
310
|
+
```tsx
|
|
311
|
+
const runtime = useA2ARuntime({
|
|
312
|
+
baseUrl: "http://localhost:9999",
|
|
313
|
+
onArtifactComplete: (artifact) => {
|
|
314
|
+
console.log("Artifact ready:", artifact.name);
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Streaming vs non-streaming
|
|
320
|
+
|
|
321
|
+
The runtime automatically selects the communication mode based on the agent's capabilities:
|
|
322
|
+
|
|
323
|
+
- If the agent card indicates `capabilities.streaming: true` (or the field is unset), the runtime uses `POST /message:stream` with SSE.
|
|
324
|
+
- If `capabilities.streaming: false`, the runtime falls back to `POST /message:send`.
|
|
325
|
+
|
|
326
|
+
## Error handling
|
|
327
|
+
|
|
328
|
+
The client throws `A2AError` instances with structured error information following the `google.rpc.Status` format:
|
|
329
|
+
|
|
330
|
+
```tsx
|
|
331
|
+
import { A2AError } from "@assistant-ui/react-a2a";
|
|
332
|
+
|
|
333
|
+
const runtime = useA2ARuntime({
|
|
334
|
+
baseUrl: "http://localhost:9999",
|
|
335
|
+
onError: (error) => {
|
|
336
|
+
if (error instanceof A2AError) {
|
|
337
|
+
console.log(error.code); // HTTP status code
|
|
338
|
+
console.log(error.status); // e.g. "NOT_FOUND"
|
|
339
|
+
console.log(error.details); // google.rpc.ErrorInfo details
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Multi-tenancy
|
|
346
|
+
|
|
347
|
+
For multi-tenant A2A servers, pass a `tenant` option:
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
const client = new A2AClient({
|
|
351
|
+
baseUrl: "https://agent.example.com",
|
|
352
|
+
tenant: "my-org",
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
This prepends `/{tenant}` to all API paths (e.g. `/my-org/message:send`).
|
|
357
|
+
|
|
358
|
+
## Feature support
|
|
359
|
+
|
|
360
|
+
| Feature | Supported |
|
|
361
|
+
| --- | --- |
|
|
362
|
+
| Streaming (SSE) | Yes |
|
|
363
|
+
| Non-streaming fallback | Yes |
|
|
364
|
+
| All 9 task states | Yes |
|
|
365
|
+
| Artifacts (text, data, file) | Yes |
|
|
366
|
+
| Agent card discovery | Yes |
|
|
367
|
+
| Multi-tenancy | Yes |
|
|
368
|
+
| Structured errors | Yes |
|
|
369
|
+
| Push notifications CRUD | Yes |
|
|
370
|
+
| Extension negotiation | Yes |
|
|
371
|
+
| Task cancellation | Yes |
|
|
372
|
+
| Message editing | Yes |
|
|
373
|
+
| Message reload | Yes |
|
|
374
|
+
| History persistence | Via [history adapter](/docs/runtimes/concepts/adapters#history-adapter) |
|
|
375
|
+
| Thread list management | Via [thread list adapter](/docs/runtimes/concepts/threads) |
|
|
376
|
+
|
|
377
|
+
## Related
|
|
378
|
+
|
|
379
|
+
<Cards>
|
|
380
|
+
<Card
|
|
381
|
+
icon={<Network width={20} height={20} />}
|
|
382
|
+
title="A2A overview"
|
|
383
|
+
description="What A2A is and when to pick it."
|
|
384
|
+
href="/docs/runtimes/a2a"
|
|
385
|
+
/>
|
|
386
|
+
<Card
|
|
387
|
+
title="Quickstart"
|
|
388
|
+
description="Minimal runtime + Thread setup."
|
|
389
|
+
href="/docs/runtimes/a2a/quickstart"
|
|
390
|
+
/>
|
|
391
|
+
<Card
|
|
392
|
+
title="Adapters"
|
|
393
|
+
description="Attachments, speech, feedback, history, threads."
|
|
394
|
+
href="/docs/runtimes/concepts/adapters"
|
|
395
|
+
/>
|
|
396
|
+
</Cards>
|