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

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 (134) hide show
  1. package/.docs/organized/code-examples/waterfall.md +20 -22
  2. package/.docs/organized/code-examples/with-a2a.md +24 -24
  3. package/.docs/organized/code-examples/with-ag-ui.md +30 -25
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +11 -9
  5. package/.docs/organized/code-examples/with-artifacts.md +49 -37
  6. package/.docs/organized/code-examples/with-assistant-transport.md +63 -51
  7. package/.docs/organized/code-examples/with-browser-extension.md +22 -10
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +406 -87
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +25 -24
  10. package/.docs/organized/code-examples/with-cloud.md +11 -9
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +14 -12
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +23 -21
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +14 -13
  14. package/.docs/organized/code-examples/with-expo.md +44 -29
  15. package/.docs/organized/code-examples/with-external-store.md +9 -7
  16. package/.docs/organized/code-examples/with-ffmpeg.md +322 -285
  17. package/.docs/organized/code-examples/with-generative-ui.md +1066 -256
  18. package/.docs/organized/code-examples/with-google-adk.md +10 -8
  19. package/.docs/organized/code-examples/with-heat-graph.md +13 -11
  20. package/.docs/organized/code-examples/with-image-generation.md +19 -17
  21. package/.docs/organized/code-examples/with-interactables.md +317 -239
  22. package/.docs/organized/code-examples/with-langchain.md +14 -12
  23. package/.docs/organized/code-examples/with-langgraph.md +91 -83
  24. package/.docs/organized/code-examples/with-livekit.md +24 -22
  25. package/.docs/organized/code-examples/with-mcp.md +18 -12
  26. package/.docs/organized/code-examples/with-opencode.md +66 -66
  27. package/.docs/organized/code-examples/with-react-hook-form.md +19 -17
  28. package/.docs/organized/code-examples/with-react-ink.md +297 -102
  29. package/.docs/organized/code-examples/with-react-router.md +17 -15
  30. package/.docs/organized/code-examples/with-resumable-stream.md +15 -14
  31. package/.docs/organized/code-examples/with-store.md +78 -76
  32. package/.docs/organized/code-examples/with-tanstack.md +13 -14
  33. package/.docs/organized/code-examples/with-tap-runtime.md +26 -24
  34. package/.docs/raw/docs/(docs)/architecture.mdx +94 -42
  35. package/.docs/raw/docs/(docs)/cli.mdx +1 -2
  36. package/.docs/raw/docs/(docs)/installation.mdx +1 -1
  37. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +5 -1
  38. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +15 -15
  39. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +14 -1
  40. package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +18 -0
  41. package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +33 -0
  42. package/.docs/raw/docs/(reference)/api-reference/generative-ui/spec.mdx +45 -0
  43. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +41 -41
  44. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +19 -1
  45. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +122 -122
  46. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +43 -2
  47. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +6 -0
  48. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +4 -6
  49. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +30 -0
  50. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +20 -3
  51. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +8 -8
  52. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +52 -4
  53. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +100 -10
  54. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +7 -59
  55. package/.docs/raw/docs/cloud/ai-sdk.mdx +0 -2
  56. package/.docs/raw/docs/{(docs)/copilots → copilots}/model-context.mdx +34 -26
  57. package/.docs/raw/docs/{(docs)/copilots → copilots}/motivation.mdx +32 -26
  58. package/.docs/raw/docs/guides/chain-of-thought.mdx +7 -9
  59. package/.docs/raw/docs/guides/context-api.mdx +2 -1
  60. package/.docs/raw/docs/guides/index.mdx +3 -12
  61. package/.docs/raw/docs/guides/mentions.mdx +4 -4
  62. package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
  63. package/.docs/raw/docs/guides/suggestions.mdx +1 -1
  64. package/.docs/raw/docs/ink/adapters.mdx +23 -1
  65. package/.docs/raw/docs/ink/hooks.mdx +101 -85
  66. package/.docs/raw/docs/ink/migration.mdx +1 -1
  67. package/.docs/raw/docs/ink/primitives.mdx +2 -2
  68. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +1 -1
  69. package/.docs/raw/docs/integrations/index.mdx +2 -2
  70. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +17 -2
  71. package/.docs/raw/docs/migrations/toolkit-tools.mdx +232 -0
  72. package/.docs/raw/docs/primitives/chain-of-thought.mdx +10 -16
  73. package/.docs/raw/docs/primitives/message.mdx +9 -10
  74. package/.docs/raw/docs/react-native/hooks.mdx +62 -79
  75. package/.docs/raw/docs/react-native/migration.mdx +1 -1
  76. package/.docs/raw/docs/react-native/primitives.mdx +2 -2
  77. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +3 -0
  78. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +41 -0
  79. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +122 -1
  80. package/.docs/raw/docs/runtimes/concepts/architecture.mdx +46 -4
  81. package/.docs/raw/docs/runtimes/concepts/threads.mdx +7 -1
  82. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +54 -12
  83. package/.docs/raw/docs/runtimes/custom/external-store.mdx +62 -4
  84. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +30 -7
  85. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +108 -38
  86. package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +2 -2
  87. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +14 -1
  88. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +64 -50
  89. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +98 -86
  90. package/.docs/raw/docs/tools/backend.mdx +144 -0
  91. package/.docs/raw/docs/tools/defining-tools.mdx +538 -0
  92. package/.docs/raw/docs/tools/dynamic-tools.mdx +110 -0
  93. package/.docs/raw/docs/tools/generative-ui.mdx +214 -0
  94. package/.docs/raw/docs/tools/index.mdx +71 -0
  95. package/.docs/raw/docs/{guides → tools}/interactables.mdx +1 -1
  96. package/.docs/raw/docs/{integrations/tools → tools}/mcp.mdx +145 -50
  97. package/.docs/raw/docs/{guides → tools}/multi-agent.mdx +15 -17
  98. package/.docs/raw/docs/tools/tool-ui.mdx +967 -0
  99. package/.docs/raw/docs/{integrations/tools/react-mcp.mdx → tools/user-managed-mcp.mdx} +7 -7
  100. package/.docs/raw/docs/ui/directive-text.mdx +3 -3
  101. package/.docs/raw/docs/ui/mcp-config.mdx +4 -4
  102. package/.docs/raw/docs/ui/mermaid.mdx +16 -9
  103. package/.docs/raw/docs/ui/part-grouping.mdx +84 -50
  104. package/.docs/raw/docs/ui/reasoning.mdx +4 -5
  105. package/.docs/raw/docs/ui/tool-fallback.mdx +16 -0
  106. package/.docs/raw/docs/ui/tool-group.mdx +5 -6
  107. package/.docs/raw/docs/utilities/heat-graph.mdx +1 -1
  108. package/.docs/raw/docs/utilities/react-o11y.mdx +2 -2
  109. package/dist/constants.js.map +1 -1
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js.map +1 -1
  112. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  113. package/dist/prepare-docs/code-examples.js.map +1 -1
  114. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  115. package/dist/prepare-docs/copy-raw.js.map +1 -1
  116. package/dist/prepare-docs/prepare.js.map +1 -1
  117. package/dist/stdio.js.map +1 -1
  118. package/dist/tools/docs.js.map +1 -1
  119. package/dist/tools/examples.js.map +1 -1
  120. package/dist/tools/tests/test-setup.js.map +1 -1
  121. package/dist/utils/mdx.js.map +1 -1
  122. package/dist/utils/paths.d.ts.map +1 -1
  123. package/dist/utils/paths.js.map +1 -1
  124. package/package.json +5 -5
  125. package/.docs/organized/code-examples/with-parent-id-grouping.md +0 -596
  126. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +0 -151
  127. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +0 -230
  128. package/.docs/raw/docs/guides/generative-ui.mdx +0 -142
  129. package/.docs/raw/docs/guides/tool-ui.mdx +0 -858
  130. package/.docs/raw/docs/guides/tools.mdx +0 -736
  131. /package/.docs/raw/docs/{(docs)/copilots → copilots}/assistant-frame.mdx +0 -0
  132. /package/.docs/raw/docs/{(docs)/copilots → copilots}/make-assistant-visible.mdx +0 -0
  133. /package/.docs/raw/docs/{(docs)/copilots → copilots}/use-assistant-instructions.mdx +0 -0
  134. /package/.docs/raw/docs/{guides → tools}/mcp-apps.mdx +0 -0
@@ -17,14 +17,44 @@ If you do not have an existing store, use [`LocalRuntime`](/docs/runtimes/custom
17
17
 
18
18
  ## Architecture
19
19
 
20
- ```mermaid
21
- graph TD
20
+ <Flow.Root
21
+ llm={`graph TD
22
22
  A[Your state] -->|messages| B[ExternalStoreAdapter]
23
23
  B --> C[ExternalStoreRuntime]
24
24
  C --> D[assistant-ui components]
25
25
  D -->|user actions| B
26
- B -->|state updates| A
27
- ```
26
+ B -->|state updates| A`}
27
+ >
28
+ <Flow.Canvas
29
+ className="pr-44"
30
+ edges={[
31
+ {
32
+ from: "components",
33
+ to: "adapter",
34
+ route: "loop-right",
35
+ label: "user actions",
36
+ laneOffset: 40,
37
+ },
38
+ {
39
+ from: "adapter",
40
+ to: "state",
41
+ route: "loop-right",
42
+ label: "state updates",
43
+ laneOffset: 88,
44
+ },
45
+ ]}
46
+ >
47
+ <Flow.Column>
48
+ <Flow.Node flowId="state">Your state</Flow.Node>
49
+ <Flow.Arrow direction="down" label="messages" length={36} />
50
+ <Flow.Node flowId="adapter">ExternalStoreAdapter</Flow.Node>
51
+ <Flow.Arrow direction="down" length={36} />
52
+ <Flow.Node>ExternalStoreRuntime</Flow.Node>
53
+ <Flow.Arrow direction="down" length={36} />
54
+ <Flow.Node flowId="components">assistant-ui components</Flow.Node>
55
+ </Flow.Column>
56
+ </Flow.Canvas>
57
+ </Flow.Root>
28
58
 
29
59
  Key idea: you own the state, the adapter translates between your format and assistant-ui's. UI features are capability-based; if you provide `setMessages`, branching turns on; if you provide `onEdit`, editing turns on; etc.
30
60
 
@@ -178,6 +208,7 @@ Each handler enables a specific UI feature.
178
208
  | `onReload` | Regenerate button |
179
209
  | `onCancel` | Cancel button while generating |
180
210
  | `onAddToolResult` | Client-side tool result handoff |
211
+ | `queue` | Queueing messages sent while a run is in progress |
181
212
 
182
213
  ## Streaming responses
183
214
 
@@ -312,6 +343,33 @@ const runtime = useExternalStoreRuntime({
312
343
  });
313
344
  ```
314
345
 
346
+ ## Queueing messages during a run
347
+
348
+ By default, sending while the thread is running is disabled. Provide a `queue` adapter to buffer a message sent during a run and process it once the run settles. The pending message is exposed on `composer.queue` and renders through [`ComposerPrimitive.Queue`](/docs/api-reference/primitives/composer).
349
+
350
+ The `createMessageQueue` helper owns the FIFO ordering and the in-flight guard. Supply a driver that runs a message, pass its `adapter` to the runtime, and tell the queue when a run starts (`notifyBusy()`, so concurrent sends buffer) and ends (`notifyIdle()`).
351
+
352
+ ```tsx
353
+ import { useEffect, useRef, useState } from "react";
354
+ import { createMessageQueue, useExternalStoreRuntime } from "@assistant-ui/react";
355
+
356
+ const [queue] = useState(() => createMessageQueue({ run: onNew }));
357
+
358
+ const runtime = useExternalStoreRuntime({
359
+ messages,
360
+ isRunning,
361
+ onNew,
362
+ queue: queue.adapter,
363
+ });
364
+
365
+ const wasRunning = useRef(isRunning);
366
+ useEffect(() => {
367
+ if (!wasRunning.current && isRunning) queue.notifyBusy();
368
+ if (wasRunning.current && !isRunning) queue.notifyIdle();
369
+ wasRunning.current = isRunning;
370
+ }, [isRunning, queue]);
371
+ ```
372
+
315
373
  ## Multi-thread
316
374
 
317
375
  `ExternalStoreRuntime` uses `ExternalStoreThreadListAdapter` (synchronous, inline). See [threads](/docs/runtimes/concepts/threads#externalstorethreadlistadapter) for the contract and best practices on keeping `currentThreadId` in sync with your store.
@@ -417,24 +417,35 @@ If you build the `content` array fresh from the current chunk each iteration, to
417
417
 
418
418
  `LocalRuntime` supports OpenAI-compatible function calling. Register tools through `useAui` so the runtime exposes them to your adapter via `context.tools`:
419
419
 
420
- ```tsx
421
- import { useAui, Tools, type Toolkit } from "@assistant-ui/react";
420
+ ```tsx title="app/toolkit.tsx"
421
+ "use generative";
422
+
423
+ import { defineToolkit } from "@assistant-ui/react";
422
424
  import { z } from "zod";
423
425
 
424
- const myToolkit: Toolkit = {
426
+ export default defineToolkit({
425
427
  getWeather: {
426
428
  description: "Get the current weather in a location",
427
429
  parameters: z.object({
428
430
  location: z.string(),
429
431
  unit: z.enum(["celsius", "fahrenheit"]).default("celsius"),
430
432
  }),
431
- execute: async ({ location, unit }) => fetchWeather(location, unit),
433
+ execute: async ({ location, unit }) => {
434
+ "use client";
435
+ return fetchWeather(location, unit);
436
+ },
437
+ renderText: { running: "Checking the weather…", complete: "Weather ready" },
432
438
  },
433
- };
439
+ });
440
+ ```
441
+
442
+ ```tsx title="app/MyRuntimeProvider.tsx"
443
+ import { useAui, Tools } from "@assistant-ui/react";
444
+ import toolkit from "./toolkit";
434
445
 
435
446
  function MyRuntimeProvider({ children }: { children: React.ReactNode }) {
436
447
  const runtime = useLocalRuntime(MyModelAdapter);
437
- const aui = useAui({ tools: Tools({ toolkit: myToolkit }) });
448
+ const aui = useAui({ tools: Tools({ toolkit }) });
438
449
 
439
450
  return (
440
451
  <AssistantRuntimeProvider aui={aui} runtime={runtime}>
@@ -444,7 +455,7 @@ function MyRuntimeProvider({ children }: { children: React.ReactNode }) {
444
455
  }
445
456
  ```
446
457
 
447
- See the [tools guide](/docs/guides/tools) for advanced patterns.
458
+ See the [tools guide](/docs/tools/defining-tools) for advanced patterns.
448
459
 
449
460
  ### Human-in-the-loop approval
450
461
 
@@ -510,6 +521,18 @@ function useStreamReconnect(threadId: string) {
510
521
  }
511
522
  ```
512
523
 
524
+ ## Queueing messages during a run
525
+
526
+ Set `unstable_enableMessageQueue` to keep the composer usable while a run is in progress. A message sent during a run is held in `composer.queue` and sent once the run settles; steering a queued message runs it next.
527
+
528
+ ```tsx
529
+ const runtime = useLocalRuntime(MyModelAdapter, {
530
+ unstable_enableMessageQueue: true,
531
+ });
532
+ ```
533
+
534
+ Render the pending messages with [`ComposerPrimitive.Queue`](/docs/api-reference/primitives/composer) and [`QueueItemPrimitive`](/docs/api-reference/primitives/queue-item).
535
+
513
536
  ## Adapters
514
537
 
515
538
  Attachments, speech, feedback, history, and suggestions are wired through the standard adapter contracts, see [adapters](/docs/runtimes/concepts/adapters):
@@ -257,7 +257,7 @@ When an ADK Python 2.0+ Workflow's `RequestInput` node pauses execution to ask t
257
257
  <Tab value="React">
258
258
 
259
259
  ```tsx
260
- import { makeAssistantToolUI } from "@assistant-ui/react";
260
+ import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
261
261
  import { useAdkSubmitInput } from "@assistant-ui/react-google-adk";
262
262
 
263
263
  type RequestInputArgs = {
@@ -267,12 +267,10 @@ type RequestInputArgs = {
267
267
  response_schema?: unknown;
268
268
  };
269
269
 
270
- export const RequestInputToolUI = makeAssistantToolUI<
270
+ export const RequestInputToolUI: ToolCallMessagePartComponent<
271
271
  RequestInputArgs,
272
272
  unknown
273
- >({
274
- toolName: "adk_request_input",
275
- render: function RequestInputUI({ toolCallId, args, result }) {
273
+ > = function RequestInputUI({ toolCallId, args, result }) {
276
274
  const submitInput = useAdkSubmitInput();
277
275
 
278
276
  if (result !== undefined) {
@@ -294,15 +292,14 @@ export const RequestInputToolUI = makeAssistantToolUI<
294
292
  <button type="submit">Submit</button>
295
293
  </form>
296
294
  );
297
- },
298
- });
295
+ };
299
296
  ```
300
297
 
301
298
  </Tab>
302
299
  <Tab value="React Native">
303
300
 
304
301
  ```tsx
305
- import { makeAssistantToolUI } from "@assistant-ui/react-native";
302
+ import type { ToolCallMessagePartComponent } from "@assistant-ui/react-native";
306
303
  import { useAdkSubmitInput } from "@assistant-ui/react-google-adk";
307
304
  import { useState } from "react";
308
305
  import { Pressable, Text, TextInput, View } from "react-native";
@@ -314,12 +311,10 @@ type RequestInputArgs = {
314
311
  response_schema?: unknown;
315
312
  };
316
313
 
317
- export const RequestInputToolUI = makeAssistantToolUI<
314
+ export const RequestInputToolUI: ToolCallMessagePartComponent<
318
315
  RequestInputArgs,
319
316
  unknown
320
- >({
321
- toolName: "adk_request_input",
322
- render: function RequestInputUI({ toolCallId, args, result }) {
317
+ > = function RequestInputUI({ toolCallId, args, result }) {
323
318
  const submitInput = useAdkSubmitInput();
324
319
  const [value, setValue] = useState("");
325
320
 
@@ -336,15 +331,14 @@ export const RequestInputToolUI = makeAssistantToolUI<
336
331
  </Pressable>
337
332
  </View>
338
333
  );
339
- },
340
- });
334
+ };
341
335
  ```
342
336
 
343
337
  </Tab>
344
338
  <Tab value="React Ink">
345
339
 
346
340
  ```tsx
347
- import { makeAssistantToolUI } from "@assistant-ui/react-ink";
341
+ import type { ToolCallMessagePartComponent } from "@assistant-ui/react-ink";
348
342
  import { useAdkSubmitInput } from "@assistant-ui/react-google-adk";
349
343
  import { useState } from "react";
350
344
  import { Box, Text, useInput } from "ink";
@@ -356,12 +350,10 @@ type RequestInputArgs = {
356
350
  response_schema?: unknown;
357
351
  };
358
352
 
359
- export const RequestInputToolUI = makeAssistantToolUI<
353
+ export const RequestInputToolUI: ToolCallMessagePartComponent<
360
354
  RequestInputArgs,
361
355
  unknown
362
- >({
363
- toolName: "adk_request_input",
364
- render: function RequestInputUI({ toolCallId, args, result }) {
356
+ > = function RequestInputUI({ toolCallId, args, result }) {
365
357
  const submitInput = useAdkSubmitInput();
366
358
  const [value, setValue] = useState("");
367
359
 
@@ -383,53 +375,131 @@ export const RequestInputToolUI = makeAssistantToolUI<
383
375
  <Text dimColor>Press enter to submit.</Text>
384
376
  </Box>
385
377
  );
386
- },
387
- });
378
+ };
388
379
  ```
389
380
 
390
381
  </Tab>
391
382
  </PlatformTabs>
392
383
 
393
- Register the tool UI inside `AssistantRuntimeProvider`:
384
+ Register the renderer with a backend toolkit entry inside `AssistantRuntimeProvider`:
394
385
 
395
386
  <PlatformTabs>
396
387
  <Tab value="React">
397
388
 
398
389
  ```tsx
399
- <AssistantRuntimeProvider runtime={runtime}>
400
- <RequestInputToolUI />
401
- <Thread />
402
- </AssistantRuntimeProvider>
390
+ import {
391
+ AssistantRuntimeProvider,
392
+ defineToolkit,
393
+ Tools,
394
+ useAui,
395
+ } from "@assistant-ui/react";
396
+ import {
397
+ createAdkStream,
398
+ useAdkRuntime,
399
+ } from "@assistant-ui/react-google-adk";
400
+ import { Thread } from "@/components/assistant-ui/thread";
401
+
402
+ const toolkit = defineToolkit({
403
+ adk_request_input: {
404
+ type: "backend",
405
+ render: RequestInputToolUI,
406
+ },
407
+ });
408
+
409
+ function App() {
410
+ const runtime = useAdkRuntime({
411
+ stream: createAdkStream({ api: "/api/chat" }),
412
+ });
413
+ const aui = useAui({ tools: Tools({ toolkit }) });
414
+
415
+ return (
416
+ <AssistantRuntimeProvider aui={aui} runtime={runtime}>
417
+ <Thread />
418
+ </AssistantRuntimeProvider>
419
+ );
420
+ }
403
421
  ```
404
422
 
405
423
  </Tab>
406
424
  <Tab value="React Native">
407
425
 
408
426
  ```tsx
427
+ import {
428
+ AssistantRuntimeProvider,
429
+ defineToolkit,
430
+ Tools,
431
+ useAui,
432
+ } from "@assistant-ui/react-native";
433
+ import {
434
+ createAdkStream,
435
+ useAdkRuntime,
436
+ } from "@assistant-ui/react-google-adk";
409
437
  import { View } from "react-native";
410
438
  import { Thread } from "@/components/assistant-ui/thread";
411
439
 
412
- <AssistantRuntimeProvider runtime={runtime}>
413
- <RequestInputToolUI />
414
- <View style={{ flex: 1 }}>
415
- <Thread />
416
- </View>
417
- </AssistantRuntimeProvider>;
440
+ const API_URL = process.env.EXPO_PUBLIC_API_URL ?? "http://localhost:3000";
441
+
442
+ const toolkit = defineToolkit({
443
+ adk_request_input: {
444
+ type: "backend",
445
+ render: RequestInputToolUI,
446
+ },
447
+ });
448
+
449
+ function App() {
450
+ const runtime = useAdkRuntime({
451
+ stream: createAdkStream({ api: `${API_URL}/api/chat` }),
452
+ });
453
+ const aui = useAui({ tools: Tools({ toolkit }) });
454
+
455
+ return (
456
+ <AssistantRuntimeProvider aui={aui} runtime={runtime}>
457
+ <View style={{ flex: 1 }}>
458
+ <Thread />
459
+ </View>
460
+ </AssistantRuntimeProvider>
461
+ );
462
+ }
418
463
  ```
419
464
 
420
465
  </Tab>
421
466
  <Tab value="React Ink">
422
467
 
423
468
  ```tsx
469
+ import {
470
+ AssistantRuntimeProvider,
471
+ defineToolkit,
472
+ Tools,
473
+ useAui,
474
+ } from "@assistant-ui/react-ink";
475
+ import {
476
+ createAdkStream,
477
+ useAdkRuntime,
478
+ } from "@assistant-ui/react-google-adk";
424
479
  import { Box } from "ink";
425
480
  import { Thread } from "./components/thread.js";
426
481
 
427
- <AssistantRuntimeProvider runtime={runtime}>
428
- <RequestInputToolUI />
429
- <Box flexDirection="column">
430
- <Thread />
431
- </Box>
432
- </AssistantRuntimeProvider>;
482
+ const toolkit = defineToolkit({
483
+ adk_request_input: {
484
+ type: "backend",
485
+ render: RequestInputToolUI,
486
+ },
487
+ });
488
+
489
+ function App() {
490
+ const runtime = useAdkRuntime({
491
+ stream: createAdkStream({ api: "http://localhost:3000/api/chat" }),
492
+ });
493
+ const aui = useAui({ tools: Tools({ toolkit }) });
494
+
495
+ return (
496
+ <AssistantRuntimeProvider aui={aui} runtime={runtime}>
497
+ <Box flexDirection="column">
498
+ <Thread />
499
+ </Box>
500
+ </AssistantRuntimeProvider>
501
+ );
502
+ }
433
503
  ```
434
504
 
435
505
  </Tab>
@@ -1,9 +1,9 @@
1
1
  ---
2
- title: Generative UI
2
+ title: LangGraph Generative UI
3
3
  description: Render structured UI components emitted by LangGraph alongside assistant messages.
4
4
  ---
5
5
 
6
- LangGraph's [Generative UI](https://docs.langchain.com/langsmith/generative-ui-react) lets your graph emit structured UI components alongside assistant messages via `push_ui_message` (Python) or `typedUi().push()` (TypeScript). The assistant-ui adapter translates these into [`DataMessagePart`s](/docs/guides/tool-ui) on the associated assistant message, which you render with the existing `makeAssistantDataUI` API.
6
+ LangGraph's [Generative UI](https://docs.langchain.com/langsmith/generative-ui-react) lets your graph emit structured UI components alongside assistant messages via `push_ui_message` (Python) or `typedUi().push()` (TypeScript). The assistant-ui adapter translates these into [`DataMessagePart`s](/docs/tools/tool-ui) on the associated assistant message, which you render with the existing `makeAssistantDataUI` API.
7
7
 
8
8
  ## Enable the `custom` stream mode
9
9
 
@@ -102,10 +102,23 @@ function MyComponent() {
102
102
 
103
103
  ## Generative UI
104
104
 
105
- LangGraph can emit structured UI components alongside assistant messages via `push_ui_message` (Python) or `typedUi().push()` (TypeScript). The assistant-ui adapter translates these into [`DataMessagePart`s](/docs/guides/tool-ui) on the associated assistant message, which you render with the existing `makeAssistantDataUI` API.
105
+ LangGraph can emit structured UI components alongside assistant messages via `push_ui_message` (Python) or `typedUi().push()` (TypeScript). The assistant-ui adapter translates these into [`DataMessagePart`s](/docs/tools/tool-ui) on the associated assistant message, which you render with the existing `makeAssistantDataUI` API.
106
106
 
107
107
  See [Generative UI](/docs/runtimes/langgraph/generative-ui) for full setup: enabling the `custom` stream channel, emitting UI messages, registering renderers, dynamic loading, and persisting UI state across thread switches.
108
108
 
109
+ ## Queueing messages during a run
110
+
111
+ Set `unstable_enableMessageQueue` to keep the composer usable while a run is streaming. A message sent during a run is held in `composer.queue` and sent once the run settles; steering a queued message runs it next.
112
+
113
+ ```tsx
114
+ const runtime = useLangGraphRuntime({
115
+ stream,
116
+ unstable_enableMessageQueue: true,
117
+ });
118
+ ```
119
+
120
+ Render the pending messages with [`ComposerPrimitive.Queue`](/docs/api-reference/primitives/composer) and [`QueueItemPrimitive`](/docs/api-reference/primitives/queue-item).
121
+
109
122
  ## Next
110
123
 
111
124
  <Cards>
@@ -64,43 +64,52 @@ type PriceSnapshotToolResult = {
64
64
  };
65
65
  ```
66
66
 
67
- Then, we use `makeAssistantToolUI` to define the tool UI:
67
+ Then, we define a tool UI renderer:
68
68
 
69
69
  ```tsx title="@/components/tools/price-snapshot/PriceSnapshotTool.tsx"
70
70
  "use client";
71
71
 
72
- import { makeAssistantToolUI } from "@assistant-ui/react";
72
+ import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
73
73
 
74
- export const PriceSnapshotTool = makeAssistantToolUI<
74
+ export const PriceSnapshotToolUI: ToolCallMessagePartComponent<
75
75
  PriceSnapshotToolArgs,
76
76
  string
77
- >({
78
- toolName: "price_snapshot",
79
- render: function PriceSnapshotUI({ args, result }) {
80
- return (
81
- <div className="mb-4 flex flex-col items-center">
82
- <pre className="whitespace-pre-wrap break-all text-center">
83
- price_snapshot({JSON.stringify(args)})
84
- </pre>
85
- </div>
86
- );
87
- },
88
- });
77
+ > = function PriceSnapshotUI({ args, result }) {
78
+ return (
79
+ <div className="mb-4 flex flex-col items-center">
80
+ <pre className="whitespace-pre-wrap break-all text-center">
81
+ price_snapshot({JSON.stringify(args)})
82
+ </pre>
83
+ </div>
84
+ );
85
+ };
89
86
  ```
90
87
 
91
88
  This simply displays the tool name and arguments passed to it, but not the result.
92
89
 
93
90
  ### Bind tool UI
94
91
 
95
- ```tsx title="@/app/page.tsx" {1,8}
96
- import { PriceSnapshotTool } from "@/components/tools/price-snapshot/PriceSnapshotTool";
92
+ ```tsx title="@/app/page.tsx" {1-3,10}
93
+ "use client";
94
+
95
+ import { Thread } from "@/components/assistant-ui/thread";
96
+ import { PriceSnapshotToolUI } from "@/components/tools/price-snapshot/PriceSnapshotTool";
97
+ import { AuiProvider, defineToolkit, Tools, useAui } from "@assistant-ui/react";
98
+
99
+ const toolkit = defineToolkit({
100
+ price_snapshot: {
101
+ type: "backend",
102
+ render: PriceSnapshotToolUI,
103
+ },
104
+ });
97
105
 
98
106
  export default function Home() {
107
+ const aui = useAui({ tools: Tools({ toolkit }) });
108
+
99
109
  return (
100
- <div className="flex h-full flex-col">
101
- <PriceSnapshotTool />
110
+ <AuiProvider value={aui}>
102
111
  <Thread />
103
- </div>
112
+ </AuiProvider>
104
113
  );
105
114
  }
106
115
  ```
@@ -201,7 +210,7 @@ We will import the new `<PriceSnapshot />` component and use it in the `render`
201
210
  "use client";
202
211
 
203
212
  import { PriceSnapshot } from "./price-snapshot";
204
- import { makeAssistantToolUI } from "@assistant-ui/react";
213
+ import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
205
214
 
206
215
  type PriceSnapshotToolArgs = {
207
216
  ticker: string;
@@ -216,34 +225,31 @@ type PriceSnapshotToolResult = {
216
225
  };
217
226
  };
218
227
 
219
- export const PriceSnapshotTool = makeAssistantToolUI<
228
+ export const PriceSnapshotToolUI: ToolCallMessagePartComponent<
220
229
  PriceSnapshotToolArgs,
221
230
  string
222
- >({
223
- toolName: "price_snapshot",
224
- render: function PriceSnapshotUI({ args, result }) {
225
- let resultObj: PriceSnapshotToolResult | { error: string };
226
- try {
227
- resultObj = result ? JSON.parse(result) : {};
228
- } catch (e) {
229
- resultObj = { error: result! };
230
- }
231
-
232
- return (
233
- <div className="mb-4 flex flex-col items-center gap-2">
234
- <pre className="whitespace-pre-wrap break-all text-center">
235
- price_snapshot({JSON.stringify(args)})
236
- </pre>
237
- {"snapshot" in resultObj && (
238
- <PriceSnapshot ticker={args.ticker} {...resultObj.snapshot} />
239
- )}
240
- {"error" in resultObj && (
241
- <p className="text-red-500">{resultObj.error}</p>
242
- )}
243
- </div>
244
- );
245
- },
246
- });
231
+ > = function PriceSnapshotUI({ args, result }) {
232
+ let resultObj: PriceSnapshotToolResult | { error: string };
233
+ try {
234
+ resultObj = result ? JSON.parse(result) : {};
235
+ } catch (e) {
236
+ resultObj = { error: result! };
237
+ }
238
+
239
+ return (
240
+ <div className="mb-4 flex flex-col items-center gap-2">
241
+ <pre className="whitespace-pre-wrap break-all text-center">
242
+ price_snapshot({JSON.stringify(args)})
243
+ </pre>
244
+ {"snapshot" in resultObj && (
245
+ <PriceSnapshot ticker={args.ticker} {...resultObj.snapshot} />
246
+ )}
247
+ {"error" in resultObj && (
248
+ <p className="text-red-500">{resultObj.error}</p>
249
+ )}
250
+ </div>
251
+ );
252
+ };
247
253
  ```
248
254
 
249
255
  ### Try it out!
@@ -320,12 +326,20 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
320
326
  ### Bind fallback UI
321
327
 
322
328
  ```tsx title="@/app/page.tsx"
329
+ const toolkit = defineToolkit({
330
+ price_snapshot: {
331
+ type: "backend",
332
+ render: PriceSnapshotToolUI,
333
+ },
334
+ });
335
+
323
336
  export default function Home() {
337
+ const aui = useAui({ tools: Tools({ toolkit }) });
338
+
324
339
  return (
325
- <div className="flex h-full flex-col">
326
- <PriceSnapshotTool />
340
+ <AuiProvider value={aui}>
327
341
  <Thread />
328
- </div>
342
+ </AuiProvider>
329
343
  );
330
344
  }
331
345
  ```