part-3-approval-ui
**Cancellation:** `create_run` exposes `controller.is_cancelled` and `controller.cancelled_event`.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
**Cancellation:** `create_run` exposes `controller.is_cancelled` and `controller.cancelled_event`.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Ansible is a radically simple IT automation platform that makes your applications and systems easier to deploy and maintain. This llms.txt indexes the official Ansible Community Documentation (latest stable). Source: https://docs.ansible.com/projects/ansible/latest/
A proposal that those interested in providing LLM-friendly content add a /llms.txt file to their site. This is a markdown file that provides brief background information and guidance, along with links to markdown files providing more detailed information.
An ultra-portable web-browser engine for games and desktop apps.
Documentation - Discord documentation and resources. Use this skill when working with Documentation - Discord or when the user mentions documentation - discord.
The official documentation for building on the Slack platform: apps, agents, workflows, and integrations. Covers the Slack CLI, Bolt frameworks (JavaScript, Python, Java), SDKs, the Web and Events APIs, Block Kit, authentication, and Slack Marketplace distribution.
Composio powers 1000+ toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent into action.
| name | part-3-approval-ui |
| description | **Cancellation:** `create_run` exposes `controller.is_cancelled` and `controller.cancelled_event`. |
Cancellation:
create_runexposescontroller.is_cancelledandcontroller.cancelled_event. If the response stream is closed early (for example user cancel or client disconnect), these are set so your backend loop can exit cooperatively.controller.cancelled_eventis a read-only signal object withwait()andis_set().create_rungives callbacks a ~50ms cooperative shutdown window before forced task cancellation. Callback exceptions that happen during early-close cleanup are not re-raised to the stream consumer, but are logged with traceback at warning level for debugging. Put critical cleanup infinallyblocks, since forced cancellation may happen after the grace window.
async def run_callback(controller: RunController):
while not controller.is_cancelled:
# Long-running work / model loop
await asyncio.sleep(0.05)
async def run_callback(controller: RunController):
await controller.cancelled_event.wait()
# cancellation-aware shutdown path
Backend Reference Implementation [#backend-reference-implementation]
Full example: python/assistant-transport-backend-langgraph
Streaming Protocol [#streaming-protocol]
The assistant-stream state replication protocol allows for streaming updates to an arbitrary JSON object.
Operations [#operations]
The protocol supports two operations:
set [#set]
Sets a value at a specific path in the JSON object.
append-text [#append-text]
Appends text to an existing string value at a path.
Wire Format [#wire-format]
The wire format is inspired by AI SDK's data stream protocol.
State Update:
Error:
Building a Frontend [#building-a-frontend]
Now let's set up the frontend. The state converter is the heart of the integration—it transforms your agent's state into the format assistant-ui expects.
The useAssistantTransportRuntime hook is used to configure the runtime. It accepts the following config:
State Converter [#state-converter]
The state converter is the core of your frontend integration. It transforms your agent's state into assistant-ui's message format.
Converting Messages [#converting-messages]
Use the createMessageConverter API to transform your agent's messages to assistant-ui format:
Reverse mapping:
The message converter allows you to retrieve the original message format anywhere inside assistant-ui. This lets you access your agent's native message structure from any assistant-ui component:
Optimistic Updates from Commands [#optimistic-updates-from-commands]
The converter also receives connectionMetadata which contains pending commands. Use this to show optimistic updates:
Handling Errors and Cancellations [#handling-errors-and-cancellations]
The onError and onCancel callbacks receive an updateState function that allows you to update the agent state on the client side without making a server request:
Custom Headers and Body [#custom-headers-and-body]
You can pass custom headers and body to the backend endpoint:
Dynamic Headers and Body [#dynamic-headers-and-body]
You can also evaluate the header and body payloads on every request by passing an async function:
Transforming the Request Body [#transforming-the-request-body]
Use prepareSendCommandsRequest to transform the entire request body before it is sent to the backend. This receives the fully assembled body object and returns the (potentially transformed) body.
This is useful for adding tracking IDs, transforming commands, or injecting metadata that depends on the assembled request:
Editing Messages [#editing-messages]
By default, editing messages is disabled. To enable it, set capabilities.edit to true:
add-message commands always include parentId and sourceId fields:
Backend Handling [#backend-handling]
When the backend receives an add-message command with a parentId, it should:
Resuming from a Sync Server [#resuming-from-a-sync-server]
When a user refreshes the page, switches tabs, or reconnects after a network interruption, the backend may still be generating a response. resumeRun allows the frontend to reconnect to the active backend stream.
Setup [#setup]
Pass a resumeApi URL to useAssistantTransportRuntime that points to your sync server:
Resuming on thread switch or page load [#resuming-on-thread-switch-or-page-load]
When switching to a thread or mounting a component, check if the backend is still running and call resumeRun:
For the AssistantTransport runtime, you do not need to pass a stream parameter — the runtime uses the configured resumeApi endpoint to reconnect.
Accessing Runtime State [#accessing-runtime-state]
Use the useAssistantTransportState hook to access the current agent state from any component:
You can also pass a selector function to extract specific values:
Type Safety [#type-safety]
Use module augmentation to add types for your agent state:
After adding the type augmentation, useAssistantTransportState will be fully typed:
Accessing the Original Message [#accessing-the-original-message]
If you're using createMessageConverter, you can access the original message format from any assistant-ui component using the converter's toOriginalMessage method:
You can also use toOriginalMessages to get all original messages when a ThreadMessage was created from multiple source messages:
Frontend Reference Implementation [#frontend-reference-implementation]
Full example: examples/with-assistant-transport
Custom Commands [#custom-commands]
Defining Custom Commands [#defining-custom-commands]
Use module augmentation to define a custom command:
Issuing Commands [#issuing-commands]
Use the useAssistantTransportSendCommand hook to send custom commands:
Backend Integration [#backend-integration]
The backend receives custom commands in the commands array, just like built-in commands:
Optimistic Updates [#optimistic-updates]
Update the state converter to optimistically handle the custom command:
Cancellation and Error Behavior [#cancellation-and-error-behavior]
Custom commands follow the same lifecycle as built-in commands. You can update your onError and onCancel handlers to take custom commands into account:
URL: /docs/runtimes/data-stream
Integration with data stream protocol endpoints for streaming AI responses.
The @assistant-ui/react-data-stream package provides integration with data stream protocol endpoints, enabling streaming AI responses with tool support and state management.
Overview [#overview]
The data stream protocol is a standardized format for streaming AI responses that supports:
Installation [#installation]
Basic Usage [#basic-usage]
Advanced Configuration [#advanced-configuration]
Custom Headers and Authentication [#custom-headers-and-authentication]
Dynamic Headers [#dynamic-headers]
Dynamic Body [#dynamic-body]
Event Callbacks [#event-callbacks]
Tool Integration [#tool-integration]
Frontend Tools [#frontend-tools]
Use toToolsJSONSchema to serialize client-side tools:
Backend Tool Processing [#backend-tool-processing]
Your backend should handle tool calls and return results:
Assistant Cloud Integration [#assistant-cloud-integration]
For Assistant Cloud deployments, use useCloudRuntime:
Message Conversion [#message-conversion]
Framework-Agnostic Conversion (Recommended) [#framework-agnostic-conversion-recommended]
For custom integrations, use the framework-agnostic utilities from assistant-stream:
The GenericMessage format can be easily converted to any LLM provider format:
AI SDK Specific Conversion [#ai-sdk-specific-conversion]
For AI SDK integration, use toLanguageModelMessages:
Error Handling [#error-handling]
The runtime automatically handles common error scenarios:
Best Practices [#best-practices]
Performance Optimization [#performance-optimization]
Error Boundaries [#error-boundaries]
State Persistence [#state-persistence]
Examples [#examples]
Explore our examples repository for implementation references.
LocalRuntimeOptions [#localruntimeoptions]
useDataStreamRuntime accepts all options from LocalRuntimeOptions in addition to its own options. These control the underlying local runtime behavior.
maxSteps [#maxsteps]
The maximum number of agentic steps (tool call rounds) allowed per run. Defaults to unlimited.
initialMessages [#initialmessages]
Pre-populate the thread with messages on first render. Useful for continuing an existing conversation.
adapters [#adapters]
Extend the runtime with optional capability adapters. The chatModel adapter is handled internally by useDataStreamRuntime and cannot be overridden here.
See the LocalRuntime adapters documentation for details on implementing each adapter.
cloud [#cloud]
Connect to Assistant Cloud for managed multi-thread support, persistence, and thread management.
unstable_humanToolNames [#unstable_humantoolnames]
Names of tools that should pause execution and wait for human or external approval before proceeding.
API Reference [#api-reference]
For detailed API documentation, see the @assistant-ui/react-data-stream API Reference.
URL: /docs/runtimes/helicone
Configure Helicone proxy for OpenAI API logging and monitoring.
Helicone acts as a proxy for your OpenAI API calls, enabling detailed logging and monitoring. To integrate, update your API base URL and add the Helicone-Auth header.
AI SDK by vercel [#ai-sdk-by-vercel]
LangChain Integration (Python) [#langchain-integration-python]
Summary [#summary]
Update your API base URL to https://oai.helicone.ai/v1 and add the Helicone-Auth header with your API key either in your Vercel AI SDK or LangChain configuration.
URL: /docs/runtimes/langserve
Connect to LangServe endpoints via Vercel AI SDK integration.
Overview [#overview]
Integration with a LangServe server via Vercel AI SDK.
Getting Started [#getting-started]
URL: /docs/runtimes/pick-a-runtime
Which runtime fits your backend? Decision guide for common setups.
Choosing the right runtime is crucial for your assistant-ui implementation. This guide helps you navigate the options based on your specific needs.
Quick Decision Tree [#quick-decision-tree]
Core Runtimes [#core-runtimes]
These are the foundational runtimes that power assistant-ui:
Pre-Built Integrations [#pre-built-integrations]
For popular frameworks, we provide ready-to-use integrations built on top of our core runtimes:
Understanding Runtime Architecture [#understanding-runtime-architecture]
How Pre-Built Integrations Work [#how-pre-built-integrations-work]
The pre-built integrations (AI SDK, LangGraph, etc.) are not separate runtime types. They're convenient wrappers built on top of our core runtimes:
This means you get all the benefits of LocalRuntime (automatic state management, built-in features) with zero configuration for your specific framework.
When to Use Pre-Built vs Core Runtimes [#when-to-use-pre-built-vs-core-runtimes]
Use a pre-built integration when:
Use a core runtime when:
Feature Comparison [#feature-comparison]
Core Runtime Capabilities [#core-runtime-capabilities]
Available Adapters [#available-adapters]
Common Implementation Patterns [#common-implementation-patterns]
Vercel AI SDK with Streaming [#vercel-ai-sdk-with-streaming]
Custom Backend with LocalRuntime [#custom-backend-with-localruntime]
Redux Integration with ExternalStoreRuntime [#redux-integration-with-externalstoreruntime]
Examples [#examples]
Explore our implementation examples:
Common Pitfalls to Avoid [#common-pitfalls-to-avoid]
LocalRuntime Pitfalls [#localruntime-pitfalls]
ExternalStoreRuntime Pitfalls [#externalstoreruntime-pitfalls]
General Pitfalls [#general-pitfalls]
Next Steps [#next-steps]
URL: /docs/utilities/heat-graph
Headless, composable activity heatmap components for React.
heat-graph provides headless, Radix-style primitives for building GitHub-style activity heatmap graphs.
Installation [#installation]
Quick Start [#quick-start]
Anatomy [#anatomy]
API Reference [#api-reference]
Root [#root]
The top-level provider. Renders a <div> that computes the grid layout and provides state to all children. Accepts all standard div props.
Grid [#grid]
A <div> with CSS Grid layout. Renders gridTemplateColumns and gridTemplateRows based on the computed data. Accepts all standard div props.
Iterates over cells internally, calling the children render function for each cell. Each cell is wrapped in a context that Cell reads from.
Cell [#cell]
A <div> that reads from cell context. Automatically applies:
Accepts all standard div props. Pass colorScale to override the Root-level color scale.
MonthLabels [#monthlabels]
Iterates over month labels, calling the children render function for each label.
Each label has { month: number, column: number }. Use totalWeeks to compute label positions. Use MONTH_SHORT[label.month] for English labels, or format with Intl.DateTimeFormat for localization.
DayLabels [#daylabels]
Iterates over day-of-week labels, calling the children render function for each label.
Each label has { dayOfWeek: number, row: number } where dayOfWeek is 0=Sun..6=Sat. Use DAY_SHORT[label.dayOfWeek] for English labels, or format with Intl.DateTimeFormat for localization.
Legend [#legend]
Iterates over legend levels, calling the children render function for each item. Each item has { level: number, color: string | undefined }.
LegendLevel [#legendlevel]
A <div> that reads from legend item context. Automatically applies backgroundColor from the color scale. Use inside Legend.
Tooltip [#tooltip]
Renders only when a cell is hovered. Positioned by Radix Popper relative to the hovered cell. Accepts Radix Popper Content props (side, sideOffset, align, etc.).
autoLevels(n) [#autolevelsn]
Default classification function. Maps counts into n evenly-distributed levels (0 to n-1). Level 0 is always count 0.
To provide a custom classifier:
MONTH_SHORT [#month_short]
English month abbreviations array: ["Jan", "Feb", ..., "Dec"]. Index by MonthLabel.month.
DAY_SHORT [#day_short]
English day abbreviations array: ["Sun", "Mon", ..., "Sat"]. Index by DayLabel.dayOfWeek.
URL: /docs/utilities/tw-shimmer
Tailwind CSS v4 plugin for shimmer effects.
tw-shimmer is a zero-dependency Tailwind CSS v4 plugin that provides polished shimmer animations for both text and skeleton loaders. It uses sine-eased gradients with 17 carefully calculated stops and OKLCH color mixing for smooth, banding-free effects.
See the interactive demo for live examples.
Installation [#installation]
Add to your CSS:
Quick Start [#quick-start]
Text Shimmer [#text-shimmer]
Skeleton Loader [#skeleton-loader]
Skeleton Card with Auto-Sizing [#skeleton-card-with-auto-sizing]
API Reference [#api-reference]
Core Utilities [#core-utilities]
shimmer [#shimmer]
Base utility for text shimmer. Applies a gradient animation over the text foreground color.
shimmer-bg [#shimmer-bg]
Background shimmer for skeleton loaders. Applies a gradient animation over the element's background. Requires a base bg-* class.
shimmer-container [#shimmer-container]
CSS-only auto-sizing helper using container queries. Sets container-type: inline-size and automatically derives speed and spread from the container width.
Customization Utilities [#customization-utilities]
All utilities are inheritable — set on a parent to affect all shimmer children.
Speed and Width [#speed-and-width]
Speed controls how fast the shimmer moves in pixels per second. Width tells the animation how wide the container is for timing calculations.
Color [#color]
Use any Tailwind color with optional opacity:
Angle [#angle]
Control the sweep direction. Default is 90deg (vertical sweep).
Position Hints (Angled Shimmer) [#position-hints-angled-shimmer]
For angled shimmers, use shimmer-x-{n} and shimmer-y-{n} to sync elements:
Repeat Delay [#repeat-delay]
Control the pause between animation cycles:
CSS Variables [#css-variables]
All values can be set via CSS variables for dynamic control:
Browser Support [#browser-support]
Uses modern CSS features: oklch(), color-mix(), independent translate transform, and CSS Container Queries.
Supported: Chrome 111+, Firefox 113+, Safari 16.4+
Older browsers degrade gracefully — shimmer effects simply won't appear.
URL: /docs/ui/accordion
A vertically stacked set of interactive headings that reveal or hide content sections.
Installation [#installation]
Usage [#usage]
Examples [#examples]
Variants [#variants]
Use the variant prop on Accordion to change the visual style. Child components inherit the variant automatically.
Multiple Items Open [#multiple-items-open]
Use type="multiple" to allow multiple items to be open simultaneously.
With Icons [#with-icons]
Add icons or custom elements inside the trigger.
Controlled [#controlled]
Use value and onValueChange for controlled accordion state.
FAQ Section [#faq-section]
A practical example of using accordion for a FAQ section.
API Reference [#api-reference]
Composable API [#composable-api]
Accordion [#accordion]
The root component that manages accordion state. Set variant here to style all child components.
AccordionItem [#accordionitem]
A single collapsible section container.
AccordionTrigger [#accordiontrigger]
The clickable header that toggles content visibility.
AccordionContent [#accordioncontent]
The collapsible content panel.
Style Variants (CVA) [#style-variants-cva]
URL: /docs/ui/assistant-modal
Floating chat bubble for support widgets and help desks.
A floating chat modal built on Radix UI Popover. Ideal for support widgets, help desks, and embedded assistants.
Getting Started [#getting-started]
Anatomy [#anatomy]
The AssistantModal component is built with the following primitives:
API Reference [#api-reference]
Root [#root]
Contains all parts of the modal. Based on Radix UI Popover.
Trigger [#trigger]
A button that toggles the modal open/closed state.
This primitive renders a <button> element unless asChild is set.
Content [#content]
The popover content container that holds the chat interface.
Anchor [#anchor]
An optional anchor element to position the modal relative to.
Related Components [#related-components]
URL: /docs/ui/assistant-sidebar
Side panel chat for co-pilot experiences and inline assistance.
A resizable side panel layout with your main content on the left and a Thread chat interface on the right. Ideal for co-pilot experiences and inline assistance.
Getting Started [#getting-started]
API Reference [#api-reference]
AssistantSidebar [#assistantsidebar]
A layout component that creates a resizable two-panel interface.
The component uses ResizablePanelGroup from shadcn/ui internally, creating:
Customization [#customization]
Since this component is copied to your project at /components/assistant-ui/assistant-sidebar.tsx, you can customize:
Related Components [#related-components]
URL: /docs/ui/attachment
UI components for attaching and viewing files in messages.
Getting Started [#getting-started]
API Reference [#api-reference]
Composer Attachments [#composer-attachments]
ComposerPrimitive.Attachments [#composerprimitiveattachments]
Renders all attachments in the composer.
ComposerPrimitive.AddAttachment [#composerprimitiveaddattachment]
A button that opens the file picker to add attachments.
This primitive renders a <button> element unless asChild is set.
Message Attachments [#message-attachments]
MessagePrimitive.Attachments [#messageprimitiveattachments]
Renders all attachments in a user message.
Attachment Primitives [#attachment-primitives]
AttachmentPrimitive.Root [#attachmentprimitiveroot]
Container for a single attachment.
AttachmentPrimitive.Name [#attachmentprimitivename]
Renders the attachment's file name.
AttachmentPrimitive.Remove [#attachmentprimitiveremove]
A button to remove the attachment from the composer.
Attachment Types [#attachment-types]
Attachments have the following structure:
The type field accepts custom strings (e.g. "data-workflow") beyond the built-in types. When an unknown type is encountered, the generic Attachment component is used as a fallback. The contentType field is optional — it can be omitted for non-file attachments where a MIME type is not meaningful.
Related Components [#related-components]
URL: /docs/ui/badge
A small label component for displaying status, categories, or metadata.
Installation [#installation]
Usage [#usage]
Examples [#examples]
Variants [#variants]
Use the variant prop to change the visual style.
Sizes [#sizes]
Use the size prop to change the badge size.
With Icons [#with-icons]
Badges automatically style SVG icons.
As Link [#as-link]
Use the asChild prop to render the badge as a different element, like a link.
Animated [#animated]
Combine with CSS transitions for scroll and color animations.
API Reference [#api-reference]
Badge [#badge]
Style Variants (CVA) [#style-variants-cva]
URL: /docs/ui/context-display
Visualize token usage relative to a model's context window — ring, bar, or text — with a detailed hover popover.
Getting Started [#getting-started]
Variants [#variants]
Three preset variants are available, each wrapping the shared tooltip popover:
All presets accept className for styling overrides and side to control tooltip placement ("top", "bottom", "left", "right").
Composable API [#composable-api]
For custom visualizations, use the building blocks directly:
API Reference [#api-reference]
Preset Props [#preset-props]
All preset variants (Ring, Bar, Text) share the same props:
Color Thresholds [#color-thresholds]
Ring and Bar share the same severity colors:
Text displays numeric values only — no severity color.
Related [#related]
URL: /docs/ui/diff-viewer
Render code diffs with syntax highlighting for additions and deletions.
Installation [#installation]
Usage [#usage]
As Markdown Language Override [#as-markdown-language-override]
Integrate with MarkdownTextPrimitive to render diff code blocks:
Examples [#examples]
Unified View [#unified-view]
Shows all changes in a single column with +/- indicators. This is the default mode.
Split View [#split-view]
Shows old content on the left, new content on the right side-by-side.
Interactive Mode Toggle [#interactive-mode-toggle]
Variants [#variants]
Sizes [#sizes]
Theming [#theming]
DiffViewer uses CSS variables for colors. Override them in your CSS:
API Reference [#api-reference]
DiffViewer [#diffviewer]
The main component for rendering diffs.
Composable API [#composable-api]
Style Variants (CVA) [#style-variants-cva]
Utilities [#utilities]
Styling [#styling]
Data Attributes [#data-attributes]
Use data attributes for custom styling:
Custom CSS Example [#custom-css-example]
Related Components [#related-components]
URL: /docs/ui/file
Display file message parts with icon, name, size, and download button.
Getting Started [#getting-started]
Variants [#variants]
Use the variant prop to change the visual style.
Sizes [#sizes]
Use the size prop to change padding and font size.
MimeType Icons [#mimetype-icons]
The component automatically selects an appropriate icon based on the file's MIME type:
API Reference [#api-reference]
Composable API [#composable-api]
The component exports composable sub-components:
Custom Icon [#custom-icon]
Pass children to File.Icon to override the default MIME type icon:
Utilities [#utilities]
The component also exports utility functions:
Related Components [#related-components]
URL: /docs/ui/image
Display image message parts with preview, loading states, and fullscreen dialog.
Getting Started [#getting-started]
Variants [#variants]
Use the variant prop to change the visual style.
Sizes [#sizes]
Use the size prop to control the maximum width.
API Reference [#api-reference]
Composable API [#composable-api]
The component exports composable sub-components:
Related Components [#related-components]
URL: /docs/ui/markdown
Display rich text with headings, lists, links, and code blocks.
Enabling markdown support [#enabling-markdown-support]
Syntax highlighting [#syntax-highlighting]
Syntax Highlighting is not included by default, see Syntax Highlighting to learn how to add it.
Related Components [#related-components]
URL: /docs/ui/mention
Let users @-mention tools in the composer with a keyboard-navigable popover picker and inline chips.
Getting Started [#getting-started]
With Lexical Rich Editor [#with-lexical-rich-editor]
For inline mention chips in the composer (not just the popover), use LexicalComposerInput from @assistant-ui/react-lexical:
Replace ComposerPrimitive.Input with LexicalComposerInput:
LexicalComposerInput auto-wires to MentionContext — no extra props needed. Selected mentions appear as inline chips that are treated as atomic units (select, delete, undo as a whole).
Custom Formatter [#custom-formatter]
The default directive format is :type[label]{name=id}. To use a custom format, pass a formatter to both the mention root and the message renderer:
Keyboard Navigation [#keyboard-navigation]
The mention popover supports full keyboard navigation out of the box:
Components [#components]
ComposerMentionPopover.Root [#composermentionpopoverroot]
Wraps the composer with mention context and a tool mention adapter. Provides the @-trigger detection, keyboard navigation, and popover state.
ComposerMentionPopover [#composermentionpopover]
Pre-built popover containing categories and items lists. Only renders when the @ trigger is active.
DirectiveText [#directivetext]
A TextMessagePartComponent that parses :type[label]{name=id} directives and renders them as styled inline chips.
createDirectiveText(formatter) [#createdirectivetextformatter]
Factory function that creates a TextMessagePartComponent using a custom Unstable_DirectiveFormatter.
URL: /docs/ui/mermaid
Render Mermaid diagrams in chat messages with streaming support.
Getting Started [#getting-started]
Configuration [#configuration]
Configure mermaid options in mermaid-diagram.tsx:
Streaming Performance [#streaming-performance]
The MermaidDiagram component is optimized for streaming scenarios:
Supported Diagram Types [#supported-diagram-types]
Mermaid supports various diagram types including:
See the Mermaid documentation for complete syntax reference.
Related Components [#related-components]
URL: /docs/ui/message-timing
Display streaming performance stats — TTFT, total time, tok/s, and chunk count — as a badge with hover popover.
Getting Started [#getting-started]
What It Shows [#what-it-shows]
The badge displays totalStreamTime inline and reveals a popover on hover with the full breakdown:
Accuracy [#accuracy]
Timing accuracy depends on how your backend is connected.
assistant-stream (accurate) [#assistant-stream-accurate]
When using assistant-stream on the backend, token counts come directly from the model's usage data sent in step-finish chunks. The tokensPerSecond metric is exact whenever your backend reports outputTokens.
Vercel AI SDK (estimated) [#vercel-ai-sdk-estimated]
When using the AI SDK integration (useChatRuntime), token counts are estimated client-side using a 4 characters per token approximation. This can overcount significantly for short messages.
API Reference [#api-reference]
MessageTiming component [#messagetiming-component]
Renders null until totalStreamTime is available (i.e., while streaming or for user messages).
For the underlying useMessageTiming() hook, field definitions, and runtime-specific setup (LocalRuntime, ExternalStore, etc.), see the Message Timing guide.
Related [#related]
URL: /docs/ui/model-selector
Model picker with unified overlay positioning and runtime integration.
A select component that lets users switch between AI models. Uses item-aligned positioning so the selected model overlays the trigger for a unified look. Integrates with assistant-ui's ModelContext system to automatically propagate the selected model to your backend.
Getting Started [#getting-started]
Variants [#variants]
Use the variant prop to change the trigger's visual style.
Sizes [#sizes]
Use the size prop to control the trigger dimensions.
Model Options [#model-options]
Each model in the models array supports:
Runtime Integration [#runtime-integration]
The default ModelSelector export automatically registers the selected model with assistant-ui's ModelContext system. When a user selects a model:
This works out of the box with @assistant-ui/react-ai-sdk.
API Reference [#api-reference]
Composable API [#composable-api]
For custom layouts, use the sub-components directly with ModelSelector.Root:
ModelSelector [#modelselector]
ModelOption [#modeloption]
URL: /docs/ui/part-grouping
Organize message parts into custom groups with flexible grouping functions.
Basic Usage [#basic-usage]
Use the MessagePrimitive.Unstable_PartsGrouped component with a custom grouping function:
How Grouping Works [#how-grouping-works]
The grouping function receives all message parts and returns an array of groups. Each group contains:
Use Cases & Examples [#use-cases--examples]
Group by Parent ID [#group-by-parent-id]
Group related content together using a parent-child relationship:
Group by Tool Name [#group-by-tool-name]
Organize tool calls by their type:
Group Consecutive Text Parts [#group-consecutive-text-parts]
Combine multiple text parts into cohesive blocks:
Group by Content Type [#group-by-content-type]
Separate different types of content for distinct visual treatment:
Group by Custom Metadata [#group-by-custom-metadata]
Use any custom metadata in your parts for grouping:
Integration with Assistant Streams [#integration-with-assistant-streams]
When using assistant-stream libraries, you can add custom metadata to parts:
Python (assistant-stream) [#python-assistant-stream]
TypeScript (assistant-stream) [#typescript-assistant-stream]
API Reference [#api-reference]
MessagePrimitive.Unstable_PartsGrouped [#messageprimitiveunstable_partsgrouped]
MessagePartGroup Type [#messagepartgroup-type]
Group Component Props [#group-component-props]
The Group component receives:
Best Practices [#best-practices]
Common Patterns [#common-patterns]
Conditional Grouping [#conditional-grouping]
Only group when certain conditions are met:
Nested Grouping [#nested-grouping]
Create hierarchical groups:
Dynamic Group Rendering [#dynamic-group-rendering]
Adjust group appearance based on content:
URL: /docs/ui/quote
Let users select and quote text from messages with a floating toolbar, composer preview, and inline quote display.
Getting Started [#getting-started]
Customization [#customization]
All three components expose sub-components for full control over styling:
API Reference [#api-reference]
QuoteBlock [#quoteblock]
Renders quoted text in user messages. Pass to MessagePrimitive.Parts as components.Quote.
Sub-components: QuoteBlock.Root, QuoteBlock.Icon, QuoteBlock.Text
SelectionToolbar [#selectiontoolbar]
Floating toolbar that appears when text is selected within a message. Renders as a portal positioned above the selection.
Sub-components: SelectionToolbar.Root, SelectionToolbar.Quote
ComposerQuotePreview [#composerquotepreview]
Quote preview inside the composer. Only renders when a quote is set.
Sub-components: ComposerQuotePreview.Root, ComposerQuotePreview.Icon, ComposerQuotePreview.Text, ComposerQuotePreview.Dismiss
injectQuoteContext [#injectquotecontext]
Extracts metadata.custom.quote from each message and prepends the quoted text as a > blockquote text part. Use before convertToModelMessages in your route handler. For alternative backend approaches, see the Quoting guide.
useMessageQuote [#usemessagequote]
Returns the quote attached to the current message, or undefined. Useful for building custom quote displays without QuoteBlock. For a usage example, see the Quoting guide.
ComposerRuntime.setQuote [#composerruntimesetquote]
Set or clear the quote on the composer programmatically. The quote is automatically cleared when the message is sent. For a usage example, see the Quoting guide.
Related [#related]
URL: /docs/ui/reasoning
Collapsible UI for displaying AI reasoning and thinking messages.
Getting Started [#getting-started]
How It Works [#how-it-works]
The component consists of two parts:
Consecutive reasoning parts are automatically grouped together by the ReasoningGroup component.
Variants [#variants]
Use the variant prop on Reasoning.Root to change the visual style:
ReasoningGroup [#reasoninggroup]
ReasoningGroup wraps consecutive reasoning parts in a collapsible container. It auto-expands during streaming.
API Reference [#api-reference]
Composable API [#composable-api]
All sub-components are exported for custom layouts:
Related Components [#related-components]
URL: /docs/ui/scrollbar
Replace the default scrollbar with a custom Radix UI scroll area.
If you want to show a custom scrollbar UI of the ThreadPrimitive.Viewport in place of the system default, you can integrate radix-ui's Scroll Area.
An example implementation of this is shadcn/ui's Scroll Area.
Related Components [#related-components]
URL: /docs/ui/select
A dropdown select component with composable sub-components.
Installation [#installation]
Usage [#usage]
Examples [#examples]
Variants [#variants]
Use the variant prop on SelectTrigger to change the visual style.
Sizes [#sizes]
Use the size prop on SelectTrigger to change the height.
Scrollable [#scrollable]
Long lists automatically become scrollable.
Groups [#groups]
Use the composable API for grouped options:
Disabled Items [#disabled-items]
With Placeholder [#with-placeholder]
Disabled Select [#disabled-select]
API Reference [#api-reference]
Composable API [#composable-api]
Select [#select]
A convenience component that renders a complete select with options.
SelectOption [#selectoption]
SelectTrigger [#selecttrigger]
The button that opens the dropdown.
Style Variants (CVA) [#style-variants-cva]
URL: /docs/ui/sources
Display URL sources with favicon, title, and external link.
Getting Started [#getting-started]
Variants [#variants]
Use the variant prop to change the visual style. The default is outline.
Sizes [#sizes]
Use the size prop to change the size.
API Reference [#api-reference]
Sources [#sources]
The default export used as a SourceMessagePartComponent. Renders a single source part when sourceType === "url". Also exposes compound sub-components for custom layouts.
Compound sub-components [#compound-sub-components]
Source [#source]
Root container rendered as an <a> tag. Accepts all <a> props plus variant and size.
SourceIcon [#sourceicon]
Displays the favicon for the given URL. Falls back to the domain initial inside a muted box when the favicon fails to load.
SourceTitle [#sourcetitle]
Truncated title text rendered as a <span>.
sourceVariants [#sourcevariants]
The underlying CVA variant function used to generate badge class names. Use this when building custom source-like components that need to match the built-in styling.
Composable API [#composable-api]
Use the named exports to build fully custom source layouts:
Related Components [#related-components]
URL: /docs/ui/streamdown
Alternative markdown renderer with built-in syntax highlighting, math, and diagram support.
Installation [#installation]
For additional features, install the optional plugins:
Basic Usage [#basic-usage]
With Plugins (Recommended) [#with-plugins-recommended]
When @streamdown/code is provided, the default theme is ["github-light", "github-dark"] for light/dark mode support.
Migration from react-markdown [#migration-from-react-markdown]
If you're migrating from @assistant-ui/react-markdown, your existing SyntaxHighlighter and CodeHeader components still work:
Props [#props]
Plugin Configuration [#plugin-configuration]
Code Highlighting [#code-highlighting]
Math (LaTeX) [#math-latex]
Mermaid Diagrams [#mermaid-diagrams]
CJK Text Optimization [#cjk-text-optimization]
Advanced Configuration [#advanced-configuration]
Mermaid Options [#mermaid-options]
Customize Mermaid diagram rendering with configuration and error handling:
Streaming Caret [#streaming-caret]
Display a caret indicator during streaming:
Link Safety [#link-safety]
Show confirmation before opening external links:
Incomplete Markdown Handling (Remend) [#incomplete-markdown-handling-remend]
Configure how incomplete markdown syntax is handled during streaming:
Allowed HTML Tags [#allowed-html-tags]
Allow specific HTML tags in markdown content:
Security Configuration [#security-configuration]
Restrict allowed URLs for links and images. This overrides streamdown's default allow-all policy:
Detecting Inline vs Block Code [#detecting-inline-vs-block-code]
When building custom code components, you can use useIsStreamdownCodeBlock to detect whether you're inside a code block or inline code:
You can also use useStreamdownPreProps to access the props passed to the parent <pre> element:
Comparison with react-markdown [#comparison-with-react-markdown]
Re-exported Utilities [#re-exported-utilities]
The package re-exports useful utilities:
Available Types [#available-types]
Related Components [#related-components]
URL: /docs/ui/syntax-highlighting
Code block syntax highlighting with react-shiki or react-syntax-highlighter.
react-shiki [#react-shiki]
Options [#options]
See react-shiki documentation for all available options.
Key options:
Dual/multi theme support [#dualmulti-theme-support]
To use multiple themes, pass a theme object:
With defaultColor="light-dark()", theme switching is automatic based on your site's color-scheme.
No custom Shiki CSS overrides are required.
Set color-scheme on your app root:
System-based (follows OS/browser preference):
Class-based theme switching:
If you need broader support for older browsers, you can still use the manual CSS-variable switching approach from the Shiki dual-theme docs.
For more information:
Bundle Optimization [#bundle-optimization]
By default, react-shiki includes the full Shiki bundle, which contains all supported languages and themes.
To reduce bundle size, you can use the web bundle by changing the import to react-shiki/web, to include a smaller bundle of web related languages:
Custom Bundles [#custom-bundles]
For strict bundle size control, react-shiki also supports custom bundles created using createHighlighterCore from react-shiki/core (re-exported from Shiki):
react-syntax-highlighter [#react-syntax-highlighter]
Options [#options-1]
Supports all options from react-syntax-highlighter.
Bundle Optimization [#bundle-optimization-1]
By default, the syntax highlighter uses a light build that only includes languages you register. To include all languages:
Related Components [#related-components]
URL: /docs/ui/tabs
A multi-variant tabs component for organizing content into switchable panels.
Installation [#installation]
Usage [#usage]
Examples [#examples]
Variants [#variants]
Use the variant prop on TabsList to change the visual style. Child components inherit the variant automatically.
Sizes [#sizes]
Use the size prop on TabsList to change the tab height. Child components inherit the size automatically.
With Icons [#with-icons]
Tabs automatically style SVG icons placed inside triggers.
Controlled [#controlled]
Use value and onValueChange for controlled tab state.
As Link [#as-link]
Use the asChild prop on TabsTrigger to render as a different element, like a navigation link.
Animated Indicator [#animated-indicator]
All variants feature smooth animated indicators that slide between tabs:
API Reference [#api-reference]
Composable API [#composable-api]
Tabs [#tabs]
The root component that manages tab state.
TabsList [#tabslist]
The container for tab triggers. Set variant and size here to style all child components.
TabsTrigger [#tabstrigger]
An individual tab button.
TabsContent [#tabscontent]
The content panel for a tab.
Style Variants (CVA) [#style-variants-cva]
URL: /docs/ui/thread-list
Switch between conversations. Supports sidebar or dropdown layouts.
Getting Started [#getting-started]
Anatomy [#anatomy]
The ThreadList component is built with the following primitives:
API Reference [#api-reference]
ThreadListPrimitive.Root [#threadlistprimitiveroot]
Container for the thread list.
ThreadListPrimitive.Items [#threadlistprimitiveitems]
Renders all threads in the list.
ThreadListPrimitive.New [#threadlistprimitivenew]
A button to create a new thread.
ThreadListItemPrimitive.Root [#threadlistitemprimitiveroot]
Container for a single thread item. Automatically sets data-active and aria-current when this is the current thread.
ThreadListItemPrimitive.Trigger [#threadlistitemprimitivetrigger]
A button that switches to this thread when clicked.
ThreadListItemPrimitive.Title [#threadlistitemprimitivetitle]
Renders the thread's title.
ThreadListItemPrimitive.Archive [#threadlistitemprimitivearchive]
A button to archive the thread.
ThreadListItemPrimitive.Unarchive [#threadlistitemprimitiveunarchive]
A button to restore an archived thread.
ThreadListItemPrimitive.Delete [#threadlistitemprimitivedelete]
A button to permanently delete the thread.
ThreadListItemMorePrimitive [#threadlistitemmoreprimitive]
A dropdown menu for additional thread actions, built on Radix UI DropdownMenu.
ThreadListItemMorePrimitive.Root [#threadlistitemmoreprimitiveroot]
Menu container that manages dropdown state.
ThreadListItemMorePrimitive.Trigger [#threadlistitemmoreprimitivetrigger]
Button to open the menu.
ThreadListItemMorePrimitive.Content [#threadlistitemmoreprimitivecontent]
Menu content container.
ThreadListItemMorePrimitive.Item [#threadlistitemmoreprimitiveitem]
Individual menu item.
ThreadListItemMorePrimitive.Separator [#threadlistitemmoreprimitiveseparator]
Visual separator between items.
Related Components [#related-components]
URL: /docs/ui/thread
The main chat container with messages, composer, and auto-scroll.
A complete chat interface that combines message rendering, auto-scrolling, composer input, attachments, and conditional UI states. Fully customizable and composable.
Anatomy [#anatomy]
The Thread component is built with the following primitives:
Getting Started [#getting-started]
Examples [#examples]
Welcome Screen [#welcome-screen]
Viewport Spacer [#viewport-spacer]
Conditional Send/Cancel Button [#conditional-sendcancel-button]
Suggestions [#suggestions]
Display suggested prompts using the Suggestions API. See the Suggestions guide for detailed configuration.
API Reference [#api-reference]
The following primitives are used within the Thread component and can be customized in your /components/assistant-ui/thread.tsx file.
Root [#root]
Contains all parts of the thread.
This primitive renders a <div> element unless asChild is set.
Viewport [#viewport]
The scrollable area containing all messages. Automatically scrolls to the bottom as new messages are added.
This primitive renders a <div> element unless asChild is set.
Messages [#messages]
Renders all messages in the thread. This primitive renders a separate component for each message.
MessageByIndex [#messagebyindex]
Renders a single message at the specified index.
Empty [#empty]
Renders children only when there are no messages in the thread.
ScrollToBottom [#scrolltobottom]
A button to scroll the viewport to the bottom. Disabled when the viewport is already at the bottom.
This primitive renders a <button> element unless asChild is set.
Suggestions [#suggestions-1]
Renders all configured suggestions. Configure suggestions using the Suggestions() API in your runtime provider.
AuiIf [#auiif]
Conditionally renders children based on assistant state. This is a generic component that can access thread, message, composer, and other state.
Related Components [#related-components]
URL: /docs/ui/tool-fallback
Default UI component for tools without dedicated custom renderers.
Getting Started [#getting-started]
Examples [#examples]
Streaming Demo [#streaming-demo]
Interactive demo showing the full tool call lifecycle: running → complete.
Running State [#running-state]
Shows a loading spinner and shimmer animation while the tool is executing.
Cancelled State [#cancelled-state]
Shows a muted appearance when a tool call was cancelled.
Composable API [#composable-api]
All sub-components are exported for custom layouts:
Related Components [#related-components]
URL: /docs/ui/tool-group
Wrapper for consecutive tool calls with collapsible and styled options.
A wrapper component that groups consecutive tool calls together, displaying them in a collapsible container with auto-expand behavior during streaming.
Getting Started [#getting-started]
Variants [#variants]
Use the variant prop on ToolGroup.Root to change the visual style:
Examples [#examples]
Streaming Demo (Custom UI + Fallback) [#streaming-demo-custom-ui--fallback]
Interactive demo showing tool group with custom tool UIs and ToolFallback working together. Watch as weather cards stream in with loading states, followed by a search tool using the fallback UI.
Custom Tool UIs [#custom-tool-uis]
ToolGroup works with any custom tool UI components:
Composable API [#composable-api]
All sub-components are exported for custom layouts:
API Reference [#api-reference]
ToolGroupRoot [#toolgrouproot]
ToolGroupTrigger [#toolgrouptrigger]
ToolGroup (Default Export) [#toolgroup-default-export]
Related Components [#related-components]
URL: /docs/copilots/assistant-frame
Share model context across iframe boundaries
The Assistant Frame API enables iframes to provide model context (tools and instructions) to a parent window's assistant. This is particularly useful for embedded applications, plugins, or sandboxed components that need to contribute capabilities to the main assistant.
Overview [#overview]
The Assistant Frame system consists of two main components:
Basic Usage [#basic-usage]
In the iframe (Provider) [#in-the-iframe-provider]
The iframe acts as a provider of model context using AssistantFrameProvider:
In the parent window (Host) [#in-the-parent-window-host]
The parent window consumes the iframe's context using AssistantFrameHost:
Advanced Usage [#advanced-usage]
ModelContextRegistry [#modelcontextregistry]
The ModelContextRegistry provides a flexible way to manage model context dynamically:
Multiple Providers [#multiple-providers]
You can register multiple model context providers in the same iframe:
Security Considerations [#security-considerations]
Origin Validation [#origin-validation]
Both the provider and host can specify allowed origins for security:
Tool Execution [#tool-execution]
Tools are executed in the iframe's context, keeping sensitive operations sandboxed:
API Reference [#api-reference]
AssistantFrameProvider [#assistantframeprovider]
Static class that manages model context providers in an iframe.
Methods [#methods]
addModelContextProvider(provider, targetOrigin?) [#addmodelcontextproviderprovider-targetorigin]
Registers a model context provider to share with parent windows.
dispose() [#dispose]
Cleans up all resources and removes all providers.
AssistantFrameHost [#assistantframehost]
Class that connects to an iframe's model context providers.
Constructor [#constructor]
Methods [#methods-1]
getModelContext() [#getmodelcontext]
Returns the current merged model context from the iframe.
subscribe(callback) [#subscribecallback]
Subscribes to model context changes.
dispose() [#dispose-1]
Cleans up the connection to the iframe.
useAssistantFrameHost [#useassistantframehost]
React hook that manages the lifecycle of an AssistantFrameHost.
ModelContextRegistry [#modelcontextregistry-1]
A flexible registry for managing model context with dynamic updates.
Methods [#methods-2]
addTool(tool) [#addtooltool]
Adds a tool and returns a handle for updates/removal.
addInstruction(instruction) [#addinstructioninstruction]
Adds a system instruction and returns a handle.
addProvider(provider) [#addproviderprovider]
Adds another model context provider.
Use Cases [#use-cases]
Embedded Analytics Dashboard [#embedded-analytics-dashboard]
An analytics iframe can provide data query tools to the parent assistant:
Plugin System [#plugin-system]
Third-party plugins can extend the assistant's capabilities:
Data Visualization [#data-visualization]
Provide data visualization tools in an iframe:
URL: /docs/copilots/make-assistant-tool-ui
Register custom UI components to render tool executions and their status.
The makeAssistantToolUI utility is used to register a tool UI component with the Assistant.
Usage [#usage]
API [#api]
Parameters [#parameters]
<ParametersTable type="AssistantToolUIProps<TArgs, TResult>" parameters="[ { name: "toolName", type: "string", description: "The name of the tool. This must match the name of the tool defined in the assistant.", }, { name: "render", type: "ComponentType<ToolCallMessagePartProps<TArgs, TResult>>", description: "A React component that renders the tool UI. Receives the following props:", required: true, children: [ { type: "ToolCallMessagePartProps<TArgs, TResult>", parameters: [ { name: "type", type: '"tool-call"', description: "The message part type", }, { name: "toolCallId", type: "string", description: "Unique identifier for this tool call", }, { name: "toolName", type: "string", description: "The name of the tool being called", }, { name: "args", type: "TArgs", description: "The arguments passed to the tool", }, { name: "argsText", type: "string", description: "String representation of the arguments", }, { name: "result", type: "TResult | undefined", description: "The result of the tool execution (if complete)", }, { name: "isError", type: "boolean | undefined", description: "Whether the result is an error", }, { name: "status",