@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.
- package/.docs/organized/code-examples/waterfall.md +20 -22
- package/.docs/organized/code-examples/with-a2a.md +24 -24
- package/.docs/organized/code-examples/with-ag-ui.md +30 -25
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +11 -9
- package/.docs/organized/code-examples/with-artifacts.md +49 -37
- package/.docs/organized/code-examples/with-assistant-transport.md +63 -51
- package/.docs/organized/code-examples/with-browser-extension.md +22 -10
- package/.docs/organized/code-examples/with-chain-of-thought.md +406 -87
- package/.docs/organized/code-examples/with-cloud-standalone.md +25 -24
- package/.docs/organized/code-examples/with-cloud.md +11 -9
- package/.docs/organized/code-examples/with-custom-thread-list.md +14 -12
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +23 -21
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +14 -13
- package/.docs/organized/code-examples/with-expo.md +44 -29
- package/.docs/organized/code-examples/with-external-store.md +9 -7
- package/.docs/organized/code-examples/with-ffmpeg.md +322 -285
- package/.docs/organized/code-examples/with-generative-ui.md +1066 -256
- package/.docs/organized/code-examples/with-google-adk.md +10 -8
- package/.docs/organized/code-examples/with-heat-graph.md +13 -11
- package/.docs/organized/code-examples/with-image-generation.md +19 -17
- package/.docs/organized/code-examples/with-interactables.md +317 -239
- package/.docs/organized/code-examples/with-langchain.md +14 -12
- package/.docs/organized/code-examples/with-langgraph.md +91 -83
- package/.docs/organized/code-examples/with-livekit.md +24 -22
- package/.docs/organized/code-examples/with-mcp.md +18 -12
- package/.docs/organized/code-examples/with-opencode.md +66 -66
- package/.docs/organized/code-examples/with-react-hook-form.md +19 -17
- package/.docs/organized/code-examples/with-react-ink.md +297 -102
- package/.docs/organized/code-examples/with-react-router.md +17 -15
- package/.docs/organized/code-examples/with-resumable-stream.md +15 -14
- package/.docs/organized/code-examples/with-store.md +78 -76
- package/.docs/organized/code-examples/with-tanstack.md +13 -14
- package/.docs/organized/code-examples/with-tap-runtime.md +26 -24
- package/.docs/raw/docs/(docs)/architecture.mdx +94 -42
- package/.docs/raw/docs/(docs)/cli.mdx +1 -2
- package/.docs/raw/docs/(docs)/installation.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +5 -1
- package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +15 -15
- package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +14 -1
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +18 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +33 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/spec.mdx +45 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +41 -41
- package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +19 -1
- package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +122 -122
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +43 -2
- package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +6 -0
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +4 -6
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +30 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +20 -3
- package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +8 -8
- package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +52 -4
- package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +100 -10
- package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +7 -59
- package/.docs/raw/docs/cloud/ai-sdk.mdx +0 -2
- package/.docs/raw/docs/{(docs)/copilots → copilots}/model-context.mdx +34 -26
- package/.docs/raw/docs/{(docs)/copilots → copilots}/motivation.mdx +32 -26
- package/.docs/raw/docs/guides/chain-of-thought.mdx +7 -9
- package/.docs/raw/docs/guides/context-api.mdx +2 -1
- package/.docs/raw/docs/guides/index.mdx +3 -12
- package/.docs/raw/docs/guides/mentions.mdx +4 -4
- package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
- package/.docs/raw/docs/guides/suggestions.mdx +1 -1
- package/.docs/raw/docs/ink/adapters.mdx +23 -1
- package/.docs/raw/docs/ink/hooks.mdx +101 -85
- package/.docs/raw/docs/ink/migration.mdx +1 -1
- package/.docs/raw/docs/ink/primitives.mdx +2 -2
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +1 -1
- package/.docs/raw/docs/integrations/index.mdx +2 -2
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +17 -2
- package/.docs/raw/docs/migrations/toolkit-tools.mdx +232 -0
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +10 -16
- package/.docs/raw/docs/primitives/message.mdx +9 -10
- package/.docs/raw/docs/react-native/hooks.mdx +62 -79
- package/.docs/raw/docs/react-native/migration.mdx +1 -1
- package/.docs/raw/docs/react-native/primitives.mdx +2 -2
- package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +3 -0
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +41 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +122 -1
- package/.docs/raw/docs/runtimes/concepts/architecture.mdx +46 -4
- package/.docs/raw/docs/runtimes/concepts/threads.mdx +7 -1
- package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +54 -12
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +62 -4
- package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +30 -7
- package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +108 -38
- package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +2 -2
- package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +14 -1
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +64 -50
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +98 -86
- package/.docs/raw/docs/tools/backend.mdx +144 -0
- package/.docs/raw/docs/tools/defining-tools.mdx +538 -0
- package/.docs/raw/docs/tools/dynamic-tools.mdx +110 -0
- package/.docs/raw/docs/tools/generative-ui.mdx +214 -0
- package/.docs/raw/docs/tools/index.mdx +71 -0
- package/.docs/raw/docs/{guides → tools}/interactables.mdx +1 -1
- package/.docs/raw/docs/{integrations/tools → tools}/mcp.mdx +145 -50
- package/.docs/raw/docs/{guides → tools}/multi-agent.mdx +15 -17
- package/.docs/raw/docs/tools/tool-ui.mdx +967 -0
- package/.docs/raw/docs/{integrations/tools/react-mcp.mdx → tools/user-managed-mcp.mdx} +7 -7
- package/.docs/raw/docs/ui/directive-text.mdx +3 -3
- package/.docs/raw/docs/ui/mcp-config.mdx +4 -4
- package/.docs/raw/docs/ui/mermaid.mdx +16 -9
- package/.docs/raw/docs/ui/part-grouping.mdx +84 -50
- package/.docs/raw/docs/ui/reasoning.mdx +4 -5
- package/.docs/raw/docs/ui/tool-fallback.mdx +16 -0
- package/.docs/raw/docs/ui/tool-group.mdx +5 -6
- package/.docs/raw/docs/utilities/heat-graph.mdx +1 -1
- package/.docs/raw/docs/utilities/react-o11y.mdx +2 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/prepare-docs/code-examples.d.ts.map +1 -1
- package/dist/prepare-docs/code-examples.js.map +1 -1
- package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
- package/dist/prepare-docs/copy-raw.js.map +1 -1
- package/dist/prepare-docs/prepare.js.map +1 -1
- package/dist/stdio.js.map +1 -1
- package/dist/tools/docs.js.map +1 -1
- package/dist/tools/examples.js.map +1 -1
- package/dist/tools/tests/test-setup.js.map +1 -1
- package/dist/utils/mdx.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js.map +1 -1
- package/package.json +5 -5
- package/.docs/organized/code-examples/with-parent-id-grouping.md +0 -596
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +0 -151
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +0 -230
- package/.docs/raw/docs/guides/generative-ui.mdx +0 -142
- package/.docs/raw/docs/guides/tool-ui.mdx +0 -858
- package/.docs/raw/docs/guides/tools.mdx +0 -736
- /package/.docs/raw/docs/{(docs)/copilots → copilots}/assistant-frame.mdx +0 -0
- /package/.docs/raw/docs/{(docs)/copilots → copilots}/make-assistant-visible.mdx +0 -0
- /package/.docs/raw/docs/{(docs)/copilots → copilots}/use-assistant-instructions.mdx +0 -0
- /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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 }) =>
|
|
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
|
|
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/
|
|
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 {
|
|
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
|
|
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 {
|
|
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
|
|
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 {
|
|
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
|
|
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
|
|
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
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
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
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
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
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
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/
|
|
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/
|
|
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
|
|
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 {
|
|
72
|
+
import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
|
|
73
73
|
|
|
74
|
-
export const
|
|
74
|
+
export const PriceSnapshotToolUI: ToolCallMessagePartComponent<
|
|
75
75
|
PriceSnapshotToolArgs,
|
|
76
76
|
string
|
|
77
|
-
>({
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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,
|
|
96
|
-
|
|
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
|
-
<
|
|
101
|
-
<PriceSnapshotTool />
|
|
110
|
+
<AuiProvider value={aui}>
|
|
102
111
|
<Thread />
|
|
103
|
-
</
|
|
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 {
|
|
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
|
|
228
|
+
export const PriceSnapshotToolUI: ToolCallMessagePartComponent<
|
|
220
229
|
PriceSnapshotToolArgs,
|
|
221
230
|
string
|
|
222
|
-
>({
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
-
<
|
|
326
|
-
<PriceSnapshotTool />
|
|
340
|
+
<AuiProvider value={aui}>
|
|
327
341
|
<Thread />
|
|
328
|
-
</
|
|
342
|
+
</AuiProvider>
|
|
329
343
|
);
|
|
330
344
|
}
|
|
331
345
|
```
|