@assistant-ui/mcp-docs-server 0.1.24 → 0.1.25
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 +4 -2
- package/.docs/organized/code-examples/with-a2a.md +676 -0
- package/.docs/organized/code-examples/with-ag-ui.md +5 -6
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +27 -15
- package/.docs/organized/code-examples/with-artifacts.md +4 -4
- package/.docs/organized/code-examples/with-assistant-transport.md +2 -2
- package/.docs/organized/code-examples/with-chain-of-thought.md +33 -25
- package/.docs/organized/code-examples/with-cloud-standalone.md +9 -6
- package/.docs/organized/code-examples/with-cloud.md +4 -4
- package/.docs/organized/code-examples/with-custom-thread-list.md +6 -6
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +7 -7
- package/.docs/organized/code-examples/with-expo.md +565 -514
- package/.docs/organized/code-examples/with-external-store.md +2 -2
- package/.docs/organized/code-examples/with-ffmpeg.md +4 -4
- package/.docs/organized/code-examples/with-google-adk.md +353 -0
- package/.docs/organized/code-examples/with-heat-graph.md +304 -0
- package/.docs/organized/code-examples/with-langgraph.md +24 -22
- package/.docs/organized/code-examples/with-parent-id-grouping.md +3 -3
- package/.docs/organized/code-examples/with-react-hook-form.md +4 -4
- package/.docs/organized/code-examples/with-react-ink.md +265 -0
- package/.docs/organized/code-examples/with-react-router.md +5 -5
- package/.docs/organized/code-examples/with-store.md +28 -17
- package/.docs/organized/code-examples/with-tanstack.md +7 -7
- package/.docs/organized/code-examples/with-tap-runtime.md +5 -3
- package/.docs/raw/blog/2025-01-31-changelog/index.mdx +1 -1
- package/.docs/raw/blog/2026-03-launch-week/index.mdx +227 -0
- package/.docs/raw/docs/(docs)/architecture.mdx +1 -1
- package/.docs/raw/docs/(docs)/cli.mdx +14 -9
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +8 -3
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +5 -1
- package/.docs/raw/docs/(docs)/copilots/{make-assistant-readable.mdx → make-assistant-visible.mdx} +14 -5
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +11 -11
- package/.docs/raw/docs/(docs)/copilots/motivation.mdx +2 -2
- package/.docs/raw/docs/(docs)/devtools.mdx +3 -2
- package/.docs/raw/docs/(docs)/guides/attachments.mdx +9 -11
- package/.docs/raw/docs/(docs)/guides/branching.mdx +11 -6
- package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +18 -16
- package/.docs/raw/docs/(docs)/guides/context-api.mdx +81 -43
- package/.docs/raw/docs/(docs)/guides/dictation.mdx +5 -5
- package/.docs/raw/docs/(docs)/guides/editing.mdx +16 -7
- package/.docs/raw/docs/(docs)/guides/latex.mdx +3 -0
- package/.docs/raw/docs/(docs)/guides/message-timing.mdx +2 -1
- package/.docs/raw/docs/(docs)/guides/multi-agent.mdx +173 -0
- package/.docs/raw/docs/(docs)/guides/quoting.mdx +55 -206
- package/.docs/raw/docs/(docs)/guides/speech.mdx +1 -4
- package/.docs/raw/docs/(docs)/guides/suggestions.mdx +9 -15
- package/.docs/raw/docs/(docs)/guides/tool-ui.mdx +17 -7
- package/.docs/raw/docs/(docs)/guides/tools.mdx +24 -9
- package/.docs/raw/docs/(docs)/index.mdx +3 -3
- package/.docs/raw/docs/(docs)/installation.mdx +69 -46
- package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +20 -6
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +24 -4
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +20 -19
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +28 -53
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +4 -4
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +7 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +20 -14
- package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +99 -45
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +52 -40
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +343 -23
- package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +4 -6
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +4 -2
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +3 -5
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +169 -22
- package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +14 -4
- package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +15 -26
- package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +39 -21
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +33 -9
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +48 -21
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +36 -7
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +30 -10
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +12 -10
- package/.docs/raw/docs/(reference)/migrations/deprecation-policy.mdx +1 -1
- package/.docs/raw/docs/(reference)/migrations/react-langgraph-v0-7.mdx +9 -4
- package/.docs/raw/docs/(reference)/migrations/v0-11.mdx +7 -5
- package/.docs/raw/docs/(reference)/migrations/v0-12.mdx +9 -7
- package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +159 -0
- package/.docs/raw/docs/(reference)/react-compatibility.mdx +5 -134
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +84 -6
- package/.docs/raw/docs/cloud/ai-sdk.mdx +14 -4
- package/.docs/raw/docs/cloud/langgraph.mdx +13 -3
- package/.docs/raw/docs/ink/adapters.mdx +41 -0
- package/.docs/raw/docs/ink/custom-backend.mdx +203 -0
- package/.docs/raw/docs/ink/hooks.mdx +448 -0
- package/.docs/raw/docs/ink/index.mdx +239 -0
- package/.docs/raw/docs/ink/migration.mdx +140 -0
- package/.docs/raw/docs/ink/primitives.mdx +699 -0
- package/.docs/raw/docs/react-native/adapters.mdx +63 -87
- package/.docs/raw/docs/react-native/custom-backend.mdx +11 -14
- package/.docs/raw/docs/react-native/hooks.mdx +214 -232
- package/.docs/raw/docs/react-native/index.mdx +118 -159
- package/.docs/raw/docs/react-native/migration.mdx +144 -0
- package/.docs/raw/docs/react-native/primitives.mdx +431 -302
- package/.docs/raw/docs/runtimes/a2a/index.mdx +294 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +9 -9
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +14 -3
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +59 -25
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +13 -6
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +138 -38
- package/.docs/raw/docs/runtimes/custom/local.mdx +184 -42
- package/.docs/raw/docs/runtimes/data-stream.mdx +92 -19
- package/.docs/raw/docs/runtimes/google-adk/index.mdx +624 -0
- package/.docs/raw/docs/runtimes/helicone.mdx +6 -6
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +38 -27
- package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +1 -1
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +15 -20
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +7 -11
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +8 -11
- package/.docs/raw/docs/runtimes/langserve.mdx +6 -7
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +18 -3
- package/.docs/raw/docs/ui/file.mdx +5 -4
- package/.docs/raw/docs/ui/image.mdx +5 -4
- package/.docs/raw/docs/ui/markdown.mdx +3 -1
- package/.docs/raw/docs/ui/model-selector.mdx +8 -8
- package/.docs/raw/docs/ui/part-grouping.mdx +7 -10
- package/.docs/raw/docs/ui/quote.mdx +210 -0
- package/.docs/raw/docs/ui/reasoning.mdx +12 -11
- package/.docs/raw/docs/ui/sources.mdx +88 -17
- package/.docs/raw/docs/ui/streamdown.mdx +16 -7
- package/.docs/raw/docs/ui/thread-list.mdx +11 -13
- package/.docs/raw/docs/ui/thread.mdx +28 -33
- package/.docs/raw/docs/ui/tool-fallback.mdx +5 -6
- package/.docs/raw/docs/ui/tool-group.mdx +9 -8
- package/.docs/raw/docs/utilities/heat-graph.mdx +236 -0
- package/.docs/raw/docs/utilities/tw-shimmer.mdx +211 -0
- package/package.json +4 -4
- package/.docs/raw/docs/(reference)/legacy/styled/assistant-modal.mdx +0 -77
- package/.docs/raw/docs/(reference)/legacy/styled/decomposition.mdx +0 -635
- package/.docs/raw/docs/(reference)/legacy/styled/markdown.mdx +0 -77
- package/.docs/raw/docs/(reference)/legacy/styled/scrollbar.mdx +0 -72
- package/.docs/raw/docs/(reference)/legacy/styled/thread-width.mdx +0 -22
- package/.docs/raw/docs/(reference)/legacy/styled/thread.mdx +0 -77
- /package/.docs/raw/docs/cloud/{overview.mdx → index.mdx} +0 -0
|
@@ -1,113 +1,35 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Quote Selected Text
|
|
3
|
-
description: Let users select and quote text from messages
|
|
3
|
+
description: Let users select and quote text from messages. Full guide including backend handling and programmatic API.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
import { QuoteComposerSample } from "@/components/docs/samples/quote-composer";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
1. User selects text in a message
|
|
11
|
-
2. A floating toolbar appears near the selection with a **Quote** button
|
|
12
|
-
3. User clicks it — a quote preview appears in the composer
|
|
13
|
-
4. User types their reply and sends
|
|
14
|
-
5. The sent message displays the quoted text above the user's reply
|
|
8
|
+
<QuoteComposerSample />
|
|
15
9
|
|
|
16
|
-
|
|
10
|
+
## Get Started
|
|
17
11
|
|
|
18
|
-
|
|
12
|
+
The **[Quote](/docs/ui/quote)** registry component gives you everything you need out of the box, including a floating selection toolbar, composer quote preview, and inline quote display.
|
|
19
13
|
|
|
20
|
-
|
|
14
|
+
<InstallCommand shadcn={["quote"]} />
|
|
21
15
|
|
|
22
|
-
|
|
16
|
+
It ships three composable pieces:
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
- **QuoteBlock** renders quoted text inline in user messages
|
|
19
|
+
- **SelectionToolbar** is a floating toolbar that appears on text selection
|
|
20
|
+
- **ComposerQuotePreview** shows the pending quote inside the composer
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
return (
|
|
30
|
-
<ThreadPrimitive.Root>
|
|
31
|
-
<ThreadPrimitive.Viewport>
|
|
32
|
-
<ThreadPrimitive.Messages components={{ ... }} />
|
|
33
|
-
...
|
|
34
|
-
</ThreadPrimitive.Viewport>
|
|
35
|
-
|
|
36
|
-
{/* Floating toolbar — appears on text selection */}
|
|
37
|
-
<SelectionToolbarPrimitive.Root className="flex items-center gap-1 rounded-lg border bg-popover px-1 py-1 shadow-md">
|
|
38
|
-
<SelectionToolbarPrimitive.Quote className="flex items-center gap-1.5 rounded-md px-2.5 py-1 text-sm hover:bg-accent">
|
|
39
|
-
<QuoteIcon className="size-3.5" />
|
|
40
|
-
Quote
|
|
41
|
-
</SelectionToolbarPrimitive.Quote>
|
|
42
|
-
</SelectionToolbarPrimitive.Root>
|
|
43
|
-
</ThreadPrimitive.Root>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
```
|
|
22
|
+
See the [Quote component page](/docs/ui/quote) for full setup steps and API reference.
|
|
47
23
|
|
|
48
|
-
|
|
49
|
-
- Listens for `mouseup` and `keyup` events to detect text selections
|
|
50
|
-
- Validates the selection is within a single message (cross-message selections are ignored)
|
|
51
|
-
- Renders a portal positioned above the selection
|
|
52
|
-
- Prevents `mousedown` from clearing the selection when clicking the toolbar
|
|
53
|
-
- Hides automatically on scroll or when the selection is cleared
|
|
54
|
-
|
|
55
|
-
### 2. Show Quote Preview in Composer
|
|
56
|
-
|
|
57
|
-
Add `ComposerPrimitive.Quote` inside the composer to show what's being quoted:
|
|
58
|
-
|
|
59
|
-
```tsx {1,8-13}
|
|
60
|
-
import { ComposerPrimitive } from "@assistant-ui/react";
|
|
61
|
-
|
|
62
|
-
const Composer = () => {
|
|
63
|
-
return (
|
|
64
|
-
<ComposerPrimitive.Root>
|
|
65
|
-
{/* Quote preview — only renders when a quote is set */}
|
|
66
|
-
<ComposerPrimitive.Quote className="flex items-start gap-2 border-l-4 border-primary/40 bg-muted/50 px-3 py-2 text-sm">
|
|
67
|
-
<ComposerPrimitive.QuoteText className="line-clamp-2 flex-1 italic text-muted-foreground" />
|
|
68
|
-
<ComposerPrimitive.QuoteDismiss>
|
|
69
|
-
×
|
|
70
|
-
</ComposerPrimitive.QuoteDismiss>
|
|
71
|
-
</ComposerPrimitive.Quote>
|
|
72
|
-
|
|
73
|
-
<ComposerPrimitive.Input placeholder="Send a message..." />
|
|
74
|
-
<ComposerPrimitive.Send />
|
|
75
|
-
</ComposerPrimitive.Root>
|
|
76
|
-
);
|
|
77
|
-
};
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### 3. Display Quotes in Sent Messages
|
|
81
|
-
|
|
82
|
-
Use `useMessageQuote()` to render quoted text in user messages:
|
|
83
|
-
|
|
84
|
-
```tsx {1,4-5,11}
|
|
85
|
-
import { MessagePrimitive, useMessageQuote } from "@assistant-ui/react";
|
|
86
|
-
|
|
87
|
-
const QuoteBlock = () => {
|
|
88
|
-
const quote = useMessageQuote();
|
|
89
|
-
if (!quote) return null;
|
|
24
|
+
---
|
|
90
25
|
|
|
91
|
-
|
|
92
|
-
<div className="mb-1 border-l-4 border-primary/40 pl-3 text-xs italic text-muted-foreground">
|
|
93
|
-
{quote.text}
|
|
94
|
-
</div>
|
|
95
|
-
);
|
|
96
|
-
};
|
|
26
|
+
## How It Works
|
|
97
27
|
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
<MessagePrimitive.Root>
|
|
101
|
-
<QuoteBlock />
|
|
102
|
-
<MessagePrimitive.Parts />
|
|
103
|
-
</MessagePrimitive.Root>
|
|
104
|
-
);
|
|
105
|
-
};
|
|
106
|
-
```
|
|
28
|
+
When a user selects text in an assistant message, a floating toolbar appears with a Quote button. Clicking it calls `composer.setQuote()` to store the selection on the composer. The [Quote component](/docs/ui/quote) does this out of the box.
|
|
107
29
|
|
|
108
|
-
|
|
30
|
+
When the message is sent, the composer runtime automatically writes the quote to `message.metadata.custom.quote` and clears it from the composer.
|
|
109
31
|
|
|
110
|
-
|
|
32
|
+
On the backend, the route handler extracts the quote from metadata and surfaces it to the LLM. We export a helper called `injectQuoteContext` that handles this automatically for AI-SDK. Without this step, the quote appears in the UI but is not sent to the model as context. See [Backend Handling](#backend-handling) for more info and alternatives.
|
|
111
33
|
|
|
112
34
|
### Data Shape
|
|
113
35
|
|
|
@@ -120,57 +42,15 @@ type QuoteInfo = {
|
|
|
120
42
|
// Stored at: message.metadata.custom.quote
|
|
121
43
|
```
|
|
122
44
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
A simple approach is to prepend the quoted text as a `>` blockquote before converting to model messages:
|
|
126
|
-
|
|
127
|
-
```typescript title="app/api/chat/route.ts" {1,9}
|
|
128
|
-
import { convertToModelMessages, streamText } from "ai";
|
|
129
|
-
import type { UIMessage } from "ai";
|
|
130
|
-
|
|
131
|
-
export async function POST(req: Request) {
|
|
132
|
-
const { messages } = await req.json();
|
|
133
|
-
|
|
134
|
-
const result = streamText({
|
|
135
|
-
model: myModel,
|
|
136
|
-
messages: await convertToModelMessages(injectQuoteContext(messages)),
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
return result.toUIMessageStreamResponse();
|
|
140
|
-
}
|
|
45
|
+
## Backend Handling
|
|
141
46
|
|
|
142
|
-
|
|
143
|
-
return messages.map((msg) => {
|
|
144
|
-
const quote = (msg.metadata as Record<string, unknown>)?.custom;
|
|
145
|
-
if (
|
|
146
|
-
!quote ||
|
|
147
|
-
typeof quote !== "object" ||
|
|
148
|
-
!("quote" in (quote as Record<string, unknown>))
|
|
149
|
-
)
|
|
150
|
-
return msg;
|
|
151
|
-
|
|
152
|
-
const q = (quote as Record<string, unknown>).quote;
|
|
153
|
-
if (
|
|
154
|
-
!q ||
|
|
155
|
-
typeof q !== "object" ||
|
|
156
|
-
!("text" in (q as Record<string, unknown>))
|
|
157
|
-
)
|
|
158
|
-
return msg;
|
|
159
|
-
|
|
160
|
-
const text = (q as { text: unknown }).text;
|
|
161
|
-
if (typeof text !== "string") return msg;
|
|
47
|
+
Quote data travels in message metadata, not content, so the LLM will not see it unless your backend extracts and surfaces it. The simplest path is [`injectQuoteContext`](/docs/ui/quote#forward-quote-context-to-the-llm), which prepends quoted text as a markdown blockquote before the message parts.
|
|
162
48
|
|
|
163
|
-
|
|
164
|
-
...msg,
|
|
165
|
-
parts: [{ type: "text" as const, text: `> ${text}\n\n` }, ...msg.parts],
|
|
166
|
-
};
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
```
|
|
49
|
+
For provider-specific handling, work with the quote metadata directly.
|
|
170
50
|
|
|
171
|
-
###
|
|
51
|
+
### Claude SDK Citations
|
|
172
52
|
|
|
173
|
-
|
|
53
|
+
Pass the quoted text as a citation source so Claude produces citations that reference it:
|
|
174
54
|
|
|
175
55
|
```typescript title="app/api/chat/route.ts"
|
|
176
56
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -180,7 +60,6 @@ const client = new Anthropic();
|
|
|
180
60
|
export async function POST(req: Request) {
|
|
181
61
|
const { messages } = await req.json();
|
|
182
62
|
|
|
183
|
-
// Transform messages: extract quotes into Claude source blocks
|
|
184
63
|
const claudeMessages = messages.map((msg) => {
|
|
185
64
|
const quote = msg.metadata?.custom?.quote;
|
|
186
65
|
if (!quote?.text) {
|
|
@@ -205,7 +84,7 @@ export async function POST(req: Request) {
|
|
|
205
84
|
});
|
|
206
85
|
|
|
207
86
|
const response = await client.messages.create({
|
|
208
|
-
model: "claude-sonnet-4-
|
|
87
|
+
model: "claude-sonnet-4-6",
|
|
209
88
|
max_tokens: 1024,
|
|
210
89
|
messages: claudeMessages,
|
|
211
90
|
});
|
|
@@ -214,9 +93,9 @@ export async function POST(req: Request) {
|
|
|
214
93
|
}
|
|
215
94
|
```
|
|
216
95
|
|
|
217
|
-
###
|
|
96
|
+
### OpenAI Message Context
|
|
218
97
|
|
|
219
|
-
|
|
98
|
+
Inject the quote as additional context in the user message:
|
|
220
99
|
|
|
221
100
|
```typescript title="app/api/chat/route.ts"
|
|
222
101
|
function injectQuoteForOpenAI(messages) {
|
|
@@ -232,9 +111,28 @@ function injectQuoteForOpenAI(messages) {
|
|
|
232
111
|
}
|
|
233
112
|
```
|
|
234
113
|
|
|
114
|
+
## Reading Quote Data
|
|
115
|
+
|
|
116
|
+
Use `useMessageQuote` to access quote data in custom components:
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
import { useMessageQuote } from "@assistant-ui/react";
|
|
120
|
+
|
|
121
|
+
function CustomQuoteDisplay() {
|
|
122
|
+
const quote = useMessageQuote();
|
|
123
|
+
if (!quote) return null;
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<blockquote className="border-l-2 pl-3 text-sm text-muted-foreground">
|
|
127
|
+
{quote.text}
|
|
128
|
+
</blockquote>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
235
133
|
## Programmatic API
|
|
236
134
|
|
|
237
|
-
|
|
135
|
+
Set or clear quotes via the composer runtime:
|
|
238
136
|
|
|
239
137
|
```tsx
|
|
240
138
|
import { useAui } from "@assistant-ui/react";
|
|
@@ -243,14 +141,14 @@ function MyComponent() {
|
|
|
243
141
|
const aui = useAui();
|
|
244
142
|
|
|
245
143
|
const quoteText = () => {
|
|
246
|
-
aui.thread().composer.setQuote({
|
|
144
|
+
aui.thread().composer().setQuote({
|
|
247
145
|
text: "The text to quote",
|
|
248
146
|
messageId: "msg-123",
|
|
249
147
|
});
|
|
250
148
|
};
|
|
251
149
|
|
|
252
150
|
const clearQuote = () => {
|
|
253
|
-
aui.thread().composer.setQuote(undefined);
|
|
151
|
+
aui.thread().composer().setQuote(undefined);
|
|
254
152
|
};
|
|
255
153
|
|
|
256
154
|
return (
|
|
@@ -262,66 +160,17 @@ function MyComponent() {
|
|
|
262
160
|
}
|
|
263
161
|
```
|
|
264
162
|
|
|
265
|
-
## API Reference
|
|
266
|
-
|
|
267
|
-
### SelectionToolbarPrimitive.Root
|
|
268
|
-
|
|
269
|
-
A floating container that appears when text is selected within a message. Renders as a portal positioned above the selection.
|
|
270
|
-
|
|
271
|
-
- Listens for `mouseup` / `keyup` to detect selection
|
|
272
|
-
- Validates selection is within a single message
|
|
273
|
-
- Hides on scroll or when selection is cleared
|
|
274
|
-
- Prevents `mousedown` from clearing the selection
|
|
275
|
-
- Provides selection context to child components
|
|
276
|
-
|
|
277
|
-
### SelectionToolbarPrimitive.Quote
|
|
278
|
-
|
|
279
|
-
A button inside the floating toolbar that captures the selection as a quote.
|
|
280
|
-
|
|
281
|
-
- Reads selection info from the toolbar context (not `window.getSelection()`)
|
|
282
|
-
- Stores `{ text, messageId }` in the thread composer
|
|
283
|
-
- Clears the text selection after quoting
|
|
284
|
-
|
|
285
|
-
### ComposerPrimitive.Quote
|
|
286
|
-
|
|
287
|
-
A container that only renders when a quote is set.
|
|
288
|
-
|
|
289
|
-
### ComposerPrimitive.QuoteText
|
|
290
|
-
|
|
291
|
-
Renders the quoted text. Defaults to `<span>`.
|
|
292
|
-
|
|
293
|
-
### ComposerPrimitive.QuoteDismiss
|
|
294
|
-
|
|
295
|
-
A button that clears the quote by calling `setQuote(undefined)`. Supports `asChild`.
|
|
296
|
-
|
|
297
|
-
### useMessageQuote()
|
|
298
|
-
|
|
299
|
-
```tsx
|
|
300
|
-
const quote: QuoteInfo | undefined = useMessageQuote();
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
Returns the quote attached to the current message, or `undefined`.
|
|
304
|
-
|
|
305
|
-
### ComposerRuntime.setQuote()
|
|
306
|
-
|
|
307
|
-
```tsx
|
|
308
|
-
setQuote(quote: QuoteInfo | undefined): void
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
Set or clear the quote on the composer. The quote is automatically cleared when the message is sent.
|
|
312
|
-
|
|
313
163
|
## Design Notes
|
|
314
164
|
|
|
315
|
-
- **Single quote
|
|
316
|
-
- **Snapshot text
|
|
317
|
-
- **Cross-message selection
|
|
318
|
-
- **Streaming messages
|
|
319
|
-
- **`isEmpty` unchanged
|
|
320
|
-
- **Scroll hides toolbar
|
|
165
|
+
- **Single quote:** `setQuote` replaces the current quote instead of appending. Only one quote can be active at a time.
|
|
166
|
+
- **Snapshot text:** The selected text is captured when the quote is created and is not linked to the source message afterward.
|
|
167
|
+
- **Cross-message selection:** The toolbar only appears when the selection stays within a single message.
|
|
168
|
+
- **Streaming messages:** The toolbar still works while a message is streaming because it relies on the captured selection rather than message status.
|
|
169
|
+
- **`isEmpty` unchanged:** A quote by itself does not make the composer non-empty. The user still needs to type a reply.
|
|
170
|
+
- **Scroll hides toolbar:** The toolbar hides on scroll because its position would otherwise become stale.
|
|
321
171
|
|
|
322
172
|
## Related
|
|
323
173
|
|
|
324
|
-
- [
|
|
325
|
-
- [
|
|
326
|
-
- [
|
|
327
|
-
- [ActionBarPrimitive](/docs/reference/primitives/ActionBar) — Action bar primitive reference
|
|
174
|
+
- [Quote component](/docs/ui/quote): Installation, component setup, and API reference
|
|
175
|
+
- [Message Editing](/docs/guides/editing): Edit user messages
|
|
176
|
+
- [Thread](/docs/ui/thread): Main chat container
|
|
@@ -21,10 +21,7 @@ Passing a `SpeechSynthesisAdapter` to the runtime will enable text-to-speech sup
|
|
|
21
21
|
|
|
22
22
|
## UI
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
This is implemented using `AssistantActionBar.SpeechControl` which is a wrapper around `AssistantActionBar.Speak` and `AssistantActionBar.StopSpeaking`.
|
|
27
|
-
The underlying primitives are `ActionBarPrimitive.Speak` and `ActionBarPrimitive.StopSpeaking`.
|
|
24
|
+
The default action bar does not include a speech button. You need to add `ActionBarPrimitive.Speak` and `ActionBarPrimitive.StopSpeaking` to your assistant message action bar manually. See the example above for a complete implementation.
|
|
28
25
|
|
|
29
26
|
## Example
|
|
30
27
|
|
|
@@ -102,11 +102,9 @@ const ThreadWelcome = () => {
|
|
|
102
102
|
|
|
103
103
|
{/* Display suggestions */}
|
|
104
104
|
<div className="grid grid-cols-2 gap-2">
|
|
105
|
-
<ThreadPrimitive.Suggestions
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}}
|
|
109
|
-
/>
|
|
105
|
+
<ThreadPrimitive.Suggestions>
|
|
106
|
+
{() => <SuggestionItem />}
|
|
107
|
+
</ThreadPrimitive.Suggestions>
|
|
110
108
|
</div>
|
|
111
109
|
</div>
|
|
112
110
|
);
|
|
@@ -135,11 +133,9 @@ const SuggestionItem = () => {
|
|
|
135
133
|
Renders all suggestions from the suggestions scope.
|
|
136
134
|
|
|
137
135
|
```tsx
|
|
138
|
-
<ThreadPrimitive.Suggestions
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}}
|
|
142
|
-
/>
|
|
136
|
+
<ThreadPrimitive.Suggestions>
|
|
137
|
+
{() => <CustomSuggestionComponent />}
|
|
138
|
+
</ThreadPrimitive.Suggestions>
|
|
143
139
|
```
|
|
144
140
|
|
|
145
141
|
### SuggestionPrimitive.Title
|
|
@@ -276,11 +272,9 @@ const aui = useAui({
|
|
|
276
272
|
2. Display suggestions using the primitives:
|
|
277
273
|
|
|
278
274
|
```tsx
|
|
279
|
-
<ThreadPrimitive.Suggestions
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}}
|
|
283
|
-
/>
|
|
275
|
+
<ThreadPrimitive.Suggestions>
|
|
276
|
+
{() => <SuggestionItem />}
|
|
277
|
+
</ThreadPrimitive.Suggestions>
|
|
284
278
|
```
|
|
285
279
|
|
|
286
280
|
The new API provides:
|
|
@@ -200,7 +200,7 @@ export async function POST(req: Request) {
|
|
|
200
200
|
|
|
201
201
|
const result = streamText({
|
|
202
202
|
model: openai("gpt-4o"),
|
|
203
|
-
messages: convertToModelMessages(messages),
|
|
203
|
+
messages: await convertToModelMessages(messages),
|
|
204
204
|
tools: {
|
|
205
205
|
getWeather: tool({
|
|
206
206
|
description: "Get current weather for a location",
|
|
@@ -275,7 +275,7 @@ export const WebSearchToolUI = makeAssistantToolUI<
|
|
|
275
275
|
Use hooks for dynamic tool UI registration:
|
|
276
276
|
|
|
277
277
|
<Callout type="tip">
|
|
278
|
-
|
|
278
|
+
Use the `useAssistantToolUI` hook directly in your component for dynamic tool UI registration. This allows access to local component state and props when rendering the tool UI.
|
|
279
279
|
</Callout>
|
|
280
280
|
|
|
281
281
|
```tsx
|
|
@@ -384,6 +384,9 @@ Build complex workflows with human-in-the-loop patterns for multi-step user inte
|
|
|
384
384
|
```tsx
|
|
385
385
|
const DeleteProjectTool = makeAssistantTool({
|
|
386
386
|
toolName: "deleteProject",
|
|
387
|
+
parameters: z.object({
|
|
388
|
+
projectId: z.string(),
|
|
389
|
+
}),
|
|
387
390
|
execute: async ({ projectId }, { human }) => {
|
|
388
391
|
const response = await human({ action, details });
|
|
389
392
|
if (!response.approved) throw new Error("Project deletion cancelled");
|
|
@@ -502,6 +505,12 @@ render: ({ status, args }) => {
|
|
|
502
505
|
|
|
503
506
|
### Field-Level Validation
|
|
504
507
|
|
|
508
|
+
<Callout type="warn">
|
|
509
|
+
`useToolArgsFieldStatus` is not currently exported from `@assistant-ui/react`.
|
|
510
|
+
The hook exists internally but is not part of the public API. This section is
|
|
511
|
+
included for reference and may become available in a future release.
|
|
512
|
+
</Callout>
|
|
513
|
+
|
|
505
514
|
Use `useToolArgsFieldStatus` to show validation states:
|
|
506
515
|
|
|
507
516
|
```tsx
|
|
@@ -510,8 +519,8 @@ import { useToolArgsFieldStatus } from "@assistant-ui/react";
|
|
|
510
519
|
const FormToolUI = makeAssistantToolUI({
|
|
511
520
|
toolName: "submitForm",
|
|
512
521
|
render: ({ args }) => {
|
|
513
|
-
const emailStatus = useToolArgsFieldStatus("email");
|
|
514
|
-
const phoneStatus = useToolArgsFieldStatus("phone");
|
|
522
|
+
const emailStatus = useToolArgsFieldStatus(["email"]);
|
|
523
|
+
const phoneStatus = useToolArgsFieldStatus(["phone"]);
|
|
515
524
|
|
|
516
525
|
return (
|
|
517
526
|
<form className="space-y-4">
|
|
@@ -611,7 +620,7 @@ Provide a custom UI for tools without specific UIs:
|
|
|
611
620
|
Generative UI components have access to execution context through props:
|
|
612
621
|
|
|
613
622
|
```tsx
|
|
614
|
-
type
|
|
623
|
+
type ToolCallMessagePartProps<TArgs, TResult> = {
|
|
615
624
|
// Tool arguments
|
|
616
625
|
args: TArgs;
|
|
617
626
|
argsText: string; // JSON stringified args
|
|
@@ -628,7 +637,7 @@ type ToolUIRenderProps<TArgs, TResult> = {
|
|
|
628
637
|
toolCallId: string;
|
|
629
638
|
|
|
630
639
|
// Interactive callbacks
|
|
631
|
-
addResult: (result: TResult) => void;
|
|
640
|
+
addResult: (result: TResult | ToolResponse<TResult>) => void;
|
|
632
641
|
resume: (payload: unknown) => void;
|
|
633
642
|
|
|
634
643
|
// Interrupt state
|
|
@@ -671,7 +680,7 @@ const ConfirmationToolUI = makeAssistantToolUI<
|
|
|
671
680
|
});
|
|
672
681
|
```
|
|
673
682
|
|
|
674
|
-
Learn more about tool human input in the [Tools Guide](/docs/guides/tools#
|
|
683
|
+
Learn more about tool human input in the [Tools Guide](/docs/guides/tools#human-in-the-loop).
|
|
675
684
|
|
|
676
685
|
## Best Practices
|
|
677
686
|
|
|
@@ -742,6 +751,7 @@ useAssistantToolUI({
|
|
|
742
751
|
## Related Guides
|
|
743
752
|
|
|
744
753
|
- [Tools Guide](/docs/guides/tools) - Learn how to create and use tools with AI models
|
|
754
|
+
- [Multi-Agent](/docs/guides/multi-agent) - Render sub-agent conversations inside tool call UIs
|
|
745
755
|
- [Tool Fallback](/docs/ui/tool-fallback) - Default UI for tools without custom components
|
|
746
756
|
- [API Reference](/docs/api-reference/primitives/message-part) - Detailed type definitions and component APIs
|
|
747
757
|
- [Message Primitive](/docs/api-reference/primitives/message) - Complete Message component documentation
|
|
@@ -92,12 +92,27 @@ function MyRuntimeProvider({ children }: { children: React.ReactNode }) {
|
|
|
92
92
|
Each tool in the toolkit is a `ToolDefinition` object with these properties:
|
|
93
93
|
|
|
94
94
|
```tsx
|
|
95
|
-
type ToolDefinition =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
type ToolDefinition =
|
|
96
|
+
| {
|
|
97
|
+
// Frontend tool: executes in the browser
|
|
98
|
+
type?: "frontend";
|
|
99
|
+
description?: string;
|
|
100
|
+
parameters: StandardSchemaV1 | JSONSchema7; // e.g. a Zod schema
|
|
101
|
+
execute: (args, context) => Promise<any>;
|
|
102
|
+
render?: (props) => React.ReactNode;
|
|
103
|
+
}
|
|
104
|
+
| {
|
|
105
|
+
// Human tool: pauses for user input (render is required)
|
|
106
|
+
type: "human";
|
|
107
|
+
description?: string;
|
|
108
|
+
parameters: StandardSchemaV1 | JSONSchema7;
|
|
109
|
+
render: (props) => React.ReactNode;
|
|
110
|
+
}
|
|
111
|
+
| {
|
|
112
|
+
// Backend tool: execution happens server-side (no execute/parameters needed)
|
|
113
|
+
type: "backend";
|
|
114
|
+
render?: (props) => React.ReactNode;
|
|
115
|
+
};
|
|
101
116
|
```
|
|
102
117
|
|
|
103
118
|
### Organizing Large Toolkits
|
|
@@ -385,7 +400,7 @@ export async function POST(req: Request) {
|
|
|
385
400
|
|
|
386
401
|
const result = streamText({
|
|
387
402
|
model: openai("gpt-4o"),
|
|
388
|
-
messages: convertToModelMessages(messages),
|
|
403
|
+
messages: await convertToModelMessages(messages),
|
|
389
404
|
tools: {
|
|
390
405
|
queryDatabase: {
|
|
391
406
|
description: "Query the application database",
|
|
@@ -447,7 +462,7 @@ export async function POST(req: Request) {
|
|
|
447
462
|
|
|
448
463
|
const result = streamText({
|
|
449
464
|
model: openai("gpt-4o"),
|
|
450
|
-
messages: convertToModelMessages(messages),
|
|
465
|
+
messages: await convertToModelMessages(messages),
|
|
451
466
|
tools: {
|
|
452
467
|
...frontendTools(tools), // Client-defined tools
|
|
453
468
|
// Additional server-side tools
|
|
@@ -487,7 +502,7 @@ export async function POST(req: Request) {
|
|
|
487
502
|
const result = streamText({
|
|
488
503
|
model: openai("gpt-4o"),
|
|
489
504
|
tools,
|
|
490
|
-
messages: convertToModelMessages(messages),
|
|
505
|
+
messages: await convertToModelMessages(messages),
|
|
491
506
|
});
|
|
492
507
|
|
|
493
508
|
return result.toUIMessageStreamResponse();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Introduction
|
|
3
|
-
description: Beautiful, enterprise-grade AI chat interfaces for React applications.
|
|
3
|
+
description: Beautiful, enterprise-grade AI chat interfaces for React, React Native, and terminal applications.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { PanelsTopLeft, Database, Terminal } from "lucide-react";
|
|
7
7
|
|
|
8
8
|
assistant-ui helps you create beautiful, enterprise-grade AI chat interfaces in minutes. Whether you're building a ChatGPT clone, a customer support chatbot, an AI assistant, or a complex multi-agent application, assistant-ui provides the frontend primitive components and state management layers to focus on what makes your application unique.
|
|
9
9
|
|
|
@@ -79,6 +79,6 @@ npx assistant-ui@latest create -t mcp
|
|
|
79
79
|
<Card
|
|
80
80
|
title="Examples"
|
|
81
81
|
description="Explore full implementations and demos"
|
|
82
|
-
href="
|
|
82
|
+
href="/examples"
|
|
83
83
|
/>
|
|
84
84
|
</Cards>
|