@assistant-ui/mcp-docs-server 0.1.31 → 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 (247) 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 +11 -11
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +13 -13
  5. package/.docs/organized/code-examples/with-artifacts.md +13 -13
  6. package/.docs/organized/code-examples/with-assistant-transport.md +10 -10
  7. package/.docs/organized/code-examples/with-browser-extension.md +345 -0
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +54 -17
  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 +13 -13
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +17 -16
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +17 -16
  14. package/.docs/organized/code-examples/with-expo.md +24 -24
  15. package/.docs/organized/code-examples/with-external-store.md +10 -10
  16. package/.docs/organized/code-examples/with-ffmpeg.md +13 -13
  17. package/.docs/organized/code-examples/with-generative-ui.md +210 -13
  18. package/.docs/organized/code-examples/with-google-adk.md +10 -10
  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 +13 -13
  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 +18 -17
  25. package/.docs/organized/code-examples/with-mcp.md +748 -0
  26. package/.docs/organized/code-examples/with-opencode.md +11 -11
  27. package/.docs/organized/code-examples/with-parent-id-grouping.md +11 -11
  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 +15 -15
  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 +1 -0
  36. package/.docs/raw/docs/(docs)/index.mdx +2 -2
  37. package/.docs/raw/docs/(docs)/installation.mdx +1 -1
  38. package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +26 -24
  39. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback.mdx +20 -0
  40. package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +20 -12
  41. package/.docs/raw/docs/(reference)/api-reference/adapters/model.mdx +44 -0
  42. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +37 -16
  43. package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +12 -23
  44. package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +20 -0
  45. package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +37 -8
  46. package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +11 -9
  47. package/.docs/raw/docs/(reference)/api-reference/context-providers/scoped-providers.mdx +64 -0
  48. package/.docs/raw/docs/(reference)/api-reference/external-store/index.mdx +22 -0
  49. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +52 -0
  50. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +36 -0
  51. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +98 -0
  52. package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +18 -13
  53. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +18 -57
  54. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +640 -0
  55. package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +15 -28
  56. package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +64 -18
  57. package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +434 -0
  58. package/.docs/raw/docs/(reference)/api-reference/integrations/cloud-ai-sdk.mdx +24 -0
  59. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +11 -12
  60. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +79 -0
  61. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +52 -0
  62. package/.docs/raw/docs/(reference)/api-reference/model-context/index.mdx +22 -0
  63. package/.docs/raw/docs/(reference)/api-reference/model-context/registry.mdx +20 -0
  64. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +110 -131
  65. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +78 -221
  66. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +127 -242
  67. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +39 -20
  68. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +66 -87
  69. package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +50 -58
  70. package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +80 -48
  71. package/.docs/raw/docs/(reference)/api-reference/primitives/chain-of-thought.mdx +67 -0
  72. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +323 -461
  73. package/.docs/raw/docs/(reference)/api-reference/primitives/error.mdx +36 -43
  74. package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +29 -24
  75. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +63 -245
  76. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +175 -591
  77. package/.docs/raw/docs/(reference)/api-reference/primitives/queue-item.mdx +65 -0
  78. package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +35 -22
  79. package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +57 -140
  80. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item-more.mdx +70 -161
  81. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +84 -108
  82. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +77 -96
  83. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +173 -349
  84. package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +9 -21
  85. package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +10 -21
  86. package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +15 -70
  87. package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +18 -13
  88. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +25 -28
  89. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +11 -63
  90. package/.docs/raw/docs/(reference)/api-reference/runtimes/queue-state.mdx +20 -0
  91. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +11 -48
  92. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +10 -47
  93. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +18 -30
  94. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +68 -0
  95. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +39 -0
  96. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +79 -0
  97. package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +42 -0
  98. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +92 -0
  99. package/.docs/raw/docs/(reference)/api-reference/transport/assistant-transport.mdx +48 -0
  100. package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +62 -0
  101. package/.docs/raw/docs/(reference)/api-reference/transport/index.mdx +22 -0
  102. package/.docs/raw/docs/(reference)/api-reference/utilities/index.mdx +19 -0
  103. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +131 -0
  104. package/.docs/raw/docs/(reference)/api-reference/voice/index.mdx +22 -0
  105. package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +54 -0
  106. package/.docs/raw/docs/(reference)/api-reference/voice/speech-dictation.mdx +36 -0
  107. package/.docs/raw/docs/cloud/ai-sdk.mdx +1 -1
  108. package/.docs/raw/docs/cloud/index.mdx +2 -2
  109. package/.docs/raw/docs/guides/attachments.mdx +4 -4
  110. package/.docs/raw/docs/guides/branching.mdx +1 -1
  111. package/.docs/raw/docs/guides/chain-of-thought.mdx +5 -5
  112. package/.docs/raw/docs/guides/context-api.mdx +4 -4
  113. package/.docs/raw/docs/guides/dictation.mdx +2 -2
  114. package/.docs/raw/docs/guides/editing.mdx +1 -1
  115. package/.docs/raw/docs/guides/generative-ui.mdx +142 -0
  116. package/.docs/raw/docs/guides/image-generation.mdx +74 -0
  117. package/.docs/raw/docs/guides/index.mdx +2 -2
  118. package/.docs/raw/docs/guides/interactables.mdx +2 -2
  119. package/.docs/raw/docs/guides/latex.mdx +2 -2
  120. package/.docs/raw/docs/guides/mcp-apps.mdx +231 -0
  121. package/.docs/raw/docs/guides/mentions.mdx +2 -2
  122. package/.docs/raw/docs/guides/message-timing.mdx +38 -5
  123. package/.docs/raw/docs/guides/multi-agent.mdx +2 -2
  124. package/.docs/raw/docs/guides/quoting.mdx +1 -1
  125. package/.docs/raw/docs/guides/resumable-stream-deployment.mdx +212 -0
  126. package/.docs/raw/docs/guides/resumable-stream-stores.mdx +152 -0
  127. package/.docs/raw/docs/guides/resumable-streams.mdx +210 -0
  128. package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
  129. package/.docs/raw/docs/guides/speech.mdx +2 -2
  130. package/.docs/raw/docs/guides/suggestions.mdx +88 -4
  131. package/.docs/raw/docs/guides/tool-ui.mdx +2 -2
  132. package/.docs/raw/docs/guides/tools.mdx +66 -5
  133. package/.docs/raw/docs/guides/voice.mdx +2 -2
  134. package/.docs/raw/docs/ink/adapters.mdx +37 -1
  135. package/.docs/raw/docs/ink/custom-backend.mdx +59 -8
  136. package/.docs/raw/docs/ink/index.mdx +10 -11
  137. package/.docs/raw/docs/ink/primitives.mdx +349 -8
  138. package/.docs/raw/docs/integrations/auth/better-auth.mdx +1 -1
  139. package/.docs/raw/docs/integrations/auth/clerk.mdx +1 -1
  140. package/.docs/raw/docs/integrations/auth/next-auth.mdx +1 -1
  141. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +2 -2
  142. package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +282 -0
  143. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +2 -2
  144. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
  145. package/.docs/raw/docs/integrations/gateways/index.mdx +9 -4
  146. package/.docs/raw/docs/integrations/index.mdx +15 -3
  147. package/.docs/raw/docs/integrations/observability/langfuse.mdx +8 -1
  148. package/.docs/raw/docs/integrations/observability/langsmith.mdx +8 -4
  149. package/.docs/raw/docs/integrations/tools/react-mcp.mdx +337 -0
  150. package/.docs/raw/docs/primitives/composer.mdx +53 -0
  151. package/.docs/raw/docs/primitives/index.mdx +2 -2
  152. package/.docs/raw/docs/primitives/suggestion.mdx +9 -0
  153. package/.docs/raw/docs/react-native/hooks.mdx +2 -2
  154. package/.docs/raw/docs/react-native/index.mdx +4 -4
  155. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +4 -4
  156. package/.docs/raw/docs/runtimes/a2a/overview.mdx +2 -2
  157. package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +2 -2
  158. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +32 -1
  159. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +2 -2
  160. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +7 -2
  161. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +1 -1
  162. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +7 -0
  163. package/.docs/raw/docs/runtimes/custom/data-stream.mdx +27 -2
  164. package/.docs/raw/docs/runtimes/custom/external-store.mdx +9 -1
  165. package/.docs/raw/docs/runtimes/custom/overview.mdx +2 -2
  166. package/.docs/raw/docs/runtimes/google-adk/overview.mdx +2 -2
  167. package/.docs/raw/docs/runtimes/langchain.mdx +2 -2
  168. package/.docs/raw/docs/runtimes/langgraph/overview.mdx +2 -2
  169. package/.docs/raw/docs/runtimes/opencode/overview.mdx +2 -2
  170. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +1 -1
  171. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +12 -5
  172. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +11 -1
  173. package/.docs/raw/docs/ui/mcp-config.mdx +102 -0
  174. package/.docs/raw/docs/ui/model-selector.mdx +8 -8
  175. package/.docs/raw/docs/ui/sources.mdx +17 -0
  176. package/.docs/raw/docs/ui/streamdown.mdx +34 -2
  177. package/.docs/raw/docs/ui/thread-list.mdx +2 -2
  178. package/.docs/raw/docs/ui/thread.mdx +2 -2
  179. package/README.md +14 -72
  180. package/dist/constants.d.ts +12 -9
  181. package/dist/constants.d.ts.map +1 -1
  182. package/dist/constants.js +13 -9
  183. package/dist/constants.js.map +1 -1
  184. package/dist/index.d.ts +7 -3
  185. package/dist/index.d.ts.map +1 -1
  186. package/dist/index.js +25 -24
  187. package/dist/index.js.map +1 -1
  188. package/dist/prepare-docs/code-examples.d.ts +4 -1
  189. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  190. package/dist/prepare-docs/code-examples.js +109 -121
  191. package/dist/prepare-docs/code-examples.js.map +1 -1
  192. package/dist/prepare-docs/copy-raw.d.ts +4 -1
  193. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  194. package/dist/prepare-docs/copy-raw.js +45 -42
  195. package/dist/prepare-docs/copy-raw.js.map +1 -1
  196. package/dist/prepare-docs/prepare.d.ts +1 -2
  197. package/dist/prepare-docs/prepare.js +17 -17
  198. package/dist/prepare-docs/prepare.js.map +1 -1
  199. package/dist/stdio.d.ts +1 -3
  200. package/dist/stdio.js +6 -3
  201. package/dist/stdio.js.map +1 -1
  202. package/dist/tools/docs.d.ts +20 -15
  203. package/dist/tools/docs.d.ts.map +1 -1
  204. package/dist/tools/docs.js +140 -161
  205. package/dist/tools/docs.js.map +1 -1
  206. package/dist/tools/examples.d.ts +20 -15
  207. package/dist/tools/examples.d.ts.map +1 -1
  208. package/dist/tools/examples.js +74 -86
  209. package/dist/tools/examples.js.map +1 -1
  210. package/dist/tools/tests/test-setup.d.ts +5 -2
  211. package/dist/tools/tests/test-setup.d.ts.map +1 -1
  212. package/dist/tools/tests/test-setup.js +21 -28
  213. package/dist/tools/tests/test-setup.js.map +1 -1
  214. package/dist/utils/logger.d.ts +8 -5
  215. package/dist/utils/logger.d.ts.map +1 -1
  216. package/dist/utils/logger.js +17 -17
  217. package/dist/utils/logger.js.map +1 -1
  218. package/dist/utils/mcp-format.d.ts +8 -5
  219. package/dist/utils/mcp-format.d.ts.map +1 -1
  220. package/dist/utils/mcp-format.js +9 -9
  221. package/dist/utils/mcp-format.js.map +1 -1
  222. package/dist/utils/mdx.d.ts +8 -6
  223. package/dist/utils/mdx.d.ts.map +1 -1
  224. package/dist/utils/mdx.js +22 -22
  225. package/dist/utils/mdx.js.map +1 -1
  226. package/dist/utils/paths.d.ts +9 -6
  227. package/dist/utils/paths.d.ts.map +1 -1
  228. package/dist/utils/paths.js +66 -76
  229. package/dist/utils/paths.js.map +1 -1
  230. package/dist/utils/security.d.ts +4 -1
  231. package/dist/utils/security.d.ts.map +1 -1
  232. package/dist/utils/security.js +19 -40
  233. package/dist/utils/security.js.map +1 -1
  234. package/package.json +5 -5
  235. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback-speech.mdx +0 -41
  236. package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +0 -40
  237. package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +0 -260
  238. package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +0 -103
  239. package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +0 -254
  240. package/dist/prepare-docs/prepare.d.ts.map +0 -1
  241. package/dist/stdio.d.ts.map +0 -1
  242. /package/.docs/raw/docs/{(reference)/migrations → migrations}/deprecation-policy.mdx +0 -0
  243. /package/.docs/raw/docs/{(reference) → migrations}/react-compatibility.mdx +0 -0
  244. /package/.docs/raw/docs/{(reference)/migrations → migrations}/react-langgraph-v0-7.mdx +0 -0
  245. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-11.mdx +0 -0
  246. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-12.mdx +0 -0
  247. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-14.mdx +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Chain of Thought
3
- description: Group reasoning and tool calls into a collapsible accordion UI.
2
+ title: Chain of Thought UI
3
+ description: Show AI reasoning steps and tool calls in a collapsible thinking accordion. Build chain-of-thought visualizations in React chat with assistant-ui.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -8,7 +8,7 @@ LLMs often produce reasoning steps and tool calls in succession. Chain of Though
8
8
 
9
9
  ## Overview
10
10
 
11
- When a model like OpenAI's `o4-mini` responds, it may emit a sequence of reasoning tokens and tool calls before producing its final text answer. Use `MessagePrimitive.GroupedParts` to group those adjacent reasoning and tool-call parts into a single collapsible "thinking" section.
11
+ When a reasoning model responds, it may emit a sequence of reasoning tokens and tool calls before producing its final text answer. Use `MessagePrimitive.GroupedParts` to group those adjacent reasoning and tool-call parts into a single collapsible "thinking" section.
12
12
 
13
13
  <Callout type="info">
14
14
  The older `components.ChainOfThought` prop on `MessagePrimitive.Parts` and `components` prop on `ChainOfThoughtPrimitive.Parts` are legacy APIs. They still work for existing code, but new code should use `MessagePrimitive.GroupedParts`.
@@ -101,7 +101,7 @@ const AssistantMessage: FC = () => {
101
101
 
102
102
  ### Use a Reasoning Model
103
103
 
104
- Chain of Thought is most useful with models that produce reasoning tokens (e.g. OpenAI `o4-mini`). Here's an example backend route using the AI SDK:
104
+ Chain of Thought is most useful with models that produce reasoning tokens. Here's an example backend route using the AI SDK:
105
105
 
106
106
  ```tsx title="app/api/chat/route.ts"
107
107
  import { openai } from "@ai-sdk/openai";
@@ -111,7 +111,7 @@ export async function POST(req: Request) {
111
111
  const { messages } = await req.json();
112
112
 
113
113
  const result = streamText({
114
- model: openai("o4-mini"),
114
+ model: openai("gpt-5.4-mini"),
115
115
  messages: await convertToModelMessages(messages),
116
116
  });
117
117
 
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Context API
3
- description: Read and update assistant state to build custom components.
2
+ title: Assistant Context API
3
+ description: Read and update assistant state to build custom React components in your chat UI — composable context API for thread, message, and runtime data via assistant-ui.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -258,8 +258,8 @@ useAuiEvent("composer.send", (event) => {
258
258
  });
259
259
 
260
260
  // Listen to thread events
261
- useAuiEvent("thread.runStart", (event) => {
262
- console.log("Run started in thread:", event.threadId);
261
+ useAuiEvent("thread.modelContextUpdate", (event) => {
262
+ console.log("Model context updated in thread:", event.threadId);
263
263
  });
264
264
 
265
265
  // Listen to all events of a type across all scopes
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Speech-to-Text (Dictation)
3
- description: Let users speak into the composer using Web Speech API or a custom dictation adapter.
2
+ title: Speech-to-Text Dictation
3
+ description: Add voice dictation to your AI chat composer with the Web Speech API or a custom adapter. Speech-to-text in React, integrated through assistant-ui.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Message Editing
3
- description: Allow users to edit their messages with custom editor interfaces.
3
+ description: Let users edit their messages and regenerate AI responses with custom editor interfaces. Edit-and-resubmit patterns for React chat via assistant-ui.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -0,0 +1,142 @@
1
+ ---
2
+ title: Generative UI
3
+ description: Render agent-described React UI from a JSON spec with a consumer-provided component allowlist.
4
+ ---
5
+
6
+ `MessagePrimitive.GenerativeUI` is a first-class primitive for rendering UI
7
+ described by the agent at runtime as a JSON spec. Instead of hard-coding a
8
+ component per tool, the agent emits a `generative-ui` message part containing
9
+ a tree of components by name. assistant-ui resolves each name against a
10
+ **consumer-provided allowlist** and renders the result.
11
+
12
+ > The allowlist controls **which** components the agent may render: any name
13
+ > not in it throws a typed `GenerativeUIRenderError` (no implicit fallback). It
14
+ > does not constrain the props passed to those components; see [Security](#security).
15
+
16
+ ## Quick start
17
+
18
+ ### 1. Define your component allowlist
19
+
20
+ ```tsx title="components/gui.tsx"
21
+ const Card = ({ title, children }) => (
22
+ <div className="rounded-xl border bg-card p-4 shadow-sm">
23
+ <div className="text-base font-semibold">{title}</div>
24
+ <div className="mt-2">{children}</div>
25
+ </div>
26
+ );
27
+
28
+ const Button = ({ label }) => (
29
+ <button className="rounded-md bg-primary px-3 py-1.5 text-primary-foreground">
30
+ {label}
31
+ </button>
32
+ );
33
+
34
+ export const componentsAllowlist = { Card, Button };
35
+ ```
36
+
37
+ ### 2. Wire the primitive into your message renderer
38
+
39
+ ```tsx title="components/assistant-message.tsx"
40
+ import { MessagePrimitive } from "@assistant-ui/react";
41
+ import { componentsAllowlist } from "./gui";
42
+
43
+ export function AssistantMessage() {
44
+ return (
45
+ <MessagePrimitive.Parts
46
+ components={{
47
+ generativeUI: { components: componentsAllowlist },
48
+ }}
49
+ />
50
+ );
51
+ }
52
+ ```
53
+
54
+ You can also use the standalone primitive form:
55
+
56
+ ```tsx
57
+ <MessagePrimitive.GenerativeUI components={componentsAllowlist} />
58
+ ```
59
+
60
+ ### 3. Have the agent emit a `generative-ui` part
61
+
62
+ A `GenerativeUIMessagePart` carries a JSON spec:
63
+
64
+ ```ts
65
+ {
66
+ type: "generative-ui",
67
+ spec: {
68
+ root: {
69
+ component: "Card",
70
+ props: { title: "Welcome" },
71
+ children: [
72
+ { component: "Button", props: { label: "Get started" } },
73
+ ],
74
+ },
75
+ },
76
+ }
77
+ ```
78
+
79
+ Bare strings act as inline text leaves.
80
+
81
+ ## Spec shape
82
+
83
+ ```ts
84
+ type GenerativeUINode =
85
+ | string
86
+ | {
87
+ component: string; // resolved against the allowlist
88
+ props?: Record<string, unknown>;
89
+ children?: GenerativeUINode[];
90
+ key?: string; // optional stable React key
91
+ };
92
+
93
+ type GenerativeUISpec = {
94
+ root: GenerativeUINode | GenerativeUINode[];
95
+ };
96
+ ```
97
+
98
+ The spec is plain JSON — easy for any agent to emit, and easy to validate
99
+ on the server before delivery.
100
+
101
+ ## Streaming
102
+
103
+ The primitive is stream-friendly: any partial spec renders progressively. As
104
+ new nodes arrive (filling in `children`, refining `props`), the rendered tree
105
+ updates without reflows or lost local state for already-mounted children.
106
+
107
+ ## Security
108
+
109
+ The allowlist is the boundary on **which** components render: a spec can only instantiate components you put in the registry, with no `eval` and no dynamic import (names are looked up in the registry and nothing else). An unknown name throws `GenerativeUIRenderError` or invokes your `Fallback`.
110
+
111
+ It does **not** constrain the `props` the agent supplies. Spec props are spread directly onto your allowlisted components, so treat every allowlisted component as receiving untrusted input: never forward agent-supplied props into `dangerouslySetInnerHTML`, validate or reject `href` / `src` values (for example block `javascript:` URLs), and avoid passing spec props anywhere they become executable. The safest allowlisted components accept only primitive, display-oriented props.
112
+
113
+ ## Error handling
114
+
115
+ Unknown component names throw `GenerativeUIRenderError` with a typed
116
+ `componentName` field. Catch it with a React error boundary, or pass a
117
+ `Fallback` component to opt into a soft-fail UX:
118
+
119
+ ```tsx
120
+ <MessagePrimitive.GenerativeUI
121
+ components={componentsAllowlist}
122
+ Fallback={({ component }) => (
123
+ <span className="rounded bg-muted px-1.5 py-0.5 font-mono text-xs">
124
+ unknown component: {component}
125
+ </span>
126
+ )}
127
+ />
128
+ ```
129
+
130
+ ## Composing with other primitives
131
+
132
+ `generative-ui` is a regular `MessagePart` type, so it composes cleanly with
133
+ `MessagePrimitive.Parts`, `MessagePrimitive.PartByIndex`, and
134
+ `MessagePrimitive.GroupedParts`. Render it alongside text, tool calls, and
135
+ reasoning in the same message.
136
+
137
+ ## Why a primitive (not just a tool)
138
+
139
+ Tool-call UI is great when the agent already invoked a known tool. Generative
140
+ UI flips it: the agent _composes_ UI from a vocabulary you ship. Useful for
141
+ forms, dashboards, status panels, multi-step flows, and anywhere the
142
+ component library you want is broader than a single tool's render surface.
@@ -0,0 +1,74 @@
1
+ ---
2
+ title: Image Generation
3
+ description: Generate images in your backend and render them inline in an assistant-ui thread.
4
+ ---
5
+
6
+ Image generation needs no dedicated primitive. Generate the image wherever you already run model calls (a route handler or a tool), store the result as an `ImageMessagePart`, and render it with the `@assistant-ui/ui` `Image` component.
7
+
8
+ <Callout type="info">
9
+ This covers non-streaming generation, rendering, and actions. Streaming partial images and multi-image galleries are out of scope.
10
+ </Callout>
11
+
12
+ ## Generate in your backend
13
+
14
+ Call your provider from a server route. With the AI SDK that is `generateImage`; return the image as a data URI (or an object-store URL) plus any provider metadata you want to keep.
15
+
16
+ ```ts
17
+ // app/api/image/route.ts
18
+ import { generateImage } from "ai";
19
+ import { openai } from "@ai-sdk/openai";
20
+
21
+ export async function POST(req: Request) {
22
+ const { prompt } = await req.json();
23
+ const result = await generateImage({
24
+ model: openai.image("gpt-image-1"),
25
+ prompt,
26
+ });
27
+ const revisedPrompt = (
28
+ result.providerMetadata as
29
+ | Record<string, Record<string, unknown>>
30
+ | undefined
31
+ )?.openai?.revisedPrompt;
32
+ return Response.json({
33
+ image: `data:${result.image.mediaType};base64,${result.image.base64}`,
34
+ mimeType: result.image.mediaType,
35
+ ...(typeof revisedPrompt === "string" && { revisedPrompt }),
36
+ });
37
+ }
38
+ ```
39
+
40
+ The model provider is irrelevant to rendering; swap `openai.image(...)` for any AI SDK image model.
41
+
42
+ ## Store it as an `ImageMessagePart`
43
+
44
+ An `ImageMessagePart` only needs `image` (a `data:` URI, an `https://` URL, or a `blob:` URL) plus an optional `filename`. Keep any provenance you want to display, the prompt, a revised prompt, a model id, in your own component state or in message metadata; the part itself stays minimal.
45
+
46
+ ```ts
47
+ const part: ImageMessagePart = {
48
+ type: "image",
49
+ image: result.image, // data:, https://, or blob: URL
50
+ };
51
+ ```
52
+
53
+ ## Render with the `Image` component
54
+
55
+ The `Image` component in `@assistant-ui/ui` handles the render states for you:
56
+
57
+ 1. **Running** (`status.type === "running"`) renders a spinner.
58
+ 2. **Content filter** (`status.type === "incomplete"` with `reason: "content-filter"`) renders an error card with no `<img src>`.
59
+ 3. **Complete** renders a zoomable `<img>` with optional `Image.Actions`.
60
+
61
+ `Image.Actions` provides download and copy buttons, plus a regenerate button when you pass an `onRegenerate` callback. Wire it to the same generation flow you used above; debounce, rate limiting, and confirmation are your call.
62
+
63
+ ```tsx
64
+ import { Image } from "@assistant-ui/ui";
65
+
66
+ <>
67
+ <Image {...imagePart} />
68
+ <Image.Actions part={imagePart} onRegenerate={() => regenerate(prompt)} />
69
+ </>;
70
+ ```
71
+
72
+ ## Example
73
+
74
+ A complete Next.js example (with a mock fallback when `OPENAI_API_KEY` is unset) lives in [`examples/with-image-generation`](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-image-generation).
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Overview
3
- description: Practical patterns for building features with assistant-ui.
2
+ title: Guides
3
+ description: Practical recipes for building AI chat features in React with assistant-ui — attachments, branching, multi-agent, voice, slash commands, generative UI, and more.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Interactables
3
- description: Persistent UI whose state can be read and updated by the AI assistant.
2
+ title: Interactable Components
3
+ description: Build persistent UI elements whose state the AI can read and update — copilot interactables in React with assistant-ui for forms, dashboards, and tools.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: LaTeX
3
- description: Render mathematical expressions in chat messages using KaTeX.
2
+ title: LaTeX in Chat Messages
3
+ description: Render LaTeX math expressions in AI chat messages with KaTeX — drop-in equation support for React chat UIs built on assistant-ui.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -0,0 +1,231 @@
1
+ ---
2
+ title: MCP Apps
3
+ description: Render MCP App UI resources inline in chat. Native renderer for the Model Context Protocol Apps spec — sandboxed iframes, JSON-RPC bridge, AI SDK integration.
4
+ platforms: ["react"]
5
+ ---
6
+
7
+ [MCP Apps](https://apps.extensions.modelcontextprotocol.io/) lets a Model Context Protocol server ship a UI resource alongside a tool — a self-contained HTML widget that the chat host renders inline when the tool is called. assistant-ui ships a native renderer that mounts the widget in a sandboxed iframe via [`SafeContentFrame`](/safe-content-frame) and runs a JSON-RPC postMessage bridge so the widget can call tools, send messages, request a display mode, and read host context.
8
+
9
+ ## Overview
10
+
11
+ When an MCP server attaches a `_meta.ui.resourceUri` (the [`text/html;profile=mcp-app`](https://apps.extensions.modelcontextprotocol.io/api/index.html) MIME) to a tool, AI SDK forwards that metadata through the message stream. assistant-ui's renderer picks it up off the `mcp` field on `ToolCallMessagePart`, fetches the resource through your backend route, and mounts it.
12
+
13
+ The renderer only acts on URIs that start with `ui://` (per the MCP Apps spec). Tools whose `resourceUri` uses any other scheme are treated as non-MCP-Apps tools and fall through to your regular tool UI.
14
+
15
+ The widget communicates back through a JSON-RPC bridge:
16
+
17
+ - **widget → host requests**: `ui/initialize`, `tools/call`, `resources/read`, `resources/list`, `openLink`, `sendMessage`, `requestDisplayMode`, `updateModelContext`
18
+ - **host → widget notifications**: tool input streaming, tool result, host context changes
19
+ - **widget → host notifications**: initialized, size changed, log, error, request teardown
20
+
21
+ Capability presence is determined at mount time by which handlers you provide. Unknown methods return JSON-RPC `-32601`; bad params return `-32602`.
22
+
23
+ ## Quick start
24
+
25
+ The renderer talks to a backend route you expose — the MCP client lives server-side so credentials and transport stay out of the browser. The route receives `{ method, params }` POSTs and dispatches to your MCP client.
26
+
27
+ ### Client
28
+
29
+ Compose `McpAppRenderer({...})` into your `Tools` resource. Provide `host.url` pointing at your route. Any tool-call part carrying `mcp.app` metadata renders the MCP App widget automatically.
30
+
31
+ ```tsx
32
+ import {
33
+ useAui,
34
+ Tools,
35
+ McpAppRenderer,
36
+ McpAppsRemoteHost,
37
+ } from "@assistant-ui/react";
38
+
39
+ function MyAssistant() {
40
+ useAui({
41
+ tools: Tools({
42
+ toolkit: myToolkit,
43
+ mcpApp: McpAppRenderer({
44
+ host: McpAppsRemoteHost({ url: "/api/mcp-apps" }),
45
+ hostInfo: { name: "my-app", version: "1.0.0" },
46
+ hostContext: { theme: "light" },
47
+ }),
48
+ }),
49
+ });
50
+ // ...
51
+ }
52
+ ```
53
+
54
+ `McpAppsRemoteHost` is the default host strategy — it POSTs `{ method, params }` to your route. A different strategy (e.g. a client-side MCP client) can be plugged in by writing a custom resource that returns the same `McpAppsHost` shape (`{ loadResource, callTool, readResource, listResources }`).
55
+
56
+ `openLink` is auto-wired to `window.open(url, "_blank", "noopener,noreferrer")`. `sendMessage` is auto-wired to append a user message to the current thread (accepts `string`, `{ prompt }`, `{ text }`, or `{ message }`).
57
+
58
+ ### Route handler
59
+
60
+ The route accepts `POST` requests with `{ method, params }` JSON bodies. Dispatch by method name and return the result as JSON. Example for Next.js App Router:
61
+
62
+ ```ts
63
+ // app/api/mcp-apps/route.ts
64
+ import { experimental_createMCPClient } from "ai";
65
+
66
+ let clientPromise: ReturnType<typeof experimental_createMCPClient> | undefined;
67
+ const getClient = () => {
68
+ clientPromise ??= experimental_createMCPClient({
69
+ transport: { type: "sse", url: process.env.MCP_SERVER_URL! },
70
+ });
71
+ return clientPromise;
72
+ };
73
+
74
+ export async function POST(req: Request) {
75
+ const { method, params } = await req.json();
76
+ const client = await getClient();
77
+
78
+ switch (method) {
79
+ case "mcp-apps/read-resource": {
80
+ const { contents } = await client.readResource({ uri: params.uri });
81
+ const c = contents.find((x: { uri: string }) => x.uri === params.uri);
82
+ return Response.json({
83
+ uri: params.uri,
84
+ mimeType: "text/html;profile=mcp-app",
85
+ html: c?.text ?? "",
86
+ });
87
+ }
88
+ case "tools/call": {
89
+ const tools = await client.tools();
90
+ const tool = tools[params.name];
91
+ if (!tool?.execute) {
92
+ return Response.json({ error: "Tool not callable" }, { status: 400 });
93
+ }
94
+ return Response.json(
95
+ await tool.execute(params.arguments ?? {}, {
96
+ toolCallId: `mcp-apps-bridge-${crypto.randomUUID()}`,
97
+ messages: [],
98
+ }),
99
+ );
100
+ }
101
+ case "resources/read":
102
+ return Response.json(await client.readResource({ uri: params.uri }));
103
+ case "resources/list":
104
+ return Response.json(await client.listResources(params));
105
+ default:
106
+ return Response.json({ error: "Unsupported method" }, { status: 400 });
107
+ }
108
+ }
109
+ ```
110
+
111
+ The renderer POSTs four method names: `mcp-apps/read-resource`, `tools/call`, `resources/read`, `resources/list`. Reject anything else server-side and apply your own auth / rate limiting in the route.
112
+
113
+ Per-name `setToolUI` registrations always win over the MCP fallback — you can still customize specific tools.
114
+
115
+ ## AI SDK integration
116
+
117
+ `@assistant-ui/react-ai-sdk` forwards `callProviderMetadata.mcp.app` from AI SDK tool UI parts into `ToolCallMessagePart.mcp.app`. With AI SDK 5.x and an MCP-Apps-capable MCP server, no extra wiring is required on the part shape.
118
+
119
+ The rich UI comes from the MCP server's metadata, not from the model, so the path is identical whichever provider drives the conversation. Running Claude is just a different `model:` in `streamText` (`anthropic("claude-sonnet-4-6")` via `@ai-sdk/anthropic`); the MCP server, `splitMcpAppTools`, and the renderer are unchanged. MCP Apps is an open standard in the MCP ecosystem (Claude is one of its hosts), so a standard MCP-Apps server renders out of the box. The bridge below is only needed for servers that use OpenAI's `openai/outputTemplate` convention, again independent of which model you run.
120
+
121
+ On the chat route, use `splitMcpAppTools()` (from `@ai-sdk/mcp`) to keep app-only tools out of the model's view:
122
+
123
+ ```ts
124
+ import { splitMcpAppTools } from "@ai-sdk/mcp";
125
+
126
+ const tools = await client.listTools();
127
+ const { modelVisible } = splitMcpAppTools(tools);
128
+
129
+ const result = streamText({
130
+ model: openai("gpt-5.4-nano"),
131
+ tools: modelVisible.tools,
132
+ // ...
133
+ });
134
+ ```
135
+
136
+ ### OpenAI Apps SDK servers
137
+
138
+ [OpenAI Apps SDK](https://developers.openai.com/apps-sdk) servers carry the same `ui://` template under a different convention: the pointer is `_meta["openai/outputTemplate"]` on the tool definition (not `_meta.ui.resourceUri`), and the resource is served as `text/html+skybridge` rather than `text/html;profile=mcp-app`. `@ai-sdk/mcp` does not recognize `openai/outputTemplate`, so it never populates `callProviderMetadata.mcp.app` and the renderer stays idle.
139
+
140
+ The renderer needs no change; you only have to surface the pointer. assistant-ui already reads `result._meta["ui/resourceUri"]` off tool results, so the smallest bridge is to copy the template onto the result by tool name. Build the map once from the tool listing, then stamp it inside each tool's `execute`:
141
+
142
+ ```ts
143
+ import type { Tool } from "ai";
144
+
145
+ // reuse the listTools() result from the AI SDK integration step above; no second round-trip
146
+ const templateByTool = new Map(
147
+ tools.tools
148
+ .filter((t) => typeof t._meta?.["openai/outputTemplate"] === "string")
149
+ .map((t) => [t.name, t._meta["openai/outputTemplate"] as string]),
150
+ );
151
+
152
+ const withTemplateUri = (tool: Tool, name: string): Tool => {
153
+ const uri = templateByTool.get(name);
154
+ const exec = tool.execute;
155
+ if (!uri || !exec) return tool;
156
+ return {
157
+ ...tool,
158
+ execute: async (args, options) => {
159
+ const result = (await exec(args, options)) as { _meta?: Record<string, unknown> };
160
+ return { ...result, _meta: { ...result._meta, "ui/resourceUri": uri } };
161
+ },
162
+ } satisfies Tool;
163
+ };
164
+ ```
165
+
166
+ Wrap the AI SDK tool objects before handing them to `streamText`:
167
+
168
+ ```ts
169
+ const aiTools = await client.tools();
170
+ const wrappedTools = Object.fromEntries(
171
+ Object.entries(aiTools).map(([name, t]) => [name, withTemplateUri(t, name)]),
172
+ );
173
+ // pass wrappedTools to streamText
174
+ ```
175
+
176
+ Your `mcp-apps/read-resource` handler reads the `ui://` resource as in the route example above. Set the response `mimeType` to the `text/html;profile=mcp-app` literal that `McpAppResource` expects and keep the server's HTML in `html`; don't forward the raw `text/html+skybridge` value, which the type rejects.
177
+
178
+ The cleaner long-term fix is upstream: if `@ai-sdk/mcp`'s `getMCPAppToolMeta` also read `openai/outputTemplate`, then `callProviderMetadata.mcp.app` would populate automatically and this bridge would be unnecessary.
179
+
180
+ ## Bridge protocol
181
+
182
+ The bridge implements the MCP UI JSON-RPC protocol over `window.postMessage`, filtered by both `event.source === frame.iframe.contentWindow` AND `event.origin === frame.origin` — the cross-origin domain `SafeContentFrame` issues per render. Messages from any other origin or window are dropped silently.
183
+
184
+ ### Widget → host requests
185
+
186
+ | Method | Notes |
187
+ |---|---|
188
+ | `ui/initialize` | Returns `{ protocolVersion, host, hostContext, capabilities }`. Always supported. |
189
+ | `tools/call` | Routed to `host.url` with method `tools/call`. Optional `handlers.allowedTools` allowlist. Invalid `arguments` shape → `-32602`. |
190
+ | `resources/read` | Routed to `host.url` with method `resources/read`. |
191
+ | `resources/list` | Routed to `host.url` with method `resources/list`. |
192
+ | `openLink` | Requires `handlers.openLink`. Rejects non-`http(s)` URLs with `-32602`. |
193
+ | `sendMessage` | Requires `handlers.sendMessage`. |
194
+ | `requestDisplayMode` | Requires `handlers.requestDisplayMode`. Modes: `inline`, `fullscreen`, `pip`. |
195
+ | `updateModelContext` | Requires `handlers.updateModelContext`. |
196
+
197
+ When a handler isn't provided, the bridge returns JSON-RPC `-32601` (method not found) — which is also how `capabilities` is reported in the `ui/initialize` response.
198
+
199
+ ### Host → widget notifications
200
+
201
+ - `notifications/tools/call/input` — sent whenever `part.args` (the streaming tool input) changes
202
+ - `notifications/tools/call/result` — sent when the tool result lands (including error envelopes)
203
+ - `notifications/host_context/changed` — sent when `hostContext` changes (e.g. user toggles theme)
204
+
205
+ ### Widget → host notifications
206
+
207
+ `notifications/initialized`, `notifications/size_changed`, `notifications/log`, `notifications/error`, `notifications/request_teardown` — wire them via `handlers.onInitialized`, `onSizeChange`, `onLog`, `onError`, `onRequestTeardown` respectively.
208
+
209
+ If the widget never sends `notifications/initialized` (broken or non-spec-compliant), the host flushes its queued notifications after a 5-second safety timeout so the iframe doesn't appear hung.
210
+
211
+ ## Sandboxing
212
+
213
+ The iframe is built with [`SafeContentFrame`](/safe-content-frame), which serves each widget from a content-hashed cross-origin so the host page is not reachable by `same-origin` references. Default sandbox flags are `allow-same-origin allow-scripts`. Tune via the `sandbox` field on `McpAppRendererOptions`:
214
+
215
+ ```tsx
216
+ McpAppRenderer({
217
+ // ...
218
+ sandbox: {
219
+ sandbox: ["allow-forms", "allow-popups"],
220
+ enableBrowserCaching: true,
221
+ className: "my-mcp-app",
222
+ },
223
+ });
224
+ ```
225
+
226
+ ## Security notes
227
+
228
+ - Widgets run cross-origin in a sandboxed iframe. The bridge filters incoming messages by both source window and origin.
229
+ - The host route is your auth boundary — apply session checks, rate limiting, and per-tool allowlists there. The renderer trusts whatever the route returns.
230
+ - `openLink` rejects non-`http(s)` URLs at the bridge layer, but your `openLink` handler should still treat the URL as untrusted (e.g. always use `noopener,noreferrer`).
231
+ - Keep `host` and `handlers` references stable across renders (e.g. module-scope constants or `useMemo`); an unstable identity will tear down and refetch the widget on every parent re-render.
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Mentions
3
- description: Let users @-mention tools or custom items in the composer to guide the LLM.
2
+ title: Mentions in Chat
3
+ description: Let users @-mention tools or custom items in the AI chat composer to guide the LLM. Mention picker built into assistant-ui's React composer.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Message Timing
3
- description: Display stream timing metadata like duration, tokens per second, and time to first token.
2
+ title: Message Timing & Token Stats
3
+ description: Display stream metadata in AI chat — generation duration, tokens per second, and time to first token, rendered via assistant-ui's React components.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -76,9 +76,9 @@ const AssistantMessage: FC = () => {
76
76
  | AI SDK (`useChatRuntime`) | Yes | Automatic via client-side tracking |
77
77
  | Local (`useLocalRuntime`) | Yes | Pass timing in `ChatModelRunResult.metadata` |
78
78
  | ExternalStore | Yes | Pass timing in `ThreadMessageLike.metadata` |
79
- | LangGraph | No | Not yet implemented |
80
- | AG-UI | No | Not yet implemented |
81
- | OpenCode | No | Not yet implemented |
79
+ | LangGraph | Yes | Automatic via client-side tracking |
80
+ | AG-UI | Yes | Automatic via client-side tracking |
81
+ | OpenCode | Yes | Automatic via client-side tracking |
82
82
 
83
83
  ### Data Stream
84
84
 
@@ -163,6 +163,39 @@ const message: ThreadMessageLike = {
163
163
  };
164
164
  ```
165
165
 
166
+ ### LangGraph (`useLangGraphRuntime`)
167
+
168
+ Timing is tracked automatically on the client side by observing streaming state transitions and `LangChainMessage` content changes. No setup required.
169
+
170
+ ```tsx
171
+ import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";
172
+
173
+ const runtime = useLangGraphRuntime({ stream: myStream });
174
+ // useMessageTiming() works out of the box
175
+ ```
176
+
177
+ ### AG-UI (`useAgUiThreadRuntime`)
178
+
179
+ Timing is tracked automatically on the client side by the AG-UI run aggregator. Each emitted message includes timing metadata computed from stream chunk observations.
180
+
181
+ ```tsx
182
+ import { useAgUiThreadRuntime } from "@assistant-ui/react-ag-ui";
183
+
184
+ const runtime = useAgUiThreadRuntime({ runtimeUrl: "..." });
185
+ // useMessageTiming() works out of the box
186
+ ```
187
+
188
+ ### OpenCode (`useOpenCodeRuntime`)
189
+
190
+ Timing is tracked automatically on the client side by observing `OpenCodeThreadState` transitions and assistant message content deltas. No setup required.
191
+
192
+ ```tsx
193
+ import { useOpenCodeRuntime } from "@assistant-ui/react-opencode";
194
+
195
+ const runtime = useOpenCodeRuntime();
196
+ // useMessageTiming() works out of the box
197
+ ```
198
+
166
199
  ## API Reference
167
200
 
168
201
  ### `useMessageTiming()`
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Multi-Agent
3
- description: Render sub-agent conversations inside tool call UIs.
2
+ title: Multi-Agent Chat UI
3
+ description: Render sub-agent conversations and handoffs inside tool calls. Build supervisor and multi-agent patterns in a React chat UI with assistant-ui.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Quote Selected Text
3
- description: Let users select and quote text from messages. Full guide including backend handling and programmatic API.
3
+ description: Let users select text from AI messages and quote it back into the composer. Full quoting flow with backend handling and programmatic API in assistant-ui.
4
4
  platforms: ["react"]
5
5
  ---
6
6