@assistant-ui/mcp-docs-server 0.1.25 → 0.1.27

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.
Files changed (62) hide show
  1. package/.docs/organized/code-examples/waterfall.md +4 -4
  2. package/.docs/organized/code-examples/with-a2a.md +5 -5
  3. package/.docs/organized/code-examples/with-ag-ui.md +6 -6
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +7 -7
  5. package/.docs/organized/code-examples/with-artifacts.md +7 -7
  6. package/.docs/organized/code-examples/with-assistant-transport.md +5 -5
  7. package/.docs/organized/code-examples/with-chain-of-thought.md +7 -7
  8. package/.docs/organized/code-examples/with-cloud-standalone.md +8 -8
  9. package/.docs/organized/code-examples/with-cloud.md +7 -7
  10. package/.docs/organized/code-examples/with-custom-thread-list.md +7 -7
  11. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +511 -0
  12. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +10 -10
  13. package/.docs/organized/code-examples/with-expo.md +18 -18
  14. package/.docs/organized/code-examples/with-external-store.md +5 -5
  15. package/.docs/organized/code-examples/with-ffmpeg.md +220 -66
  16. package/.docs/organized/code-examples/with-google-adk.md +6 -6
  17. package/.docs/organized/code-examples/with-heat-graph.md +4 -4
  18. package/.docs/organized/code-examples/with-interactables.md +836 -0
  19. package/.docs/organized/code-examples/with-langgraph.md +6 -6
  20. package/.docs/organized/code-examples/with-livekit.md +591 -0
  21. package/.docs/organized/code-examples/with-parent-id-grouping.md +6 -6
  22. package/.docs/organized/code-examples/with-react-hook-form.md +8 -8
  23. package/.docs/organized/code-examples/with-react-ink.md +3 -3
  24. package/.docs/organized/code-examples/with-react-router.md +11 -11
  25. package/.docs/organized/code-examples/with-store.md +11 -6
  26. package/.docs/organized/code-examples/with-tanstack.md +8 -8
  27. package/.docs/organized/code-examples/with-tap-runtime.md +8 -8
  28. package/.docs/raw/blog/2026-03-launch-week/index.mdx +31 -0
  29. package/.docs/raw/docs/(docs)/cli.mdx +60 -0
  30. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +9 -1
  31. package/.docs/raw/docs/(docs)/guides/attachments.mdx +65 -4
  32. package/.docs/raw/docs/(docs)/guides/interactables.mdx +354 -0
  33. package/.docs/raw/docs/(docs)/guides/message-timing.mdx +3 -3
  34. package/.docs/raw/docs/(docs)/guides/multi-agent.mdx +1 -0
  35. package/.docs/raw/docs/(docs)/guides/tool-ui.mdx +29 -0
  36. package/.docs/raw/docs/(docs)/guides/voice.mdx +333 -0
  37. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +128 -0
  38. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +23 -0
  39. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +6 -0
  40. package/.docs/raw/docs/cloud/ai-sdk.mdx +81 -1
  41. package/.docs/raw/docs/ink/primitives.mdx +141 -0
  42. package/.docs/raw/docs/primitives/action-bar.mdx +351 -0
  43. package/.docs/raw/docs/primitives/assistant-modal.mdx +215 -0
  44. package/.docs/raw/docs/primitives/attachment.mdx +216 -0
  45. package/.docs/raw/docs/primitives/branch-picker.mdx +221 -0
  46. package/.docs/raw/docs/primitives/chain-of-thought.mdx +311 -0
  47. package/.docs/raw/docs/primitives/composer.mdx +526 -0
  48. package/.docs/raw/docs/primitives/error.mdx +141 -0
  49. package/.docs/raw/docs/primitives/index.mdx +98 -0
  50. package/.docs/raw/docs/primitives/message.mdx +524 -0
  51. package/.docs/raw/docs/primitives/selection-toolbar.mdx +165 -0
  52. package/.docs/raw/docs/primitives/suggestion.mdx +242 -0
  53. package/.docs/raw/docs/primitives/thread-list.mdx +404 -0
  54. package/.docs/raw/docs/primitives/thread.mdx +482 -0
  55. package/.docs/raw/docs/runtimes/a2a/index.mdx +4 -0
  56. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +2 -2
  57. package/.docs/raw/docs/runtimes/assistant-transport.mdx +6 -2
  58. package/.docs/raw/docs/ui/context-display.mdx +2 -2
  59. package/.docs/raw/docs/ui/mention.mdx +168 -0
  60. package/.docs/raw/docs/ui/model-selector.mdx +1 -1
  61. package/.docs/raw/docs/ui/voice.mdx +172 -0
  62. package/package.json +3 -4
@@ -0,0 +1,215 @@
1
+ ---
2
+ title: AssistantModal
3
+ description: A floating chat popover with a fixed-position trigger button that opens a chat panel.
4
+ ---
5
+
6
+ import { AssistantModalSample } from "@/components/docs/samples/assistant-modal";
7
+ import { AssistantModalPrimitive as AssistantModalPrimitiveDocs } from "@/generated/primitiveDocs";
8
+
9
+ 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.
10
+
11
+ <Tabs items={["Preview", "Code"]}>
12
+ <Tab>
13
+ <AssistantModalSample />
14
+ </Tab>
15
+ <Tab>
16
+ ```tsx
17
+ import { AssistantModalPrimitive } from "@assistant-ui/react";
18
+
19
+ function MinimalAssistantModal() {
20
+ return (
21
+ <AssistantModalPrimitive.Root>
22
+ <AssistantModalPrimitive.Anchor>
23
+ <AssistantModalPrimitive.Trigger>
24
+ Open Chat
25
+ </AssistantModalPrimitive.Trigger>
26
+ </AssistantModalPrimitive.Anchor>
27
+ <AssistantModalPrimitive.Content>
28
+ {/* Your Thread goes here */}
29
+ </AssistantModalPrimitive.Content>
30
+ </AssistantModalPrimitive.Root>
31
+ );
32
+ }
33
+ ```
34
+ </Tab>
35
+ </Tabs>
36
+
37
+ ## Quick Start
38
+
39
+ Minimal example:
40
+
41
+ ```tsx
42
+ import { AssistantModalPrimitive } from "@assistant-ui/react";
43
+
44
+ <AssistantModalPrimitive.Root>
45
+ <AssistantModalPrimitive.Anchor>
46
+ <AssistantModalPrimitive.Trigger>Open</AssistantModalPrimitive.Trigger>
47
+ </AssistantModalPrimitive.Anchor>
48
+ <AssistantModalPrimitive.Content>
49
+ <Thread />
50
+ </AssistantModalPrimitive.Content>
51
+ </AssistantModalPrimitive.Root>
52
+ ```
53
+
54
+ `Root` is a Radix Popover provider (no DOM), `Trigger` renders a `<button>`, `Anchor` renders a `<div>`, and `Content` renders a `<div>` inside a portal. Add your own classes, animations, and layout.
55
+
56
+ <Callout type="info">
57
+ Runtime setup: primitives require runtime context. Wrap your UI in `AssistantRuntimeProvider` with a runtime (for example `useLocalRuntime(...)`). See [Pick a Runtime](/docs/runtimes/pick-a-runtime).
58
+ </Callout>
59
+
60
+ ## Core Concepts
61
+
62
+ ### Popover Architecture
63
+
64
+ AssistantModal is built directly on Radix Popover. `Root` manages open/close state, `Trigger` toggles it, `Anchor` positions the popover, and `Content` is the floating panel. All Radix Popover props are available on the corresponding parts.
65
+
66
+ ### Anchor vs Trigger
67
+
68
+ `Content` positions itself relative to `Anchor`, not `Trigger`. The common pattern is wrapping `Trigger` inside `Anchor` so the popover aligns to a larger area (like a fixed-position button container) rather than the button itself:
69
+
70
+ ```tsx
71
+ <AssistantModalPrimitive.Anchor className="fixed right-4 bottom-4 size-11">
72
+ <AssistantModalPrimitive.Trigger>
73
+ Open
74
+ </AssistantModalPrimitive.Trigger>
75
+ </AssistantModalPrimitive.Anchor>
76
+ ```
77
+
78
+ ### Auto-Open on Run Start
79
+
80
+ The `unstable_openOnRunStart` prop (default `true`) automatically opens the modal when the assistant starts responding. This means if a user triggers a run programmatically while the modal is closed, it pops open to show the response. Set to `false` to disable.
81
+
82
+ ### Dismiss Behavior
83
+
84
+ `Content` uses `dissmissOnInteractOutside` *(intentional current API spelling, with the extra `s`)* and defaults it to `false`. Clicking outside the modal does **not** close it. This matches expected chat UX where users interact with the page while keeping the chat open. Set it to `true` for standard popover dismiss behavior.
85
+
86
+ ### Open/Close Animations
87
+
88
+ `Content` exposes `data-[state=open]` and `data-[state=closed]` attributes for CSS animations:
89
+
90
+ ```tsx
91
+ <AssistantModalPrimitive.Content
92
+ className="data-[state=open]:animate-in data-[state=open]:fade-in data-[state=closed]:animate-out data-[state=closed]:fade-out"
93
+ >
94
+ ```
95
+
96
+ ## Parts
97
+
98
+ ### Root
99
+
100
+ Radix Popover provider, manages open/close state. No DOM element rendered.
101
+
102
+ ```tsx
103
+ <AssistantModalPrimitive.Root unstable_openOnRunStart={false}>
104
+ ...
105
+ </AssistantModalPrimitive.Root>
106
+ ```
107
+
108
+ <PrimitivesTypeTable type="AssistantModalPrimitiveRootProps" parameters={AssistantModalPrimitiveDocs.Root.props} />
109
+
110
+ ### Trigger
111
+
112
+ Button that toggles the modal open and closed. Renders a `<button>` element unless `asChild` is set.
113
+
114
+ ```tsx
115
+ <AssistantModalPrimitive.Trigger className="rounded-full bg-primary px-4 py-2 text-primary-foreground">
116
+ Open Chat
117
+ </AssistantModalPrimitive.Trigger>
118
+ ```
119
+
120
+ ### Anchor
121
+
122
+ Positions the trigger and content relative to a shared anchor. Renders a `<div>` element unless `asChild` is set.
123
+
124
+ ```tsx
125
+ <AssistantModalPrimitive.Anchor className="fixed right-4 bottom-4">
126
+ <AssistantModalPrimitive.Trigger>Chat</AssistantModalPrimitive.Trigger>
127
+ </AssistantModalPrimitive.Anchor>
128
+ ```
129
+
130
+ ### Content
131
+
132
+ The floating chat panel. Renders a `<div>` element inside a portal.
133
+
134
+ ```tsx
135
+ <AssistantModalPrimitive.Content
136
+ sideOffset={16}
137
+ className="h-[600px] w-[400px] rounded-xl border bg-background shadow-lg"
138
+ >
139
+ <Thread />
140
+ </AssistantModalPrimitive.Content>
141
+ ```
142
+
143
+ <PrimitivesTypeTable type="AssistantModalPrimitiveContentProps" parameters={AssistantModalPrimitiveDocs.Content.props} />
144
+
145
+ ## Patterns
146
+
147
+ ### Floating Bottom-Right Widget
148
+
149
+ ```tsx
150
+ <AssistantModalPrimitive.Root>
151
+ <AssistantModalPrimitive.Anchor className="fixed right-4 bottom-4 size-11">
152
+ <AssistantModalPrimitive.Trigger className="size-full rounded-full bg-primary text-primary-foreground shadow-lg">
153
+ <BotIcon className="size-6" />
154
+ </AssistantModalPrimitive.Trigger>
155
+ </AssistantModalPrimitive.Anchor>
156
+ <AssistantModalPrimitive.Content
157
+ sideOffset={16}
158
+ className="h-[600px] w-[400px] rounded-xl border bg-background shadow-lg"
159
+ >
160
+ <Thread />
161
+ </AssistantModalPrimitive.Content>
162
+ </AssistantModalPrimitive.Root>
163
+ ```
164
+
165
+ ### Trigger Icon Swap
166
+
167
+ The `Trigger` button receives a `data-state` attribute from Radix (`"open"` or `"closed"`). To pass that state down to child icons, use `asChild` with a wrapper component that destructures and forwards it:
168
+
169
+ ```tsx
170
+ import { forwardRef } from "react";
171
+
172
+ const ModalButton = forwardRef<
173
+ HTMLButtonElement,
174
+ React.ComponentPropsWithoutRef<"button"> & { "data-state"?: string }
175
+ >(({ "data-state": state, ...props }, ref) => (
176
+ <button ref={ref} {...props} className="relative size-11 rounded-full">
177
+ <BotIcon
178
+ data-state={state}
179
+ className="absolute size-6 transition-all data-[state=open]:rotate-90 data-[state=open]:scale-0"
180
+ />
181
+ <XIcon
182
+ data-state={state}
183
+ className="absolute size-6 transition-all data-[state=closed]:-rotate-90 data-[state=closed]:scale-0"
184
+ />
185
+ </button>
186
+ ));
187
+
188
+ <AssistantModalPrimitive.Trigger asChild>
189
+ <ModalButton />
190
+ </AssistantModalPrimitive.Trigger>
191
+ ```
192
+
193
+ ### Custom Portal Container
194
+
195
+ Render the content inside a specific container instead of `document.body`:
196
+
197
+ ```tsx
198
+ <AssistantModalPrimitive.Content
199
+ portalProps={{ container: myContainerRef.current }}
200
+ >
201
+ <Thread />
202
+ </AssistantModalPrimitive.Content>
203
+ ```
204
+
205
+ ## Relationship to Components
206
+
207
+ The shadcn [AssistantModal](/docs/ui/assistant-modal) component wraps these primitives with slide/fade animations, icon transitions between open and closed states, and responsive sizing. Start there for a prebuilt floating chat widget.
208
+
209
+ ## API Reference
210
+
211
+ For full prop details on every part, see the [AssistantModalPrimitive API Reference](/docs/api-reference/primitives/assistant-modal).
212
+
213
+ Related:
214
+ - [ThreadPrimitive](/docs/primitives/thread)
215
+ - [ComposerPrimitive](/docs/primitives/composer)
@@ -0,0 +1,216 @@
1
+ ---
2
+ title: Attachment
3
+ description: File and image attachment rendering for the composer and messages.
4
+ ---
5
+
6
+ import { AttachmentSample } from "@/components/docs/samples/attachment";
7
+
8
+ 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.
9
+
10
+ <Tabs items={["Preview", "Code"]}>
11
+ <Tab>
12
+ <AttachmentSample />
13
+ </Tab>
14
+ <Tab>
15
+ ```tsx
16
+ import {
17
+ AttachmentPrimitive,
18
+ ComposerPrimitive,
19
+ } from "@assistant-ui/react";
20
+ import { XIcon } from "lucide-react";
21
+
22
+ function ComposerAttachment() {
23
+ return (
24
+ <AttachmentPrimitive.Root className="flex items-center gap-2 rounded-lg border p-2">
25
+ <AttachmentPrimitive.unstable_Thumb className="flex size-10 items-center justify-center rounded bg-muted text-xs" />
26
+ <span className="text-sm">
27
+ <AttachmentPrimitive.Name />
28
+ </span>
29
+ <AttachmentPrimitive.Remove className="ml-auto rounded-full p-1 hover:bg-muted">
30
+ <XIcon className="size-3" />
31
+ </AttachmentPrimitive.Remove>
32
+ </AttachmentPrimitive.Root>
33
+ );
34
+ }
35
+ ```
36
+ </Tab>
37
+ </Tabs>
38
+
39
+ ## Quick Start
40
+
41
+ An attachment inside a composer:
42
+
43
+ ```tsx
44
+ import { AttachmentPrimitive, ComposerPrimitive } from "@assistant-ui/react";
45
+
46
+ <ComposerPrimitive.Root>
47
+ <ComposerPrimitive.Attachments>
48
+ {() => <MyAttachment />}
49
+ </ComposerPrimitive.Attachments>
50
+ <ComposerPrimitive.Input placeholder="Ask anything..." />
51
+ <ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
52
+ </ComposerPrimitive.Root>
53
+ ```
54
+
55
+ `Root` renders a `<div>`, `unstable_Thumb` renders a `<div>` showing the file extension with a leading dot (e.g., `.pdf`), `Name` renders plain text, and `Remove` renders a `<button>`.
56
+
57
+ <Callout type="info">
58
+ Runtime setup: primitives require runtime context. Wrap your UI in `AssistantRuntimeProvider` with a runtime (for example `useLocalRuntime(...)`). See [Pick a Runtime](/docs/runtimes/pick-a-runtime).
59
+ </Callout>
60
+
61
+ ## Core Concepts
62
+
63
+ ### Two Contexts
64
+
65
+ Attachments appear in two different contexts:
66
+
67
+ - **Composer**: via `ComposerPrimitive.Attachments`. These are pending uploads that can be removed before sending.
68
+ - **Messages**: via `MessagePrimitive.Attachments`. These are sent attachments, displayed read-only (the iterator renders attachments for user messages).
69
+
70
+ The same `AttachmentPrimitive` parts work in both contexts. The difference is behavioral: `Remove` only works in the composer context.
71
+
72
+ ### Iterator Pattern
73
+
74
+ You don't loop over attachments yourself. Instead, use the children render function:
75
+
76
+ ```tsx
77
+ // Composer attachments
78
+ <ComposerPrimitive.Attachments>
79
+ {({ attachment }) => {
80
+ if (attachment.type === "image") return <ImageAttachment />;
81
+ if (attachment.type === "document") return <DocumentAttachment />;
82
+ return <GenericAttachment />;
83
+ }}
84
+ </ComposerPrimitive.Attachments>
85
+
86
+ // Message attachments
87
+ <MessagePrimitive.Attachments>
88
+ {({ attachment }) => {
89
+ if (attachment.type === "image") return <ImageAttachment />;
90
+ if (attachment.type === "document") return <DocumentAttachment />;
91
+ return <GenericAttachment />;
92
+ }}
93
+ </MessagePrimitive.Attachments>
94
+ ```
95
+
96
+ Each component receives its attachment context automatically, with no props to pass. `components` is deprecated — use the `children` render function instead.
97
+
98
+ ### Remove Button
99
+
100
+ `Remove` calls the attachment runtime remove action. In composer attachments it removes the attachment from the pending message. In message attachments, this action is not supported and clicking `Remove` will throw `"Message attachments cannot be removed"`. Only render `Remove` in composer UIs.
101
+
102
+ ### Name as Text
103
+
104
+ `Name` renders plain text with no wrapper element. Wrap it in a `<span>` or other element for styling:
105
+
106
+ ```tsx
107
+ <span className="text-sm font-medium">
108
+ <AttachmentPrimitive.Name />
109
+ </span>
110
+ ```
111
+
112
+ ## Parts
113
+
114
+ ### Root
115
+
116
+ Container for a single attachment item. Renders a `<div>` element unless `asChild` is set.
117
+
118
+ ```tsx
119
+ <AttachmentPrimitive.Root className="flex items-center gap-2 rounded-lg border p-2">
120
+ <AttachmentPrimitive.Name />
121
+ </AttachmentPrimitive.Root>
122
+ ```
123
+
124
+ ### unstable_Thumb
125
+
126
+ Thumbnail slot for attachment previews. Renders a `<div>` element unless `asChild` is set.
127
+
128
+ ```tsx
129
+ <AttachmentPrimitive.unstable_Thumb className="flex size-10 items-center justify-center rounded bg-muted text-xs" />
130
+ ```
131
+
132
+ ### Name
133
+
134
+ Renders the attachment filename text.
135
+
136
+ ```tsx
137
+ <AttachmentPrimitive.Name />
138
+ ```
139
+
140
+ ### Remove
141
+
142
+ Button that removes the current attachment when used in a removable attachment context. Renders a `<button>` element unless `asChild` is set.
143
+
144
+ ```tsx
145
+ <AttachmentPrimitive.Remove className="rounded-full p-1 hover:bg-muted">
146
+ <XIcon className="size-3" />
147
+ </AttachmentPrimitive.Remove>
148
+ ```
149
+
150
+ ## Patterns
151
+
152
+ ### Composer Attachment with Remove
153
+
154
+ ```tsx
155
+ function ComposerAttachmentItem() {
156
+ return (
157
+ <AttachmentPrimitive.Root className="flex items-center gap-2 rounded-lg border p-2">
158
+ <AttachmentPrimitive.unstable_Thumb className="flex size-10 items-center justify-center rounded bg-muted text-xs font-mono" />
159
+ <span className="min-w-0 flex-1 truncate text-sm">
160
+ <AttachmentPrimitive.Name />
161
+ </span>
162
+ <AttachmentPrimitive.Remove className="rounded-full p-1 hover:bg-muted">
163
+ <XIcon className="size-3" />
164
+ </AttachmentPrimitive.Remove>
165
+ </AttachmentPrimitive.Root>
166
+ );
167
+ }
168
+
169
+ <ComposerPrimitive.Root>
170
+ <ComposerPrimitive.Attachments
171
+ components={{ Attachment: ComposerAttachmentItem }}
172
+ />
173
+ <ComposerPrimitive.Input placeholder="Ask anything..." />
174
+ <ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
175
+ </ComposerPrimitive.Root>
176
+ ```
177
+
178
+ ### Message Attachment (Read-Only)
179
+
180
+ ```tsx
181
+ function MessageAttachment() {
182
+ return (
183
+ <AttachmentPrimitive.Root className="flex items-center gap-2 rounded-lg border p-2">
184
+ <AttachmentPrimitive.unstable_Thumb className="flex size-10 items-center justify-center rounded bg-muted text-xs font-mono" />
185
+ <span className="text-sm">
186
+ <AttachmentPrimitive.Name />
187
+ </span>
188
+ </AttachmentPrimitive.Root>
189
+ );
190
+ }
191
+ ```
192
+
193
+ ### Custom Layout with asChild
194
+
195
+ ```tsx
196
+ <AttachmentPrimitive.Root asChild>
197
+ <li className="flex items-center gap-3 py-1">
198
+ <AttachmentPrimitive.unstable_Thumb className="size-8 rounded bg-muted text-xs" />
199
+ <span className="text-sm">
200
+ <AttachmentPrimitive.Name />
201
+ </span>
202
+ </li>
203
+ </AttachmentPrimitive.Root>
204
+ ```
205
+
206
+ ## Relationship to Components
207
+
208
+ The shadcn [Attachment](/docs/ui/attachment) component wraps these primitives with styled thumbnails, tooltip filenames, remove buttons, and image preview dialogs. Start there for a prebuilt attachment UI.
209
+
210
+ ## API Reference
211
+
212
+ For full prop details on every part, see the [AttachmentPrimitive API Reference](/docs/api-reference/primitives/attachment).
213
+
214
+ Related:
215
+ - [ComposerPrimitive API Reference](/docs/api-reference/primitives/composer)
216
+ - [MessagePrimitive API Reference](/docs/api-reference/primitives/message)
@@ -0,0 +1,221 @@
1
+ ---
2
+ title: BranchPicker
3
+ description: Navigate between message branches, which are alternative responses the user can flip through.
4
+ ---
5
+
6
+ import { BranchPickerPrimitiveSample } from "@/components/docs/samples/branch-picker-primitive";
7
+ import { BranchPickerPrimitive as BranchPickerPrimitiveDocs } from "@/generated/primitiveDocs";
8
+
9
+ 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.
10
+
11
+ <Tabs items={["Preview", "Code"]}>
12
+ <Tab>
13
+ <BranchPickerPrimitiveSample />
14
+ </Tab>
15
+ <Tab>
16
+ ```tsx
17
+ import {
18
+ BranchPickerPrimitive,
19
+ MessagePrimitive,
20
+ } from "@assistant-ui/react";
21
+ import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
22
+
23
+ function AssistantMessage() {
24
+ return (
25
+ <MessagePrimitive.Root className="flex flex-col items-start gap-1">
26
+ <div className="rounded-2xl bg-muted px-4 py-2.5 text-sm">
27
+ <MessagePrimitive.Parts />
28
+ </div>
29
+ <BranchPickerPrimitive.Root className="inline-flex items-center gap-0.5 text-xs">
30
+ <BranchPickerPrimitive.Previous className="flex size-6 items-center justify-center rounded-md disabled:opacity-30">
31
+ <ChevronLeftIcon className="size-3.5" />
32
+ </BranchPickerPrimitive.Previous>
33
+ <span>
34
+ <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
35
+ </span>
36
+ <BranchPickerPrimitive.Next className="flex size-6 items-center justify-center rounded-md disabled:opacity-30">
37
+ <ChevronRightIcon className="size-3.5" />
38
+ </BranchPickerPrimitive.Next>
39
+ </BranchPickerPrimitive.Root>
40
+ </MessagePrimitive.Root>
41
+ );
42
+ }
43
+ ```
44
+ </Tab>
45
+ </Tabs>
46
+
47
+ ## Quick Start
48
+
49
+ Minimal example:
50
+
51
+ ```tsx
52
+ import { BranchPickerPrimitive } from "@assistant-ui/react";
53
+
54
+ <BranchPickerPrimitive.Root>
55
+ <BranchPickerPrimitive.Previous>←</BranchPickerPrimitive.Previous>
56
+ <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
57
+ <BranchPickerPrimitive.Next>→</BranchPickerPrimitive.Next>
58
+ </BranchPickerPrimitive.Root>
59
+ ```
60
+
61
+ `Root` renders a `<div>`, `Previous` and `Next` render `<button>` elements that auto-disable at boundaries. `Number` and `Count` render plain text (the current branch index and total count).
62
+
63
+ <Callout type="info">
64
+ BranchPicker must be placed inside a `MessagePrimitive.Root` because it reads branch state from the nearest message context.
65
+ </Callout>
66
+
67
+ <Callout type="info">
68
+ Runtime setup: primitives require runtime context. Wrap your UI in `AssistantRuntimeProvider` with a runtime (for example `useLocalRuntime(...)`). See [Pick a Runtime](/docs/runtimes/pick-a-runtime).
69
+ </Callout>
70
+
71
+ ## Core Concepts
72
+
73
+ ### Branch Navigation
74
+
75
+ `Previous` and `Next` buttons automatically disable at boundaries. `Previous` is disabled on the first branch, and `Next` is disabled on the last. Both also disable while the thread is running if the runtime doesn't support `switchBranchDuringRun`.
76
+
77
+ ### Number & Count
78
+
79
+ `Number` and `Count` are text-only primitives that render raw numbers with no wrapping element. Use a `<span>` if you need to style them:
80
+
81
+ ```tsx
82
+ <span className="tabular-nums">
83
+ <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
84
+ </span>
85
+ ```
86
+
87
+ ### hideWhenSingleBranch
88
+
89
+ The `hideWhenSingleBranch` prop on `Root` hides the entire picker when there's only one branch. This is a common production pattern to reduce visual clutter:
90
+
91
+ ```tsx
92
+ <BranchPickerPrimitive.Root hideWhenSingleBranch>
93
+ <BranchPickerPrimitive.Previous>←</BranchPickerPrimitive.Previous>
94
+ <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
95
+ <BranchPickerPrimitive.Next>→</BranchPickerPrimitive.Next>
96
+ </BranchPickerPrimitive.Root>
97
+ ```
98
+
99
+ ### Context Requirement
100
+
101
+ BranchPicker reads branch state from the nearest message context. It must be placed inside a `MessagePrimitive.Root`, either directly or nested inside your message component.
102
+
103
+ ## Parts
104
+
105
+ ### Root
106
+
107
+ Container with optional `hideWhenSingleBranch`. Renders a `<div>` element unless `asChild` is set.
108
+
109
+ ```tsx
110
+ <BranchPickerPrimitive.Root hideWhenSingleBranch className="inline-flex items-center gap-1">
111
+ <BranchPickerPrimitive.Previous>←</BranchPickerPrimitive.Previous>
112
+ <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
113
+ <BranchPickerPrimitive.Next>→</BranchPickerPrimitive.Next>
114
+ </BranchPickerPrimitive.Root>
115
+ ```
116
+
117
+ <PrimitivesTypeTable type="BranchPickerPrimitiveRootProps" parameters={BranchPickerPrimitiveDocs.Root.props.filter(p => p.name !== "asChild")} />
118
+
119
+ ### Previous
120
+
121
+ Button that selects the previous branch. Renders a `<button>` element unless `asChild` is set.
122
+
123
+ ```tsx
124
+ <BranchPickerPrimitive.Previous>Previous</BranchPickerPrimitive.Previous>
125
+ ```
126
+
127
+ ### Next
128
+
129
+ Button that selects the next branch. Renders a `<button>` element unless `asChild` is set.
130
+
131
+ ```tsx
132
+ <BranchPickerPrimitive.Next>Next</BranchPickerPrimitive.Next>
133
+ ```
134
+
135
+ ### Number
136
+
137
+ Displays the current branch number.
138
+
139
+ ```tsx
140
+ <BranchPickerPrimitive.Number />
141
+ ```
142
+
143
+ ### Count
144
+
145
+ Displays the total number of branches for the current message.
146
+
147
+ ```tsx
148
+ <BranchPickerPrimitive.Count />
149
+ ```
150
+
151
+ ## Patterns
152
+
153
+ ### Standard Picker with Icons
154
+
155
+ ```tsx
156
+ import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
157
+
158
+ <BranchPickerPrimitive.Root
159
+ hideWhenSingleBranch
160
+ className="inline-flex items-center gap-1 text-xs text-muted-foreground"
161
+ >
162
+ <BranchPickerPrimitive.Previous className="size-6 rounded-md hover:bg-muted disabled:opacity-30">
163
+ <ChevronLeftIcon className="size-3.5" />
164
+ </BranchPickerPrimitive.Previous>
165
+ <span className="tabular-nums">
166
+ <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
167
+ </span>
168
+ <BranchPickerPrimitive.Next className="size-6 rounded-md hover:bg-muted disabled:opacity-30">
169
+ <ChevronRightIcon className="size-3.5" />
170
+ </BranchPickerPrimitive.Next>
171
+ </BranchPickerPrimitive.Root>
172
+ ```
173
+
174
+ ### Custom Elements with asChild
175
+
176
+ ```tsx
177
+ <BranchPickerPrimitive.Previous asChild>
178
+ <MyIconButton tooltip="Previous branch">
179
+ <ChevronLeftIcon />
180
+ </MyIconButton>
181
+ </BranchPickerPrimitive.Previous>
182
+ ```
183
+
184
+ The primitive's disabled state and click handler merge onto your element.
185
+
186
+ ### Inside a Message Footer
187
+
188
+ The most common pattern places the BranchPicker alongside an ActionBar in a message footer:
189
+
190
+ ```tsx
191
+ function AssistantMessage() {
192
+ return (
193
+ <MessagePrimitive.Root>
194
+ <div className="rounded-xl bg-muted p-3">
195
+ <MessagePrimitive.Parts />
196
+ </div>
197
+ <div className="flex items-center justify-between">
198
+ <BranchPickerPrimitive.Root hideWhenSingleBranch>
199
+ {/* prev / number / count / next */}
200
+ </BranchPickerPrimitive.Root>
201
+ <ActionBarPrimitive.Root>
202
+ <ActionBarPrimitive.Copy>Copy</ActionBarPrimitive.Copy>
203
+ <ActionBarPrimitive.Reload>Reload</ActionBarPrimitive.Reload>
204
+ </ActionBarPrimitive.Root>
205
+ </div>
206
+ </MessagePrimitive.Root>
207
+ );
208
+ }
209
+ ```
210
+
211
+ ## Relationship to Components
212
+
213
+ The shadcn [Thread](/docs/ui/thread) component includes a BranchPicker in both AssistantMessage and UserMessage footers, with `hideWhenSingleBranch` enabled. If the default layout works, use the component. Reach for `BranchPickerPrimitive` directly when you need a custom position, different styling, or a non-standard branch navigation experience.
214
+
215
+ ## API Reference
216
+
217
+ For full prop details on every part, see the [BranchPickerPrimitive API Reference](/docs/api-reference/primitives/branch-picker).
218
+
219
+ Related:
220
+ - [ActionBarPrimitive API Reference](/docs/api-reference/primitives/action-bar)
221
+ - [MessagePrimitive API Reference](/docs/api-reference/primitives/message)