@assistant-ui/mcp-docs-server 0.1.24 → 0.1.26

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 (151) hide show
  1. package/.docs/organized/code-examples/waterfall.md +8 -6
  2. package/.docs/organized/code-examples/with-a2a.md +676 -0
  3. package/.docs/organized/code-examples/with-ag-ui.md +10 -11
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +31 -19
  5. package/.docs/organized/code-examples/with-artifacts.md +8 -8
  6. package/.docs/organized/code-examples/with-assistant-transport.md +6 -6
  7. package/.docs/organized/code-examples/with-chain-of-thought.md +37 -29
  8. package/.docs/organized/code-examples/with-cloud-standalone.md +14 -11
  9. package/.docs/organized/code-examples/with-cloud.md +8 -8
  10. package/.docs/organized/code-examples/with-custom-thread-list.md +10 -10
  11. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +11 -11
  12. package/.docs/organized/code-examples/with-expo.md +571 -520
  13. package/.docs/organized/code-examples/with-external-store.md +6 -6
  14. package/.docs/organized/code-examples/with-ffmpeg.md +8 -8
  15. package/.docs/organized/code-examples/with-google-adk.md +353 -0
  16. package/.docs/organized/code-examples/with-heat-graph.md +304 -0
  17. package/.docs/organized/code-examples/with-interactables.md +778 -0
  18. package/.docs/organized/code-examples/with-langgraph.md +28 -26
  19. package/.docs/organized/code-examples/with-parent-id-grouping.md +7 -7
  20. package/.docs/organized/code-examples/with-react-hook-form.md +9 -9
  21. package/.docs/organized/code-examples/with-react-ink.md +265 -0
  22. package/.docs/organized/code-examples/with-react-router.md +12 -12
  23. package/.docs/organized/code-examples/with-store.md +33 -22
  24. package/.docs/organized/code-examples/with-tanstack.md +10 -10
  25. package/.docs/organized/code-examples/with-tap-runtime.md +12 -10
  26. package/.docs/raw/blog/2025-01-31-changelog/index.mdx +1 -1
  27. package/.docs/raw/blog/2026-03-launch-week/index.mdx +258 -0
  28. package/.docs/raw/docs/(docs)/architecture.mdx +1 -1
  29. package/.docs/raw/docs/(docs)/cli.mdx +74 -9
  30. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +8 -3
  31. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +5 -1
  32. package/.docs/raw/docs/(docs)/copilots/{make-assistant-readable.mdx → make-assistant-visible.mdx} +14 -5
  33. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +11 -11
  34. package/.docs/raw/docs/(docs)/copilots/motivation.mdx +2 -2
  35. package/.docs/raw/docs/(docs)/devtools.mdx +3 -2
  36. package/.docs/raw/docs/(docs)/guides/attachments.mdx +74 -15
  37. package/.docs/raw/docs/(docs)/guides/branching.mdx +11 -6
  38. package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +18 -16
  39. package/.docs/raw/docs/(docs)/guides/context-api.mdx +81 -43
  40. package/.docs/raw/docs/(docs)/guides/dictation.mdx +5 -5
  41. package/.docs/raw/docs/(docs)/guides/editing.mdx +16 -7
  42. package/.docs/raw/docs/(docs)/guides/interactables.mdx +292 -0
  43. package/.docs/raw/docs/(docs)/guides/latex.mdx +3 -0
  44. package/.docs/raw/docs/(docs)/guides/message-timing.mdx +5 -4
  45. package/.docs/raw/docs/(docs)/guides/multi-agent.mdx +174 -0
  46. package/.docs/raw/docs/(docs)/guides/quoting.mdx +55 -206
  47. package/.docs/raw/docs/(docs)/guides/speech.mdx +1 -4
  48. package/.docs/raw/docs/(docs)/guides/suggestions.mdx +9 -15
  49. package/.docs/raw/docs/(docs)/guides/tool-ui.mdx +17 -7
  50. package/.docs/raw/docs/(docs)/guides/tools.mdx +24 -9
  51. package/.docs/raw/docs/(docs)/index.mdx +3 -3
  52. package/.docs/raw/docs/(docs)/installation.mdx +69 -46
  53. package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +20 -6
  54. package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +24 -4
  55. package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +1 -1
  56. package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +20 -19
  57. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +28 -53
  58. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +4 -4
  59. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +7 -1
  60. package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +20 -14
  61. package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +1 -1
  62. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +226 -44
  63. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +52 -40
  64. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +343 -23
  65. package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +4 -6
  66. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +4 -2
  67. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +3 -5
  68. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +169 -22
  69. package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +14 -4
  70. package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +15 -26
  71. package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +39 -21
  72. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +33 -9
  73. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +48 -21
  74. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +36 -7
  75. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +30 -10
  76. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +12 -10
  77. package/.docs/raw/docs/(reference)/migrations/deprecation-policy.mdx +1 -1
  78. package/.docs/raw/docs/(reference)/migrations/react-langgraph-v0-7.mdx +9 -4
  79. package/.docs/raw/docs/(reference)/migrations/v0-11.mdx +7 -5
  80. package/.docs/raw/docs/(reference)/migrations/v0-12.mdx +9 -7
  81. package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +159 -0
  82. package/.docs/raw/docs/(reference)/react-compatibility.mdx +5 -134
  83. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +90 -6
  84. package/.docs/raw/docs/cloud/ai-sdk.mdx +95 -5
  85. package/.docs/raw/docs/cloud/langgraph.mdx +13 -3
  86. package/.docs/raw/docs/ink/adapters.mdx +41 -0
  87. package/.docs/raw/docs/ink/custom-backend.mdx +203 -0
  88. package/.docs/raw/docs/ink/hooks.mdx +448 -0
  89. package/.docs/raw/docs/ink/index.mdx +239 -0
  90. package/.docs/raw/docs/ink/migration.mdx +140 -0
  91. package/.docs/raw/docs/ink/primitives.mdx +840 -0
  92. package/.docs/raw/docs/primitives/action-bar.mdx +351 -0
  93. package/.docs/raw/docs/primitives/assistant-modal.mdx +215 -0
  94. package/.docs/raw/docs/primitives/attachment.mdx +216 -0
  95. package/.docs/raw/docs/primitives/branch-picker.mdx +221 -0
  96. package/.docs/raw/docs/primitives/chain-of-thought.mdx +311 -0
  97. package/.docs/raw/docs/primitives/composer.mdx +526 -0
  98. package/.docs/raw/docs/primitives/error.mdx +141 -0
  99. package/.docs/raw/docs/primitives/index.mdx +98 -0
  100. package/.docs/raw/docs/primitives/message.mdx +524 -0
  101. package/.docs/raw/docs/primitives/selection-toolbar.mdx +165 -0
  102. package/.docs/raw/docs/primitives/suggestion.mdx +242 -0
  103. package/.docs/raw/docs/primitives/thread-list.mdx +404 -0
  104. package/.docs/raw/docs/primitives/thread.mdx +482 -0
  105. package/.docs/raw/docs/react-native/adapters.mdx +63 -87
  106. package/.docs/raw/docs/react-native/custom-backend.mdx +11 -14
  107. package/.docs/raw/docs/react-native/hooks.mdx +214 -232
  108. package/.docs/raw/docs/react-native/index.mdx +118 -159
  109. package/.docs/raw/docs/react-native/migration.mdx +144 -0
  110. package/.docs/raw/docs/react-native/primitives.mdx +431 -302
  111. package/.docs/raw/docs/runtimes/a2a/index.mdx +294 -0
  112. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +9 -9
  113. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +14 -3
  114. package/.docs/raw/docs/runtimes/assistant-transport.mdx +59 -25
  115. package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +13 -6
  116. package/.docs/raw/docs/runtimes/custom/external-store.mdx +138 -38
  117. package/.docs/raw/docs/runtimes/custom/local.mdx +184 -42
  118. package/.docs/raw/docs/runtimes/data-stream.mdx +92 -19
  119. package/.docs/raw/docs/runtimes/google-adk/index.mdx +624 -0
  120. package/.docs/raw/docs/runtimes/helicone.mdx +6 -6
  121. package/.docs/raw/docs/runtimes/langgraph/index.mdx +38 -27
  122. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +1 -1
  123. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +15 -20
  124. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +7 -11
  125. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +8 -11
  126. package/.docs/raw/docs/runtimes/langserve.mdx +6 -7
  127. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +18 -3
  128. package/.docs/raw/docs/ui/file.mdx +5 -4
  129. package/.docs/raw/docs/ui/image.mdx +5 -4
  130. package/.docs/raw/docs/ui/markdown.mdx +3 -1
  131. package/.docs/raw/docs/ui/mention.mdx +168 -0
  132. package/.docs/raw/docs/ui/model-selector.mdx +8 -8
  133. package/.docs/raw/docs/ui/part-grouping.mdx +7 -10
  134. package/.docs/raw/docs/ui/quote.mdx +210 -0
  135. package/.docs/raw/docs/ui/reasoning.mdx +12 -11
  136. package/.docs/raw/docs/ui/sources.mdx +88 -17
  137. package/.docs/raw/docs/ui/streamdown.mdx +16 -7
  138. package/.docs/raw/docs/ui/thread-list.mdx +11 -13
  139. package/.docs/raw/docs/ui/thread.mdx +28 -33
  140. package/.docs/raw/docs/ui/tool-fallback.mdx +5 -6
  141. package/.docs/raw/docs/ui/tool-group.mdx +9 -8
  142. package/.docs/raw/docs/utilities/heat-graph.mdx +236 -0
  143. package/.docs/raw/docs/utilities/tw-shimmer.mdx +211 -0
  144. package/package.json +5 -5
  145. package/.docs/raw/docs/(reference)/legacy/styled/assistant-modal.mdx +0 -77
  146. package/.docs/raw/docs/(reference)/legacy/styled/decomposition.mdx +0 -635
  147. package/.docs/raw/docs/(reference)/legacy/styled/markdown.mdx +0 -77
  148. package/.docs/raw/docs/(reference)/legacy/styled/scrollbar.mdx +0 -72
  149. package/.docs/raw/docs/(reference)/legacy/styled/thread-width.mdx +0 -22
  150. package/.docs/raw/docs/(reference)/legacy/styled/thread.mdx +0 -77
  151. /package/.docs/raw/docs/cloud/{overview.mdx → index.mdx} +0 -0
@@ -0,0 +1,98 @@
1
+ ---
2
+ title: Overview
3
+ description: Unstyled, accessible building blocks for AI chat interfaces.
4
+ ---
5
+
6
+ Primitives are the foundation of assistant-ui. They are unstyled, accessible React components that handle all the wiring for AI chat, including state management, keyboard shortcuts, auto-scrolling, streaming, and tool calls, so you can focus entirely on your UI.
7
+
8
+ ## Why Primitives?
9
+
10
+ Every assistant-ui [Component](/docs/ui/thread) is built from primitives. When you install a component like `Thread`, you get a pre-styled composition of primitives with default styling and behavior included.
11
+
12
+ But when you need a UI that doesn't fit the defaults, such as a floating composer, a custom message layout, or an inline editing experience, you reach for the primitives directly.
13
+
14
+ ```tsx
15
+ import { ComposerPrimitive } from "@assistant-ui/react";
16
+
17
+ <ComposerPrimitive.Root>
18
+ <ComposerPrimitive.Input placeholder="Ask anything..." />
19
+ <ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
20
+ </ComposerPrimitive.Root>
21
+ ```
22
+
23
+ This renders an unstyled `<form>` with a `<textarea>` and a `<button>`. No styles, no opinions, but it already handles submit-on-enter, focus management, empty-state disabling, and streaming state.
24
+
25
+ ## How They Work
26
+
27
+ Every primitive follows the same pattern inspired by [Radix UI](https://www.radix-ui.com/):
28
+
29
+ - **`Primitive.Root`**: container that provides context to child parts
30
+ - **`Primitive.PartName`**: individual elements (input, button, text, etc.)
31
+ - **`asChild`**: merge primitive behavior onto your own element instead of rendering a wrapper
32
+ - **`AuiIf`**: conditional rendering based on state
33
+
34
+ Primitives read from the nearest runtime context. Place them inside an `AssistantRuntimeProvider` and they work without prop drilling or manual state wiring.
35
+
36
+ ## Available Primitives
37
+
38
+ <Cards>
39
+ <Card title="Composer" href="/docs/primitives/composer">
40
+ Text input, send button, attachments, and dictation. The interface for composing new messages or editing existing ones.
41
+ </Card>
42
+ <Card title="Thread" href="/docs/primitives/thread">
43
+ The scrollable message container with auto-scroll, empty states, and message rendering.
44
+ </Card>
45
+ <Card title="Message" href="/docs/primitives/message">
46
+ Individual message rendering with role-based content, parts, and metadata.
47
+ </Card>
48
+ <Card title="ActionBar" href="/docs/primitives/action-bar">
49
+ Copy, reload, edit, and other message actions.
50
+ </Card>
51
+ <Card title="BranchPicker" href="/docs/primitives/branch-picker">
52
+ Navigate between message branches (alternative responses).
53
+ </Card>
54
+ <Card title="ThreadList" href="/docs/primitives/thread-list">
55
+ Multi-thread management: list, create, switch, and archive threads.
56
+ </Card>
57
+ <Card title="AssistantModal" href="/docs/primitives/assistant-modal">
58
+ Floating chat popover built on Radix UI Popover.
59
+ </Card>
60
+ <Card title="Attachment" href="/docs/primitives/attachment">
61
+ File and image attachment rendering.
62
+ </Card>
63
+ <Card title="Suggestion" href="/docs/primitives/suggestion">
64
+ Suggested prompts and quick actions.
65
+ </Card>
66
+ <Card title="SelectionToolbar" href="/docs/primitives/selection-toolbar">
67
+ Floating toolbar for text selection actions like quoting.
68
+ </Card>
69
+ <Card title="Error" href="/docs/primitives/error">
70
+ Error display with accessible alert role and automatic error text.
71
+ </Card>
72
+ <Card title="ChainOfThought" href="/docs/primitives/chain-of-thought">
73
+ Collapsible reasoning accordion for thinking steps and tool calls.
74
+ </Card>
75
+ </Cards>
76
+
77
+ `MessagePartPrimitive` (for rendering individual text, image, and streaming parts) is documented within the [Message](/docs/primitives/message#messagepartprimitive) primitive page.
78
+
79
+ ## Related Primitive References
80
+
81
+ Additional primitive references:
82
+
83
+ - [MessagePartPrimitive](/docs/api-reference/primitives/message-part)
84
+ - [ThreadListItemPrimitive](/docs/api-reference/primitives/thread-list-item)
85
+ - [ThreadListItemMorePrimitive](/docs/api-reference/primitives/thread-list-item-more)
86
+ - [ActionBarMorePrimitive](/docs/api-reference/primitives/action-bar-more)
87
+ - [AssistantIf (`AuiIf`)](/docs/api-reference/primitives/assistant-if)
88
+
89
+ ## Common Mistakes
90
+
91
+ - Forgetting to wrap primitives with runtime context (`AssistantRuntimeProvider` + runtime hook)
92
+ - Mixing deprecated props with current APIs (`submitOnEnter`, `autoSend`, legacy `Suggestion`)
93
+ - Mounting primitives in the wrong context (`ActionBarPrimitive` / `BranchPickerPrimitive` outside `MessagePrimitive.Root`)
94
+ - Using unstable props unintentionally (`unstable_*` APIs)
95
+
96
+ ## Next Steps
97
+
98
+ Start with the [Composer](/docs/primitives/composer) primitive to see how primitives work in practice, or jump to the [API Reference](/docs/api-reference/primitives/composer) for full prop details.
@@ -0,0 +1,524 @@
1
+ ---
2
+ title: Message
3
+ description: Build custom message rendering with content parts, attachments, and hover state.
4
+ ---
5
+
6
+ import { MessagePrimitiveSample } from "@/components/docs/samples/message-primitive";
7
+ import { MessagePrimitive as MessagePrimitiveDocs } from "@/generated/primitiveDocs";
8
+
9
+ 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.
10
+
11
+ <Tabs items={["Preview", "Code"]}>
12
+ <Tab>
13
+ <MessagePrimitiveSample />
14
+ </Tab>
15
+ <Tab>
16
+ ```tsx
17
+ import {
18
+ MessagePrimitive,
19
+ MessagePartPrimitive,
20
+ } from "@assistant-ui/react";
21
+
22
+ function UserMessage() {
23
+ return (
24
+ <MessagePrimitive.Root className="flex justify-end">
25
+ <div className="max-w-[80%] rounded-2xl bg-primary px-4 py-2.5 text-sm text-primary-foreground">
26
+ <MessagePrimitive.Parts>
27
+ {({ part }) => {
28
+ if (part.type === "text") return <UserText />;
29
+ return null;
30
+ }}
31
+ </MessagePrimitive.Parts>
32
+ </div>
33
+ </MessagePrimitive.Root>
34
+ );
35
+ }
36
+
37
+ function AssistantMessage() {
38
+ return (
39
+ <MessagePrimitive.Root className="flex justify-start gap-3">
40
+ <div className="flex size-8 items-center justify-center rounded-full bg-primary/10 text-xs font-medium text-primary">
41
+ AI
42
+ </div>
43
+ <div className="max-w-[80%] rounded-2xl bg-muted px-4 py-2.5 text-sm">
44
+ <MessagePrimitive.Parts>
45
+ {({ part }) => {
46
+ if (part.type === "text") return <AssistantText />;
47
+ return part.toolUI ?? null;
48
+ }}
49
+ </MessagePrimitive.Parts>
50
+ </div>
51
+ </MessagePrimitive.Root>
52
+ );
53
+ }
54
+
55
+ function UserText() {
56
+ return (
57
+ <p>
58
+ <MessagePartPrimitive.Text />
59
+ </p>
60
+ );
61
+ }
62
+
63
+ function AssistantText() {
64
+ return (
65
+ <p className="leading-relaxed">
66
+ <MessagePartPrimitive.Text />
67
+ </p>
68
+ );
69
+ }
70
+ ```
71
+ </Tab>
72
+ </Tabs>
73
+
74
+ ## Quick Start
75
+
76
+ A minimal message with parts rendering:
77
+
78
+ ```tsx
79
+ import { MessagePrimitive } from "@assistant-ui/react";
80
+
81
+ <MessagePrimitive.Root>
82
+ <MessagePrimitive.Parts />
83
+ </MessagePrimitive.Root>
84
+ ```
85
+
86
+ `Root` renders a `<div>` that provides message context and tracks hover state. `Parts` iterates over the message's content parts and renders each one. Without custom components, parts render with sensible defaults: `Text` renders a `<p>` with `white-space: pre-line` and a streaming indicator, `Image` renders via `MessagePartPrimitive.Image`, and tool calls render nothing unless a tool UI is registered globally or inline. Reasoning, source, file, and audio parts render nothing by default.
87
+
88
+ <Callout type="info">
89
+ 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).
90
+ </Callout>
91
+
92
+ ## Core Concepts
93
+
94
+ ### Parts Pipeline
95
+
96
+ `MessagePrimitive.Parts` now prefers a children render function. It gives you the current enriched part state directly, so you can branch inline and return exactly the UI you want:
97
+
98
+ ```tsx
99
+ <MessagePrimitive.Parts>
100
+ {({ part }) => {
101
+ if (part.type === "text") return <MyTextRenderer />;
102
+ if (part.type === "image") return <MyImageRenderer />;
103
+ if (part.type === "tool-call")
104
+ return part.toolUI ?? <GenericToolUI {...part} />;
105
+ return null;
106
+ }}
107
+ </MessagePrimitive.Parts>
108
+ ```
109
+
110
+ <Callout type="info">
111
+ For most new `MessagePrimitive.Parts` code, prefer the `children` render function. Grouped Chain of Thought is the current exception: it plugs into `MessagePrimitive.Parts` via `components.ChainOfThought`.
112
+ </Callout>
113
+
114
+ ### Tool Resolution
115
+
116
+ Tool call parts resolve in this order:
117
+
118
+ 1. **`tools.Override`**: if provided inline through the deprecated `components` prop, handles **all** tool calls
119
+ 2. **Globally registered tools**: tools registered via `makeAssistantTool` / `useAssistantToolUI`
120
+ 3. **`tools.by_name[toolName]`**: per-`MessagePrimitive.Parts` inline overrides from the deprecated `components` prop
121
+ 4. **`tools.Fallback`**: catch-all for unmatched tool calls from the deprecated `components` prop
122
+ 5. **`part.toolUI`**: the resolved tool UI exposed directly in the children render function
123
+
124
+ In the children API, tool and data parts expose resolved UI helpers directly:
125
+
126
+ ```tsx
127
+ <MessagePrimitive.Parts>
128
+ {({ part }) => {
129
+ if (part.type === "tool-call")
130
+ return part.toolUI ?? <ToolFallback {...part} />;
131
+
132
+ if (part.type === "data")
133
+ return part.dataRendererUI ?? null;
134
+
135
+ return null;
136
+ }}
137
+ </MessagePrimitive.Parts>
138
+ ```
139
+
140
+ Returning `null` still allows registered tool UIs and data renderer UIs to render automatically. Return `<></>` if you want to suppress them entirely.
141
+
142
+ ### Components Prop (Deprecated)
143
+
144
+ `components` is deprecated. This section only documents it so older code is still understandable:
145
+
146
+ - `ToolGroup` wraps consecutive tool-call parts
147
+ - `ReasoningGroup` wraps consecutive reasoning parts
148
+ - `components.ChainOfThought` takes over all reasoning and tool-call rendering (mutually exclusive with `ToolGroup`, `ReasoningGroup`, `tools`, and `Reasoning`). Despite the deprecation of `components` in general, this is still the current way to wire grouped Chain of Thought.
149
+ - `data.by_name` and `data.Fallback` let you route custom data part types
150
+ - `Quote` renders quoted message references from metadata
151
+ - `Empty` and `Unstable_Audio` are available for edge and experimental rendering paths
152
+
153
+ ```tsx
154
+ <MessagePrimitive.Parts
155
+ components={{
156
+ Text: () => (
157
+ <p className="whitespace-pre-wrap">
158
+ <MessagePartPrimitive.Text />
159
+ </p>
160
+ ),
161
+ Image: () => <MessagePartPrimitive.Image className="max-w-sm rounded-xl" />,
162
+ File: () => <div className="rounded-md border px-2 py-1 text-xs">File part</div>,
163
+ tools: {
164
+ by_name: {
165
+ get_weather: () => <div>Weather tool</div>,
166
+ },
167
+ Fallback: ({ toolName }) => <div>Unknown tool: {toolName}</div>,
168
+ },
169
+ data: {
170
+ by_name: {
171
+ "my-event": ({ data }) => <pre>{JSON.stringify(data, null, 2)}</pre>,
172
+ },
173
+ Fallback: ({ name }) => <div>Unknown data event: {name}</div>,
174
+ },
175
+ ToolGroup: ({ children }) => (
176
+ <div className="space-y-2 rounded-lg border p-2">{children}</div>
177
+ ),
178
+ ReasoningGroup: ({ children }) => (
179
+ <details className="rounded-lg border p-2">
180
+ <summary>Reasoning</summary>
181
+ {children}
182
+ </details>
183
+ ),
184
+ Empty: () => <span className="text-muted-foreground">...</span>,
185
+ Unstable_Audio: () => null,
186
+ }}
187
+ />
188
+ ```
189
+
190
+ For new code, use the `children` render function instead.
191
+
192
+ ### Hover State
193
+
194
+ `MessagePrimitive.Root` automatically tracks mouse enter/leave events. This hover state is consumed by `ActionBarPrimitive` to implement auto-hide behavior, with no extra wiring needed.
195
+
196
+ ### MessagePartPrimitive
197
+
198
+ Inside your custom part components, use these sub-primitives to access the actual content:
199
+
200
+ - **`MessagePartPrimitive.Text`**: renders the text content of a text part
201
+ - **`MessagePartPrimitive.Image`**: renders the image of an image part
202
+ - **`MessagePartPrimitive.InProgress`**: renders only while the part is still streaming
203
+
204
+ ```tsx
205
+ function MyText() {
206
+ return (
207
+ <p className="whitespace-pre-wrap">
208
+ <MessagePartPrimitive.Text />
209
+ <MessagePartPrimitive.InProgress>
210
+ <span className="animate-pulse">▊</span>
211
+ </MessagePartPrimitive.InProgress>
212
+ </p>
213
+ );
214
+ }
215
+ ```
216
+
217
+ ## Parts
218
+
219
+ ### Root
220
+
221
+ Container for a single message. Renders a `<div>` element unless `asChild` is set.
222
+
223
+ ```tsx
224
+ <MessagePrimitive.Root className="flex flex-col gap-2">
225
+ <MessagePrimitive.Quote>
226
+ {({ text }) => <blockquote className="mb-2 border-l pl-3 italic">{text}</blockquote>}
227
+ </MessagePrimitive.Quote>
228
+ <MessagePrimitive.Parts />
229
+ </MessagePrimitive.Root>
230
+ ```
231
+
232
+ ### Parts
233
+
234
+ Renders each content part with type-based component resolution.
235
+
236
+ ```tsx
237
+ <MessagePrimitive.Parts>
238
+ {({ part }) => {
239
+ if (part.type === "text") return <MyTextRenderer />;
240
+ if (part.type === "image") return <MyImageRenderer />;
241
+ if (part.type === "tool-call")
242
+ return part.toolUI ?? <GenericToolUI {...part} />;
243
+ return null;
244
+ }}
245
+ </MessagePrimitive.Parts>
246
+ ```
247
+
248
+ <PrimitivesTypeTable type="MessagePrimitivePartsProps" parameters={MessagePrimitiveDocs.Parts.props} />
249
+
250
+ ### Content
251
+
252
+ Legacy alias for `Parts`.
253
+
254
+ ```tsx
255
+ <MessagePrimitive.Content>
256
+ {({ part }) => {
257
+ if (part.type === "text") return <MyTextRenderer />;
258
+ return null;
259
+ }}
260
+ </MessagePrimitive.Content>
261
+ ```
262
+
263
+ ### PartByIndex
264
+
265
+ Renders a single part at a specific index.
266
+
267
+ ```tsx
268
+ <MessagePrimitive.PartByIndex
269
+ index={0}
270
+ components={{ Text: MyTextRenderer }}
271
+ />
272
+ ```
273
+
274
+ ### Attachments
275
+
276
+ Renders all user message attachments.
277
+
278
+ ```tsx
279
+ <MessagePrimitive.Attachments>
280
+ {({ attachment }) => {
281
+ if (attachment.type === "image") {
282
+ const imageSrc = attachment.content?.find((part) => part.type === "image")?.image;
283
+ if (!imageSrc) return null;
284
+ return <img src={imageSrc} alt={attachment.name} className="max-w-xs rounded-lg" />;
285
+ }
286
+
287
+ if (attachment.type === "document") {
288
+ return (
289
+ <div className="rounded-lg border p-2 text-sm">
290
+ {attachment.name}
291
+ </div>
292
+ );
293
+ }
294
+
295
+ return null;
296
+ }}
297
+ </MessagePrimitive.Attachments>
298
+ ```
299
+
300
+ <PrimitivesTypeTable type="MessagePrimitiveAttachmentsProps" parameters={MessagePrimitiveDocs.Attachments.props} />
301
+
302
+ ### AttachmentByIndex
303
+
304
+ Renders a single attachment at the specified index within the current message.
305
+
306
+ ```tsx
307
+ <MessagePrimitive.AttachmentByIndex
308
+ index={0}
309
+ components={{ Attachment: MyAttachment }}
310
+ />
311
+ ```
312
+
313
+ <PrimitivesTypeTable type="MessagePrimitiveAttachmentByIndexProps" parameters={MessagePrimitiveDocs.AttachmentByIndex.props} />
314
+
315
+ ### Error
316
+
317
+ Renders children only when the message has an error.
318
+
319
+ ```tsx
320
+ <MessagePrimitive.Error>
321
+ <ErrorPrimitive.Root className="mt-2 rounded-md border border-destructive/20 bg-destructive/5 p-3">
322
+ <ErrorPrimitive.Message />
323
+ </ErrorPrimitive.Root>
324
+ </MessagePrimitive.Error>
325
+ ```
326
+
327
+ ### Quote
328
+
329
+ Renders quote metadata when the current message includes a quote. Place it above `MessagePrimitive.Parts`.
330
+
331
+ ```tsx
332
+ <MessagePrimitive.Quote>
333
+ {({ text, messageId }) => (
334
+ <blockquote className="mb-2 border-l pl-3 italic" data-message-id={messageId}>
335
+ {text}
336
+ </blockquote>
337
+ )}
338
+ </MessagePrimitive.Quote>
339
+ ```
340
+
341
+ ### Unstable_PartsGrouped
342
+
343
+ Groups consecutive parts by a custom grouping function *(unstable)*.
344
+
345
+ ```tsx
346
+ <MessagePrimitive.Unstable_PartsGrouped
347
+ groupingFunction={myGroupFn}
348
+ components={{ Text: MyText, Group: MyGroupWrapper }}
349
+ />
350
+ ```
351
+
352
+ <PrimitivesTypeTable type="MessagePrimitiveUnstablePartsGroupedProps" parameters={MessagePrimitiveDocs.Unstable_PartsGrouped.props} />
353
+
354
+ ### Unstable_PartsGroupedByParentId
355
+
356
+ Groups parts by parent ID *(unstable, deprecated; use `Unstable_PartsGrouped`)*.
357
+
358
+ ```tsx
359
+ <MessagePrimitive.Unstable_PartsGroupedByParentId
360
+ components={{ Text: MyText, Group: MyGroupWrapper }}
361
+ />
362
+ ```
363
+
364
+ ### If (deprecated)
365
+
366
+ <Callout type="warn">
367
+ Deprecated. Use [`AuiIf`](/docs/api-reference/primitives/assistant-if) instead.
368
+ </Callout>
369
+
370
+ ```tsx
371
+ // Before (deprecated)
372
+ <MessagePrimitive.If user>...</MessagePrimitive.If>
373
+ <MessagePrimitive.If assistant>...</MessagePrimitive.If>
374
+
375
+ // After
376
+ <AuiIf condition={(s) => s.message.role === "user"}>...</AuiIf>
377
+ <AuiIf condition={(s) => s.message.role === "assistant"}>...</AuiIf>
378
+ ```
379
+
380
+ ## Patterns
381
+
382
+ ### Custom Text Rendering
383
+
384
+ ```tsx
385
+ function MarkdownText() {
386
+ return (
387
+ <div className="prose prose-sm">
388
+ <MessagePartPrimitive.Text />
389
+ </div>
390
+ );
391
+ }
392
+
393
+ <MessagePrimitive.Parts>
394
+ {({ part }) => {
395
+ if (part.type === "text") return <MarkdownText />;
396
+ return null;
397
+ }}
398
+ </MessagePrimitive.Parts>
399
+ ```
400
+
401
+ ### Tool UI with by_name
402
+
403
+ ```tsx
404
+ <MessagePrimitive.Parts
405
+ components={{
406
+ Text: MyText,
407
+ tools: {
408
+ by_name: {
409
+ get_weather: ({ result }) => (
410
+ <div className="rounded-lg border p-3">
411
+ <p className="font-medium">Weather</p>
412
+ <p>{result?.temperature}°F, {result?.condition}</p>
413
+ </div>
414
+ ),
415
+ },
416
+ Fallback: ({ toolName, status }) => (
417
+ <div className="text-muted-foreground text-sm">
418
+ {status.type === "running" ? `Running ${toolName}...` : `${toolName} completed`}
419
+ </div>
420
+ ),
421
+ },
422
+ }}
423
+ />
424
+ ```
425
+
426
+ ### Error Display
427
+
428
+ ```tsx
429
+ <MessagePrimitive.Root>
430
+ <MessagePrimitive.Parts />
431
+ <MessagePrimitive.Error>
432
+ <div className="mt-2 rounded-md bg-destructive/10 p-2 text-sm text-destructive">
433
+ Something went wrong. Please try again.
434
+ </div>
435
+ </MessagePrimitive.Error>
436
+ </MessagePrimitive.Root>
437
+ ```
438
+
439
+ ### Error Display with ErrorPrimitive
440
+
441
+ For more control over error rendering, `ErrorPrimitive` provides a dedicated component that auto-reads the error string from the message status:
442
+
443
+ ```tsx
444
+ import { ErrorPrimitive, MessagePrimitive } from "@assistant-ui/react";
445
+
446
+ <MessagePrimitive.Root>
447
+ <MessagePrimitive.Parts />
448
+ <ErrorPrimitive.Root className="mt-2 rounded-md bg-destructive/10 p-2 text-sm text-destructive" role="alert">
449
+ <ErrorPrimitive.Message />
450
+ </ErrorPrimitive.Root>
451
+ </MessagePrimitive.Root>
452
+ ```
453
+
454
+ `ErrorPrimitive.Root` renders a `<div>` container with `role="alert"` and `ErrorPrimitive.Message` renders a `<span>` that displays the error text. `Root` always renders. Only `Message` conditionally returns `null` when there is no error. Wrap in `<MessagePrimitive.Error>` if you want the entire block to be conditional. See the [ErrorPrimitive API Reference](/docs/api-reference/primitives/error) for full details.
455
+
456
+ ### Legacy and Unstable APIs
457
+
458
+ - `MessagePrimitive.Unstable_PartsGrouped` and `MessagePrimitive.Unstable_PartsGroupedByParentId` are unstable APIs for custom grouping.
459
+ - `Unstable_PartsGroupedByParentId` is deprecated in favor of `Unstable_PartsGrouped`.
460
+
461
+ ### Role-Based Styling
462
+
463
+ `MessagePrimitive.Root` sets `data-message-id` automatically but does not set a `data-role` attribute. Style by role in your message components:
464
+
465
+ ```tsx
466
+ // In your ThreadPrimitive.Messages children render function:
467
+ function UserMessage() {
468
+ return (
469
+ <MessagePrimitive.Root data-role="user" className="flex justify-end">
470
+ <MessagePrimitive.Parts />
471
+ </MessagePrimitive.Root>
472
+ );
473
+ }
474
+
475
+ function AssistantMessage() {
476
+ return (
477
+ <MessagePrimitive.Root data-role="assistant" className="flex justify-start">
478
+ <MessagePrimitive.Parts />
479
+ </MessagePrimitive.Root>
480
+ );
481
+ }
482
+ ```
483
+
484
+ ### Attachments
485
+
486
+ ```tsx
487
+ <MessagePrimitive.Root>
488
+ <MessagePrimitive.Attachments>
489
+ {({ attachment }) => {
490
+ if (attachment.type === "image") {
491
+ const imageSrc = attachment.content?.find((part) => part.type === "image")?.image;
492
+ if (!imageSrc) return null;
493
+ return <img src={imageSrc} alt={attachment.name} className="max-w-xs rounded-lg" />;
494
+ }
495
+
496
+ if (attachment.type === "document") {
497
+ return (
498
+ <div className="flex items-center gap-2 rounded-lg border p-2 text-sm">
499
+ 📄 {attachment.name}
500
+ </div>
501
+ );
502
+ }
503
+
504
+ return null;
505
+ }}
506
+ </MessagePrimitive.Attachments>
507
+ <MessagePrimitive.Parts />
508
+ </MessagePrimitive.Root>
509
+ ```
510
+
511
+ ## Relationship to Components
512
+
513
+ The shadcn [Thread](/docs/ui/thread) component renders user and assistant messages built from these primitives. The pre-built `AssistantMessage` and `UserMessage` components handle text rendering, tool UIs, error display, and action bars, all using `MessagePrimitive` under the hood.
514
+
515
+ Messages are commonly paired with [ActionBar](/docs/primitives/action-bar) for copy/reload/edit actions and [BranchPicker](/docs/primitives/branch-picker) for navigating between alternative responses.
516
+
517
+ ## API Reference
518
+
519
+ For full prop details on every part, see the [MessagePrimitive API Reference](/docs/api-reference/primitives/message).
520
+
521
+ Related:
522
+ - [MessagePartPrimitive API Reference](/docs/api-reference/primitives/message-part)
523
+ - [ActionBarPrimitive API Reference](/docs/api-reference/primitives/action-bar)
524
+ - [BranchPickerPrimitive API Reference](/docs/api-reference/primitives/branch-picker)