Skip to content

Type Alias: ChatViewProps

ChatViewProps = object

optional activeThreadId?: string

Id of the currently-active thread, highlighted in the sidebar.


optional className?: string

Extra classes merged onto the root layout container.


optional defaultModelName?: string

The serving-endpoint fallback the server uses when no model is pinned, already humanized (the server’s displayName, e.g. “Claude Sonnet 4.6”). When set, the picker’s default option shows this name; otherwise it shows a neutral “Default”. Never a raw endpoint id.


optional error?: Error | null

The error from the last failed turn, surfaced as a destructive Alert when status is "error". When omitted, the Alert shows a generic message. useMastraChat populates it on the drop-in path; a host driving ChatView itself supplies its own.


optional feedbackByMessage?: Record<string, MessageFeedback>

Feedback state keyed by assistant message id. Only messages with an entry (i.e. a captured MLflow trace id) show feedback controls, so this doubles as the “is feedback available for this message” gate. useMastraChat populates it from each streamed turn’s trace-id response header when MLflow logging is enabled.


optional hasMore?: boolean

True when more history is still available (drives the trigger).


optional isLoadingHistory?: boolean

True while the initial history page is loading.


optional isLoadingMore?: boolean

True while a ChatViewProps.onLoadMore fetch is in flight.


optional isLoadingThreads?: boolean

True while the initial thread list is loading (drives a sidebar spinner).


messages: UIMessage[]


optional model?: string

Currently selected model name; empty string means “use server default”.


optional models?: ChatModelOption[]

Available model endpoints. Pass an empty array (or omit) to hide the picker.


optional onCancelThread?: (threadId) => void

Cancel a thread’s in-flight run by id, without switching to it. When provided, each running sidebar row shows a stop affordance next to its streaming indicator (see streamingThreadIds). Isolated to that thread - other threads keep streaming.

string

void


optional onClear?: () => void | Promise<void>

Wipe the current chat thread. When provided, the header renders a “Clear” button that calls this and shows a confirmation prompt first. The handler is responsible for both the server-side delete (typically mastraClient.clearHistory()) and resetting client-side transcript / tool-event state so the blank slate sticks across the next render. Omit to hide the button entirely (read-only embeds, history-less agents).

void | Promise<void>


optional onDeleteThread?: (threadId) => void

Delete a conversation by id. The handler removes it server-side and refreshes the list; deleting the active thread starts a new one. When provided, each sidebar row shows a delete affordance.

string

void


optional onExportConversation?: (format) => void | Promise<void>

Export the whole conversation in the chosen ExportFormat (PDF via the browser print dialog, or a Markdown download). When provided, the header shows an Export menu. Charts and data tables are inlined into the export. Omit to hide conversation-level export.

ExportFormat

void | Promise<void>


optional onExportMessage?: (message, format) => void | Promise<void>

Export a single message in the chosen ExportFormat. When provided, each assistant bubble shows a per-message export menu.

UIMessage

ExportFormat

void | Promise<void>


optional onFeedback?: (message, submission) => void | Promise<void>

Submit thumbs / comment feedback for an assistant message. When provided (and the message has a feedbackByMessage entry), the bubble shows thumbs up/down plus a comment affordance. The handler logs the feedback to MLflow via the plugin’s feedback route.

UIMessage

FeedbackSubmission

void | Promise<void>


optional onLoadMore?: () => void

Optional infinite-scroll-up handler. Fired when the user scrolls within TOP_LOAD_MORE_THRESHOLD_PX of the top of the transcript. The parent is expected to fetch the next older page and prepend it to messages; the view preserves the visual scroll position across the prepend so the reveal feels like paging up through history rather than a layout jump.

void


optional onModelChange?: (model) => void

string

void


optional onNewThread?: () => void

Start a fresh conversation. The handler mints a new thread id, clears the transcript, and points subsequent turns at it. When provided, the sidebar shows a “New chat” affordance.

void


optional onRemoveSteer?: (steerId) => void

Drop a queued steer without sending it.

string

void


optional onRenameThread?: (threadId, title) => void

Rename a conversation by id. The handler persists the new title server-side and updates the list (optimistically, so the new name shows immediately). When provided, each sidebar row shows a rename affordance that swaps the title into an inline text field.

string

string

void


optional onReorderSteers?: (orderedIds) => void

Reorder the pending steers to match orderedIds (a drag-reorder). The queue then drains - and “send now” fires - in the new order. When provided, queued steer chips become drag-reorderable.

string[]

void


optional onResolveToolApproval?: (args) => void | Promise<void>

Resolve an approval-gated tool call. Fired when the user clicks Approve or Deny on the inline approval card. The handler must resume the suspended Mastra workflow on its own: with mastraClient.getAgent(...).stream(), call agent.approveToolCall({ runId, toolCallId }) / agent.declineToolCall({ runId, toolCallId }) to get a fresh stream Response and pipe it through the same chunk handler (this is exactly what useMastraChat does).

It requires the runId Mastra emitted with the approval chunk - the field is always populated when the card was rendered from a live data-tool-call-approval part or an out-of-band pendingApprovalsByMessage entry. It will be missing only for approvals reconstructed from history (where the original runId is lost), in which case the handler should surface a “this approval is stale, please re-ask the model” message rather than trying to resume a workflow that no longer exists.

ApprovalDecision

void | Promise<void>


optional onSelectThread?: (threadId) => void

Switch the conversation to threadId. The handler reloads that thread’s history and points subsequent turns at it. Providing this (with threads) is what turns the sidebar on.

string

void


optional onSendSteerNow?: (steerId) => void

Fire a queued steer immediately, out of order: interrupt the current turn and start a fresh turn with that steer (removing it from the queue).

string

void


optional onStop?: (threadId?) => void

Abort the in-flight response. When provided and the chat is running (status is "submitted" or "streaming"), the composer swaps the Send button for a Stop button that calls this. The handler should cancel the active generation and return the chat to "ready". Omit to hide the Stop affordance (the Send button just disables while a response streams).

string

void


optional onToggleSidebar?: () => void

Toggle the conversation sidebar’s visibility. Provided alongside sidebarOpen for controlled mode; when omitted the view flips its own internal open state.

void


optional pendingApprovalsByMessage?: Record<string, PendingApproval[]>

Out-of-band approval requests keyed by assistant message id, for transports that don’t surface approvals as UIMessage parts. The /stream page populates this from Mastra’s tool-call-approval chunk so the same ToolApprovalCard UI works without injecting synthetic data parts. Each entry is merged with any approvals already discovered in message.parts.


optional queuedSteers?: QueuedSteer[]

Steers submitted mid-turn that are waiting to run (oldest first). When non-empty the composer shows them as chips above the input, each with a “send now” and a remove action.


optional regenerate?: () => void

void


sendMessage: (message) => void

Send a message on the active thread. Submitting while a turn is streaming ENQUEUES the message as a steer (it waits, no interrupt); the queue drains oldest-first when the turn ends. An idle submit starts a turn immediately.

string

void


optional sidebarOpen?: boolean

Controlled open/closed state for the conversation sidebar. When omitted the view manages its own (session-only) open state; pass this together with onToggleSidebar to control and persist the show/hide choice from the host (the driver does this so the choice survives reloads). The header toggle is shown whenever the sidebar is enabled, regardless of who owns the state. Only applies to the left / right placements; the top tab strip is always visible.


status: ChatStatus


optional streamingThreadIds?: string[]

Thread ids with an in-flight generation (submitted or streaming). Drives a per-row streaming indicator in the sidebar while a turn continues after the user switches away.


optional suggestions?: string[]

Starter questions shown as one-tap buttons on the empty state. Defaults to none - nothing renders when omitted or empty, so the component carries no built-in example prompts. The drop-in MastraChat fills this from the agent’s Genie space sample questions when the caller doesn’t pass an explicit list.


optional threadPlacement?: ThreadPlacement

Where the conversation list renders (or "disabled" to hide it even when threads and onSelectThread are wired). Defaults to "auto": a left side panel while the chat is wide, a tab strip once it is too narrow for one. See ThreadPlacement.


optional threads?: ThreadSummary[]

The caller’s conversation threads, newest first. When provided together with onSelectThread, the view renders a collapsible sidebar listing them so the user can switch between conversations. Omit (or pass without onSelectThread) to render the classic single-thread chat with no sidebar.


optional toolEventsByMessage?: Record<string, ToolEvent[]>