@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.
- package/.docs/organized/code-examples/waterfall.md +8 -6
- package/.docs/organized/code-examples/with-a2a.md +676 -0
- package/.docs/organized/code-examples/with-ag-ui.md +10 -11
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +31 -19
- package/.docs/organized/code-examples/with-artifacts.md +8 -8
- package/.docs/organized/code-examples/with-assistant-transport.md +6 -6
- package/.docs/organized/code-examples/with-chain-of-thought.md +37 -29
- package/.docs/organized/code-examples/with-cloud-standalone.md +14 -11
- package/.docs/organized/code-examples/with-cloud.md +8 -8
- package/.docs/organized/code-examples/with-custom-thread-list.md +10 -10
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +11 -11
- package/.docs/organized/code-examples/with-expo.md +571 -520
- package/.docs/organized/code-examples/with-external-store.md +6 -6
- package/.docs/organized/code-examples/with-ffmpeg.md +8 -8
- 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-interactables.md +778 -0
- package/.docs/organized/code-examples/with-langgraph.md +28 -26
- package/.docs/organized/code-examples/with-parent-id-grouping.md +7 -7
- package/.docs/organized/code-examples/with-react-hook-form.md +9 -9
- package/.docs/organized/code-examples/with-react-ink.md +265 -0
- package/.docs/organized/code-examples/with-react-router.md +12 -12
- package/.docs/organized/code-examples/with-store.md +33 -22
- package/.docs/organized/code-examples/with-tanstack.md +10 -10
- package/.docs/organized/code-examples/with-tap-runtime.md +12 -10
- package/.docs/raw/blog/2025-01-31-changelog/index.mdx +1 -1
- package/.docs/raw/blog/2026-03-launch-week/index.mdx +258 -0
- package/.docs/raw/docs/(docs)/architecture.mdx +1 -1
- package/.docs/raw/docs/(docs)/cli.mdx +74 -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 +74 -15
- 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/interactables.mdx +292 -0
- package/.docs/raw/docs/(docs)/guides/latex.mdx +3 -0
- package/.docs/raw/docs/(docs)/guides/message-timing.mdx +5 -4
- package/.docs/raw/docs/(docs)/guides/multi-agent.mdx +174 -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 +226 -44
- 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 +90 -6
- package/.docs/raw/docs/cloud/ai-sdk.mdx +95 -5
- 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 +840 -0
- package/.docs/raw/docs/primitives/action-bar.mdx +351 -0
- package/.docs/raw/docs/primitives/assistant-modal.mdx +215 -0
- package/.docs/raw/docs/primitives/attachment.mdx +216 -0
- package/.docs/raw/docs/primitives/branch-picker.mdx +221 -0
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +311 -0
- package/.docs/raw/docs/primitives/composer.mdx +526 -0
- package/.docs/raw/docs/primitives/error.mdx +141 -0
- package/.docs/raw/docs/primitives/index.mdx +98 -0
- package/.docs/raw/docs/primitives/message.mdx +524 -0
- package/.docs/raw/docs/primitives/selection-toolbar.mdx +165 -0
- package/.docs/raw/docs/primitives/suggestion.mdx +242 -0
- package/.docs/raw/docs/primitives/thread-list.mdx +404 -0
- package/.docs/raw/docs/primitives/thread.mdx +482 -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/mention.mdx +168 -0
- 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 +5 -5
- 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
|
@@ -94,14 +94,31 @@ const UserMessage = () => {
|
|
|
94
94
|
|
|
95
95
|
## Built-in Attachment Adapters
|
|
96
96
|
|
|
97
|
+
### AI SDK Runtime (Default)
|
|
98
|
+
|
|
99
|
+
When using `useChatRuntime`, the built-in adapter accepts all file types and converts them to base64 data URLs. This works well for images and small files.
|
|
100
|
+
|
|
101
|
+
<Callout type="warn">
|
|
102
|
+
Most models only support **image** attachments. Sending unsupported file types (audio, video, PDF, etc.) will result in an API error. Check your model provider's documentation for supported input types.
|
|
103
|
+
</Callout>
|
|
104
|
+
|
|
105
|
+
To restrict accepted file types, pass a custom adapter:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
const runtime = useChatRuntime({
|
|
109
|
+
adapters: {
|
|
110
|
+
attachments: new SimpleImageAttachmentAdapter(), // only images
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
97
115
|
### SimpleImageAttachmentAdapter
|
|
98
116
|
|
|
99
|
-
Handles image files and converts them to data URLs for display in the chat UI.
|
|
117
|
+
Handles image files and converts them to data URLs for display in the chat UI.
|
|
100
118
|
|
|
101
119
|
```tsx
|
|
102
120
|
const imageAdapter = new SimpleImageAttachmentAdapter();
|
|
103
121
|
// Accepts: image/* (JPEG, PNG, GIF, etc.)
|
|
104
|
-
// Output: { type: "image", url: "data:image/..." }
|
|
105
122
|
```
|
|
106
123
|
|
|
107
124
|
### SimpleTextAttachmentAdapter
|
|
@@ -111,7 +128,6 @@ Processes text files and wraps content in formatted tags:
|
|
|
111
128
|
```tsx
|
|
112
129
|
const textAdapter = new SimpleTextAttachmentAdapter();
|
|
113
130
|
// Accepts: text/plain, text/html, text/markdown, etc.
|
|
114
|
-
// Output: Content wrapped in <attachment>...</attachment> tags
|
|
115
131
|
```
|
|
116
132
|
|
|
117
133
|
### CompositeAttachmentAdapter
|
|
@@ -122,7 +138,6 @@ Combines multiple adapters to support various file types:
|
|
|
122
138
|
const compositeAdapter = new CompositeAttachmentAdapter([
|
|
123
139
|
new SimpleImageAttachmentAdapter(),
|
|
124
140
|
new SimpleTextAttachmentAdapter(),
|
|
125
|
-
// Add more adapters as needed
|
|
126
141
|
]);
|
|
127
142
|
```
|
|
128
143
|
|
|
@@ -157,7 +172,7 @@ class VisionImageAdapter implements AttachmentAdapter {
|
|
|
157
172
|
type: "image",
|
|
158
173
|
name: file.name,
|
|
159
174
|
file,
|
|
160
|
-
status: { type: "
|
|
175
|
+
status: { type: "requires-action", reason: "composer-send" },
|
|
161
176
|
};
|
|
162
177
|
}
|
|
163
178
|
|
|
@@ -224,7 +239,7 @@ class PDFAttachmentAdapter implements AttachmentAdapter {
|
|
|
224
239
|
type: "document",
|
|
225
240
|
name: file.name,
|
|
226
241
|
file,
|
|
227
|
-
status: { type: "
|
|
242
|
+
status: { type: "requires-action", reason: "composer-send" },
|
|
228
243
|
};
|
|
229
244
|
}
|
|
230
245
|
|
|
@@ -360,7 +375,7 @@ class UploadAttachmentAdapter implements AttachmentAdapter {
|
|
|
360
375
|
type: "file",
|
|
361
376
|
name: file.name,
|
|
362
377
|
file,
|
|
363
|
-
status: { type: "running", progress: 0 },
|
|
378
|
+
status: { type: "running", reason: "uploading", progress: 0 },
|
|
364
379
|
} as PendingAttachment;
|
|
365
380
|
|
|
366
381
|
// Simulate upload progress
|
|
@@ -372,7 +387,7 @@ class UploadAttachmentAdapter implements AttachmentAdapter {
|
|
|
372
387
|
type: "file",
|
|
373
388
|
name: file.name,
|
|
374
389
|
file,
|
|
375
|
-
status: { type: "running", progress },
|
|
390
|
+
status: { type: "running", reason: "uploading", progress },
|
|
376
391
|
} as PendingAttachment;
|
|
377
392
|
}
|
|
378
393
|
|
|
@@ -382,7 +397,7 @@ class UploadAttachmentAdapter implements AttachmentAdapter {
|
|
|
382
397
|
type: "file",
|
|
383
398
|
name: file.name,
|
|
384
399
|
file,
|
|
385
|
-
status: { type: "running", progress: 100 },
|
|
400
|
+
status: { type: "running", reason: "uploading", progress: 100 },
|
|
386
401
|
} as PendingAttachment;
|
|
387
402
|
}
|
|
388
403
|
|
|
@@ -436,7 +451,6 @@ class ValidatedImageAdapter implements AttachmentAdapter {
|
|
|
436
451
|
status: {
|
|
437
452
|
type: "incomplete",
|
|
438
453
|
reason: "error",
|
|
439
|
-
error: new Error("File size exceeds 5MB limit"),
|
|
440
454
|
},
|
|
441
455
|
};
|
|
442
456
|
}
|
|
@@ -456,7 +470,6 @@ class ValidatedImageAdapter implements AttachmentAdapter {
|
|
|
456
470
|
status: {
|
|
457
471
|
type: "incomplete",
|
|
458
472
|
reason: "error",
|
|
459
|
-
error,
|
|
460
473
|
},
|
|
461
474
|
};
|
|
462
475
|
}
|
|
@@ -467,7 +480,7 @@ class ValidatedImageAdapter implements AttachmentAdapter {
|
|
|
467
480
|
type: "image",
|
|
468
481
|
name: file.name,
|
|
469
482
|
file,
|
|
470
|
-
status: { type: "
|
|
483
|
+
status: { type: "requires-action", reason: "composer-send" },
|
|
471
484
|
};
|
|
472
485
|
}
|
|
473
486
|
|
|
@@ -514,7 +527,7 @@ const handleMultipleFiles = async (files: FileList) => {
|
|
|
514
527
|
const filesToAdd = Array.from(files).slice(0, maxFiles);
|
|
515
528
|
|
|
516
529
|
for (const file of filesToAdd) {
|
|
517
|
-
await aui.composer().addAttachment(
|
|
530
|
+
await aui.composer().addAttachment(file);
|
|
518
531
|
}
|
|
519
532
|
};
|
|
520
533
|
```
|
|
@@ -529,7 +542,7 @@ Attachments are sent to the backend as file content parts.
|
|
|
529
542
|
|
|
530
543
|
Attachments work with all assistant-ui runtimes:
|
|
531
544
|
|
|
532
|
-
- **AI SDK Runtime**: `useChatRuntime
|
|
545
|
+
- **AI SDK Runtime**: `useChatRuntime`
|
|
533
546
|
- **External Store**: `useExternalStoreRuntime`
|
|
534
547
|
- **LangGraph**: `useLangGraphRuntime`
|
|
535
548
|
- **Custom Runtimes**: Any runtime implementing the attachment interface
|
|
@@ -540,6 +553,52 @@ Attachments work with all assistant-ui runtimes:
|
|
|
540
553
|
processing logic to fit your specific needs.
|
|
541
554
|
</Callout>
|
|
542
555
|
|
|
556
|
+
## Large File Uploads
|
|
557
|
+
|
|
558
|
+
The built-in adapters convert files to base64 data URLs in memory. For large files (long audio, video, etc.), this can cause performance issues. Instead, upload to a server and pass the URL:
|
|
559
|
+
|
|
560
|
+
```tsx
|
|
561
|
+
class ServerUploadAdapter implements AttachmentAdapter {
|
|
562
|
+
accept = "*";
|
|
563
|
+
private urls = new Map<string, string>();
|
|
564
|
+
|
|
565
|
+
async *add({ file }: { file: File }) {
|
|
566
|
+
const id = crypto.randomUUID();
|
|
567
|
+
yield {
|
|
568
|
+
id, type: "file" as const, name: file.name, file,
|
|
569
|
+
contentType: file.type,
|
|
570
|
+
status: { type: "running" as const, reason: "uploading" as const, progress: 0 },
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
const form = new FormData();
|
|
574
|
+
form.append("file", file);
|
|
575
|
+
const { url } = await fetch("/api/upload", { method: "POST", body: form }).then(r => r.json());
|
|
576
|
+
this.urls.set(id, url);
|
|
577
|
+
|
|
578
|
+
yield {
|
|
579
|
+
id, type: "file" as const, name: file.name, file,
|
|
580
|
+
contentType: file.type,
|
|
581
|
+
status: { type: "requires-action" as const, reason: "composer-send" as const },
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
async send(attachment: PendingAttachment): Promise<CompleteAttachment> {
|
|
586
|
+
const url = this.urls.get(attachment.id)!;
|
|
587
|
+
this.urls.delete(attachment.id);
|
|
588
|
+
return {
|
|
589
|
+
...attachment, status: { type: "complete" },
|
|
590
|
+
content: [{ type: "file", data: url, mimeType: attachment.contentType ?? "", filename: attachment.name }],
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
async remove() {}
|
|
595
|
+
}
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
<Callout type="tip">
|
|
599
|
+
[assistant-ui Cloud](/docs/cloud/ai-sdk-assistant-ui) includes `CloudFileAttachmentAdapter` which handles large file uploads via presigned URLs out of the box.
|
|
600
|
+
</Callout>
|
|
601
|
+
|
|
543
602
|
## Best Practices
|
|
544
603
|
|
|
545
604
|
1. **File Size Limits**: Always validate file sizes to prevent memory issues
|
|
@@ -552,4 +611,4 @@ Attachments work with all assistant-ui runtimes:
|
|
|
552
611
|
## Resources
|
|
553
612
|
|
|
554
613
|
- [Attachment UI Components](/docs/ui/attachment) - UI implementation details
|
|
555
|
-
- [API Reference](/docs/api-reference) - Detailed type definitions
|
|
614
|
+
- [API Reference](/docs/api-reference/overview) - Detailed type definitions
|
|
@@ -30,7 +30,7 @@ const Message = () => {
|
|
|
30
30
|
...
|
|
31
31
|
<BranchPicker /> {/* <-- show the branch picker */}
|
|
32
32
|
...
|
|
33
|
-
</
|
|
33
|
+
</MessagePrimitive.Root>
|
|
34
34
|
);
|
|
35
35
|
};
|
|
36
36
|
|
|
@@ -48,13 +48,18 @@ const BranchPicker = () => {
|
|
|
48
48
|
|
|
49
49
|
## API
|
|
50
50
|
|
|
51
|
-
You can access the current branch state or navigate via the API as well.
|
|
52
|
-
These APIs rely on the message
|
|
51
|
+
You can access the current branch state or navigate via the API as well.
|
|
52
|
+
These APIs rely on the message scope and may only be called inside a message component.
|
|
53
53
|
|
|
54
54
|
```tsx
|
|
55
|
-
|
|
55
|
+
import { useAui, useAuiState } from "@assistant-ui/react";
|
|
56
|
+
|
|
57
|
+
// read branch state
|
|
58
|
+
const { branchNumber, branchCount } = useAuiState((s) => s.message);
|
|
56
59
|
|
|
57
60
|
// navigation
|
|
58
|
-
const
|
|
59
|
-
|
|
61
|
+
const aui = useAui();
|
|
62
|
+
aui.message().switchToBranch({ position: "next" });
|
|
63
|
+
aui.message().switchToBranch({ position: "previous" });
|
|
64
|
+
aui.message().switchToBranch({ branchId: "some-id" });
|
|
60
65
|
```
|
|
@@ -47,9 +47,13 @@ const ChainOfThought: FC = () => {
|
|
|
47
47
|
Thinking
|
|
48
48
|
</ChainOfThoughtPrimitive.AccordionTrigger>
|
|
49
49
|
<AuiIf condition={(s) => !s.chainOfThought.collapsed}>
|
|
50
|
-
<ChainOfThoughtPrimitive.Parts
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
<ChainOfThoughtPrimitive.Parts>
|
|
51
|
+
{({ part }) => {
|
|
52
|
+
if (part.type === "reasoning") return <Reasoning {...part} />;
|
|
53
|
+
if (part.type === "tool-call") return <ToolFallback {...part} />;
|
|
54
|
+
return null;
|
|
55
|
+
}}
|
|
56
|
+
</ChainOfThoughtPrimitive.Parts>
|
|
53
57
|
</AuiIf>
|
|
54
58
|
</ChainOfThoughtPrimitive.Root>
|
|
55
59
|
);
|
|
@@ -58,12 +62,12 @@ const ChainOfThought: FC = () => {
|
|
|
58
62
|
const AssistantMessage: FC = () => {
|
|
59
63
|
return (
|
|
60
64
|
<MessagePrimitive.Root>
|
|
61
|
-
<MessagePrimitive.Parts
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
<MessagePrimitive.Parts>
|
|
66
|
+
{({ part }) => {
|
|
67
|
+
if (part.type === "text") return <MarkdownText />;
|
|
68
|
+
return null;
|
|
65
69
|
}}
|
|
66
|
-
|
|
70
|
+
</MessagePrimitive.Parts>
|
|
67
71
|
</MessagePrimitive.Root>
|
|
68
72
|
);
|
|
69
73
|
};
|
|
@@ -111,15 +115,13 @@ Renders the grouped parts when expanded (nothing when collapsed).
|
|
|
111
115
|
|
|
112
116
|
```tsx
|
|
113
117
|
<AuiIf condition={(s) => !s.chainOfThought.collapsed}>
|
|
114
|
-
<ChainOfThoughtPrimitive.Parts
|
|
115
|
-
|
|
116
|
-
Reasoning
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
<div className="border-l-2 border-muted pl-4">{children}</div>
|
|
120
|
-
),
|
|
118
|
+
<ChainOfThoughtPrimitive.Parts>
|
|
119
|
+
{({ part }) => {
|
|
120
|
+
if (part.type === "reasoning") return <Reasoning {...part} />;
|
|
121
|
+
if (part.type === "tool-call") return <ToolFallback {...part} />;
|
|
122
|
+
return null;
|
|
121
123
|
}}
|
|
122
|
-
|
|
124
|
+
</ChainOfThoughtPrimitive.Parts>
|
|
123
125
|
</AuiIf>
|
|
124
126
|
```
|
|
125
127
|
|
|
@@ -30,13 +30,18 @@ assistant-ui organizes state into **scopes** - logical boundaries that provide a
|
|
|
30
30
|
└── 💬 Thread (thread) - Active conversation with messages
|
|
31
31
|
├── 🔵 Message (message) - User or assistant message
|
|
32
32
|
│ ├── 📝 Part (part) - Content within a message (text, tool calls, etc.)
|
|
33
|
+
│ ├── 🧠 ChainOfThought (chainOfThought) - Reasoning steps within a message
|
|
34
|
+
│ │ └── 📝 Part (part) - Individual reasoning/tool-call step
|
|
33
35
|
│ ├── 📎 Attachment (attachment) - Files attached to messages
|
|
34
36
|
│ └── ✏️ Composer (composer) - Edit mode for existing messages
|
|
35
37
|
│ └── 📎 Attachment (attachment) - Files in edit mode
|
|
36
38
|
└── ✏️ Composer (composer) - New message input
|
|
37
39
|
└── 📎 Attachment (attachment) - Files being added
|
|
38
40
|
|
|
41
|
+
💡 Suggestions (suggestions) - Follow-up message suggestions
|
|
42
|
+
└── 💬 Suggestion (suggestion) - Individual suggestion item
|
|
39
43
|
🔧 Tools (tools) - Custom UI components for tool calls
|
|
44
|
+
🧩 ModelContext (modelContext) - Model context and tool registration
|
|
40
45
|
```
|
|
41
46
|
|
|
42
47
|
**How scopes work:**
|
|
@@ -166,12 +171,12 @@ The API object is stable and doesn't cause re-renders. Use it for:
|
|
|
166
171
|
// Thread actions
|
|
167
172
|
aui.thread().append(message);
|
|
168
173
|
aui.thread().startRun(config);
|
|
174
|
+
aui.thread().resumeRun(config);
|
|
169
175
|
aui.thread().cancelRun();
|
|
170
|
-
aui.thread().switchToNewThread();
|
|
171
|
-
aui.thread().switchToThread(threadId);
|
|
172
176
|
aui.thread().getState();
|
|
173
|
-
aui.thread().message(
|
|
174
|
-
aui.thread().
|
|
177
|
+
aui.thread().message({ index: idx });
|
|
178
|
+
aui.thread().message({ id: messageId });
|
|
179
|
+
aui.thread().composer();
|
|
175
180
|
|
|
176
181
|
// Message actions
|
|
177
182
|
aui.message().reload();
|
|
@@ -180,12 +185,14 @@ aui.message().stopSpeaking();
|
|
|
180
185
|
aui.message().submitFeedback({ type: "positive" | "negative" });
|
|
181
186
|
aui.message().switchToBranch({ position, branchId });
|
|
182
187
|
aui.message().getState();
|
|
183
|
-
aui.message().part(
|
|
184
|
-
aui.message().
|
|
188
|
+
aui.message().part({ index: idx });
|
|
189
|
+
aui.message().part({ toolCallId });
|
|
190
|
+
aui.message().composer();
|
|
185
191
|
|
|
186
192
|
// Part actions
|
|
187
|
-
|
|
188
|
-
|
|
193
|
+
aui.part().addToolResult(result);
|
|
194
|
+
aui.part().resumeToolCall(result);
|
|
195
|
+
aui.part().getState();
|
|
189
196
|
|
|
190
197
|
// Composer actions
|
|
191
198
|
aui.composer().send();
|
|
@@ -193,8 +200,8 @@ aui.composer().setText(text);
|
|
|
193
200
|
aui.composer().setRole(role);
|
|
194
201
|
aui.composer().addAttachment(file); // File object
|
|
195
202
|
aui.composer().addAttachment({ name, content }); // external source
|
|
196
|
-
aui.composer().clearAttachments();
|
|
197
|
-
aui.composer().reset();
|
|
203
|
+
await aui.composer().clearAttachments();
|
|
204
|
+
await aui.composer().reset();
|
|
198
205
|
aui.composer().getState();
|
|
199
206
|
|
|
200
207
|
// Attachment actions
|
|
@@ -212,7 +219,23 @@ aui.threadListItem().rename(title);
|
|
|
212
219
|
aui.threadListItem().archive();
|
|
213
220
|
aui.threadListItem().unarchive();
|
|
214
221
|
aui.threadListItem().delete();
|
|
215
|
-
aui.
|
|
222
|
+
aui.threadListItem().getState();
|
|
223
|
+
|
|
224
|
+
// Suggestions actions
|
|
225
|
+
aui.suggestions().getState();
|
|
226
|
+
aui.suggestions().suggestion({ index: 0 });
|
|
227
|
+
|
|
228
|
+
// Suggestion actions
|
|
229
|
+
aui.suggestion().getState();
|
|
230
|
+
|
|
231
|
+
// ChainOfThought actions
|
|
232
|
+
aui.chainOfThought().getState();
|
|
233
|
+
aui.chainOfThought().setCollapsed(collapsed);
|
|
234
|
+
aui.chainOfThought().part({ index: 0 });
|
|
235
|
+
|
|
236
|
+
// ModelContext actions
|
|
237
|
+
aui.modelContext().getState();
|
|
238
|
+
aui.modelContext().register(provider);
|
|
216
239
|
|
|
217
240
|
// Tools actions
|
|
218
241
|
aui.tools().setToolUI(toolName, render);
|
|
@@ -228,26 +251,29 @@ import { useAuiEvent } from "@assistant-ui/react";
|
|
|
228
251
|
|
|
229
252
|
// Listen to current scope events (most common)
|
|
230
253
|
useAuiEvent("composer.send", (event) => {
|
|
231
|
-
console.log("
|
|
254
|
+
console.log("Composer sent message in thread:", event.threadId);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// Listen to thread events
|
|
258
|
+
useAuiEvent("thread.runStart", (event) => {
|
|
259
|
+
console.log("Run started in thread:", event.threadId);
|
|
232
260
|
});
|
|
233
261
|
|
|
234
262
|
// Listen to all events of a type across all scopes
|
|
235
263
|
useAuiEvent({ event: "composer.send", scope: "*" }, (event) => {
|
|
236
|
-
console.log("Any composer sent a message:", event);
|
|
264
|
+
console.log("Any composer sent a message:", event.threadId);
|
|
237
265
|
});
|
|
238
266
|
|
|
239
267
|
// Listen to ALL events (useful for debugging or analytics)
|
|
240
268
|
useAuiEvent("*", (event) => {
|
|
241
|
-
console.log("Event occurred:", event.
|
|
242
|
-
// Send to analytics, logging, etc.
|
|
269
|
+
console.log("Event occurred:", event.event, event.payload);
|
|
243
270
|
});
|
|
244
271
|
|
|
245
272
|
// Practical example: Track user interactions
|
|
246
273
|
function AnalyticsTracker() {
|
|
247
274
|
useAuiEvent("composer.send", (event) => {
|
|
248
275
|
analytics.track("message_sent", {
|
|
249
|
-
|
|
250
|
-
hasAttachments: event.message.attachments.length > 0,
|
|
276
|
+
threadId: event.threadId,
|
|
251
277
|
});
|
|
252
278
|
});
|
|
253
279
|
|
|
@@ -272,9 +298,13 @@ Each scope provides access to specific state and actions:
|
|
|
272
298
|
- **Thread** (`thread`): Conversation with messages
|
|
273
299
|
- **Message** (`message`): Individual message (user or assistant)
|
|
274
300
|
- **Part** (`part`): Content part within a message (text, tool calls, etc.)
|
|
301
|
+
- **ChainOfThought** (`chainOfThought`): Reasoning steps grouped within a message
|
|
275
302
|
- **Composer** (`composer`): Text input for sending or editing messages
|
|
276
303
|
- **Attachment** (`attachment`): File or media attached to a message or composer
|
|
304
|
+
- **Suggestions** (`suggestions`): Collection of follow-up message suggestions
|
|
305
|
+
- **Suggestion** (`suggestion`): Individual follow-up suggestion
|
|
277
306
|
- **Tools** (`tools`): Tool UI components
|
|
307
|
+
- **ModelContext** (`modelContext`): Model context and tool registration
|
|
278
308
|
|
|
279
309
|
### Scope Resolution
|
|
280
310
|
|
|
@@ -301,7 +331,7 @@ Before accessing a scope, check if it's available:
|
|
|
301
331
|
const aui = useAui();
|
|
302
332
|
|
|
303
333
|
// Check if message scope exists
|
|
304
|
-
if (
|
|
334
|
+
if (aui.message.source) {
|
|
305
335
|
// Safe to use message scope
|
|
306
336
|
const { role } = aui.message().getState();
|
|
307
337
|
}
|
|
@@ -325,9 +355,9 @@ const partByToolCall = aui.message().part({ toolCallId: "call_123" });
|
|
|
325
355
|
// Access attachment by index
|
|
326
356
|
const attachment = aui.composer().attachment({ index: 0 }).getState();
|
|
327
357
|
|
|
328
|
-
// Access thread
|
|
329
|
-
const thread = aui.threads().thread("main");
|
|
358
|
+
// Access thread list item by ID or index
|
|
330
359
|
const threadItem = aui.threads().item({ id: "thread_123" });
|
|
360
|
+
const threadByIndex = aui.threads().item({ index: 0 });
|
|
331
361
|
```
|
|
332
362
|
|
|
333
363
|
## Common Patterns
|
|
@@ -400,7 +430,7 @@ function MessageCounter() {
|
|
|
400
430
|
|
|
401
431
|
### Resolution Dynamics
|
|
402
432
|
|
|
403
|
-
When you call `
|
|
433
|
+
When you call `aui.scope()`, the API resolves the current scope at that moment. This resolution happens each time you call the function, which matters when dealing with changing contexts:
|
|
404
434
|
|
|
405
435
|
```tsx
|
|
406
436
|
const aui = useAui();
|
|
@@ -458,27 +488,35 @@ const isRunning = useAuiState((s) => s.thread.isRunning);
|
|
|
458
488
|
|
|
459
489
|
### Scope States
|
|
460
490
|
|
|
461
|
-
| Scope | Key State Properties
|
|
462
|
-
| -------------- |
|
|
463
|
-
| ThreadList | `mainThreadId`, `threadIds`, `isLoading`, `threadItems`
|
|
464
|
-
| ThreadListItem | `id`, `title`, `status`, `remoteId`, `externalId`
|
|
465
|
-
| Thread | `isRunning`, `isLoading`, `isDisabled`, `messages`, `capabilities`, `suggestions`
|
|
466
|
-
| Message | `role`, `content`, `status`, `attachments`, `parentId`, `branchNumber`, `isLast`
|
|
467
|
-
|
|
|
468
|
-
|
|
|
469
|
-
|
|
|
491
|
+
| Scope | Key State Properties | Description |
|
|
492
|
+
| -------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------- |
|
|
493
|
+
| ThreadList | `mainThreadId`, `newThreadId`, `threadIds`, `archivedThreadIds`, `isLoading`, `threadItems` | Manages all available conversation threads |
|
|
494
|
+
| ThreadListItem | `id`, `title`, `status`, `remoteId`, `externalId` | Individual thread metadata and status |
|
|
495
|
+
| Thread | `isRunning`, `isLoading`, `isDisabled`, `isEmpty`, `messages`, `capabilities`, `suggestions` | Active conversation state and message history |
|
|
496
|
+
| Message | `role`, `content`, `status`, `attachments`, `parts`, `parentId`, `branchNumber`, `branchCount`, `isLast`, `index` | Individual message content and metadata |
|
|
497
|
+
| Part | `type`, `status`, `text`, `toolCallId`, `toolName` | Content parts within messages (text, tool calls) |
|
|
498
|
+
| ChainOfThought | `parts`, `collapsed`, `status` | Reasoning steps grouped within a message |
|
|
499
|
+
| Composer | `text`, `role`, `attachments`, `isEmpty`, `canCancel`, `type`, `isEditing` | Text input state for new/edited messages |
|
|
500
|
+
| Attachment | `id`, `type`, `name`, `contentType`, `status` | File attachments metadata and content |
|
|
501
|
+
| Suggestions | `suggestions` | Collection of follow-up message suggestions |
|
|
502
|
+
| Suggestion | `title`, `label`, `prompt` | Individual suggestion with title, label, and prompt |
|
|
503
|
+
| ModelContext | *(empty — use `register()` / `getToolCallParams()` methods)* | Model context and tool registration |
|
|
470
504
|
|
|
471
505
|
### Available Actions by Scope
|
|
472
506
|
|
|
473
|
-
| Scope | Actions
|
|
474
|
-
| -------------- |
|
|
475
|
-
| ThreadList | `switchToNewThread()`, `switchToThread(id)`, `getState()`
|
|
476
|
-
| ThreadListItem | `switchTo()`, `rename(title)`, `archive()`, `unarchive()`, `delete()`
|
|
477
|
-
| Thread | `append(message)`, `startRun()`, `cancelRun()`, `
|
|
478
|
-
| Message | `reload()`, `speak()`, `stopSpeaking()`, `submitFeedback(feedback)`
|
|
479
|
-
|
|
|
480
|
-
|
|
|
481
|
-
|
|
|
507
|
+
| Scope | Actions | Use Cases |
|
|
508
|
+
| -------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
|
|
509
|
+
| ThreadList | `switchToNewThread()`, `switchToThread(id)`, `item(selector)`, `thread("main")`, `getState()` | Thread navigation and creation |
|
|
510
|
+
| ThreadListItem | `switchTo()`, `rename(title)`, `archive()`, `unarchive()`, `delete()`, `getState()` | Thread management operations |
|
|
511
|
+
| Thread | `append(message)`, `startRun(config)`, `resumeRun(config)`, `cancelRun()`, `reset()`, `export()`, `import(repository)`, `message(selector)`, `composer()`, `getState()` | Message handling and conversation control |
|
|
512
|
+
| Message | `reload()`, `speak()`, `stopSpeaking()`, `submitFeedback(feedback)`, `switchToBranch(options)`, `getCopyText()`, `part(selector)`, `attachment(selector)`, `composer()`, `setIsCopied(value)`, `setIsHovering(value)`, `getState()` | Message interactions and regeneration |
|
|
513
|
+
| Part | `addToolResult(result)`, `resumeToolCall(result)`, `getState()` | Tool call result handling |
|
|
514
|
+
| ChainOfThought | `setCollapsed(collapsed)`, `part({ index })`, `getState()` | Expand/collapse reasoning steps |
|
|
515
|
+
| Composer | `send()`, `setText(text)`, `setRole(role)`, `addAttachment(file \| attachment)`, `clearAttachments()` (async), `reset()` (async), `getState()` | Text input and message composition |
|
|
516
|
+
| Attachment | `remove()`, `getState()` | File management |
|
|
517
|
+
| Suggestions | `suggestion({ index })`, `getState()` | Access follow-up suggestions |
|
|
518
|
+
| Suggestion | `getState()` | Read individual suggestion data |
|
|
519
|
+
| ModelContext | `register(provider)`, `getState()` | Register model context providers |
|
|
482
520
|
|
|
483
521
|
### Common Events
|
|
484
522
|
|
|
@@ -508,7 +546,7 @@ function SafeMessageButton() {
|
|
|
508
546
|
const aui = useAui();
|
|
509
547
|
|
|
510
548
|
const role = useAuiState((s) =>
|
|
511
|
-
|
|
549
|
+
aui.message.source !== undefined ? s.message.role : "none",
|
|
512
550
|
);
|
|
513
551
|
|
|
514
552
|
return <div>Role: {role}</div>;
|
|
@@ -558,18 +596,18 @@ const value = useAuiState((s) => s.scope.property);
|
|
|
558
596
|
|
|
559
597
|
// Perform action
|
|
560
598
|
const aui = useAui();
|
|
561
|
-
|
|
599
|
+
aui.scope().action();
|
|
562
600
|
|
|
563
601
|
// Listen to events
|
|
564
602
|
useAuiEvent("source.event", (e) => {});
|
|
565
603
|
|
|
566
604
|
// Check scope availability
|
|
567
|
-
if (
|
|
605
|
+
if (aui.scope.source) {
|
|
568
606
|
/* scope exists */
|
|
569
607
|
}
|
|
570
608
|
|
|
571
609
|
// Get state imperatively
|
|
572
|
-
const state =
|
|
610
|
+
const state = aui.scope().getState();
|
|
573
611
|
|
|
574
612
|
// Navigate scopes
|
|
575
613
|
aui.thread().message({ id: "..." }).getState();
|
|
@@ -38,7 +38,7 @@ const runtime = useChatRuntime({
|
|
|
38
38
|
The dictation feature uses `ComposerPrimitive.Dictate` and `ComposerPrimitive.StopDictation` components.
|
|
39
39
|
|
|
40
40
|
```tsx
|
|
41
|
-
import { ComposerPrimitive } from "@assistant-ui/react";
|
|
41
|
+
import { AuiIf, ComposerPrimitive } from "@assistant-ui/react";
|
|
42
42
|
import { MicIcon, SquareIcon } from "lucide-react";
|
|
43
43
|
|
|
44
44
|
const ComposerWithDictation = () => (
|
|
@@ -46,18 +46,18 @@ const ComposerWithDictation = () => (
|
|
|
46
46
|
<ComposerPrimitive.Input />
|
|
47
47
|
|
|
48
48
|
{/* Show Dictate button when not dictating */}
|
|
49
|
-
<
|
|
49
|
+
<AuiIf condition={(s) => s.composer.dictation == null}>
|
|
50
50
|
<ComposerPrimitive.Dictate>
|
|
51
51
|
<MicIcon />
|
|
52
52
|
</ComposerPrimitive.Dictate>
|
|
53
|
-
</
|
|
53
|
+
</AuiIf>
|
|
54
54
|
|
|
55
55
|
{/* Show Stop button when dictating */}
|
|
56
|
-
<
|
|
56
|
+
<AuiIf condition={(s) => s.composer.dictation != null}>
|
|
57
57
|
<ComposerPrimitive.StopDictation>
|
|
58
58
|
<SquareIcon className="animate-pulse" />
|
|
59
59
|
</ComposerPrimitive.StopDictation>
|
|
60
|
-
</
|
|
60
|
+
</AuiIf>
|
|
61
61
|
|
|
62
62
|
<ComposerPrimitive.Send />
|
|
63
63
|
</ComposerPrimitive.Root>
|
|
@@ -9,8 +9,8 @@ Give the user the ability to edit their message.
|
|
|
9
9
|
|
|
10
10
|
You can show an editor interface by using `ComposerPrimitive`.
|
|
11
11
|
|
|
12
|
-
```tsx {1,11,25,31-
|
|
13
|
-
import { ComposerPrimitive } from "@assistant-ui/react";
|
|
12
|
+
```tsx {1-2,11,25,31-52}
|
|
13
|
+
import { ComposerPrimitive, useAuiState } from "@assistant-ui/react";
|
|
14
14
|
...
|
|
15
15
|
|
|
16
16
|
const Thread = () => {
|
|
@@ -18,10 +18,12 @@ const Thread = () => {
|
|
|
18
18
|
<ThreadPrimitive.Root>
|
|
19
19
|
<ThreadPrimitive.Viewport>
|
|
20
20
|
...
|
|
21
|
-
<ThreadPrimitive.Messages
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
<ThreadPrimitive.Messages>
|
|
22
|
+
{({ message }) => {
|
|
23
|
+
// Show our new component during edit mode
|
|
24
|
+
return <MessageWithEditComposer />;
|
|
25
|
+
}}
|
|
26
|
+
</ThreadPrimitive.Messages>
|
|
25
27
|
</ThreadPrimitive.Viewport>
|
|
26
28
|
...
|
|
27
29
|
</ThreadPrimitive.Root>
|
|
@@ -40,7 +42,14 @@ const UserMessage = () => {
|
|
|
40
42
|
);
|
|
41
43
|
};
|
|
42
44
|
|
|
43
|
-
// define a
|
|
45
|
+
// define a wrapper component that handles both display and edit mode
|
|
46
|
+
const MessageWithEditComposer = () => {
|
|
47
|
+
const isEditing = useAuiState((s) => s.composer.isEditing);
|
|
48
|
+
if (isEditing) return <EditComposer />;
|
|
49
|
+
return <UserMessage />;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// define the edit composer component
|
|
44
53
|
const EditComposer = () => {
|
|
45
54
|
return (
|
|
46
55
|
// you can return a MessagePrimitive including a ComposerPrimitive, or only a ComposerPrimitive
|