@assistant-ui/mcp-docs-server 0.2.1 → 0.2.3
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 +3 -3
- package/.docs/organized/code-examples/with-a2a.md +5 -4
- package/.docs/organized/code-examples/with-ag-ui.md +7 -6
- package/.docs/organized/code-examples/with-ai-sdk-v7.md +14 -13
- package/.docs/organized/code-examples/with-artifacts.md +12 -11
- package/.docs/organized/code-examples/with-assistant-transport.md +6 -5
- package/.docs/organized/code-examples/with-browser-extension.md +6 -6
- package/.docs/organized/code-examples/with-chain-of-thought.md +16 -14
- package/.docs/organized/code-examples/with-cloud-standalone.md +7 -7
- package/.docs/organized/code-examples/with-cloud.md +11 -10
- package/.docs/organized/code-examples/with-custom-thread-list.md +11 -10
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +14 -13
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +15 -14
- package/.docs/organized/code-examples/with-eve.md +6 -5
- package/.docs/organized/code-examples/with-expo.md +213 -36
- package/.docs/organized/code-examples/with-external-store.md +6 -5
- package/.docs/organized/code-examples/with-ffmpeg.md +11 -10
- package/.docs/organized/code-examples/with-generative-ui.md +263 -29
- package/.docs/organized/code-examples/with-google-adk.md +5 -4
- package/.docs/organized/code-examples/with-heat-graph.md +3 -3
- package/.docs/organized/code-examples/with-image-generation.md +8 -7
- package/.docs/organized/code-examples/with-interactables.md +11 -10
- package/.docs/organized/code-examples/with-langchain.md +10 -9
- package/.docs/organized/code-examples/with-langgraph.md +7 -6
- package/.docs/organized/code-examples/with-livekit.md +15 -14
- package/.docs/organized/code-examples/with-mcp.md +14 -12
- package/.docs/organized/code-examples/with-nuxt.md +511 -575
- package/.docs/organized/code-examples/with-opencode.md +4 -4
- package/.docs/organized/code-examples/with-openui.md +450 -0
- package/.docs/organized/code-examples/with-pi.md +6 -5
- package/.docs/organized/code-examples/with-react-hook-form.md +16 -13
- package/.docs/organized/code-examples/with-react-ink-web.md +65 -15
- package/.docs/organized/code-examples/with-react-ink.md +5 -4
- package/.docs/organized/code-examples/with-react-router.md +8 -7
- package/.docs/organized/code-examples/with-resumable-stream.md +13 -12
- package/.docs/organized/code-examples/with-store.md +3 -3
- package/.docs/organized/code-examples/with-svelte.md +415 -0
- package/.docs/organized/code-examples/with-sveltekit.md +1061 -0
- package/.docs/organized/code-examples/with-tanstack.md +10 -9
- package/.docs/organized/code-examples/with-tap-runtime.md +5 -4
- package/.docs/organized/code-examples/with-virtualized-thread.md +6 -5
- package/.docs/organized/code-examples/with-vue.md +2 -2
- package/.docs/raw/docs/{(docs) → (getting-started)}/cli.mdx +6 -1
- package/.docs/raw/docs/{(docs) → (getting-started)}/devtools.mdx +1 -1
- package/.docs/raw/docs/{(docs) → (getting-started)}/index.mdx +4 -2
- package/.docs/raw/docs/{(docs) → (getting-started)}/installation.mdx +26 -26
- package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +6 -0
- package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +6 -1
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/slack.mdx +5 -1
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/teams.mdx +9 -2
- package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +2 -2
- package/.docs/raw/docs/(reference)/api-reference/integrations/{react-ai-sdk.mdx → ai-sdk.mdx} +43 -18
- package/.docs/raw/docs/(reference)/api-reference/integrations/eve.mdx +61 -2
- package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +3 -3
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +2 -2
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +20 -2
- package/.docs/raw/docs/(reference)/api-reference/tools/interactables.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +32 -1
- package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +1 -1
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +10 -10
- package/.docs/raw/docs/cloud/ai-sdk.mdx +4 -2
- package/.docs/raw/docs/cloud/index.mdx +1 -1
- package/.docs/raw/docs/copilots/assistant-frame.mdx +19 -8
- package/.docs/raw/docs/guides/attachments.mdx +4 -4
- package/.docs/raw/docs/guides/branching.mdx +1 -1
- package/.docs/raw/docs/guides/chatgpt-subscription.mdx +1 -1
- package/.docs/raw/docs/guides/context-api.mdx +15 -17
- package/.docs/raw/docs/guides/dictation.mdx +2 -2
- package/.docs/raw/docs/guides/electron.mdx +1 -1
- package/.docs/raw/docs/guides/latex.mdx +1 -1
- package/.docs/raw/docs/guides/mentions.mdx +2 -0
- package/.docs/raw/docs/guides/message-timing.mdx +11 -5
- package/.docs/raw/docs/guides/quoting.mdx +1 -1
- package/.docs/raw/docs/guides/resumable-streams.mdx +3 -3
- package/.docs/raw/docs/guides/speech.mdx +1 -1
- package/.docs/raw/docs/guides/suggestions.mdx +8 -5
- package/.docs/raw/docs/guides/voice.mdx +1 -1
- package/.docs/raw/docs/ink/hooks.mdx +1 -1
- package/.docs/raw/docs/ink/index.mdx +3 -2
- package/.docs/raw/docs/ink/migration.mdx +1 -1
- package/.docs/raw/docs/ink/primitives.mdx +1 -1
- package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +3 -3
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +3 -3
- package/.docs/raw/docs/integrations/frameworks/{cloudflare-agents/overview.mdx → cloudflare-agents.mdx} +4 -3
- package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +1 -1
- package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
- package/.docs/raw/docs/integrations/index.mdx +2 -2
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +149 -131
- package/.docs/raw/docs/migrations/toolkit-tools.mdx +2 -2
- package/.docs/raw/docs/migrations/v0-15.mdx +34 -0
- package/.docs/raw/docs/primitives/action-bar.mdx +1 -1
- package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -1
- package/.docs/raw/docs/primitives/attachment.mdx +1 -1
- package/.docs/raw/docs/primitives/branch-picker.mdx +1 -1
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +3 -3
- package/.docs/raw/docs/primitives/composer.mdx +1 -1
- package/.docs/raw/docs/primitives/error.mdx +1 -1
- package/.docs/raw/docs/primitives/message.mdx +1 -1
- package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -1
- package/.docs/raw/docs/primitives/suggestion.mdx +4 -2
- package/.docs/raw/docs/primitives/thread-list.mdx +1 -1
- package/.docs/raw/docs/primitives/thread.mdx +2 -2
- package/.docs/raw/docs/react-native/adapters.mdx +1 -1
- package/.docs/raw/docs/react-native/index.mdx +2 -2
- package/.docs/raw/docs/react-native/migration.mdx +2 -2
- package/.docs/raw/docs/react-native/primitives.mdx +142 -5
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +48 -6
- package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +3 -3
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +4 -4
- package/.docs/raw/docs/runtimes/ai-sdk/v7.mdx +31 -16
- package/.docs/raw/docs/runtimes/claude-managed-agents.mdx +118 -0
- package/.docs/raw/docs/runtimes/concepts/adapters.mdx +3 -3
- package/.docs/raw/docs/runtimes/concepts/architecture.mdx +3 -3
- package/.docs/raw/docs/runtimes/concepts/stability.mdx +2 -1
- package/.docs/raw/docs/runtimes/concepts/threads.mdx +73 -33
- package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +1 -1
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +6 -2
- package/.docs/raw/docs/runtimes/langchain.mdx +2 -2
- package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +4 -0
- package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +9 -2
- package/.docs/raw/docs/tools/backend.mdx +4 -4
- package/.docs/raw/docs/tools/defining-tools.mdx +21 -2
- package/.docs/raw/docs/tools/generative-ui-primitive.mdx +180 -0
- package/.docs/raw/docs/tools/generative-ui-slack.mdx +167 -0
- package/.docs/raw/docs/tools/generative-ui-teams.mdx +160 -0
- package/.docs/raw/docs/tools/generative-ui.mdx +224 -211
- package/.docs/raw/docs/tools/index.mdx +2 -1
- package/.docs/raw/docs/tools/interactables.mdx +8 -7
- package/.docs/raw/docs/tools/mcp-apps.mdx +18 -1
- package/.docs/raw/docs/tools/mcp.mdx +2 -2
- package/.docs/raw/docs/tools/openui.mdx +175 -0
- package/.docs/raw/docs/tools/tool-ui.mdx +18 -7
- package/.docs/raw/docs/tools/user-managed-mcp.mdx +7 -3
- package/.docs/raw/docs/ui/assistant-modal.mdx +3 -3
- package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -1
- package/.docs/raw/docs/ui/attachment.mdx +50 -3
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +36 -1
- package/.docs/raw/docs/ui/context-display.mdx +1 -1
- package/.docs/raw/docs/ui/directive-text.mdx +1 -1
- package/.docs/raw/docs/ui/file.mdx +2 -2
- package/.docs/raw/docs/ui/follow-up-suggestions.mdx +1 -1
- package/.docs/raw/docs/ui/image.mdx +2 -2
- package/.docs/raw/docs/ui/markdown.mdx +40 -1
- package/.docs/raw/docs/ui/mermaid.mdx +1 -1
- package/.docs/raw/docs/ui/message-timing.mdx +1 -1
- package/.docs/raw/docs/ui/model-selector.mdx +4 -4
- package/.docs/raw/docs/ui/part-grouping.mdx +1 -1
- package/.docs/raw/docs/ui/quote.mdx +3 -3
- package/.docs/raw/docs/ui/reasoning.mdx +31 -3
- package/.docs/raw/docs/ui/scrollbar.mdx +1 -1
- package/.docs/raw/docs/ui/sources.mdx +10 -1
- package/.docs/raw/docs/ui/streamdown.mdx +2 -2
- package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -1
- package/.docs/raw/docs/ui/thread-list.mdx +40 -1
- package/.docs/raw/docs/ui/thread.mdx +49 -2
- package/.docs/raw/docs/ui/tool-fallback.mdx +23 -9
- package/.docs/raw/docs/ui/tool-group.mdx +1 -1
- package/.docs/raw/docs/ui/voice.mdx +1 -1
- package/.docs/raw/docs/utilities/react-o11y.mdx +2 -2
- package/dist/xulux/catalog-client.d.ts.map +1 -1
- package/dist/xulux/catalog-client.js +51 -6
- package/dist/xulux/catalog-client.js.map +1 -1
- package/dist/xulux/types.d.ts +7 -7
- package/dist/xulux/types.d.ts.map +1 -1
- package/dist/xulux/types.js.map +1 -1
- package/package.json +5 -5
- package/src/tools/tests/docs.test.ts +10 -7
- package/src/tools/tests/path-traversal.test.ts +5 -2
- package/src/tools/tests/xulux-templates.test.ts +63 -0
- package/src/xulux/catalog-client.ts +68 -23
- package/src/xulux/types.ts +17 -13
- package/.docs/raw/docs/tools/interactables-legacy.mdx +0 -423
- package/.docs/raw/docs/ui/accordion.mdx +0 -266
- package/.docs/raw/docs/ui/badge.mdx +0 -150
- package/.docs/raw/docs/ui/diff-viewer.mdx +0 -280
- package/.docs/raw/docs/ui/dot-matrix.mdx +0 -133
- package/.docs/raw/docs/ui/number-roll.mdx +0 -154
- package/.docs/raw/docs/ui/select.mdx +0 -254
- package/.docs/raw/docs/ui/tabs.mdx +0 -271
- /package/.docs/raw/docs/{(docs) → (getting-started)}/architecture.mdx +0 -0
- /package/.docs/raw/docs/{(docs) → (getting-started)}/base-ui.mdx +0 -0
- /package/.docs/raw/docs/{(docs) → (getting-started)}/llm.mdx +0 -0
- /package/.docs/raw/docs/{(docs) → (getting-started)}/rtl.mdx +0 -0
|
@@ -224,6 +224,40 @@ return (
|
|
|
224
224
|
);
|
|
225
225
|
```
|
|
226
226
|
|
|
227
|
+
## Thread Switch Events: `threads.selectionChanged`
|
|
228
|
+
|
|
229
|
+
The per-item thread switch events are deprecated in favor of a single event on the thread list. `threads.selectionChanged` fires once per switch and carries both sides of the transition:
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
// Before
|
|
233
|
+
useAuiEvent("threadListItem.switchedTo", ({ threadId }) => {
|
|
234
|
+
// threadId: the newly selected thread
|
|
235
|
+
});
|
|
236
|
+
useAuiEvent("threadListItem.switchedAway", ({ threadId }) => {
|
|
237
|
+
// threadId: the thread that was switched away from
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// After
|
|
241
|
+
useAuiEvent("threads.selectionChanged", ({ threadId, previousThreadId }) => {
|
|
242
|
+
// threadId: the newly selected thread
|
|
243
|
+
// previousThreadId: the thread that was switched away from
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Like its predecessors, it does not fire for the initially selected thread on mount. The deprecated events still fire and will keep working until the next major.
|
|
248
|
+
|
|
249
|
+
The deprecated pair was scope-filtered: inside a per-item `threadListItem` scope (such as `ThreadListPrimitive.Items`), `threadListItem.switchedTo` only fired for that item. `threads.selectionChanged` resolves against the shared `threads` scope, so every listener fires on every switch. Filter by id to reproduce the per-item behavior:
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
const id = useAuiState((s) => s.threadListItem.id);
|
|
253
|
+
useAuiEvent("threads.selectionChanged", ({ threadId }) => {
|
|
254
|
+
if (threadId !== id) return;
|
|
255
|
+
// this item became selected
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The new event also fires in situations where the deprecated pair did not: `InMemoryThreadList` emits on selection changes (it previously emitted no switch events), and `switchToNewThread()` emits for the newly created thread. Selection-driven defaults such as `scrollToBottomOnThreadSwitch` and `unstable_focusOnThreadSwitched` now engage in both situations. Runtimes that resolve a deep-linked `threadId`/`initialThreadId` after mount (such as `useRemoteThreadListRuntime`) start on a placeholder new thread, so the deep link's resolution also fires the event — `previousThreadId` is the placeholder in that case.
|
|
260
|
+
|
|
227
261
|
## Still Deprecated (not removed)
|
|
228
262
|
|
|
229
263
|
- Primitive `If` components (`ThreadPrimitive.If`, `MessagePrimitive.If`, `ThreadPrimitive.Empty`) — replaced by `AuiIf`. The codemod migrates these.
|
|
@@ -4,7 +4,7 @@ description: Build message action buttons with auto-hide, copy state, and intell
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { ActionBarPrimitiveSample } from "@/components/docs/samples/action-bar-primitive";
|
|
7
|
+
import { ActionBarPrimitiveSample } from "@/components/pages/docs/samples/action-bar-primitive";
|
|
8
8
|
import { ActionBarPrimitive as ActionBarPrimitiveDocs } from "@/generated/primitiveDocs";
|
|
9
9
|
|
|
10
10
|
The ActionBar primitive provides message actions: copy, reload, edit, feedback, speech, and export. It handles intelligent visibility with auto-hide on hover, automatic disabling based on message state, and floating behavior. You compose the buttons; the primitive handles action state and availability.
|
|
@@ -4,7 +4,7 @@ description: A floating chat popover with a fixed-position trigger button that o
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { AssistantModalSample } from "@/components/docs/samples/assistant-modal";
|
|
7
|
+
import { AssistantModalSample } from "@/components/pages/docs/samples/assistant-modal";
|
|
8
8
|
import { AssistantModalPrimitive as AssistantModalPrimitiveDocs } from "@/generated/primitiveDocs";
|
|
9
9
|
|
|
10
10
|
The AssistantModal primitive is a floating chat popover built on [Radix Popover](https://www.radix-ui.com/primitives/docs/components/popover). A trigger button opens a chat panel, which is a common floating assistant launcher pattern. You control the trigger, content, positioning, and animations.
|
|
@@ -4,7 +4,7 @@ description: File and image attachment rendering for the composer and messages.
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { AttachmentSample } from "@/components/docs/samples/attachment";
|
|
7
|
+
import { AttachmentSample } from "@/components/pages/docs/samples/attachment";
|
|
8
8
|
|
|
9
9
|
The Attachment primitive renders file and image attachments. It appears in two places: inside the composer for pending uploads (with a remove button), and inside messages for sent attachments (read-only). You provide the layout and styling.
|
|
10
10
|
|
|
@@ -4,7 +4,7 @@ description: Navigate between message branches, which are alternative responses
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { BranchPickerPrimitiveSample } from "@/components/docs/samples/branch-picker-primitive";
|
|
7
|
+
import { BranchPickerPrimitiveSample } from "@/components/pages/docs/samples/branch-picker-primitive";
|
|
8
8
|
import { BranchPickerPrimitive as BranchPickerPrimitiveDocs } from "@/generated/primitiveDocs";
|
|
9
9
|
|
|
10
10
|
The BranchPicker primitive lets users navigate between message branches, which are alternative responses generated by editing a message or regenerating a reply. It's used alongside ActionBar inside message components.
|
|
@@ -4,9 +4,9 @@ description: Collapsible accordion for grouping reasoning steps and tool calls.
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { ChainOfThoughtPrimitiveSample } from "@/components/docs/samples/chain-of-thought-primitive";
|
|
8
|
-
import { ChainOfThoughtPrimitiveSample as ChainOfThoughtPrimitiveSampleRadix } from "@/components/docs/samples/chain-of-thought-primitive.radix";
|
|
9
|
-
import { Flavored } from "@/components/docs/contexts/flavor.server";
|
|
7
|
+
import { ChainOfThoughtPrimitiveSample } from "@/components/pages/docs/samples/chain-of-thought-primitive";
|
|
8
|
+
import { ChainOfThoughtPrimitiveSample as ChainOfThoughtPrimitiveSampleRadix } from "@/components/pages/docs/samples/chain-of-thought-primitive.radix";
|
|
9
|
+
import { Flavored } from "@/components/pages/docs/contexts/flavor.server";
|
|
10
10
|
import {
|
|
11
11
|
ChainOfThoughtPrimitive as ChainOfThoughtPrimitiveDocs,
|
|
12
12
|
MessagePrimitive as MessagePrimitiveDocs,
|
|
@@ -4,7 +4,7 @@ description: Build custom message input UIs with full control over layout and be
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { ComposerPrimitiveSample } from "@/components/docs/samples/composer-primitive";
|
|
7
|
+
import { ComposerPrimitiveSample } from "@/components/pages/docs/samples/composer-primitive";
|
|
8
8
|
import { ComposerPrimitive as ComposerPrimitiveDocs } from "@/generated/primitiveDocs";
|
|
9
9
|
|
|
10
10
|
The Composer primitive is the interface for composing new messages or editing existing ones. It handles submit behavior, keyboard shortcuts, focus management, attachment state, and streaming status. You provide the UI.
|
|
@@ -4,7 +4,7 @@ description: Accessible error display for messages with automatic error text ext
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { ErrorPrimitiveSample } from "@/components/docs/samples/error-primitive";
|
|
7
|
+
import { ErrorPrimitiveSample } from "@/components/pages/docs/samples/error-primitive";
|
|
8
8
|
|
|
9
9
|
The Error primitive renders error states on messages using an accessible `role="alert"` container with automatic error text extraction. `Root` always renders its container; `Message` only renders when the message has an error. Wrap in `MessagePrimitive.Error` if you need the entire block to be conditional.
|
|
10
10
|
|
|
@@ -4,7 +4,7 @@ description: Build custom message rendering with content parts, attachments, and
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { MessagePrimitiveSample } from "@/components/docs/samples/message-primitive";
|
|
7
|
+
import { MessagePrimitiveSample } from "@/components/pages/docs/samples/message-primitive";
|
|
8
8
|
import { MessagePrimitive as MessagePrimitiveDocs } from "@/generated/primitiveDocs";
|
|
9
9
|
|
|
10
10
|
The Message primitive handles individual message rendering: content parts, attachments, quotes, hover state, and error display. It's the building block inside each message bubble, resolving text, images, tool calls, and more through a parts pipeline.
|
|
@@ -4,7 +4,7 @@ description: A floating toolbar that appears when text is selected within a mess
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { SelectionToolbarPrimitiveSample } from "@/components/docs/samples/selection-toolbar-primitive";
|
|
7
|
+
import { SelectionToolbarPrimitiveSample } from "@/components/pages/docs/samples/selection-toolbar-primitive";
|
|
8
8
|
|
|
9
9
|
The SelectionToolbar primitive is a floating toolbar that appears when the user selects text within a message. It lets users quote selected text into the composer. Styling and action layout are fully customizable.
|
|
10
10
|
|
|
@@ -4,7 +4,7 @@ description: Suggested prompts that users can click to quickly send or populate
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { SuggestionPrimitiveSample } from "@/components/docs/samples/suggestion-primitive";
|
|
7
|
+
import { SuggestionPrimitiveSample } from "@/components/pages/docs/samples/suggestion-primitive";
|
|
8
8
|
import { SuggestionPrimitive as SuggestionPrimitiveDocs } from "@/generated/primitiveDocs";
|
|
9
9
|
|
|
10
10
|
The Suggestion primitive renders suggested prompts as clickable pills that send a message or populate the composer. Use it for welcome screen suggestions, follow-up prompts, or quick actions. You provide the layout and styling.
|
|
@@ -130,11 +130,13 @@ When `send={false}`, the `clearComposer` prop controls whether the suggestion re
|
|
|
130
130
|
|
|
131
131
|
### Static configuration vs. runtime suggestions
|
|
132
132
|
|
|
133
|
-
There are two
|
|
133
|
+
There are two data flows for suggestions:
|
|
134
134
|
|
|
135
135
|
- **Static configuration** flows through the `suggestions` scope. Pass an array to `Suggestions(...)` in your runtime provider; render it with `ThreadPrimitive.Suggestions`. Best for welcome screen prompts.
|
|
136
136
|
- **Runtime / dynamic suggestions** flow through `thread.suggestions`. Populate it via `SuggestionAdapter` (local runtime) or the `suggestions` field on `useExternalStoreRuntime`; render it with the shadcn `ThreadFollowupSuggestions` component or your own component reading `useAuiState((s) => s.thread.suggestions)`. Best for follow up prompts after a turn.
|
|
137
137
|
|
|
138
|
+
When no static configuration is provided, the `suggestions` scope derives from `thread.suggestions`, so runtime suggestions also render through `ThreadPrimitive.Suggestions`. A static `Suggestions(...)` configuration takes precedence over the derived values.
|
|
139
|
+
|
|
138
140
|
See [Suggested Prompts](/docs/guides/suggestions) for end to end examples.
|
|
139
141
|
|
|
140
142
|
### ThreadPrimitive.Suggestion (Legacy)
|
|
@@ -4,7 +4,7 @@ description: Multi-thread management for listing, creating, switching, archiving
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { ThreadListPrimitiveSample } from "@/components/docs/samples/thread-list-primitive";
|
|
7
|
+
import { ThreadListPrimitiveSample } from "@/components/pages/docs/samples/thread-list-primitive";
|
|
8
8
|
import { ThreadListPrimitive as ThreadListPrimitiveDocs, ThreadListItemPrimitive as ThreadListItemPrimitiveDocs, ThreadListItemMorePrimitive as ThreadListItemMorePrimitiveDocs } from "@/generated/primitiveDocs";
|
|
9
9
|
|
|
10
10
|
The ThreadList primitive manages multiple conversations by listing threads, creating new ones, switching between them, and archiving or deleting old ones. It's composed from three primitive namespaces: `ThreadListPrimitive`, `ThreadListItemPrimitive`, and `ThreadListItemMorePrimitive`.
|
|
@@ -4,7 +4,7 @@ description: Build custom scrollable message containers with auto-scroll, empty
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { ThreadPrimitiveSample } from "@/components/docs/samples/thread-primitive";
|
|
7
|
+
import { ThreadPrimitiveSample } from "@/components/pages/docs/samples/thread-primitive";
|
|
8
8
|
import { ThreadPrimitive as ThreadPrimitiveDocs } from "@/generated/primitiveDocs";
|
|
9
9
|
|
|
10
10
|
The Thread primitive is the scrollable message container, and the backbone of any chat interface. It handles viewport management, auto-scrolling, empty states, message rendering, and suggestions. You provide the layout and styling.
|
|
@@ -143,7 +143,7 @@ Use `topAnchorMessageClamp` to control how much of a long user message remains v
|
|
|
143
143
|
|
|
144
144
|
- `scrollToBottomOnRunStart` (default `true`): scrolls when `thread.runStart` fires
|
|
145
145
|
- `scrollToBottomOnInitialize` (default `true`): scrolls when `thread.initialize` fires
|
|
146
|
-
- `scrollToBottomOnThreadSwitch` (default `true`): scrolls when `
|
|
146
|
+
- `scrollToBottomOnThreadSwitch` (default `true`): scrolls when `threads.selectionChanged` fires
|
|
147
147
|
|
|
148
148
|
These work alongside `autoScroll`. If `autoScroll` is omitted, it defaults to `true` for `turnAnchor="bottom"` and `false` for `turnAnchor="top"`.
|
|
149
149
|
|
|
@@ -15,7 +15,7 @@ The simplest way to add persistence. Pass a `cloud` option to `useLocalRuntime`:
|
|
|
15
15
|
|
|
16
16
|
```tsx
|
|
17
17
|
import { useLocalRuntime } from "@assistant-ui/react-native";
|
|
18
|
-
import { AssistantCloud } from "
|
|
18
|
+
import { AssistantCloud } from "assistant-cloud";
|
|
19
19
|
|
|
20
20
|
const cloud = new AssistantCloud({
|
|
21
21
|
baseUrl: "https://backend.assistant-ui.com",
|
|
@@ -49,7 +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
|
-
<InstallCommand expo={["@assistant-ui/react-native", "@assistant-ui/
|
|
52
|
+
<InstallCommand expo={["@assistant-ui/react-native", "@assistant-ui/ai-sdk"]} />
|
|
53
53
|
|
|
54
54
|
</Step>
|
|
55
55
|
<Step>
|
|
@@ -120,7 +120,7 @@ export async function POST(req: Request) {
|
|
|
120
120
|
### Set up the runtime
|
|
121
121
|
|
|
122
122
|
```tsx title="hooks/use-app-runtime.ts"
|
|
123
|
-
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/
|
|
123
|
+
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/ai-sdk";
|
|
124
124
|
|
|
125
125
|
const API_URL = process.env.EXPO_PUBLIC_API_URL ?? "http://localhost:3000";
|
|
126
126
|
|
|
@@ -8,7 +8,7 @@ If you already have an assistant-ui web app, most of your code transfers directl
|
|
|
8
8
|
## What stays the same
|
|
9
9
|
|
|
10
10
|
- **Runtime setup** — `useChatRuntime`, `useLocalRuntime`, `ChatModelAdapter`, and all runtime options work identically.
|
|
11
|
-
- **AI SDK integration** — `@assistant-ui/
|
|
11
|
+
- **AI SDK integration** — `@assistant-ui/ai-sdk` works with React Native. Your `useChatRuntime` + `AssistantChatTransport` setup transfers directly.
|
|
12
12
|
- **Tool definitions** — `Tools({ toolkit })` and toolkit renderers use the same API.
|
|
13
13
|
- **State hooks** — `useAuiState`, `useAui`, and selector patterns are the same.
|
|
14
14
|
- **Backend code** — Your API routes, streaming endpoints, and server-side logic need zero changes.
|
|
@@ -40,7 +40,7 @@ Your `useChatRuntime` setup works as-is — no changes needed:
|
|
|
40
40
|
|
|
41
41
|
```tsx title="hooks/use-app-runtime.ts"
|
|
42
42
|
// This file is identical to your web version
|
|
43
|
-
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/
|
|
43
|
+
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/ai-sdk";
|
|
44
44
|
|
|
45
45
|
export function useAppRuntime() {
|
|
46
46
|
return useChatRuntime({
|
|
@@ -12,7 +12,7 @@ Many primitives share their core logic with `@assistant-ui/react` via `@assistan
|
|
|
12
12
|
## Thread
|
|
13
13
|
|
|
14
14
|
```tsx
|
|
15
|
-
import { ThreadPrimitive } from "@assistant-ui/react-native";
|
|
15
|
+
import { AuiIf, ThreadPrimitive } from "@assistant-ui/react-native";
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
### ThreadPrimitive.Root
|
|
@@ -100,12 +100,17 @@ Renders a single message at a specific index in the thread. Provides message con
|
|
|
100
100
|
|
|
101
101
|
### ThreadPrimitive.Empty
|
|
102
102
|
|
|
103
|
-
Renders its children only when the thread
|
|
103
|
+
Renders its children only when the thread is empty (no messages and not loading). Deprecated in favor of `AuiIf`.
|
|
104
104
|
|
|
105
105
|
```tsx
|
|
106
106
|
<ThreadPrimitive.Empty>
|
|
107
107
|
<Text>Send a message to get started</Text>
|
|
108
108
|
</ThreadPrimitive.Empty>
|
|
109
|
+
|
|
110
|
+
// preferred
|
|
111
|
+
<AuiIf condition={(s) => s.thread.isEmpty}>
|
|
112
|
+
<Text>Send a message to get started</Text>
|
|
113
|
+
</AuiIf>
|
|
109
114
|
```
|
|
110
115
|
|
|
111
116
|
### ThreadPrimitive.If
|
|
@@ -117,9 +122,14 @@ Conditional rendering based on thread state. Deprecated in favor of `AuiIf`.
|
|
|
117
122
|
<Text>No messages yet</Text>
|
|
118
123
|
</ThreadPrimitive.If>
|
|
119
124
|
|
|
120
|
-
|
|
125
|
+
// preferred
|
|
126
|
+
<AuiIf condition={(s) => s.thread.isEmpty}>
|
|
127
|
+
<Text>No messages yet</Text>
|
|
128
|
+
</AuiIf>
|
|
129
|
+
|
|
130
|
+
<AuiIf condition={(s) => s.thread.isRunning}>
|
|
121
131
|
<ActivityIndicator />
|
|
122
|
-
</
|
|
132
|
+
</AuiIf>
|
|
123
133
|
```
|
|
124
134
|
|
|
125
135
|
| Prop | Type | Description |
|
|
@@ -197,7 +207,10 @@ import { AuiIf } from "@assistant-ui/react-native";
|
|
|
197
207
|
## Composer
|
|
198
208
|
|
|
199
209
|
```tsx
|
|
200
|
-
import {
|
|
210
|
+
import {
|
|
211
|
+
ComposerPrimitive,
|
|
212
|
+
QueueItemPrimitive,
|
|
213
|
+
} from "@assistant-ui/react-native";
|
|
201
214
|
```
|
|
202
215
|
|
|
203
216
|
### ComposerPrimitive.Root
|
|
@@ -275,6 +288,79 @@ Renders composer attachments using the provided component configuration.
|
|
|
275
288
|
</ComposerPrimitive.AddAttachment>
|
|
276
289
|
```
|
|
277
290
|
|
|
291
|
+
### ComposerPrimitive.Queue
|
|
292
|
+
|
|
293
|
+
Renders all queued composer items. Each item is wrapped in a `QueueItemByIndexProvider`, so `QueueItemPrimitive.*` can read item state and call queue actions inside the render prop. Backed by the shared `ComposerPrimitiveQueue` from `@assistant-ui/core/react`.
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
<ComposerPrimitive.Queue>
|
|
297
|
+
{({ queueItem }) => (
|
|
298
|
+
<View>
|
|
299
|
+
<QueueItemPrimitive.Text />
|
|
300
|
+
<QueueItemPrimitive.Steer>
|
|
301
|
+
<Text>Run now</Text>
|
|
302
|
+
</QueueItemPrimitive.Steer>
|
|
303
|
+
<QueueItemPrimitive.Remove>
|
|
304
|
+
<Text>Remove</Text>
|
|
305
|
+
</QueueItemPrimitive.Remove>
|
|
306
|
+
</View>
|
|
307
|
+
)}
|
|
308
|
+
</ComposerPrimitive.Queue>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
| Prop | Type | Description |
|
|
312
|
+
|------|------|-------------|
|
|
313
|
+
| `children` | `(value: { queueItem: QueueItemState }) => ReactNode` | Render function called for each queue item |
|
|
314
|
+
|
|
315
|
+
### ComposerPrimitive.Quote
|
|
316
|
+
|
|
317
|
+
Renders the active composer quote preview. Children are only rendered while `s.composer.quote` is set, so this acts as both a container and a gate.
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
<ComposerPrimitive.Quote>
|
|
321
|
+
<View>
|
|
322
|
+
<Text>Quoting:</Text>
|
|
323
|
+
<ComposerPrimitive.QuoteText />
|
|
324
|
+
<ComposerPrimitive.QuoteDismiss>
|
|
325
|
+
<Text>Clear</Text>
|
|
326
|
+
</ComposerPrimitive.QuoteDismiss>
|
|
327
|
+
</View>
|
|
328
|
+
</ComposerPrimitive.Quote>
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
| Prop | Type | Description |
|
|
332
|
+
|------|------|-------------|
|
|
333
|
+
| `children` | `ReactNode` | Quote preview content; only rendered when a quote is set |
|
|
334
|
+
| `...rest` | `ViewProps` | Standard React Native View props |
|
|
335
|
+
|
|
336
|
+
### ComposerPrimitive.QuoteText
|
|
337
|
+
|
|
338
|
+
Renders the quoted text from `s.composer.quote?.text`. Pass `children` to override the displayed value.
|
|
339
|
+
|
|
340
|
+
```tsx
|
|
341
|
+
<ComposerPrimitive.QuoteText />
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
| Prop | Type | Description |
|
|
345
|
+
|------|------|-------------|
|
|
346
|
+
| `children` | `ReactNode` | Override content; defaults to `s.composer.quote?.text` |
|
|
347
|
+
| `...rest` | `TextProps` | Standard React Native Text props |
|
|
348
|
+
|
|
349
|
+
### ComposerPrimitive.QuoteDismiss
|
|
350
|
+
|
|
351
|
+
`Pressable` that clears the active quote by calling `aui.composer.setQuote(undefined)`.
|
|
352
|
+
|
|
353
|
+
```tsx
|
|
354
|
+
<ComposerPrimitive.QuoteDismiss>
|
|
355
|
+
<Text>Clear</Text>
|
|
356
|
+
</ComposerPrimitive.QuoteDismiss>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
| Prop | Type | Description |
|
|
360
|
+
|------|------|-------------|
|
|
361
|
+
| `children` | `PressableProps["children"]` | Button content, including Pressable render-function children |
|
|
362
|
+
| `...rest` | `Omit<PressableProps, "onPress">` | Standard React Native Pressable props except `onPress` |
|
|
363
|
+
|
|
278
364
|
### ComposerPrimitive.AttachmentByIndex
|
|
279
365
|
|
|
280
366
|
Renders a single composer attachment at the specified index. Useful for building custom attachment layouts.
|
|
@@ -557,6 +643,57 @@ Container `View` for an attachment.
|
|
|
557
643
|
</AttachmentPrimitive.Remove>
|
|
558
644
|
```
|
|
559
645
|
|
|
646
|
+
## QueueItem
|
|
647
|
+
|
|
648
|
+
```tsx
|
|
649
|
+
import { QueueItemPrimitive } from "@assistant-ui/react-native";
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
Primitives for rendering individual queued composer items. Use inside a `ComposerPrimitive.Queue` render prop, where the queue item context is set up by `QueueItemByIndexProvider`.
|
|
653
|
+
|
|
654
|
+
### QueueItemPrimitive.Text
|
|
655
|
+
|
|
656
|
+
Renders the queue item's text with React Native `<Text>`. Pass `children` to override the displayed value.
|
|
657
|
+
|
|
658
|
+
```tsx
|
|
659
|
+
<QueueItemPrimitive.Text />
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
| Prop | Type | Description |
|
|
663
|
+
|------|------|-------------|
|
|
664
|
+
| `children` | `ReactNode` | Override content; defaults to the text parts of `s.queueItem.parts` |
|
|
665
|
+
| `...rest` | `TextProps` | Standard React Native Text props |
|
|
666
|
+
|
|
667
|
+
### QueueItemPrimitive.Remove
|
|
668
|
+
|
|
669
|
+
`Pressable` that removes the queue item by calling `aui.queueItem.remove()`.
|
|
670
|
+
|
|
671
|
+
```tsx
|
|
672
|
+
<QueueItemPrimitive.Remove>
|
|
673
|
+
<Text>Remove</Text>
|
|
674
|
+
</QueueItemPrimitive.Remove>
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
| Prop | Type | Description |
|
|
678
|
+
|------|------|-------------|
|
|
679
|
+
| `children` | `PressableProps["children"]` | Button content, including Pressable render-function children |
|
|
680
|
+
| `...rest` | `Omit<PressableProps, "onPress">` | Standard React Native Pressable props except `onPress` |
|
|
681
|
+
|
|
682
|
+
### QueueItemPrimitive.Steer
|
|
683
|
+
|
|
684
|
+
`Pressable` that promotes the queue item to run next by calling `aui.queueItem.steer()`.
|
|
685
|
+
|
|
686
|
+
```tsx
|
|
687
|
+
<QueueItemPrimitive.Steer>
|
|
688
|
+
<Text>Run now</Text>
|
|
689
|
+
</QueueItemPrimitive.Steer>
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
| Prop | Type | Description |
|
|
693
|
+
|------|------|-------------|
|
|
694
|
+
| `children` | `PressableProps["children"]` | Button content, including Pressable render-function children |
|
|
695
|
+
| `...rest` | `Omit<PressableProps, "onPress">` | Standard React Native Pressable props except `onPress` |
|
|
696
|
+
|
|
560
697
|
## ActionBar
|
|
561
698
|
|
|
562
699
|
```tsx
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Runtime options
|
|
3
|
-
description: useAgUiRuntime options, adapters,
|
|
3
|
+
description: useAgUiRuntime options, adapters, message conversion, thread list.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
import { AguiIcon } from "@/components/icons/agui";
|
|
@@ -16,7 +16,7 @@ Reference for the runtime's API surface. Start with [quickstart](/docs/runtimes/
|
|
|
16
16
|
| `showThinking` | `boolean` | Whether to render `THINKING_*` and `REASONING_*` events as visible reasoning. Defaults to `true`. |
|
|
17
17
|
| `autoCancelPendingToolCalls` | `boolean` | Cancel unresolved client-side tool calls automatically when the user sends, edits, or reloads a message. Defaults to `true`. See [below](#auto-cancelling-pending-tool-calls). |
|
|
18
18
|
| `onError` | `(e: Error) => void` | Error callback fired on `RUN_ERROR` events and protocol errors. |
|
|
19
|
-
| `onCancel` | `() => void` | Cancellation callback fired when
|
|
19
|
+
| `onCancel` | `() => void` | Cancellation callback fired when a run is cancelled, including user cancel and runtime teardown. |
|
|
20
20
|
| `adapters` | `UseAgUiRuntimeAdapters` | Standard adapter slots (see below). |
|
|
21
21
|
|
|
22
22
|
## Adapter slots
|
|
@@ -64,8 +64,20 @@ messages are gone on the next page load.
|
|
|
64
64
|
|
|
65
65
|
`fromAgUiMessages` accepts an optional second argument: pass
|
|
66
66
|
`{ showThinking: false }` to match a runtime configured with
|
|
67
|
-
`showThinking: false`, so
|
|
68
|
-
time, the same way a live run never stores
|
|
67
|
+
`showThinking: false`, so the readable text of an imported reasoning message is
|
|
68
|
+
dropped at conversion time, the same way a live run never stores it. An
|
|
69
|
+
`encryptedValue` on that message is kept, because it is opaque state the agent
|
|
70
|
+
needs back rather than something the option hides.
|
|
71
|
+
|
|
72
|
+
Reasoning makes the round trip in the shape it arrived in. `fromAgUiMessages` imports a `reasoning` record as an assistant message holding a reasoning part, and the run input converts that part back into a standalone `reasoning` record instead of dropping it, so a reloaded thread keeps its reasoning history on the next run. A reasoning part on an assistant message that also has text or tool calls leaves as its own `reasoning` record placed ahead of that assistant record; the AG-UI message body carries no run identity, so the original position of reasoning within a run is not recoverable.
|
|
73
|
+
|
|
74
|
+
The encrypted value survives with it. AG-UI describes it as an opaque chain-of-thought blob the client stores and forwards for state continuity, not as a signature computed over the text. An imported `ReasoningMessage` carrying `encryptedValue` keeps it at `providerMetadata.agui.encryptedValue` on the part, and a live run picks the same value up from the `REASONING_ENCRYPTED_VALUE` event (`subtype: "message"`, keyed by `entityId`), so reasoning from either source is re-emitted with the value intact and an agent that needs it back can replay it. A record whose readable `content` is empty and whose payload lives entirely in `encryptedValue`, the zero-data-retention shape AG-UI describes when an agent advertises `capabilities.reasoning.encrypted`, is preserved on the import path only. It has nothing to render by construction, so it never becomes a message or a part; it rides on `metadata.custom.agui.opaqueReasoning` of the message it sat next to on the wire and is replayed into the run input adjacent to that message. `showThinking` does not discard it. That option hides reasoning from the UI, and the encrypted value is opaque state the agent needs back rather than something rendered, so a hidden record keeps it and loses only the readable text. This is an import-path guarantee: a live run with `showThinking: false` opens no reasoning block, so a `REASONING_ENCRYPTED_VALUE` arriving during it resolves no slot and is not retained. The same thread therefore carries the value after a reload but not within the live session that produced it. A consumer calling `fromAgUiMessages` directly sees the metadata rather than a part.
|
|
75
|
+
|
|
76
|
+
Three limits apply to that record. A live stream that emits no readable content produces no reasoning part, so the runtime has nothing to attach the value to; only `fromAgUiMessages` preserves it, whether you call it yourself or the runtime calls it for you while importing a `MESSAGES_SNAPSHOT`. A record that sat between an assistant message and its own tool result is replayed after that tool result rather than between the two, because the import folds the result into the assistant message and the boundary is gone by export. A record in a snapshot that contains no other message has nothing to anchor to and is dropped.
|
|
77
|
+
|
|
78
|
+
Sending reasoning back is what the protocol asks for, and the inbound side has to handle it. `ag-ui-langgraph` is worth pinning for that reason: below 0.0.36 it raises `ValueError: Unsupported message role: reasoning` on the second turn of any thread that produced reasoning, because its converter recognised only the user, assistant, system, and tool roles. 0.0.36 skips inbound `reasoning` and `developer` records instead of raising, so the turn succeeds but the reasoning is discarded. 0.0.42 re-attaches an inbound `reasoning` record as a content block on the assistant message that follows it, encrypted content included, so the replay actually reaches the model; a record that no assistant message follows is still discarded there, which is what becomes of one replayed after the last message of a thread. Keep it at 0.0.36 or newer to avoid the error, and at 0.0.42 or newer for the replay to be worth anything.
|
|
79
|
+
|
|
80
|
+
What a server does with a replayed record remains its own choice, so treat continuity as best effort rather than guaranteed. `ag-ui-langgraph` covers all three behaviours across those three versions, and another integration may pick any of them; an `encryptedValue` reaches the provider only where the server forwards it.
|
|
69
81
|
|
|
70
82
|
`fromAgUiMessages` reconstructs the text, reasoning, and tool calls of each message. Multimodal user input (`image`, `audio`, `video`, and `document` parts, as well as legacy `binary` parts) is restored as attachments on the user message, so a backend that persists multimodal messages shows them again on reload and re-sends them on the next run. Legacy `binary` parts that only reference a file id are not restored.
|
|
71
83
|
|
|
@@ -73,6 +85,18 @@ An assistant message whose tool call has no matching tool result is reconstructe
|
|
|
73
85
|
|
|
74
86
|
Interrupts are restored when your backend persists them on the assistant message. The AG-UI message body has no interrupt field, so persist the runtime's own `metadata.custom.agui.interrupts` array alongside the message; `fromAgUiMessages` reads it back, reconstructs `requires-action` / `interrupt` status, and re-attaches the metadata, so `getPendingInterrupts`, `useAgUiInterrupts`, and `submitInterruptResponses` work on reload. When both a pending tool call and an interrupt are present on the same message, interrupt status wins. Without the persisted array, interrupt state cannot be reconstructed.
|
|
75
87
|
|
|
88
|
+
## Building AG-UI run input
|
|
89
|
+
|
|
90
|
+
`toAgUiMessages` is the converter the runtime uses to build `runAgent` input. Use it when you own the transport, for example an AG-UI WebSocket, and need the same conversion from `onNew`'s `AppendMessage`:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { toAgUiMessages } from "@assistant-ui/react-ag-ui";
|
|
94
|
+
|
|
95
|
+
const [agUiMessage] = toAgUiMessages([message]);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`AppendMessage` has no `id`. The converter assigns one so the AG-UI message schema is satisfied. A caller-supplied id is kept. A generated id is new on every call, so convert once and send that object. Only `user`, `assistant`, `system`, `developer`, `tool`, and `reasoning` inputs are converted.
|
|
99
|
+
|
|
76
100
|
## Thread list (experimental)
|
|
77
101
|
|
|
78
102
|
<Callout type="warn">
|
|
@@ -183,8 +207,25 @@ The runtime parses the AG-UI event stream and maps each event type to assistant-
|
|
|
183
207
|
| `STATE_SNAPSHOT` | Replaces the agent's external state. |
|
|
184
208
|
| `STATE_DELTA` | Applies a JSON-patch-style delta to the agent's state. |
|
|
185
209
|
| `MESSAGES_SNAPSHOT` | Replaces the full message list (used for thread restore). |
|
|
186
|
-
| `CUSTOM` |
|
|
187
|
-
| `RAW` |
|
|
210
|
+
| `CUSTOM` | Appended to the in-flight assistant message as a `data` part. |
|
|
211
|
+
| `RAW` | Parsed and ignored; unrecognized wire event types are normalized into `RAW`. |
|
|
212
|
+
|
|
213
|
+
### Custom events
|
|
214
|
+
|
|
215
|
+
`CUSTOM` events are the protocol's extension mechanism for application-defined data. Each event is appended to the in-flight assistant message as a canonical `data` part in arrival order: `CUSTOM { name: "sources", value: {...} }` becomes `{ type: "data", name: "sources", data: {...} }`. Repeated names append separate parts, the `value` is passed through verbatim, and data parts reset with each run. Tool calls that carry a `parentMessageId` are anchored under that message rather than at their wire position, so a data part can render after a tool call that arrived later. A run that delivers its assistant message only through `MESSAGES_SNAPSHOT`, with no streamed text or tool calls, drops that run's data parts when the snapshot supersedes the in-flight message.
|
|
216
|
+
|
|
217
|
+
Render them by registering a per-name renderer; parts without a registered renderer are not displayed, unless a `Data` fallback component is registered, in which case the fallback receives every custom event name, including the framework plumbing listed below.
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
import { useAssistantDataUI } from "@assistant-ui/react";
|
|
221
|
+
|
|
222
|
+
useAssistantDataUI({
|
|
223
|
+
name: "sources",
|
|
224
|
+
render: ({ data }) => <SourceList sources={data.sources} />,
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Data parts stay in the assistant-ui message but are not sent back to the agent, since the AG-UI assistant record has no field for them. History adapters, including the assistant-cloud one, persist them as part of the message JSON. Framework integrations emit their own plumbing over this channel (`on_interrupt`, `PredictState`, `Exit`, `hook_error`, `state_update_error`, `system:*`, `MultiAgentHandoff`), and those names surface as data parts like any other, so only register renderers for names your backend owns.
|
|
188
229
|
|
|
189
230
|
## Feature support
|
|
190
231
|
|
|
@@ -195,6 +236,7 @@ The runtime parses the AG-UI event stream and maps each event type to assistant-
|
|
|
195
236
|
| Tool calls and results | Yes |
|
|
196
237
|
| Tool result handoff (client-side execution) | Yes |
|
|
197
238
|
| State snapshots and deltas | Yes |
|
|
239
|
+
| Custom events (as `data` parts) | Yes |
|
|
198
240
|
| Cancellation | Yes |
|
|
199
241
|
| Message editing | Yes |
|
|
200
242
|
| Message reload | Yes |
|
|
@@ -5,13 +5,13 @@ description: Connect the Vercel AI SDK to a React chat UI via assistant-ui — u
|
|
|
5
5
|
|
|
6
6
|
import { VercelIcon } from "@/components/icons/vercel";
|
|
7
7
|
|
|
8
|
-
`@assistant-ui/
|
|
8
|
+
`@assistant-ui/ai-sdk` integrates assistant-ui with the [Vercel AI SDK](https://ai-sdk.dev/). It covers `useChat` flows, custom transports, frontend tools, attachments, quote context, multi-step agents, token usage, and cloud persistence.
|
|
9
9
|
|
|
10
10
|
## Pick a version
|
|
11
11
|
|
|
12
12
|
| AI SDK | Runtime package | Docs |
|
|
13
13
|
| --- | --- | --- |
|
|
14
|
-
| `ai@^7` + `@ai-sdk/react@^4` | `@assistant-ui/
|
|
14
|
+
| `ai@^7` + `@ai-sdk/react@^4` | `@assistant-ui/ai-sdk` (latest) | [v7 (current)](/docs/runtimes/ai-sdk/v7) |
|
|
15
15
|
| `ai@^6` + `@ai-sdk/react@^3` | `@assistant-ui/react-ai-sdk@1.3.40` | [v6 (legacy)](/docs/runtimes/ai-sdk/v6-legacy) |
|
|
16
16
|
| `ai@^5` + `@ai-sdk/react@^2` | `@assistant-ui/react-ai-sdk@1.1.21` | [v5 (legacy)](/docs/runtimes/ai-sdk/v5-legacy) |
|
|
17
17
|
| `ai@^4` | `@assistant-ui/react-data-stream` | [v4 (legacy)](/docs/runtimes/ai-sdk/v4-legacy) |
|
|
@@ -20,7 +20,7 @@ New projects should target v7. v6, v5, and v4 are documented for projects that h
|
|
|
20
20
|
|
|
21
21
|
## Architecture
|
|
22
22
|
|
|
23
|
-
`@assistant-ui/
|
|
23
|
+
`@assistant-ui/ai-sdk` is layered on `ExternalStoreRuntime` (see [architecture](/docs/runtimes/concepts/architecture)). Features that ship as runtime adapters work the same way they do everywhere else; see [adapters](/docs/runtimes/concepts/adapters).
|
|
24
24
|
|
|
25
25
|
For reload-safe streaming (persist an in-flight response so the client can reconnect), see [Resumable Streams](/docs/guides/resumable-streams).
|
|
26
26
|
|
|
@@ -6,12 +6,12 @@ description: Reference for projects still on AI SDK v4. New projects should use
|
|
|
6
6
|
import { VercelIcon } from "@/components/icons/vercel";
|
|
7
7
|
|
|
8
8
|
<Callout type="warn">
|
|
9
|
-
AI SDK v4 is a legacy version. New projects should use [AI SDK v7](/docs/runtimes/ai-sdk/v7). v4 integrations use the older `@assistant-ui/react-data-stream` package, not `@assistant-ui/
|
|
9
|
+
AI SDK v4 is a legacy version. New projects should use [AI SDK v7](/docs/runtimes/ai-sdk/v7). v4 integrations use the older `@assistant-ui/react-data-stream` package, not `@assistant-ui/ai-sdk`.
|
|
10
10
|
</Callout>
|
|
11
11
|
|
|
12
12
|
## Why legacy
|
|
13
13
|
|
|
14
|
-
Vercel ships AI SDK majors roughly yearly; v4 is three majors behind v7. The current `@assistant-ui/
|
|
14
|
+
Vercel ships AI SDK majors roughly yearly; v4 is three majors behind v7. The current `@assistant-ui/ai-sdk` package targets the current AI SDK major (v7) exclusively, so v4 users plug into [`@assistant-ui/react-data-stream`](/docs/runtimes/custom/data-stream) instead — the same data stream protocol that v4's `toDataStreamResponse()` emits.
|
|
15
15
|
|
|
16
16
|
This page is reference for existing v4 projects. Plan to migrate to v7 when feasible.
|
|
17
17
|
|
|
@@ -79,7 +79,7 @@ detects it automatically. If a custom proxy strips or hides that header, pass
|
|
|
79
79
|
| Feature | v4 | v6 |
|
|
80
80
|
| --- | --- | --- |
|
|
81
81
|
| `ai` package | `ai@^4` | `ai@^6` |
|
|
82
|
-
| Runtime package | `@assistant-ui/react-data-stream` | `@assistant-ui/react-ai-sdk` |
|
|
82
|
+
| Runtime package | `@assistant-ui/react-data-stream` | `@assistant-ui/react-ai-sdk@1.3.40` |
|
|
83
83
|
| Runtime hook | `useDataStreamRuntime` | `useChatRuntime` |
|
|
84
84
|
| Response | `toDataStreamResponse()` | `toUIMessageStreamResponse()` |
|
|
85
85
|
| Tool schema | `parameters: z.object({...})` | `inputSchema: zodSchema(z.object({...}))` |
|
|
@@ -89,7 +89,7 @@ detects it automatically. If a custom proxy strips or hides that header, pass
|
|
|
89
89
|
|
|
90
90
|
When you are ready to upgrade:
|
|
91
91
|
|
|
92
|
-
1. Swap `@assistant-ui/react-data-stream` for `@assistant-ui/
|
|
92
|
+
1. Swap `@assistant-ui/react-data-stream` for `@assistant-ui/ai-sdk`.
|
|
93
93
|
2. Update your backend to the current AI SDK's `streamText` (see [v7 docs](/docs/runtimes/ai-sdk/v7)).
|
|
94
94
|
3. Switch the runtime hook from `useDataStreamRuntime` to `useChatRuntime`.
|
|
95
95
|
|