@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
|
@@ -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
|
|
@@ -32,6 +32,7 @@ import "katex/dist/katex.min.css"; // [!code ++]
|
|
|
32
32
|
### Update `markdown-text.tsx`
|
|
33
33
|
|
|
34
34
|
```tsx title="/components/assistant-ui/markdown-text.tsx"
|
|
35
|
+
import { MarkdownTextPrimitive } from "@assistant-ui/react-markdown";
|
|
35
36
|
import remarkMath from "remark-math"; // [!code ++]
|
|
36
37
|
import rehypeKatex from "rehype-katex"; // [!code ++]
|
|
37
38
|
|
|
@@ -69,6 +70,8 @@ Many language models generate LaTeX using different delimiter formats:
|
|
|
69
70
|
You can use the `preprocess` prop to normalize these formats:
|
|
70
71
|
|
|
71
72
|
```tsx title="/components/assistant-ui/markdown-text.tsx"
|
|
73
|
+
import { MarkdownTextPrimitive } from "@assistant-ui/react-markdown";
|
|
74
|
+
|
|
72
75
|
const MarkdownTextImpl = () => {
|
|
73
76
|
return (
|
|
74
77
|
<MarkdownTextPrimitive
|
|
@@ -14,6 +14,7 @@ Display stream performance metrics — duration, tokens per second, TTFT — on
|
|
|
14
14
|
Use `useMessageTiming()` inside a message component to access timing data:
|
|
15
15
|
|
|
16
16
|
```tsx
|
|
17
|
+
import type { FC } from "react";
|
|
17
18
|
import { useMessageTiming } from "@assistant-ui/react";
|
|
18
19
|
|
|
19
20
|
const MessageTimingDisplay: FC = () => {
|
|
@@ -39,7 +40,7 @@ Place it inside `MessagePrimitive.Root`, typically near the action bar:
|
|
|
39
40
|
const AssistantMessage: FC = () => {
|
|
40
41
|
return (
|
|
41
42
|
<MessagePrimitive.Root>
|
|
42
|
-
<MessagePrimitive.Parts
|
|
43
|
+
<MessagePrimitive.Parts>{...}</MessagePrimitive.Parts>
|
|
43
44
|
<ActionBarPrimitive.Root>
|
|
44
45
|
<ActionBarPrimitive.Copy />
|
|
45
46
|
<ActionBarPrimitive.Reload />
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Multi-Agent
|
|
3
|
+
description: Render sub-agent conversations inside tool call UIs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
In a multi-agent (orchestrator) architecture, a main agent invokes sub-agents via tool calls. Each sub-agent may produce its own conversation (user/assistant messages, tool calls, etc.). assistant-ui supports rendering these nested conversations using the `MessagePartPrimitive.Messages` primitive.
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
When a tool call includes a `messages` field (`ToolCallMessagePart.messages`), it represents a sub-agent's conversation history. `MessagePartPrimitive.Messages` reads this field from the current tool call part and renders it as a nested thread.
|
|
11
|
+
|
|
12
|
+
Key behaviors:
|
|
13
|
+
|
|
14
|
+
- **Scope inheritance** — Parent tool UI registrations are available in sub-agent messages. A `makeAssistantToolUI` registered at the top level works inside sub-agent conversations too.
|
|
15
|
+
- **Recursive** — Sub-agent messages can contain tool calls that themselves have nested messages. Just use `MessagePartPrimitive.Messages` again.
|
|
16
|
+
- **Read-only** — Sub-agent messages are rendered in a readonly context. No editing, branching, or composing.
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
<Steps>
|
|
21
|
+
<Step>
|
|
22
|
+
|
|
23
|
+
### Register a Tool UI for the Sub-Agent
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import {
|
|
27
|
+
makeAssistantToolUI,
|
|
28
|
+
MessagePartPrimitive,
|
|
29
|
+
} from "@assistant-ui/react";
|
|
30
|
+
|
|
31
|
+
const ResearchAgentToolUI = makeAssistantToolUI({
|
|
32
|
+
toolName: "invoke_researcher",
|
|
33
|
+
render: ({ args, status }) => (
|
|
34
|
+
<div className="my-2 rounded-lg border p-4">
|
|
35
|
+
<div className="mb-2 text-sm font-medium text-gray-500">
|
|
36
|
+
Researcher Agent {status.type === "running" && "(working...)"}
|
|
37
|
+
</div>
|
|
38
|
+
<MessagePartPrimitive.Messages>
|
|
39
|
+
{({ message }) => {
|
|
40
|
+
if (message.role === "user") return <MyUserMessage />;
|
|
41
|
+
return <MyAssistantMessage />;
|
|
42
|
+
}}
|
|
43
|
+
</MessagePartPrimitive.Messages>
|
|
44
|
+
</div>
|
|
45
|
+
),
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
</Step>
|
|
50
|
+
<Step>
|
|
51
|
+
|
|
52
|
+
### Provide the Messages from the Backend
|
|
53
|
+
|
|
54
|
+
Your backend must populate the `messages` field on the tool call result. For example, with the AI SDK:
|
|
55
|
+
|
|
56
|
+
```ts title="api/chat/route.ts"
|
|
57
|
+
tools: {
|
|
58
|
+
invoke_researcher: tool({
|
|
59
|
+
description: "Invoke the researcher sub-agent",
|
|
60
|
+
parameters: z.object({ query: z.string() }),
|
|
61
|
+
execute: async ({ query }) => {
|
|
62
|
+
const subAgentMessages = await runResearcherAgent(query);
|
|
63
|
+
return {
|
|
64
|
+
answer: subAgentMessages.at(-1)?.content,
|
|
65
|
+
// The messages field is picked up by assistant-ui
|
|
66
|
+
messages: subAgentMessages,
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
}),
|
|
70
|
+
},
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
<Callout type="info">
|
|
74
|
+
The exact mechanism for populating `messages` depends on your backend
|
|
75
|
+
framework. The key requirement is that the tool result's corresponding
|
|
76
|
+
`ToolCallMessagePart` includes a `messages` array of `ThreadMessage` objects.
|
|
77
|
+
</Callout>
|
|
78
|
+
|
|
79
|
+
</Step>
|
|
80
|
+
<Step>
|
|
81
|
+
|
|
82
|
+
### Register the Tool UI Component
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
function App() {
|
|
86
|
+
return (
|
|
87
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
88
|
+
<Thread />
|
|
89
|
+
<ResearchAgentToolUI />
|
|
90
|
+
</AssistantRuntimeProvider>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
</Step>
|
|
96
|
+
</Steps>
|
|
97
|
+
|
|
98
|
+
## Recursive Sub-Agents
|
|
99
|
+
|
|
100
|
+
If a sub-agent's tool calls also have nested messages, the same pattern applies recursively:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
const OuterAgentToolUI = makeAssistantToolUI({
|
|
104
|
+
toolName: "invoke_planner",
|
|
105
|
+
render: () => (
|
|
106
|
+
<div className="rounded border p-3">
|
|
107
|
+
<h4>Planner Agent</h4>
|
|
108
|
+
<MessagePartPrimitive.Messages>
|
|
109
|
+
{({ message }) => {
|
|
110
|
+
if (message.role === "user") return <MyUserMessage />;
|
|
111
|
+
return (
|
|
112
|
+
<MessagePrimitive.Parts>
|
|
113
|
+
{({ part }) => {
|
|
114
|
+
if (part.type === "text") return <MyText />;
|
|
115
|
+
if (part.type === "tool-call" && part.toolName === "invoke_researcher") return (
|
|
116
|
+
<div className="ml-4 rounded border p-3">
|
|
117
|
+
<h5>Researcher Agent</h5>
|
|
118
|
+
{/* Nested sub-agent renders recursively */}
|
|
119
|
+
<MessagePartPrimitive.Messages>
|
|
120
|
+
{({ message }) => {
|
|
121
|
+
if (message.role === "user") return <MyUserMessage />;
|
|
122
|
+
return <MyAssistantMessage />;
|
|
123
|
+
}}
|
|
124
|
+
</MessagePartPrimitive.Messages>
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
if (part.type === "tool-call") return <MyToolFallback {...part} />;
|
|
128
|
+
return null;
|
|
129
|
+
}}
|
|
130
|
+
</MessagePrimitive.Parts>
|
|
131
|
+
);
|
|
132
|
+
}}
|
|
133
|
+
</MessagePartPrimitive.Messages>
|
|
134
|
+
</div>
|
|
135
|
+
),
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## ReadonlyThreadProvider
|
|
140
|
+
|
|
141
|
+
For advanced use cases where you have a `ThreadMessage[]` array and want to render it as a thread outside of a tool call context, use `ReadonlyThreadProvider` directly:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
import {
|
|
145
|
+
ReadonlyThreadProvider,
|
|
146
|
+
ThreadPrimitive,
|
|
147
|
+
type ThreadMessage,
|
|
148
|
+
} from "@assistant-ui/react";
|
|
149
|
+
|
|
150
|
+
function SubConversation({
|
|
151
|
+
messages,
|
|
152
|
+
}: {
|
|
153
|
+
messages: readonly ThreadMessage[];
|
|
154
|
+
}) {
|
|
155
|
+
return (
|
|
156
|
+
<ReadonlyThreadProvider messages={messages}>
|
|
157
|
+
<ThreadPrimitive.Messages>
|
|
158
|
+
{({ message }) => {
|
|
159
|
+
if (message.role === "user") return <MyUserMessage />;
|
|
160
|
+
return <MyAssistantMessage />;
|
|
161
|
+
}}
|
|
162
|
+
</ThreadPrimitive.Messages>
|
|
163
|
+
</ReadonlyThreadProvider>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`ReadonlyThreadProvider` inherits the parent's tool UI registrations and model context through scope inheritance.
|
|
169
|
+
|
|
170
|
+
## Related
|
|
171
|
+
|
|
172
|
+
- [Generative UI](/docs/guides/tool-ui) — Creating tool call UIs
|
|
173
|
+
- [MessagePartPrimitive](/docs/api-reference/primitives/message-part) — API reference for message part primitives
|