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

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 (208) hide show
  1. package/.docs/organized/code-examples/waterfall.md +1 -1
  2. package/.docs/organized/code-examples/with-a2a.md +2 -2
  3. package/.docs/organized/code-examples/with-ag-ui.md +3 -3
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +5 -5
  5. package/.docs/organized/code-examples/with-artifacts.md +5 -5
  6. package/.docs/organized/code-examples/with-assistant-transport.md +3 -3
  7. package/.docs/organized/code-examples/with-chain-of-thought.md +79 -50
  8. package/.docs/organized/code-examples/with-cloud-standalone.md +4 -4
  9. package/.docs/organized/code-examples/with-cloud.md +4 -4
  10. package/.docs/organized/code-examples/with-custom-thread-list.md +56 -11
  11. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +7 -7
  12. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +7 -7
  13. package/.docs/organized/code-examples/with-expo.md +16 -16
  14. package/.docs/organized/code-examples/with-external-store.md +2 -2
  15. package/.docs/organized/code-examples/with-ffmpeg.md +5 -5
  16. package/.docs/organized/code-examples/with-generative-ui.md +5 -5
  17. package/.docs/organized/code-examples/with-google-adk.md +4 -4
  18. package/.docs/organized/code-examples/with-heat-graph.md +1 -1
  19. package/.docs/organized/code-examples/with-interactables.md +5 -5
  20. package/.docs/organized/code-examples/with-langchain.md +3 -3
  21. package/.docs/organized/code-examples/with-langgraph.md +3 -3
  22. package/.docs/organized/code-examples/with-livekit.md +8 -8
  23. package/.docs/organized/code-examples/with-opencode.md +99 -54
  24. package/.docs/organized/code-examples/with-parent-id-grouping.md +4 -4
  25. package/.docs/organized/code-examples/with-react-hook-form.md +5 -5
  26. package/.docs/organized/code-examples/with-react-ink.md +1 -1
  27. package/.docs/organized/code-examples/with-react-router.md +8 -8
  28. package/.docs/organized/code-examples/with-store.md +1 -1
  29. package/.docs/organized/code-examples/with-tanstack.md +5 -5
  30. package/.docs/organized/code-examples/with-tap-runtime.md +2 -2
  31. package/.docs/raw/docs/(docs)/cli.mdx +2 -1
  32. package/.docs/raw/docs/(docs)/copilots/assistant-frame.mdx +1 -0
  33. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +10 -3
  34. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +8 -3
  35. package/.docs/raw/docs/(docs)/copilots/make-assistant-visible.mdx +1 -0
  36. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +1 -0
  37. package/.docs/raw/docs/(docs)/copilots/motivation.mdx +1 -0
  38. package/.docs/raw/docs/(docs)/copilots/use-assistant-instructions.mdx +1 -0
  39. package/.docs/raw/docs/(docs)/devtools.mdx +1 -0
  40. package/.docs/raw/docs/(docs)/index.mdx +1 -0
  41. package/.docs/raw/docs/(docs)/installation.mdx +1 -0
  42. package/.docs/raw/docs/(docs)/rtl.mdx +1 -0
  43. package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +34 -0
  44. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback-speech.mdx +41 -0
  45. package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +26 -0
  46. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +34 -0
  47. package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +31 -0
  48. package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +20 -0
  49. package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +26 -0
  50. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +72 -0
  51. package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +41 -0
  52. package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +48 -0
  53. package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +30 -0
  54. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +23 -0
  55. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +21 -0
  56. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +7 -0
  57. package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +65 -0
  58. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +50 -6
  59. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +15 -0
  60. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +36 -1
  61. package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +38 -0
  62. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +5 -0
  63. package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +144 -6
  64. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +230 -2
  65. package/.docs/raw/docs/cloud/ai-sdk.mdx +221 -3
  66. package/.docs/raw/docs/cloud/langgraph.mdx +274 -2
  67. package/.docs/raw/docs/{(docs)/guides → guides}/attachments.mdx +41 -36
  68. package/.docs/raw/docs/guides/branching.mdx +76 -0
  69. package/.docs/raw/docs/guides/chain-of-thought.mdx +166 -0
  70. package/.docs/raw/docs/{(docs)/guides → guides}/context-api.mdx +50 -22
  71. package/.docs/raw/docs/{(docs)/guides → guides}/dictation.mdx +2 -0
  72. package/.docs/raw/docs/guides/editing.mdx +102 -0
  73. package/.docs/raw/docs/guides/index.mdx +103 -0
  74. package/.docs/raw/docs/{(docs)/guides → guides}/interactables.mdx +49 -0
  75. package/.docs/raw/docs/{(docs)/guides → guides}/latex.mdx +51 -8
  76. package/.docs/raw/docs/{(docs)/guides → guides}/mentions.mdx +61 -86
  77. package/.docs/raw/docs/{(docs)/guides → guides}/message-timing.mdx +8 -2
  78. package/.docs/raw/docs/{(docs)/guides → guides}/multi-agent.mdx +64 -4
  79. package/.docs/raw/docs/{(docs)/guides → guides}/quoting.mdx +10 -17
  80. package/.docs/raw/docs/{(docs)/guides → guides}/slash-commands.mdx +103 -37
  81. package/.docs/raw/docs/guides/speech.mdx +156 -0
  82. package/.docs/raw/docs/{(docs)/guides → guides}/suggestions.mdx +21 -83
  83. package/.docs/raw/docs/{(docs)/guides → guides}/tool-ui.mdx +108 -36
  84. package/.docs/raw/docs/{(docs)/guides → guides}/tools.mdx +131 -35
  85. package/.docs/raw/docs/{(docs)/guides → guides}/voice.mdx +39 -0
  86. package/.docs/raw/docs/ink/index.mdx +1 -3
  87. package/.docs/raw/docs/ink/migration.mdx +1 -3
  88. package/.docs/raw/docs/ink/primitives.mdx +37 -1
  89. package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +520 -0
  90. package/.docs/raw/docs/integrations/auth/better-auth.mdx +191 -0
  91. package/.docs/raw/docs/integrations/auth/clerk.mdx +172 -0
  92. package/.docs/raw/docs/integrations/auth/next-auth.mdx +196 -0
  93. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +79 -0
  94. package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +188 -0
  95. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +57 -0
  96. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +201 -0
  97. package/.docs/raw/docs/integrations/gateways/index.mdx +157 -0
  98. package/.docs/raw/docs/integrations/index.mdx +173 -0
  99. package/.docs/raw/docs/integrations/observability/helicone.mdx +130 -0
  100. package/.docs/raw/docs/integrations/observability/langfuse.mdx +156 -0
  101. package/.docs/raw/docs/integrations/observability/langsmith.mdx +146 -0
  102. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +712 -0
  103. package/.docs/raw/docs/integrations/tools/mcp.mdx +267 -0
  104. package/.docs/raw/docs/primitives/action-bar.mdx +1 -0
  105. package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -0
  106. package/.docs/raw/docs/primitives/attachment.mdx +1 -0
  107. package/.docs/raw/docs/primitives/branch-picker.mdx +1 -0
  108. package/.docs/raw/docs/primitives/chain-of-thought.mdx +90 -85
  109. package/.docs/raw/docs/primitives/composer.mdx +2 -1
  110. package/.docs/raw/docs/primitives/error.mdx +1 -0
  111. package/.docs/raw/docs/primitives/index.mdx +2 -1
  112. package/.docs/raw/docs/primitives/message.mdx +68 -5
  113. package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -0
  114. package/.docs/raw/docs/primitives/suggestion.mdx +1 -0
  115. package/.docs/raw/docs/primitives/thread-list.mdx +39 -0
  116. package/.docs/raw/docs/primitives/thread.mdx +16 -13
  117. package/.docs/raw/docs/react-native/index.mdx +1 -3
  118. package/.docs/raw/docs/react-native/migration.mdx +1 -3
  119. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +396 -0
  120. package/.docs/raw/docs/runtimes/a2a/overview.mdx +60 -0
  121. package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +216 -0
  122. package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +70 -0
  123. package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +243 -0
  124. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +123 -0
  125. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +52 -0
  126. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +71 -131
  127. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +69 -63
  128. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +330 -123
  129. package/.docs/raw/docs/runtimes/concepts/adapters.mdx +265 -0
  130. package/.docs/raw/docs/runtimes/concepts/architecture.mdx +125 -0
  131. package/.docs/raw/docs/runtimes/concepts/stability.mdx +67 -0
  132. package/.docs/raw/docs/runtimes/concepts/threads.mdx +428 -0
  133. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +703 -0
  134. package/.docs/raw/docs/runtimes/custom/data-stream.mdx +323 -0
  135. package/.docs/raw/docs/runtimes/custom/external-store.mdx +253 -1236
  136. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +746 -0
  137. package/.docs/raw/docs/runtimes/custom/overview.mdx +71 -0
  138. package/.docs/raw/docs/runtimes/google-adk/api.mdx +256 -0
  139. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +717 -0
  140. package/.docs/raw/docs/runtimes/google-adk/overview.mdx +69 -0
  141. package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +229 -0
  142. package/.docs/raw/docs/runtimes/langchain.mdx +533 -0
  143. package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +305 -0
  144. package/.docs/raw/docs/runtimes/langgraph/interrupts.mdx +104 -0
  145. package/.docs/raw/docs/runtimes/langgraph/overview.mdx +84 -0
  146. package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +496 -0
  147. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +127 -0
  148. package/.docs/raw/docs/runtimes/langgraph/threads.mdx +113 -0
  149. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +3 -3
  150. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +0 -23
  151. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +1 -1
  152. package/.docs/raw/docs/runtimes/opencode/hooks.mdx +191 -0
  153. package/.docs/raw/docs/runtimes/opencode/overview.mdx +48 -0
  154. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +119 -0
  155. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +71 -203
  156. package/.docs/raw/docs/ui/accordion.mdx +1 -0
  157. package/.docs/raw/docs/ui/assistant-modal.mdx +1 -0
  158. package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -0
  159. package/.docs/raw/docs/ui/attachment.mdx +1 -0
  160. package/.docs/raw/docs/ui/badge.mdx +1 -0
  161. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +1 -0
  162. package/.docs/raw/docs/ui/context-display.mdx +1 -0
  163. package/.docs/raw/docs/ui/diff-viewer.mdx +1 -0
  164. package/.docs/raw/docs/ui/directive-text.mdx +1 -0
  165. package/.docs/raw/docs/ui/file.mdx +1 -0
  166. package/.docs/raw/docs/ui/image.mdx +1 -0
  167. package/.docs/raw/docs/ui/markdown.mdx +2 -14
  168. package/.docs/raw/docs/ui/mermaid.mdx +1 -0
  169. package/.docs/raw/docs/ui/message-timing.mdx +3 -2
  170. package/.docs/raw/docs/ui/model-selector.mdx +1 -0
  171. package/.docs/raw/docs/ui/part-grouping.mdx +325 -313
  172. package/.docs/raw/docs/ui/quote.mdx +1 -0
  173. package/.docs/raw/docs/ui/reasoning.mdx +66 -33
  174. package/.docs/raw/docs/ui/scrollbar.mdx +1 -0
  175. package/.docs/raw/docs/ui/select.mdx +1 -0
  176. package/.docs/raw/docs/ui/sources.mdx +1 -0
  177. package/.docs/raw/docs/ui/streamdown.mdx +1 -0
  178. package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -0
  179. package/.docs/raw/docs/ui/tabs.mdx +1 -0
  180. package/.docs/raw/docs/ui/thread-list.mdx +17 -0
  181. package/.docs/raw/docs/ui/thread.mdx +56 -1
  182. package/.docs/raw/docs/ui/tool-fallback.mdx +1 -0
  183. package/.docs/raw/docs/ui/tool-group.mdx +39 -11
  184. package/.docs/raw/docs/ui/voice.mdx +1 -0
  185. package/.docs/raw/docs/utilities/heat-graph.mdx +1 -0
  186. package/.docs/raw/docs/utilities/react-o11y.mdx +278 -0
  187. package/.docs/raw/docs/utilities/tw-shimmer.mdx +1 -0
  188. package/package.json +3 -3
  189. package/src/tools/tests/path-traversal.test.ts +1 -1
  190. package/.docs/raw/docs/(docs)/guides/branching.mdx +0 -65
  191. package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +0 -164
  192. package/.docs/raw/docs/(docs)/guides/editing.mdx +0 -66
  193. package/.docs/raw/docs/(docs)/guides/speech.mdx +0 -38
  194. package/.docs/raw/docs/runtimes/a2a/index.mdx +0 -298
  195. package/.docs/raw/docs/runtimes/assistant-transport.mdx +0 -1033
  196. package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +0 -314
  197. package/.docs/raw/docs/runtimes/custom/local.mdx +0 -1464
  198. package/.docs/raw/docs/runtimes/data-stream.mdx +0 -422
  199. package/.docs/raw/docs/runtimes/google-adk/index.mdx +0 -686
  200. package/.docs/raw/docs/runtimes/helicone.mdx +0 -61
  201. package/.docs/raw/docs/runtimes/langchain/comparison.mdx +0 -60
  202. package/.docs/raw/docs/runtimes/langchain/index.mdx +0 -210
  203. package/.docs/raw/docs/runtimes/langgraph/index.mdx +0 -699
  204. package/.docs/raw/docs/runtimes/langgraph/tutorial/index.mdx +0 -12
  205. package/.docs/raw/docs/runtimes/langserve.mdx +0 -116
  206. package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +0 -218
  207. package/.docs/raw/docs/runtimes/mastra/overview.mdx +0 -18
  208. package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +0 -217
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: Tools
3
3
  description: Give your assistant actions like API calls, database queries, and more.
4
+ platforms: ["react"]
4
5
  ---
5
6
 
6
7
  Tools enable LLMs to take actions and interact with external systems. assistant-ui provides a comprehensive toolkit for creating, managing, and visualizing tool interactions in real-time.
@@ -24,9 +25,9 @@ When tools are executed, you can display custom generative UI components that pr
24
25
  creating your own Tool UI component for the tool's name.
25
26
  </Callout>
26
27
 
27
- ## Recommended: Tools() API
28
+ ## Tools() API
28
29
 
29
- The `Tools()` API is the recommended way to register tools in assistant-ui. It provides centralized tool registration that prevents duplicate registrations and works seamlessly with all runtimes.
30
+ The `Tools()` API is the recommended starting point for registering tools in assistant-ui. It provides centralized tool registration that prevents duplicate registrations and works seamlessly with all runtimes. For tools whose availability depends on a specific part of your UI being mounted, see the [component-based APIs](#component-based-apis) below; both styles are supported and can be mixed in the same app.
30
31
 
31
32
  ### Quick Start
32
33
 
@@ -207,6 +208,32 @@ execute: async (args, context) => {
207
208
  };
208
209
  ```
209
210
 
211
+ ### Cancellation
212
+
213
+ `context.abortSignal` is an `AbortSignal` that fires when the user stops the run. Pass it to any async I/O so the work stops immediately:
214
+
215
+ ```tsx
216
+ execute: async ({ query }, { abortSignal }) => {
217
+ const res = await fetch(`/api/search?q=${query}`, { signal: abortSignal });
218
+ return res.json();
219
+ },
220
+ ```
221
+
222
+ When using LangGraph with `unstable_createLangGraphStream`, the default `onDisconnect` value is already `"cancel"`, which tells the LangGraph server to cancel the run on abort:
223
+
224
+ ```ts
225
+ import { unstable_createLangGraphStream } from "@assistant-ui/react-langgraph";
226
+
227
+ const stream = unstable_createLangGraphStream({
228
+ client,
229
+ assistantId,
230
+ // onDisconnect defaults to "cancel"; the server cancels the run when the
231
+ // client disconnects or the user stops the message.
232
+ });
233
+ ```
234
+
235
+ See the [LangGraph quickstart](/docs/runtimes/langgraph/quickstart) for full setup.
236
+
210
237
  ### Human-in-the-Loop
211
238
 
212
239
  Tools can pause execution to request user input or approval:
@@ -260,15 +287,51 @@ const confirmationToolkit: Toolkit = {
260
287
  };
261
288
  ```
262
289
 
263
- ## Alternative Methods (Legacy)
290
+ ### Streaming Tool Args
291
+
292
+ While a tool is running, its arguments arrive as partial JSON. Use `useToolArgsStatus` inside a tool UI render function to react to each top-level field as it streams in. The hook is exported from `@assistant-ui/react`.
293
+
294
+ ```tsx
295
+ import { useToolArgsStatus } from "@assistant-ui/react";
296
+
297
+ const SearchToolUI = makeAssistantToolUI<{ query: string; limit: number }, unknown>({
298
+ toolName: "search",
299
+ render: ({ args }) => {
300
+ const { propStatus } = useToolArgsStatus<{ query: string; limit: number }>();
301
+
302
+ return (
303
+ <div>
304
+ <span className={propStatus.query === "streaming" ? "animate-pulse" : ""}>
305
+ {args.query ?? "..."}
306
+ </span>
307
+ {propStatus.limit === "complete" && <span> (limit: {args.limit})</span>}
308
+ </div>
309
+ );
310
+ },
311
+ });
312
+ ```
313
+
314
+ `propStatus` maps each top-level key in the args object to `"streaming"` while it is still being parsed and to `"complete"` once that field is fully present.
315
+
316
+ ## Component-Based APIs
317
+
318
+ `makeAssistantTool`, `useAssistantTool`, and `makeAssistantToolUI` are component-and-hook-based APIs that coexist with the [`Tools()`](#tools-api) toolkit pattern. They are fully supported and the natural fit for the [intelligent components](/docs/copilots/motivation) pattern, where each part of your UI registers the tools it owns when it is mounted, for example a product-specific tool that should only be exposed while that product's screen is open.
319
+
320
+ <Callout type="info">
321
+ Be careful not to register the same tool from both APIs at once: each API
322
+ registers under `toolName`, and duplicate registrations will be rejected.
323
+ </Callout>
264
324
 
265
- <Callout type="warning">
266
- The following methods are supported for backwards compatibility but are not
267
- recommended for new code. They can cause duplicate registration errors and are
268
- harder to maintain. Use the `Tools()` API instead.
325
+ <Callout type="warn">
326
+ Tool **execution** can be registered dynamically (when a component mounts),
327
+ but tool **UI** should generally be pre-registered. A `render` function that
328
+ is only registered while a specific component is mounted will not render
329
+ when chat history is replayed or during server-side rendering. Either
330
+ declare the tool's `render` in a `Tools()` toolkit, or mount
331
+ `makeAssistantToolUI` near the root of your tree.
269
332
  </Callout>
270
333
 
271
- ### Using `makeAssistantTool` (Deprecated)
334
+ ### Using `makeAssistantTool`
272
335
 
273
336
  Register tools with the assistant context. Returns a React component that registers the tool when rendered:
274
337
 
@@ -303,9 +366,9 @@ function App() {
303
366
  }
304
367
  ```
305
368
 
306
- **Why this is deprecated**: Component-based registration can lead to duplicate registrations if components are remounted or if the same tool is defined in multiple places.
369
+ Tradeoff: component-based registration is tied to React lifecycle, so the tool is registered when the component mounts and unregistered when it unmounts. Take care not to remount it accidentally if you also register the same tool elsewhere.
307
370
 
308
- ### Using `useAssistantTool` Hook (Deprecated)
371
+ ### Using the `useAssistantTool` Hook
309
372
 
310
373
  Register tools dynamically using React hooks:
311
374
 
@@ -329,9 +392,9 @@ function DynamicTools() {
329
392
  }
330
393
  ```
331
394
 
332
- **Why this is deprecated**: Hook-based registration ties tool definitions to component lifecycle, making them harder to test and potentially causing duplicate registrations.
395
+ Tradeoff: like `makeAssistantTool`, the registration follows the component lifecycle. Useful for dynamic tools that depend on component state or props.
333
396
 
334
- ### Using `makeAssistantToolUI` (Deprecated)
397
+ ### Using `makeAssistantToolUI`
335
398
 
336
399
  Create UI-only components for tools defined elsewhere:
337
400
 
@@ -365,7 +428,7 @@ function App() {
365
428
  }
366
429
  ```
367
430
 
368
- **Why this is deprecated**: Component-based UI registration can cause issues with tool UI not appearing or appearing multiple times.
431
+ Tradeoff: like the other component-based APIs, the UI is registered while the component is mounted. Useful when the tool UI needs access to surrounding component state or context.
369
432
 
370
433
  ## Tool Paradigms
371
434
 
@@ -391,37 +454,32 @@ const frontendToolkit: Toolkit = {
391
454
 
392
455
  ### Backend Tools
393
456
 
394
- Tools executed server-side:
457
+ Tools executed server-side live in your API route. A minimal example with the AI SDK:
458
+
459
+ ```ts title="@/app/api/chat/route.ts"
460
+ import { openai } from "@ai-sdk/openai";
461
+ import { streamText, convertToModelMessages, tool, zodSchema } from "ai";
462
+ import { z } from "zod";
395
463
 
396
- ```tsx
397
- // Backend route (AI SDK)
398
464
  export async function POST(req: Request) {
399
465
  const { messages } = await req.json();
400
-
401
466
  const result = streamText({
402
467
  model: openai("gpt-4o"),
403
468
  messages: await convertToModelMessages(messages),
404
469
  tools: {
405
- queryDatabase: {
470
+ queryDatabase: tool({
406
471
  description: "Query the application database",
407
- inputSchema: zodSchema(
408
- z.object({
409
- query: z.string(),
410
- table: z.string(),
411
- }),
412
- ),
413
- execute: async ({ query, table }) => {
414
- const results = await db.query(query, { table });
415
- return results;
416
- },
417
- },
472
+ inputSchema: zodSchema(z.object({ query: z.string(), table: z.string() })),
473
+ execute: async ({ query, table }) => db.query(query, { table }),
474
+ }),
418
475
  },
419
476
  });
420
-
421
477
  return result.toUIMessageStreamResponse();
422
478
  }
423
479
  ```
424
480
 
481
+ For the full AI SDK v6 backend setup including multi-step tool calls, frontend tools, history persistence with `withFormat`, and more, see the [AI SDK v6 guide](/docs/runtimes/ai-sdk/v6).
482
+
425
483
  ### Client-Defined Tools with frontendTools
426
484
 
427
485
  The Vercel AI SDK adapter implements automatic serialization of client-defined tools. Tools registered via the `Tools()` API are automatically included in API requests:
@@ -512,9 +570,47 @@ export async function POST(req: Request) {
512
570
  }
513
571
  ```
514
572
 
573
+ ## LangGraph subgraph events
574
+
575
+ When a LangGraph graph contains sub-agents (nested subgraphs), events from those subgraphs arrive with a `metadata.namespace` field identifying the originating subgraph. Pass event handlers to `useLangGraphRuntime` (or `useLangGraphMessages`) to react to them:
576
+
577
+ ```ts
578
+ const runtime = useLangGraphRuntime({
579
+ stream,
580
+ eventHandlers: {
581
+ onSubgraphValues: (namespace, values) => {
582
+ console.log("subgraph", namespace, "state:", values);
583
+ },
584
+ onSubgraphUpdates: (namespace, updates) => {
585
+ console.log("subgraph", namespace, "updates:", updates);
586
+ },
587
+ onSubgraphError: (namespace, error) => {
588
+ console.error("subgraph", namespace, "error:", error);
589
+ },
590
+ },
591
+ });
592
+ ```
593
+
594
+ `namespace` is a pipe-separated string like `"parent|child_agent"`. Messages emitted by a subgraph include `metadata.namespace` so you can attribute tool results to the correct sub-agent.
595
+
596
+ ## `useLangChainState`
597
+
598
+ When using `@assistant-ui/react-langchain` (`useStreamRuntime`), the `useLangChainState` hook lets you read any key from the current LangChain/LangGraph state on the client without a separate API call:
599
+
600
+ ```tsx
601
+ import { useLangChainState } from "@assistant-ui/react-langchain";
602
+
603
+ function TodoSidebar() {
604
+ const todos = useLangChainState<string[]>("todos", []);
605
+ return <ul>{todos.map((t) => <li key={t}>{t}</li>)}</ul>;
606
+ }
607
+ ```
608
+
609
+ The second argument is an optional default value. The hook re-renders whenever the state key changes during a stream.
610
+
515
611
  ## Best Practices
516
612
 
517
- 1. **Use Tools() API**: Always prefer the `Tools()` API over legacy component/hook-based registration
613
+ 1. **Pick one registration style per tool**: avoid registering the same tool through both the `Tools()` toolkit and a component-based API; both routes will register, and duplicates are rejected
518
614
  2. **Centralize Definitions**: Keep all tools in a toolkit file for easy management
519
615
  3. **Clear Descriptions**: Write descriptive tool descriptions that help the LLM understand when to use each tool
520
616
  4. **Parameter Validation**: Use Zod schemas to ensure type safety
@@ -524,9 +620,9 @@ export async function POST(req: Request) {
524
620
  8. **Performance**: Use abort signals for cancellable operations
525
621
  9. **Testing**: Test tools in isolation and with the full assistant flow
526
622
 
527
- ## Migration from Legacy APIs
623
+ ## Switching from Component-Based to Toolkit
528
624
 
529
- To migrate from legacy APIs to the `Tools()` API:
625
+ If you prefer the toolkit shape, switching is mechanical:
530
626
 
531
627
  1. **Create a toolkit object** with all your tools
532
628
  2. **Move tool definitions** from `makeAssistantTool`/`useAssistantTool` calls into the toolkit
@@ -537,7 +633,7 @@ To migrate from legacy APIs to the `Tools()` API:
537
633
  Example migration:
538
634
 
539
635
  ```tsx
540
- // Before (Legacy)
636
+ // Component-based API
541
637
  const WeatherTool = makeAssistantTool({
542
638
  toolName: "getWeather",
543
639
  description: "Get weather",
@@ -554,7 +650,7 @@ function App() {
554
650
  );
555
651
  }
556
652
 
557
- // After (Recommended)
653
+ // Toolkit API
558
654
  const toolkit: Toolkit = {
559
655
  getWeather: {
560
656
  description: "Get weather",
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: Realtime Voice
3
3
  description: Bidirectional realtime voice conversations with AI agents.
4
+ platforms: ["react"]
4
5
  ---
5
6
 
6
7
  import { VoiceSample } from "@/components/docs/samples/voice";
@@ -63,6 +64,10 @@ const { connect, disconnect, mute, unmute } = useVoiceControls();
63
64
 
64
65
  ## UI Example
65
66
 
67
+ <Callout type="info">
68
+ For a ready-made control bar with a voice orb and call controls, see the [Voice component](/docs/ui/voice).
69
+ </Callout>
70
+
66
71
  ```tsx
67
72
  import { useVoiceState, useVoiceControls } from "@assistant-ui/react";
68
73
  import { PhoneIcon, PhoneOffIcon, MicIcon, MicOffIcon } from "lucide-react";
@@ -301,6 +306,40 @@ const runtime = useChatRuntime({
301
306
  });
302
307
  ```
303
308
 
309
+ ## Using `createVoiceSession`
310
+
311
+ `createVoiceSession` is a helper that eliminates the manual `Set<callback>` boilerplate shown in the ElevenLabs example above. Pass it an async `setup` function that receives a `helpers` object and returns `{ disconnect, mute, unmute }`. The helper wires up all callback sets, status tracking, and abort-signal handling for you.
312
+
313
+ ```tsx title="lib/my-voice-adapter.ts"
314
+ import { createVoiceSession, type RealtimeVoiceAdapter } from "@assistant-ui/react";
315
+
316
+ export class MyVoiceAdapter implements RealtimeVoiceAdapter {
317
+ connect(options: { abortSignal?: AbortSignal }): RealtimeVoiceAdapter.Session {
318
+ return createVoiceSession(options, async (helpers) => {
319
+ // Connect to your provider
320
+ const client = await MyVoiceClient.connect();
321
+
322
+ client.on("open", () => helpers.setStatus({ type: "running" }));
323
+ client.on("close", () => helpers.end("finished"));
324
+ client.on("error", (err) => helpers.end("error", err));
325
+
326
+ client.on("transcript", (item) => helpers.emitTranscript(item));
327
+ client.on("mode", (mode) => helpers.emitMode(mode));
328
+ client.on("volume", (v) => helpers.emitVolume(v));
329
+
330
+ // Return controls — createVoiceSession calls these on disconnect/mute/unmute
331
+ return {
332
+ disconnect: () => client.close(),
333
+ mute: () => client.setMuted(true),
334
+ unmute: () => client.setMuted(false),
335
+ };
336
+ });
337
+ }
338
+ }
339
+ ```
340
+
341
+ The `helpers` object exposes `setStatus`, `end`, `emitTranscript`, `emitMode`, `emitVolume`, and `isDisposed`. When `isDisposed()` is true the session has been torn down and you can skip further event handling.
342
+
304
343
  ## Example: LiveKit
305
344
 
306
345
  [LiveKit](https://livekit.io/) provides realtime voice via WebRTC rooms with transcription support. Unlike fully-hosted agent services, LiveKit follows a "bring-your-own-agent" model: the browser adapter only joins a room, and you run a separate **agent worker** that joins the same room and handles STT, LLM, and TTS. Without an agent in the room, the client will connect successfully but have nothing to talk to.
@@ -47,9 +47,7 @@ If you prefer to add assistant-ui to an existing Node.js project, follow these s
47
47
 
48
48
  ### Install dependencies
49
49
 
50
- ```sh
51
- npm install @assistant-ui/react-ink @assistant-ui/react-ink-markdown ink react
52
- ```
50
+ <InstallCommand npm={["@assistant-ui/react-ink", "@assistant-ui/react-ink-markdown", "ink", "react"]} />
53
51
 
54
52
  </Step>
55
53
  <Step>
@@ -30,9 +30,7 @@ If you already have an assistant-ui web app, most of your code transfers directl
30
30
 
31
31
  ### Install the React Ink package
32
32
 
33
- ```sh
34
- npm install @assistant-ui/react-ink ink react
35
- ```
33
+ <InstallCommand npm={["@assistant-ui/react-ink", "ink", "react"]} />
36
34
 
37
35
  </Step>
38
36
  <Step>
@@ -177,11 +177,12 @@ Container `Box` for the composer area.
177
177
 
178
178
  ### Input
179
179
 
180
- Ink `TextInput` wired to the composer runtime. Value is managed automatically.
180
+ Terminal line editor wired to the composer runtime. Value is managed automatically and supports cursor-aware editing.
181
181
 
182
182
  ```tsx
183
183
  <ComposerPrimitive.Input
184
184
  submitOnEnter
185
+ multiLine
185
186
  placeholder="Type a message..."
186
187
  autoFocus
187
188
  />
@@ -192,6 +193,41 @@ Ink `TextInput` wired to the composer runtime. Value is managed automatically.
192
193
  | `submitOnEnter` | `boolean` | Whether Enter sends the message (default: `false`) |
193
194
  | `placeholder` | `string` | Placeholder text when empty |
194
195
  | `autoFocus` | `boolean` | Auto-focus on mount |
196
+ | `multiLine` | `boolean` | When true, Enter inserts a newline unless `submitOnEnter` is enabled |
197
+ | `onSubmit` | `(text: string) => void` | Overrides the default send behavior and receives the current composer text |
198
+
199
+ Supported keyboard bindings:
200
+
201
+ | Key | Action | Context |
202
+ |-----|--------|---------|
203
+ | `Left` / `Right` | Move cursor by one grapheme | Always |
204
+ | `Backspace` / `Delete` | Remove the grapheme before / after the cursor | Always |
205
+ | `Home` / `End` | Jump to buffer or line boundary | Buffer in single-line, line in multi-line |
206
+ | `Up` / `Down` | Move between lines, preserving column when possible | Multi-line only |
207
+ | `Ctrl+A` / `Ctrl+E` | Move to line start / end | Always |
208
+ | `Ctrl+W` | Kill the word before the cursor | Always |
209
+ | `Ctrl+D` | Delete the grapheme after the cursor | Always |
210
+ | `Ctrl+U` / `Ctrl+K` | Kill from cursor to line start / end; in multi-line, `Ctrl+K` at end-of-line joins the next line | Always |
211
+ | `Ctrl+J` | Insert a newline | Multi-line only; swallowed in single-line so it never submits |
212
+ | `Alt+B` / `Alt+F` | Move by word backward / forward | Terminals that emit meta-key sequences |
213
+ | `Alt+D` | Kill the word after the cursor | Terminals that emit meta-key sequences |
214
+ | `Shift+Enter` | Insert a newline | Multi-line submit mode, terminals that distinguish it |
215
+
216
+ Word boundaries and grapheme stepping use `Intl.Segmenter`, so emoji, accented letters, skin-tone modifiers, ZWJ sequences, and CJK ideographs each move and delete as a single character.
217
+
218
+ Some bindings depend on terminal capabilities. iTerm2, Windows Terminal, and most Linux terminals emit `Alt`-letter combinations as `Esc`-prefixed sequences that Ink decodes as meta-key input; macOS Terminal.app requires enabling "Use Option as Meta key" in its preferences before `Alt+B` / `Alt+F` / `Alt+D` work as expected. `Shift+Enter` requires a terminal that supports the CSI-u protocol (iTerm2 3.4+, kitty, foot, and similar) — terminals that conflate it with `Enter` will fall back to the `submitOnEnter` behaviour.
219
+
220
+ Example with custom submit handling:
221
+
222
+ ```tsx
223
+ <ComposerPrimitive.Input
224
+ multiLine
225
+ submitOnEnter
226
+ onSubmit={(text) => {
227
+ console.log("submit", text);
228
+ }}
229
+ />
230
+ ```
195
231
 
196
232
  ### Send
197
233