@assistant-ui/mcp-docs-server 0.1.3 → 0.1.4
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/local-ollama.md +7 -7
- package/.docs/organized/code-examples/search-agent-for-e-commerce.md +9 -9
- package/.docs/organized/code-examples/with-ai-sdk.md +7 -7
- package/.docs/organized/code-examples/with-cloud.md +7 -7
- package/.docs/organized/code-examples/with-external-store.md +6 -6
- package/.docs/organized/code-examples/with-ffmpeg.md +10 -10
- package/.docs/organized/code-examples/with-langgraph.md +10 -10
- package/.docs/organized/code-examples/with-openai-assistants.md +7 -7
- package/.docs/organized/code-examples/with-react-hook-form.md +10 -10
- package/.docs/organized/code-examples/with-vercel-ai-rsc.md +7 -7
- package/.docs/raw/docs/api-reference/context-providers/{TextContentPartProvider.mdx → TextMessagePartProvider.mdx} +3 -3
- package/.docs/raw/docs/api-reference/integrations/react-hook-form.mdx +2 -2
- package/.docs/raw/docs/api-reference/overview.mdx +23 -23
- package/.docs/raw/docs/api-reference/primitives/Error.mdx +5 -3
- package/.docs/raw/docs/api-reference/primitives/Message.mdx +32 -0
- package/.docs/raw/docs/api-reference/primitives/{ContentPart.mdx → MessagePart.mdx} +41 -41
- package/.docs/raw/docs/api-reference/runtimes/MessagePartRuntime.mdx +22 -0
- package/.docs/raw/docs/api-reference/runtimes/ThreadListRuntime.mdx +1 -0
- package/.docs/raw/docs/api-reference/runtimes/ThreadRuntime.mdx +1 -0
- package/.docs/raw/docs/concepts/runtime-layer.mdx +7 -7
- package/.docs/raw/docs/copilots/make-assistant-tool-ui.mdx +22 -13
- package/.docs/raw/docs/copilots/make-assistant-tool.mdx +20 -14
- package/.docs/raw/docs/getting-started.mdx +11 -10
- package/.docs/raw/docs/guides/Attachments.mdx +24 -21
- package/.docs/raw/docs/guides/ToolUI.mdx +45 -8
- package/.docs/raw/docs/migrations/v0-11.mdx +169 -0
- package/.docs/raw/docs/migrations/v0-7.mdx +8 -8
- package/.docs/raw/docs/migrations/v0-8.mdx +14 -14
- package/.docs/raw/docs/migrations/v0-9.mdx +3 -3
- package/.docs/raw/docs/runtimes/ai-sdk/rsc.mdx +2 -2
- package/.docs/raw/docs/runtimes/ai-sdk/use-assistant-hook.mdx +1 -1
- package/.docs/raw/docs/runtimes/ai-sdk/use-chat-hook.mdx +2 -2
- package/.docs/raw/docs/runtimes/ai-sdk/use-chat.mdx +2 -2
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +5 -5
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +2 -2
- package/.docs/raw/docs/ui/Attachment.mdx +5 -2
- package/.docs/raw/docs/ui/Markdown.mdx +2 -3
- package/.docs/raw/docs/ui/ToolFallback.mdx +2 -2
- package/package.json +5 -5
- package/.docs/raw/docs/api-reference/runtimes/ContentPartRuntime.mdx +0 -22
|
@@ -34,7 +34,8 @@ npx shadcn@latest add "https://r.assistant-ui.com/attachment"
|
|
|
34
34
|
This adds `/components/assistant-ui/attachment.tsx` to your project.
|
|
35
35
|
|
|
36
36
|
<Callout type="tip">
|
|
37
|
-
**Next steps:** Feel free to adjust these auto-generated components (styling,
|
|
37
|
+
**Next steps:** Feel free to adjust these auto-generated components (styling,
|
|
38
|
+
layout, behavior) to match your application's design system.
|
|
38
39
|
</Callout>
|
|
39
40
|
|
|
40
41
|
</Step>
|
|
@@ -94,7 +95,7 @@ const UserMessage = () => {
|
|
|
94
95
|
return (
|
|
95
96
|
<MessagePrimitive.Root>
|
|
96
97
|
<UserMessageAttachments />
|
|
97
|
-
<MessagePrimitive.
|
|
98
|
+
<MessagePrimitive.Parts />
|
|
98
99
|
</MessagePrimitive.Root>
|
|
99
100
|
);
|
|
100
101
|
};
|
|
@@ -242,7 +243,7 @@ class PDFAttachmentAdapter implements AttachmentAdapter {
|
|
|
242
243
|
async send(attachment: PendingAttachment): Promise<CompleteAttachment> {
|
|
243
244
|
// Option 1: Extract text from PDF (requires pdf parsing library)
|
|
244
245
|
// const text = await this.extractTextFromPDF(attachment.file);
|
|
245
|
-
|
|
246
|
+
|
|
246
247
|
// Option 2: Convert to base64 for API processing
|
|
247
248
|
const base64Data = await this.fileToBase64(attachment.file);
|
|
248
249
|
|
|
@@ -253,8 +254,8 @@ class PDFAttachmentAdapter implements AttachmentAdapter {
|
|
|
253
254
|
content: [
|
|
254
255
|
{
|
|
255
256
|
type: "text",
|
|
256
|
-
text: `[PDF Document: ${attachment.name}]\nBase64 data: ${base64Data.substring(0, 50)}
|
|
257
|
-
}
|
|
257
|
+
text: `[PDF Document: ${attachment.name}]\nBase64 data: ${base64Data.substring(0, 50)}...`,
|
|
258
|
+
},
|
|
258
259
|
],
|
|
259
260
|
status: { type: "complete" },
|
|
260
261
|
};
|
|
@@ -268,12 +269,12 @@ class PDFAttachmentAdapter implements AttachmentAdapter {
|
|
|
268
269
|
const arrayBuffer = await file.arrayBuffer();
|
|
269
270
|
const bytes = new Uint8Array(arrayBuffer);
|
|
270
271
|
let binary = "";
|
|
271
|
-
bytes.forEach(byte => {
|
|
272
|
+
bytes.forEach((byte) => {
|
|
272
273
|
binary += String.fromCharCode(byte);
|
|
273
274
|
});
|
|
274
275
|
return btoa(binary);
|
|
275
276
|
}
|
|
276
|
-
|
|
277
|
+
|
|
277
278
|
// Optional: Extract text from PDF using a library like pdf.js
|
|
278
279
|
private async extractTextFromPDF(file: File): Promise<string> {
|
|
279
280
|
// Implementation would use pdf.js or similar
|
|
@@ -296,33 +297,36 @@ import { useLocalRuntime, ChatModelAdapter } from "@assistant-ui/react";
|
|
|
296
297
|
const MyModelAdapter: ChatModelAdapter = {
|
|
297
298
|
async run({ messages, abortSignal }) {
|
|
298
299
|
// Convert messages to format expected by your vision-capable API
|
|
299
|
-
const formattedMessages = messages.map(msg => {
|
|
300
|
-
if (
|
|
300
|
+
const formattedMessages = messages.map((msg) => {
|
|
301
|
+
if (
|
|
302
|
+
msg.role === "user" &&
|
|
303
|
+
msg.content.some((part) => part.type === "image")
|
|
304
|
+
) {
|
|
301
305
|
// Format for GPT-4V or similar vision models
|
|
302
306
|
return {
|
|
303
307
|
role: "user",
|
|
304
|
-
content: msg.content.map(part => {
|
|
308
|
+
content: msg.content.map((part) => {
|
|
305
309
|
if (part.type === "text") {
|
|
306
310
|
return { type: "text", text: part.text };
|
|
307
311
|
}
|
|
308
312
|
if (part.type === "image") {
|
|
309
313
|
return {
|
|
310
314
|
type: "image_url",
|
|
311
|
-
image_url: { url: part.image }
|
|
315
|
+
image_url: { url: part.image },
|
|
312
316
|
};
|
|
313
317
|
}
|
|
314
318
|
return part;
|
|
315
|
-
})
|
|
319
|
+
}),
|
|
316
320
|
};
|
|
317
321
|
}
|
|
318
|
-
|
|
322
|
+
|
|
319
323
|
// Regular text messages
|
|
320
324
|
return {
|
|
321
325
|
role: msg.role,
|
|
322
326
|
content: msg.content
|
|
323
|
-
.filter(c => c.type === "text")
|
|
324
|
-
.map(c => c.text)
|
|
325
|
-
.join("\n")
|
|
327
|
+
.filter((c) => c.type === "text")
|
|
328
|
+
.map((c) => c.text)
|
|
329
|
+
.join("\n"),
|
|
326
330
|
};
|
|
327
331
|
});
|
|
328
332
|
|
|
@@ -343,8 +347,8 @@ const MyModelAdapter: ChatModelAdapter = {
|
|
|
343
347
|
|
|
344
348
|
// Create runtime with vision image adapter
|
|
345
349
|
const runtime = useLocalRuntime(MyModelAdapter, {
|
|
346
|
-
adapters: {
|
|
347
|
-
attachments: new VisionImageAdapter()
|
|
350
|
+
adapters: {
|
|
351
|
+
attachments: new VisionImageAdapter(),
|
|
348
352
|
},
|
|
349
353
|
});
|
|
350
354
|
```
|
|
@@ -363,12 +367,12 @@ export async function POST(req: Request) {
|
|
|
363
367
|
|
|
364
368
|
const result = streamText({
|
|
365
369
|
model: openai("gpt-4-vision-preview"),
|
|
366
|
-
messages: messages.map(msg => {
|
|
370
|
+
messages: messages.map((msg) => {
|
|
367
371
|
if (msg.experimental_attachments?.length) {
|
|
368
372
|
// Images are automatically formatted for the model
|
|
369
373
|
return {
|
|
370
374
|
...msg,
|
|
371
|
-
experimental_attachments: msg.experimental_attachments
|
|
375
|
+
experimental_attachments: msg.experimental_attachments,
|
|
372
376
|
};
|
|
373
377
|
}
|
|
374
378
|
return msg;
|
|
@@ -637,4 +641,3 @@ Attachments work with all assistant-ui runtimes:
|
|
|
637
641
|
|
|
638
642
|
- [Attachment UI Components](/docs/ui/Attachment) - UI implementation details
|
|
639
643
|
- [API Reference](/docs/api-reference) - Detailed type definitions
|
|
640
|
-
|
|
@@ -43,13 +43,13 @@ const weatherTool = tool({
|
|
|
43
43
|
execute: async ({ location, unit }) => {
|
|
44
44
|
const weather = await fetchWeatherAPI(location, unit);
|
|
45
45
|
return weather;
|
|
46
|
-
}
|
|
46
|
+
},
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
// Register the tool
|
|
50
50
|
const WeatherTool = makeAssistantTool({
|
|
51
51
|
...weatherTool,
|
|
52
|
-
toolName: "getWeather"
|
|
52
|
+
toolName: "getWeather",
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
// Create the UI
|
|
@@ -77,7 +77,8 @@ const WeatherToolUI = makeAssistantToolUI<
|
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
<Callout type="tip">
|
|
80
|
-
Tools defined with `makeAssistantTool` can be passed to your backend using the
|
|
80
|
+
Tools defined with `makeAssistantTool` can be passed to your backend using the
|
|
81
|
+
`frontendTools` utility
|
|
81
82
|
</Callout>
|
|
82
83
|
|
|
83
84
|
Learn more about creating tools in the [Tools Guide](/docs/guides/Tools).
|
|
@@ -305,8 +306,9 @@ function DynamicToolUI() {
|
|
|
305
306
|
For tools that need access to parent component props:
|
|
306
307
|
|
|
307
308
|
<Callout type="tip">
|
|
308
|
-
**Why `useInlineRender`?**
|
|
309
|
-
|
|
309
|
+
**Why `useInlineRender`?** By default, a tool UI's `render` function is
|
|
310
|
+
static. Use `useInlineRender` when your UI needs access to dynamic component
|
|
311
|
+
props (for example, to pass in an `id` or other contextual data).
|
|
310
312
|
</Callout>
|
|
311
313
|
|
|
312
314
|
```tsx
|
|
@@ -340,7 +342,9 @@ function ProductPage({ productId, productName }) {
|
|
|
340
342
|
Create tools that collect user input during execution:
|
|
341
343
|
|
|
342
344
|
<Callout type="tip">
|
|
343
|
-
**Pro tip:** Call `addResult(...)` exactly once to complete the tool call.
|
|
345
|
+
**Pro tip:** Call `addResult(...)` exactly once to complete the tool call.
|
|
346
|
+
After it's invoked, the assistant will resume the conversation with your
|
|
347
|
+
provided data.
|
|
344
348
|
</Callout>
|
|
345
349
|
|
|
346
350
|
```tsx
|
|
@@ -575,7 +579,7 @@ type ToolUIRenderProps<TArgs, TResult> = {
|
|
|
575
579
|
argsText: string; // JSON stringified args
|
|
576
580
|
|
|
577
581
|
// Execution status
|
|
578
|
-
status:
|
|
582
|
+
status: ToolCallMessagePartStatus;
|
|
579
583
|
isError?: boolean;
|
|
580
584
|
|
|
581
585
|
// Tool result (may be partial during streaming)
|
|
@@ -659,8 +663,41 @@ useAssistantToolUI({
|
|
|
659
663
|
server.
|
|
660
664
|
</Callout>
|
|
661
665
|
|
|
666
|
+
### Collapsible Tool Groups
|
|
667
|
+
|
|
668
|
+
Create collapsible sections for consecutive tool calls:
|
|
669
|
+
|
|
670
|
+
```tsx
|
|
671
|
+
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### Advanced Tool Group UI
|
|
675
|
+
|
|
676
|
+
Add progress indicators and enhanced styling:
|
|
677
|
+
|
|
678
|
+
```tsx
|
|
679
|
+
const ToolGroup = ({ startIndex, endIndex, children }) => {
|
|
680
|
+
return (
|
|
681
|
+
<details className="tool-group my-4">
|
|
682
|
+
<summary className="cursor-pointer rounded bg-gray-50 p-3 hover:bg-gray-100">
|
|
683
|
+
<span className="font-medium">
|
|
684
|
+
{endIndex - startIndex + 1} tool calls executed
|
|
685
|
+
</span>
|
|
686
|
+
<span className="ml-2 text-sm text-gray-500">
|
|
687
|
+
(#{startIndex + 1}-{endIndex + 1})
|
|
688
|
+
</span>
|
|
689
|
+
</summary>
|
|
690
|
+
<div className="mt-2 space-y-2 pl-4">{children}</div>
|
|
691
|
+
</details>
|
|
692
|
+
);
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
<Thread components={{ ToolGroup }} />;
|
|
696
|
+
```
|
|
697
|
+
|
|
662
698
|
## Related Guides
|
|
663
699
|
|
|
664
700
|
- [Tools Guide](/docs/guides/Tools) - Learn how to create and use tools with AI models
|
|
665
701
|
- [Tool Fallback](/docs/ui/ToolFallback) - Default UI for tools without custom components
|
|
666
|
-
- [API Reference](/docs/api-reference/primitives/
|
|
702
|
+
- [API Reference](/docs/api-reference/primitives/MessagePart) - Detailed type definitions and component APIs
|
|
703
|
+
- [Message Primitive](/docs/api-reference/primitives/Message) - Complete Message component documentation
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Migration to v0.11
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## ContentPart renamed to MessagePart
|
|
6
|
+
|
|
7
|
+
All ContentPart-related types, hooks, and components have been renamed to MessagePart for better semantic clarity and consistency.
|
|
8
|
+
|
|
9
|
+
### What changed
|
|
10
|
+
|
|
11
|
+
The following types and components have been renamed:
|
|
12
|
+
|
|
13
|
+
#### Core Types
|
|
14
|
+
|
|
15
|
+
- `TextContentPart` → `TextMessagePart`
|
|
16
|
+
- `ReasoningContentPart` → `ReasoningMessagePart`
|
|
17
|
+
- `SourceContentPart` → `SourceMessagePart`
|
|
18
|
+
- `ImageContentPart` → `ImageMessagePart`
|
|
19
|
+
- `FileContentPart` → `FileMessagePart`
|
|
20
|
+
- `Unstable_AudioContentPart` → `Unstable_AudioMessagePart`
|
|
21
|
+
- `ToolCallContentPart` → `ToolCallMessagePart`
|
|
22
|
+
- `ContentPartStatus` → `MessagePartStatus`
|
|
23
|
+
- `ToolCallContentPartStatus` → `ToolCallMessagePartStatus`
|
|
24
|
+
|
|
25
|
+
#### Thread Message Parts
|
|
26
|
+
|
|
27
|
+
- `ThreadUserContentPart` → `ThreadUserMessagePart`
|
|
28
|
+
- `ThreadAssistantContentPart` → `ThreadAssistantMessagePart`
|
|
29
|
+
|
|
30
|
+
#### Runtime and State Types
|
|
31
|
+
|
|
32
|
+
- `ContentPartRuntime` → `MessagePartRuntime`
|
|
33
|
+
- `ContentPartState` → `MessagePartState`
|
|
34
|
+
|
|
35
|
+
#### Hooks
|
|
36
|
+
|
|
37
|
+
- `useContentPart` → `useMessagePart`
|
|
38
|
+
- `useContentPartRuntime` → `useMessagePartRuntime`
|
|
39
|
+
- `useContentPartText` → `useMessagePartText`
|
|
40
|
+
- `useContentPartReasoning` → `useMessagePartReasoning`
|
|
41
|
+
- `useContentPartSource` → `useMessagePartSource`
|
|
42
|
+
- `useContentPartFile` → `useMessagePartFile`
|
|
43
|
+
- `useContentPartImage` → `useMessagePartImage`
|
|
44
|
+
- `useTextContentPart` → `useTextMessagePart`
|
|
45
|
+
|
|
46
|
+
#### Component Types
|
|
47
|
+
|
|
48
|
+
- `EmptyContentPartComponent` → `EmptyMessagePartComponent`
|
|
49
|
+
- `TextContentPartComponent` → `TextMessagePartComponent`
|
|
50
|
+
- `ReasoningContentPartComponent` → `ReasoningMessagePartComponent`
|
|
51
|
+
- `SourceContentPartComponent` → `SourceMessagePartComponent`
|
|
52
|
+
- `ImageContentPartComponent` → `ImageMessagePartComponent`
|
|
53
|
+
- `FileContentPartComponent` → `FileMessagePartComponent`
|
|
54
|
+
- `Unstable_AudioContentPartComponent` → `Unstable_AudioMessagePartComponent`
|
|
55
|
+
- `ToolCallContentPartComponent` → `ToolCallMessagePartComponent`
|
|
56
|
+
|
|
57
|
+
#### Props Types
|
|
58
|
+
|
|
59
|
+
- `EmptyContentPartProps` → `EmptyMessagePartProps`
|
|
60
|
+
- `TextContentPartProps` → `TextMessagePartProps`
|
|
61
|
+
- `ReasoningContentPartProps` → `ReasoningMessagePartProps`
|
|
62
|
+
- `SourceContentPartProps` → `SourceMessagePartProps`
|
|
63
|
+
- `ImageContentPartProps` → `ImageMessagePartProps`
|
|
64
|
+
- `FileContentPartProps` → `FileMessagePartProps`
|
|
65
|
+
- `Unstable_AudioContentPartProps` → `Unstable_AudioMessagePartProps`
|
|
66
|
+
- `ToolCallContentPartProps` → `ToolCallMessagePartProps`
|
|
67
|
+
|
|
68
|
+
#### Providers and Context
|
|
69
|
+
|
|
70
|
+
- `TextContentPartProvider` → `TextMessagePartProvider`
|
|
71
|
+
- `TextContentPartProviderProps` → `TextMessagePartProviderProps`
|
|
72
|
+
- `ContentPartRuntimeProvider` → `MessagePartRuntimeProvider`
|
|
73
|
+
- `ContentPartContext` → `MessagePartContext`
|
|
74
|
+
- `ContentPartContextValue` → `MessagePartContextValue`
|
|
75
|
+
|
|
76
|
+
#### Primitives
|
|
77
|
+
|
|
78
|
+
- `ContentPartPrimitive` → `MessagePartPrimitive`
|
|
79
|
+
- `ContentPartPrimitiveText` → `MessagePartPrimitiveText`
|
|
80
|
+
- `ContentPartPrimitiveImage` → `MessagePartPrimitiveImage`
|
|
81
|
+
- `ContentPartPrimitiveInProgress` → `MessagePartPrimitiveInProgress`
|
|
82
|
+
|
|
83
|
+
### MessagePrimitive.Content renamed to MessagePrimitive.Parts
|
|
84
|
+
|
|
85
|
+
The `MessagePrimitive.Content` component has been renamed to `MessagePrimitive.Parts` to better reflect its purpose of rendering message parts.
|
|
86
|
+
|
|
87
|
+
```diff
|
|
88
|
+
-<MessagePrimitive.Content components={{ Text: MyText }} />
|
|
89
|
+
+<MessagePrimitive.Parts components={{ Text: MyText }} />
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Migration
|
|
93
|
+
|
|
94
|
+
To migrate your codebase automatically, use the migration codemod:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
# IMPORTANT: make sure to commit all changes to git / create a backup before running the codemod
|
|
98
|
+
npx @assistant-ui/cli upgrade
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Or run the specific migration:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
npx @assistant-ui/cli codemod v0-11/content-part-to-message-part .
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### Manual Migration Examples
|
|
108
|
+
|
|
109
|
+
If you prefer to migrate manually, here are some examples:
|
|
110
|
+
|
|
111
|
+
**Imports:**
|
|
112
|
+
|
|
113
|
+
```diff
|
|
114
|
+
-import { TextContentPart, useContentPart, ToolCallContentPartComponent } from "@assistant-ui/react";
|
|
115
|
+
+import { TextMessagePart, useMessagePart, ToolCallMessagePartComponent } from "@assistant-ui/react";
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Type annotations:**
|
|
119
|
+
|
|
120
|
+
```diff
|
|
121
|
+
-function processContent(part: TextContentPart): void {
|
|
122
|
+
+function processContent(part: TextMessagePart): void {
|
|
123
|
+
console.log(part.text);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
-const MyTool: ToolCallContentPartComponent = ({ toolName }) => {
|
|
127
|
+
+const MyTool: ToolCallMessagePartComponent = ({ toolName }) => {
|
|
128
|
+
return <div>{toolName}</div>;
|
|
129
|
+
};
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Hooks:**
|
|
133
|
+
|
|
134
|
+
```diff
|
|
135
|
+
function MyComponent() {
|
|
136
|
+
- const part = useContentPart();
|
|
137
|
+
- const text = useContentPartText();
|
|
138
|
+
- const runtime = useContentPartRuntime();
|
|
139
|
+
+ const part = useMessagePart();
|
|
140
|
+
+ const text = useMessagePartText();
|
|
141
|
+
+ const runtime = useMessagePartRuntime();
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**JSX Components:**
|
|
147
|
+
|
|
148
|
+
```diff
|
|
149
|
+
-<ContentPartPrimitive.Text />
|
|
150
|
+
-<ContentPartPrimitive.Image />
|
|
151
|
+
+<MessagePartPrimitive.Text />
|
|
152
|
+
+<MessagePartPrimitive.Image />
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Providers:**
|
|
156
|
+
|
|
157
|
+
```diff
|
|
158
|
+
-<TextContentPartProvider text="Hello" isRunning={false}>
|
|
159
|
+
+<TextMessagePartProvider text="Hello" isRunning={false}>
|
|
160
|
+
<div>Content</div>
|
|
161
|
+
-</TextContentPartProvider>
|
|
162
|
+
+</TextMessagePartProvider>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Why this change?
|
|
166
|
+
|
|
167
|
+
The ContentPart naming was inconsistent with the rest of the codebase, where "message parts" are used throughout. This change improves semantic clarity and makes the API more intuitive by aligning terminology across the entire library.
|
|
168
|
+
|
|
169
|
+
The old ContentPart APIs continue to work but are now deprecated and will be removed in a future major version.
|
|
@@ -24,7 +24,7 @@ Component property types are now neatly organized under the component itself.
|
|
|
24
24
|
|
|
25
25
|
### `useThreadContext`, `useMessageContext`, ... replaced with direct imports of stores
|
|
26
26
|
|
|
27
|
-
`useAssistantContext`, `useThreadContext`, `useMessageContext` and `
|
|
27
|
+
`useAssistantContext`, `useThreadContext`, `useMessageContext` and `useMessagePartContext` have been removed in favor of direct exports from `@assistant-ui/react`;
|
|
28
28
|
|
|
29
29
|
```diff
|
|
30
30
|
-const { useThread } = useThreadContext();
|
|
@@ -56,7 +56,7 @@ Component property types are now neatly organized under the component itself.
|
|
|
56
56
|
```diff
|
|
57
57
|
-useSwitchToNewThread();
|
|
58
58
|
+const runtime = useAssistantRuntime()
|
|
59
|
-
+runtime.switchToNewThread();
|
|
59
|
+
+runtime.switchToNewThread();
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
### `runtime.subscribe` removed, `subscribeToMainThread` removed
|
|
@@ -106,7 +106,7 @@ The branch IDs are an internal implementation detail. The new Message Runtime AP
|
|
|
106
106
|
A few methods from `useThreadRuntime` have been moved to `useMessageRuntime()`.
|
|
107
107
|
|
|
108
108
|
- `threadRuntime.switchToBranch()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).switchToBranch()`.
|
|
109
|
-
- `threadRuntime.addToolResult()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).
|
|
109
|
+
- `threadRuntime.addToolResult()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).getMessagePartByToolCallId(toolCallId).addToolResult()`.
|
|
110
110
|
- `threadRuntime.speak()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).speak()`.
|
|
111
111
|
- `threadRuntime.submitFeedback()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).submitFeedback()`.
|
|
112
112
|
- `threadRuntime.getEditComposer()` has been removed in favor of `useThreadRuntime().getMessageById(id).getMessageByIndex(idx).composer`.
|
|
@@ -149,15 +149,15 @@ These methods have been removed.
|
|
|
149
149
|
|
|
150
150
|
`useMessageStore` has been removed in favor of `useMessageRuntime().getState()`.
|
|
151
151
|
|
|
152
|
-
##
|
|
152
|
+
## Message part Context API simplifications
|
|
153
153
|
|
|
154
|
-
### Flattened context values `
|
|
154
|
+
### Flattened context values `useMessagePart().part` -> `useMessagePart()`
|
|
155
155
|
|
|
156
|
-
`
|
|
156
|
+
`MessagePartState` is now itself a message part, so you no longer need to access the nested `useMessagePart().part` field.
|
|
157
157
|
|
|
158
158
|
```diff
|
|
159
|
-
-
|
|
160
|
-
+
|
|
159
|
+
-useMessagePart(c => c.part.type);
|
|
160
|
+
+useMessagePart(c => c.type);
|
|
161
161
|
```
|
|
162
162
|
|
|
163
163
|
This also applies to tool UI render functions:
|
|
@@ -27,10 +27,10 @@ import { RSCDisplay } from "@assistant-ui/react-ai-sdk";
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
// if you are using unstyled primitives, update MyThread.tsx
|
|
30
|
-
<MessagePrimitive.
|
|
30
|
+
<MessagePrimitive.Parts components={{ Text: RSCDisplay }} />
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
## Migrate away from
|
|
33
|
+
## Migrate away from UIMessagePart
|
|
34
34
|
|
|
35
35
|
For instructions on migrating for Vercel AI SDK RSC, see section above.
|
|
36
36
|
This migration guide is for users of `useExternalStoreRuntime`.
|
|
@@ -40,13 +40,13 @@ This migration guide is for users of `useExternalStoreRuntime`.
|
|
|
40
40
|
First, reconsider your approach.
|
|
41
41
|
|
|
42
42
|
Creating UI components in the `convertMessage` callback is considered an anti-pattern.
|
|
43
|
-
The recommended alternative approach is to pass tool-call
|
|
43
|
+
The recommended alternative approach is to pass tool-call message parts, and use `makeAssistantToolUI` to map these tool calls to UI components.
|
|
44
44
|
|
|
45
45
|
This ensures that the data layer is separate and decoupled from the UI layer.
|
|
46
46
|
|
|
47
47
|
#### Example
|
|
48
48
|
|
|
49
|
-
Consider the following example, where you are using a
|
|
49
|
+
Consider the following example, where you are using a UIMessagePart to show a loading indicator.
|
|
50
50
|
|
|
51
51
|
```ts title="bad.ts"
|
|
52
52
|
// THIS IS BAD
|
|
@@ -66,11 +66,11 @@ const convertMessage = (message: MyMessage): ThreadMessageLike => {
|
|
|
66
66
|
// ...
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
// use the empty
|
|
69
|
+
// use the empty message part to show the loading indicator
|
|
70
70
|
<Thread assistantMessage={{ components: { Empty: MyLoader } }} />;
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
(if you are using unstyled primitives, update MyThread.tsx, and pass the component to MessagePrimitive.
|
|
73
|
+
(if you are using unstyled primitives, update MyThread.tsx, and pass the component to MessagePrimitive.Parts)
|
|
74
74
|
|
|
75
75
|
#### Example 2
|
|
76
76
|
|
|
@@ -107,13 +107,13 @@ const ChartToolUI = makeAssistantToolUI({
|
|
|
107
107
|
|
|
108
108
|
(if you are using unstyled primitives, render the `<ChartToolUI />` component anywhere inside your AssistantRuntimeProvider)
|
|
109
109
|
|
|
110
|
-
### Fallback Approach: Override
|
|
110
|
+
### Fallback Approach: Override MessagePartText
|
|
111
111
|
|
|
112
112
|
However, sometimes you receive UI components from an external source.
|
|
113
113
|
|
|
114
114
|
The example below assumes that your custom `MyMessage` type has a `display` field.
|
|
115
115
|
|
|
116
|
-
First, we define a dummy `UI_PLACEHOLDER`
|
|
116
|
+
First, we define a dummy `UI_PLACEHOLDER` message part, which we will replace with the UI component later:
|
|
117
117
|
|
|
118
118
|
```ts
|
|
119
119
|
const UI_PLACEHOLDER = Object.freeze({
|
|
@@ -122,17 +122,17 @@ const UI_PLACEHOLDER = Object.freeze({
|
|
|
122
122
|
});
|
|
123
123
|
const convertMessage = (message: MyMessage): ThreadMessageLike => ({
|
|
124
124
|
content: [
|
|
125
|
-
// other
|
|
125
|
+
// other message parts,
|
|
126
126
|
UI_PLACEHOLDER,
|
|
127
127
|
],
|
|
128
128
|
});
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
Then, we define a custom `
|
|
131
|
+
Then, we define a custom `TextMessagePartComponent`:
|
|
132
132
|
|
|
133
133
|
```tsx
|
|
134
|
-
const MyText:
|
|
135
|
-
const isUIPlaceholder =
|
|
134
|
+
const MyText: TextMessagePartComponent = () => {
|
|
135
|
+
const isUIPlaceholder = useMessagePart((p) => p === UI_PLACEHOLDER);
|
|
136
136
|
|
|
137
137
|
// this assumes that you have a `display` field on your original message objects before conversion.
|
|
138
138
|
const ui = useMessage((m) =>
|
|
@@ -155,6 +155,6 @@ We pass this component to our Thread:
|
|
|
155
155
|
/>
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
(if you are using unstyled primitives, update MyThread.tsx, and pass the component to MessagePrimitive.
|
|
158
|
+
(if you are using unstyled primitives, update MyThread.tsx, and pass the component to MessagePrimitive.Parts)
|
|
159
159
|
|
|
160
|
-
Now, the `UI_PLACEHOLDER`
|
|
160
|
+
Now, the `UI_PLACEHOLDER` message part is replaced with the UI component we defined earlier.
|
|
@@ -23,9 +23,9 @@ The following components and types have been moved to `@assistant-ui/react-edge`
|
|
|
23
23
|
- `CoreUserMessage`
|
|
24
24
|
- `CoreAssistantMessage`
|
|
25
25
|
- `CoreSystemMessage`
|
|
26
|
-
- `
|
|
27
|
-
- `
|
|
28
|
-
- `
|
|
26
|
+
- `CoreUserMessagePart`
|
|
27
|
+
- `CoreAssistantMessagePart`
|
|
28
|
+
- `CoreToolCallMessagePart`
|
|
29
29
|
- Core message converters
|
|
30
30
|
- `fromCoreMessages`
|
|
31
31
|
- `fromCoreMessage`
|
|
@@ -206,10 +206,10 @@ export default function RootLayout({
|
|
|
206
206
|
|
|
207
207
|
## Set up RSCDisplay
|
|
208
208
|
|
|
209
|
-
Pass the `RSCDisplay` component to your `MessagePrimitive.
|
|
209
|
+
Pass the `RSCDisplay` component to your `MessagePrimitive.Parts`:
|
|
210
210
|
|
|
211
211
|
```tsx
|
|
212
|
-
<MessagePrimitive.
|
|
212
|
+
<MessagePrimitive.Parts components={{ Text: RSCDisplay }} />
|
|
213
213
|
```
|
|
214
214
|
|
|
215
215
|
(if you are using react-ui: `<Thread assistantMessage={{ components: { Text: RSCDisplay } }} />`)
|
|
@@ -188,7 +188,7 @@ const MyAssistantMessage = () => {
|
|
|
188
188
|
|
|
189
189
|
const WeatherToolUI = makeAssistantToolUI({
|
|
190
190
|
render: () => {
|
|
191
|
-
const aiSDKMessage =
|
|
191
|
+
const aiSDKMessage = useMessagePart((p) => getExternalStoreMessages(p)[0]);
|
|
192
192
|
// ...
|
|
193
193
|
},
|
|
194
194
|
});
|
|
@@ -131,8 +131,8 @@ const MyAssistantMessage = () => {
|
|
|
131
131
|
|
|
132
132
|
const WeatherToolUI = makeAssistantToolUI({
|
|
133
133
|
render: () => {
|
|
134
|
-
const aiSDKMessage =
|
|
134
|
+
const aiSDKMessage = useMessagePart((p) => getExternalStoreMessages(p)[0]);
|
|
135
135
|
// ...
|
|
136
136
|
},
|
|
137
137
|
});
|
|
138
|
-
```
|
|
138
|
+
```
|
|
@@ -129,8 +129,8 @@ const MyAssistantMessage = () => {
|
|
|
129
129
|
|
|
130
130
|
const WeatherToolUI = makeAssistantToolUI({
|
|
131
131
|
render: () => {
|
|
132
|
-
const aiSDKMessage =
|
|
132
|
+
const aiSDKMessage = useMessagePart((p) => getExternalStoreMessages(p)[0]);
|
|
133
133
|
// ...
|
|
134
134
|
},
|
|
135
135
|
});
|
|
136
|
-
```
|
|
136
|
+
```
|
|
@@ -1144,13 +1144,13 @@ const MyComponent = () => {
|
|
|
1144
1144
|
messages for display.
|
|
1145
1145
|
</Callout>
|
|
1146
1146
|
|
|
1147
|
-
###
|
|
1147
|
+
### Message part Access
|
|
1148
1148
|
|
|
1149
1149
|
```tsx
|
|
1150
1150
|
const ToolUI = makeAssistantToolUI({
|
|
1151
1151
|
render: () => {
|
|
1152
|
-
const originalMessages =
|
|
1153
|
-
// Access original message data for this
|
|
1152
|
+
const originalMessages = useMessagePart((p) => getExternalStoreMessages(p));
|
|
1153
|
+
// Access original message data for this message part
|
|
1154
1154
|
},
|
|
1155
1155
|
});
|
|
1156
1156
|
```
|
|
@@ -1500,8 +1500,8 @@ A flexible message format that can be converted to assistant-ui's internal forma
|
|
|
1500
1500
|
},
|
|
1501
1501
|
{
|
|
1502
1502
|
name: "content",
|
|
1503
|
-
type: "string | readonly
|
|
1504
|
-
description: "Message content as string or structured
|
|
1503
|
+
type: "string | readonly MessagePart[]",
|
|
1504
|
+
description: "Message content as string or structured message parts",
|
|
1505
1505
|
required: true,
|
|
1506
1506
|
},
|
|
1507
1507
|
{
|
|
@@ -273,12 +273,12 @@ npx shadcn@latest add button
|
|
|
273
273
|
Then create a new file under `/components/tools/ToolFallback.tsx` to define the fallback UI.
|
|
274
274
|
|
|
275
275
|
```tsx title="@/components/tools/ToolFallback.tsx"
|
|
276
|
-
import {
|
|
276
|
+
import { ToolCallMessagePartComponent } from "@assistant-ui/react";
|
|
277
277
|
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
|
278
278
|
import { useState } from "react";
|
|
279
279
|
import { Button } from "../ui/button";
|
|
280
280
|
|
|
281
|
-
export const ToolFallback:
|
|
281
|
+
export const ToolFallback: ToolCallMessagePartComponent = ({
|
|
282
282
|
toolName,
|
|
283
283
|
argsText,
|
|
284
284
|
result,
|
|
@@ -13,7 +13,10 @@ The Attachment components let the user attach files and view the attachments.
|
|
|
13
13
|
<AttachmentSample />
|
|
14
14
|
|
|
15
15
|
<Callout type="info">
|
|
16
|
-
**Note:** These components provide the UI for attachments, but you also need
|
|
16
|
+
**Note:** These components provide the UI for attachments, but you also need
|
|
17
|
+
to configure attachment adapters in your runtime to handle file uploads and
|
|
18
|
+
processing. See the [Attachments Guide](/docs/guides/Attachments) for complete
|
|
19
|
+
setup instructions.
|
|
17
20
|
</Callout>
|
|
18
21
|
|
|
19
22
|
## Getting Started
|
|
@@ -69,7 +72,7 @@ const UserMessage: FC = () => {
|
|
|
69
72
|
<UserMessageAttachments />
|
|
70
73
|
|
|
71
74
|
<div className="...">
|
|
72
|
-
<MessagePrimitive.
|
|
75
|
+
<MessagePrimitive.Parts />
|
|
73
76
|
</div>
|
|
74
77
|
|
|
75
78
|
<BranchPicker className="..." />
|