@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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Mentions
|
|
3
|
-
description: Let users @-mention tools or custom items in the composer to guide the LLM.
|
|
2
|
+
title: Mentions in Chat
|
|
3
|
+
description: Let users @-mention tools or custom items in the AI chat composer to guide the LLM. Mention picker built into assistant-ui's React composer.
|
|
4
|
+
platforms: ["react"]
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
Mentions let users type `@` in the composer to open a popover picker, select an item (e.g. a tool), and insert a directive into the message text. The LLM can then use the directive as a hint.
|
|
@@ -82,6 +83,63 @@ const myAdapter: Unstable_TriggerAdapter = {
|
|
|
82
83
|
};
|
|
83
84
|
```
|
|
84
85
|
|
|
86
|
+
### Async Mention Search
|
|
87
|
+
|
|
88
|
+
The adapter interface is synchronous, but the data it reads can come from any async source. Load results into React state (or a query cache) and read the current snapshot inside the adapter methods. The adapter re-creates on each render, so the popover always sees the latest results.
|
|
89
|
+
|
|
90
|
+
**With React state and `useEffect`:**
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { useState, useEffect, useMemo } from "react";
|
|
94
|
+
import type { Unstable_TriggerAdapter } from "@assistant-ui/core";
|
|
95
|
+
|
|
96
|
+
function useUserMentionAdapter(query: string) {
|
|
97
|
+
const [users, setUsers] = useState<{ id: string; name: string }[]>([]);
|
|
98
|
+
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (!query) return;
|
|
101
|
+
let cancelled = false;
|
|
102
|
+
fetchUsers(query).then((results) => {
|
|
103
|
+
if (!cancelled) setUsers(results);
|
|
104
|
+
});
|
|
105
|
+
return () => { cancelled = true; };
|
|
106
|
+
}, [query]);
|
|
107
|
+
|
|
108
|
+
const adapter: Unstable_TriggerAdapter = useMemo(() => ({
|
|
109
|
+
categories: () => [],
|
|
110
|
+
categoryItems: () => [],
|
|
111
|
+
search: () =>
|
|
112
|
+
users.map((u) => ({ id: u.id, type: "user", label: u.name })),
|
|
113
|
+
}), [users]);
|
|
114
|
+
|
|
115
|
+
return adapter;
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`query` here is the text the user typed after `@`. You can read it from `unstable_useTriggerPopoverScopeContext` if you need it inside the component tree, or pass it as state from a controlled input.
|
|
120
|
+
|
|
121
|
+
**With React Query:**
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
import { useQuery } from "@tanstack/react-query";
|
|
125
|
+
import type { Unstable_TriggerAdapter } from "@assistant-ui/core";
|
|
126
|
+
|
|
127
|
+
function useMentionAdapter(query: string): Unstable_TriggerAdapter {
|
|
128
|
+
const { data = [] } = useQuery({
|
|
129
|
+
queryKey: ["mention-search", query],
|
|
130
|
+
queryFn: () => fetchUsers(query),
|
|
131
|
+
enabled: query.length > 0,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
return useMemo(() => ({
|
|
135
|
+
categories: () => [],
|
|
136
|
+
categoryItems: () => [],
|
|
137
|
+
search: () =>
|
|
138
|
+
data.map((u) => ({ id: u.id, type: "user", label: u.name })),
|
|
139
|
+
}), [data]);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
85
143
|
Pass the adapter to `TriggerPopover` and declare a `Directive` sub-primitive to bind the insertion behavior:
|
|
86
144
|
|
|
87
145
|
```tsx
|
|
@@ -333,27 +391,7 @@ import { LexicalComposerInput } from "@assistant-ui/react-lexical";
|
|
|
333
391
|
|
|
334
392
|
## Rendering Mentions in Messages
|
|
335
393
|
|
|
336
|
-
Use `DirectiveText` as the `Text` component for user messages so directives render as inline chips instead of raw syntax
|
|
337
|
-
|
|
338
|
-
```tsx
|
|
339
|
-
import { DirectiveText } from "@/components/assistant-ui/directive-text";
|
|
340
|
-
|
|
341
|
-
<MessagePrimitive.Parts
|
|
342
|
-
components={{
|
|
343
|
-
Text: DirectiveText,
|
|
344
|
-
}}
|
|
345
|
-
/>
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
For assistant messages, keep using your markdown renderer (e.g. `MarkdownText`) — the LLM typically does not emit directive syntax.
|
|
349
|
-
|
|
350
|
-
For a custom formatter, use `createDirectiveText`:
|
|
351
|
-
|
|
352
|
-
```tsx
|
|
353
|
-
import { createDirectiveText } from "@/components/assistant-ui/directive-text";
|
|
354
|
-
|
|
355
|
-
const MyDirectiveText = createDirectiveText(myFormatter);
|
|
356
|
-
```
|
|
394
|
+
Use `DirectiveText` as the `Text` component for user messages so directives render as inline chips instead of raw syntax. See the [Directive Text](/docs/ui/directive-text) guide for setup and customization.
|
|
357
395
|
|
|
358
396
|
## Processing Mentions on the Backend
|
|
359
397
|
|
|
@@ -467,74 +505,11 @@ Use the trigger popover primitives to build a fully custom popover:
|
|
|
467
505
|
|
|
468
506
|
### Primitives Reference
|
|
469
507
|
|
|
470
|
-
|
|
471
|
-
| --- | --- |
|
|
472
|
-
| `Unstable_TriggerPopoverRoot` | Root provider — groups one or more triggers, manages plugin registry |
|
|
473
|
-
| `Unstable_TriggerPopover` | Declares a trigger (id, char, adapter) and renders the popover container |
|
|
474
|
-
| `Unstable_TriggerPopover.Directive` | Behavior sub-primitive — inserts a formatted directive into the composer on selection |
|
|
475
|
-
| `Unstable_TriggerPopover.Action` | Behavior sub-primitive — runs a callback on selection; inserts a chip by default |
|
|
476
|
-
| `Unstable_TriggerPopoverCategories` | Render-function for the top-level category list |
|
|
477
|
-
| `Unstable_TriggerPopoverCategoryItem` | Button that drills into a category (`role="option"`, auto `data-highlighted`) |
|
|
478
|
-
| `Unstable_TriggerPopoverItems` | Render-function for items within the active category or search results |
|
|
479
|
-
| `Unstable_TriggerPopoverItem` | Button that selects an item (`role="option"`, auto `data-highlighted`) |
|
|
480
|
-
| `Unstable_TriggerPopoverBack` | Button that navigates back from items to categories |
|
|
481
|
-
|
|
482
|
-
See the [Composer API reference](/docs/api-reference/primitives/composer) for full prop details.
|
|
508
|
+
See the [Composer Primitives](/docs/primitives/composer) reference for the full list of trigger popover primitives and their props.
|
|
483
509
|
|
|
484
510
|
## Combining with Slash Commands
|
|
485
511
|
|
|
486
|
-
Mentions and
|
|
487
|
-
|
|
488
|
-
```tsx
|
|
489
|
-
<ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
490
|
-
<ComposerPrimitive.Root>
|
|
491
|
-
<ComposerPrimitive.Input placeholder="Type @ to mention, / for commands..." />
|
|
492
|
-
<ComposerPrimitive.Send />
|
|
493
|
-
|
|
494
|
-
{/* Mention popover (shows on @) */}
|
|
495
|
-
<ComposerPrimitive.Unstable_TriggerPopover
|
|
496
|
-
char="@"
|
|
497
|
-
adapter={mention.adapter}
|
|
498
|
-
>
|
|
499
|
-
<ComposerPrimitive.Unstable_TriggerPopover.Directive {...mention.directive} />
|
|
500
|
-
<ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
501
|
-
{(categories) => categories.map((cat) => (
|
|
502
|
-
<ComposerPrimitive.Unstable_TriggerPopoverCategoryItem key={cat.id} categoryId={cat.id}>
|
|
503
|
-
{cat.label}
|
|
504
|
-
</ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
|
|
505
|
-
))}
|
|
506
|
-
</ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
507
|
-
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
508
|
-
{(items) => items.map((item) => (
|
|
509
|
-
<ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item}>
|
|
510
|
-
{item.label}
|
|
511
|
-
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
512
|
-
))}
|
|
513
|
-
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
514
|
-
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
515
|
-
|
|
516
|
-
{/* Slash command popover (shows on /) */}
|
|
517
|
-
<ComposerPrimitive.Unstable_TriggerPopover
|
|
518
|
-
char="/"
|
|
519
|
-
adapter={slashAdapter}
|
|
520
|
-
>
|
|
521
|
-
<ComposerPrimitive.Unstable_TriggerPopover.Action
|
|
522
|
-
formatter={unstable_defaultDirectiveFormatter}
|
|
523
|
-
onExecute={(item) => commandHandlers[item.id]?.()}
|
|
524
|
-
/>
|
|
525
|
-
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
526
|
-
{(items) => items.map((item, index) => (
|
|
527
|
-
<ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item} index={index}>
|
|
528
|
-
{item.label}
|
|
529
|
-
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
530
|
-
))}
|
|
531
|
-
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
532
|
-
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
533
|
-
</ComposerPrimitive.Root>
|
|
534
|
-
</ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
Each `TriggerPopover` declares its own scope — its popover UI reads state only from that declaration, so `@` and `/` never collide.
|
|
512
|
+
Mentions and slash commands coexist on the same composer. See [Combining Slash Commands and Mentions](/docs/guides/slash-commands#combining-with-mentions) for the full pattern.
|
|
538
513
|
|
|
539
514
|
## Related
|
|
540
515
|
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Message Timing
|
|
3
|
-
description: Display stream
|
|
2
|
+
title: Message Timing & Token Stats
|
|
3
|
+
description: Display stream metadata in AI chat — generation duration, tokens per second, and time to first token, rendered via assistant-ui's React components.
|
|
4
|
+
platforms: ["react"]
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
Display stream performance metrics — duration, tokens per second, TTFT — on assistant messages.
|
|
7
8
|
|
|
9
|
+
<Callout type="warn">
|
|
10
|
+
This feature is experimental. The `useMessageTiming()` API and the set of tracked fields may change in future versions.
|
|
11
|
+
</Callout>
|
|
12
|
+
|
|
8
13
|
<Callout type="info">
|
|
9
14
|
The [`MessageTiming`](/docs/ui/message-timing) registry component provides a ready-made badge + popover UI. This guide covers the underlying `useMessageTiming()` hook for custom implementations and runtime-specific setup.
|
|
10
15
|
</Callout>
|
|
@@ -67,14 +72,15 @@ const AssistantMessage: FC = () => {
|
|
|
67
72
|
|
|
68
73
|
| Runtime | Supported | Notes |
|
|
69
74
|
|---------|:-:|-------|
|
|
70
|
-
|
|
|
75
|
+
| [Data Stream](/docs/runtimes/custom/data-stream) | Yes | Automatic via `AssistantMessageAccumulator` |
|
|
71
76
|
| AI SDK (`useChatRuntime`) | Yes | Automatic via client-side tracking |
|
|
72
77
|
| Local (`useLocalRuntime`) | Yes | Pass timing in `ChatModelRunResult.metadata` |
|
|
73
78
|
| ExternalStore | Yes | Pass timing in `ThreadMessageLike.metadata` |
|
|
74
|
-
| LangGraph |
|
|
75
|
-
| AG-UI |
|
|
79
|
+
| LangGraph | Yes | Automatic via client-side tracking |
|
|
80
|
+
| AG-UI | Yes | Automatic via client-side tracking |
|
|
81
|
+
| OpenCode | Yes | Automatic via client-side tracking |
|
|
76
82
|
|
|
77
|
-
###
|
|
83
|
+
### Data Stream
|
|
78
84
|
|
|
79
85
|
Timing is tracked automatically inside `AssistantMessageAccumulator`. No setup required.
|
|
80
86
|
|
|
@@ -157,6 +163,39 @@ const message: ThreadMessageLike = {
|
|
|
157
163
|
};
|
|
158
164
|
```
|
|
159
165
|
|
|
166
|
+
### LangGraph (`useLangGraphRuntime`)
|
|
167
|
+
|
|
168
|
+
Timing is tracked automatically on the client side by observing streaming state transitions and `LangChainMessage` content changes. No setup required.
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";
|
|
172
|
+
|
|
173
|
+
const runtime = useLangGraphRuntime({ stream: myStream });
|
|
174
|
+
// useMessageTiming() works out of the box
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### AG-UI (`useAgUiThreadRuntime`)
|
|
178
|
+
|
|
179
|
+
Timing is tracked automatically on the client side by the AG-UI run aggregator. Each emitted message includes timing metadata computed from stream chunk observations.
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
import { useAgUiThreadRuntime } from "@assistant-ui/react-ag-ui";
|
|
183
|
+
|
|
184
|
+
const runtime = useAgUiThreadRuntime({ runtimeUrl: "..." });
|
|
185
|
+
// useMessageTiming() works out of the box
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### OpenCode (`useOpenCodeRuntime`)
|
|
189
|
+
|
|
190
|
+
Timing is tracked automatically on the client side by observing `OpenCodeThreadState` transitions and assistant message content deltas. No setup required.
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { useOpenCodeRuntime } from "@assistant-ui/react-opencode";
|
|
194
|
+
|
|
195
|
+
const runtime = useOpenCodeRuntime();
|
|
196
|
+
// useMessageTiming() works out of the box
|
|
197
|
+
```
|
|
198
|
+
|
|
160
199
|
## API Reference
|
|
161
200
|
|
|
162
201
|
### `useMessageTiming()`
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Multi-Agent
|
|
3
|
-
description: Render sub-agent conversations inside tool
|
|
2
|
+
title: Multi-Agent Chat UI
|
|
3
|
+
description: Render sub-agent conversations and handoffs inside tool calls. Build supervisor and multi-agent patterns in a React chat UI with assistant-ui.
|
|
4
|
+
platforms: ["react"]
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
In a multi-agent (orchestrator) architecture, a main agent invokes sub-agents via tool calls. Each sub-agent may produce its own conversation (user/assistant messages, tool calls, etc.). assistant-ui supports rendering these nested conversations using the `MessagePartPrimitive.Messages` primitive.
|
|
@@ -51,7 +52,10 @@ const ResearchAgentToolUI = makeAssistantToolUI({
|
|
|
51
52
|
|
|
52
53
|
### Provide the Messages from the Backend
|
|
53
54
|
|
|
54
|
-
Your backend must populate the `messages` field on the tool call result.
|
|
55
|
+
Your backend must populate the `messages` field on the tool call result.
|
|
56
|
+
|
|
57
|
+
<Tabs items={["AI SDK", "LangGraph"]}>
|
|
58
|
+
<Tab value="AI SDK">
|
|
55
59
|
|
|
56
60
|
```ts title="api/chat/route.ts"
|
|
57
61
|
tools: {
|
|
@@ -62,7 +66,6 @@ tools: {
|
|
|
62
66
|
const subAgentMessages = await runResearcherAgent(query);
|
|
63
67
|
return {
|
|
64
68
|
answer: subAgentMessages.at(-1)?.content,
|
|
65
|
-
// The messages field is picked up by assistant-ui
|
|
66
69
|
messages: subAgentMessages,
|
|
67
70
|
};
|
|
68
71
|
},
|
|
@@ -70,9 +73,53 @@ tools: {
|
|
|
70
73
|
},
|
|
71
74
|
```
|
|
72
75
|
|
|
76
|
+
</Tab>
|
|
77
|
+
<Tab value="LangGraph">
|
|
78
|
+
|
|
79
|
+
With `@assistant-ui/react-langgraph`, use `unstable_createLangGraphStream` and set `unstable_allowCancellation: true` to wire up the stop button. When your graph runs a subgraph, the subgraph's messages appear on `ToolCallMessagePart.messages` automatically once you handle the `onSubgraphValues` / `onSubgraphUpdates` events.
|
|
80
|
+
|
|
81
|
+
```ts title="runtime.ts"
|
|
82
|
+
import {
|
|
83
|
+
useLangGraphRuntime,
|
|
84
|
+
unstable_createLangGraphStream,
|
|
85
|
+
} from "@assistant-ui/react-langgraph";
|
|
86
|
+
|
|
87
|
+
const runtime = useLangGraphRuntime({
|
|
88
|
+
unstable_allowCancellation: true,
|
|
89
|
+
stream: unstable_createLangGraphStream({
|
|
90
|
+
client,
|
|
91
|
+
assistantId,
|
|
92
|
+
// "custom" is required for generative UI; "updates" for subgraph events
|
|
93
|
+
streamMode: ["messages", "updates", "custom"],
|
|
94
|
+
// abort the run server-side when the user clicks stop
|
|
95
|
+
onDisconnect: "cancel",
|
|
96
|
+
}),
|
|
97
|
+
eventHandlers: {
|
|
98
|
+
onSubgraphValues: (namespace, values) => {
|
|
99
|
+
// namespace = e.g. "tools:call_abc" — the sub-agent's node path
|
|
100
|
+
// values contains the subgraph state, including its messages array
|
|
101
|
+
},
|
|
102
|
+
onSubgraphUpdates: (namespace, updates) => {
|
|
103
|
+
// incremental state updates from the subgraph
|
|
104
|
+
},
|
|
105
|
+
onSubgraphError: (namespace, error) => {
|
|
106
|
+
// error scoped to the subgraph; does not mark the parent message failed
|
|
107
|
+
},
|
|
108
|
+
onMessageChunk: (chunk, metadata) => {
|
|
109
|
+
// metadata.namespace is set when the chunk originates from a subgraph
|
|
110
|
+
// use it to attribute the chunk to the correct sub-agent
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
See [LangGraph Streaming](/docs/runtimes/langgraph/streaming) for the full event handler reference.
|
|
117
|
+
|
|
118
|
+
</Tab>
|
|
119
|
+
</Tabs>
|
|
120
|
+
|
|
73
121
|
<Callout type="info">
|
|
74
|
-
The
|
|
75
|
-
framework. The key requirement is that the tool result's corresponding
|
|
122
|
+
The key requirement is that the tool result's corresponding
|
|
76
123
|
`ToolCallMessagePart` includes a `messages` array of `ThreadMessage` objects.
|
|
77
124
|
</Callout>
|
|
78
125
|
|
|
@@ -95,6 +142,17 @@ function App() {
|
|
|
95
142
|
</Step>
|
|
96
143
|
</Steps>
|
|
97
144
|
|
|
145
|
+
## Subgraph Namespace Events
|
|
146
|
+
|
|
147
|
+
When using LangGraph, subgraph events carry a `namespace` that identifies which sub-agent emitted them. This lets you attribute messages and state to specific sub-agents without polling or manual coordination.
|
|
148
|
+
|
|
149
|
+
- `onSubgraphValues(namespace, values)` fires when a subgraph emits a full state snapshot. Use the `values.messages` array to populate `ToolCallMessagePart.messages` for that sub-agent.
|
|
150
|
+
- `onSubgraphUpdates(namespace, updates)` fires for incremental state patches from a subgraph.
|
|
151
|
+
- `onSubgraphError(namespace, error)` fires when a subgraph fails. The parent message is not marked incomplete; only top-level errors trigger that.
|
|
152
|
+
- `onMessageChunk(chunk, metadata)` includes `metadata.namespace` when the chunk originates from a subgraph. Use this to display per-sub-agent streaming indicators.
|
|
153
|
+
|
|
154
|
+
The `namespace` value mirrors the pipe-separated suffix on the LangGraph event name (e.g. `values|tools:call_abc` gives `"tools:call_abc"`).
|
|
155
|
+
|
|
98
156
|
## Recursive Sub-Agents
|
|
99
157
|
|
|
100
158
|
If a sub-agent's tool calls also have nested messages, the same pattern applies recursively:
|
|
@@ -172,3 +230,5 @@ function SubConversation({
|
|
|
172
230
|
- [Generative UI](/docs/guides/tool-ui) — Creating tool call UIs
|
|
173
231
|
- [MessagePartPrimitive](/docs/api-reference/primitives/message-part) — API reference for message part primitives
|
|
174
232
|
- [Sub-Agent Model Tracking](/docs/cloud/ai-sdk#sub-agent-model-tracking) — Track delegated model usage and costs in the Cloud dashboard
|
|
233
|
+
- [LangGraph Streaming](/docs/runtimes/langgraph/streaming) — Event handlers, subgraph events, and message metadata
|
|
234
|
+
- [LangGraph Generative UI](/docs/runtimes/langgraph/generative-ui) — Structured UI components emitted by your graph
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Quote Selected Text
|
|
3
|
-
description: Let users select and quote
|
|
3
|
+
description: Let users select text from AI messages and quote it back into the composer. Full quoting flow with backend handling and programmatic API in assistant-ui.
|
|
4
|
+
platforms: ["react"]
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
import { QuoteComposerSample } from "@/components/docs/samples/quote-composer";
|
|
@@ -9,17 +10,11 @@ import { QuoteComposerSample } from "@/components/docs/samples/quote-composer";
|
|
|
9
10
|
|
|
10
11
|
## Get Started
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
Install and wire up the `quote` registry component by following the [Quote component page](/docs/ui/quote). It covers the install command, component placement, and the `injectQuoteContext` helper for forwarding quote data to the LLM.
|
|
13
14
|
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- **QuoteBlock** renders quoted text inline in user messages
|
|
19
|
-
- **SelectionToolbar** is a floating toolbar that appears on text selection
|
|
20
|
-
- **ComposerQuotePreview** shows the pending quote inside the composer
|
|
21
|
-
|
|
22
|
-
See the [Quote component page](/docs/ui/quote) for full setup steps and API reference.
|
|
15
|
+
<Callout type="warn">
|
|
16
|
+
**Limitations:** only one quote can be active at a time. `setQuote` replaces the previous quote instead of appending. The floating toolbar only appears when the selection is entirely within a single message part; cross-message and cross-part selections are ignored.
|
|
17
|
+
</Callout>
|
|
23
18
|
|
|
24
19
|
---
|
|
25
20
|
|
|
@@ -132,7 +127,7 @@ function CustomQuoteDisplay() {
|
|
|
132
127
|
|
|
133
128
|
## Programmatic API
|
|
134
129
|
|
|
135
|
-
Set or clear quotes via
|
|
130
|
+
Set or clear quotes via `useAui` from `@assistant-ui/react`. Call `aui.thread().composer().setQuote()` when your component is rendered outside of a specific thread context, or `aui.composer().setQuote()` when it is rendered inside a thread:
|
|
136
131
|
|
|
137
132
|
```tsx
|
|
138
133
|
import { useAui } from "@assistant-ui/react";
|
|
@@ -162,12 +157,10 @@ function MyComponent() {
|
|
|
162
157
|
|
|
163
158
|
## Design Notes
|
|
164
159
|
|
|
165
|
-
- **
|
|
166
|
-
- **
|
|
167
|
-
-
|
|
168
|
-
- **
|
|
169
|
-
- **`isEmpty` unchanged:** A quote by itself does not make the composer non-empty. The user still needs to type a reply.
|
|
170
|
-
- **Scroll hides toolbar:** The toolbar hides on scroll because its position would otherwise become stale.
|
|
160
|
+
- **snapshot text:** the selected text is captured when the quote is created and is not linked to the source message afterward.
|
|
161
|
+
- **streaming messages:** the toolbar still works while a message is streaming because it relies on the captured selection rather than message status.
|
|
162
|
+
- **`isEmpty` unchanged:** a quote by itself does not make the composer non-empty; the user still needs to type a reply.
|
|
163
|
+
- **scroll hides toolbar:** the toolbar hides on scroll because its position would otherwise become stale.
|
|
171
164
|
|
|
172
165
|
## Related
|
|
173
166
|
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Resumable Stream Deployment
|
|
3
|
+
description: Production hardening for resumable streams. Authorization, serverless lifetimes, TTLs, key isolation, observability, resource limits, and incident response.
|
|
4
|
+
platforms: ["react"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
This guide assumes you have the basic wiring from [Resumable Streams](/docs/guides/resumable-streams) in place and focuses on what to add before serving production traffic.
|
|
8
|
+
|
|
9
|
+
## Authentication and authorization
|
|
10
|
+
|
|
11
|
+
The default resume endpoint serves any caller that knows the `streamId`. Treat the id as opaque, not as a credential. Bind every newly created `streamId` to the requesting user at acquire time and verify the binding on every resume.
|
|
12
|
+
|
|
13
|
+
Store the binding next to the rest of your session state, or in Redis under a separate key. The example below uses a parallel `<keyPrefix>:owner:<streamId>` entry that mirrors the TTL of the underlying stream.
|
|
14
|
+
|
|
15
|
+
```ts title="/lib/resumable-context.ts"
|
|
16
|
+
import { createResumableStreamContext } from "assistant-stream/resumable";
|
|
17
|
+
import { redis } from "@/lib/redis";
|
|
18
|
+
import { store } from "@/lib/resumable-store";
|
|
19
|
+
|
|
20
|
+
const OWNER_PREFIX = "aui:resumable:owner";
|
|
21
|
+
const OWNER_TTL_SEC = 24 * 60 * 60;
|
|
22
|
+
|
|
23
|
+
export const resumableContext = createResumableStreamContext({ store });
|
|
24
|
+
|
|
25
|
+
export async function bindStreamToUser(streamId: string, userId: string) {
|
|
26
|
+
await redis.set(`${OWNER_PREFIX}:${streamId}`, userId, { EX: OWNER_TTL_SEC });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function assertStreamOwner(streamId: string, userId: string) {
|
|
30
|
+
const owner = await redis.get(`${OWNER_PREFIX}:${streamId}`);
|
|
31
|
+
if (owner !== userId) {
|
|
32
|
+
throw new Response("Not Found", { status: 404 });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Wrap `resume` with the ownership check. Returning 404 (not 403) avoids confirming the existence of a stream the caller does not own.
|
|
38
|
+
|
|
39
|
+
```ts title="/app/api/chat/resume/[streamId]/route.ts"
|
|
40
|
+
import { assertStreamOwner, resumableContext } from "@/lib/resumable-context";
|
|
41
|
+
import { getSessionUserId } from "@/lib/auth";
|
|
42
|
+
|
|
43
|
+
export async function GET(
|
|
44
|
+
req: Request,
|
|
45
|
+
ctx: { params: Promise<{ streamId: string }> },
|
|
46
|
+
) {
|
|
47
|
+
const userId = await getSessionUserId(req);
|
|
48
|
+
if (!userId) return new Response("Unauthorized", { status: 401 });
|
|
49
|
+
|
|
50
|
+
const { streamId } = await ctx.params;
|
|
51
|
+
await assertStreamOwner(streamId, userId);
|
|
52
|
+
|
|
53
|
+
const stream = await resumableContext.resume(streamId);
|
|
54
|
+
if (!stream) return new Response("Not Found", { status: 404 });
|
|
55
|
+
|
|
56
|
+
return new Response(stream, {
|
|
57
|
+
headers: { "Content-Type": "text/event-stream" },
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## `waitUntil` on serverless
|
|
63
|
+
|
|
64
|
+
On Vercel and Cloudflare the request handler is torn down once the response is returned, taking the producer task with it. Without a `waitUntil` hook the persisted stream stops growing the moment the originating request unwinds, so reconnects only see the bytes that happened to land before the response flushed.
|
|
65
|
+
|
|
66
|
+
On Vercel, pass `after` from `next/server`:
|
|
67
|
+
|
|
68
|
+
```ts title="/lib/resumable-context.ts"
|
|
69
|
+
import { after } from "next/server";
|
|
70
|
+
import { createResumableStreamContext } from "assistant-stream/resumable";
|
|
71
|
+
import { store } from "@/lib/resumable-store";
|
|
72
|
+
|
|
73
|
+
export const resumableContext = createResumableStreamContext({
|
|
74
|
+
store,
|
|
75
|
+
waitUntil: after,
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
On Cloudflare Workers, take the `ExecutionContext` from your handler and forward `ctx.waitUntil`:
|
|
80
|
+
|
|
81
|
+
```ts title="/src/worker.ts"
|
|
82
|
+
import { createResumableStreamContext } from "assistant-stream/resumable";
|
|
83
|
+
import { store } from "./resumable-store";
|
|
84
|
+
|
|
85
|
+
export default {
|
|
86
|
+
async fetch(req: Request, env: Env, ctx: ExecutionContext) {
|
|
87
|
+
const resumableContext = createResumableStreamContext({
|
|
88
|
+
store,
|
|
89
|
+
waitUntil: (promise) => ctx.waitUntil(promise),
|
|
90
|
+
});
|
|
91
|
+
return handle(req, resumableContext);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
In long-lived Node servers (a custom Express app, a container) `waitUntil` can be omitted; the producer task runs on the same event loop as the handler and is not preempted.
|
|
97
|
+
|
|
98
|
+
## TTL strategy
|
|
99
|
+
|
|
100
|
+
Streams expire 24 hours after the last write. The default suits typical chat workloads where a user might reload after lunch, but every deployment should pick a number deliberately.
|
|
101
|
+
|
|
102
|
+
- Shorten when chunks contain sensitive payloads (PII, drafts, internal documents). A 5 to 30 minute window usually covers reload survival without leaving recoverable bytes around.
|
|
103
|
+
- Extend for long-running agent tasks that may legitimately stretch past a day. Set the TTL above the worst-case task duration so the producer can still finalize.
|
|
104
|
+
- Match TTLs across layers. The store TTL, the owner-binding TTL, and any signed cookie that references `streamId` should expire together; otherwise one outlives the other and either leaks or 404s unexpectedly.
|
|
105
|
+
|
|
106
|
+
Configure on the store for the global default and on the context for a per-deployment override:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import {
|
|
110
|
+
createInMemoryResumableStreamStore,
|
|
111
|
+
createResumableStreamContext,
|
|
112
|
+
} from "assistant-stream/resumable";
|
|
113
|
+
|
|
114
|
+
const store = createInMemoryResumableStreamStore({
|
|
115
|
+
defaultTtlMs: 30 * 60 * 1000,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
export const resumableContext = createResumableStreamContext({
|
|
119
|
+
store,
|
|
120
|
+
ttlMs: 30 * 60 * 1000,
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The Redis adapters accept the same `defaultTtlMs` option.
|
|
125
|
+
|
|
126
|
+
## Multi-tenant key isolation
|
|
127
|
+
|
|
128
|
+
When multiple apps or tenants share a Redis instance, set `keyPrefix` per environment so a misconfigured stream in one tenant cannot collide with, or be deleted alongside, another's. The prefix becomes the leading segment of every meta and data key.
|
|
129
|
+
|
|
130
|
+
```ts title="/lib/resumable-store.ts"
|
|
131
|
+
import { createClient } from "redis";
|
|
132
|
+
import { createRedisResumableStreamStore } from "assistant-stream/resumable/redis";
|
|
133
|
+
|
|
134
|
+
const client = createClient({ url: process.env.REDIS_URL });
|
|
135
|
+
await client.connect();
|
|
136
|
+
|
|
137
|
+
export const store = createRedisResumableStreamStore(client, {
|
|
138
|
+
keyPrefix: `aui:${process.env.APP_NAME}:${process.env.TENANT_ID}`,
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Per-tenant prefixes also make incident response cheaper. A `SCAN MATCH aui:app:tenant-42:*` lets you audit or purge a single tenant without touching the rest.
|
|
143
|
+
|
|
144
|
+
## Observability hooks
|
|
145
|
+
|
|
146
|
+
`ResumableStreamContextOptions` exposes lifecycle hooks for structured logging, metrics, and tracing. Each hook is invoked synchronously around the underlying store call; throwing inside a hook surfaces as a producer error.
|
|
147
|
+
|
|
148
|
+
```ts title="/lib/resumable-context.ts"
|
|
149
|
+
import { createResumableStreamContext } from "assistant-stream/resumable";
|
|
150
|
+
import { logger, metrics } from "@/lib/observability";
|
|
151
|
+
import { store } from "@/lib/resumable-store";
|
|
152
|
+
|
|
153
|
+
export const resumableContext = createResumableStreamContext({
|
|
154
|
+
store,
|
|
155
|
+
onAcquire: (streamId, role) => {
|
|
156
|
+
metrics.increment("resumable.acquire", { role });
|
|
157
|
+
logger.info("resumable.acquire", { streamId, role });
|
|
158
|
+
},
|
|
159
|
+
onAppend: (streamId, byteLength) => {
|
|
160
|
+
metrics.histogram("resumable.append.bytes", byteLength);
|
|
161
|
+
},
|
|
162
|
+
onFinalize: (streamId, status, error) => {
|
|
163
|
+
metrics.increment("resumable.finalize", { status });
|
|
164
|
+
logger.info("resumable.finalize", { streamId, status, error });
|
|
165
|
+
},
|
|
166
|
+
onError: (streamId, error) => {
|
|
167
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
168
|
+
logger.error("resumable.error", { streamId, error: message });
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Keep hook bodies cheap. They run on the producer's hot path and any latency they add becomes streaming latency seen by the client.
|
|
174
|
+
|
|
175
|
+
## Resource limits
|
|
176
|
+
|
|
177
|
+
The in-memory store enforces three caps that the Redis adapters intentionally leave to the underlying database. Set them whenever your process can be reached by untrusted callers.
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
import { createInMemoryResumableStreamStore } from "assistant-stream/resumable";
|
|
181
|
+
|
|
182
|
+
const store = createInMemoryResumableStreamStore({
|
|
183
|
+
maxChunkBytes: 64 * 1024,
|
|
184
|
+
maxEntriesPerStream: 5000,
|
|
185
|
+
maxStreams: 10_000,
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
- `maxChunkBytes` rejects oversized writes from a misbehaving producer (a runaway tool result, a base64 blob accidentally piped through). The producer task fails fast instead of pinning memory.
|
|
190
|
+
- `maxEntriesPerStream` caps the per-stream entry count. This bounds how much any single stream can grow before it starts erroring; pair it with TTLs so finalized streams clear quickly.
|
|
191
|
+
- `maxStreams` caps total live streams. Useful as a backstop in shared development environments and in single-tenant containers; in serverless deployments the platform already constrains concurrency.
|
|
192
|
+
|
|
193
|
+
These limits exist on the in-memory store. For Redis, configure `maxmemory` and an eviction policy on the server, and rely on application-level rate limiting upstream.
|
|
194
|
+
|
|
195
|
+
## Incident response
|
|
196
|
+
|
|
197
|
+
The streamId leaks through response headers, browser session storage, server access logs, and (in some setups) error reports. If you suspect any of those channels were compromised, treat all in-flight stream ids as exposed.
|
|
198
|
+
|
|
199
|
+
What to log up front, so you have it when you need it:
|
|
200
|
+
|
|
201
|
+
- The acquiring user id, request id, and IP for every `acquire` call (via `onAcquire`).
|
|
202
|
+
- The finalize status (and any error) for every stream (via `onFinalize`).
|
|
203
|
+
- The owner-binding writes and reads, with the user id and the streamId.
|
|
204
|
+
|
|
205
|
+
What to rotate or invalidate during an incident:
|
|
206
|
+
|
|
207
|
+
- Bump `keyPrefix` on the store. Existing streams become unreachable and new ones land under the rotated namespace.
|
|
208
|
+
- Invalidate signed session cookies that reference any cached streamId.
|
|
209
|
+
- Drop the owner-binding keys for affected users (`DEL aui:resumable:owner:*` scoped by user) so resumes are forced through a fresh acquire.
|
|
210
|
+
- Shorten `defaultTtlMs` temporarily so any orphaned stream rolls off quickly.
|
|
211
|
+
|
|
212
|
+
After rotation, reissue stream ids server-side and redirect clients through a fresh acquire; do not trust any streamId the client already holds.
|