# Agent UI — Complete Documentation > **@agent-ui/react** — 24 shadcn-style React components for building ChatGPT-class chat interfaces. WCAG AA, TypeScript, zero vendor lock-in. **Version:** 0.1.0 **License:** MIT **Repository:** https://github.com/agent-ui/agent-ui **npm:** https://npmjs.com/@agent-ui/react **Install:** `pnpm add @agent-ui/react` --- ## Table of Contents 1. [Installation](#installation) 2. [Core Chat Components](#core-chat-components) - [MessageBubble](#messagebubble) - [Composer](#composer) - [MessageList](#messagelist) - [ChatShell](#chatshell) - [useChat](#usechat) 3. [Display Components](#display-components) - [MarkdownContent](#markdowncontent) - [CodeBlock](#codeblock) - [Skeleton](#skeleton) 4. [Streaming Components](#streaming-components) - [StreamingText](#streamingtext) - [TypingIndicator](#typingindicator) - [StopButton](#stopbutton) - [CancelledBadge](#cancelledbadge) 5. [Agent / Tool Components](#agent--tool-components) - [ToolCallCard](#toolcallcard) - [ToolResult](#toolresult) - [ThinkingBlock](#thinkingblock) - [SourceCard](#sourcecard) 6. [Model / Provider Components](#model--provider-components) - [ModelPicker](#modelpicker) - [ProviderSelector](#providerselector) 7. [Input Components](#input-components) - [Button](#button) - [SuggestionChips](#suggestionchips) 8. [Chrome Components](#chrome-components) - [ConversationSidebar](#conversationsidebar) - [FeedbackButtons](#feedbackbuttons) - [BranchPicker](#branchpicker) 9. [Protocol](#protocol) - [dcmp](#dcmp) 10. [Demo Apps](#demo-apps) 11. [Architecture](#architecture) 12. [Accessibility](#accessibility) --- ## Installation ```bash pnpm add @agent-ui/react ``` Each component is importable from its own subpath: ```tsx import { MessageBubble } from "@agent-ui/react/message-bubble"; import { Composer } from "@agent-ui/react/composer"; import { useChat } from "@agent-ui/react/use-chat"; ``` Or import everything from the barrel: ```tsx import { Button, MessageBubble, ChatShell } from "@agent-ui/react"; ``` --- ## Core Chat Components ### MessageBubble A chat message bubble with role-based styling. Supports user, assistant, and system roles. **Import:** `@agent-ui/react/message-bubble` ```tsx import { MessageBubble } from "@agent-ui/react/message-bubble"; ``` #### Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `role` | `"user" \| "assistant" \| "system"` | required | Message role determines alignment and styling | | `children` | `ReactNode` | required | Message content | | `avatar?` | `string` | — | Avatar image URL | | `name?` | `string` | — | Display name | | `timestamp?` | `Date` | — | Message timestamp | | `status?` | `"sending" \| "sent" \| "error"` | — | Delivery status indicator | | `className?` | `string` | — | Additional CSS classes | #### Example ```tsx Hello! How can I help you today? ``` #### Accessibility - Uses `
` with `role="article"` - `aria-label` set to "User message" / "Assistant message" / "System message" - Status text rendered visually for delivery state --- ### Composer A compound component for chat input with multiple slots. Uses React Context for state sharing between sub-components. **Import:** `@agent-ui/react/composer` ```tsx import { Composer } from "@agent-ui/react/composer"; ``` #### Composer Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `onSend?` | `(text: string, attachments: File[]) => void` | — | Send handler | | `disabled?` | `boolean` | — | Disables input and send | | `className?` | `string` | — | Additional CSS classes | | `children` | `ReactNode` | required | Slot components | #### Slots | Slot | Description | |------|-------------| | `Composer.Input` | Auto-resizing `textarea` with `@` mention detection, Enter to send, Shift+Enter for newline | | `Composer.SendButton` | Send button, disabled when text is empty | | `Composer.ProviderModelSlot` | Container for provider/model selector | | `Composer.SkillSlot` | Container for skill selector | | `Composer.AttachmentSlot` | Container for attachment preview | | `Composer.SearchToggle` | Toggle button for web search (`aria-pressed`) | | `Composer.ThinkingToggle` | Cycling toggle: off → low → medium → high → off | | `Composer.MentionMenu` | Conditional `@` mention suggestions `listbox` | #### Composer.Input Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `placeholder?` | `string` | `"Type a message..."` | Input placeholder | | `className?` | `string` | — | Additional CSS classes | #### Example ```tsx console.log(text)}> ``` #### SimpleComposer A pre-composed variant with just Input + SendButton: ```tsx console.log(text)} /> ``` #### Accessibility - Textarea has `role="textbox"` and `aria-label="Message composer"` - Send button has `aria-label="Send message"` - Toggle buttons use `aria-pressed` for state - MentionMenu uses `role="listbox"` and `aria-label="Mention suggestions"` --- ### MessageList ARIA live region container for chat messages with auto-scroll and empty state. **Import:** `@agent-ui/react/message-list` ```tsx import { MessageList } from "@agent-ui/react/message-list"; ``` #### Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `children?` | `ReactNode` | — | Message elements | | `emptyMessage?` | `ReactNode` | `"Start a conversation"` | Empty state content | | `isLoading?` | `boolean` | — | Shows loading state | | `className?` | `string` | — | Additional CSS classes | #### Example ```tsx {messages.map(msg => ( {msg.content} ))} ``` #### Accessibility - `role="log"` with `aria-live="polite"` for dynamic content announcements - `aria-relevant="additions text"` for screen reader updates - Focusable via `tabIndex={0}` for keyboard scrolling --- ### ChatShell A pre-composed chat interface combining MessageList, MessageBubble, Composer, TypingIndicator, StopButton, and CancelledBadge. **Import:** `@agent-ui/react/chat-shell` ```tsx import { ChatShell } from "@agent-ui/react/chat-shell"; ``` #### Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `messages` | `ChatMessage[]` | required | Array of chat messages | | `isStreaming?` | `boolean` | — | Shows typing indicator + stop button | | `error?` | `string \| null` | — | Shows error badge | | `onSend?` | `(text: string) => void` | — | Send handler | | `onStop?` | `() => void` | — | Stop generation handler | | `placeholder?` | `string` | — | Composer placeholder | | `className?` | `string` | — | Additional CSS classes | #### Example ```tsx function App() { const { messages, isStreaming, error, send, stop } = useChat({ onSend: async (text) => { /* API call */ return response; }, }); return ( ); } ``` --- ### useChat React hook for chat state management. **Import:** `@agent-ui/react/use-chat` ```tsx import { useChat } from "@agent-ui/react/use-chat"; ``` #### Types ```tsx interface ChatMessage { id: string; role: "user" | "assistant" | "system"; content: string; timestamp: Date; status?: "sending" | "sent" | "error"; name?: string; } interface UseChatOptions { initialMessages?: ChatMessage[]; onSend?: (message: string) => Promise; } ``` #### Returns | Property | Type | Description | |----------|------|-------------| | `messages` | `ChatMessage[]` | Current messages | | `isStreaming` | `boolean` | True during response generation | | `error` | `string \| null` | Error message if send failed | | `send` | `(text: string) => Promise` | Send a message, await response | | `stop` | `() => void` | Stop current generation | | `clear` | `() => void` | Clear all messages | #### Example ```tsx const { messages, isStreaming, send, stop, clear } = useChat({ initialMessages: [{ id: "1", role: "assistant", content: "Hi!", timestamp: new Date() }], onSend: async (text) => { const res = await fetch("/api/chat", { method: "POST", body: JSON.stringify({ text }) }); return res.text(); }, }); ``` --- ## Display Components ### MarkdownContent Renders GFM markdown with XSS protection. Supports headings, bold, inline code, fenced code blocks, links (with target="_blank"), ordered/unordered lists, and blockquotes. **Import:** `@agent-ui/react/markdown-content` ```tsx import { MarkdownContent } from "@agent-ui/react/markdown-content"; ``` #### Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `content` | `string` | required | Markdown string | | `className?` | `string` | — | Additional CSS classes | #### Example ```tsx ``` #### Security - Strips `