@assistant-ui/mcp-docs-server 0.1.30 → 0.1.32

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 (341) hide show
  1. package/.docs/organized/code-examples/waterfall.md +8 -8
  2. package/.docs/organized/code-examples/with-a2a.md +10 -10
  3. package/.docs/organized/code-examples/with-ag-ui.md +12 -12
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +14 -14
  5. package/.docs/organized/code-examples/with-artifacts.md +14 -14
  6. package/.docs/organized/code-examples/with-assistant-transport.md +11 -11
  7. package/.docs/organized/code-examples/with-browser-extension.md +345 -0
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +129 -63
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +13 -13
  10. package/.docs/organized/code-examples/with-cloud.md +13 -13
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +65 -20
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +18 -17
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +18 -17
  14. package/.docs/organized/code-examples/with-expo.md +25 -25
  15. package/.docs/organized/code-examples/with-external-store.md +10 -10
  16. package/.docs/organized/code-examples/with-ffmpeg.md +14 -14
  17. package/.docs/organized/code-examples/with-generative-ui.md +211 -14
  18. package/.docs/organized/code-examples/with-google-adk.md +12 -12
  19. package/.docs/organized/code-examples/with-heat-graph.md +8 -8
  20. package/.docs/organized/code-examples/with-image-generation.md +454 -0
  21. package/.docs/organized/code-examples/with-interactables.md +14 -14
  22. package/.docs/organized/code-examples/with-langchain.md +12 -12
  23. package/.docs/organized/code-examples/with-langgraph.md +15 -12
  24. package/.docs/organized/code-examples/with-livekit.md +19 -18
  25. package/.docs/organized/code-examples/with-mcp.md +748 -0
  26. package/.docs/organized/code-examples/with-opencode.md +107 -62
  27. package/.docs/organized/code-examples/with-parent-id-grouping.md +12 -12
  28. package/.docs/organized/code-examples/with-react-hook-form.md +14 -14
  29. package/.docs/organized/code-examples/with-react-ink.md +4 -4
  30. package/.docs/organized/code-examples/with-react-router.md +16 -16
  31. package/.docs/organized/code-examples/with-resumable-stream.md +660 -0
  32. package/.docs/organized/code-examples/with-store.md +8 -8
  33. package/.docs/organized/code-examples/with-tanstack.md +14 -14
  34. package/.docs/organized/code-examples/with-tap-runtime.md +11 -10
  35. package/.docs/raw/docs/(docs)/cli.mdx +3 -1
  36. package/.docs/raw/docs/(docs)/copilots/assistant-frame.mdx +1 -0
  37. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +10 -3
  38. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +8 -3
  39. package/.docs/raw/docs/(docs)/copilots/make-assistant-visible.mdx +1 -0
  40. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +1 -0
  41. package/.docs/raw/docs/(docs)/copilots/motivation.mdx +1 -0
  42. package/.docs/raw/docs/(docs)/copilots/use-assistant-instructions.mdx +1 -0
  43. package/.docs/raw/docs/(docs)/devtools.mdx +1 -0
  44. package/.docs/raw/docs/(docs)/index.mdx +3 -2
  45. package/.docs/raw/docs/(docs)/installation.mdx +2 -1
  46. package/.docs/raw/docs/(docs)/rtl.mdx +1 -0
  47. package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +36 -0
  48. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback.mdx +20 -0
  49. package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +34 -0
  50. package/.docs/raw/docs/(reference)/api-reference/adapters/model.mdx +44 -0
  51. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +55 -0
  52. package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +20 -0
  53. package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +20 -0
  54. package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +37 -8
  55. package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +22 -0
  56. package/.docs/raw/docs/(reference)/api-reference/context-providers/scoped-providers.mdx +64 -0
  57. package/.docs/raw/docs/(reference)/api-reference/external-store/index.mdx +22 -0
  58. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +52 -0
  59. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +36 -0
  60. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +98 -0
  61. package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +31 -0
  62. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +33 -0
  63. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +640 -0
  64. package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +28 -0
  65. package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +94 -0
  66. package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +464 -0
  67. package/.docs/raw/docs/(reference)/api-reference/integrations/cloud-ai-sdk.mdx +24 -0
  68. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +22 -0
  69. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +79 -0
  70. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +52 -0
  71. package/.docs/raw/docs/(reference)/api-reference/model-context/index.mdx +22 -0
  72. package/.docs/raw/docs/(reference)/api-reference/model-context/registry.mdx +20 -0
  73. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +125 -125
  74. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +78 -221
  75. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +127 -242
  76. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +46 -20
  77. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +66 -87
  78. package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +50 -58
  79. package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +80 -48
  80. package/.docs/raw/docs/(reference)/api-reference/primitives/chain-of-thought.mdx +67 -0
  81. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +323 -461
  82. package/.docs/raw/docs/(reference)/api-reference/primitives/error.mdx +36 -43
  83. package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +70 -0
  84. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +63 -245
  85. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +182 -554
  86. package/.docs/raw/docs/(reference)/api-reference/primitives/queue-item.mdx +65 -0
  87. package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +35 -22
  88. package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +57 -140
  89. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item-more.mdx +70 -161
  90. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +84 -108
  91. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +82 -86
  92. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +173 -314
  93. package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +9 -21
  94. package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +10 -21
  95. package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +15 -70
  96. package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +43 -0
  97. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +25 -28
  98. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +11 -63
  99. package/.docs/raw/docs/(reference)/api-reference/runtimes/queue-state.mdx +20 -0
  100. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +11 -48
  101. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +10 -42
  102. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +18 -30
  103. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +68 -0
  104. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +39 -0
  105. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +79 -0
  106. package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +42 -0
  107. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +92 -0
  108. package/.docs/raw/docs/(reference)/api-reference/transport/assistant-transport.mdx +48 -0
  109. package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +62 -0
  110. package/.docs/raw/docs/(reference)/api-reference/transport/index.mdx +22 -0
  111. package/.docs/raw/docs/(reference)/api-reference/utilities/index.mdx +19 -0
  112. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +131 -0
  113. package/.docs/raw/docs/(reference)/api-reference/voice/index.mdx +22 -0
  114. package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +54 -0
  115. package/.docs/raw/docs/(reference)/api-reference/voice/speech-dictation.mdx +36 -0
  116. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +230 -2
  117. package/.docs/raw/docs/cloud/ai-sdk.mdx +222 -4
  118. package/.docs/raw/docs/cloud/index.mdx +2 -2
  119. package/.docs/raw/docs/cloud/langgraph.mdx +274 -2
  120. package/.docs/raw/docs/{(docs)/guides → guides}/attachments.mdx +45 -40
  121. package/.docs/raw/docs/guides/branching.mdx +76 -0
  122. package/.docs/raw/docs/guides/chain-of-thought.mdx +166 -0
  123. package/.docs/raw/docs/{(docs)/guides → guides}/context-api.mdx +54 -26
  124. package/.docs/raw/docs/{(docs)/guides → guides}/dictation.mdx +3 -1
  125. package/.docs/raw/docs/guides/editing.mdx +102 -0
  126. package/.docs/raw/docs/guides/generative-ui.mdx +142 -0
  127. package/.docs/raw/docs/guides/image-generation.mdx +74 -0
  128. package/.docs/raw/docs/guides/index.mdx +103 -0
  129. package/.docs/raw/docs/{(docs)/guides → guides}/interactables.mdx +51 -2
  130. package/.docs/raw/docs/{(docs)/guides → guides}/latex.mdx +53 -10
  131. package/.docs/raw/docs/guides/mcp-apps.mdx +231 -0
  132. package/.docs/raw/docs/{(docs)/guides → guides}/mentions.mdx +63 -88
  133. package/.docs/raw/docs/{(docs)/guides → guides}/message-timing.mdx +45 -6
  134. package/.docs/raw/docs/{(docs)/guides → guides}/multi-agent.mdx +66 -6
  135. package/.docs/raw/docs/{(docs)/guides → guides}/quoting.mdx +11 -18
  136. package/.docs/raw/docs/guides/resumable-stream-deployment.mdx +212 -0
  137. package/.docs/raw/docs/guides/resumable-stream-stores.mdx +152 -0
  138. package/.docs/raw/docs/guides/resumable-streams.mdx +210 -0
  139. package/.docs/raw/docs/{(docs)/guides → guides}/slash-commands.mdx +104 -38
  140. package/.docs/raw/docs/guides/speech.mdx +156 -0
  141. package/.docs/raw/docs/{(docs)/guides → guides}/suggestions.mdx +91 -69
  142. package/.docs/raw/docs/{(docs)/guides → guides}/tool-ui.mdx +110 -38
  143. package/.docs/raw/docs/{(docs)/guides → guides}/tools.mdx +197 -40
  144. package/.docs/raw/docs/{(docs)/guides → guides}/voice.mdx +41 -2
  145. package/.docs/raw/docs/ink/adapters.mdx +37 -1
  146. package/.docs/raw/docs/ink/custom-backend.mdx +59 -8
  147. package/.docs/raw/docs/ink/index.mdx +11 -14
  148. package/.docs/raw/docs/ink/migration.mdx +1 -3
  149. package/.docs/raw/docs/ink/primitives.mdx +386 -9
  150. package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +520 -0
  151. package/.docs/raw/docs/integrations/auth/better-auth.mdx +191 -0
  152. package/.docs/raw/docs/integrations/auth/clerk.mdx +172 -0
  153. package/.docs/raw/docs/integrations/auth/next-auth.mdx +196 -0
  154. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +79 -0
  155. package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +282 -0
  156. package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +188 -0
  157. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +57 -0
  158. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +201 -0
  159. package/.docs/raw/docs/integrations/gateways/index.mdx +162 -0
  160. package/.docs/raw/docs/integrations/index.mdx +185 -0
  161. package/.docs/raw/docs/integrations/observability/helicone.mdx +130 -0
  162. package/.docs/raw/docs/integrations/observability/langfuse.mdx +163 -0
  163. package/.docs/raw/docs/integrations/observability/langsmith.mdx +150 -0
  164. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +712 -0
  165. package/.docs/raw/docs/integrations/tools/mcp.mdx +267 -0
  166. package/.docs/raw/docs/integrations/tools/react-mcp.mdx +337 -0
  167. package/.docs/raw/docs/migrations/v0-14.mdx +297 -0
  168. package/.docs/raw/docs/primitives/action-bar.mdx +1 -0
  169. package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -0
  170. package/.docs/raw/docs/primitives/attachment.mdx +1 -0
  171. package/.docs/raw/docs/primitives/branch-picker.mdx +1 -0
  172. package/.docs/raw/docs/primitives/chain-of-thought.mdx +90 -85
  173. package/.docs/raw/docs/primitives/composer.mdx +55 -1
  174. package/.docs/raw/docs/primitives/error.mdx +1 -0
  175. package/.docs/raw/docs/primitives/index.mdx +4 -3
  176. package/.docs/raw/docs/primitives/message.mdx +68 -5
  177. package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -0
  178. package/.docs/raw/docs/primitives/suggestion.mdx +10 -0
  179. package/.docs/raw/docs/primitives/thread-list.mdx +39 -0
  180. package/.docs/raw/docs/primitives/thread.mdx +16 -13
  181. package/.docs/raw/docs/react-native/hooks.mdx +2 -2
  182. package/.docs/raw/docs/react-native/index.mdx +5 -7
  183. package/.docs/raw/docs/react-native/migration.mdx +1 -3
  184. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +396 -0
  185. package/.docs/raw/docs/runtimes/a2a/overview.mdx +60 -0
  186. package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +216 -0
  187. package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +70 -0
  188. package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +243 -0
  189. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +154 -0
  190. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +52 -0
  191. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +73 -128
  192. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +70 -64
  193. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +337 -123
  194. package/.docs/raw/docs/runtimes/concepts/adapters.mdx +265 -0
  195. package/.docs/raw/docs/runtimes/concepts/architecture.mdx +125 -0
  196. package/.docs/raw/docs/runtimes/concepts/stability.mdx +67 -0
  197. package/.docs/raw/docs/runtimes/concepts/threads.mdx +428 -0
  198. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +703 -0
  199. package/.docs/raw/docs/runtimes/custom/data-stream.mdx +348 -0
  200. package/.docs/raw/docs/runtimes/custom/external-store.mdx +261 -1236
  201. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +746 -0
  202. package/.docs/raw/docs/runtimes/custom/overview.mdx +71 -0
  203. package/.docs/raw/docs/runtimes/google-adk/api.mdx +256 -0
  204. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +717 -0
  205. package/.docs/raw/docs/runtimes/google-adk/overview.mdx +69 -0
  206. package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +229 -0
  207. package/.docs/raw/docs/runtimes/langchain.mdx +533 -0
  208. package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +305 -0
  209. package/.docs/raw/docs/runtimes/langgraph/interrupts.mdx +104 -0
  210. package/.docs/raw/docs/runtimes/langgraph/overview.mdx +84 -0
  211. package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +496 -0
  212. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +127 -0
  213. package/.docs/raw/docs/runtimes/langgraph/threads.mdx +113 -0
  214. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +3 -3
  215. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +0 -23
  216. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +1 -1
  217. package/.docs/raw/docs/runtimes/opencode/hooks.mdx +191 -0
  218. package/.docs/raw/docs/runtimes/opencode/overview.mdx +48 -0
  219. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +119 -0
  220. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +78 -203
  221. package/.docs/raw/docs/ui/accordion.mdx +1 -0
  222. package/.docs/raw/docs/ui/assistant-modal.mdx +1 -0
  223. package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -0
  224. package/.docs/raw/docs/ui/attachment.mdx +1 -0
  225. package/.docs/raw/docs/ui/badge.mdx +1 -0
  226. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +12 -1
  227. package/.docs/raw/docs/ui/context-display.mdx +1 -0
  228. package/.docs/raw/docs/ui/diff-viewer.mdx +1 -0
  229. package/.docs/raw/docs/ui/directive-text.mdx +1 -0
  230. package/.docs/raw/docs/ui/file.mdx +1 -0
  231. package/.docs/raw/docs/ui/image.mdx +1 -0
  232. package/.docs/raw/docs/ui/markdown.mdx +2 -14
  233. package/.docs/raw/docs/ui/mcp-config.mdx +102 -0
  234. package/.docs/raw/docs/ui/mermaid.mdx +1 -0
  235. package/.docs/raw/docs/ui/message-timing.mdx +3 -2
  236. package/.docs/raw/docs/ui/model-selector.mdx +9 -8
  237. package/.docs/raw/docs/ui/part-grouping.mdx +325 -313
  238. package/.docs/raw/docs/ui/quote.mdx +1 -0
  239. package/.docs/raw/docs/ui/reasoning.mdx +66 -33
  240. package/.docs/raw/docs/ui/scrollbar.mdx +1 -0
  241. package/.docs/raw/docs/ui/select.mdx +1 -0
  242. package/.docs/raw/docs/ui/sources.mdx +18 -0
  243. package/.docs/raw/docs/ui/streamdown.mdx +35 -2
  244. package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -0
  245. package/.docs/raw/docs/ui/tabs.mdx +1 -0
  246. package/.docs/raw/docs/ui/thread-list.mdx +19 -2
  247. package/.docs/raw/docs/ui/thread.mdx +58 -3
  248. package/.docs/raw/docs/ui/tool-fallback.mdx +1 -0
  249. package/.docs/raw/docs/ui/tool-group.mdx +39 -11
  250. package/.docs/raw/docs/ui/voice.mdx +1 -0
  251. package/.docs/raw/docs/utilities/heat-graph.mdx +1 -0
  252. package/.docs/raw/docs/utilities/react-o11y.mdx +278 -0
  253. package/.docs/raw/docs/utilities/tw-shimmer.mdx +1 -0
  254. package/README.md +14 -72
  255. package/dist/constants.d.ts +12 -9
  256. package/dist/constants.d.ts.map +1 -1
  257. package/dist/constants.js +13 -9
  258. package/dist/constants.js.map +1 -1
  259. package/dist/index.d.ts +7 -3
  260. package/dist/index.d.ts.map +1 -1
  261. package/dist/index.js +25 -24
  262. package/dist/index.js.map +1 -1
  263. package/dist/prepare-docs/code-examples.d.ts +4 -1
  264. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  265. package/dist/prepare-docs/code-examples.js +109 -121
  266. package/dist/prepare-docs/code-examples.js.map +1 -1
  267. package/dist/prepare-docs/copy-raw.d.ts +4 -1
  268. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  269. package/dist/prepare-docs/copy-raw.js +45 -42
  270. package/dist/prepare-docs/copy-raw.js.map +1 -1
  271. package/dist/prepare-docs/prepare.d.ts +1 -2
  272. package/dist/prepare-docs/prepare.js +17 -17
  273. package/dist/prepare-docs/prepare.js.map +1 -1
  274. package/dist/stdio.d.ts +1 -3
  275. package/dist/stdio.js +6 -3
  276. package/dist/stdio.js.map +1 -1
  277. package/dist/tools/docs.d.ts +20 -15
  278. package/dist/tools/docs.d.ts.map +1 -1
  279. package/dist/tools/docs.js +140 -161
  280. package/dist/tools/docs.js.map +1 -1
  281. package/dist/tools/examples.d.ts +20 -15
  282. package/dist/tools/examples.d.ts.map +1 -1
  283. package/dist/tools/examples.js +74 -86
  284. package/dist/tools/examples.js.map +1 -1
  285. package/dist/tools/tests/test-setup.d.ts +5 -2
  286. package/dist/tools/tests/test-setup.d.ts.map +1 -1
  287. package/dist/tools/tests/test-setup.js +21 -28
  288. package/dist/tools/tests/test-setup.js.map +1 -1
  289. package/dist/utils/logger.d.ts +8 -5
  290. package/dist/utils/logger.d.ts.map +1 -1
  291. package/dist/utils/logger.js +17 -17
  292. package/dist/utils/logger.js.map +1 -1
  293. package/dist/utils/mcp-format.d.ts +8 -5
  294. package/dist/utils/mcp-format.d.ts.map +1 -1
  295. package/dist/utils/mcp-format.js +9 -9
  296. package/dist/utils/mcp-format.js.map +1 -1
  297. package/dist/utils/mdx.d.ts +8 -6
  298. package/dist/utils/mdx.d.ts.map +1 -1
  299. package/dist/utils/mdx.js +22 -22
  300. package/dist/utils/mdx.js.map +1 -1
  301. package/dist/utils/paths.d.ts +9 -6
  302. package/dist/utils/paths.d.ts.map +1 -1
  303. package/dist/utils/paths.js +66 -76
  304. package/dist/utils/paths.js.map +1 -1
  305. package/dist/utils/security.d.ts +4 -1
  306. package/dist/utils/security.d.ts.map +1 -1
  307. package/dist/utils/security.js +19 -40
  308. package/dist/utils/security.js.map +1 -1
  309. package/package.json +6 -6
  310. package/src/tools/tests/path-traversal.test.ts +1 -1
  311. package/.docs/raw/docs/(docs)/guides/branching.mdx +0 -65
  312. package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +0 -164
  313. package/.docs/raw/docs/(docs)/guides/editing.mdx +0 -66
  314. package/.docs/raw/docs/(docs)/guides/speech.mdx +0 -38
  315. package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +0 -40
  316. package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +0 -260
  317. package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +0 -103
  318. package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +0 -254
  319. package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +0 -159
  320. package/.docs/raw/docs/runtimes/a2a/index.mdx +0 -298
  321. package/.docs/raw/docs/runtimes/assistant-transport.mdx +0 -1033
  322. package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +0 -314
  323. package/.docs/raw/docs/runtimes/custom/local.mdx +0 -1464
  324. package/.docs/raw/docs/runtimes/data-stream.mdx +0 -422
  325. package/.docs/raw/docs/runtimes/google-adk/index.mdx +0 -686
  326. package/.docs/raw/docs/runtimes/helicone.mdx +0 -61
  327. package/.docs/raw/docs/runtimes/langchain/comparison.mdx +0 -60
  328. package/.docs/raw/docs/runtimes/langchain/index.mdx +0 -210
  329. package/.docs/raw/docs/runtimes/langgraph/index.mdx +0 -699
  330. package/.docs/raw/docs/runtimes/langgraph/tutorial/index.mdx +0 -12
  331. package/.docs/raw/docs/runtimes/langserve.mdx +0 -116
  332. package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +0 -218
  333. package/.docs/raw/docs/runtimes/mastra/overview.mdx +0 -18
  334. package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +0 -217
  335. package/dist/prepare-docs/prepare.d.ts.map +0 -1
  336. package/dist/stdio.d.ts.map +0 -1
  337. /package/.docs/raw/docs/{(reference)/migrations → migrations}/deprecation-policy.mdx +0 -0
  338. /package/.docs/raw/docs/{(reference) → migrations}/react-compatibility.mdx +0 -0
  339. /package/.docs/raw/docs/{(reference)/migrations → migrations}/react-langgraph-v0-7.mdx +0 -0
  340. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-11.mdx +0 -0
  341. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-12.mdx +0 -0
@@ -1,44 +1,39 @@
1
1
  ---
2
2
  title: Message Part Grouping
3
3
  description: Organize message parts into custom groups with flexible grouping functions.
4
+ platforms: ["react"]
4
5
  ---
5
6
 
6
7
  import { PartGroupingSample } from "@/components/docs/samples/part-grouping";
7
8
 
8
9
  <PartGroupingSample />
9
10
 
10
- <Callout type="warn">
11
- This feature is experimental and the API may change in future versions.
12
- </Callout>
13
-
14
11
  ## Basic Usage
15
12
 
16
- Use the `MessagePrimitive.Unstable_PartsGrouped` component with a custom grouping function:
17
-
18
- ```tsx twoslash title="/components/assistant-ui/thread.tsx"
19
- import { FC, PropsWithChildren } from "react";
20
- import { MessagePrimitive } from "@assistant-ui/react";
21
-
22
- const AssistantActionBar: FC = () => null;
23
- const BranchPicker: FC<{ className?: string }> = () => null;
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.
24
14
 
25
- // ---cut---
15
+ ```tsx title="/components/assistant-ui/thread.tsx"
26
16
  const AssistantMessage: FC = () => {
27
17
  return (
28
18
  <MessagePrimitive.Root className="...">
29
19
  <div className="...">
30
- <MessagePrimitive.Unstable_PartsGrouped
31
- groupingFunction={(parts) => {
32
- // Your custom grouping logic here
33
- return [{ groupKey: undefined, indices: [0, 1, 2] }];
20
+ <MessagePrimitive.GroupedParts
21
+ groupBy={(part) => {
22
+ if (part.type === "tool-call") return ["group-tool"];
23
+ return null;
34
24
  }}
35
- components={{
36
- Group: ({ groupKey, indices, children }) => {
37
- // Your custom group rendering
38
- return <div className="group">{children}</div>;
39
- },
25
+ >
26
+ {({ part, children }) => {
27
+ switch (part.type) {
28
+ case "group-tool":
29
+ return <div className="group">{children}</div>;
30
+ case "tool-call":
31
+ return part.toolUI ?? null;
32
+ default:
33
+ return null;
34
+ }
40
35
  }}
41
- />
36
+ </MessagePrimitive.GroupedParts>
42
37
  </div>
43
38
  <AssistantActionBar />
44
39
  <BranchPicker className="..." />
@@ -47,107 +42,103 @@ const AssistantMessage: FC = () => {
47
42
  };
48
43
  ```
49
44
 
50
- ## How Grouping Works
45
+ ## How Adjacent Grouping Works
46
+
47
+ `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.
51
48
 
52
- The grouping function receives all message parts and returns an array of groups. Each group contains:
49
+ The render function receives both group nodes and leaf parts through `{ part, children }`. Only group cases should render `children`; leaf cases should render their own UI or return `null`.
53
50
 
54
- - `groupKey`: A string identifier for the group (or `undefined` for ungrouped parts)
55
- - `indices`: An array of indices indicating which parts belong to this group
51
+ <Callout type="warn">
52
+ `MessagePrimitive.Unstable_PartsGrouped` remains available for rare non-adjacent clustering where one group needs to collect parts from different positions in the message. For normal consecutive reasoning/tool grouping, use `GroupedParts`.
53
+ </Callout>
56
54
 
57
55
  ## Use Cases & Examples
58
56
 
59
57
  ### Group by Parent ID
60
58
 
61
- Group related content together using a parent-child relationship:
59
+ Group adjacent content that shares the same parent relationship:
62
60
 
63
61
  ```tsx
64
- import { FC, PropsWithChildren, useState } from "react";
62
+ import { useState, type PropsWithChildren } from "react";
65
63
  import { ChevronDownIcon, ChevronUpIcon } from "lucide-react";
64
+ import { MessagePrimitive } from "@assistant-ui/react";
66
65
 
67
- const groupByParentId = (parts: readonly any[]) => {
68
- const groups = new Map<string, number[]>();
69
-
70
- for (let i = 0; i < parts.length; i++) {
71
- const part = parts[i];
72
- const groupId = part?.parentId ?? `__ungrouped_${i}`;
73
-
74
- const indices = groups.get(groupId) ?? [];
75
- indices.push(i);
76
- groups.set(groupId, indices);
77
- }
78
-
79
- return Array.from(groups.entries()).map(([groupId, indices]) => ({
80
- groupKey: groupId.startsWith("__ungrouped_") ? undefined : groupId,
81
- indices,
82
- }));
83
- };
84
-
85
- // Usage with collapsible groups
86
- const CollapsibleGroup: FC<
87
- PropsWithChildren<{ groupKey: string | undefined; indices: number[] }>
88
- > = ({ groupKey, indices, children }) => {
89
- const [isCollapsed, setIsCollapsed] = useState(false);
90
-
91
- if (!groupKey) return <>{children}</>;
66
+ function ParentGroup({
67
+ id,
68
+ count,
69
+ children,
70
+ }: PropsWithChildren<{ id: string; count: number }>) {
71
+ const [collapsed, setCollapsed] = useState(false);
92
72
 
93
73
  return (
94
74
  <div className="my-2 overflow-hidden rounded-lg border">
95
75
  <button
96
- onClick={() => setIsCollapsed(!isCollapsed)}
76
+ type="button"
77
+ onClick={() => setCollapsed((value) => !value)}
97
78
  className="hover:bg-muted/50 flex w-full items-center justify-between p-3"
98
79
  >
99
80
  <span>
100
- Group {groupKey} ({indices.length} items)
81
+ Group {id} ({count} items)
101
82
  </span>
102
- {isCollapsed ? <ChevronDownIcon /> : <ChevronUpIcon />}
83
+ {collapsed ? <ChevronDownIcon /> : <ChevronUpIcon />}
103
84
  </button>
104
- {!isCollapsed && <div className="border-t p-3">{children}</div>}
85
+ {!collapsed && <div className="border-t p-3">{children}</div>}
105
86
  </div>
106
87
  );
107
- };
88
+ }
89
+
90
+ <MessagePrimitive.GroupedParts
91
+ groupBy={(part) => {
92
+ if (!part.parentId) return null;
93
+ return [`group-parent-${part.parentId}`];
94
+ }}
95
+ >
96
+ {({ part, children }) => {
97
+ if (part.type.startsWith("group-parent-")) {
98
+ const id = part.type.replace("group-parent-", "");
99
+ return (
100
+ <ParentGroup id={id} count={part.indices.length}>
101
+ {children}
102
+ </ParentGroup>
103
+ );
104
+ }
105
+
106
+ if (part.type === "text") return <MarkdownText />;
107
+ if (part.type === "tool-call") return part.toolUI ?? <ToolFallback {...part} />;
108
+ return null;
109
+ }}
110
+ </MessagePrimitive.GroupedParts>
108
111
  ```
109
112
 
110
113
  ### Group by Tool Name
111
114
 
112
- Organize tool calls by their type:
115
+ Organize adjacent tool calls by tool name:
113
116
 
114
117
  ```tsx
115
- import { FC, PropsWithChildren } from "react";
116
-
117
- const groupByToolName = (parts: readonly any[]) => {
118
- const groups = new Map<string, number[]>();
119
-
120
- for (let i = 0; i < parts.length; i++) {
121
- const part = parts[i];
122
- // Group tool calls by tool name, everything else ungrouped
123
- const groupKey = part.type === "tool-call" ? part.toolName : `__other_${i}`;
124
-
125
- const indices = groups.get(groupKey) ?? [];
126
- indices.push(i);
127
- groups.set(groupKey, indices);
128
- }
129
-
130
- return Array.from(groups.entries()).map(([groupKey, indices]) => ({
131
- groupKey: groupKey.startsWith("__other_") ? undefined : groupKey,
132
- indices,
133
- }));
134
- };
135
-
136
- // Render tool groups with custom styling
137
- const ToolGroup: FC<
138
- PropsWithChildren<{ groupKey: string | undefined; indices: number[] }>
139
- > = ({ groupKey, indices, children }) => {
140
- if (!groupKey) return <>{children}</>;
118
+ <MessagePrimitive.GroupedParts
119
+ groupBy={(part) => {
120
+ if (part.type !== "tool-call") return null;
121
+ return [`group-tool-${part.toolName}`];
122
+ }}
123
+ >
124
+ {({ part, children }) => {
125
+ if (part.type.startsWith("group-tool-")) {
126
+ const toolName = part.type.replace("group-tool-", "");
127
+ return (
128
+ <div className="tool-group my-2 rounded-lg border">
129
+ <div className="bg-muted/50 px-4 py-2 text-sm font-medium">
130
+ Tool: {toolName} ({part.indices.length} calls)
131
+ </div>
132
+ <div className="p-4">{children}</div>
133
+ </div>
134
+ );
135
+ }
141
136
 
142
- return (
143
- <div className="tool-group my-2 rounded-lg border">
144
- <div className="bg-muted/50 px-4 py-2 text-sm font-medium">
145
- Tool: {groupKey} ({indices.length} calls)
146
- </div>
147
- <div className="p-4">{children}</div>
148
- </div>
149
- );
150
- };
137
+ if (part.type === "text") return <MarkdownText />;
138
+ if (part.type === "tool-call") return part.toolUI ?? <ToolFallback {...part} />;
139
+ return null;
140
+ }}
141
+ </MessagePrimitive.GroupedParts>
151
142
  ```
152
143
 
153
144
  ### Group Consecutive Text Parts
@@ -155,58 +146,29 @@ const ToolGroup: FC<
155
146
  Combine multiple text parts into cohesive blocks:
156
147
 
157
148
  ```tsx
158
- import { FC, PropsWithChildren } from "react";
159
-
160
- type MessagePartGroup = {
161
- groupKey: string | undefined;
162
- indices: number[];
163
- };
164
-
165
- const groupConsecutiveText = (parts: readonly any[]) => {
166
- const groups: MessagePartGroup[] = [];
167
- let currentGroup: number[] = [];
168
- let isTextGroup = false;
169
-
170
- for (let i = 0; i < parts.length; i++) {
171
- const isText = parts[i].type === "text";
172
-
173
- if (isText === isTextGroup && currentGroup.length > 0) {
174
- currentGroup.push(i);
175
- } else {
176
- if (currentGroup.length > 0) {
177
- groups.push({
178
- groupKey: isTextGroup ? "text-block" : undefined,
179
- indices: currentGroup,
180
- });
181
- }
182
- currentGroup = [i];
183
- isTextGroup = isText;
149
+ <MessagePrimitive.GroupedParts
150
+ groupBy={(part) => {
151
+ if (part.type === "text") return ["group-text-block"];
152
+ return null;
153
+ }}
154
+ >
155
+ {({ part, children }) => {
156
+ switch (part.type) {
157
+ case "group-text-block":
158
+ return (
159
+ <div className="prose prose-sm my-2 rounded-lg bg-gray-50 p-4">
160
+ {children}
161
+ </div>
162
+ );
163
+ case "text":
164
+ return <MarkdownText />;
165
+ case "tool-call":
166
+ return part.toolUI ?? <ToolFallback {...part} />;
167
+ default:
168
+ return null;
184
169
  }
185
- }
186
-
187
- if (currentGroup.length > 0) {
188
- groups.push({
189
- groupKey: isTextGroup ? "text-block" : undefined,
190
- indices: currentGroup,
191
- });
192
- }
193
-
194
- return groups;
195
- };
196
-
197
- // Render text blocks with special formatting
198
- const TextBlockGroup: FC<
199
- PropsWithChildren<{ groupKey: string | undefined; indices: number[] }>
200
- > = ({ groupKey, indices, children }) => {
201
- if (groupKey === "text-block") {
202
- return (
203
- <div className="prose prose-sm my-2 rounded-lg bg-gray-50 p-4">
204
- {children}
205
- </div>
206
- );
207
- }
208
- return <>{children}</>;
209
- };
170
+ }}
171
+ </MessagePrimitive.GroupedParts>
210
172
  ```
211
173
 
212
174
  ### Group by Content Type
@@ -214,50 +176,33 @@ const TextBlockGroup: FC<
214
176
  Separate different types of content for distinct visual treatment:
215
177
 
216
178
  ```tsx
217
- type MessagePartGroup = {
218
- groupKey: string | undefined;
219
- indices: number[];
220
- };
221
-
222
- const groupByContentType = (parts: readonly any[]) => {
223
- const typeGroups = new Map<string, number[]>();
224
-
225
- for (let i = 0; i < parts.length; i++) {
226
- const part = parts[i];
227
- const type = part.type;
228
-
229
- const indices = typeGroups.get(type) ?? [];
230
- indices.push(i);
231
- typeGroups.set(type, indices);
232
- }
233
-
234
- // Order groups by type priority
235
- const typeOrder = [
236
- "reasoning",
237
- "tool-call",
238
- "source",
239
- "text",
240
- "image",
241
- "file",
242
- ];
243
- const orderedGroups: MessagePartGroup[] = [];
244
-
245
- for (const type of typeOrder) {
246
- const indices = typeGroups.get(type);
247
- if (indices && indices.length > 0) {
248
- orderedGroups.push({ groupKey: type, indices });
179
+ <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
+ }}
186
+ >
187
+ {({ part, children }) => {
188
+ switch (part.type) {
189
+ case "group-content-text":
190
+ return <div className="space-y-2">{children}</div>;
191
+ case "group-content-tools":
192
+ return <div className="my-2 rounded-lg border p-3">{children}</div>;
193
+ case "group-content-reasoning":
194
+ return <div className="my-2 text-muted-foreground">{children}</div>;
195
+ case "text":
196
+ return <MarkdownText />;
197
+ case "reasoning":
198
+ return <Reasoning {...part} />;
199
+ case "tool-call":
200
+ return part.toolUI ?? <ToolFallback {...part} />;
201
+ default:
202
+ return null;
249
203
  }
250
- }
251
-
252
- // Add any remaining types
253
- for (const [type, indices] of typeGroups) {
254
- if (!typeOrder.includes(type)) {
255
- orderedGroups.push({ groupKey: type, indices });
256
- }
257
- }
258
-
259
- return orderedGroups;
260
- };
204
+ }}
205
+ </MessagePrimitive.GroupedParts>
261
206
  ```
262
207
 
263
208
  ### Group by Custom Metadata
@@ -265,63 +210,39 @@ const groupByContentType = (parts: readonly any[]) => {
265
210
  Use any custom metadata in your parts for grouping:
266
211
 
267
212
  ```tsx
268
- import { FC, PropsWithChildren } from "react";
269
-
270
- type MessagePartGroup = {
271
- groupKey: string | undefined;
272
- indices: number[];
213
+ const priorityStyles = {
214
+ high: "border-red-500 bg-red-50",
215
+ normal: "border-gray-300 bg-white",
216
+ low: "border-gray-200 bg-gray-50",
273
217
  };
274
218
 
275
- const groupByPriority = (parts: readonly any[]) => {
276
- const priorityGroups = new Map<string, number[]>();
277
-
278
- for (let i = 0; i < parts.length; i++) {
279
- const part = parts[i];
280
- // Assume parts have a custom priority field
281
- const priority = part.priority || "normal";
282
-
283
- const indices = priorityGroups.get(priority) ?? [];
284
- indices.push(i);
285
- priorityGroups.set(priority, indices);
286
- }
287
-
288
- // Order by priority
289
- const priorityOrder = ["high", "normal", "low"];
290
- const orderedGroups: MessagePartGroup[] = [];
291
-
292
- for (const priority of priorityOrder) {
293
- const indices = priorityGroups.get(priority);
294
- if (indices) {
295
- orderedGroups.push({ groupKey: priority, indices });
219
+ <MessagePrimitive.GroupedParts
220
+ groupBy={(part) => {
221
+ const priority = part.metadata?.priority;
222
+ if (!priority) return null;
223
+ return [`group-priority-${priority}`];
224
+ }}
225
+ >
226
+ {({ part, children }) => {
227
+ if (part.type.startsWith("group-priority-")) {
228
+ const priority = part.type.replace("group-priority-", "");
229
+ return (
230
+ <div
231
+ className={`my-2 rounded-lg border-2 p-4 ${priorityStyles[priority] || ""}`}
232
+ >
233
+ <div className="mb-2 text-xs font-semibold uppercase text-gray-600">
234
+ {priority} Priority
235
+ </div>
236
+ {children}
237
+ </div>
238
+ );
296
239
  }
297
- }
298
-
299
- return orderedGroups;
300
- };
301
240
 
302
- // Render with priority indicators
303
- const PriorityGroup: FC<
304
- PropsWithChildren<{ groupKey: string | undefined; indices: number[] }>
305
- > = ({ groupKey, indices, children }) => {
306
- if (!groupKey) return <>{children}</>;
307
-
308
- const priorityStyles = {
309
- high: "border-red-500 bg-red-50",
310
- normal: "border-gray-300 bg-white",
311
- low: "border-gray-200 bg-gray-50",
312
- };
313
-
314
- return (
315
- <div
316
- className={`my-2 rounded-lg border-2 p-4 ${priorityStyles[groupKey] || ""}`}
317
- >
318
- <div className="mb-2 text-xs font-semibold uppercase text-gray-600">
319
- {groupKey} Priority
320
- </div>
321
- {children}
322
- </div>
323
- );
324
- };
241
+ if (part.type === "text") return <MarkdownText />;
242
+ if (part.type === "tool-call") return part.toolUI ?? <ToolFallback {...part} />;
243
+ return null;
244
+ }}
245
+ </MessagePrimitive.GroupedParts>
325
246
  ```
326
247
 
327
248
  ## Integration with Assistant Streams
@@ -372,23 +293,181 @@ const stream = createAssistantStream(async (controller) => {
372
293
 
373
294
  ## API Reference
374
295
 
375
- ### MessagePrimitive.Unstable_PartsGrouped
296
+ ### MessagePrimitive.GroupedParts
297
+
298
+ <ParametersTable
299
+ type="MessagePrimitiveGroupedPartsProps"
300
+ parameters={[
301
+ {
302
+ name: "groupBy",
303
+ type: "(part: PartState, index: number, parts: readonly PartState[]) => GroupKey",
304
+ 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-.",
306
+ required: true,
307
+ },
308
+ {
309
+ name: "children",
310
+ type: "({ part, children }) => ReactNode",
311
+ description:
312
+ "Render function called for group nodes and leaf parts. Group nodes expose children; leaf parts should render their own UI or return null.",
313
+ required: true,
314
+ },
315
+ ]}
316
+ />
317
+
318
+ ### GroupPart Type
319
+
320
+ ```typescript
321
+ type GroupPart<TKey extends `group-${string}` = `group-${string}`> = {
322
+ readonly type: TKey;
323
+ readonly status: MessagePartStatus | ToolCallMessagePartStatus;
324
+ readonly indices: readonly number[];
325
+ };
326
+ ```
327
+
328
+ ## Best Practices
329
+
330
+ 1. **Keep grouping local**: `GroupedParts` groups adjacent runs. If the same key appears again later, it becomes a new group in that position.
331
+ 2. **Handle ungrouped parts**: Always include leaf cases for the part types your message can render.
332
+ 3. **Only render `children` for groups**: Leaf parts receive a sentinel `children` value that throws if rendered accidentally.
333
+ 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
+
336
+ ## Common Patterns
337
+
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
+ ### Nested Grouping
363
+
364
+ Create hierarchical adjacent groups by returning multiple keys:
365
+
366
+ ```tsx
367
+ <MessagePrimitive.GroupedParts
368
+ groupBy={(part) => {
369
+ if (part.type === "reasoning")
370
+ return ["group-chainOfThought", "group-reasoning"];
371
+ if (part.type === "tool-call")
372
+ return ["group-chainOfThought", `group-tool-${part.toolName}`];
373
+ return null;
374
+ }}
375
+ >
376
+ {({ part, children }) => {
377
+ if (part.type === "group-chainOfThought") return <div>{children}</div>;
378
+ if (part.type === "group-reasoning") return <ReasoningRoot>{children}</ReasoningRoot>;
379
+ if (part.type.startsWith("group-tool-")) return <div>{children}</div>;
380
+ if (part.type === "reasoning") return <Reasoning {...part} />;
381
+ if (part.type === "tool-call") return part.toolUI ?? <ToolFallback {...part} />;
382
+ if (part.type === "text") return <MarkdownText />;
383
+ return null;
384
+ }}
385
+ </MessagePrimitive.GroupedParts>
386
+ ```
387
+
388
+ ### Dynamic Group Rendering
389
+
390
+ Adjust group appearance based on the group node's status or indices:
391
+
392
+ ```tsx
393
+ <MessagePrimitive.GroupedParts
394
+ groupBy={(part) => {
395
+ if (part.type === "tool-call") return ["group-tools"];
396
+ return null;
397
+ }}
398
+ >
399
+ {({ part, children }) => {
400
+ if (part.type === "group-tools") {
401
+ const isRunning = part.status.type === "running";
402
+
403
+ return (
404
+ <div
405
+ className={`my-2 rounded-lg border p-4 ${
406
+ isRunning ? "animate-pulse border-blue-500" : ""
407
+ }`}
408
+ >
409
+ <div className="mb-2 text-sm text-muted-foreground">
410
+ {part.indices.length} tool calls
411
+ </div>
412
+ {children}
413
+ </div>
414
+ );
415
+ }
416
+
417
+ if (part.type === "tool-call") return part.toolUI ?? <ToolFallback {...part} />;
418
+ if (part.type === "text") return <MarkdownText />;
419
+ return null;
420
+ }}
421
+ </MessagePrimitive.GroupedParts>
422
+ ```
423
+
424
+ ## Non-adjacent grouping (Unstable)
425
+
426
+ Use `MessagePrimitive.Unstable_PartsGrouped` only when you need to collect non-adjacent parts into the same rendered group, such as gathering every part with the same parent ID even when other parts appear between them. This API is unstable and should not be used for normal consecutive reasoning or tool-call grouping.
427
+
428
+ ```tsx
429
+ <MessagePrimitive.Unstable_PartsGrouped
430
+ groupingFunction={(parts) => {
431
+ const groups = new Map<string, number[]>();
432
+
433
+ parts.forEach((part, index) => {
434
+ const key = part.parentId ?? `__ungrouped_${index}`;
435
+ const indices = groups.get(key) ?? [];
436
+ indices.push(index);
437
+ groups.set(key, indices);
438
+ });
439
+
440
+ return Array.from(groups.entries()).map(([key, indices]) => ({
441
+ groupKey: key.startsWith("__ungrouped_") ? undefined : key,
442
+ indices,
443
+ }));
444
+ }}
445
+ components={{
446
+ Text: MarkdownText,
447
+ tools: { Fallback: ToolFallback },
448
+ Group: ({ groupKey, children }) => {
449
+ if (!groupKey) return <>{children}</>;
450
+ return <div className="rounded-lg border p-3">{children}</div>;
451
+ },
452
+ }}
453
+ />
454
+ ```
376
455
 
377
456
  <ParametersTable
378
457
  type="MessagePrimitiveUnstable_PartsGroupedProps"
379
458
  parameters={[
380
459
  {
381
460
  name: "groupingFunction",
382
- type: "(parts: readonly any[]) => MessagePartGroup[]",
461
+ type: "(parts: readonly PartState[]) => MessagePartGroup[]",
383
462
  description:
384
- "Function that takes an array of message parts and returns an array of groups. Each group contains a groupKey (for identification) and an array of indices.",
463
+ "Function that takes all message parts and returns non-adjacent group descriptors.",
385
464
  required: true,
386
465
  },
387
466
  {
388
467
  name: "components",
389
468
  type: "object",
390
469
  description:
391
- "Component configuration for rendering different types of message content and groups.",
470
+ "Legacy component map used to render message part types and group wrappers.",
392
471
  children: [
393
472
  {
394
473
  type: "Components",
@@ -465,70 +544,3 @@ The `Group` component receives:
465
544
  - `groupKey`: The group identifier (or `undefined` for ungrouped parts)
466
545
  - `indices`: Array of indices for the parts in this group
467
546
  - `children`: The rendered message part components
468
-
469
- ## Best Practices
470
-
471
- 1. **Keep grouping logic simple**: Complex grouping functions can impact performance
472
- 2. **Handle ungrouped parts**: Always consider parts that don't match any group criteria
473
- 3. **Maintain order**: Consider the visual flow when ordering groups
474
- 4. **Use meaningful keys**: Group keys should be descriptive for debugging
475
- 5. **Test edge cases**: Empty messages, single parts, and large numbers of parts
476
-
477
- ## Common Patterns
478
-
479
- ### Conditional Grouping
480
-
481
- Only group when certain conditions are met:
482
-
483
- ```tsx
484
- const conditionalGrouping = (parts: readonly any[]) => {
485
- // Only group if there are enough parts
486
- if (parts.length < 5) {
487
- return [{ groupKey: undefined, indices: parts.map((_, i) => i) }];
488
- }
489
-
490
- // Your grouping logic here
491
- };
492
- ```
493
-
494
- ### Nested Grouping
495
-
496
- Create hierarchical groups:
497
-
498
- ```tsx
499
- const nestedGrouping = (parts: readonly any[]) => {
500
- // First level: group by type
501
- // Second level: group by subtype or metadata
502
- // Implementation depends on your specific needs
503
- };
504
- ```
505
-
506
- ### Dynamic Group Rendering
507
-
508
- Adjust group appearance based on content:
509
-
510
- ```tsx
511
- import { FC, PropsWithChildren } from "react";
512
- import { useAuiState } from "@assistant-ui/react";
513
-
514
- const DynamicGroup: FC<
515
- PropsWithChildren<{ groupKey: string | undefined; indices: number[] }>
516
- > = ({ groupKey, indices, children }) => {
517
- const parts = useAuiState((s) => s.message.parts);
518
- const groupParts = indices.map((i) => parts[i]);
519
-
520
- // Analyze group content
521
- const hasErrors = groupParts.some((p) => p.error);
522
- const isLoading = groupParts.some((p) => p.status?.type === "running");
523
-
524
- if (!groupKey) return <>{children}</>;
525
-
526
- return (
527
- <div
528
- className={`my-2 rounded-lg border p-4 ${hasErrors ? "border-red-500 bg-red-50" : ""} ${isLoading ? "animate-pulse" : ""} `}
529
- >
530
- {children}
531
- </div>
532
- );
533
- };
534
- ```