@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.
Files changed (112) hide show
  1. package/.docs/organized/code-examples/waterfall.md +15 -17
  2. package/.docs/organized/code-examples/with-a2a.md +19 -19
  3. package/.docs/organized/code-examples/with-ag-ui.md +25 -20
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +6 -4
  5. package/.docs/organized/code-examples/with-artifacts.md +34 -28
  6. package/.docs/organized/code-examples/with-assistant-transport.md +59 -47
  7. package/.docs/organized/code-examples/with-browser-extension.md +17 -5
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +376 -78
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +20 -19
  10. package/.docs/organized/code-examples/with-cloud.md +6 -4
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +9 -7
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +18 -16
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +9 -8
  14. package/.docs/organized/code-examples/with-expo.md +23 -17
  15. package/.docs/organized/code-examples/with-external-store.md +4 -2
  16. package/.docs/organized/code-examples/with-ffmpeg.md +317 -280
  17. package/.docs/organized/code-examples/with-generative-ui.md +1018 -214
  18. package/.docs/organized/code-examples/with-google-adk.md +4 -2
  19. package/.docs/organized/code-examples/with-heat-graph.md +8 -6
  20. package/.docs/organized/code-examples/with-image-generation.md +19 -17
  21. package/.docs/organized/code-examples/with-interactables.md +312 -234
  22. package/.docs/organized/code-examples/with-langchain.md +9 -7
  23. package/.docs/organized/code-examples/with-langgraph.md +82 -78
  24. package/.docs/organized/code-examples/with-livekit.md +19 -17
  25. package/.docs/organized/code-examples/with-mcp.md +13 -7
  26. package/.docs/organized/code-examples/with-opencode.md +61 -61
  27. package/.docs/organized/code-examples/with-react-hook-form.md +14 -12
  28. package/.docs/organized/code-examples/with-react-ink.md +2 -2
  29. package/.docs/organized/code-examples/with-react-router.md +11 -9
  30. package/.docs/organized/code-examples/with-resumable-stream.md +10 -9
  31. package/.docs/organized/code-examples/with-store.md +14 -12
  32. package/.docs/organized/code-examples/with-tanstack.md +8 -9
  33. package/.docs/organized/code-examples/with-tap-runtime.md +21 -19
  34. package/.docs/raw/docs/(docs)/architecture.mdx +43 -2
  35. package/.docs/raw/docs/(docs)/cli.mdx +1 -2
  36. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +34 -26
  37. package/.docs/raw/docs/(docs)/copilots/motivation.mdx +32 -26
  38. package/.docs/raw/docs/(docs)/installation.mdx +1 -1
  39. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +5 -1
  40. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +14 -14
  41. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +11 -1
  42. package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +18 -0
  43. package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +33 -0
  44. package/.docs/raw/docs/(reference)/api-reference/generative-ui/spec.mdx +45 -0
  45. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +41 -41
  46. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +19 -1
  47. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +122 -122
  48. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +32 -2
  49. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +6 -0
  50. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +4 -6
  51. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +30 -0
  52. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +20 -3
  53. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +8 -8
  54. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +52 -4
  55. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +6 -7
  56. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +58 -46
  57. package/.docs/raw/docs/cloud/ai-sdk.mdx +0 -2
  58. package/.docs/raw/docs/guides/chain-of-thought.mdx +7 -9
  59. package/.docs/raw/docs/guides/context-api.mdx +2 -1
  60. package/.docs/raw/docs/guides/index.mdx +3 -12
  61. package/.docs/raw/docs/guides/mentions.mdx +4 -4
  62. package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
  63. package/.docs/raw/docs/guides/suggestions.mdx +1 -1
  64. package/.docs/raw/docs/ink/hooks.mdx +98 -85
  65. package/.docs/raw/docs/ink/migration.mdx +1 -1
  66. package/.docs/raw/docs/ink/primitives.mdx +2 -2
  67. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +1 -1
  68. package/.docs/raw/docs/integrations/index.mdx +2 -2
  69. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +17 -2
  70. package/.docs/raw/docs/migrations/toolkit-tools.mdx +226 -0
  71. package/.docs/raw/docs/primitives/chain-of-thought.mdx +10 -16
  72. package/.docs/raw/docs/primitives/message.mdx +9 -10
  73. package/.docs/raw/docs/react-native/hooks.mdx +57 -82
  74. package/.docs/raw/docs/react-native/migration.mdx +1 -1
  75. package/.docs/raw/docs/react-native/primitives.mdx +2 -2
  76. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +3 -0
  77. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +122 -1
  78. package/.docs/raw/docs/runtimes/concepts/threads.mdx +7 -1
  79. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +18 -7
  80. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +108 -38
  81. package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +2 -2
  82. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +1 -1
  83. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +64 -50
  84. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +98 -86
  85. package/.docs/raw/docs/tools/backend.mdx +136 -0
  86. package/.docs/raw/docs/tools/defining-tools.mdx +413 -0
  87. package/.docs/raw/docs/tools/dynamic-tools.mdx +110 -0
  88. package/.docs/raw/docs/tools/generative-ui.mdx +214 -0
  89. package/.docs/raw/docs/tools/index.mdx +76 -0
  90. package/.docs/raw/docs/{guides → tools}/interactables.mdx +1 -1
  91. package/.docs/raw/docs/{integrations/tools → tools}/mcp.mdx +77 -50
  92. package/.docs/raw/docs/{guides → tools}/multi-agent.mdx +17 -19
  93. package/.docs/raw/docs/tools/tool-ui.mdx +967 -0
  94. package/.docs/raw/docs/{integrations/tools/react-mcp.mdx → tools/user-managed-mcp.mdx} +3 -3
  95. package/.docs/raw/docs/ui/directive-text.mdx +3 -3
  96. package/.docs/raw/docs/ui/mcp-config.mdx +4 -4
  97. package/.docs/raw/docs/ui/part-grouping.mdx +84 -50
  98. package/.docs/raw/docs/ui/reasoning.mdx +4 -5
  99. package/.docs/raw/docs/ui/tool-group.mdx +5 -6
  100. package/.docs/raw/docs/utilities/heat-graph.mdx +1 -1
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  103. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  104. package/dist/utils/paths.d.ts.map +1 -1
  105. package/package.json +3 -3
  106. package/.docs/organized/code-examples/with-parent-id-grouping.md +0 -596
  107. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +0 -151
  108. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +0 -230
  109. package/.docs/raw/docs/guides/generative-ui.mdx +0 -142
  110. package/.docs/raw/docs/guides/tool-ui.mdx +0 -858
  111. package/.docs/raw/docs/guides/tools.mdx +0 -736
  112. /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/integrations/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.
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/integrations/tools/mcp"
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/guides/tools"
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/core";
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/core";
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/core` and renders chips without icons. For per-type icons, build a component with `createDirectiveText(formatter, { iconMap })`.
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/integrations/tools/react-mcp) primitives. Render it anywhere inside an `McpManagerResource`-mounted client and your users get a styled MCP server panel — no manual primitive composition.
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/integrations/tools/react-mcp#handle-the-oauth-callback) for the route handler.
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/integrations/tools/react-mcp"
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/integrations/tools/mcp"
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`. Return a group-key path for each part; adjacent parts that share a group key are coalesced and rendered through the group case.
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={(part) => {
22
- if (part.type === "tool-call") return ["group-tool"];
23
- return null;
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 null;
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 null;
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={(part) => {
151
- if (part.type === "text") return ["group-text-block"];
152
- return null;
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={(part) => {
181
- if (part.type === "text") return ["group-content-text"];
182
- if (part.type === "tool-call") return ["group-content-tools"];
183
- if (part.type === "reasoning") return ["group-content-reasoning"];
184
- return null;
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 null;
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, index: number, parts: readonly PartState[]) => GroupKey",
350
+ type: "(part: PartState) => readonly `group-${string}`[]",
304
351
  description:
305
- "Maps a part to a group-key path. Return null, undefined, or [] to leave the part ungrouped. Group keys must start with group-.",
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 null;
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={(part) => {
395
- if (part.type === "tool-call") return ["group-tools"];
396
- return null;
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={(part) => { // [!code ++]
51
- if (part.type === "reasoning") return ["group-reasoning"]; // [!code ++]
52
- return null; // [!code ++]
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` and return `"group-tool"` for tool-call parts. The group case wraps `children`; the tool-call leaf renders the resolved tool UI or your fallback.
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={(part) => {
48
- if (part.type === "tool-call") return ["group-tool"];
49
- return null;
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
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;cAca,MAAA,EAAM,SAGjB;AAAA,iBAeoB,SAAA,CAAA,GAAS,OAAA"}
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,CAAA,GAAuB,OAAO"}
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,CAAA,GAAW,OAAO"}
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,CAAA,GAAqB,OAAO;AAAA,iBA0BlC,gBAAA,CACd,aAAA,UACA,cAAwB;AAAA,iBAoCJ,UAAA,CAAW,IAAA,WAAe,OAAO"}
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.32",
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.3",
41
+ "tsx": "^4.22.4",
42
42
  "vitest": "^4.1.7",
43
- "@assistant-ui/x-buildutils": "0.0.9"
43
+ "@assistant-ui/x-buildutils": "0.0.11"
44
44
  },
45
45
  "publishConfig": {
46
46
  "access": "public",