Component
Agent chat shell
Agent chatA resizable AI chat shell for conversations, tools, and text or audio handoff.
Demo
Store-backed agent workspace
A Pinia setup store drives conversation loading, sidebar selection, closable split panels, streaming assistant parts, text/audio mode switching, and custom tool-call rendering.
Agent conversation
Ask, inspect, and continue the work in one thread.
No messages yet
Select a conversation or start a new one.
Agent conversation
Ask, inspect, and continue the work in one thread.
No messages yet
Select a conversation or start a new one.
Demo API
Last request and response
Request
{}Response
{}Active agent
Loading agent
The selected conversation controls this panel.
Request log
Architecture
Reusable component split
Shell
DomAgentChatShell composes the sidebar, conversation, and aside using split panels. Apps can use it full screen or replace any pane with slots.
Conversation
DomAgentConversation owns the header, scroll-contained message viewport, composer footer, autoscroll, and tool rendering.
List
DomAgentConversationList is a dedicated conversation picker for full app shells, popovers, drawers, and focused chat panels.
Data contract
Message parts
The conversation component renders ordered message parts. Text, audio, handoff, reasoning summaries, tool calls, and tool results can appear in one assistant message while a stream is still active.
Use reasoning parts for safe reasoning summaries or product-owned traces. Keep hidden model reasoning private unless your backend intentionally stores a reviewed trace that users are allowed to inspect.
API
Streaming endpoint shape
The demo API uses callbacks so it can run in the docs without infrastructure. A production endpoint can deliver the same events over SSE, a WebSocket, a fetch stream, or a queue worker bridge.
Tool calls are ordinary message parts. If the frontend has no renderer for a tool, the conversation uses the generic argument/result card. If a renderer exists, it receives the full tool part and parent message.
Custom tools
Renderer map
Store
Pinia integration
The exported store factory keeps the component transport-free. It owns active conversation state, panel state, composer state, stream cancellation, and request logging, while your API adapter owns persistence and streaming transport.
Reference
Props
Control props
| Name | Type | TS | Default | Description |
|---|---|---|---|---|
conversations | array | Array<unknown> | [] | Conversation summaries for the sidebar. |
conversation | object | Record<string, unknown> | — | Active conversation record. |
messages | array | Array<unknown> | [] | Messages for the active conversation. |
agents | array | Array<unknown> | [] | Agents available to the chat shell. |
activeConversationId | string | string | '' | Selected conversation id. |
modelValue | string | string | '' | Controlled composer text. |
mode | 'text' | 'audio' | string | 'text' | Active composer mode. |
search | string | string | '' | Controlled sidebar search value. |
streaming | boolean | boolean | false | Whether the active assistant response is streaming. |
loading | boolean | boolean | false | Whether active conversation messages are loading. |
sidebarOpen | boolean | boolean | true | Controls the conversation sidebar visibility. |
asideOpen | boolean | boolean | true | Controls the contextual aside visibility. |
sidebarSize | number | number | 300 | Resizable sidebar width in pixels. |
asideSize | number | number | 340 | Resizable aside width in pixels. |
minSidebar | number | number | 240 | Minimum sidebar width while open. |
minConversation | number | number | 420 | Minimum center conversation width. |
minAside | number | number | 280 | Minimum aside width while open. |
toolComponents | object | Record<string, unknown> | {} | Tool renderer component map passed through to DomAgentConversation. |
title | string | string | 'Agent workspace' | Accessible label for the chat application shell. |
Auto-generated from Agent chat shell.props and inline _edit hints.
Events
| Name | Payload | Description |
|---|---|---|
| @update:modelValue | string | Passes composer updates from the conversation component. |
| @update:mode | 'text' | 'audio' | Passes audio/text mode changes from the conversation component. |
| @update:search | string | Passes sidebar search updates. |
| @update:sidebarOpen | boolean | Fired when the sidebar is opened or closed. |
| @update:asideOpen | boolean | Fired when the aside is opened or closed. |
| @update:sidebarSize | number | Fired when the sidebar splitter changes width. |
| @update:asideSize | number | Fired when the aside splitter changes width. |
| @select-conversation | conversation | Fired when a sidebar row is selected. |
| @new-conversation | undefined | Fired when the sidebar new button is activated. |
| @submit | ({ content, mode, conversation }) | Fired when the composer submits. |
| @stop | ({ conversation }) | Fired when streaming is stopped. |
| @tool-action | ({ action, tool, message }) | Fired by generic or custom tool renderers. |
Names auto-detected from defineEmits and source emit() calls; payload and description from __doc.events when present.
Slots
| Name | Scope | Description |
|---|---|---|
| #sidebar | { conversations, activeConversationId } | Replace the conversation sidebar. |
| #conversation | { conversation, messages, activeAgent } | Replace the main conversation component. |
| #aside | { conversation, activeAgent, toolParts } | Replace the contextual aside. |
DomAgentConversation
Props
Control props
| Name | Type | TS | Default | Description |
|---|---|---|---|---|
conversation | object | Record<string, unknown> | — | Active conversation record. Used for the header, status, and empty state context. |
messages | array | Array<unknown> | [] | Ordered conversation messages. Messages may contain text, reasoning, audio, handoff, and tool-call parts. |
agents | array | Array<unknown> | [] | Agents that can author assistant messages or be displayed in the header. |
modelValue | string | string | '' | Controlled composer text. |
mode | 'text' | 'audio' | string | 'text' | Active composer modality. |
streaming | boolean | boolean | false | Show the stop control and live status while the assistant response streams. |
loading | boolean | boolean | false | Show a loading state before conversation messages are available. |
autoScroll | boolean | boolean | true | Keep the scroller pinned to the bottom while new content arrives. |
showHeader | boolean | boolean | true | Render the built-in conversation header. |
showFooter | boolean | boolean | true | Render the built-in composer footer. |
showReasoning | boolean | boolean | true | Render reasoning summary parts when the supplied message data includes them. |
placeholder | string | string | 'Ask the agent to plan, inspect, or create...' | Composer placeholder text. |
emptyText | string | string | 'Select a conversation or start a new one.' | Message shown when there are no messages. |
disabled | boolean | boolean | false | Disable composer input and send controls. |
toolComponents | object | Record<string, unknown> | {} | Component map keyed by tool rendererKey or tool name. Falls back to the generic tool card. |
maxMessageWidth | string | string | '48rem' | CSS max-width applied to message bubbles. |
Auto-generated from Agent conversation.props and inline _edit hints.
Events
| Name | Payload | Description |
|---|---|---|
| @update:modelValue | string | Fired when the composer text changes. |
| @update:mode | 'text' | 'audio' | Fired when the composer switches between text and audio mode. |
| @submit | ({ content, mode, conversation }) | Fired when the user submits the composer. |
| @stop | ({ conversation }) | Fired when the user stops an active stream. |
| @tool-action | ({ action, tool, message }) | Fired by generic and custom tool renderers for approvals, retries, and inspection. |
| @scroll-bottom | ({ conversation }) | Fired when the built-in jump-to-bottom control is used. |
Names auto-detected from defineEmits and source emit() calls; payload and description from __doc.events when present.
Slots
| Name | Scope | Description |
|---|---|---|
| #header-leading | { conversation, activeAgent } | Controls shown before the title, useful for opening an app sidebar. |
| #header-actions | { conversation, activeAgent, streaming } | Controls shown at the end of the header. |
| #message | { message, activeAgent, parts } | Replace the full message renderer. |
| #tool | { tool, message, component, action } | Replace generic tool rendering without supplying toolComponents. |
| #composer-actions | { mode, setMode, disabled, streaming } | Extra controls inside the composer row. |
| #footer | { value, mode, submit, setMode } | Replace the built-in composer footer. |
| #empty | — | Custom empty conversation state. |
DomAgentConversationList
Props
Control props
| Name | Type | TS | Default | Description |
|---|---|---|---|---|
conversations | array | Array<unknown> | [] | Conversation summaries shown in the navigation list. |
agents | array | Array<unknown> | [] | Agent records used to label each conversation. |
activeConversationId | string | string | '' | Selected conversation id. |
search | string | string | '' | Controlled conversation search value. |
loading | boolean | boolean | false | Show loading rows while conversations are fetched. |
title | string | string | 'Conversations' | Sidebar heading. |
showNewButton | boolean | boolean | true | Show the built-in new conversation button. |
emptyText | string | string | 'No conversations match this view.' | Message shown when the filtered list is empty. |
Auto-generated from Agent conversation list.props and inline _edit hints.
Events
| Name | Payload | Description |
|---|---|---|
| @update:search | string | Fired when the sidebar search changes. |
| @select | conversation | Fired when a conversation row is selected. |
| @new | undefined | Fired when the new conversation action is activated. |
Names auto-detected from defineEmits and source emit() calls; payload and description from __doc.events when present.
Slots
| Name | Scope | Description |
|---|---|---|
| #actions | { conversations } | Extra controls beside the heading. |
| #conversation | { conversation, active, agent } | Replace a conversation row. |
| #empty | — | Custom empty state. |