@assistant-ui/mcp-docs-server 0.1.32 → 0.1.33
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 +15 -17
- package/.docs/organized/code-examples/with-a2a.md +19 -19
- package/.docs/organized/code-examples/with-ag-ui.md +25 -20
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +6 -4
- package/.docs/organized/code-examples/with-artifacts.md +34 -28
- package/.docs/organized/code-examples/with-assistant-transport.md +59 -47
- package/.docs/organized/code-examples/with-browser-extension.md +17 -5
- package/.docs/organized/code-examples/with-chain-of-thought.md +376 -78
- package/.docs/organized/code-examples/with-cloud-standalone.md +20 -19
- package/.docs/organized/code-examples/with-cloud.md +6 -4
- package/.docs/organized/code-examples/with-custom-thread-list.md +9 -7
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +18 -16
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +9 -8
- package/.docs/organized/code-examples/with-expo.md +23 -17
- package/.docs/organized/code-examples/with-external-store.md +4 -2
- package/.docs/organized/code-examples/with-ffmpeg.md +317 -280
- package/.docs/organized/code-examples/with-generative-ui.md +1018 -214
- package/.docs/organized/code-examples/with-google-adk.md +4 -2
- package/.docs/organized/code-examples/with-heat-graph.md +8 -6
- package/.docs/organized/code-examples/with-image-generation.md +19 -17
- package/.docs/organized/code-examples/with-interactables.md +312 -234
- package/.docs/organized/code-examples/with-langchain.md +9 -7
- package/.docs/organized/code-examples/with-langgraph.md +82 -78
- package/.docs/organized/code-examples/with-livekit.md +19 -17
- package/.docs/organized/code-examples/with-mcp.md +13 -7
- package/.docs/organized/code-examples/with-opencode.md +61 -61
- package/.docs/organized/code-examples/with-react-hook-form.md +14 -12
- package/.docs/organized/code-examples/with-react-ink.md +2 -2
- package/.docs/organized/code-examples/with-react-router.md +11 -9
- package/.docs/organized/code-examples/with-resumable-stream.md +10 -9
- package/.docs/organized/code-examples/with-store.md +14 -12
- package/.docs/organized/code-examples/with-tanstack.md +8 -9
- package/.docs/organized/code-examples/with-tap-runtime.md +21 -19
- package/.docs/raw/docs/(docs)/architecture.mdx +43 -2
- package/.docs/raw/docs/(docs)/cli.mdx +1 -2
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +34 -26
- package/.docs/raw/docs/(docs)/copilots/motivation.mdx +32 -26
- package/.docs/raw/docs/(docs)/installation.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +5 -1
- package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +14 -14
- package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +11 -1
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +18 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +33 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/spec.mdx +45 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +41 -41
- package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +19 -1
- package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +122 -122
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +32 -2
- package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +6 -0
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +4 -6
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +30 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +20 -3
- package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +8 -8
- package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +52 -4
- package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +6 -7
- package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +58 -46
- package/.docs/raw/docs/cloud/ai-sdk.mdx +0 -2
- package/.docs/raw/docs/guides/chain-of-thought.mdx +7 -9
- package/.docs/raw/docs/guides/context-api.mdx +2 -1
- package/.docs/raw/docs/guides/index.mdx +3 -12
- package/.docs/raw/docs/guides/mentions.mdx +4 -4
- package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
- package/.docs/raw/docs/guides/suggestions.mdx +1 -1
- package/.docs/raw/docs/ink/hooks.mdx +98 -85
- package/.docs/raw/docs/ink/migration.mdx +1 -1
- package/.docs/raw/docs/ink/primitives.mdx +2 -2
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +1 -1
- package/.docs/raw/docs/integrations/index.mdx +2 -2
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +17 -2
- package/.docs/raw/docs/migrations/toolkit-tools.mdx +226 -0
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +10 -16
- package/.docs/raw/docs/primitives/message.mdx +9 -10
- package/.docs/raw/docs/react-native/hooks.mdx +57 -82
- package/.docs/raw/docs/react-native/migration.mdx +1 -1
- package/.docs/raw/docs/react-native/primitives.mdx +2 -2
- package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +3 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +122 -1
- package/.docs/raw/docs/runtimes/concepts/threads.mdx +7 -1
- package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +18 -7
- package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +108 -38
- package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +2 -2
- package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +1 -1
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +64 -50
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +98 -86
- package/.docs/raw/docs/tools/backend.mdx +136 -0
- package/.docs/raw/docs/tools/defining-tools.mdx +413 -0
- package/.docs/raw/docs/tools/dynamic-tools.mdx +110 -0
- package/.docs/raw/docs/tools/generative-ui.mdx +214 -0
- package/.docs/raw/docs/tools/index.mdx +76 -0
- package/.docs/raw/docs/{guides → tools}/interactables.mdx +1 -1
- package/.docs/raw/docs/{integrations/tools → tools}/mcp.mdx +77 -50
- package/.docs/raw/docs/{guides → tools}/multi-agent.mdx +17 -19
- package/.docs/raw/docs/tools/tool-ui.mdx +967 -0
- package/.docs/raw/docs/{integrations/tools/react-mcp.mdx → tools/user-managed-mcp.mdx} +3 -3
- package/.docs/raw/docs/ui/directive-text.mdx +3 -3
- package/.docs/raw/docs/ui/mcp-config.mdx +4 -4
- package/.docs/raw/docs/ui/part-grouping.mdx +84 -50
- package/.docs/raw/docs/ui/reasoning.mdx +4 -5
- package/.docs/raw/docs/ui/tool-group.mdx +5 -6
- package/.docs/raw/docs/utilities/heat-graph.mdx +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/prepare-docs/code-examples.d.ts.map +1 -1
- package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/package.json +3 -3
- package/.docs/organized/code-examples/with-parent-id-grouping.md +0 -596
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +0 -151
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +0 -230
- package/.docs/raw/docs/guides/generative-ui.mdx +0 -142
- package/.docs/raw/docs/guides/tool-ui.mdx +0 -858
- package/.docs/raw/docs/guides/tools.mdx +0 -736
- /package/.docs/raw/docs/{guides → tools}/mcp-apps.mdx +0 -0
|
@@ -3,7 +3,7 @@ title: User-managed MCP servers
|
|
|
3
3
|
description: Let end users add and authenticate MCP servers from the browser with @assistant-ui/react-mcp.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
[`@assistant-ui/react-mcp`](https://npmjs.com/package/@assistant-ui/react-mcp) is the user-facing layer for MCP. Where the [server-side MCP guide](/docs/
|
|
6
|
+
[`@assistant-ui/react-mcp`](https://npmjs.com/package/@assistant-ui/react-mcp) is the user-facing layer for MCP. Where the [server-side MCP guide](/docs/tools/mcp) wires a single fixed set of MCP servers into your API route, this package lets *end users* see a list of connectors, sign in via OAuth, paste a custom server URL, and have the resulting tool catalog flow into the chat — automatically.
|
|
7
7
|
|
|
8
8
|
Two ways a server reaches the user:
|
|
9
9
|
|
|
@@ -327,11 +327,11 @@ What's deferred:
|
|
|
327
327
|
<Card
|
|
328
328
|
title="Server-side MCP"
|
|
329
329
|
description="App-developer-controlled MCP servers wired into the API route."
|
|
330
|
-
href="/docs/
|
|
330
|
+
href="/docs/tools/mcp"
|
|
331
331
|
/>
|
|
332
332
|
<Card
|
|
333
333
|
title="Tools and tool UI"
|
|
334
334
|
description="Build custom renderers for tool calls and approvals."
|
|
335
|
-
href="/docs/
|
|
335
|
+
href="/docs/tools/defining-tools"
|
|
336
336
|
/>
|
|
337
337
|
</Cards>
|
|
@@ -49,7 +49,7 @@ Keep your markdown renderer (e.g. `MarkdownText`) for assistant messages — ass
|
|
|
49
49
|
|
|
50
50
|
```tsx
|
|
51
51
|
import { createDirectiveText } from "@/components/assistant-ui/directive-text";
|
|
52
|
-
import { unstable_defaultDirectiveFormatter } from "@assistant-ui/
|
|
52
|
+
import { unstable_defaultDirectiveFormatter } from "@assistant-ui/react";
|
|
53
53
|
import { FileTextIcon, SparklesIcon, UserIcon, WrenchIcon } from "lucide-react";
|
|
54
54
|
|
|
55
55
|
const DirectiveTextWithIcons = createDirectiveText(
|
|
@@ -74,7 +74,7 @@ A matching `iconMap` / `fallbackIcon` option is accepted by [`ComposerTriggerPop
|
|
|
74
74
|
The default format is `:type[label]{name=id}`. For a different format, build a custom `Unstable_DirectiveFormatter` and wrap it with `createDirectiveText`:
|
|
75
75
|
|
|
76
76
|
```tsx
|
|
77
|
-
import type { Unstable_DirectiveFormatter } from "@assistant-ui/
|
|
77
|
+
import type { Unstable_DirectiveFormatter } from "@assistant-ui/react";
|
|
78
78
|
import { createDirectiveText } from "@/components/assistant-ui/directive-text";
|
|
79
79
|
|
|
80
80
|
const slashFormatter: Unstable_DirectiveFormatter = {
|
|
@@ -97,7 +97,7 @@ Because `directive-text.tsx` is copied into your project, you can also edit it d
|
|
|
97
97
|
|
|
98
98
|
### `DirectiveText`
|
|
99
99
|
|
|
100
|
-
A `TextMessagePartComponent` that parses `:type[label]{name=id}` directives and renders them as inline chips. Uses the default formatter from `@assistant-ui/
|
|
100
|
+
A `TextMessagePartComponent` that parses `:type[label]{name=id}` directives and renders them as inline chips. Uses the default formatter from `@assistant-ui/react` and renders chips without icons. For per-type icons, build a component with `createDirectiveText(formatter, { iconMap })`.
|
|
101
101
|
|
|
102
102
|
### `createDirectiveText(formatter, options?)`
|
|
103
103
|
|
|
@@ -4,7 +4,7 @@ description: Drop-in shadcn dialog that lists MCP connectors and custom servers,
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
`McpConfigDialog` is a shadcn template that wraps the [`@assistant-ui/react-mcp`](/docs/
|
|
7
|
+
`McpConfigDialog` is a shadcn template that wraps the [`@assistant-ui/react-mcp`](/docs/tools/user-managed-mcp) primitives. Render it anywhere inside an `McpManagerResource`-mounted client and your users get a styled MCP server panel — no manual primitive composition.
|
|
8
8
|
|
|
9
9
|
## Getting Started
|
|
10
10
|
|
|
@@ -81,7 +81,7 @@ Pass children to swap the default button for your own:
|
|
|
81
81
|
|
|
82
82
|
### Wire up the OAuth callback
|
|
83
83
|
|
|
84
|
-
Required for any OAuth-enabled connector or custom server. See the [OAuth callback section in the react-mcp guide](/docs/
|
|
84
|
+
Required for any OAuth-enabled connector or custom server. See the [OAuth callback section in the react-mcp guide](/docs/tools/user-managed-mcp#handle-the-oauth-callback) for the route handler.
|
|
85
85
|
|
|
86
86
|
</Step>
|
|
87
87
|
</Steps>
|
|
@@ -92,11 +92,11 @@ Required for any OAuth-enabled connector or custom server. See the [OAuth callba
|
|
|
92
92
|
<Card
|
|
93
93
|
title="User-managed MCP servers"
|
|
94
94
|
description="Full @assistant-ui/react-mcp guide — connectors, custom servers, OAuth, storage, custom primitives."
|
|
95
|
-
href="/docs/
|
|
95
|
+
href="/docs/tools/user-managed-mcp"
|
|
96
96
|
/>
|
|
97
97
|
<Card
|
|
98
98
|
title="Server-side MCP"
|
|
99
99
|
description="App-developer-controlled MCP servers wired into the API route."
|
|
100
|
-
href="/docs/
|
|
100
|
+
href="/docs/tools/mcp"
|
|
101
101
|
/>
|
|
102
102
|
</Cards>
|
|
@@ -10,18 +10,19 @@ import { PartGroupingSample } from "@/components/docs/samples/part-grouping";
|
|
|
10
10
|
|
|
11
11
|
## Basic Usage
|
|
12
12
|
|
|
13
|
-
For adjacent grouping, use `MessagePrimitive.GroupedParts`.
|
|
13
|
+
For adjacent grouping, use `MessagePrimitive.GroupedParts`. For the common case — grouping by `part.type` — pass `groupPartByType` to map each part type to a group-key path. Adjacent parts that share a group key are coalesced and rendered through the group case.
|
|
14
14
|
|
|
15
15
|
```tsx title="/components/assistant-ui/thread.tsx"
|
|
16
|
+
import { MessagePrimitive, groupPartByType } from "@assistant-ui/react";
|
|
17
|
+
|
|
16
18
|
const AssistantMessage: FC = () => {
|
|
17
19
|
return (
|
|
18
20
|
<MessagePrimitive.Root className="...">
|
|
19
21
|
<div className="...">
|
|
20
22
|
<MessagePrimitive.GroupedParts
|
|
21
|
-
groupBy={(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}}
|
|
23
|
+
groupBy={groupPartByType({
|
|
24
|
+
"tool-call": ["group-tool"],
|
|
25
|
+
})}
|
|
25
26
|
>
|
|
26
27
|
{({ part, children }) => {
|
|
27
28
|
switch (part.type) {
|
|
@@ -42,6 +43,8 @@ const AssistantMessage: FC = () => {
|
|
|
42
43
|
};
|
|
43
44
|
```
|
|
44
45
|
|
|
46
|
+
Reach for an inline `groupBy={(part) => …}` only when the helper isn't expressive enough — e.g. you need to branch on `part.toolName`, `part.parentId`, or part metadata.
|
|
47
|
+
|
|
45
48
|
## How Adjacent Grouping Works
|
|
46
49
|
|
|
47
50
|
`groupBy` receives each part and returns either `null` for an ungrouped leaf or a group-key path such as `["group-chainOfThought", "group-tool"]`. Group keys must start with `"group-"` so your render function can distinguish synthetic groups from real part types.
|
|
@@ -89,7 +92,7 @@ function ParentGroup({
|
|
|
89
92
|
|
|
90
93
|
<MessagePrimitive.GroupedParts
|
|
91
94
|
groupBy={(part) => {
|
|
92
|
-
if (!part.parentId) return
|
|
95
|
+
if (!part.parentId) return [];
|
|
93
96
|
return [`group-parent-${part.parentId}`];
|
|
94
97
|
}}
|
|
95
98
|
>
|
|
@@ -117,7 +120,7 @@ Organize adjacent tool calls by tool name:
|
|
|
117
120
|
```tsx
|
|
118
121
|
<MessagePrimitive.GroupedParts
|
|
119
122
|
groupBy={(part) => {
|
|
120
|
-
if (part.type !== "tool-call") return
|
|
123
|
+
if (part.type !== "tool-call") return [];
|
|
121
124
|
return [`group-tool-${part.toolName}`];
|
|
122
125
|
}}
|
|
123
126
|
>
|
|
@@ -147,10 +150,9 @@ Combine multiple text parts into cohesive blocks:
|
|
|
147
150
|
|
|
148
151
|
```tsx
|
|
149
152
|
<MessagePrimitive.GroupedParts
|
|
150
|
-
groupBy={(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}}
|
|
153
|
+
groupBy={groupPartByType({
|
|
154
|
+
text: ["group-text-block"],
|
|
155
|
+
})}
|
|
154
156
|
>
|
|
155
157
|
{({ part, children }) => {
|
|
156
158
|
switch (part.type) {
|
|
@@ -177,12 +179,11 @@ Separate different types of content for distinct visual treatment:
|
|
|
177
179
|
|
|
178
180
|
```tsx
|
|
179
181
|
<MessagePrimitive.GroupedParts
|
|
180
|
-
groupBy={(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}}
|
|
182
|
+
groupBy={groupPartByType({
|
|
183
|
+
text: ["group-content-text"],
|
|
184
|
+
"tool-call": ["group-content-tools"],
|
|
185
|
+
reasoning: ["group-content-reasoning"],
|
|
186
|
+
})}
|
|
186
187
|
>
|
|
187
188
|
{({ part, children }) => {
|
|
188
189
|
switch (part.type) {
|
|
@@ -205,6 +206,52 @@ Separate different types of content for distinct visual treatment:
|
|
|
205
206
|
</MessagePrimitive.GroupedParts>
|
|
206
207
|
```
|
|
207
208
|
|
|
209
|
+
### Keep Standalone Tool UIs Out of the Trace
|
|
210
|
+
|
|
211
|
+
Tool UIs fall into three buckets: prompting the user (human-in-the-loop), informing the user (generative UI), and traces of what the model is doing (routine tool calls). The first two should be surfaced on their own, while the last belongs folded into a collapsible chain-of-thought group.
|
|
212
|
+
|
|
213
|
+
Mark a tool with `display: "standalone"` to keep its UI out of the grouped trace. `human` tools and MCP apps are standalone automatically; every other tool defaults to `"inline"` and opts in explicitly:
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
const toolkit = {
|
|
217
|
+
ask_user: { type: "human", render: AskUI }, // standalone (forced)
|
|
218
|
+
search_web: { type: "frontend", render: SearchUI }, // inline trace (default)
|
|
219
|
+
checkout: {
|
|
220
|
+
type: "frontend",
|
|
221
|
+
render: CheckoutUI,
|
|
222
|
+
display: "standalone", // opt in
|
|
223
|
+
},
|
|
224
|
+
} satisfies Toolkit;
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The synthetic `"standalone-tool-call"` key on `groupPartByType` matches all of these. `MessagePrimitive.GroupedParts` passes the live tool-UI registry to `groupBy` as a second `context` argument, and the helper reads it to resolve the registry-driven cases — MCP-app calls are detected from the part alone, so nothing is threaded in:
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
<MessagePrimitive.GroupedParts
|
|
231
|
+
groupBy={groupPartByType({
|
|
232
|
+
reasoning: ["group-chainOfThought", "group-reasoning"],
|
|
233
|
+
"tool-call": ["group-chainOfThought", "group-tool"],
|
|
234
|
+
"standalone-tool-call": [], // ungrouped — rendered on its own
|
|
235
|
+
})}
|
|
236
|
+
>
|
|
237
|
+
{({ part, children }) => {
|
|
238
|
+
switch (part.type) {
|
|
239
|
+
case "group-chainOfThought":
|
|
240
|
+
return <div className="chain-of-thought">{children}</div>;
|
|
241
|
+
case "tool-call":
|
|
242
|
+
return part.toolUI ?? <ToolFallback {...part} />;
|
|
243
|
+
// ...
|
|
244
|
+
default:
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
}}
|
|
248
|
+
</MessagePrimitive.GroupedParts>;
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
<Callout type="info">
|
|
252
|
+
The `"mcp-app"` key is deprecated in favor of `"standalone-tool-call"`, which is a superset (it also matches MCP-app tool calls). Existing `"mcp-app"` usage keeps working.
|
|
253
|
+
</Callout>
|
|
254
|
+
|
|
208
255
|
### Group by Custom Metadata
|
|
209
256
|
|
|
210
257
|
Use any custom metadata in your parts for grouping:
|
|
@@ -219,7 +266,7 @@ const priorityStyles = {
|
|
|
219
266
|
<MessagePrimitive.GroupedParts
|
|
220
267
|
groupBy={(part) => {
|
|
221
268
|
const priority = part.metadata?.priority;
|
|
222
|
-
if (!priority) return
|
|
269
|
+
if (!priority) return [];
|
|
223
270
|
return [`group-priority-${priority}`];
|
|
224
271
|
}}
|
|
225
272
|
>
|
|
@@ -300,9 +347,9 @@ const stream = createAssistantStream(async (controller) => {
|
|
|
300
347
|
parameters={[
|
|
301
348
|
{
|
|
302
349
|
name: "groupBy",
|
|
303
|
-
type: "(part: PartState
|
|
350
|
+
type: "(part: PartState) => readonly `group-${string}`[]",
|
|
304
351
|
description:
|
|
305
|
-
"Maps a part to a group-key path. Return
|
|
352
|
+
"Maps a part to a group-key path. Return `[]` to leave the part ungrouped. Group keys must start with `group-`. Prefer `groupPartByType` for the common `part.type → path` case.",
|
|
306
353
|
required: true,
|
|
307
354
|
},
|
|
308
355
|
{
|
|
@@ -315,6 +362,19 @@ const stream = createAssistantStream(async (controller) => {
|
|
|
315
362
|
]}
|
|
316
363
|
/>
|
|
317
364
|
|
|
365
|
+
### groupPartByType helper
|
|
366
|
+
|
|
367
|
+
`groupPartByType` builds a `groupBy` from a `part.type → group-key path` map. Part types missing from the map are left ungrouped. The returned function carries an internal memo fingerprint so the tree survives unrelated re-renders.
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
import { groupPartByType } from "@assistant-ui/react";
|
|
371
|
+
|
|
372
|
+
groupPartByType({
|
|
373
|
+
reasoning: ["group-thought", "group-reasoning"],
|
|
374
|
+
"tool-call": ["group-thought", "group-tool"],
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
318
378
|
### GroupPart Type
|
|
319
379
|
|
|
320
380
|
```typescript
|
|
@@ -331,34 +391,9 @@ type GroupPart<TKey extends `group-${string}` = `group-${string}`> = {
|
|
|
331
391
|
2. **Handle ungrouped parts**: Always include leaf cases for the part types your message can render.
|
|
332
392
|
3. **Only render `children` for groups**: Leaf parts receive a sentinel `children` value that throws if rendered accidentally.
|
|
333
393
|
4. **Use `group-` prefixes**: Synthetic group keys must start with `group-` so they cannot collide with real part types.
|
|
334
|
-
5. **Keep `groupBy` stable**: Prefer a module-level function or `useCallback` for frequently re-rendering message trees.
|
|
335
394
|
|
|
336
395
|
## Common Patterns
|
|
337
396
|
|
|
338
|
-
### Conditional Grouping
|
|
339
|
-
|
|
340
|
-
Only group when certain conditions are met:
|
|
341
|
-
|
|
342
|
-
```tsx
|
|
343
|
-
<MessagePrimitive.GroupedParts
|
|
344
|
-
groupBy={(part, index, parts) => {
|
|
345
|
-
const hasManyParts = parts.length >= 5;
|
|
346
|
-
if (!hasManyParts) return null;
|
|
347
|
-
if (part.type === "tool-call") return ["group-tools"];
|
|
348
|
-
return null;
|
|
349
|
-
}}
|
|
350
|
-
>
|
|
351
|
-
{({ part, children }) => {
|
|
352
|
-
if (part.type === "group-tools") {
|
|
353
|
-
return <div className="rounded-lg border p-3">{children}</div>;
|
|
354
|
-
}
|
|
355
|
-
if (part.type === "tool-call") return part.toolUI ?? <ToolFallback {...part} />;
|
|
356
|
-
if (part.type === "text") return <MarkdownText />;
|
|
357
|
-
return null;
|
|
358
|
-
}}
|
|
359
|
-
</MessagePrimitive.GroupedParts>
|
|
360
|
-
```
|
|
361
|
-
|
|
362
397
|
### Nested Grouping
|
|
363
398
|
|
|
364
399
|
Create hierarchical adjacent groups by returning multiple keys:
|
|
@@ -370,7 +405,7 @@ Create hierarchical adjacent groups by returning multiple keys:
|
|
|
370
405
|
return ["group-chainOfThought", "group-reasoning"];
|
|
371
406
|
if (part.type === "tool-call")
|
|
372
407
|
return ["group-chainOfThought", `group-tool-${part.toolName}`];
|
|
373
|
-
return
|
|
408
|
+
return [];
|
|
374
409
|
}}
|
|
375
410
|
>
|
|
376
411
|
{({ part, children }) => {
|
|
@@ -391,10 +426,9 @@ Adjust group appearance based on the group node's status or indices:
|
|
|
391
426
|
|
|
392
427
|
```tsx
|
|
393
428
|
<MessagePrimitive.GroupedParts
|
|
394
|
-
groupBy={(
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}}
|
|
429
|
+
groupBy={groupPartByType({
|
|
430
|
+
"tool-call": ["group-tools"],
|
|
431
|
+
})}
|
|
398
432
|
>
|
|
399
433
|
{({ part, children }) => {
|
|
400
434
|
if (part.type === "group-tools") {
|
|
@@ -31,7 +31,7 @@ Render reasoning parts through `MessagePrimitive.GroupedParts`. Group consecutiv
|
|
|
31
31
|
While reasoning is streaming, `part.status.type === "running"`. Pass that to `defaultOpen` so the accordion auto-opens during streaming and lets the user collapse it once the model moves on.
|
|
32
32
|
|
|
33
33
|
```tsx title="/app/components/assistant-ui/thread.tsx"
|
|
34
|
-
import { MessagePrimitive } from "@assistant-ui/react";
|
|
34
|
+
import { MessagePrimitive, groupPartByType } from "@assistant-ui/react";
|
|
35
35
|
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
|
|
36
36
|
import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
|
|
37
37
|
import {
|
|
@@ -47,10 +47,9 @@ const AssistantMessage: FC = () => {
|
|
|
47
47
|
<MessagePrimitive.Root className="...">
|
|
48
48
|
<div className="...">
|
|
49
49
|
<MessagePrimitive.GroupedParts // [!code ++]
|
|
50
|
-
groupBy={(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}} // [!code ++]
|
|
50
|
+
groupBy={groupPartByType({ // [!code ++]
|
|
51
|
+
reasoning: ["group-reasoning"], // [!code ++]
|
|
52
|
+
})} // [!code ++]
|
|
54
53
|
> // [!code ++]
|
|
55
54
|
{({ part, children }) => { // [!code ++]
|
|
56
55
|
switch (part.type) { // [!code ++]
|
|
@@ -29,10 +29,10 @@ This adds `/components/assistant-ui/tool-group.tsx` and `/components/assistant-u
|
|
|
29
29
|
|
|
30
30
|
### Use it in your application
|
|
31
31
|
|
|
32
|
-
Use `MessagePrimitive.GroupedParts`
|
|
32
|
+
Use `MessagePrimitive.GroupedParts` with `groupPartByType` to map tool-call parts to `"group-tool"`. The group case wraps `children`; the tool-call leaf renders the resolved tool UI or your fallback.
|
|
33
33
|
|
|
34
34
|
```tsx title="/components/assistant-ui/thread.tsx"
|
|
35
|
-
import { MessagePrimitive } from "@assistant-ui/react";
|
|
35
|
+
import { MessagePrimitive, groupPartByType } from "@assistant-ui/react";
|
|
36
36
|
import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
|
|
37
37
|
import {
|
|
38
38
|
ToolGroupContent,
|
|
@@ -44,10 +44,9 @@ const AssistantMessage = () => {
|
|
|
44
44
|
return (
|
|
45
45
|
<MessagePrimitive.Root>
|
|
46
46
|
<MessagePrimitive.GroupedParts
|
|
47
|
-
groupBy={(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}}
|
|
47
|
+
groupBy={groupPartByType({
|
|
48
|
+
"tool-call": ["group-tool"],
|
|
49
|
+
})}
|
|
51
50
|
>
|
|
52
51
|
{({ part, children }) => {
|
|
53
52
|
switch (part.type) {
|
|
@@ -4,7 +4,7 @@ description: Headless, composable activity heatmap components for React.
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { HeatGraphDemo } from "@/app/heat-graph/heat-graph-demo";
|
|
7
|
+
import { HeatGraphDemo } from "@/app/(demos)/heat-graph/heat-graph-demo";
|
|
8
8
|
|
|
9
9
|
`heat-graph` provides headless, Radix-style primitives for building GitHub-style activity heatmap graphs.
|
|
10
10
|
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;cAca,MAAA,EAAM,SAGjB;AAAA,iBAeoB,SAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;cAca,MAAA,EAAM,SAGjB;AAAA,iBAeoB,SAAA,IAAS,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-examples.d.ts","names":[],"sources":["../../src/prepare-docs/code-examples.ts"],"mappings":";iBA2FsB,mBAAA,
|
|
1
|
+
{"version":3,"file":"code-examples.d.ts","names":[],"sources":["../../src/prepare-docs/code-examples.ts"],"mappings":";iBA2FsB,mBAAA,IAAuB,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-raw.d.ts","names":[],"sources":["../../src/prepare-docs/copy-raw.ts"],"mappings":";iBAkCsB,OAAA,
|
|
1
|
+
{"version":3,"file":"copy-raw.d.ts","names":[],"sources":["../../src/prepare-docs/copy-raw.ts"],"mappings":";iBAkCsB,OAAA,IAAW,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","names":[],"sources":["../../src/utils/paths.ts"],"mappings":";iBAYsB,eAAA,CAAgB,OAAA,WAAkB,OAAO;EAC7D,WAAA;EACA,KAAA;AAAA;AAAA,iBA4BoB,iBAAA,
|
|
1
|
+
{"version":3,"file":"paths.d.ts","names":[],"sources":["../../src/utils/paths.ts"],"mappings":";iBAYsB,eAAA,CAAgB,OAAA,WAAkB,OAAO;EAC7D,WAAA;EACA,KAAA;AAAA;AAAA,iBA4BoB,iBAAA,IAAqB,OAAO;AAAA,iBA0BlC,gBAAA,CACd,aAAA,UACA,cAAwB;AAAA,iBAoCJ,UAAA,CAAW,IAAA,WAAe,OAAO"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/mcp-docs-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.33",
|
|
4
4
|
"description": "MCP server for assistant-ui documentation and examples",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^25.9.1",
|
|
41
|
-
"tsx": "^4.22.
|
|
41
|
+
"tsx": "^4.22.4",
|
|
42
42
|
"vitest": "^4.1.7",
|
|
43
|
-
"@assistant-ui/x-buildutils": "0.0.
|
|
43
|
+
"@assistant-ui/x-buildutils": "0.0.11"
|
|
44
44
|
},
|
|
45
45
|
"publishConfig": {
|
|
46
46
|
"access": "public",
|