@assistant-ui/mcp-docs-server 0.1.35 → 0.1.38
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 +2 -2
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +4 -4
- package/.docs/organized/code-examples/with-artifacts.md +4 -4
- package/.docs/organized/code-examples/with-assistant-transport.md +70 -54
- package/.docs/organized/code-examples/with-browser-extension.md +4 -4
- package/.docs/organized/code-examples/with-chain-of-thought.md +40 -89
- 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 +4 -4
- 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-eve.md +343 -0
- package/.docs/organized/code-examples/with-expo.md +910 -933
- package/.docs/organized/code-examples/with-external-store.md +2 -2
- package/.docs/organized/code-examples/with-ffmpeg.md +5 -8
- package/.docs/organized/code-examples/with-generative-ui.md +6 -6
- package/.docs/organized/code-examples/with-google-adk.md +3 -3
- package/.docs/organized/code-examples/with-heat-graph.md +1 -1
- package/.docs/organized/code-examples/with-image-generation.md +4 -4
- package/.docs/organized/code-examples/with-interactables.md +166 -338
- package/.docs/organized/code-examples/with-langchain.md +4 -4
- package/.docs/organized/code-examples/with-langgraph.md +20 -157
- package/.docs/organized/code-examples/with-livekit.md +8 -8
- package/.docs/organized/code-examples/with-mcp.md +19 -10
- package/.docs/organized/code-examples/with-opencode.md +3 -3
- package/.docs/organized/code-examples/with-pi.md +9 -7
- package/.docs/organized/code-examples/with-react-hook-form.md +13 -6
- package/.docs/organized/code-examples/with-react-ink-web.md +5 -5
- package/.docs/organized/code-examples/with-react-ink.md +1 -1
- package/.docs/organized/code-examples/with-react-router.md +11 -11
- package/.docs/organized/code-examples/with-resumable-stream.md +5 -5
- package/.docs/organized/code-examples/with-store.md +1 -1
- package/.docs/organized/code-examples/with-tanstack.md +7 -7
- package/.docs/organized/code-examples/with-tap-runtime.md +2 -2
- package/.docs/organized/code-examples/with-virtualized-thread.md +44 -24
- package/.docs/raw/docs/(docs)/cli.mdx +5 -3
- package/.docs/raw/docs/(docs)/devtools.mdx +25 -2
- package/.docs/raw/docs/(docs)/index.mdx +5 -2
- package/.docs/raw/docs/(docs)/installation.mdx +5 -2
- package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +16 -16
- package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +73 -42
- package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +3 -20
- package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +234 -166
- package/.docs/raw/docs/(reference)/api-reference/integrations/eve.mdx +51 -0
- package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +4 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +70 -38
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +30 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +7 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +26 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/chain-of-thought.mdx +15 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +103 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +16 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +56 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/queue-item.mdx +12 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +12 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +14 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +57 -1
- package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +6 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/interactables-legacy.mdx +55 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/interactables.mdx +151 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +15 -15
- package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +20 -20
- package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +25 -9
- package/.docs/raw/docs/cloud/langgraph.mdx +1 -1
- package/.docs/raw/docs/guides/headless-composer-input.mdx +113 -0
- package/.docs/raw/docs/guides/latex.mdx +28 -22
- package/.docs/raw/docs/guides/mentions.mdx +32 -7
- package/.docs/raw/docs/guides/slash-commands.mdx +3 -6
- package/.docs/raw/docs/guides/speech.mdx +5 -7
- package/.docs/raw/docs/guides/virtualization.mdx +77 -7
- package/.docs/raw/docs/guides/voice.mdx +3 -2
- package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +4 -12
- package/.docs/raw/docs/integrations/auth/better-auth.mdx +7 -10
- package/.docs/raw/docs/integrations/auth/clerk.mdx +3 -9
- package/.docs/raw/docs/integrations/auth/next-auth.mdx +3 -8
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +11 -8
- package/.docs/raw/docs/integrations/index.mdx +6 -13
- package/.docs/raw/docs/integrations/observability/helicone.mdx +3 -4
- package/.docs/raw/docs/integrations/observability/langfuse.mdx +3 -5
- package/.docs/raw/docs/integrations/observability/langsmith.mdx +5 -4
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +4 -3
- package/.docs/raw/docs/migrations/react-langgraph-v0-7.mdx +2 -2
- package/.docs/raw/docs/primitives/composer.mdx +8 -0
- package/.docs/raw/docs/primitives/thread-list.mdx +30 -6
- package/.docs/raw/docs/primitives/thread.mdx +24 -0
- package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +24 -1
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +1 -1
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +54 -0
- package/.docs/raw/docs/runtimes/eve/overview.mdx +100 -0
- package/.docs/raw/docs/runtimes/eve/quickstart.mdx +143 -0
- package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/langchain.mdx +388 -20
- package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +1 -1
- package/.docs/raw/docs/runtimes/opencode/hooks.mdx +1 -1
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +6 -0
- package/.docs/raw/docs/tools/defining-tools.mdx +9 -0
- package/.docs/raw/docs/tools/generative-ui.mdx +37 -0
- package/.docs/raw/docs/tools/interactables-legacy.mdx +410 -0
- package/.docs/raw/docs/tools/interactables.mdx +892 -223
- package/.docs/raw/docs/tools/mcp-apps.mdx +12 -3
- package/.docs/raw/docs/tools/mcp.mdx +9 -4
- package/.docs/raw/docs/tools/multi-agent.mdx +5 -0
- package/.docs/raw/docs/tools/user-managed-mcp.mdx +17 -3
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +2 -0
- package/.docs/raw/docs/ui/file.mdx +1 -1
- package/.docs/raw/docs/ui/follow-up-suggestions.mdx +80 -0
- package/.docs/raw/docs/ui/model-selector.mdx +38 -5
- package/.docs/raw/docs/ui/part-grouping.mdx +38 -0
- package/.docs/raw/docs/utilities/react-o11y.mdx +92 -6
- package/README.md +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -2
- package/dist/index.js.map +1 -1
- package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
- package/dist/prepare-docs/copy-raw.js +0 -4
- package/dist/prepare-docs/copy-raw.js.map +1 -1
- package/dist/tools/docs.d.ts.map +1 -1
- package/dist/tools/docs.js +18 -6
- package/dist/tools/docs.js.map +1 -1
- package/dist/tools/examples.d.ts +3 -1
- package/dist/tools/examples.d.ts.map +1 -1
- package/dist/tools/examples.js +1 -1
- package/dist/tools/examples.js.map +1 -1
- package/dist/tools/resources.d.ts +7 -0
- package/dist/tools/resources.d.ts.map +1 -0
- package/dist/tools/resources.js +74 -0
- package/dist/tools/resources.js.map +1 -0
- package/dist/tools/search.d.ts +33 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +39 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/tests/test-setup.d.ts.map +1 -1
- package/dist/tools/tests/test-setup.js +3 -1
- package/dist/tools/tests/test-setup.js.map +1 -1
- package/dist/utils/mdx.d.ts +2 -1
- package/dist/utils/mdx.d.ts.map +1 -1
- package/dist/utils/mdx.js +19 -2
- package/dist/utils/mdx.js.map +1 -1
- package/dist/utils/paths.d.ts +2 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +18 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/search.d.ts +10 -0
- package/dist/utils/search.d.ts.map +1 -0
- package/dist/utils/search.js +97 -0
- package/dist/utils/search.js.map +1 -0
- package/package.json +4 -4
- package/src/constants.ts +2 -0
- package/src/index.ts +28 -6
- package/src/prepare-docs/copy-raw.ts +0 -5
- package/src/tools/docs.ts +30 -4
- package/src/tools/examples.ts +4 -2
- package/src/tools/resources.ts +114 -0
- package/src/tools/search.ts +46 -0
- package/src/tools/tests/completions.test.ts +46 -0
- package/src/tools/tests/directory-size-cap.test.ts +50 -0
- package/src/tools/tests/mcp-protocol.test.ts +21 -1
- package/src/tools/tests/resources.test.ts +102 -0
- package/src/tools/tests/search.test.ts +37 -0
- package/src/tools/tests/test-setup.ts +2 -0
- package/src/utils/mdx.ts +21 -1
- package/src/utils/paths.ts +22 -0
- package/src/utils/search.ts +131 -0
- package/.docs/raw/blog/2024-07-29-hello/index.mdx +0 -64
- package/.docs/raw/blog/2024-09-11/index.mdx +0 -10
- package/.docs/raw/blog/2024-12-15/index.mdx +0 -10
- package/.docs/raw/blog/2025-01-31-changelog/index.mdx +0 -127
- package/.docs/raw/blog/2026-03-launch-week/index.mdx +0 -258
|
@@ -8,12 +8,9 @@ Mentions let users type `@` in the composer to open a popover picker, select an
|
|
|
8
8
|
|
|
9
9
|
## How It Works
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Directive inserted ← User selects item from popover
|
|
15
|
-
↓
|
|
16
|
-
Message sent with ":tool[Label]{name=id}" in text
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart LR
|
|
13
|
+
type["User types @"] --> trigger["Trigger detected"] --> adapter["Adapter provides<br/>categories / items"] --> select["User selects item<br/>from popover"] --> insert["Directive inserted"] --> sent["Message sent with<br/>:tool[Label]{name=id} text"]
|
|
17
14
|
```
|
|
18
15
|
|
|
19
16
|
The mention system has three layers:
|
|
@@ -85,7 +82,35 @@ const myAdapter: Unstable_TriggerAdapter = {
|
|
|
85
82
|
|
|
86
83
|
### Async Mention Search
|
|
87
84
|
|
|
88
|
-
The
|
|
85
|
+
The built-in `unstable_useLiveCompletionAdapter` wraps an async fetcher with debouncing, stale-request cancellation (results for an outdated query are dropped), and a single-entry cache. Its `search` returns the last results synchronously and schedules a debounced fetch when the query changes; when results arrive the returned `adapter` re-creates, which re-runs the popover lookup so the fresh items render. It also reports `isLoading`, which you pass to the popover to show a loading state.
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import {
|
|
89
|
+
unstable_useLiveCompletionAdapter,
|
|
90
|
+
unstable_defaultDirectiveFormatter,
|
|
91
|
+
} from "@assistant-ui/react";
|
|
92
|
+
import { ComposerTriggerPopover } from "@/components/assistant-ui/composer-trigger-popover";
|
|
93
|
+
|
|
94
|
+
function MentionPopover() {
|
|
95
|
+
const mentions = unstable_useLiveCompletionAdapter({
|
|
96
|
+
fetcher: async (query) => {
|
|
97
|
+
const users = await fetchUsers(query);
|
|
98
|
+
return users.map((u) => ({ id: u.id, type: "user", label: u.name }));
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<ComposerTriggerPopover
|
|
104
|
+
char="@"
|
|
105
|
+
adapter={mentions.adapter}
|
|
106
|
+
isLoading={mentions.isLoading}
|
|
107
|
+
directive={{ formatter: unstable_defaultDirectiveFormatter }}
|
|
108
|
+
/>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The adapter interface is itself synchronous, so you can also wire async data by hand when you need a custom cache, no debounce, or an existing query client. Load results into React state (or a query cache) and read the current snapshot inside the adapter methods. The adapter re-creates on each render, so the popover always sees the latest results.
|
|
89
114
|
|
|
90
115
|
**With React state and `useEffect`:**
|
|
91
116
|
|
|
@@ -8,12 +8,9 @@ Slash commands let users type `/` in the composer to open a popover, browse avai
|
|
|
8
8
|
|
|
9
9
|
## How It Works
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Callback fired ← User selects command from popover
|
|
15
|
-
↓
|
|
16
|
-
Directive chip left in composer (or removed if removeOnExecute)
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart LR
|
|
13
|
+
type["User types /"] --> trigger["Trigger detected"] --> adapter["Adapter provides<br/>commands"] --> select["User selects command<br/>from popover"] --> callback["Callback fired"] --> chip["Directive chip left in composer<br/>(or removed if removeOnExecute)"]
|
|
17
14
|
```
|
|
18
15
|
|
|
19
16
|
The slash command system is built on the same [trigger popover architecture](#trigger-popover-architecture) as mentions. A slash command declares its behavior with a `<TriggerPopover.Action>` sub-primitive whose `onExecute` callback fires when an item is chosen.
|
|
@@ -57,24 +57,22 @@ const runtime = useChatRuntime({
|
|
|
57
57
|
The default action bar does not include a speech button. Add `ActionBarPrimitive.Speak` and `ActionBarPrimitive.StopSpeaking` to your assistant message action bar:
|
|
58
58
|
|
|
59
59
|
```tsx
|
|
60
|
-
import { ActionBarPrimitive,
|
|
60
|
+
import { ActionBarPrimitive, AuiIf } from "@assistant-ui/react";
|
|
61
61
|
import { AudioLinesIcon, StopCircleIcon } from "lucide-react";
|
|
62
62
|
|
|
63
63
|
const AssistantActionBar = () => {
|
|
64
|
-
const isSpeaking = useMessageTTS();
|
|
65
|
-
|
|
66
64
|
return (
|
|
67
65
|
<ActionBarPrimitive.Root>
|
|
68
|
-
{
|
|
66
|
+
<AuiIf condition={(s) => s.message.speech == null}>
|
|
69
67
|
<ActionBarPrimitive.Speak>
|
|
70
68
|
<AudioLinesIcon />
|
|
71
69
|
</ActionBarPrimitive.Speak>
|
|
72
|
-
|
|
73
|
-
{
|
|
70
|
+
</AuiIf>
|
|
71
|
+
<AuiIf condition={(s) => s.message.speech != null}>
|
|
74
72
|
<ActionBarPrimitive.StopSpeaking>
|
|
75
73
|
<StopCircleIcon />
|
|
76
74
|
</ActionBarPrimitive.StopSpeaking>
|
|
77
|
-
|
|
75
|
+
</AuiIf>
|
|
78
76
|
<ActionBarPrimitive.Copy />
|
|
79
77
|
</ActionBarPrimitive.Root>
|
|
80
78
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Thread Virtualization
|
|
3
|
-
description: Render very long threads with @tanstack/react-virtual and ThreadPrimitive.MessageByIndex.
|
|
3
|
+
description: Render very long threads with @tanstack/react-virtual, with ThreadPrimitive.Unstable_MessageById and ThreadPrimitive.MessageByIndex.
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -10,9 +10,35 @@ Virtualization mounts only the messages near the viewport and represents the res
|
|
|
10
10
|
|
|
11
11
|
Probably not. The default kit already renders message bodies with `content-visibility: auto` and `contain-intrinsic-size`, which skips paint work for off-screen messages, and `ThreadPrimitive.Viewport` handles auto-scroll. That covers typical threads. Reach for virtualization when React mount and update cost itself becomes the bottleneck: threads with hundreds to thousands of messages, or very heavy per-message content, where typing latency degrades because every message stays mounted.
|
|
12
12
|
|
|
13
|
-
## Rendering
|
|
13
|
+
## Rendering Messages By Id
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
For virtualized rows, use message ids as the row identity. `unstable_useThreadMessageIds` returns the thread's ids with stable array identity across content-only updates, and `ThreadPrimitive.Unstable_MessageById` renders one message with the same `components` surface as `MessageByIndex`. Unknown ids render `null`, which is useful when a virtual row unmounts after a message was removed.
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
const MESSAGE_COMPONENTS = { UserMessage, AssistantMessage };
|
|
19
|
+
|
|
20
|
+
const messageIds = unstable_useThreadMessageIds();
|
|
21
|
+
|
|
22
|
+
return messageIds.map((messageId) => (
|
|
23
|
+
<ThreadPrimitive.Unstable_MessageById
|
|
24
|
+
key={messageId}
|
|
25
|
+
messageId={messageId}
|
|
26
|
+
components={MESSAGE_COMPONENTS}
|
|
27
|
+
/>
|
|
28
|
+
));
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
<Callout type="warn">
|
|
32
|
+
`unstable_useThreadMessageIds` and `ThreadPrimitive.Unstable_MessageById` are
|
|
33
|
+
experimental and may change in any release.
|
|
34
|
+
</Callout>
|
|
35
|
+
|
|
36
|
+
## Rendering Messages By Index
|
|
37
|
+
|
|
38
|
+
`ThreadPrimitive.MessageByIndex` is still supported and is the smaller API when
|
|
39
|
+
you already have a stable index from a fixed-order list. It renders a single
|
|
40
|
+
message at that index and memoizes on the index plus the per-field `components`
|
|
41
|
+
identity:
|
|
16
42
|
|
|
17
43
|
```tsx
|
|
18
44
|
const MESSAGE_COMPONENTS = { UserMessage, AssistantMessage };
|
|
@@ -20,15 +46,59 @@ const MESSAGE_COMPONENTS = { UserMessage, AssistantMessage };
|
|
|
20
46
|
<ThreadPrimitive.MessageByIndex index={index} components={MESSAGE_COMPONENTS} />;
|
|
21
47
|
```
|
|
22
48
|
|
|
49
|
+
For virtualizers, prefer the id-based API above when you can. Index rows are more
|
|
50
|
+
fragile when messages are inserted, removed, reordered, or when a virtual row
|
|
51
|
+
briefly outlives the item it was created for.
|
|
52
|
+
|
|
23
53
|
## Grouping into turns
|
|
24
54
|
|
|
25
|
-
|
|
55
|
+
The example virtualizes per user turn (a user message plus the responses that follow it), which gives the virtualizer stable, meaningfully sized items. Keep the id and role together in a stable row shape so the turn array only rebuilds when message membership or roles change:
|
|
26
56
|
|
|
27
57
|
```tsx
|
|
28
|
-
|
|
29
|
-
|
|
58
|
+
type MessageRow = {
|
|
59
|
+
id: string;
|
|
60
|
+
role: "user" | "assistant" | "system";
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const useThreadMessageRows = (): readonly MessageRow[] => {
|
|
64
|
+
const prevRowsRef = useRef<readonly MessageRow[]>([]);
|
|
65
|
+
|
|
66
|
+
return useAuiState((s) => {
|
|
67
|
+
const messages = s.thread.messages;
|
|
68
|
+
const prev = prevRowsRef.current;
|
|
69
|
+
if (
|
|
70
|
+
prev.length === messages.length &&
|
|
71
|
+
prev.every((row, index) => {
|
|
72
|
+
const message = messages[index]!;
|
|
73
|
+
return row.id === message.id && row.role === message.role;
|
|
74
|
+
})
|
|
75
|
+
) {
|
|
76
|
+
return prev;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const next = messages.map(({ id, role }) => ({ id, role }));
|
|
80
|
+
prevRowsRef.current = next;
|
|
81
|
+
return next;
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const messageRows = useThreadMessageRows();
|
|
86
|
+
const turns = useMemo(
|
|
87
|
+
() => buildTurns(messageRows),
|
|
88
|
+
[messageRows],
|
|
30
89
|
);
|
|
31
|
-
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Then each virtual turn renders the ids it owns:
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
{turn.messageIds.map((messageId) => (
|
|
96
|
+
<ThreadPrimitive.Unstable_MessageById
|
|
97
|
+
key={messageId}
|
|
98
|
+
messageId={messageId}
|
|
99
|
+
components={MESSAGE_COMPONENTS}
|
|
100
|
+
/>
|
|
101
|
+
))}
|
|
32
102
|
```
|
|
33
103
|
|
|
34
104
|
## Padding spacers, not absolute positioning
|
|
@@ -156,8 +156,9 @@ class MyVoiceAdapter implements RealtimeVoiceAdapter {
|
|
|
156
156
|
|
|
157
157
|
The session status follows the same pattern as other adapters:
|
|
158
158
|
|
|
159
|
-
```
|
|
160
|
-
|
|
159
|
+
```mermaid
|
|
160
|
+
flowchart LR
|
|
161
|
+
starting["starting"] --> running["running"] --> ended["ended"]
|
|
161
162
|
```
|
|
162
163
|
|
|
163
164
|
The `ended` status includes a `reason`:
|
|
@@ -9,18 +9,10 @@ For the adapter contract itself, see [adapters](/docs/runtimes/concepts/adapters
|
|
|
9
9
|
|
|
10
10
|
## How it works
|
|
11
11
|
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
PendingAttachment with the public URL
|
|
17
|
-
│
|
|
18
|
-
composer send ◄────────────────────────────────────┘
|
|
19
|
-
│
|
|
20
|
-
└─► send() emits a content part with the URL
|
|
21
|
-
│
|
|
22
|
-
▼
|
|
23
|
-
AI SDK passes URL to the model
|
|
12
|
+
```mermaid
|
|
13
|
+
flowchart LR
|
|
14
|
+
add["composer add"] --> presign["POST /api/upload<br/>(presign)"] --> put["PUT to object storage"] --> pending["PendingAttachment<br/>with the public URL"]
|
|
15
|
+
pending --> send["composer send"] --> part["send() emits a<br/>content part with the URL"] --> model["AI SDK passes<br/>URL to the model"]
|
|
24
16
|
```
|
|
25
17
|
|
|
26
18
|
Three ideas to internalize before reading the code:
|
|
@@ -9,16 +9,13 @@ This page covers the non-cloud path. AssistantCloud users should see [cloud auth
|
|
|
9
9
|
|
|
10
10
|
## How it works
|
|
11
11
|
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
│
|
|
20
|
-
▼
|
|
21
|
-
scope queries by userId
|
|
12
|
+
```mermaid
|
|
13
|
+
flowchart LR
|
|
14
|
+
browser["browser"] --> routes["/api/auth/[...all]<br/>/api/chat<br/>/api/threads/*"]
|
|
15
|
+
routes --> handlers["better-auth handlers"]
|
|
16
|
+
routes --> session["auth.api.getSession({ headers })"]
|
|
17
|
+
handlers --> session
|
|
18
|
+
session --> uid["session.user.id"] --> scope["scope queries by userId"]
|
|
22
19
|
```
|
|
23
20
|
|
|
24
21
|
Three integration points:
|
|
@@ -9,15 +9,9 @@ If you use AssistantCloud, see [cloud authorization](/docs/cloud/authorization)
|
|
|
9
9
|
|
|
10
10
|
## How it works
|
|
11
11
|
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
│
|
|
16
|
-
▼
|
|
17
|
-
auth() returns { userId }
|
|
18
|
-
│
|
|
19
|
-
▼
|
|
20
|
-
scope queries by userId
|
|
12
|
+
```mermaid
|
|
13
|
+
flowchart LR
|
|
14
|
+
browser["browser"] --> mw["clerkMiddleware<br/>(proxy.ts)"] --> routes["/api/chat<br/>/api/threads/*"] --> auth["auth() returns { userId }"] --> scope["scope queries by userId"]
|
|
21
15
|
```
|
|
22
16
|
|
|
23
17
|
Three places Clerk touches the integration:
|
|
@@ -9,14 +9,9 @@ If you use AssistantCloud, see [cloud authorization](/docs/cloud) instead; cloud
|
|
|
9
9
|
|
|
10
10
|
## How it works
|
|
11
11
|
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
▼
|
|
16
|
-
scope queries by session.user.id
|
|
17
|
-
│
|
|
18
|
-
▼
|
|
19
|
-
database
|
|
12
|
+
```mermaid
|
|
13
|
+
flowchart LR
|
|
14
|
+
browser["browser"] --> routes["/api/chat<br/>/api/threads/*"] --> auth["auth() returns session"] --> scope["scope queries by<br/>session.user.id"] --> db["database"]
|
|
20
15
|
```
|
|
21
16
|
|
|
22
17
|
Three places auth touches the integration:
|
|
@@ -5,7 +5,7 @@ description: Wire the Vercel AI SDK into a React chat UI with assistant-ui — u
|
|
|
5
5
|
|
|
6
6
|
import { VercelIcon } from "@/components/icons/vercel";
|
|
7
7
|
|
|
8
|
-
[Vercel AI SDK](https://ai-sdk.dev/) is the most common framework people pair with assistant-ui. The full setup, attachments, persistence, tool-call patterns, and version notes are documented under [runtimes/ai-sdk](/docs/runtimes/ai-sdk); this page is the entry point in the integrations tree for discoverability and architecture context.
|
|
8
|
+
[Vercel AI SDK](https://ai-sdk.dev/) is the most common framework people pair with assistant-ui. The full setup, attachments, persistence, tool-call patterns, and version notes are documented under [runtimes/ai-sdk](/docs/runtimes/ai-sdk/overview); this page is the entry point in the integrations tree for discoverability and architecture context.
|
|
9
9
|
|
|
10
10
|
<Callout type="info">
|
|
11
11
|
If you arrived here looking to wire up your first chat: jump to [AI SDK v6 quickstart](/docs/runtimes/ai-sdk/v6). This page is a high-level pointer.
|
|
@@ -13,11 +13,14 @@ If you arrived here looking to wire up your first chat: jump to [AI SDK v6 quick
|
|
|
13
13
|
|
|
14
14
|
## Where it slots in
|
|
15
15
|
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
```mermaid
|
|
17
|
+
flowchart LR
|
|
18
|
+
client["client"]
|
|
19
|
+
runtime["useChatRuntime (react-ai-sdk)<br/>(thread state · tool calls · attachments<br/>speech · dictation · feedback adapters)"]
|
|
20
|
+
api["/api/chat<br/>(streamText)"]
|
|
21
|
+
provider["provider"]
|
|
22
|
+
|
|
23
|
+
client --> runtime --> api --> provider
|
|
21
24
|
```
|
|
22
25
|
|
|
23
26
|
`@assistant-ui/react-ai-sdk` wraps the AI SDK's `useChat` hook and exposes it as an assistant-ui runtime. The runtime owns conversation state on the client; your `/api/chat` route returns a UI message stream from `streamText`. Everything else (tools, attachments, observability, gateways, custom persistence) layers on top of this base.
|
|
@@ -55,7 +58,7 @@ AI SDK is the default choice for new projects on Next.js, Remix, or any framewor
|
|
|
55
58
|
- You will compose with a framework like [Mastra](/docs/integrations/frameworks/mastra/overview), an [observability tool](/docs/integrations/observability/helicone), an [LLM gateway](/docs/integrations/gateways), or [tools through MCP](/docs/tools/mcp), all of which assume an AI SDK route.
|
|
56
59
|
- You want first-party `frontendTools`, attachments, multi-step tool calls, token-usage metadata, and persisted history via `withFormat`.
|
|
57
60
|
|
|
58
|
-
If you need streaming agent state (subgraph events, generative UI messages), look at [LangGraph](/docs/runtimes/langgraph) instead. If you have a different protocol-shaped backend (A2A, AG-UI, OpenCode), see [pick a runtime](/docs/runtimes/pick-a-runtime).
|
|
61
|
+
If you need streaming agent state (subgraph events, generative UI messages), look at [LangGraph](/docs/runtimes/langgraph/overview) instead. If you have a different protocol-shaped backend (A2A, AG-UI, OpenCode), see [pick a runtime](/docs/runtimes/pick-a-runtime).
|
|
59
62
|
|
|
60
63
|
## Related
|
|
61
64
|
|
|
@@ -64,7 +67,7 @@ If you need streaming agent state (subgraph events, generative UI messages), loo
|
|
|
64
67
|
icon={<VercelIcon width={20} height={20} />}
|
|
65
68
|
title="AI SDK runtime overview"
|
|
66
69
|
description="The full runtime documentation and version selector."
|
|
67
|
-
href="/docs/runtimes/ai-sdk"
|
|
70
|
+
href="/docs/runtimes/ai-sdk/overview"
|
|
68
71
|
/>
|
|
69
72
|
<Card
|
|
70
73
|
title="Pick a runtime"
|
|
@@ -15,18 +15,11 @@ Integrations are wiring guides for using third-party services with assistant-ui,
|
|
|
15
15
|
|
|
16
16
|
## Where integrations slot in
|
|
17
17
|
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
frameworks │ │ proxies
|
|
24
|
-
(e.g. │ │ (e.g. Helicone,
|
|
25
|
-
Mastra) │ │ Langfuse)
|
|
26
|
-
▼ │
|
|
27
|
-
run on the server, │
|
|
28
|
-
then forward calls ──────┘
|
|
29
|
-
to the provider
|
|
18
|
+
```mermaid
|
|
19
|
+
flowchart LR
|
|
20
|
+
client["client"] --> route["your API route"] --> provider["LLM provider"]
|
|
21
|
+
route -->|"agent frameworks (e.g. Mastra)"| server["run on the server,<br/>then forward calls"]
|
|
22
|
+
server -->|"observability proxies (e.g. Helicone, Langfuse)"| provider
|
|
30
23
|
```
|
|
31
24
|
|
|
32
25
|
Integrations live on the server. **Agent frameworks** like Mastra take over the API route. **Gateways** swap the upstream provider URL. **Observability** logs or traces every call. **Auth** gates the route and scopes per-user data. **Persistence** and **attachments** are adapter recipes for storing chat data outside the default in-memory path.
|
|
@@ -165,7 +158,7 @@ Upload chat attachments to object storage instead of inlining as data URLs.
|
|
|
165
158
|
assistant-ui doesn't ship a guide for every tool, but most fit one of two patterns:
|
|
166
159
|
|
|
167
160
|
- **Routes through your AI SDK handler** (agent frameworks, observability proxies, gateways): adapt the [Mastra full-stack](/docs/integrations/frameworks/mastra/full-stack) or [Helicone proxy](/docs/integrations/observability/helicone) pattern using the service's own SDK.
|
|
168
|
-
- **Replaces the runtime entirely** (custom backends): see [custom backend](/docs/runtimes/custom).
|
|
161
|
+
- **Replaces the runtime entirely** (custom backends): see [custom backend](/docs/runtimes/custom/overview).
|
|
169
162
|
|
|
170
163
|
If you build something useful, [open an issue](https://github.com/assistant-ui/assistant-ui/issues) or post in [Discord](https://discord.gg/S9dwgCNEFs); the docs are open to contributions.
|
|
171
164
|
|
|
@@ -11,10 +11,9 @@ Helicone is independent of which assistant-ui runtime you use. It slots in at th
|
|
|
11
11
|
|
|
12
12
|
## How it works
|
|
13
13
|
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
└─ logs request, response, tokens, cost
|
|
14
|
+
```mermaid
|
|
15
|
+
flowchart LR
|
|
16
|
+
server["your server"] --> proxy["Helicone proxy<br/>(logs request, response, tokens, cost)"] --> provider["OpenAI / Anthropic / etc."]
|
|
18
17
|
```
|
|
19
18
|
|
|
20
19
|
Calls pass through Helicone's edge before reaching the upstream provider. The proxy is transparent: response shape and streaming behavior are unchanged, you just gain a dashboard of every call.
|
|
@@ -13,11 +13,9 @@ Pick Langfuse when you want to see the agent's full call tree inside a single tu
|
|
|
13
13
|
|
|
14
14
|
## How it works
|
|
15
15
|
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
▼
|
|
20
|
-
OpenTelemetry SDK ──► LangfuseSpanProcessor ──► Langfuse
|
|
16
|
+
```mermaid
|
|
17
|
+
flowchart LR
|
|
18
|
+
route["your route"] --> stream["AI SDK streamText<br/>(experimental_telemetry)"] --> otel["OpenTelemetry SDK"] --> proc["LangfuseSpanProcessor"] --> langfuse["Langfuse"]
|
|
21
19
|
```
|
|
22
20
|
|
|
23
21
|
Langfuse subscribes to OpenTelemetry spans the AI SDK already emits when telemetry is enabled. No proxy, no wrapping; the SDK ships spans and Langfuse renders them.
|
|
@@ -9,14 +9,15 @@ import { VercelIcon } from "@/components/icons/vercel";
|
|
|
9
9
|
|
|
10
10
|
[LangSmith](https://www.langchain.com/langsmith) is LangChain's observability and eval platform. If you are already in the LangChain or LangGraph ecosystem, LangSmith is the natural pairing: traces, datasets, prompt versioning, and LLM-as-judge evals share state with the rest of the LangChain stack.
|
|
11
11
|
|
|
12
|
-
This page covers the **AI SDK** path. If you use [`@assistant-ui/react-langgraph`](/docs/runtimes/langgraph), tracing flows through LangGraph Cloud automatically; you only need this guide when your route handler talks to AI SDK directly.
|
|
12
|
+
This page covers the **AI SDK** path. If you use [`@assistant-ui/react-langgraph`](/docs/runtimes/langgraph/overview), tracing flows through LangGraph Cloud automatically; you only need this guide when your route handler talks to AI SDK directly.
|
|
13
13
|
|
|
14
14
|
## How it works
|
|
15
15
|
|
|
16
16
|
LangSmith provides a wrapper around the `ai` namespace. You call `wrapAISDK(ai)`, get back the same exports (`generateText`, `streamText`, `generateObject`, `streamObject`), and use those in place of the originals. Every call is then traced.
|
|
17
17
|
|
|
18
|
-
```
|
|
19
|
-
|
|
18
|
+
```mermaid
|
|
19
|
+
flowchart LR
|
|
20
|
+
route["your route"] --> stream["wrapped streamText"] --> client["LangSmith client"] --> langsmith["LangSmith"]
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
## Setup
|
|
@@ -133,7 +134,7 @@ Send a message. The trace should appear in your LangSmith project within seconds
|
|
|
133
134
|
icon={<LangGraphIcon width={20} height={20} className="text-[#1C3C3C] dark:text-[#5b9595]" />}
|
|
134
135
|
title="LangGraph runtime"
|
|
135
136
|
description="If your backend is LangGraph, tracing flows through LangGraph Cloud automatically."
|
|
136
|
-
href="/docs/runtimes/langgraph"
|
|
137
|
+
href="/docs/runtimes/langgraph/overview"
|
|
137
138
|
/>
|
|
138
139
|
<Card
|
|
139
140
|
icon={<LangfuseIcon width={20} height={20} />}
|
|
@@ -18,9 +18,10 @@ If you're rolling your own auth, replace `auth()` calls with whatever your stack
|
|
|
18
18
|
|
|
19
19
|
## How it works
|
|
20
20
|
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
```mermaid
|
|
22
|
+
flowchart LR
|
|
23
|
+
client["client"] --> threads["/api/threads/*<br/>(RemoteThreadListAdapter)"] --> tt["threads table"]
|
|
24
|
+
client --> messages["/api/messages/*<br/>(ThreadHistoryAdapter)"] --> mt["messages table"]
|
|
24
25
|
```
|
|
25
26
|
|
|
26
27
|
Two adapters, two tables:
|
|
@@ -323,6 +323,6 @@ export function Provider({ children }) {
|
|
|
323
323
|
## Need Help?
|
|
324
324
|
|
|
325
325
|
If you encounter issues during migration:
|
|
326
|
-
1. Check the updated [LangGraph documentation](/docs/runtimes/langgraph)
|
|
326
|
+
1. Check the updated [LangGraph documentation](/docs/runtimes/langgraph/overview)
|
|
327
327
|
2. Review the [example implementation](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-langgraph)
|
|
328
|
-
3. Report issues on [GitHub](https://github.com/assistant-ui/assistant-ui/issues)
|
|
328
|
+
3. Report issues on [GitHub](https://github.com/assistant-ui/assistant-ui/issues)
|
|
@@ -103,6 +103,14 @@ import { ComposerPrimitive } from "@assistant-ui/react";
|
|
|
103
103
|
|
|
104
104
|
The primitive's behavior (keyboard handling, disabled state, form submission) is merged onto your element. Your styles, your component, primitive wiring.
|
|
105
105
|
|
|
106
|
+
<Callout type="info">
|
|
107
|
+
Own the input DOM entirely, such as a `contentEditable` surface or editor
|
|
108
|
+
library that cannot be expressed through `asChild` or `render`? See
|
|
109
|
+
[Headless Composer Input](/docs/guides/headless-composer-input) for the
|
|
110
|
+
unstable hook that supplies composer text and send gating without
|
|
111
|
+
`ComposerPrimitive.Input`.
|
|
112
|
+
</Callout>
|
|
113
|
+
|
|
106
114
|
### Unstable Trigger Popovers
|
|
107
115
|
|
|
108
116
|
Composer includes an unstable **trigger popover** system for character-triggered popovers (e.g. `@` for mentions, `/` for slash commands). Multiple triggers coexist under a single `TriggerPopoverRoot`.
|
|
@@ -38,12 +38,12 @@ function MyThreadList() {
|
|
|
38
38
|
|
|
39
39
|
function ThreadListItem() {
|
|
40
40
|
return (
|
|
41
|
-
<ThreadListItemPrimitive.Root className="group flex h-9 items-center rounded-lg hover:bg-muted data-active:bg-muted">
|
|
42
|
-
<ThreadListItemPrimitive.Trigger className="flex-1 truncate px-3 text-sm">
|
|
41
|
+
<ThreadListItemPrimitive.Root className="group relative flex h-9 items-center rounded-lg hover:bg-muted data-active:bg-muted has-focus-visible:bg-muted">
|
|
42
|
+
<ThreadListItemPrimitive.Trigger className="min-w-0 flex-1 truncate px-3 text-sm outline-none">
|
|
43
43
|
<ThreadListItemPrimitive.Title fallback="New Chat" />
|
|
44
44
|
</ThreadListItemPrimitive.Trigger>
|
|
45
|
-
<ThreadListItemMorePrimitive.Root>
|
|
46
|
-
<ThreadListItemMorePrimitive.Trigger className="
|
|
45
|
+
<ThreadListItemMorePrimitive.Root sharedFocusGroup>
|
|
46
|
+
<ThreadListItemMorePrimitive.Trigger className="absolute end-1.5 top-1/2 size-7 -translate-y-1/2 rounded-md opacity-0 group-hover:opacity-100 group-has-focus-visible:opacity-100 data-[state=open]:opacity-100">
|
|
47
47
|
<MoreHorizontalIcon className="size-4" />
|
|
48
48
|
</ThreadListItemMorePrimitive.Trigger>
|
|
49
49
|
<ThreadListItemMorePrimitive.Content className="rounded-md border bg-popover p-1 shadow-md">
|
|
@@ -118,6 +118,21 @@ Both `ThreadListPrimitive.New` and `ThreadListItemPrimitive.Root` get a `data-ac
|
|
|
118
118
|
|
|
119
119
|
The `New` button gets `data-active` when the user is on a fresh, unsaved thread.
|
|
120
120
|
|
|
121
|
+
### Keyboard Navigation
|
|
122
|
+
|
|
123
|
+
Every item stays a native Tab stop, and arrow keys are layered on top. Up/Down move between items and Right focuses an item's `More` button (Left/Right are mirrored in RTL). This is built into the primitives — no prop is required.
|
|
124
|
+
|
|
125
|
+
To fold the `More` menu into the same navigation, opt it in with `sharedFocusGroup`:
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
<ThreadListItemMorePrimitive.Root sharedFocusGroup>
|
|
129
|
+
{/* Right opens the menu from the trigger; Left/Escape close it and
|
|
130
|
+
return focus to the trigger, keeping the highlight continuous. */}
|
|
131
|
+
</ThreadListItemMorePrimitive.Root>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`sharedFocusGroup` joins the menu to the list's focus group, so its trigger and the open menu act as one keyboard-navigable unit: Right opens it and Left/Escape close it, synchronously restoring focus to the trigger so a `group-has-focus-visible` highlight never flickers. Enabling it forces the menu non-modal, because a focus trap and a shared focus group are mutually exclusive — the trap keeps focus inside the menu, the shared group lets it move out across the boundary. Without `sharedFocusGroup` the menu keeps its standard Radix `DropdownMenu` keyboard behavior (modal by default), so menus you already render are unchanged. Our assistant-ui [thread-list](/docs/ui/thread-list) registry component sets `sharedFocusGroup` for you.
|
|
135
|
+
|
|
121
136
|
### Items Iterator
|
|
122
137
|
|
|
123
138
|
`ThreadListPrimitive.Items` now prefers a children render function, similar to `ThreadPrimitive.Messages`:
|
|
@@ -168,6 +183,15 @@ The canonical pattern composes `ThreadListItemPrimitive.Archive asChild` with `T
|
|
|
168
183
|
|
|
169
184
|
`Archive` provides the click handler and disabled logic. `Item` provides the menu item behavior and styling. `asChild` merges them into a single element.
|
|
170
185
|
|
|
186
|
+
## Accessibility
|
|
187
|
+
|
|
188
|
+
The thread list leans on native button semantics and Radix's `DropdownMenu`; the arrow-key navigation is layered on top as a convenience, not a requirement.
|
|
189
|
+
|
|
190
|
+
- Each `ThreadListItemPrimitive.Trigger` is a native `<button>` and its own Tab stop, so the whole list is reachable with <Kbd>Tab</Kbd> alone. The arrow keys (see [Keyboard Navigation](#keyboard-navigation)) speed traversal up, but nothing depends on them.
|
|
191
|
+
- The item representing the current thread sets `aria-current="true"` (alongside `data-active`) on `ThreadListItemPrimitive.Root`, so assistive tech announces which conversation is open.
|
|
192
|
+
- The `More` trigger exposes `aria-haspopup="menu"`, and its panel is a Radix `role="menu"` with `role="menuitem"` children, so screen readers announce it as a menu and the arrow keys cycle its items.
|
|
193
|
+
- With `sharedFocusGroup`, the `More` menu is non-modal and joins the list's focus group: opening and closing it move focus synchronously between the trigger and the menu, so keyboard focus is never dropped and the `group-has-focus-visible` highlight never flickers. Without it, the menu keeps Radix's default modal focus trap.
|
|
194
|
+
|
|
171
195
|
## Parts
|
|
172
196
|
|
|
173
197
|
### ThreadListPrimitive
|
|
@@ -319,10 +343,10 @@ Button that deletes the current thread item. Renders a `<button>` element unless
|
|
|
319
343
|
|
|
320
344
|
#### Root
|
|
321
345
|
|
|
322
|
-
Root container for the overflow menu primitives.
|
|
346
|
+
Root container for the overflow menu primitives. Pass `sharedFocusGroup` to fold the menu into the list's arrow-key navigation (see [Keyboard Navigation](#keyboard-navigation)); doing so forces it non-modal. Without it the menu honors the `modal` prop, defaulting to modal like Radix's `DropdownMenu`.
|
|
323
347
|
|
|
324
348
|
```tsx
|
|
325
|
-
<ThreadListItemMorePrimitive.Root>
|
|
349
|
+
<ThreadListItemMorePrimitive.Root sharedFocusGroup>
|
|
326
350
|
<ThreadListItemMorePrimitive.Trigger>More</ThreadListItemMorePrimitive.Trigger>
|
|
327
351
|
</ThreadListItemMorePrimitive.Root>
|
|
328
352
|
```
|
|
@@ -319,6 +319,30 @@ Renders a single message at a specific index in the thread.
|
|
|
319
319
|
|
|
320
320
|
<PrimitivesTypeTable type="ThreadPrimitiveMessageByIndexProps" parameters={ThreadPrimitiveDocs.MessageByIndex.props} />
|
|
321
321
|
|
|
322
|
+
### Unstable_MessageById
|
|
323
|
+
|
|
324
|
+
Renders a single message by id with the same `components` surface as
|
|
325
|
+
`MessageByIndex`. Pair it with `unstable_useThreadMessageIds` for virtualized or
|
|
326
|
+
custom message lists that should stay attached to messages across reordering and
|
|
327
|
+
windowing. Unknown ids render `null`.
|
|
328
|
+
|
|
329
|
+
```tsx
|
|
330
|
+
const messageIds = unstable_useThreadMessageIds();
|
|
331
|
+
|
|
332
|
+
messageIds.map((messageId) => (
|
|
333
|
+
<ThreadPrimitive.Unstable_MessageById
|
|
334
|
+
key={messageId}
|
|
335
|
+
messageId={messageId}
|
|
336
|
+
components={{ Message: MyMessage }}
|
|
337
|
+
/>
|
|
338
|
+
));
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
<Callout type="warn">
|
|
342
|
+
`unstable_useThreadMessageIds` and `ThreadPrimitive.Unstable_MessageById` are
|
|
343
|
+
experimental and may change in any release.
|
|
344
|
+
</Callout>
|
|
345
|
+
|
|
322
346
|
### ScrollToBottom
|
|
323
347
|
|
|
324
348
|
Scrolls the viewport to the bottom. Automatically disabled when already at the bottom. Renders a `<button>` element unless `asChild` is set.
|
|
@@ -3,7 +3,7 @@ title: Quickstart
|
|
|
3
3
|
description: Minimal runtime and Thread setup against an A2A server.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Three steps to a working chat against an A2A server. Assumes you have already installed the package and have an A2A v1.0 server reachable; if not, start at [overview](/docs/runtimes/a2a).
|
|
6
|
+
Three steps to a working chat against an A2A server. Assumes you have already installed the package and have an A2A v1.0 server reachable; if not, start at [overview](/docs/runtimes/a2a/overview).
|
|
7
7
|
|
|
8
8
|
<Steps>
|
|
9
9
|
<Step>
|
|
@@ -3,7 +3,7 @@ title: Quickstart
|
|
|
3
3
|
description: Minimal HttpAgent + useAgUiRuntime setup against an AG-UI server.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Three steps to a working chat against an AG-UI agent. Assumes you have already installed the package and have an AG-UI server reachable; if not, start at [overview](/docs/runtimes/ag-ui).
|
|
6
|
+
Three steps to a working chat against an AG-UI agent. Assumes you have already installed the package and have an AG-UI server reachable; if not, start at [overview](/docs/runtimes/ag-ui/overview).
|
|
7
7
|
|
|
8
8
|
<Steps>
|
|
9
9
|
<Step>
|