@assistant-ui/mcp-docs-server 0.1.31 → 0.1.33
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 +23 -25
- package/.docs/organized/code-examples/with-a2a.md +28 -28
- package/.docs/organized/code-examples/with-ag-ui.md +35 -30
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +16 -14
- package/.docs/organized/code-examples/with-artifacts.md +44 -38
- package/.docs/organized/code-examples/with-assistant-transport.md +68 -56
- package/.docs/organized/code-examples/with-browser-extension.md +357 -0
- package/.docs/organized/code-examples/with-chain-of-thought.md +425 -90
- package/.docs/organized/code-examples/with-cloud-standalone.md +30 -29
- package/.docs/organized/code-examples/with-cloud.md +16 -14
- package/.docs/organized/code-examples/with-custom-thread-list.md +19 -17
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +29 -26
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +20 -18
- package/.docs/organized/code-examples/with-expo.md +37 -31
- package/.docs/organized/code-examples/with-external-store.md +13 -11
- package/.docs/organized/code-examples/with-ffmpeg.md +327 -290
- package/.docs/organized/code-examples/with-generative-ui.md +1195 -194
- package/.docs/organized/code-examples/with-google-adk.md +13 -11
- package/.docs/organized/code-examples/with-heat-graph.md +16 -14
- package/.docs/organized/code-examples/with-image-generation.md +456 -0
- package/.docs/organized/code-examples/with-interactables.md +322 -244
- package/.docs/organized/code-examples/with-langchain.md +18 -16
- package/.docs/organized/code-examples/with-langgraph.md +95 -88
- package/.docs/organized/code-examples/with-livekit.md +30 -27
- package/.docs/organized/code-examples/with-mcp.md +754 -0
- package/.docs/organized/code-examples/with-opencode.md +70 -70
- package/.docs/organized/code-examples/with-react-hook-form.md +24 -22
- package/.docs/organized/code-examples/with-react-ink.md +4 -4
- package/.docs/organized/code-examples/with-react-router.md +20 -18
- package/.docs/organized/code-examples/with-resumable-stream.md +661 -0
- package/.docs/organized/code-examples/with-store.md +22 -20
- package/.docs/organized/code-examples/with-tanstack.md +18 -19
- package/.docs/organized/code-examples/with-tap-runtime.md +31 -28
- package/.docs/raw/docs/(docs)/architecture.mdx +43 -2
- package/.docs/raw/docs/(docs)/cli.mdx +2 -2
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +34 -26
- package/.docs/raw/docs/(docs)/copilots/motivation.mdx +32 -26
- package/.docs/raw/docs/(docs)/index.mdx +2 -2
- package/.docs/raw/docs/(docs)/installation.mdx +2 -2
- package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +26 -24
- package/.docs/raw/docs/(reference)/api-reference/adapters/feedback.mdx +20 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +20 -12
- package/.docs/raw/docs/(reference)/api-reference/adapters/model.mdx +44 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +41 -16
- package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +12 -23
- package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +20 -0
- package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +37 -8
- package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +11 -9
- package/.docs/raw/docs/(reference)/api-reference/context-providers/scoped-providers.mdx +64 -0
- package/.docs/raw/docs/(reference)/api-reference/external-store/index.mdx +22 -0
- package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +52 -0
- package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +46 -0
- 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 +98 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +18 -13
- package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +31 -52
- package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +640 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +15 -28
- package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +64 -18
- package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +434 -0
- package/.docs/raw/docs/(reference)/api-reference/integrations/cloud-ai-sdk.mdx +24 -0
- package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +11 -12
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +109 -0
- package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +58 -0
- package/.docs/raw/docs/(reference)/api-reference/model-context/index.mdx +22 -0
- package/.docs/raw/docs/(reference)/api-reference/model-context/registry.mdx +20 -0
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +109 -132
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +78 -221
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +127 -242
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +39 -20
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +66 -87
- package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +50 -58
- package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +80 -48
- package/.docs/raw/docs/(reference)/api-reference/primitives/chain-of-thought.mdx +67 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +323 -461
- package/.docs/raw/docs/(reference)/api-reference/primitives/error.mdx +36 -43
- package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +29 -24
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +63 -245
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +202 -588
- package/.docs/raw/docs/(reference)/api-reference/primitives/queue-item.mdx +65 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +35 -22
- package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +57 -140
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item-more.mdx +70 -161
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +84 -108
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +77 -96
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +173 -349
- package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +9 -21
- package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +10 -21
- package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +15 -70
- package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +18 -13
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +25 -28
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +11 -63
- package/.docs/raw/docs/(reference)/api-reference/runtimes/queue-state.mdx +20 -0
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +11 -48
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +10 -47
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +18 -30
- package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +85 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +39 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +127 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +42 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +91 -0
- package/.docs/raw/docs/(reference)/api-reference/transport/assistant-transport.mdx +48 -0
- package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +62 -0
- package/.docs/raw/docs/(reference)/api-reference/transport/index.mdx +22 -0
- package/.docs/raw/docs/(reference)/api-reference/utilities/index.mdx +19 -0
- package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +143 -0
- package/.docs/raw/docs/(reference)/api-reference/voice/index.mdx +22 -0
- package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +54 -0
- package/.docs/raw/docs/(reference)/api-reference/voice/speech-dictation.mdx +36 -0
- package/.docs/raw/docs/cloud/ai-sdk.mdx +1 -3
- package/.docs/raw/docs/cloud/index.mdx +2 -2
- package/.docs/raw/docs/guides/attachments.mdx +4 -4
- package/.docs/raw/docs/guides/branching.mdx +1 -1
- package/.docs/raw/docs/guides/chain-of-thought.mdx +12 -14
- package/.docs/raw/docs/guides/context-api.mdx +6 -5
- package/.docs/raw/docs/guides/dictation.mdx +2 -2
- package/.docs/raw/docs/guides/editing.mdx +1 -1
- package/.docs/raw/docs/guides/image-generation.mdx +74 -0
- package/.docs/raw/docs/guides/index.mdx +5 -14
- package/.docs/raw/docs/guides/latex.mdx +2 -2
- package/.docs/raw/docs/guides/mentions.mdx +6 -6
- package/.docs/raw/docs/guides/message-timing.mdx +38 -5
- package/.docs/raw/docs/guides/quoting.mdx +1 -1
- package/.docs/raw/docs/guides/resumable-stream-deployment.mdx +212 -0
- package/.docs/raw/docs/guides/resumable-stream-stores.mdx +152 -0
- package/.docs/raw/docs/guides/resumable-streams.mdx +210 -0
- package/.docs/raw/docs/guides/slash-commands.mdx +2 -2
- package/.docs/raw/docs/guides/speech.mdx +2 -2
- package/.docs/raw/docs/guides/suggestions.mdx +89 -5
- package/.docs/raw/docs/guides/voice.mdx +2 -2
- package/.docs/raw/docs/ink/adapters.mdx +37 -1
- package/.docs/raw/docs/ink/custom-backend.mdx +59 -8
- package/.docs/raw/docs/ink/hooks.mdx +98 -85
- package/.docs/raw/docs/ink/index.mdx +10 -11
- package/.docs/raw/docs/ink/migration.mdx +1 -1
- package/.docs/raw/docs/ink/primitives.mdx +350 -9
- package/.docs/raw/docs/integrations/auth/better-auth.mdx +1 -1
- package/.docs/raw/docs/integrations/auth/clerk.mdx +1 -1
- package/.docs/raw/docs/integrations/auth/next-auth.mdx +1 -1
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +3 -3
- package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +282 -0
- package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +2 -2
- package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
- package/.docs/raw/docs/integrations/gateways/index.mdx +9 -4
- package/.docs/raw/docs/integrations/index.mdx +17 -5
- package/.docs/raw/docs/integrations/observability/langfuse.mdx +8 -1
- package/.docs/raw/docs/integrations/observability/langsmith.mdx +8 -4
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +17 -2
- package/.docs/raw/docs/migrations/toolkit-tools.mdx +226 -0
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +10 -16
- package/.docs/raw/docs/primitives/composer.mdx +53 -0
- package/.docs/raw/docs/primitives/index.mdx +2 -2
- package/.docs/raw/docs/primitives/message.mdx +9 -10
- package/.docs/raw/docs/primitives/suggestion.mdx +9 -0
- package/.docs/raw/docs/react-native/hooks.mdx +57 -82
- package/.docs/raw/docs/react-native/index.mdx +4 -4
- 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 +7 -4
- package/.docs/raw/docs/runtimes/a2a/overview.mdx +2 -2
- package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +2 -2
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +32 -1
- package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +2 -2
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +7 -2
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +1 -1
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +129 -1
- package/.docs/raw/docs/runtimes/concepts/threads.mdx +7 -1
- package/.docs/raw/docs/runtimes/custom/data-stream.mdx +27 -2
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +9 -1
- package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +18 -7
- package/.docs/raw/docs/runtimes/custom/overview.mdx +2 -2
- package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +108 -38
- package/.docs/raw/docs/runtimes/google-adk/overview.mdx +2 -2
- package/.docs/raw/docs/runtimes/langchain.mdx +2 -2
- package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +2 -2
- package/.docs/raw/docs/runtimes/langgraph/overview.mdx +2 -2
- package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +1 -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/runtimes/opencode/overview.mdx +2 -2
- package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +12 -5
- package/.docs/raw/docs/tools/backend.mdx +136 -0
- package/.docs/raw/docs/tools/defining-tools.mdx +413 -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 +76 -0
- package/.docs/raw/docs/{guides → tools}/interactables.mdx +3 -3
- package/.docs/raw/docs/tools/mcp-apps.mdx +231 -0
- package/.docs/raw/docs/{integrations/tools → tools}/mcp.mdx +77 -50
- package/.docs/raw/docs/{guides → tools}/multi-agent.mdx +19 -21
- package/.docs/raw/docs/tools/tool-ui.mdx +967 -0
- package/.docs/raw/docs/tools/user-managed-mcp.mdx +337 -0
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +11 -1
- package/.docs/raw/docs/ui/directive-text.mdx +3 -3
- package/.docs/raw/docs/ui/mcp-config.mdx +102 -0
- package/.docs/raw/docs/ui/model-selector.mdx +8 -8
- package/.docs/raw/docs/ui/part-grouping.mdx +84 -50
- package/.docs/raw/docs/ui/reasoning.mdx +4 -5
- package/.docs/raw/docs/ui/sources.mdx +17 -0
- package/.docs/raw/docs/ui/streamdown.mdx +34 -2
- package/.docs/raw/docs/ui/thread-list.mdx +2 -2
- package/.docs/raw/docs/ui/thread.mdx +2 -2
- package/.docs/raw/docs/ui/tool-group.mdx +5 -6
- package/.docs/raw/docs/utilities/heat-graph.mdx +1 -1
- package/README.md +14 -72
- package/dist/constants.d.ts +12 -9
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +13 -9
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -24
- package/dist/index.js.map +1 -1
- package/dist/prepare-docs/code-examples.d.ts +4 -1
- package/dist/prepare-docs/code-examples.d.ts.map +1 -1
- package/dist/prepare-docs/code-examples.js +109 -121
- package/dist/prepare-docs/code-examples.js.map +1 -1
- package/dist/prepare-docs/copy-raw.d.ts +4 -1
- package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
- package/dist/prepare-docs/copy-raw.js +45 -42
- package/dist/prepare-docs/copy-raw.js.map +1 -1
- package/dist/prepare-docs/prepare.d.ts +1 -2
- package/dist/prepare-docs/prepare.js +17 -17
- package/dist/prepare-docs/prepare.js.map +1 -1
- package/dist/stdio.d.ts +1 -3
- package/dist/stdio.js +6 -3
- package/dist/stdio.js.map +1 -1
- package/dist/tools/docs.d.ts +20 -15
- package/dist/tools/docs.d.ts.map +1 -1
- package/dist/tools/docs.js +140 -161
- package/dist/tools/docs.js.map +1 -1
- package/dist/tools/examples.d.ts +20 -15
- package/dist/tools/examples.d.ts.map +1 -1
- package/dist/tools/examples.js +74 -86
- package/dist/tools/examples.js.map +1 -1
- package/dist/tools/tests/test-setup.d.ts +5 -2
- package/dist/tools/tests/test-setup.d.ts.map +1 -1
- package/dist/tools/tests/test-setup.js +21 -28
- package/dist/tools/tests/test-setup.js.map +1 -1
- package/dist/utils/logger.d.ts +8 -5
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +17 -17
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/mcp-format.d.ts +8 -5
- package/dist/utils/mcp-format.d.ts.map +1 -1
- package/dist/utils/mcp-format.js +9 -9
- package/dist/utils/mcp-format.js.map +1 -1
- package/dist/utils/mdx.d.ts +8 -6
- package/dist/utils/mdx.d.ts.map +1 -1
- package/dist/utils/mdx.js +22 -22
- package/dist/utils/mdx.js.map +1 -1
- package/dist/utils/paths.d.ts +9 -6
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +66 -76
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/security.d.ts +4 -1
- package/dist/utils/security.d.ts.map +1 -1
- package/dist/utils/security.js +19 -40
- package/dist/utils/security.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/(reference)/api-reference/adapters/feedback-speech.mdx +0 -41
- package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +0 -40
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +0 -260
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +0 -103
- package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +0 -254
- package/.docs/raw/docs/guides/tool-ui.mdx +0 -858
- package/.docs/raw/docs/guides/tools.mdx +0 -675
- package/dist/prepare-docs/prepare.d.ts.map +0 -1
- package/dist/stdio.d.ts.map +0 -1
- /package/.docs/raw/docs/{(reference)/migrations → migrations}/deprecation-policy.mdx +0 -0
- /package/.docs/raw/docs/{(reference) → migrations}/react-compatibility.mdx +0 -0
- /package/.docs/raw/docs/{(reference)/migrations → migrations}/react-langgraph-v0-7.mdx +0 -0
- /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-11.mdx +0 -0
- /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-12.mdx +0 -0
- /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-14.mdx +0 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Migrating Tools to Toolkits
|
|
3
|
+
description: Move makeAssistantTool, useAssistantTool, makeAssistantToolUI, and useAssistantToolUI registrations to the toolkit API.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The component and hook based tool APIs are deprecated:
|
|
7
|
+
|
|
8
|
+
- `makeAssistantTool`
|
|
9
|
+
- `useAssistantTool`
|
|
10
|
+
- `makeAssistantToolUI`
|
|
11
|
+
- `useAssistantToolUI`
|
|
12
|
+
|
|
13
|
+
Use a toolkit registered with `Tools({ toolkit })` instead. Toolkits keep the model contract, browser execution, and tool-call rendering in one named map, which avoids duplicate registrations and makes the client/backend split explicit.
|
|
14
|
+
|
|
15
|
+
## Before
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { AssistantRuntimeProvider, makeAssistantTool } from "@assistant-ui/react";
|
|
19
|
+
import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
|
|
22
|
+
const WeatherTool = makeAssistantTool({
|
|
23
|
+
toolName: "get_weather",
|
|
24
|
+
description: "Get the current weather for a city.",
|
|
25
|
+
parameters: z.object({
|
|
26
|
+
city: z.string(),
|
|
27
|
+
}),
|
|
28
|
+
execute: async ({ city }) => fetchWeather(city),
|
|
29
|
+
render: ({ args, result }) => (
|
|
30
|
+
<WeatherCard city={args.city} weather={result} />
|
|
31
|
+
),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export function App() {
|
|
35
|
+
const runtime = useChatRuntime({ api: "/api/chat" });
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
39
|
+
<WeatherTool />
|
|
40
|
+
<Thread />
|
|
41
|
+
</AssistantRuntimeProvider>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## After
|
|
47
|
+
|
|
48
|
+
```tsx title="app/toolkit.tsx"
|
|
49
|
+
"use generative";
|
|
50
|
+
|
|
51
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
52
|
+
import { z } from "zod";
|
|
53
|
+
|
|
54
|
+
export default defineToolkit({
|
|
55
|
+
get_weather: {
|
|
56
|
+
description: "Get the current weather for a city.",
|
|
57
|
+
parameters: z.object({
|
|
58
|
+
city: z.string(),
|
|
59
|
+
}),
|
|
60
|
+
execute: async ({ city }) => {
|
|
61
|
+
"use client";
|
|
62
|
+
return fetchWeather(city);
|
|
63
|
+
},
|
|
64
|
+
render: ({ args, result }) => (
|
|
65
|
+
<WeatherCard city={args.city} weather={result} />
|
|
66
|
+
),
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```tsx title="app/MyRuntimeProvider.tsx"
|
|
72
|
+
"use client";
|
|
73
|
+
|
|
74
|
+
import {
|
|
75
|
+
AssistantRuntimeProvider,
|
|
76
|
+
Tools,
|
|
77
|
+
useAui,
|
|
78
|
+
} from "@assistant-ui/react";
|
|
79
|
+
import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
|
|
80
|
+
import toolkit from "./toolkit";
|
|
81
|
+
|
|
82
|
+
export function App() {
|
|
83
|
+
const runtime = useChatRuntime({ api: "/api/chat" });
|
|
84
|
+
const aui = useAui({
|
|
85
|
+
tools: Tools({ toolkit }),
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<AssistantRuntimeProvider aui={aui} runtime={runtime}>
|
|
90
|
+
<Thread />
|
|
91
|
+
</AssistantRuntimeProvider>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Mechanical Steps
|
|
97
|
+
|
|
98
|
+
1. Create a `Toolkit` object.
|
|
99
|
+
2. Move each `toolName` into the toolkit key.
|
|
100
|
+
3. Move `description`, `parameters`, `execute`, `providerOptions`, `render`, `renderText`, and `display` onto the toolkit entry.
|
|
101
|
+
4. Register the toolkit once with `useAui({ tools: Tools({ toolkit }) })`.
|
|
102
|
+
5. Remove `<Tool />`, `<ToolUI />`, `useAssistantTool(...)`, and `useAssistantToolUI(...)` registrations.
|
|
103
|
+
|
|
104
|
+
## UI-Only Tool Renderers
|
|
105
|
+
|
|
106
|
+
If you used `makeAssistantToolUI` or `useAssistantToolUI` for a backend, MCP, or LangGraph tool, the tool executes elsewhere, so there is no `execute` to author. That makes it a **render-only** entry, which belongs in a plain `satisfies Toolkit` object — not a `"use generative"` file (a generative tool must declare an `execute`). Author an explicit `type: "backend"` with just a `render`:
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
// app/tool-ui.tsx
|
|
110
|
+
"use client";
|
|
111
|
+
|
|
112
|
+
import type { Toolkit } from "@assistant-ui/react";
|
|
113
|
+
|
|
114
|
+
export const toolkit = {
|
|
115
|
+
web_search: {
|
|
116
|
+
type: "backend",
|
|
117
|
+
render: ({ args, result }) => (
|
|
118
|
+
<SearchResults query={args.query} results={result?.results ?? []} />
|
|
119
|
+
),
|
|
120
|
+
},
|
|
121
|
+
} satisfies Toolkit;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Register it like any toolkit: `useAui({ tools: Tools({ toolkit }) })`. Render-only entries upload no schema and run no browser code — they only attach UI for matching tool-call message parts.
|
|
125
|
+
|
|
126
|
+
For a one-off renderer that should only affect a particular message surface, use `MessagePrimitive.Parts` inline tool render overrides instead of a global registration.
|
|
127
|
+
|
|
128
|
+
## Dynamic Tools
|
|
129
|
+
|
|
130
|
+
If a tool needs component state or props, keep the toolkit contract in a `"use generative"` file and use `stubTool()` for the executor. The component that owns the state supplies the real executor with `useAuiToolOverrides(...)`:
|
|
131
|
+
|
|
132
|
+
<Callout type="warn">
|
|
133
|
+
`useAuiToolOverrides` is experimental and its API may change.
|
|
134
|
+
</Callout>
|
|
135
|
+
|
|
136
|
+
```tsx title="task-board-toolkit.tsx"
|
|
137
|
+
"use generative";
|
|
138
|
+
|
|
139
|
+
import { defineToolkit, stubTool } from "@assistant-ui/react";
|
|
140
|
+
import { z } from "zod";
|
|
141
|
+
|
|
142
|
+
export type Task = { id: string; title: string };
|
|
143
|
+
|
|
144
|
+
export default defineToolkit({
|
|
145
|
+
add_task: {
|
|
146
|
+
description: "Add a task to the board.",
|
|
147
|
+
parameters: z.object({ title: z.string() }),
|
|
148
|
+
execute: stubTool(),
|
|
149
|
+
renderText: {
|
|
150
|
+
running: "Adding task",
|
|
151
|
+
complete: "Task added",
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```tsx title="TaskBoard.tsx"
|
|
158
|
+
import { AuiProvider, Tools, useAui, useAuiToolOverrides } from "@assistant-ui/react";
|
|
159
|
+
import { useState, type Dispatch, type SetStateAction } from "react";
|
|
160
|
+
import type { Task } from "./task-board-toolkit";
|
|
161
|
+
import toolkit from "./task-board-toolkit";
|
|
162
|
+
|
|
163
|
+
function TaskBoard() {
|
|
164
|
+
const [tasks, setTasks] = useState<Task[]>([]);
|
|
165
|
+
|
|
166
|
+
const aui = useAui({
|
|
167
|
+
tools: Tools({ toolkit }),
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
return (
|
|
171
|
+
<AuiProvider value={aui}>
|
|
172
|
+
<TaskBoardToolOverrides setTasks={setTasks} />
|
|
173
|
+
<TaskList tasks={tasks} />
|
|
174
|
+
</AuiProvider>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function TaskBoardToolOverrides({
|
|
179
|
+
setTasks,
|
|
180
|
+
}: {
|
|
181
|
+
setTasks: Dispatch<SetStateAction<Task[]>>;
|
|
182
|
+
}) {
|
|
183
|
+
useAuiToolOverrides({
|
|
184
|
+
add_task: {
|
|
185
|
+
execute: async ({ title }) => {
|
|
186
|
+
setTasks((prev) => [
|
|
187
|
+
...prev,
|
|
188
|
+
{ id: crypto.randomUUID(), title },
|
|
189
|
+
]);
|
|
190
|
+
return { ok: true };
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
This keeps the model-facing contract in the toolkit file while the component owns the stateful executor.
|
|
199
|
+
|
|
200
|
+
## Generative Toolkits
|
|
201
|
+
|
|
202
|
+
For tools authored in a `"use generative"` file, export a toolkit with `defineToolkit(...)`. The compiler splits backend, frontend, and human tools for you. This is the default shape to use for docs and copy-paste examples:
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
"use generative";
|
|
206
|
+
|
|
207
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
208
|
+
import { z } from "zod";
|
|
209
|
+
|
|
210
|
+
export default defineToolkit({
|
|
211
|
+
create_chart: {
|
|
212
|
+
description: "Create a chart for the user.",
|
|
213
|
+
parameters: z.object({
|
|
214
|
+
title: z.string(),
|
|
215
|
+
values: z.array(z.number()),
|
|
216
|
+
}),
|
|
217
|
+
execute: async ({ title, values }) => {
|
|
218
|
+
"use client";
|
|
219
|
+
return renderChart(title, values);
|
|
220
|
+
},
|
|
221
|
+
render: ChartTool,
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Frontend and human tools produced by the generative compiler already have their schema defaults on the backend, so the client no longer re-uploads those schemas.
|
|
@@ -22,19 +22,16 @@ For new grouped reasoning/tool-call UI, use `MessagePrimitive.GroupedParts`. `Ch
|
|
|
22
22
|
</Tab>
|
|
23
23
|
<Tab>
|
|
24
24
|
```tsx
|
|
25
|
-
import { MessagePrimitive } from "@assistant-ui/react";
|
|
25
|
+
import { MessagePrimitive, groupPartByType } from "@assistant-ui/react";
|
|
26
26
|
|
|
27
27
|
function AssistantMessage() {
|
|
28
28
|
return (
|
|
29
29
|
<MessagePrimitive.Root>
|
|
30
30
|
<MessagePrimitive.GroupedParts
|
|
31
|
-
groupBy={(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return ["group-chainOfThought", "group-tool"];
|
|
36
|
-
return null;
|
|
37
|
-
}}
|
|
31
|
+
groupBy={groupPartByType({
|
|
32
|
+
reasoning: ["group-chainOfThought", "group-reasoning"],
|
|
33
|
+
"tool-call": ["group-chainOfThought", "group-tool"],
|
|
34
|
+
})}
|
|
38
35
|
>
|
|
39
36
|
{({ part, children }) => {
|
|
40
37
|
switch (part.type) {
|
|
@@ -67,17 +64,14 @@ function AssistantMessage() {
|
|
|
67
64
|
Group reasoning and tool-call parts directly in your assistant message:
|
|
68
65
|
|
|
69
66
|
```tsx
|
|
70
|
-
import { MessagePrimitive } from "@assistant-ui/react";
|
|
67
|
+
import { MessagePrimitive, groupPartByType } from "@assistant-ui/react";
|
|
71
68
|
|
|
72
69
|
<MessagePrimitive.Root>
|
|
73
70
|
<MessagePrimitive.GroupedParts
|
|
74
|
-
groupBy={(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return ["group-chainOfThought", "group-tool"];
|
|
79
|
-
return null;
|
|
80
|
-
}}
|
|
71
|
+
groupBy={groupPartByType({
|
|
72
|
+
reasoning: ["group-chainOfThought", "group-reasoning"],
|
|
73
|
+
"tool-call": ["group-chainOfThought", "group-tool"],
|
|
74
|
+
})}
|
|
81
75
|
>
|
|
82
76
|
{({ part, children }) => {
|
|
83
77
|
switch (part.type) {
|
|
@@ -526,6 +526,46 @@ Use `onSubmit` on `Root` to intercept submission:
|
|
|
526
526
|
</ComposerPrimitive.Root>
|
|
527
527
|
```
|
|
528
528
|
|
|
529
|
+
### Gate Sending on External State
|
|
530
|
+
|
|
531
|
+
Sometimes you want users to type while sending is temporarily blocked, for example while tool configuration, auth, or the first model context is still loading. Disabling the entire thread via `isDisabled` works but also disables the text input, which feels broken.
|
|
532
|
+
|
|
533
|
+
Use `isSendDisabled` on the runtime adapter to keep the input usable while blocking send:
|
|
534
|
+
|
|
535
|
+
```tsx
|
|
536
|
+
const runtime = useExternalStoreRuntime({
|
|
537
|
+
isSendDisabled: !toolsLoaded,
|
|
538
|
+
onNew,
|
|
539
|
+
messages,
|
|
540
|
+
// ...
|
|
541
|
+
});
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
When `isSendDisabled` is `true`:
|
|
545
|
+
|
|
546
|
+
- `composer.canSend` becomes `false`
|
|
547
|
+
- `<ComposerPrimitive.Send>` is disabled
|
|
548
|
+
- Enter and the `Cmd/Ctrl+Shift+Enter` steer hotkey become no-ops
|
|
549
|
+
- `aui.composer().send()` short-circuits at the runtime, so direct calls cannot escape the gate
|
|
550
|
+
|
|
551
|
+
Read the same flag from React with `<AuiIf>` to render hints alongside the input:
|
|
552
|
+
|
|
553
|
+
```tsx
|
|
554
|
+
<ComposerPrimitive.Root>
|
|
555
|
+
<ComposerPrimitive.Input placeholder="Ask anything..." />
|
|
556
|
+
<AuiIf condition={(s) => !s.composer.canSend}>
|
|
557
|
+
<p className="text-sm text-muted-foreground">Loading tools, hang on...</p>
|
|
558
|
+
</AuiIf>
|
|
559
|
+
<ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
|
|
560
|
+
</ComposerPrimitive.Root>
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
`canSend` reflects the composer's own willingness to send (editing mode, non-empty content, `isSendDisabled` not set). Cross-thread gating like an in-flight run without queue support is layered on top by `<ComposerPrimitive.Send>` automatically.
|
|
564
|
+
|
|
565
|
+
`isSendDisabled` only gates the thread composer. Saving an in-progress message edit is unaffected, since it is a per-message action rather than a new send.
|
|
566
|
+
|
|
567
|
+
For the difference between `isDisabled` and `isSendDisabled`, see the [external store adapter reference](/docs/runtimes/custom/external-store).
|
|
568
|
+
|
|
529
569
|
### Ctrl+Enter to Submit
|
|
530
570
|
|
|
531
571
|
```tsx
|
|
@@ -537,6 +577,19 @@ Use `onSubmit` on `Root` to intercept submission:
|
|
|
537
577
|
|
|
538
578
|
With `submitMode="ctrlEnter"`, plain Enter inserts a newline and Ctrl/Cmd+Enter submits.
|
|
539
579
|
|
|
580
|
+
### Mobile / touch devices
|
|
581
|
+
|
|
582
|
+
```tsx
|
|
583
|
+
<ComposerPrimitive.Root>
|
|
584
|
+
<ComposerPrimitive.Input unstable_insertNewlineOnTouchEnter />
|
|
585
|
+
<ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
|
|
586
|
+
</ComposerPrimitive.Root>
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
`unstable_insertNewlineOnTouchEnter` switches Enter to insert a newline on touch-primary devices (detected via `(pointer: coarse) and (not (any-pointer: fine))`), so the on-screen Return key never accidentally sends a half-finished message. Submission moves to the explicit Send button, matching WhatsApp, Slack, Discord, iMessage, ChatGPT, and Claude.ai.
|
|
590
|
+
|
|
591
|
+
Desktop behavior is unchanged. A tablet paired with a hardware keyboard still gets `submitMode`'s usual semantics if you set `submitMode="ctrlEnter"` or `"none"` — the flag only downgrades the default `"enter"` mode.
|
|
592
|
+
|
|
540
593
|
### Floating Composer
|
|
541
594
|
|
|
542
595
|
Primitives aren't bound to any layout. Here's how the floating composer on this docs site is built, using the same `ComposerPrimitive.Root` and `ComposerPrimitive.Input` positioned with CSS:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
3
|
-
description: Unstyled, accessible building blocks for AI chat interfaces.
|
|
2
|
+
title: Headless Chat Primitives
|
|
3
|
+
description: Unstyled, accessible Radix-style building blocks for React AI chat interfaces — Thread, Composer, Message, and more, ready to compose with assistant-ui.
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -117,7 +117,7 @@ For most new code, prefer `MessagePrimitive.Parts` with a `children` render func
|
|
|
117
117
|
Tool call parts resolve in this order:
|
|
118
118
|
|
|
119
119
|
1. **`tools.Override`**: if provided inline through the deprecated `components` prop, handles **all** tool calls
|
|
120
|
-
2. **Globally registered tools**: tools registered via `
|
|
120
|
+
2. **Globally registered tools**: tools registered via `Tools({ toolkit })`
|
|
121
121
|
3. **`tools.by_name[toolName]`**: per-`MessagePrimitive.Parts` inline overrides from the deprecated `components` prop
|
|
122
122
|
4. **`tools.Fallback`**: catch-all for unmatched tool calls from the deprecated `components` prop
|
|
123
123
|
5. **`part.toolUI`**: the resolved tool UI exposed directly in the children render function
|
|
@@ -250,17 +250,16 @@ Renders each content part with type-based component resolution.
|
|
|
250
250
|
|
|
251
251
|
### GroupedParts
|
|
252
252
|
|
|
253
|
-
Groups adjacent message parts into a nested tree. Use `groupBy` to
|
|
253
|
+
Groups adjacent message parts into a nested tree. Use `groupBy` to map each part to a group-key path, then switch on `part.type` in the render function. Group cases render `children`; leaf cases render their own UI. Prefer the `groupPartByType` helper for the common `part.type → path` case.
|
|
254
254
|
|
|
255
255
|
```tsx
|
|
256
|
+
import { MessagePrimitive, groupPartByType } from "@assistant-ui/react";
|
|
257
|
+
|
|
256
258
|
<MessagePrimitive.GroupedParts
|
|
257
|
-
groupBy={(
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
return ["group-chainOfThought", "group-tool"];
|
|
262
|
-
return null;
|
|
263
|
-
}}
|
|
259
|
+
groupBy={groupPartByType({
|
|
260
|
+
reasoning: ["group-chainOfThought", "group-reasoning"],
|
|
261
|
+
"tool-call": ["group-chainOfThought", "group-tool"],
|
|
262
|
+
})}
|
|
264
263
|
>
|
|
265
264
|
{({ part, children }) => {
|
|
266
265
|
switch (part.type) {
|
|
@@ -514,7 +513,7 @@ import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
|
514
513
|
</MessagePrimitive.Root>;
|
|
515
514
|
```
|
|
516
515
|
|
|
517
|
-
`s.message.status` is a discriminated union of `running | requires-action | complete | incomplete`, defined only on assistant messages. The `role === "assistant"` guard keeps the predicate type-safe. For tool-call-driven generative UI that defers rendering inside the part itself, see [Deferred Rendering](/docs/
|
|
516
|
+
`s.message.status` is a discriminated union of `running | requires-action | complete | incomplete`, defined only on assistant messages. The `role === "assistant"` guard keeps the predicate type-safe. For tool-call-driven generative UI that defers rendering inside the part itself, see [Deferred Rendering](/docs/tools/tool-ui#deferred-rendering) in the Generative UI guide.
|
|
518
517
|
|
|
519
518
|
### Legacy and Unstable APIs
|
|
520
519
|
|
|
@@ -128,6 +128,15 @@ When `send={false}`, the `clearComposer` prop controls whether the suggestion re
|
|
|
128
128
|
- **`clearComposer={true}`** (default): replaces the current composer text
|
|
129
129
|
- **`clearComposer={false}`**: appends the suggestion to the existing text
|
|
130
130
|
|
|
131
|
+
### Static configuration vs. runtime suggestions
|
|
132
|
+
|
|
133
|
+
There are two separate data flows for suggestions:
|
|
134
|
+
|
|
135
|
+
- **Static configuration** flows through the `suggestions` scope. Pass an array to `Suggestions(...)` in your runtime provider; render it with `ThreadPrimitive.Suggestions`. Best for welcome screen prompts.
|
|
136
|
+
- **Runtime / dynamic suggestions** flow through `thread.suggestions`. Populate it via `SuggestionAdapter` (local runtime) or the `suggestions` field on `useExternalStoreRuntime`; render it with the shadcn `ThreadFollowupSuggestions` component or your own component reading `useAuiState((s) => s.thread.suggestions)`. Best for follow up prompts after a turn.
|
|
137
|
+
|
|
138
|
+
See [Suggested Prompts](/docs/guides/suggestions) for end to end examples.
|
|
139
|
+
|
|
131
140
|
### ThreadPrimitive.Suggestion (Legacy)
|
|
132
141
|
|
|
133
142
|
`ThreadPrimitive.Suggestion` is a self-contained button that takes a `prompt` prop directly. The newer pattern (`ThreadPrimitive.Suggestions` + `SuggestionPrimitive` parts) is preferred for structured suggestions with title and description:
|
|
@@ -55,8 +55,8 @@ Subscribe to events without causing re-renders.
|
|
|
55
55
|
```tsx
|
|
56
56
|
import { useAuiEvent } from "@assistant-ui/react-native";
|
|
57
57
|
|
|
58
|
-
useAuiEvent("thread.
|
|
59
|
-
console.log("
|
|
58
|
+
useAuiEvent("thread.modelContextUpdate", ({ threadId }) => {
|
|
59
|
+
console.log("Model context updated:", threadId);
|
|
60
60
|
});
|
|
61
61
|
```
|
|
62
62
|
|
|
@@ -114,52 +114,46 @@ const runtime = useRemoteThreadListRuntime({
|
|
|
114
114
|
|
|
115
115
|
## Model Context Hooks
|
|
116
116
|
|
|
117
|
-
###
|
|
117
|
+
### Tools
|
|
118
118
|
|
|
119
|
-
Register
|
|
119
|
+
Register tools with a toolkit. The tool definition is forwarded to the model, and when the model calls it, the `execute` function runs and the `render` component displays the result.
|
|
120
120
|
|
|
121
|
-
```tsx
|
|
122
|
-
import {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
121
|
+
```tsx title="weather-toolkit.tsx"
|
|
122
|
+
import type { Toolkit } from "@assistant-ui/react-native";
|
|
123
|
+
import { Text, View } from "react-native";
|
|
124
|
+
|
|
125
|
+
export const toolkit = {
|
|
126
|
+
get_weather: {
|
|
127
|
+
type: "frontend",
|
|
128
|
+
description: "Get the current weather for a city",
|
|
129
|
+
parameters: {
|
|
130
|
+
type: "object",
|
|
131
|
+
properties: {
|
|
132
|
+
city: { type: "string" },
|
|
133
|
+
},
|
|
134
|
+
required: ["city"],
|
|
131
135
|
},
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
execute: async ({ city }) => {
|
|
137
|
+
const res = await fetch(`https://api.weather.example/${city}`);
|
|
138
|
+
return res.json();
|
|
139
|
+
},
|
|
140
|
+
render: ({ args, result }) => (
|
|
141
|
+
<View>
|
|
142
|
+
<Text>{args.city}: {result?.temperature}°F</Text>
|
|
143
|
+
</View>
|
|
144
|
+
),
|
|
137
145
|
},
|
|
138
|
-
|
|
139
|
-
<View>
|
|
140
|
-
<Text>{args.city}: {result?.temperature}°F</Text>
|
|
141
|
-
</View>
|
|
142
|
-
),
|
|
143
|
-
});
|
|
146
|
+
} satisfies Toolkit;
|
|
144
147
|
```
|
|
145
148
|
|
|
146
|
-
|
|
149
|
+
```tsx title="ToolProvider.tsx"
|
|
150
|
+
import { AuiProvider, Tools, useAui } from "@assistant-ui/react-native";
|
|
151
|
+
import { toolkit } from "./weather-toolkit";
|
|
147
152
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
useAssistantToolUI({
|
|
154
|
-
toolName: "get_weather",
|
|
155
|
-
render: ({ args, result, status }) => (
|
|
156
|
-
<View>
|
|
157
|
-
{status?.type === "running"
|
|
158
|
-
? <Text>Loading weather for {args.city}...</Text>
|
|
159
|
-
: <Text>{args.city}: {result?.temperature}°F</Text>}
|
|
160
|
-
</View>
|
|
161
|
-
),
|
|
162
|
-
});
|
|
153
|
+
function ToolProvider({ children }: { children: React.ReactNode }) {
|
|
154
|
+
const aui = useAui({ tools: Tools({ toolkit }) });
|
|
155
|
+
return <AuiProvider value={aui}>{children}</AuiProvider>;
|
|
156
|
+
}
|
|
163
157
|
```
|
|
164
158
|
|
|
165
159
|
### useAssistantDataUI
|
|
@@ -193,49 +187,30 @@ useAssistantInstructions("You are a helpful weather assistant.");
|
|
|
193
187
|
|
|
194
188
|
Wrap a tool UI component so that inline state updates (from a parent component's render) are reflected without remounting. Use this when the render function closes over props that change over time.
|
|
195
189
|
|
|
196
|
-
```tsx
|
|
197
|
-
import { useInlineRender } from "@assistant-ui/react-native";
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
execute: async ({ city }) => ({ temperature: 72 }),
|
|
218
|
-
render: ({ args, result }) => <Text>{args.city}: {result?.temperature}°F</Text>,
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
// Mount inside AssistantRuntimeProvider to register
|
|
222
|
-
<WeatherTool />
|
|
190
|
+
```tsx title="my-tool-toolkit.tsx"
|
|
191
|
+
import { type Toolkit, useInlineRender } from "@assistant-ui/react-native";
|
|
192
|
+
import { Text } from "react-native";
|
|
193
|
+
import { useMemo } from "react";
|
|
194
|
+
|
|
195
|
+
export function useMyToolToolkit(someOuterProp: string) {
|
|
196
|
+
const stableRender = useInlineRender(({ args, result }) => (
|
|
197
|
+
<Text>{someOuterProp}: {result?.value}</Text>
|
|
198
|
+
));
|
|
199
|
+
|
|
200
|
+
return useMemo(
|
|
201
|
+
() =>
|
|
202
|
+
({
|
|
203
|
+
my_tool: {
|
|
204
|
+
type: "backend",
|
|
205
|
+
render: stableRender,
|
|
206
|
+
},
|
|
207
|
+
}) satisfies Toolkit,
|
|
208
|
+
[stableRender],
|
|
209
|
+
);
|
|
210
|
+
}
|
|
223
211
|
```
|
|
224
212
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
Create a component that registers only a tool UI renderer when mounted.
|
|
228
|
-
|
|
229
|
-
```tsx
|
|
230
|
-
import { makeAssistantToolUI } from "@assistant-ui/react-native";
|
|
231
|
-
|
|
232
|
-
const WeatherToolUI = makeAssistantToolUI({
|
|
233
|
-
toolName: "get_weather",
|
|
234
|
-
render: ({ args, result }) => <Text>{args.city}: {result?.temperature}°F</Text>,
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
<WeatherToolUI />
|
|
238
|
-
```
|
|
213
|
+
Import the toolkit hook, pass its result to `useAui({ tools: Tools({ toolkit }) })`, and provide the returned `aui` with `AuiProvider`, as shown in the [Tools](#tools) section above.
|
|
239
214
|
|
|
240
215
|
### makeAssistantDataUI
|
|
241
216
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
3
|
-
description: Build AI chat
|
|
2
|
+
title: React Native AI Chat
|
|
3
|
+
description: Build AI chat for iOS and Android with @assistant-ui/react-native — streaming, tools, attachments, and platform-native components from the same primitives as the web SDK.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## Quick Start
|
|
@@ -69,7 +69,7 @@ export const maxDuration = 30;
|
|
|
69
69
|
export async function POST(req: Request) {
|
|
70
70
|
const { messages } = await req.json();
|
|
71
71
|
const result = streamText({
|
|
72
|
-
model: openai("gpt-
|
|
72
|
+
model: openai("gpt-5.4-nano"),
|
|
73
73
|
messages: await convertToModelMessages(messages),
|
|
74
74
|
});
|
|
75
75
|
return result.toUIMessageStreamResponse();
|
|
@@ -85,7 +85,7 @@ export const maxDuration = 30;
|
|
|
85
85
|
export async function POST(req: Request) {
|
|
86
86
|
const { messages } = await req.json();
|
|
87
87
|
const result = streamText({
|
|
88
|
-
model: anthropic("claude-sonnet-4-
|
|
88
|
+
model: anthropic("claude-sonnet-4-6"),
|
|
89
89
|
messages: await convertToModelMessages(messages),
|
|
90
90
|
});
|
|
91
91
|
return result.toUIMessageStreamResponse();
|
|
@@ -9,7 +9,7 @@ If you already have an assistant-ui web app, most of your code transfers directl
|
|
|
9
9
|
|
|
10
10
|
- **Runtime setup** — `useChatRuntime`, `useLocalRuntime`, `ChatModelAdapter`, and all runtime options work identically.
|
|
11
11
|
- **AI SDK integration** — `@assistant-ui/react-ai-sdk` works with React Native. Your `useChatRuntime` + `AssistantChatTransport` setup transfers directly.
|
|
12
|
-
- **Tool definitions** — `
|
|
12
|
+
- **Tool definitions** — `Tools({ toolkit })` and toolkit renderers use the same API.
|
|
13
13
|
- **State hooks** — `useAuiState`, `useAui`, and selector patterns are the same.
|
|
14
14
|
- **Backend code** — Your API routes, streaming endpoints, and server-side logic need zero changes.
|
|
15
15
|
|
|
@@ -338,7 +338,7 @@ Container `View` for a single message.
|
|
|
338
338
|
|
|
339
339
|
### MessagePrimitive.Content
|
|
340
340
|
|
|
341
|
-
Renders message content parts using render-prop functions instead of the component-map approach used by `MessagePrimitive.Parts`. Each part type receives a `part` object and its `index`. Registered
|
|
341
|
+
Renders message content parts using render-prop functions instead of the component-map approach used by `MessagePrimitive.Parts`. Each part type receives a `part` object and its `index`. Registered toolkit renderers are automatically dispatched and take priority over `renderToolCall`.
|
|
342
342
|
|
|
343
343
|
```tsx
|
|
344
344
|
<MessagePrimitive.Content
|
|
@@ -364,7 +364,7 @@ Renders message content parts using render-prop functions instead of the compone
|
|
|
364
364
|
|
|
365
365
|
### MessagePrimitive.Parts
|
|
366
366
|
|
|
367
|
-
Renders message content parts via a `components` prop. Tool call and data parts automatically render registered
|
|
367
|
+
Renders message content parts via a `components` prop. Tool call and data parts automatically render registered toolkit renderers and data UIs (via `useAssistantDataUI`), falling back to components provided here. A default `Text` component using React Native's `<Text>` is provided out of the box.
|
|
368
368
|
|
|
369
369
|
```tsx
|
|
370
370
|
<MessagePrimitive.Parts>
|