@assistant-ui/mcp-docs-server 0.2.3 → 0.3.0
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/README.md +16 -43
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -91
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +9 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +76 -0
- package/dist/proxy.js.map +1 -0
- package/package.json +8 -12
- package/src/index.ts +3 -115
- package/src/proxy.test.ts +250 -0
- package/src/proxy.ts +111 -0
- package/.docs/organized/code-examples/waterfall.md +0 -807
- package/.docs/organized/code-examples/with-a2a.md +0 -675
- package/.docs/organized/code-examples/with-ag-ui.md +0 -553
- package/.docs/organized/code-examples/with-ai-sdk-v7.md +0 -466
- package/.docs/organized/code-examples/with-artifacts.md +0 -815
- package/.docs/organized/code-examples/with-assistant-transport.md +0 -576
- package/.docs/organized/code-examples/with-browser-extension.md +0 -371
- package/.docs/organized/code-examples/with-chain-of-thought.md +0 -962
- package/.docs/organized/code-examples/with-cloud-standalone.md +0 -681
- package/.docs/organized/code-examples/with-cloud.md +0 -439
- package/.docs/organized/code-examples/with-custom-thread-list.md +0 -569
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +0 -527
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +0 -697
- package/.docs/organized/code-examples/with-eve.md +0 -405
- package/.docs/organized/code-examples/with-expo.md +0 -2246
- package/.docs/organized/code-examples/with-external-store.md +0 -421
- package/.docs/organized/code-examples/with-ffmpeg.md +0 -829
- package/.docs/organized/code-examples/with-generative-ui.md +0 -1810
- package/.docs/organized/code-examples/with-google-adk.md +0 -368
- package/.docs/organized/code-examples/with-heat-graph.md +0 -304
- package/.docs/organized/code-examples/with-image-generation.md +0 -463
- package/.docs/organized/code-examples/with-interactables.md +0 -733
- package/.docs/organized/code-examples/with-langchain.md +0 -446
- package/.docs/organized/code-examples/with-langgraph.md +0 -855
- package/.docs/organized/code-examples/with-livekit.md +0 -643
- package/.docs/organized/code-examples/with-mcp.md +0 -782
- package/.docs/organized/code-examples/with-nuxt.md +0 -2428
- package/.docs/organized/code-examples/with-opencode.md +0 -1974
- package/.docs/organized/code-examples/with-openui.md +0 -450
- package/.docs/organized/code-examples/with-pi.md +0 -2084
- package/.docs/organized/code-examples/with-react-hook-form.md +0 -727
- package/.docs/organized/code-examples/with-react-ink-web.md +0 -740
- package/.docs/organized/code-examples/with-react-ink.md +0 -473
- package/.docs/organized/code-examples/with-react-router.md +0 -936
- package/.docs/organized/code-examples/with-resumable-stream.md +0 -668
- package/.docs/organized/code-examples/with-store.md +0 -679
- package/.docs/organized/code-examples/with-svelte.md +0 -415
- package/.docs/organized/code-examples/with-sveltekit.md +0 -1061
- package/.docs/organized/code-examples/with-tanstack.md +0 -812
- package/.docs/organized/code-examples/with-tap-runtime.md +0 -813
- package/.docs/organized/code-examples/with-virtualized-thread.md +0 -681
- package/.docs/organized/code-examples/with-vue.md +0 -408
- package/.docs/raw/docs/(getting-started)/architecture.mdx +0 -146
- package/.docs/raw/docs/(getting-started)/base-ui.mdx +0 -39
- package/.docs/raw/docs/(getting-started)/cli.mdx +0 -542
- package/.docs/raw/docs/(getting-started)/devtools.mdx +0 -79
- package/.docs/raw/docs/(getting-started)/index.mdx +0 -23
- package/.docs/raw/docs/(getting-started)/installation.mdx +0 -483
- package/.docs/raw/docs/(getting-started)/llm.mdx +0 -211
- package/.docs/raw/docs/(getting-started)/rtl.mdx +0 -78
- package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +0 -36
- package/.docs/raw/docs/(reference)/api-reference/adapters/feedback.mdx +0 -20
- package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +0 -34
- package/.docs/raw/docs/(reference)/api-reference/adapters/model.mdx +0 -44
- package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +0 -59
- package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +0 -20
- package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +0 -26
- package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +0 -84
- package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +0 -22
- package/.docs/raw/docs/(reference)/api-reference/context-providers/scoped-providers.mdx +0 -64
- package/.docs/raw/docs/(reference)/api-reference/external-store/index.mdx +0 -22
- package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +0 -57
- package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +0 -49
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/a2ui.mdx +0 -40
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/actions.mdx +0 -56
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/components.mdx +0 -86
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +0 -39
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/json-generative-ui.mdx +0 -42
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +0 -84
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/slack.mdx +0 -85
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/spec.mdx +0 -45
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/teams.mdx +0 -93
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/tokens.mdx +0 -62
- package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +0 -129
- package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +0 -31
- package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +0 -34
- package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +0 -350
- package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +0 -28
- package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +0 -97
- package/.docs/raw/docs/(reference)/api-reference/integrations/ai-sdk.mdx +0 -200
- package/.docs/raw/docs/(reference)/api-reference/integrations/cloud-ai-sdk.mdx +0 -24
- package/.docs/raw/docs/(reference)/api-reference/integrations/eve.mdx +0 -118
- package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +0 -28
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +0 -37
- package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +0 -50
- package/.docs/raw/docs/(reference)/api-reference/model-context/index.mdx +0 -22
- package/.docs/raw/docs/(reference)/api-reference/model-context/registry.mdx +0 -20
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +0 -566
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +0 -152
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +0 -239
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +0 -208
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +0 -108
- package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +0 -99
- package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +0 -145
- package/.docs/raw/docs/(reference)/api-reference/primitives/chain-of-thought.mdx +0 -82
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +0 -637
- package/.docs/raw/docs/(reference)/api-reference/primitives/composition.mdx +0 -22
- package/.docs/raw/docs/(reference)/api-reference/primitives/error.mdx +0 -65
- package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +0 -73
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +0 -117
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +0 -339
- package/.docs/raw/docs/(reference)/api-reference/primitives/queue-item.mdx +0 -77
- package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +0 -88
- package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +0 -81
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item-more.mdx +0 -129
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +0 -138
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +0 -122
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +0 -289
- package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +0 -20
- package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +0 -24
- package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +0 -32
- package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +0 -43
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +0 -43
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +0 -24
- package/.docs/raw/docs/(reference)/api-reference/runtimes/queue-state.mdx +0 -20
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +0 -24
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +0 -24
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +0 -36
- package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +0 -85
- package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +0 -45
- package/.docs/raw/docs/(reference)/api-reference/tools/interactables-legacy.mdx +0 -55
- package/.docs/raw/docs/(reference)/api-reference/tools/interactables.mdx +0 -151
- package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +0 -106
- package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +0 -62
- package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +0 -178
- package/.docs/raw/docs/(reference)/api-reference/transport/assistant-transport.mdx +0 -48
- package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +0 -62
- package/.docs/raw/docs/(reference)/api-reference/transport/index.mdx +0 -22
- package/.docs/raw/docs/(reference)/api-reference/utilities/index.mdx +0 -19
- package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +0 -152
- package/.docs/raw/docs/(reference)/api-reference/voice/index.mdx +0 -22
- package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +0 -54
- package/.docs/raw/docs/(reference)/api-reference/voice/speech-dictation.mdx +0 -36
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +0 -527
- package/.docs/raw/docs/cloud/ai-sdk.mdx +0 -604
- package/.docs/raw/docs/cloud/authorization.mdx +0 -252
- package/.docs/raw/docs/cloud/index.mdx +0 -46
- package/.docs/raw/docs/cloud/langgraph.mdx +0 -554
- package/.docs/raw/docs/copilots/assistant-frame.mdx +0 -411
- package/.docs/raw/docs/copilots/make-assistant-visible.mdx +0 -82
- package/.docs/raw/docs/copilots/model-context.mdx +0 -156
- package/.docs/raw/docs/copilots/motivation.mdx +0 -202
- package/.docs/raw/docs/copilots/use-assistant-instructions.mdx +0 -64
- package/.docs/raw/docs/guides/attachments.mdx +0 -619
- package/.docs/raw/docs/guides/branching.mdx +0 -76
- package/.docs/raw/docs/guides/chain-of-thought.mdx +0 -164
- package/.docs/raw/docs/guides/chatgpt-subscription.mdx +0 -108
- package/.docs/raw/docs/guides/context-api.mdx +0 -619
- package/.docs/raw/docs/guides/dictation.mdx +0 -298
- package/.docs/raw/docs/guides/editing.mdx +0 -102
- package/.docs/raw/docs/guides/electron.mdx +0 -369
- package/.docs/raw/docs/guides/headless-composer-input.mdx +0 -113
- package/.docs/raw/docs/guides/image-generation.mdx +0 -74
- package/.docs/raw/docs/guides/index.mdx +0 -117
- package/.docs/raw/docs/guides/input-history.mdx +0 -55
- package/.docs/raw/docs/guides/latex.mdx +0 -158
- package/.docs/raw/docs/guides/mentions.mdx +0 -575
- package/.docs/raw/docs/guides/message-timing.mdx +0 -215
- package/.docs/raw/docs/guides/quoting.mdx +0 -169
- package/.docs/raw/docs/guides/resumable-stream-deployment.mdx +0 -212
- package/.docs/raw/docs/guides/resumable-stream-stores.mdx +0 -152
- package/.docs/raw/docs/guides/resumable-streams.mdx +0 -292
- package/.docs/raw/docs/guides/slash-commands.mdx +0 -358
- package/.docs/raw/docs/guides/speech.mdx +0 -172
- package/.docs/raw/docs/guides/suggestions.mdx +0 -384
- package/.docs/raw/docs/guides/virtualization.mdx +0 -133
- package/.docs/raw/docs/guides/voice.mdx +0 -310
- package/.docs/raw/docs/ink/adapters.mdx +0 -99
- package/.docs/raw/docs/ink/custom-backend.mdx +0 -254
- package/.docs/raw/docs/ink/hooks.mdx +0 -469
- package/.docs/raw/docs/ink/index.mdx +0 -237
- package/.docs/raw/docs/ink/migration.mdx +0 -138
- package/.docs/raw/docs/ink/primitives.mdx +0 -1259
- package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +0 -528
- package/.docs/raw/docs/integrations/auth/better-auth.mdx +0 -188
- package/.docs/raw/docs/integrations/auth/clerk.mdx +0 -166
- package/.docs/raw/docs/integrations/auth/next-auth.mdx +0 -191
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +0 -88
- package/.docs/raw/docs/integrations/frameworks/cloudflare-agents.mdx +0 -283
- package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +0 -188
- package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +0 -57
- package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +0 -201
- package/.docs/raw/docs/integrations/gateways/index.mdx +0 -162
- package/.docs/raw/docs/integrations/index.mdx +0 -178
- package/.docs/raw/docs/integrations/observability/helicone.mdx +0 -129
- package/.docs/raw/docs/integrations/observability/langfuse.mdx +0 -161
- package/.docs/raw/docs/integrations/observability/langsmith.mdx +0 -151
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +0 -773
- package/.docs/raw/docs/migrations/deprecation-policy.mdx +0 -42
- package/.docs/raw/docs/migrations/index.mdx +0 -50
- package/.docs/raw/docs/migrations/react-compatibility.mdx +0 -74
- package/.docs/raw/docs/migrations/react-langgraph-v0-7.mdx +0 -328
- package/.docs/raw/docs/migrations/toolkit-tools.mdx +0 -236
- package/.docs/raw/docs/migrations/v0-11.mdx +0 -172
- package/.docs/raw/docs/migrations/v0-12.mdx +0 -302
- package/.docs/raw/docs/migrations/v0-14.mdx +0 -297
- package/.docs/raw/docs/migrations/v0-15.mdx +0 -270
- package/.docs/raw/docs/primitives/action-bar.mdx +0 -352
- package/.docs/raw/docs/primitives/assistant-modal.mdx +0 -216
- package/.docs/raw/docs/primitives/attachment.mdx +0 -217
- package/.docs/raw/docs/primitives/branch-picker.mdx +0 -222
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +0 -315
- package/.docs/raw/docs/primitives/composer.mdx +0 -659
- package/.docs/raw/docs/primitives/error.mdx +0 -142
- package/.docs/raw/docs/primitives/index.mdx +0 -99
- package/.docs/raw/docs/primitives/message.mdx +0 -618
- package/.docs/raw/docs/primitives/selection-toolbar.mdx +0 -191
- package/.docs/raw/docs/primitives/suggestion.mdx +0 -254
- package/.docs/raw/docs/primitives/thread-list.mdx +0 -467
- package/.docs/raw/docs/primitives/thread.mdx +0 -509
- package/.docs/raw/docs/react-native/adapters.mdx +0 -94
- package/.docs/raw/docs/react-native/custom-backend.mdx +0 -207
- package/.docs/raw/docs/react-native/hooks.mdx +0 -339
- package/.docs/raw/docs/react-native/index.mdx +0 -289
- package/.docs/raw/docs/react-native/migration.mdx +0 -142
- package/.docs/raw/docs/react-native/primitives.mdx +0 -976
- package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +0 -399
- package/.docs/raw/docs/runtimes/a2a/overview.mdx +0 -60
- package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +0 -216
- package/.docs/raw/docs/runtimes/ag-ui/agent-state.mdx +0 -124
- package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +0 -70
- package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +0 -243
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +0 -267
- package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +0 -61
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +0 -122
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +0 -135
- package/.docs/raw/docs/runtimes/ai-sdk/v6-legacy.mdx +0 -636
- package/.docs/raw/docs/runtimes/ai-sdk/v7.mdx +0 -731
- package/.docs/raw/docs/runtimes/claude-managed-agents.mdx +0 -118
- package/.docs/raw/docs/runtimes/concepts/adapters.mdx +0 -265
- package/.docs/raw/docs/runtimes/concepts/architecture.mdx +0 -167
- package/.docs/raw/docs/runtimes/concepts/stability.mdx +0 -68
- package/.docs/raw/docs/runtimes/concepts/threads.mdx +0 -513
- package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +0 -763
- package/.docs/raw/docs/runtimes/custom/data-stream.mdx +0 -339
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +0 -957
- package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +0 -902
- package/.docs/raw/docs/runtimes/custom/overview.mdx +0 -71
- package/.docs/raw/docs/runtimes/eve/overview.mdx +0 -151
- package/.docs/raw/docs/runtimes/eve/quickstart.mdx +0 -192
- package/.docs/raw/docs/runtimes/google-adk/api.mdx +0 -256
- package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +0 -784
- package/.docs/raw/docs/runtimes/google-adk/overview.mdx +0 -69
- package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +0 -229
- package/.docs/raw/docs/runtimes/langchain.mdx +0 -901
- package/.docs/raw/docs/runtimes/langgraph/agent-state.mdx +0 -181
- package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +0 -305
- package/.docs/raw/docs/runtimes/langgraph/interrupts.mdx +0 -104
- package/.docs/raw/docs/runtimes/langgraph/overview.mdx +0 -84
- package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +0 -496
- package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +0 -144
- package/.docs/raw/docs/runtimes/langgraph/threads.mdx +0 -113
- package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +0 -29
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +0 -93
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +0 -347
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +0 -393
- package/.docs/raw/docs/runtimes/opencode/hooks.mdx +0 -194
- package/.docs/raw/docs/runtimes/opencode/overview.mdx +0 -58
- package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +0 -119
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +0 -133
- package/.docs/raw/docs/tools/a2ui.mdx +0 -107
- package/.docs/raw/docs/tools/backend.mdx +0 -147
- package/.docs/raw/docs/tools/defining-tools.mdx +0 -574
- package/.docs/raw/docs/tools/dynamic-tools.mdx +0 -112
- package/.docs/raw/docs/tools/generative-ui-primitive.mdx +0 -180
- package/.docs/raw/docs/tools/generative-ui-slack.mdx +0 -167
- package/.docs/raw/docs/tools/generative-ui-teams.mdx +0 -160
- package/.docs/raw/docs/tools/generative-ui.mdx +0 -322
- package/.docs/raw/docs/tools/index.mdx +0 -72
- package/.docs/raw/docs/tools/interactables.mdx +0 -1084
- package/.docs/raw/docs/tools/mcp-apps.mdx +0 -363
- package/.docs/raw/docs/tools/mcp.mdx +0 -466
- package/.docs/raw/docs/tools/multi-agent.mdx +0 -237
- package/.docs/raw/docs/tools/openui.mdx +0 -175
- package/.docs/raw/docs/tools/tool-ui.mdx +0 -1020
- package/.docs/raw/docs/tools/user-managed-mcp.mdx +0 -428
- package/.docs/raw/docs/ui/assistant-modal.mdx +0 -166
- package/.docs/raw/docs/ui/assistant-sidebar.mdx +0 -89
- package/.docs/raw/docs/ui/attachment.mdx +0 -279
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +0 -247
- package/.docs/raw/docs/ui/context-display.mdx +0 -148
- package/.docs/raw/docs/ui/directive-text.mdx +0 -114
- package/.docs/raw/docs/ui/file.mdx +0 -159
- package/.docs/raw/docs/ui/follow-up-suggestions.mdx +0 -82
- package/.docs/raw/docs/ui/image.mdx +0 -102
- package/.docs/raw/docs/ui/markdown.mdx +0 -103
- package/.docs/raw/docs/ui/mcp-config.mdx +0 -107
- package/.docs/raw/docs/ui/mermaid.mdx +0 -92
- package/.docs/raw/docs/ui/message-timing.mdx +0 -93
- package/.docs/raw/docs/ui/model-selector.mdx +0 -455
- package/.docs/raw/docs/ui/part-grouping.mdx +0 -614
- package/.docs/raw/docs/ui/quote.mdx +0 -211
- package/.docs/raw/docs/ui/reasoning.mdx +0 -214
- package/.docs/raw/docs/ui/scrollbar.mdx +0 -77
- package/.docs/raw/docs/ui/sources.mdx +0 -186
- package/.docs/raw/docs/ui/streamdown.mdx +0 -392
- package/.docs/raw/docs/ui/syntax-highlighting.mdx +0 -205
- package/.docs/raw/docs/ui/thread-list.mdx +0 -411
- package/.docs/raw/docs/ui/thread.mdx +0 -559
- package/.docs/raw/docs/ui/tool-fallback.mdx +0 -141
- package/.docs/raw/docs/ui/tool-group.mdx +0 -240
- package/.docs/raw/docs/ui/voice.mdx +0 -173
- package/.docs/raw/docs/utilities/heat-graph.mdx +0 -237
- package/.docs/raw/docs/utilities/react-o11y.mdx +0 -362
- package/.docs/raw/docs/utilities/tw-shimmer.mdx +0 -212
- package/dist/constants.d.ts +0 -14
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -19
- package/dist/constants.js.map +0 -1
- package/dist/prepare-docs/code-examples.d.ts +0 -5
- package/dist/prepare-docs/code-examples.d.ts.map +0 -1
- package/dist/prepare-docs/code-examples.js +0 -117
- package/dist/prepare-docs/code-examples.js.map +0 -1
- package/dist/prepare-docs/copy-raw.d.ts +0 -5
- package/dist/prepare-docs/copy-raw.d.ts.map +0 -1
- package/dist/prepare-docs/copy-raw.js +0 -49
- package/dist/prepare-docs/copy-raw.js.map +0 -1
- package/dist/prepare-docs/prepare.d.ts +0 -1
- package/dist/prepare-docs/prepare.js +0 -22
- package/dist/prepare-docs/prepare.js.map +0 -1
- package/dist/prompts/xulux-playground.d.ts +0 -12
- package/dist/prompts/xulux-playground.d.ts.map +0 -1
- package/dist/prompts/xulux-playground.js +0 -33
- package/dist/prompts/xulux-playground.js.map +0 -1
- package/dist/tools/docs.d.ts +0 -22
- package/dist/tools/docs.d.ts.map +0 -1
- package/dist/tools/docs.js +0 -177
- package/dist/tools/docs.js.map +0 -1
- package/dist/tools/examples.d.ts +0 -24
- package/dist/tools/examples.d.ts.map +0 -1
- package/dist/tools/examples.js +0 -87
- package/dist/tools/examples.js.map +0 -1
- package/dist/tools/resources.d.ts +0 -6
- package/dist/tools/resources.d.ts.map +0 -1
- package/dist/tools/resources.js +0 -75
- package/dist/tools/resources.js.map +0 -1
- package/dist/tools/search.d.ts +0 -24
- package/dist/tools/search.d.ts.map +0 -1
- package/dist/tools/search.js +0 -39
- package/dist/tools/search.js.map +0 -1
- package/dist/tools/tests/mcp-test-client.d.ts +0 -15
- package/dist/tools/tests/mcp-test-client.d.ts.map +0 -1
- package/dist/tools/tests/mcp-test-client.js +0 -68
- package/dist/tools/tests/mcp-test-client.js.map +0 -1
- package/dist/tools/tests/test-setup.d.ts +0 -7
- package/dist/tools/tests/test-setup.d.ts.map +0 -1
- package/dist/tools/tests/test-setup.js +0 -36
- package/dist/tools/tests/test-setup.js.map +0 -1
- package/dist/tools/xulux-templates.d.ts +0 -58
- package/dist/tools/xulux-templates.d.ts.map +0 -1
- package/dist/tools/xulux-templates.js +0 -84
- package/dist/tools/xulux-templates.js.map +0 -1
- package/dist/utils/cache.d.ts +0 -5
- package/dist/utils/cache.d.ts.map +0 -1
- package/dist/utils/cache.js +0 -18
- package/dist/utils/cache.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -10
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -20
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/mcp-format.d.ts +0 -11
- package/dist/utils/mcp-format.d.ts.map +0 -1
- package/dist/utils/mcp-format.js +0 -14
- package/dist/utils/mcp-format.js.map +0 -1
- package/dist/utils/mdx.d.ts +0 -12
- package/dist/utils/mdx.d.ts.map +0 -1
- package/dist/utils/mdx.js +0 -45
- package/dist/utils/mdx.js.map +0 -1
- package/dist/utils/paths.d.ts +0 -12
- package/dist/utils/paths.d.ts.map +0 -1
- package/dist/utils/paths.js +0 -93
- package/dist/utils/paths.js.map +0 -1
- package/dist/utils/search.d.ts +0 -10
- package/dist/utils/search.d.ts.map +0 -1
- package/dist/utils/search.js +0 -97
- package/dist/utils/search.js.map +0 -1
- package/dist/utils/security.d.ts +0 -5
- package/dist/utils/security.d.ts.map +0 -1
- package/dist/utils/security.js +0 -22
- package/dist/utils/security.js.map +0 -1
- package/dist/xulux/catalog-client.d.ts +0 -14
- package/dist/xulux/catalog-client.d.ts.map +0 -1
- package/dist/xulux/catalog-client.js +0 -112
- package/dist/xulux/catalog-client.js.map +0 -1
- package/dist/xulux/fallback-catalog.d.ts +0 -7
- package/dist/xulux/fallback-catalog.d.ts.map +0 -1
- package/dist/xulux/fallback-catalog.js +0 -47
- package/dist/xulux/fallback-catalog.js.map +0 -1
- package/dist/xulux/fetch-sandbox.d.ts +0 -5
- package/dist/xulux/fetch-sandbox.d.ts.map +0 -1
- package/dist/xulux/fetch-sandbox.js +0 -40
- package/dist/xulux/fetch-sandbox.js.map +0 -1
- package/dist/xulux/template-service.d.ts +0 -84
- package/dist/xulux/template-service.d.ts.map +0 -1
- package/dist/xulux/template-service.js +0 -223
- package/dist/xulux/template-service.js.map +0 -1
- package/dist/xulux/types.d.ts +0 -55
- package/dist/xulux/types.d.ts.map +0 -1
- package/dist/xulux/types.js +0 -6
- package/dist/xulux/types.js.map +0 -1
- package/src/constants.ts +0 -24
- package/src/prepare-docs/code-examples.ts +0 -158
- package/src/prepare-docs/copy-raw.ts +0 -50
- package/src/prepare-docs/prepare.ts +0 -24
- package/src/prompts/xulux-playground.ts +0 -36
- package/src/tools/docs.ts +0 -255
- package/src/tools/examples.ts +0 -114
- package/src/tools/resources.ts +0 -111
- package/src/tools/search.ts +0 -46
- package/src/tools/tests/completions.test.ts +0 -60
- package/src/tools/tests/directory-size-cap.test.ts +0 -50
- package/src/tools/tests/docs.test.ts +0 -147
- package/src/tools/tests/examples.test.ts +0 -94
- package/src/tools/tests/integration.test.ts +0 -45
- package/src/tools/tests/json-parsing.test.ts +0 -23
- package/src/tools/tests/listings-cache.test.ts +0 -19
- package/src/tools/tests/mcp-protocol.test.ts +0 -216
- package/src/tools/tests/mcp-test-client.ts +0 -111
- package/src/tools/tests/path-traversal.test.ts +0 -84
- package/src/tools/tests/resources.test.ts +0 -133
- package/src/tools/tests/search.test.ts +0 -37
- package/src/tools/tests/test-setup.ts +0 -50
- package/src/tools/tests/xulux-templates.test.ts +0 -325
- package/src/tools/xulux-templates.ts +0 -141
- package/src/utils/cache.ts +0 -20
- package/src/utils/logger.ts +0 -20
- package/src/utils/mcp-format.ts +0 -14
- package/src/utils/mdx.ts +0 -59
- package/src/utils/paths.ts +0 -139
- package/src/utils/search.ts +0 -131
- package/src/utils/security.ts +0 -52
- package/src/utils/tests/cache.test.ts +0 -51
- package/src/utils/tests/mcp-format.test.ts +0 -22
- package/src/utils/tests/security.test.ts +0 -119
- package/src/xulux/catalog-client.ts +0 -150
- package/src/xulux/fallback-catalog.ts +0 -63
- package/src/xulux/fetch-sandbox.ts +0 -56
- package/src/xulux/template-service.ts +0 -406
- package/src/xulux/types.ts +0 -64
|
@@ -1,619 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: File Attachments
|
|
3
|
-
description: Let users attach images, PDFs, and other files to AI chat messages in React. Drag-drop, paste, and vision-model support, built into assistant-ui.
|
|
4
|
-
platforms: ["react"]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
import { AttachmentSample } from "@/components/pages/docs/samples/attachment";
|
|
8
|
-
|
|
9
|
-
Enable users to attach files to their messages, enhancing conversations with images, documents, and other content.
|
|
10
|
-
|
|
11
|
-
<AttachmentSample />
|
|
12
|
-
|
|
13
|
-
## Overview
|
|
14
|
-
|
|
15
|
-
The attachment system in assistant-ui provides a flexible framework for handling file uploads in your AI chat interface. It consists of:
|
|
16
|
-
|
|
17
|
-
- **Attachment Adapters**: Backend logic for processing attachment files
|
|
18
|
-
- **UI Components**: Pre-built components for attachment display and interaction
|
|
19
|
-
- **Runtime Integration**: Seamless integration with all assistant-ui runtimes
|
|
20
|
-
|
|
21
|
-
## Getting Started
|
|
22
|
-
|
|
23
|
-
<Steps>
|
|
24
|
-
<Step>
|
|
25
|
-
|
|
26
|
-
### Install UI Components
|
|
27
|
-
|
|
28
|
-
First, add the attachment UI components to your project:
|
|
29
|
-
|
|
30
|
-
<InstallCommand shadcn={["attachment"]} />
|
|
31
|
-
|
|
32
|
-
This adds `/components/assistant-ui/attachment.tsx` to your project.
|
|
33
|
-
|
|
34
|
-
<Callout type="tip">
|
|
35
|
-
**Next steps:** Feel free to adjust these auto-generated components (styling,
|
|
36
|
-
layout, behavior) to match your application's design system.
|
|
37
|
-
</Callout>
|
|
38
|
-
|
|
39
|
-
</Step>
|
|
40
|
-
<Step>
|
|
41
|
-
|
|
42
|
-
### Set up Runtime (No Configuration Required)
|
|
43
|
-
|
|
44
|
-
For `useChatRuntime`, attachments work automatically without additional configuration:
|
|
45
|
-
|
|
46
|
-
```tsx title="/app/MyRuntimeProvider.tsx"
|
|
47
|
-
import { useChatRuntime } from "@assistant-ui/ai-sdk";
|
|
48
|
-
|
|
49
|
-
const runtime = useChatRuntime();
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
<Callout type="info">
|
|
53
|
-
**Note:** The AI SDK runtime handles attachments automatically. For other runtimes like `useLocalRuntime`, you may still need to configure attachment adapters as shown in the [Creating Custom Attachment Adapters](#creating-custom-attachment-adapters) section below.
|
|
54
|
-
</Callout>
|
|
55
|
-
|
|
56
|
-
</Step>
|
|
57
|
-
<Step>
|
|
58
|
-
|
|
59
|
-
### Add UI Components
|
|
60
|
-
|
|
61
|
-
Integrate the attachment components into your chat interface. See [Attachment UI components](/docs/ui/attachment) for the full install and usage guide.
|
|
62
|
-
|
|
63
|
-
</Step>
|
|
64
|
-
</Steps>
|
|
65
|
-
|
|
66
|
-
## Built-in Attachment Adapters
|
|
67
|
-
|
|
68
|
-
### AI SDK Runtime (Default)
|
|
69
|
-
|
|
70
|
-
When using `useChatRuntime`, the built-in adapter accepts all file types and converts them to base64 data URLs. This works well for images and small files.
|
|
71
|
-
|
|
72
|
-
<Callout type="warn">
|
|
73
|
-
Most models only support **image** attachments. Sending unsupported file types (audio, video, PDF, etc.) will result in an API error. Check your model provider's documentation for supported input types.
|
|
74
|
-
</Callout>
|
|
75
|
-
|
|
76
|
-
To restrict accepted file types, pass a custom adapter:
|
|
77
|
-
|
|
78
|
-
```tsx
|
|
79
|
-
const runtime = useChatRuntime({
|
|
80
|
-
adapters: {
|
|
81
|
-
attachments: new SimpleImageAttachmentAdapter(), // only images
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### SimpleImageAttachmentAdapter
|
|
87
|
-
|
|
88
|
-
Handles image files and converts them to data URLs for display in the chat UI.
|
|
89
|
-
|
|
90
|
-
```tsx
|
|
91
|
-
const imageAdapter = new SimpleImageAttachmentAdapter();
|
|
92
|
-
// Accepts: image/* (JPEG, PNG, GIF, etc.)
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### SimpleTextAttachmentAdapter
|
|
96
|
-
|
|
97
|
-
Processes text files and wraps content in formatted tags:
|
|
98
|
-
|
|
99
|
-
```tsx
|
|
100
|
-
const textAdapter = new SimpleTextAttachmentAdapter();
|
|
101
|
-
// Accepts: text/plain, text/html, text/markdown, etc.
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### CompositeAttachmentAdapter
|
|
105
|
-
|
|
106
|
-
Combines multiple adapters to support various file types:
|
|
107
|
-
|
|
108
|
-
```tsx
|
|
109
|
-
const compositeAdapter = new CompositeAttachmentAdapter([
|
|
110
|
-
new SimpleImageAttachmentAdapter(),
|
|
111
|
-
new SimpleTextAttachmentAdapter(),
|
|
112
|
-
]);
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Creating Custom Attachment Adapters
|
|
116
|
-
|
|
117
|
-
Build your own adapters for specialized file handling. Below are complete examples for common use cases. For `PendingAttachment` and `CompleteAttachment` type definitions, see [Attachment types](/docs/ui/attachment#attachment-types).
|
|
118
|
-
|
|
119
|
-
### Vision-Capable Image Adapter
|
|
120
|
-
|
|
121
|
-
Send images to vision-capable LLMs like GPT-5.6, Claude Sonnet 4.6, or Gemini Pro Vision:
|
|
122
|
-
|
|
123
|
-
```tsx
|
|
124
|
-
import {
|
|
125
|
-
AttachmentAdapter,
|
|
126
|
-
PendingAttachment,
|
|
127
|
-
CompleteAttachment,
|
|
128
|
-
} from "@assistant-ui/react";
|
|
129
|
-
|
|
130
|
-
class VisionImageAdapter implements AttachmentAdapter {
|
|
131
|
-
accept = "image/jpeg,image/png,image/webp,image/gif";
|
|
132
|
-
|
|
133
|
-
async add({ file }: { file: File }): Promise<PendingAttachment> {
|
|
134
|
-
// Validate file size (e.g., 20MB limit for most LLMs)
|
|
135
|
-
const maxSize = 20 * 1024 * 1024; // 20MB
|
|
136
|
-
if (file.size > maxSize) {
|
|
137
|
-
throw new Error("Image size exceeds 20MB limit");
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Return pending attachment while processing
|
|
141
|
-
return {
|
|
142
|
-
id: crypto.randomUUID(),
|
|
143
|
-
type: "image",
|
|
144
|
-
name: file.name,
|
|
145
|
-
file,
|
|
146
|
-
status: { type: "requires-action", reason: "composer-send" },
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async send(attachment: PendingAttachment): Promise<CompleteAttachment> {
|
|
151
|
-
// Convert image to base64 data URL
|
|
152
|
-
const base64 = await this.fileToBase64DataURL(attachment.file);
|
|
153
|
-
|
|
154
|
-
// Return in assistant-ui format with image content
|
|
155
|
-
return {
|
|
156
|
-
id: attachment.id,
|
|
157
|
-
type: "image",
|
|
158
|
-
name: attachment.name,
|
|
159
|
-
content: [
|
|
160
|
-
{
|
|
161
|
-
type: "image",
|
|
162
|
-
image: base64, // data:image/jpeg;base64,... format
|
|
163
|
-
},
|
|
164
|
-
],
|
|
165
|
-
status: { type: "complete" },
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async remove(attachment: PendingAttachment): Promise<void> {
|
|
170
|
-
// Cleanup if needed (e.g., revoke object URLs if you created any)
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
private async fileToBase64DataURL(file: File): Promise<string> {
|
|
174
|
-
return new Promise((resolve, reject) => {
|
|
175
|
-
const reader = new FileReader();
|
|
176
|
-
reader.onload = () => {
|
|
177
|
-
// FileReader result is already a data URL
|
|
178
|
-
resolve(reader.result as string);
|
|
179
|
-
};
|
|
180
|
-
reader.onerror = reject;
|
|
181
|
-
reader.readAsDataURL(file);
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### PDF Document Adapter
|
|
188
|
-
|
|
189
|
-
Handle PDF files by extracting text or converting to base64 for processing:
|
|
190
|
-
|
|
191
|
-
```tsx
|
|
192
|
-
import {
|
|
193
|
-
AttachmentAdapter,
|
|
194
|
-
PendingAttachment,
|
|
195
|
-
CompleteAttachment,
|
|
196
|
-
} from "@assistant-ui/react";
|
|
197
|
-
|
|
198
|
-
class PDFAttachmentAdapter implements AttachmentAdapter {
|
|
199
|
-
accept = "application/pdf";
|
|
200
|
-
|
|
201
|
-
async add({ file }: { file: File }): Promise<PendingAttachment> {
|
|
202
|
-
// Validate file size
|
|
203
|
-
const maxSize = 10 * 1024 * 1024; // 10MB limit
|
|
204
|
-
if (file.size > maxSize) {
|
|
205
|
-
throw new Error("PDF size exceeds 10MB limit");
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return {
|
|
209
|
-
id: crypto.randomUUID(),
|
|
210
|
-
type: "document",
|
|
211
|
-
name: file.name,
|
|
212
|
-
file,
|
|
213
|
-
status: { type: "requires-action", reason: "composer-send" },
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
async send(attachment: PendingAttachment): Promise<CompleteAttachment> {
|
|
218
|
-
// Option 1: Extract text from PDF (requires pdf parsing library)
|
|
219
|
-
// const text = await this.extractTextFromPDF(attachment.file);
|
|
220
|
-
|
|
221
|
-
// Option 2: Convert to base64 for API processing
|
|
222
|
-
const base64Data = await this.fileToBase64(attachment.file);
|
|
223
|
-
|
|
224
|
-
return {
|
|
225
|
-
id: attachment.id,
|
|
226
|
-
type: "document",
|
|
227
|
-
name: attachment.name,
|
|
228
|
-
content: [
|
|
229
|
-
{
|
|
230
|
-
type: "text",
|
|
231
|
-
text: `[PDF Document: ${attachment.name}]\nBase64 data: ${base64Data.substring(0, 50)}...`,
|
|
232
|
-
},
|
|
233
|
-
],
|
|
234
|
-
status: { type: "complete" },
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
async remove(attachment: PendingAttachment): Promise<void> {
|
|
239
|
-
// Cleanup if needed
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
private async fileToBase64(file: File): Promise<string> {
|
|
243
|
-
const arrayBuffer = await file.arrayBuffer();
|
|
244
|
-
const bytes = new Uint8Array(arrayBuffer);
|
|
245
|
-
let binary = "";
|
|
246
|
-
bytes.forEach((byte) => {
|
|
247
|
-
binary += String.fromCharCode(byte);
|
|
248
|
-
});
|
|
249
|
-
return btoa(binary);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Optional: Extract text from PDF using a library like pdf.js
|
|
253
|
-
private async extractTextFromPDF(file: File): Promise<string> {
|
|
254
|
-
// Implementation would use pdf.js or similar
|
|
255
|
-
// This is a placeholder
|
|
256
|
-
return "Extracted PDF text content";
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
## Using Custom Adapters
|
|
262
|
-
|
|
263
|
-
### With LocalRuntime
|
|
264
|
-
|
|
265
|
-
When using `LocalRuntime`, you need to handle images in your `ChatModelAdapter` (the adapter that connects to your AI backend):
|
|
266
|
-
|
|
267
|
-
```tsx
|
|
268
|
-
import { useLocalRuntime, ChatModelAdapter } from "@assistant-ui/react";
|
|
269
|
-
|
|
270
|
-
// This adapter connects LocalRuntime to your AI backend
|
|
271
|
-
const MyModelAdapter: ChatModelAdapter = {
|
|
272
|
-
async run({ messages, abortSignal }) {
|
|
273
|
-
// Convert messages to format expected by your vision-capable API
|
|
274
|
-
const formattedMessages = messages.map((msg) => {
|
|
275
|
-
if (
|
|
276
|
-
msg.role === "user" &&
|
|
277
|
-
msg.content.some((part) => part.type === "image")
|
|
278
|
-
) {
|
|
279
|
-
// Format for GPT-5.6 or similar vision models
|
|
280
|
-
return {
|
|
281
|
-
role: "user",
|
|
282
|
-
content: msg.content.map((part) => {
|
|
283
|
-
if (part.type === "text") {
|
|
284
|
-
return { type: "text", text: part.text };
|
|
285
|
-
}
|
|
286
|
-
if (part.type === "image") {
|
|
287
|
-
return {
|
|
288
|
-
type: "image_url",
|
|
289
|
-
image_url: { url: part.image },
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
return part;
|
|
293
|
-
}),
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Regular text messages
|
|
298
|
-
return {
|
|
299
|
-
role: msg.role,
|
|
300
|
-
content: msg.content
|
|
301
|
-
.filter((c) => c.type === "text")
|
|
302
|
-
.map((c) => c.text)
|
|
303
|
-
.join("\n"),
|
|
304
|
-
};
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
// Send to your vision-capable API
|
|
308
|
-
const response = await fetch("/api/vision-chat", {
|
|
309
|
-
method: "POST",
|
|
310
|
-
headers: { "Content-Type": "application/json" },
|
|
311
|
-
body: JSON.stringify({ messages: formattedMessages }),
|
|
312
|
-
signal: abortSignal,
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
const data = await response.json();
|
|
316
|
-
return {
|
|
317
|
-
content: [{ type: "text", text: data.message }],
|
|
318
|
-
};
|
|
319
|
-
},
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
// Create runtime with vision image adapter
|
|
323
|
-
const runtime = useLocalRuntime(MyModelAdapter, {
|
|
324
|
-
adapters: {
|
|
325
|
-
attachments: new VisionImageAdapter(),
|
|
326
|
-
},
|
|
327
|
-
});
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
## Advanced Features
|
|
331
|
-
|
|
332
|
-
### Progress Updates
|
|
333
|
-
|
|
334
|
-
Provide real-time upload progress using async generators:
|
|
335
|
-
|
|
336
|
-
```tsx
|
|
337
|
-
class UploadAttachmentAdapter implements AttachmentAdapter {
|
|
338
|
-
accept = "*";
|
|
339
|
-
|
|
340
|
-
async *add({ file }: { file: File }) {
|
|
341
|
-
const id = generateId();
|
|
342
|
-
|
|
343
|
-
// Initial pending state
|
|
344
|
-
yield {
|
|
345
|
-
id,
|
|
346
|
-
type: "file",
|
|
347
|
-
name: file.name,
|
|
348
|
-
file,
|
|
349
|
-
status: { type: "running", reason: "uploading", progress: 0 },
|
|
350
|
-
} as PendingAttachment;
|
|
351
|
-
|
|
352
|
-
// Simulate upload progress
|
|
353
|
-
for (let progress = 10; progress <= 90; progress += 10) {
|
|
354
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
355
|
-
|
|
356
|
-
yield {
|
|
357
|
-
id,
|
|
358
|
-
type: "file",
|
|
359
|
-
name: file.name,
|
|
360
|
-
file,
|
|
361
|
-
status: { type: "running", reason: "uploading", progress },
|
|
362
|
-
} as PendingAttachment;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// Yield final progress so the 100% state reaches the composer
|
|
366
|
-
yield {
|
|
367
|
-
id,
|
|
368
|
-
type: "file",
|
|
369
|
-
name: file.name,
|
|
370
|
-
file,
|
|
371
|
-
status: { type: "running", reason: "uploading", progress: 100 },
|
|
372
|
-
} as PendingAttachment;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
async send(attachment: PendingAttachment): Promise<CompleteAttachment> {
|
|
376
|
-
// Upload the file and return complete attachment
|
|
377
|
-
const url = await this.uploadFile(attachment.file);
|
|
378
|
-
|
|
379
|
-
return {
|
|
380
|
-
id: attachment.id,
|
|
381
|
-
type: attachment.type,
|
|
382
|
-
name: attachment.name,
|
|
383
|
-
content: [
|
|
384
|
-
{
|
|
385
|
-
type: "file",
|
|
386
|
-
data: url, // or base64 data
|
|
387
|
-
mimeType: attachment.file.type,
|
|
388
|
-
},
|
|
389
|
-
],
|
|
390
|
-
status: { type: "complete" },
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
async remove(attachment: PendingAttachment): Promise<void> {
|
|
395
|
-
// Cleanup logic
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
private async uploadFile(file: File): Promise<string> {
|
|
399
|
-
// Your upload logic here
|
|
400
|
-
return "https://example.com/file-url";
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
### Validation and Error Handling
|
|
406
|
-
|
|
407
|
-
Implement robust validation in your adapters:
|
|
408
|
-
|
|
409
|
-
```tsx
|
|
410
|
-
class ValidatedImageAdapter implements AttachmentAdapter {
|
|
411
|
-
accept = "image/*";
|
|
412
|
-
maxSizeBytes = 5 * 1024 * 1024; // 5MB
|
|
413
|
-
|
|
414
|
-
async add({ file }: { file: File }): Promise<PendingAttachment> {
|
|
415
|
-
// Validate file size
|
|
416
|
-
if (file.size > this.maxSizeBytes) {
|
|
417
|
-
return {
|
|
418
|
-
id: generateId(),
|
|
419
|
-
type: "image",
|
|
420
|
-
name: file.name,
|
|
421
|
-
file,
|
|
422
|
-
status: {
|
|
423
|
-
type: "incomplete",
|
|
424
|
-
reason: "error",
|
|
425
|
-
},
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// Validate image dimensions
|
|
430
|
-
try {
|
|
431
|
-
const dimensions = await this.getImageDimensions(file);
|
|
432
|
-
if (dimensions.width > 4096 || dimensions.height > 4096) {
|
|
433
|
-
throw new Error("Image dimensions exceed 4096x4096");
|
|
434
|
-
}
|
|
435
|
-
} catch (error) {
|
|
436
|
-
return {
|
|
437
|
-
id: generateId(),
|
|
438
|
-
type: "image",
|
|
439
|
-
name: file.name,
|
|
440
|
-
file,
|
|
441
|
-
status: {
|
|
442
|
-
type: "incomplete",
|
|
443
|
-
reason: "error",
|
|
444
|
-
},
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
// Return valid attachment
|
|
449
|
-
return {
|
|
450
|
-
id: generateId(),
|
|
451
|
-
type: "image",
|
|
452
|
-
name: file.name,
|
|
453
|
-
file,
|
|
454
|
-
status: { type: "requires-action", reason: "composer-send" },
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
private async getImageDimensions(file: File) {
|
|
459
|
-
// Implementation to check image dimensions
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
To surface failures in the UI, subscribe to `composer.attachmentAddError`. It fires whenever an add operation produces a failure, in either of two ways:
|
|
465
|
-
|
|
466
|
-
1. `addAttachment()` rejects: no adapter is configured, the file type does not match `accept`, or the adapter's `add()` throws.
|
|
467
|
-
2. `addAttachment()` resolves but the adapter returned (or, for async-iterator adapters, yielded) an attachment whose `status.reason === "error"`. The promise resolves successfully, yet the event still fires so the UI can react.
|
|
468
|
-
|
|
469
|
-
The event payload carries a `reason` discriminator and a human-readable `message`, so you can branch UI on the failure mode:
|
|
470
|
-
|
|
471
|
-
| `reason` | When It Fires |
|
|
472
|
-
| ---------------- | ------------------------------------------------------------------------------------------------------ |
|
|
473
|
-
| `no-adapter` | `addAttachment(File)` was called but no `AttachmentAdapter` is configured. |
|
|
474
|
-
| `not-accepted` | The file's content type (or filename extension) did not match `adapter.accept`. External `CreateAttachment` descriptors also trigger this when their `contentType` does not match `adapter.accept`. |
|
|
475
|
-
| `adapter-error` | The adapter's `add()` threw, or returned/yielded an attachment with `status.reason === "error"`. If the adapter produced any attachment before failing, the errored attachment is also visible in `composer.attachments`; if it threw before producing one, the event is the only signal. |
|
|
476
|
-
|
|
477
|
-
```tsx
|
|
478
|
-
import { toast } from "sonner"; // or your toast library of choice
|
|
479
|
-
import { useAuiEvent } from "@assistant-ui/react";
|
|
480
|
-
|
|
481
|
-
function AttachmentErrorToast() {
|
|
482
|
-
useAuiEvent("composer.attachmentAddError", ({ reason, message, error }) => {
|
|
483
|
-
if (reason === "not-accepted") {
|
|
484
|
-
toast.error("This file type is not supported.");
|
|
485
|
-
} else if (reason === "no-adapter") {
|
|
486
|
-
toast.error("Attachments are not configured for this composer.");
|
|
487
|
-
} else {
|
|
488
|
-
if (error) console.error(error); // underlying Error, useful for logging
|
|
489
|
-
toast.error(message || "Attachment failed to upload.");
|
|
490
|
-
}
|
|
491
|
-
});
|
|
492
|
-
return null;
|
|
493
|
-
}
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
`attachmentId` is included when the failure is associated with an attachment that was registered (typically `adapter-error` cases). It is `undefined` for `no-adapter` and `not-accepted` failures because those reject before any attachment is registered.
|
|
497
|
-
|
|
498
|
-
### External Source Attachments
|
|
499
|
-
|
|
500
|
-
Add attachments from external sources (URLs, API data, CMS references) without needing a `File` object or an `AttachmentAdapter`:
|
|
501
|
-
|
|
502
|
-
```tsx
|
|
503
|
-
const aui = useAui();
|
|
504
|
-
|
|
505
|
-
// Add an attachment from an external source
|
|
506
|
-
await aui.composer.addAttachment({
|
|
507
|
-
name: "report.pdf",
|
|
508
|
-
contentType: "application/pdf",
|
|
509
|
-
content: [{ type: "text", text: "Extracted document content..." }],
|
|
510
|
-
});
|
|
511
|
-
|
|
512
|
-
// Optionally provide id and type
|
|
513
|
-
await aui.composer.addAttachment({
|
|
514
|
-
id: "cms-doc-123",
|
|
515
|
-
type: "document",
|
|
516
|
-
name: "Product Spec",
|
|
517
|
-
content: [{ type: "text", text: "Product specification content..." }],
|
|
518
|
-
});
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
External attachments are added as complete attachments directly. They bypass the `AttachmentAdapter`'s `add()` step (no upload), but `adapter.accept` is still enforced when an `AttachmentAdapter` is configured: a `CreateAttachment` whose `contentType` does not match `adapter.accept` is rejected and emits `composer.attachmentAddError`. If `contentType` is omitted, the descriptor's filename extension is matched against `adapter.accept` only when `accept` itself contains explicit extension entries (e.g. `.png,.pdf`); MIME-wildcard `accept` strings such as `image/*` always require a matching `contentType`. When no `AttachmentAdapter` is configured, external attachments are added without any content-type check, and they can be removed without an adapter.
|
|
522
|
-
|
|
523
|
-
### Multiple File Selection
|
|
524
|
-
|
|
525
|
-
Enable multi-file selection with custom limits:
|
|
526
|
-
|
|
527
|
-
```tsx
|
|
528
|
-
const aui = useAui();
|
|
529
|
-
|
|
530
|
-
const handleMultipleFiles = async (files: FileList) => {
|
|
531
|
-
const maxFiles = 5;
|
|
532
|
-
const filesToAdd = Array.from(files).slice(0, maxFiles);
|
|
533
|
-
|
|
534
|
-
for (const file of filesToAdd) {
|
|
535
|
-
await aui.composer.addAttachment(file);
|
|
536
|
-
}
|
|
537
|
-
};
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
## Backend Integration
|
|
541
|
-
|
|
542
|
-
### With Vercel AI SDK
|
|
543
|
-
|
|
544
|
-
Attachments are sent to the backend as file content parts.
|
|
545
|
-
|
|
546
|
-
## Runtime Support
|
|
547
|
-
|
|
548
|
-
Attachments work with all assistant-ui runtimes:
|
|
549
|
-
|
|
550
|
-
- **AI SDK Runtime**: `useChatRuntime`
|
|
551
|
-
- **External Store**: `useExternalStoreRuntime`
|
|
552
|
-
- **LangGraph**: `useLangGraphRuntime`
|
|
553
|
-
- **Custom Runtimes**: Any runtime implementing the attachment interface
|
|
554
|
-
|
|
555
|
-
<Callout type="tip">
|
|
556
|
-
The attachment system is designed to be extensible. You can create adapters
|
|
557
|
-
for any file type, integrate with cloud storage services, or implement custom
|
|
558
|
-
processing logic to fit your specific needs.
|
|
559
|
-
</Callout>
|
|
560
|
-
|
|
561
|
-
## Large File Uploads
|
|
562
|
-
|
|
563
|
-
The built-in adapters convert files to base64 data URLs in memory. For large files (long audio, video, etc.), this can cause performance issues. Instead, upload to a server and pass the URL:
|
|
564
|
-
|
|
565
|
-
```tsx
|
|
566
|
-
class ServerUploadAdapter implements AttachmentAdapter {
|
|
567
|
-
accept = "*";
|
|
568
|
-
private urls = new Map<string, string>();
|
|
569
|
-
|
|
570
|
-
async *add({ file }: { file: File }) {
|
|
571
|
-
const id = crypto.randomUUID();
|
|
572
|
-
yield {
|
|
573
|
-
id, type: "file" as const, name: file.name, file,
|
|
574
|
-
contentType: file.type,
|
|
575
|
-
status: { type: "running" as const, reason: "uploading" as const, progress: 0 },
|
|
576
|
-
};
|
|
577
|
-
|
|
578
|
-
const form = new FormData();
|
|
579
|
-
form.append("file", file);
|
|
580
|
-
const { url } = await fetch("/api/upload", { method: "POST", body: form }).then(r => r.json());
|
|
581
|
-
this.urls.set(id, url);
|
|
582
|
-
|
|
583
|
-
yield {
|
|
584
|
-
id, type: "file" as const, name: file.name, file,
|
|
585
|
-
contentType: file.type,
|
|
586
|
-
status: { type: "requires-action" as const, reason: "composer-send" as const },
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
async send(attachment: PendingAttachment): Promise<CompleteAttachment> {
|
|
591
|
-
const url = this.urls.get(attachment.id)!;
|
|
592
|
-
this.urls.delete(attachment.id);
|
|
593
|
-
return {
|
|
594
|
-
...attachment, status: { type: "complete" },
|
|
595
|
-
content: [{ type: "file", data: url, mimeType: attachment.contentType ?? "", filename: attachment.name }],
|
|
596
|
-
};
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
async remove() {}
|
|
600
|
-
}
|
|
601
|
-
```
|
|
602
|
-
|
|
603
|
-
<Callout type="tip">
|
|
604
|
-
[assistant-ui Cloud](/docs/cloud/ai-sdk-assistant-ui) includes `CloudFileAttachmentAdapter` which handles large file uploads via presigned URLs out of the box.
|
|
605
|
-
</Callout>
|
|
606
|
-
|
|
607
|
-
## Best Practices
|
|
608
|
-
|
|
609
|
-
1. **File Size Limits**: Always validate file sizes to prevent memory issues
|
|
610
|
-
2. **Type Validation**: Verify file types match your `accept` pattern
|
|
611
|
-
3. **Error Handling**: Provide clear error messages for failed uploads
|
|
612
|
-
4. **Progress Feedback**: Show upload progress for better UX
|
|
613
|
-
5. **Security**: Validate and sanitize file content before processing
|
|
614
|
-
6. **Accessibility**: Ensure attachment UI is keyboard navigable
|
|
615
|
-
|
|
616
|
-
## Resources
|
|
617
|
-
|
|
618
|
-
- [Attachment UI Components](/docs/ui/attachment) - UI implementation details
|
|
619
|
-
- [API Reference](/docs/api-reference/overview) - Detailed type definitions
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Message Branching
|
|
3
|
-
description: Edit messages or regenerate AI responses, then switch between alternative replies. Branching navigation built into assistant-ui's React chat UI.
|
|
4
|
-
platforms: ["react"]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
import { BranchingSample } from "@/components/pages/docs/samples/branching";
|
|
8
|
-
|
|
9
|
-
Branching lets users navigate between alternative versions of a message. A new branch is created when:
|
|
10
|
-
|
|
11
|
-
- A user message is edited
|
|
12
|
-
- An assistant message is reloaded (reload creates a new branch on the same message)
|
|
13
|
-
|
|
14
|
-
Branches are automatically tracked by assistant-ui by observing changes to the `messages` array.
|
|
15
|
-
|
|
16
|
-
## Shortest Working Pattern
|
|
17
|
-
|
|
18
|
-
<BranchingSample />
|
|
19
|
-
|
|
20
|
-
Place a branch picker inside your message component:
|
|
21
|
-
|
|
22
|
-
```tsx
|
|
23
|
-
import { BranchPickerPrimitive } from "@assistant-ui/react";
|
|
24
|
-
|
|
25
|
-
const BranchPicker = () => (
|
|
26
|
-
<BranchPickerPrimitive.Root hideWhenSingleBranch>
|
|
27
|
-
<BranchPickerPrimitive.Previous />
|
|
28
|
-
<BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
|
|
29
|
-
<BranchPickerPrimitive.Next />
|
|
30
|
-
</BranchPickerPrimitive.Root>
|
|
31
|
-
);
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
`BranchPickerPrimitive.Previous` and `.Next` automatically disable at branch boundaries and while a run is in flight (unless the runtime supports `switchBranchDuringRun`). For the full primitive API, see [BranchPickerPrimitive](/docs/primitives/branch-picker).
|
|
35
|
-
|
|
36
|
-
## Triggering Reload
|
|
37
|
-
|
|
38
|
-
`ActionBarPrimitive.Reload` creates a new branch on an assistant message and re-runs from there:
|
|
39
|
-
|
|
40
|
-
```tsx
|
|
41
|
-
import { ActionBarPrimitive, MessagePrimitive } from "@assistant-ui/react";
|
|
42
|
-
|
|
43
|
-
const AssistantMessage = () => (
|
|
44
|
-
<MessagePrimitive.Root>
|
|
45
|
-
<MessagePrimitive.Parts />
|
|
46
|
-
<ActionBarPrimitive.Root>
|
|
47
|
-
<ActionBarPrimitive.Reload />
|
|
48
|
-
</ActionBarPrimitive.Root>
|
|
49
|
-
</MessagePrimitive.Root>
|
|
50
|
-
);
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
`Reload` is disabled while `thread.isRunning` or `thread.isDisabled` is true. See [ActionBarPrimitive](/docs/primitives/action-bar) for the full reference.
|
|
54
|
-
|
|
55
|
-
## Programmatic Branch Navigation
|
|
56
|
-
|
|
57
|
-
For headless or keyboard-shortcut flows, navigate directly to a branch by id via `aui.message.switchToBranch`:
|
|
58
|
-
|
|
59
|
-
```tsx
|
|
60
|
-
import { useAui } from "@assistant-ui/react";
|
|
61
|
-
|
|
62
|
-
const SwitchToBranch = ({ branchId }: { branchId: string }) => {
|
|
63
|
-
const aui = useAui();
|
|
64
|
-
return (
|
|
65
|
-
<button onClick={() => aui.message.switchToBranch({ branchId })}>
|
|
66
|
-
Go to branch
|
|
67
|
-
</button>
|
|
68
|
-
);
|
|
69
|
-
};
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
This must be called inside a message context (e.g. nested within `MessagePrimitive.Root`).
|
|
73
|
-
|
|
74
|
-
## Grouped Parts After Branching
|
|
75
|
-
|
|
76
|
-
Each branch is a distinct message version with its own content parts. `MessagePrimitive.GroupedParts` provides hierarchical adjacent grouping of those parts, useful when a message mixes tool calls and text across branches. See the [MessagePrimitive](/docs/primitives/message) reference for `GroupedParts` usage.
|