@assistant-ui/mcp-docs-server 0.1.30 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docs/organized/code-examples/waterfall.md +8 -8
- package/.docs/organized/code-examples/with-a2a.md +10 -10
- package/.docs/organized/code-examples/with-ag-ui.md +12 -12
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +14 -14
- package/.docs/organized/code-examples/with-artifacts.md +14 -14
- package/.docs/organized/code-examples/with-assistant-transport.md +11 -11
- package/.docs/organized/code-examples/with-browser-extension.md +345 -0
- package/.docs/organized/code-examples/with-chain-of-thought.md +129 -63
- package/.docs/organized/code-examples/with-cloud-standalone.md +13 -13
- package/.docs/organized/code-examples/with-cloud.md +13 -13
- package/.docs/organized/code-examples/with-custom-thread-list.md +65 -20
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +18 -17
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +18 -17
- package/.docs/organized/code-examples/with-expo.md +25 -25
- package/.docs/organized/code-examples/with-external-store.md +10 -10
- package/.docs/organized/code-examples/with-ffmpeg.md +14 -14
- package/.docs/organized/code-examples/with-generative-ui.md +211 -14
- package/.docs/organized/code-examples/with-google-adk.md +12 -12
- package/.docs/organized/code-examples/with-heat-graph.md +8 -8
- package/.docs/organized/code-examples/with-image-generation.md +454 -0
- package/.docs/organized/code-examples/with-interactables.md +14 -14
- package/.docs/organized/code-examples/with-langchain.md +12 -12
- package/.docs/organized/code-examples/with-langgraph.md +15 -12
- package/.docs/organized/code-examples/with-livekit.md +19 -18
- package/.docs/organized/code-examples/with-mcp.md +748 -0
- package/.docs/organized/code-examples/with-opencode.md +107 -62
- package/.docs/organized/code-examples/with-parent-id-grouping.md +12 -12
- package/.docs/organized/code-examples/with-react-hook-form.md +14 -14
- package/.docs/organized/code-examples/with-react-ink.md +4 -4
- package/.docs/organized/code-examples/with-react-router.md +16 -16
- package/.docs/organized/code-examples/with-resumable-stream.md +660 -0
- package/.docs/organized/code-examples/with-store.md +8 -8
- package/.docs/organized/code-examples/with-tanstack.md +14 -14
- package/.docs/organized/code-examples/with-tap-runtime.md +11 -10
- package/.docs/raw/docs/(docs)/cli.mdx +3 -1
- package/.docs/raw/docs/(docs)/copilots/assistant-frame.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +10 -3
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +8 -3
- package/.docs/raw/docs/(docs)/copilots/make-assistant-visible.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/motivation.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/use-assistant-instructions.mdx +1 -0
- package/.docs/raw/docs/(docs)/devtools.mdx +1 -0
- package/.docs/raw/docs/(docs)/index.mdx +3 -2
- package/.docs/raw/docs/(docs)/installation.mdx +2 -1
- package/.docs/raw/docs/(docs)/rtl.mdx +1 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +36 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/feedback.mdx +20 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +34 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/model.mdx +44 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +55 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +20 -0
- 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 +22 -0
- 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 +36 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +98 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +31 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +33 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +640 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +28 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +94 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +464 -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 +22 -0
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +79 -0
- package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +52 -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 +125 -125
- 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 +46 -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 +70 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +63 -245
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +182 -554
- 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 +82 -86
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +173 -314
- 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 +43 -0
- 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 -42
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +18 -30
- package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +68 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +39 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +79 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +42 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +92 -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 +131 -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-assistant-ui.mdx +230 -2
- package/.docs/raw/docs/cloud/ai-sdk.mdx +222 -4
- package/.docs/raw/docs/cloud/index.mdx +2 -2
- package/.docs/raw/docs/cloud/langgraph.mdx +274 -2
- package/.docs/raw/docs/{(docs)/guides → guides}/attachments.mdx +45 -40
- package/.docs/raw/docs/guides/branching.mdx +76 -0
- package/.docs/raw/docs/guides/chain-of-thought.mdx +166 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/context-api.mdx +54 -26
- package/.docs/raw/docs/{(docs)/guides → guides}/dictation.mdx +3 -1
- package/.docs/raw/docs/guides/editing.mdx +102 -0
- package/.docs/raw/docs/guides/generative-ui.mdx +142 -0
- package/.docs/raw/docs/guides/image-generation.mdx +74 -0
- package/.docs/raw/docs/guides/index.mdx +103 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/interactables.mdx +51 -2
- package/.docs/raw/docs/{(docs)/guides → guides}/latex.mdx +53 -10
- package/.docs/raw/docs/guides/mcp-apps.mdx +231 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/mentions.mdx +63 -88
- package/.docs/raw/docs/{(docs)/guides → guides}/message-timing.mdx +45 -6
- package/.docs/raw/docs/{(docs)/guides → guides}/multi-agent.mdx +66 -6
- package/.docs/raw/docs/{(docs)/guides → guides}/quoting.mdx +11 -18
- 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/{(docs)/guides → guides}/slash-commands.mdx +104 -38
- package/.docs/raw/docs/guides/speech.mdx +156 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/suggestions.mdx +91 -69
- package/.docs/raw/docs/{(docs)/guides → guides}/tool-ui.mdx +110 -38
- package/.docs/raw/docs/{(docs)/guides → guides}/tools.mdx +197 -40
- package/.docs/raw/docs/{(docs)/guides → guides}/voice.mdx +41 -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/index.mdx +11 -14
- package/.docs/raw/docs/ink/migration.mdx +1 -3
- package/.docs/raw/docs/ink/primitives.mdx +386 -9
- package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +520 -0
- package/.docs/raw/docs/integrations/auth/better-auth.mdx +191 -0
- package/.docs/raw/docs/integrations/auth/clerk.mdx +172 -0
- package/.docs/raw/docs/integrations/auth/next-auth.mdx +196 -0
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +79 -0
- package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +282 -0
- package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +188 -0
- package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +57 -0
- package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +201 -0
- package/.docs/raw/docs/integrations/gateways/index.mdx +162 -0
- package/.docs/raw/docs/integrations/index.mdx +185 -0
- package/.docs/raw/docs/integrations/observability/helicone.mdx +130 -0
- package/.docs/raw/docs/integrations/observability/langfuse.mdx +163 -0
- package/.docs/raw/docs/integrations/observability/langsmith.mdx +150 -0
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +712 -0
- package/.docs/raw/docs/integrations/tools/mcp.mdx +267 -0
- package/.docs/raw/docs/integrations/tools/react-mcp.mdx +337 -0
- package/.docs/raw/docs/migrations/v0-14.mdx +297 -0
- package/.docs/raw/docs/primitives/action-bar.mdx +1 -0
- package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -0
- package/.docs/raw/docs/primitives/attachment.mdx +1 -0
- package/.docs/raw/docs/primitives/branch-picker.mdx +1 -0
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +90 -85
- package/.docs/raw/docs/primitives/composer.mdx +55 -1
- package/.docs/raw/docs/primitives/error.mdx +1 -0
- package/.docs/raw/docs/primitives/index.mdx +4 -3
- package/.docs/raw/docs/primitives/message.mdx +68 -5
- package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -0
- package/.docs/raw/docs/primitives/suggestion.mdx +10 -0
- package/.docs/raw/docs/primitives/thread-list.mdx +39 -0
- package/.docs/raw/docs/primitives/thread.mdx +16 -13
- package/.docs/raw/docs/react-native/hooks.mdx +2 -2
- package/.docs/raw/docs/react-native/index.mdx +5 -7
- package/.docs/raw/docs/react-native/migration.mdx +1 -3
- package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +396 -0
- package/.docs/raw/docs/runtimes/a2a/overview.mdx +60 -0
- package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +216 -0
- package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +70 -0
- package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +243 -0
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +154 -0
- package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +52 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +73 -128
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +70 -64
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +337 -123
- package/.docs/raw/docs/runtimes/concepts/adapters.mdx +265 -0
- package/.docs/raw/docs/runtimes/concepts/architecture.mdx +125 -0
- package/.docs/raw/docs/runtimes/concepts/stability.mdx +67 -0
- package/.docs/raw/docs/runtimes/concepts/threads.mdx +428 -0
- package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +703 -0
- package/.docs/raw/docs/runtimes/custom/data-stream.mdx +348 -0
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +261 -1236
- package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +746 -0
- package/.docs/raw/docs/runtimes/custom/overview.mdx +71 -0
- package/.docs/raw/docs/runtimes/google-adk/api.mdx +256 -0
- package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +717 -0
- package/.docs/raw/docs/runtimes/google-adk/overview.mdx +69 -0
- package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +229 -0
- package/.docs/raw/docs/runtimes/langchain.mdx +533 -0
- package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +305 -0
- package/.docs/raw/docs/runtimes/langgraph/interrupts.mdx +104 -0
- package/.docs/raw/docs/runtimes/langgraph/overview.mdx +84 -0
- package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +496 -0
- package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +127 -0
- package/.docs/raw/docs/runtimes/langgraph/threads.mdx +113 -0
- package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +3 -3
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +0 -23
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +1 -1
- package/.docs/raw/docs/runtimes/opencode/hooks.mdx +191 -0
- package/.docs/raw/docs/runtimes/opencode/overview.mdx +48 -0
- package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +119 -0
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +78 -203
- package/.docs/raw/docs/ui/accordion.mdx +1 -0
- package/.docs/raw/docs/ui/assistant-modal.mdx +1 -0
- package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -0
- package/.docs/raw/docs/ui/attachment.mdx +1 -0
- package/.docs/raw/docs/ui/badge.mdx +1 -0
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +12 -1
- package/.docs/raw/docs/ui/context-display.mdx +1 -0
- package/.docs/raw/docs/ui/diff-viewer.mdx +1 -0
- package/.docs/raw/docs/ui/directive-text.mdx +1 -0
- package/.docs/raw/docs/ui/file.mdx +1 -0
- package/.docs/raw/docs/ui/image.mdx +1 -0
- package/.docs/raw/docs/ui/markdown.mdx +2 -14
- package/.docs/raw/docs/ui/mcp-config.mdx +102 -0
- package/.docs/raw/docs/ui/mermaid.mdx +1 -0
- package/.docs/raw/docs/ui/message-timing.mdx +3 -2
- package/.docs/raw/docs/ui/model-selector.mdx +9 -8
- package/.docs/raw/docs/ui/part-grouping.mdx +325 -313
- package/.docs/raw/docs/ui/quote.mdx +1 -0
- package/.docs/raw/docs/ui/reasoning.mdx +66 -33
- package/.docs/raw/docs/ui/scrollbar.mdx +1 -0
- package/.docs/raw/docs/ui/select.mdx +1 -0
- package/.docs/raw/docs/ui/sources.mdx +18 -0
- package/.docs/raw/docs/ui/streamdown.mdx +35 -2
- package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -0
- package/.docs/raw/docs/ui/tabs.mdx +1 -0
- package/.docs/raw/docs/ui/thread-list.mdx +19 -2
- package/.docs/raw/docs/ui/thread.mdx +58 -3
- package/.docs/raw/docs/ui/tool-fallback.mdx +1 -0
- package/.docs/raw/docs/ui/tool-group.mdx +39 -11
- package/.docs/raw/docs/ui/voice.mdx +1 -0
- package/.docs/raw/docs/utilities/heat-graph.mdx +1 -0
- package/.docs/raw/docs/utilities/react-o11y.mdx +278 -0
- package/.docs/raw/docs/utilities/tw-shimmer.mdx +1 -0
- 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 +6 -6
- package/src/tools/tests/path-traversal.test.ts +1 -1
- package/.docs/raw/docs/(docs)/guides/branching.mdx +0 -65
- package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +0 -164
- package/.docs/raw/docs/(docs)/guides/editing.mdx +0 -66
- package/.docs/raw/docs/(docs)/guides/speech.mdx +0 -38
- 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/(reference)/migrations/v0-14.mdx +0 -159
- package/.docs/raw/docs/runtimes/a2a/index.mdx +0 -298
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +0 -1033
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +0 -314
- package/.docs/raw/docs/runtimes/custom/local.mdx +0 -1464
- package/.docs/raw/docs/runtimes/data-stream.mdx +0 -422
- package/.docs/raw/docs/runtimes/google-adk/index.mdx +0 -686
- package/.docs/raw/docs/runtimes/helicone.mdx +0 -61
- package/.docs/raw/docs/runtimes/langchain/comparison.mdx +0 -60
- package/.docs/raw/docs/runtimes/langchain/index.mdx +0 -210
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +0 -699
- package/.docs/raw/docs/runtimes/langgraph/tutorial/index.mdx +0 -12
- package/.docs/raw/docs/runtimes/langserve.mdx +0 -116
- package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +0 -218
- package/.docs/raw/docs/runtimes/mastra/overview.mdx +0 -18
- package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +0 -217
- 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
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Chain of Thought UI
|
|
3
|
+
description: Show AI reasoning steps and tool calls in a collapsible thinking accordion. Build chain-of-thought visualizations in React chat with assistant-ui.
|
|
4
|
+
platforms: ["react"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
LLMs often produce reasoning steps and tool calls in succession. Chain of Thought lets you visually group these consecutive parts into a single collapsible accordion, giving users a clean "thinking" UI.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
When a reasoning model responds, it may emit a sequence of reasoning tokens and tool calls before producing its final text answer. Use `MessagePrimitive.GroupedParts` to group those adjacent reasoning and tool-call parts into a single collapsible "thinking" section.
|
|
12
|
+
|
|
13
|
+
<Callout type="info">
|
|
14
|
+
The older `components.ChainOfThought` prop on `MessagePrimitive.Parts` and `components` prop on `ChainOfThoughtPrimitive.Parts` are legacy APIs. They still work for existing code, but new code should use `MessagePrimitive.GroupedParts`.
|
|
15
|
+
</Callout>
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
<Steps>
|
|
20
|
+
<Step>
|
|
21
|
+
|
|
22
|
+
### Wire GroupedParts into your assistant message
|
|
23
|
+
|
|
24
|
+
Return the same top-level group for reasoning and tool calls, with nested groups for each type:
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import {
|
|
28
|
+
MessagePrimitive,
|
|
29
|
+
} from "@assistant-ui/react";
|
|
30
|
+
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
|
|
31
|
+
import {
|
|
32
|
+
Reasoning,
|
|
33
|
+
ReasoningContent,
|
|
34
|
+
ReasoningRoot,
|
|
35
|
+
ReasoningText,
|
|
36
|
+
ReasoningTrigger,
|
|
37
|
+
} from "@/components/assistant-ui/reasoning";
|
|
38
|
+
import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
|
|
39
|
+
import {
|
|
40
|
+
ToolGroupContent,
|
|
41
|
+
ToolGroupRoot,
|
|
42
|
+
ToolGroupTrigger,
|
|
43
|
+
} from "@/components/assistant-ui/tool-group";
|
|
44
|
+
import type { FC } from "react";
|
|
45
|
+
|
|
46
|
+
const AssistantMessage: FC = () => {
|
|
47
|
+
return (
|
|
48
|
+
<MessagePrimitive.Root>
|
|
49
|
+
<MessagePrimitive.GroupedParts
|
|
50
|
+
groupBy={(part) => {
|
|
51
|
+
if (part.type === "reasoning")
|
|
52
|
+
return ["group-chainOfThought", "group-reasoning"];
|
|
53
|
+
if (part.type === "tool-call")
|
|
54
|
+
return ["group-chainOfThought", "group-tool"];
|
|
55
|
+
return null;
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
{({ part, children }) => {
|
|
59
|
+
switch (part.type) {
|
|
60
|
+
case "group-chainOfThought":
|
|
61
|
+
return <div className="my-2">{children}</div>;
|
|
62
|
+
case "group-reasoning": {
|
|
63
|
+
const running = part.status.type === "running";
|
|
64
|
+
return (
|
|
65
|
+
<ReasoningRoot defaultOpen={running}>
|
|
66
|
+
<ReasoningTrigger active={running} />
|
|
67
|
+
<ReasoningContent aria-busy={running}>
|
|
68
|
+
<ReasoningText>{children}</ReasoningText>
|
|
69
|
+
</ReasoningContent>
|
|
70
|
+
</ReasoningRoot>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
case "group-tool":
|
|
74
|
+
return (
|
|
75
|
+
<ToolGroupRoot>
|
|
76
|
+
<ToolGroupTrigger
|
|
77
|
+
count={part.indices.length}
|
|
78
|
+
active={part.status.type === "running"}
|
|
79
|
+
/>
|
|
80
|
+
<ToolGroupContent>{children}</ToolGroupContent>
|
|
81
|
+
</ToolGroupRoot>
|
|
82
|
+
);
|
|
83
|
+
case "text":
|
|
84
|
+
return <MarkdownText />;
|
|
85
|
+
case "reasoning":
|
|
86
|
+
return <Reasoning {...part} />;
|
|
87
|
+
case "tool-call":
|
|
88
|
+
return part.toolUI ?? <ToolFallback {...part} />;
|
|
89
|
+
default:
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}}
|
|
93
|
+
</MessagePrimitive.GroupedParts>
|
|
94
|
+
</MessagePrimitive.Root>
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
</Step>
|
|
100
|
+
<Step>
|
|
101
|
+
|
|
102
|
+
### Use a Reasoning Model
|
|
103
|
+
|
|
104
|
+
Chain of Thought is most useful with models that produce reasoning tokens. Here's an example backend route using the AI SDK:
|
|
105
|
+
|
|
106
|
+
```tsx title="app/api/chat/route.ts"
|
|
107
|
+
import { openai } from "@ai-sdk/openai";
|
|
108
|
+
import { streamText, convertToModelMessages } from "ai";
|
|
109
|
+
|
|
110
|
+
export async function POST(req: Request) {
|
|
111
|
+
const { messages } = await req.json();
|
|
112
|
+
|
|
113
|
+
const result = streamText({
|
|
114
|
+
model: openai("gpt-5.4-mini"),
|
|
115
|
+
messages: await convertToModelMessages(messages),
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return result.toUIMessageStreamResponse();
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
</Step>
|
|
123
|
+
</Steps>
|
|
124
|
+
|
|
125
|
+
## LangGraph
|
|
126
|
+
|
|
127
|
+
Chain-of-thought parts are surfaced by the AI SDK's built-in reasoning stream. LangGraph does not emit reasoning tokens in that format, so reasoning grouping will not activate automatically. If you want to display reasoning text from a LangGraph agent, emit it as a custom data part from your graph and render it with `makeAssistantDataUI`. See [generative UI with LangGraph](/docs/runtimes/langgraph/generative-ui) for details.
|
|
128
|
+
|
|
129
|
+
## Legacy: ChainOfThoughtPrimitive
|
|
130
|
+
|
|
131
|
+
### Reading Collapsed State
|
|
132
|
+
|
|
133
|
+
For existing `ChainOfThoughtPrimitive` code, use `AuiIf` to conditionally render based on the accordion state:
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import { AuiIf, ChainOfThoughtPrimitive } from "@assistant-ui/react";
|
|
137
|
+
import { ChevronDownIcon, ChevronRightIcon } from "lucide-react";
|
|
138
|
+
|
|
139
|
+
const ChainOfThoughtAccordionTrigger = () => {
|
|
140
|
+
return (
|
|
141
|
+
<ChainOfThoughtPrimitive.AccordionTrigger className="flex w-full cursor-pointer items-center gap-2 px-4 py-2 text-sm">
|
|
142
|
+
<AuiIf condition={(s) => s.chainOfThought.collapsed}>
|
|
143
|
+
<ChevronRightIcon className="size-4" />
|
|
144
|
+
</AuiIf>
|
|
145
|
+
<AuiIf condition={(s) => !s.chainOfThought.collapsed}>
|
|
146
|
+
<ChevronDownIcon className="size-4" />
|
|
147
|
+
</AuiIf>
|
|
148
|
+
Thinking
|
|
149
|
+
</ChainOfThoughtPrimitive.AccordionTrigger>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### API Reference
|
|
155
|
+
|
|
156
|
+
For lower-level legacy compatibility details, see the [`ChainOfThought` primitive reference](/docs/primitives/chain-of-thought).
|
|
157
|
+
|
|
158
|
+
## Full Example
|
|
159
|
+
|
|
160
|
+
See the complete [with-chain-of-thought example](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-chain-of-thought) for a working implementation with tool calls and reasoning.
|
|
161
|
+
|
|
162
|
+
## Related Guides
|
|
163
|
+
|
|
164
|
+
- [Reasoning](/docs/ui/reasoning) — reasoning UI primitives for grouped parts
|
|
165
|
+
- [Generative UI](/docs/guides/tool-ui) — custom UI for tool calls
|
|
166
|
+
- [Tools](/docs/guides/tools) — defining and using tools
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Context API
|
|
3
|
-
description: Read and update assistant state to build custom components.
|
|
2
|
+
title: Assistant Context API
|
|
3
|
+
description: Read and update assistant state to build custom React components in your chat UI — composable context API for thread, message, and runtime data via assistant-ui.
|
|
4
|
+
platforms: ["react"]
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
The Context API provides direct access to assistant-ui's state management system, enabling you to build custom components that integrate seamlessly with the assistant runtime.
|
|
@@ -211,6 +212,8 @@ aui.attachment().getState();
|
|
|
211
212
|
// ThreadList actions
|
|
212
213
|
aui.threads().switchToNewThread();
|
|
213
214
|
aui.threads().switchToThread(threadId);
|
|
215
|
+
aui.threads().reload();
|
|
216
|
+
await aui.threads().getLoadThreadsPromise();
|
|
214
217
|
aui.threads().getState();
|
|
215
218
|
|
|
216
219
|
// ThreadListItem actions
|
|
@@ -233,9 +236,9 @@ aui.chainOfThought().getState();
|
|
|
233
236
|
aui.chainOfThought().setCollapsed(collapsed);
|
|
234
237
|
aui.chainOfThought().part({ index: 0 });
|
|
235
238
|
|
|
236
|
-
// ModelContext actions
|
|
237
|
-
aui.modelContext().getState();
|
|
239
|
+
// ModelContext actions — see /docs/copilots/model-context for full usage
|
|
238
240
|
aui.modelContext().register(provider);
|
|
241
|
+
aui.modelContext().getState();
|
|
239
242
|
|
|
240
243
|
// Tools actions
|
|
241
244
|
aui.tools().setToolUI(toolName, render);
|
|
@@ -255,8 +258,8 @@ useAuiEvent("composer.send", (event) => {
|
|
|
255
258
|
});
|
|
256
259
|
|
|
257
260
|
// Listen to thread events
|
|
258
|
-
useAuiEvent("thread.
|
|
259
|
-
console.log("
|
|
261
|
+
useAuiEvent("thread.modelContextUpdate", (event) => {
|
|
262
|
+
console.log("Model context updated in thread:", event.threadId);
|
|
260
263
|
});
|
|
261
264
|
|
|
262
265
|
// Listen to all events of a type across all scopes
|
|
@@ -355,9 +358,14 @@ const partByToolCall = aui.message().part({ toolCallId: "call_123" });
|
|
|
355
358
|
// Access attachment by index
|
|
356
359
|
const attachment = aui.composer().attachment({ index: 0 }).getState();
|
|
357
360
|
|
|
358
|
-
// Access thread list item by ID or
|
|
361
|
+
// Access thread list item by ID, index, or the "main" selector
|
|
359
362
|
const threadItem = aui.threads().item({ id: "thread_123" });
|
|
360
363
|
const threadByIndex = aui.threads().item({ index: 0 });
|
|
364
|
+
const archivedThread = aui.threads().item({ index: 0, archived: true });
|
|
365
|
+
|
|
366
|
+
// Traverse to the main thread directly
|
|
367
|
+
const mainThread = aui.threads().thread("main");
|
|
368
|
+
const message = aui.threads().thread("main").message({ id: "msg_123" });
|
|
361
369
|
```
|
|
362
370
|
|
|
363
371
|
## Common Patterns
|
|
@@ -490,9 +498,9 @@ const isRunning = useAuiState((s) => s.thread.isRunning);
|
|
|
490
498
|
|
|
491
499
|
| Scope | Key State Properties | Description |
|
|
492
500
|
| -------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------- |
|
|
493
|
-
| ThreadList | `mainThreadId`, `newThreadId`, `threadIds`, `archivedThreadIds`, `isLoading`, `threadItems`
|
|
494
|
-
| ThreadListItem | `id`, `title`, `status`, `remoteId`, `externalId`
|
|
495
|
-
| Thread | `isRunning
|
|
501
|
+
| ThreadList | `mainThreadId`, `newThreadId`, `threadIds`, `archivedThreadIds`, `isLoading`, `threadItems` (`readonly ThreadListItemState[]`) | Manages all available conversation threads |
|
|
502
|
+
| ThreadListItem | `id`, `title`, `status`, `remoteId`, `externalId`, `custom?: Record<string, unknown>` | Individual thread metadata and status; `custom` carries arbitrary per-thread metadata set by remote runtimes |
|
|
503
|
+
| Thread | `isRunning` (may be explicitly set by the runtime rather than derived from last-message status), `isLoading`, `isDisabled`, `isEmpty`, `messages`, `capabilities`, `suggestions` | Active conversation state and message history |
|
|
496
504
|
| Message | `role`, `content`, `status`, `attachments`, `parts`, `parentId`, `branchNumber`, `branchCount`, `isLast`, `index` | Individual message content and metadata |
|
|
497
505
|
| Part | `type`, `status`, `text`, `toolCallId`, `toolName` | Content parts within messages (text, tool calls) |
|
|
498
506
|
| ChainOfThought | `parts`, `collapsed`, `status` | Reasoning steps grouped within a message |
|
|
@@ -500,13 +508,15 @@ const isRunning = useAuiState((s) => s.thread.isRunning);
|
|
|
500
508
|
| Attachment | `id`, `type`, `name`, `contentType`, `status` | File attachments metadata and content |
|
|
501
509
|
| Suggestions | `suggestions` | Collection of follow-up message suggestions |
|
|
502
510
|
| Suggestion | `title`, `label`, `prompt` | Individual suggestion with title, label, and prompt |
|
|
503
|
-
| ModelContext | *(empty — use `register()` / `getToolCallParams()` methods)*
|
|
511
|
+
| ModelContext | *(empty — use `register()` / `getToolCallParams()` methods; see [Model Context](/docs/copilots/model-context))* | System instructions, tools, and context providers |
|
|
504
512
|
|
|
505
513
|
### Available Actions by Scope
|
|
506
514
|
|
|
515
|
+
The table below covers the most commonly used actions. For the full catalog, see the [API Reference](/docs/api-reference/overview).
|
|
516
|
+
|
|
507
517
|
| Scope | Actions | Use Cases |
|
|
508
518
|
| -------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
|
|
509
|
-
| ThreadList | `switchToNewThread()`, `switchToThread(id)`, `item(selector)`, `thread("main")`, `getState()`
|
|
519
|
+
| ThreadList | `switchToNewThread()`, `switchToThread(id)`, `reload()`, `getLoadThreadsPromise()`, `item(selector)`, `thread("main")`, `getState()` | Thread navigation, creation, and sync |
|
|
510
520
|
| ThreadListItem | `switchTo()`, `rename(title)`, `archive()`, `unarchive()`, `delete()`, `getState()` | Thread management operations |
|
|
511
521
|
| Thread | `append(message)`, `startRun(config)`, `resumeRun(config)`, `cancelRun()`, `reset()`, `export()`, `import(repository)`, `message(selector)`, `composer()`, `getState()` | Message handling and conversation control |
|
|
512
522
|
| Message | `reload()`, `speak()`, `stopSpeaking()`, `submitFeedback(feedback)`, `switchToBranch(options)`, `getCopyText()`, `part(selector)`, `attachment(selector)`, `composer()`, `setIsCopied(value)`, `setIsHovering(value)`, `getState()` | Message interactions and regeneration |
|
|
@@ -516,20 +526,38 @@ const isRunning = useAuiState((s) => s.thread.isRunning);
|
|
|
516
526
|
| Attachment | `remove()`, `getState()` | File management |
|
|
517
527
|
| Suggestions | `suggestion({ index })`, `getState()` | Access follow-up suggestions |
|
|
518
528
|
| Suggestion | `getState()` | Read individual suggestion data |
|
|
519
|
-
| ModelContext | `register(provider)`, `getState()` | Register model
|
|
520
|
-
|
|
521
|
-
###
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
529
|
+
| ModelContext | `register(provider)`, `getState()` | Register providers; full details in [Model Context](/docs/copilots/model-context) |
|
|
530
|
+
|
|
531
|
+
### Events vs State Observation
|
|
532
|
+
|
|
533
|
+
`useAuiEvent` is the escape hatch for **transient occurrences that are not derivable from state**. State-derivable transitions (attachment list changing, run progress, thread switching) should be observed with `useAuiState`, not subscribed via events.
|
|
534
|
+
|
|
535
|
+
The rule of thumb:
|
|
536
|
+
|
|
537
|
+
1. Can you read the new value from state right now? → use `useAuiState`.
|
|
538
|
+
2. Are you the caller and want immediate feedback? → catch the rejection / read the return value.
|
|
539
|
+
3. Did something happen that has no representation in state at all? → use `useAuiEvent`.
|
|
540
|
+
|
|
541
|
+
Most existing events are kept for backward compatibility but duplicate state. They are marked `@deprecated` in the type definitions; new code should follow the rule above.
|
|
542
|
+
|
|
543
|
+
#### Currently Recommended (Truly Transient)
|
|
544
|
+
|
|
545
|
+
| Event | When It Fires |
|
|
546
|
+
| ----------------------------- | ---------------------------------------------------------------------------- |
|
|
547
|
+
| `composer.attachmentAddError` | An `addAttachment()` call failed. Payload `reason` discriminates `no-adapter` / `not-accepted` / `adapter-error`. `no-adapter` and `not-accepted` are non-state-derivable. `adapter-error` is partially state-derivable: if the adapter produced any attachment before failing, the errored attachment also appears in `composer.attachments` with `status.reason === "error"`. The event additionally surfaces a human-readable `message` (and the underlying `Error` instance via the low-level `runtime.unstable_on("attachmentAddError")` API; `useAuiEvent` payloads omit it because raw `Error` objects are not store-serializable). |
|
|
548
|
+
| `thread.modelContextUpdate` | The model context provider notified a change. The model context lives in a provider, not in thread state, so this event has no state-derivable equivalent. |
|
|
549
|
+
|
|
550
|
+
#### Legacy (State-Derivable, Prefer `useAuiState`)
|
|
551
|
+
|
|
552
|
+
These events fire at the same transition you can observe via state. They are kept for backward compatibility but new code should observe state instead.
|
|
553
|
+
|
|
554
|
+
| Legacy Event | Observe Instead |
|
|
555
|
+
| -------------------------------------------- | -------------------------------------------------------------- |
|
|
556
|
+
| `composer.send` | composer `text` clearing |
|
|
557
|
+
| `composer.attachmentAdd` | composer `attachments` |
|
|
558
|
+
| `thread.runStart` / `runEnd` | thread `isRunning` flipping to `true` / `false` |
|
|
559
|
+
| `thread.initialize` | thread `messages` becoming non-empty (or `isEmpty` flipping) |
|
|
560
|
+
| `threadListItem.switchedTo` / `switchedAway` | compare `s.threads.mainThreadId` against `s.threadListItem.id` |
|
|
533
561
|
|
|
534
562
|
## Troubleshooting
|
|
535
563
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Speech-to-Text
|
|
2
|
+
title: Speech-to-Text Dictation
|
|
3
|
+
description: Add voice dictation to your AI chat composer with the Web Speech API or a custom adapter. Speech-to-text in React, integrated through assistant-ui.
|
|
4
|
+
platforms: ["react"]
|
|
3
5
|
---
|
|
4
6
|
|
|
5
7
|
import { DictationSample } from "@/components/docs/samples/dictation";
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Message Editing
|
|
3
|
+
description: Let users edit their messages and regenerate AI responses with custom editor interfaces. Edit-and-resubmit patterns for React chat via assistant-ui.
|
|
4
|
+
platforms: ["react"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Mental Model
|
|
8
|
+
|
|
9
|
+
Editing re-submits a message from a past point in the conversation and creates a new branch. The messages after the edited one are discarded, and the assistant generates a fresh response from that point forward. Each user message has an independent edit composer; only one can be active at a time.
|
|
10
|
+
|
|
11
|
+
The recommended way to wire this up is via the `children` render prop on `ThreadPrimitive.Messages`, branching on `message.role` and on `message.composer.isEditing` to swap in an edit composer when needed.
|
|
12
|
+
|
|
13
|
+
## Enabling Edit Support
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import {
|
|
17
|
+
ActionBarPrimitive,
|
|
18
|
+
ComposerPrimitive,
|
|
19
|
+
MessagePrimitive,
|
|
20
|
+
ThreadPrimitive,
|
|
21
|
+
} from "@assistant-ui/react";
|
|
22
|
+
|
|
23
|
+
const Thread = () => {
|
|
24
|
+
return (
|
|
25
|
+
<ThreadPrimitive.Root>
|
|
26
|
+
<ThreadPrimitive.Viewport>
|
|
27
|
+
<ThreadPrimitive.Messages>
|
|
28
|
+
{({ message }) => {
|
|
29
|
+
if (message.role === "user") {
|
|
30
|
+
if (message.composer.isEditing) return <UserEditComposer />;
|
|
31
|
+
return <UserMessage />;
|
|
32
|
+
}
|
|
33
|
+
return <AssistantMessage />;
|
|
34
|
+
}}
|
|
35
|
+
</ThreadPrimitive.Messages>
|
|
36
|
+
</ThreadPrimitive.Viewport>
|
|
37
|
+
</ThreadPrimitive.Root>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const UserMessage = () => {
|
|
42
|
+
return (
|
|
43
|
+
<MessagePrimitive.Root>
|
|
44
|
+
{/* message content */}
|
|
45
|
+
<ActionBarPrimitive.Root>
|
|
46
|
+
<ActionBarPrimitive.Edit />
|
|
47
|
+
</ActionBarPrimitive.Root>
|
|
48
|
+
</MessagePrimitive.Root>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const UserEditComposer = () => {
|
|
53
|
+
return (
|
|
54
|
+
<MessagePrimitive.Root>
|
|
55
|
+
<ComposerPrimitive.Root>
|
|
56
|
+
<ComposerPrimitive.Input />
|
|
57
|
+
<ComposerPrimitive.Cancel />
|
|
58
|
+
<ComposerPrimitive.Send />
|
|
59
|
+
</ComposerPrimitive.Root>
|
|
60
|
+
</MessagePrimitive.Root>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const AssistantMessage = () => {
|
|
65
|
+
return <MessagePrimitive.Root>{/* message content */}</MessagePrimitive.Root>;
|
|
66
|
+
};
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`ActionBarPrimitive.Edit` calls `aui.composer().beginEdit()` under the hood and is disabled when the composer is already in edit mode.
|
|
70
|
+
|
|
71
|
+
`ComposerPrimitive.Cancel` calls `aui.composer().cancel()`, which exits edit mode and restores the original message content. See [Composer primitives](/docs/primitives/composer) for the full composer API.
|
|
72
|
+
|
|
73
|
+
## Detecting Edit Mode
|
|
74
|
+
|
|
75
|
+
The `isEditing` flag is available on both `ThreadComposerState` and `EditComposerState`, so `useAuiState((s) => s.composer.isEditing)` works inside any composer context. The more idiomatic path is to rely on the `UserEditComposer` slot in the render function (shown above), which scopes the component tree automatically and avoids manual state checks.
|
|
76
|
+
|
|
77
|
+
## Imperative API
|
|
78
|
+
|
|
79
|
+
`aui.composer().beginEdit()` is the programmatic entry point for entering edit mode on a message. Use it for headless or keyboard-shortcut-driven flows where `ActionBarPrimitive.Edit` is not rendered:
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import { useAui } from "@assistant-ui/react";
|
|
83
|
+
|
|
84
|
+
const EditButton = () => {
|
|
85
|
+
const aui = useAui();
|
|
86
|
+
return (
|
|
87
|
+
<button onClick={() => aui.composer().beginEdit()}>Edit</button>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`aui.composer().cancel()` exits edit mode without re-submitting.
|
|
93
|
+
|
|
94
|
+
## Editing While Streaming
|
|
95
|
+
|
|
96
|
+
If a user triggers edit mode while the assistant is still generating a response, the in-progress run is cancelled and a new branch is started from the edited message. The hook does not block this. If your UI should prevent editing during streaming, gate the edit button on the thread run state before rendering `ActionBarPrimitive.Edit` or calling `beginEdit()`.
|
|
97
|
+
|
|
98
|
+
## References
|
|
99
|
+
|
|
100
|
+
- [ActionBar primitives](/docs/primitives/action-bar) — `ActionBarPrimitive.Edit` and related actions
|
|
101
|
+
- [Composer primitives](/docs/primitives/composer) — full composer anatomy including `Cancel`, `Send`, and `Input`
|
|
102
|
+
- [Message primitives](/docs/primitives/message) — `MessagePrimitive.Root` and content parts
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Generative UI
|
|
3
|
+
description: Render agent-described React UI from a JSON spec with a consumer-provided component allowlist.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`MessagePrimitive.GenerativeUI` is a first-class primitive for rendering UI
|
|
7
|
+
described by the agent at runtime as a JSON spec. Instead of hard-coding a
|
|
8
|
+
component per tool, the agent emits a `generative-ui` message part containing
|
|
9
|
+
a tree of components by name. assistant-ui resolves each name against a
|
|
10
|
+
**consumer-provided allowlist** and renders the result.
|
|
11
|
+
|
|
12
|
+
> The allowlist controls **which** components the agent may render: any name
|
|
13
|
+
> not in it throws a typed `GenerativeUIRenderError` (no implicit fallback). It
|
|
14
|
+
> does not constrain the props passed to those components; see [Security](#security).
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
### 1. Define your component allowlist
|
|
19
|
+
|
|
20
|
+
```tsx title="components/gui.tsx"
|
|
21
|
+
const Card = ({ title, children }) => (
|
|
22
|
+
<div className="rounded-xl border bg-card p-4 shadow-sm">
|
|
23
|
+
<div className="text-base font-semibold">{title}</div>
|
|
24
|
+
<div className="mt-2">{children}</div>
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const Button = ({ label }) => (
|
|
29
|
+
<button className="rounded-md bg-primary px-3 py-1.5 text-primary-foreground">
|
|
30
|
+
{label}
|
|
31
|
+
</button>
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
export const componentsAllowlist = { Card, Button };
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2. Wire the primitive into your message renderer
|
|
38
|
+
|
|
39
|
+
```tsx title="components/assistant-message.tsx"
|
|
40
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
41
|
+
import { componentsAllowlist } from "./gui";
|
|
42
|
+
|
|
43
|
+
export function AssistantMessage() {
|
|
44
|
+
return (
|
|
45
|
+
<MessagePrimitive.Parts
|
|
46
|
+
components={{
|
|
47
|
+
generativeUI: { components: componentsAllowlist },
|
|
48
|
+
}}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
You can also use the standalone primitive form:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
<MessagePrimitive.GenerativeUI components={componentsAllowlist} />
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. Have the agent emit a `generative-ui` part
|
|
61
|
+
|
|
62
|
+
A `GenerativeUIMessagePart` carries a JSON spec:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
{
|
|
66
|
+
type: "generative-ui",
|
|
67
|
+
spec: {
|
|
68
|
+
root: {
|
|
69
|
+
component: "Card",
|
|
70
|
+
props: { title: "Welcome" },
|
|
71
|
+
children: [
|
|
72
|
+
{ component: "Button", props: { label: "Get started" } },
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Bare strings act as inline text leaves.
|
|
80
|
+
|
|
81
|
+
## Spec shape
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
type GenerativeUINode =
|
|
85
|
+
| string
|
|
86
|
+
| {
|
|
87
|
+
component: string; // resolved against the allowlist
|
|
88
|
+
props?: Record<string, unknown>;
|
|
89
|
+
children?: GenerativeUINode[];
|
|
90
|
+
key?: string; // optional stable React key
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
type GenerativeUISpec = {
|
|
94
|
+
root: GenerativeUINode | GenerativeUINode[];
|
|
95
|
+
};
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The spec is plain JSON — easy for any agent to emit, and easy to validate
|
|
99
|
+
on the server before delivery.
|
|
100
|
+
|
|
101
|
+
## Streaming
|
|
102
|
+
|
|
103
|
+
The primitive is stream-friendly: any partial spec renders progressively. As
|
|
104
|
+
new nodes arrive (filling in `children`, refining `props`), the rendered tree
|
|
105
|
+
updates without reflows or lost local state for already-mounted children.
|
|
106
|
+
|
|
107
|
+
## Security
|
|
108
|
+
|
|
109
|
+
The allowlist is the boundary on **which** components render: a spec can only instantiate components you put in the registry, with no `eval` and no dynamic import (names are looked up in the registry and nothing else). An unknown name throws `GenerativeUIRenderError` or invokes your `Fallback`.
|
|
110
|
+
|
|
111
|
+
It does **not** constrain the `props` the agent supplies. Spec props are spread directly onto your allowlisted components, so treat every allowlisted component as receiving untrusted input: never forward agent-supplied props into `dangerouslySetInnerHTML`, validate or reject `href` / `src` values (for example block `javascript:` URLs), and avoid passing spec props anywhere they become executable. The safest allowlisted components accept only primitive, display-oriented props.
|
|
112
|
+
|
|
113
|
+
## Error handling
|
|
114
|
+
|
|
115
|
+
Unknown component names throw `GenerativeUIRenderError` with a typed
|
|
116
|
+
`componentName` field. Catch it with a React error boundary, or pass a
|
|
117
|
+
`Fallback` component to opt into a soft-fail UX:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
<MessagePrimitive.GenerativeUI
|
|
121
|
+
components={componentsAllowlist}
|
|
122
|
+
Fallback={({ component }) => (
|
|
123
|
+
<span className="rounded bg-muted px-1.5 py-0.5 font-mono text-xs">
|
|
124
|
+
unknown component: {component}
|
|
125
|
+
</span>
|
|
126
|
+
)}
|
|
127
|
+
/>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Composing with other primitives
|
|
131
|
+
|
|
132
|
+
`generative-ui` is a regular `MessagePart` type, so it composes cleanly with
|
|
133
|
+
`MessagePrimitive.Parts`, `MessagePrimitive.PartByIndex`, and
|
|
134
|
+
`MessagePrimitive.GroupedParts`. Render it alongside text, tool calls, and
|
|
135
|
+
reasoning in the same message.
|
|
136
|
+
|
|
137
|
+
## Why a primitive (not just a tool)
|
|
138
|
+
|
|
139
|
+
Tool-call UI is great when the agent already invoked a known tool. Generative
|
|
140
|
+
UI flips it: the agent _composes_ UI from a vocabulary you ship. Useful for
|
|
141
|
+
forms, dashboards, status panels, multi-step flows, and anywhere the
|
|
142
|
+
component library you want is broader than a single tool's render surface.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Image Generation
|
|
3
|
+
description: Generate images in your backend and render them inline in an assistant-ui thread.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Image generation needs no dedicated primitive. Generate the image wherever you already run model calls (a route handler or a tool), store the result as an `ImageMessagePart`, and render it with the `@assistant-ui/ui` `Image` component.
|
|
7
|
+
|
|
8
|
+
<Callout type="info">
|
|
9
|
+
This covers non-streaming generation, rendering, and actions. Streaming partial images and multi-image galleries are out of scope.
|
|
10
|
+
</Callout>
|
|
11
|
+
|
|
12
|
+
## Generate in your backend
|
|
13
|
+
|
|
14
|
+
Call your provider from a server route. With the AI SDK that is `generateImage`; return the image as a data URI (or an object-store URL) plus any provider metadata you want to keep.
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// app/api/image/route.ts
|
|
18
|
+
import { generateImage } from "ai";
|
|
19
|
+
import { openai } from "@ai-sdk/openai";
|
|
20
|
+
|
|
21
|
+
export async function POST(req: Request) {
|
|
22
|
+
const { prompt } = await req.json();
|
|
23
|
+
const result = await generateImage({
|
|
24
|
+
model: openai.image("gpt-image-1"),
|
|
25
|
+
prompt,
|
|
26
|
+
});
|
|
27
|
+
const revisedPrompt = (
|
|
28
|
+
result.providerMetadata as
|
|
29
|
+
| Record<string, Record<string, unknown>>
|
|
30
|
+
| undefined
|
|
31
|
+
)?.openai?.revisedPrompt;
|
|
32
|
+
return Response.json({
|
|
33
|
+
image: `data:${result.image.mediaType};base64,${result.image.base64}`,
|
|
34
|
+
mimeType: result.image.mediaType,
|
|
35
|
+
...(typeof revisedPrompt === "string" && { revisedPrompt }),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The model provider is irrelevant to rendering; swap `openai.image(...)` for any AI SDK image model.
|
|
41
|
+
|
|
42
|
+
## Store it as an `ImageMessagePart`
|
|
43
|
+
|
|
44
|
+
An `ImageMessagePart` only needs `image` (a `data:` URI, an `https://` URL, or a `blob:` URL) plus an optional `filename`. Keep any provenance you want to display, the prompt, a revised prompt, a model id, in your own component state or in message metadata; the part itself stays minimal.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const part: ImageMessagePart = {
|
|
48
|
+
type: "image",
|
|
49
|
+
image: result.image, // data:, https://, or blob: URL
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Render with the `Image` component
|
|
54
|
+
|
|
55
|
+
The `Image` component in `@assistant-ui/ui` handles the render states for you:
|
|
56
|
+
|
|
57
|
+
1. **Running** (`status.type === "running"`) renders a spinner.
|
|
58
|
+
2. **Content filter** (`status.type === "incomplete"` with `reason: "content-filter"`) renders an error card with no `<img src>`.
|
|
59
|
+
3. **Complete** renders a zoomable `<img>` with optional `Image.Actions`.
|
|
60
|
+
|
|
61
|
+
`Image.Actions` provides download and copy buttons, plus a regenerate button when you pass an `onRegenerate` callback. Wire it to the same generation flow you used above; debounce, rate limiting, and confirmation are your call.
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { Image } from "@assistant-ui/ui";
|
|
65
|
+
|
|
66
|
+
<>
|
|
67
|
+
<Image {...imagePart} />
|
|
68
|
+
<Image.Actions part={imagePart} onRegenerate={() => regenerate(prompt)} />
|
|
69
|
+
</>;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Example
|
|
73
|
+
|
|
74
|
+
A complete Next.js example (with a mock fallback when `OPENAI_API_KEY` is unset) lives in [`examples/with-image-generation`](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-image-generation).
|