ThreadRuntime

ThreadRuntime state and actions for controlling assistant-ui messages, composers, suggestions, model context, and the full thread lifecycle.

API Reference

ThreadComposerRuntime

ThreadComposerRuntime
pathComposerRuntimePath

ThreadComposerRuntime["path"]
refstring

threadSelectorThreadComposerRuntime["path"]["threadSelector"]

ThreadComposerRuntime["path"]["threadSelector"]
type"main"

composerSource"thread"

type"edit" | "thread"

addAttachment(fileOrAttachment: File | CreateAttachment) => Promise<void>

Add an attachment to the composer. Accepts either a standard File object (processed through the AttachmentAdapter) or a CreateAttachment descriptor for external-source attachments (URLs, API data, CMS references). External descriptors bypass the adapter's `add()` step but still respect `adapter.accept` when an adapter is configured; without an adapter they are added as-is.

setText(text: string) => void

Set the text of the composer.

setRole(role: MessageRole) => void

Set the role of the composer. For instance, if you'd like a specific message to have the 'assistant' role, you can do so here.

setRunConfig(runConfig: RunConfig) => void

Set the run config of the composer. This is used to send custom configuration data to the model. Within your backend, you can use the `runConfig` object. Example: ```ts composerRuntime.setRunConfig({ custom: { customField: "customValue" } }); ```

reset() => Promise<void>

Reset the composer. This will clear the entire state of the composer, including all text and attachments.

clearAttachments() => Promise<void>

Clear all attachments from the composer.

send(options?: SendOptions) => void

Send a message. This will send whatever text or attachments are in the composer.

cancel() => void

Cancel the current run. In edit mode, this will exit edit mode.

steerQueueItem(queueItemId: string) => voiddeprecated

Deprecated: Use `moveQueueItem(queueItemId, { lane: "steer", insertAfter: null })` instead. Removal after 2026-11-05.

moveQueueItem(queueItemId: string, placement: QueuePlacement) => void

Move a queued message between lanes or within a lane.

removeQueueItem(queueItemId: string) => void

Remove a queued message.

subscribe(callback: () => void) => Unsubscribe

Listens for changes to the composer state.

startDictation() => void

Start dictation to convert voice to text input. Requires a DictationAdapter to be configured.

stopDictation() => void

Stop the current dictation session.

setQuote(quote: QuoteInfo | undefined) => void

Set a quote for the next message. Pass undefined to clear.

unstable_on<E extends ComposerRuntimeEventType>(event: E, callback: ComposerRuntimeEventCallback<E>) => Unsubscribeunstable

getState() => ThreadComposerState

getAttachmentByIndex(idx: number) => AttachmentRuntime & { source: "thread-composer"; }

ThreadComposerState

ThreadComposerState
canCancelboolean

Whether the composer can cancel the current run. `true` when the runtime supports cancel and a run is in flight, not merely when cancel is a capability.

canSendboolean

isEditingboolean

isEmptyboolean

textstring

roleMessageRole

attachmentsreadonly Attachment[]

runConfigRunConfig

RunConfig
custom?Record<string, unknown>

attachmentAcceptstring

dictation?DictationState | undefined

The current state of dictation. Undefined when dictation is not active.

ThreadComposerState["dictation"]
statusDictationAdapter.Status

Status
type"starting" | "running"

transcript?string

inputDisabled?boolean

quote?QuoteInfo | undefined

The currently quoted text, if any. Undefined when no quote is set.

ThreadComposerState["quote"]
textstring

messageIdstring

queuereadonly QueueItemState[]

Messages waiting to be processed. Empty unless the `queue` capability is set.

submission?ComposerSubmission | undefined

The message this composer sent while its attachments are prepared. Undefined once the runtime has taken it.

ThreadComposerState["submission"]
idstring

roleMessageRole

textstring

quote?QuoteInfo | undefined

ThreadComposerState["submission"]["quote"]
textstring

messageIdstring

attachmentsreadonly Attachment[]

inTransit?readonly ComposerSubmission[] | undefined

Messages this composer handed to the runtime that the thread does not show yet, oldest first. The thread keeps rendering each one until the runtime shows the message it became.

type"thread"

ThreadRuntime

ThreadRuntime
pathThreadRuntimePath

The selector for the thread runtime.

ThreadRuntimePath
refstring

threadSelectorThreadRuntimePath["threadSelector"]

ThreadRuntimePath["threadSelector"]
type"main"

composerThreadComposerRuntime

The thread composer runtime.

ThreadComposerRuntime
pathComposerRuntimePath

ThreadComposerRuntime["path"]
refstring

threadSelectorThreadComposerRuntime["path"]["threadSelector"]

ThreadComposerRuntime["path"]["threadSelector"]
type"main"

composerSource"thread"

type"edit" | "thread"

addAttachment(fileOrAttachment: File | CreateAttachment) => Promise<void>

Add an attachment to the composer. Accepts either a standard File object (processed through the AttachmentAdapter) or a CreateAttachment descriptor for external-source attachments (URLs, API data, CMS references). External descriptors bypass the adapter's `add()` step but still respect `adapter.accept` when an adapter is configured; without an adapter they are added as-is.

setText(text: string) => void

Set the text of the composer.

setRole(role: MessageRole) => void

Set the role of the composer. For instance, if you'd like a specific message to have the 'assistant' role, you can do so here.

setRunConfig(runConfig: RunConfig) => void

Set the run config of the composer. This is used to send custom configuration data to the model. Within your backend, you can use the `runConfig` object. Example: ```ts composerRuntime.setRunConfig({ custom: { customField: "customValue" } }); ```

reset() => Promise<void>

Reset the composer. This will clear the entire state of the composer, including all text and attachments.

clearAttachments() => Promise<void>

Clear all attachments from the composer.

send(options?: SendOptions) => void

Send a message. This will send whatever text or attachments are in the composer.

cancel() => void

Cancel the current run. In edit mode, this will exit edit mode.

steerQueueItem(queueItemId: string) => voiddeprecated

Deprecated: Use `moveQueueItem(queueItemId, { lane: "steer", insertAfter: null })` instead. Removal after 2026-11-05.

moveQueueItem(queueItemId: string, placement: QueuePlacement) => void

Move a queued message between lanes or within a lane.

removeQueueItem(queueItemId: string) => void

Remove a queued message.

subscribe(callback: () => void) => Unsubscribe

Listens for changes to the composer state.

startDictation() => void

Start dictation to convert voice to text input. Requires a DictationAdapter to be configured.

stopDictation() => void

Stop the current dictation session.

setQuote(quote: QuoteInfo | undefined) => void

Set a quote for the next message. Pass undefined to clear.

unstable_on<E extends ComposerRuntimeEventType>(event: E, callback: ComposerRuntimeEventCallback<E>) => Unsubscribeunstable

getState() => ThreadComposerState

getAttachmentByIndex(idx: number) => AttachmentRuntime & { source: "thread-composer"; }

getState() => ThreadRuntimeState

Gets a snapshot of the thread state.

append(message: CreateAppendMessage) => void

Append a new message to the thread.

deleteMessage(messageId: string) => void | Promise<void>

startRun(config: CreateStartRunConfig) => void

Start a new run with the given configuration.

resumeRun(config: CreateResumeRunConfig) => void

Resume a run with the given configuration.

exportExternalState() => any

Export the thread state in the external store format. For AI SDK runtimes, this returns the AI SDK message format. For other runtimes, this may return different formats or throw an error.

importExternalState(state: any) => void

Import thread state from the external store format. For AI SDK runtimes, this accepts AI SDK messages. For other runtimes, this may accept different formats or throw an error.

subscribe(callback: () => void) => Unsubscribe

cancelRun() => void

loadEarlier() => Promise<void>

Loads the page before the first loaded message; resolves at once when `hasEarlier` is false. Concurrent calls share one load.

unstable_notifySessionReset() => voidunstable

Notifies the runtime that the adapter discarded its backing session. Clears session-scoped tool-invocation state without run-cancel side effects such as composer draft restoration. Internal API for external-store adapter authors.

getModelContext() => ModelContext

export() => ExportedMessageRepository

import(repository: ExportedMessageRepository) => void

reset(initialMessages?: readonly ThreadMessageLike[]) => void

Reset the thread with optional initial messages.

getMessageByIndex(idx: number) => MessageRuntime

getMessageById(messageId: string) => MessageRuntime

stopSpeaking() => voidunstable

connectVoice() => void

disconnectVoice() => void

getVoiceVolume() => number

subscribeVoiceVolume(callback: () => void) => Unsubscribe

muteVoice() => void

unmuteVoice() => void

unstable_on<E extends ThreadRuntimeEventType>(event: E, callback: ThreadRuntimeEventCallback<E>) => Unsubscribeunstable

ThreadRuntimeState

ThreadRuntimeState
threadIdstringdeprecated

The thread ID.

Deprecated: This field is deprecated and will be removed in 0.12.0. Use `useThreadListItem().id` instead.

metadataThreadListItemRuntimeStatedeprecated

The thread metadata.

Deprecated: Use `useThreadListItem()` instead. This field is deprecated and will be removed in 0.12.0.

ThreadListItemRuntimeState
isMainboolean

isRunningboolean

Whether this thread has a run in progress, including a run that continues after the user switches to another thread.

idstring

remoteId?string | undefined

externalId?string | undefined

statusThreadListItemStatus

title?string | undefined

lastMessageAt?Date | undefined

custom?Record<string, unknown> | undefined

isDisabledboolean

Whether typing into the composer, adding attachments, sending, and editing messages are disabled for the thread.

isSendDisabledboolean

Whether the runtime's send policy disables composer sends, apart from whether the current draft is ready.

isLoadingboolean

Whether the thread is loading its history.

hasEarlierboolean

Whether messages exist before the first loaded one, for a runtime that pages long threads.

isLoadingEarlierboolean

Whether the page before the first loaded message is being loaded.

isRunningboolean

Whether the thread is running. A thread is considered running when there is an active stream connection to the backend.

capabilitiesRuntimeCapabilities

The capabilities of the thread, such as whether the thread supports editing, branch switching, etc.

RuntimeCapabilities
switchToBranchboolean

switchBranchDuringRunboolean

editboolean

reloadboolean

refetchThreadboolean

Whether the runtime can refetch this thread's remote state in place.

deleteboolean

cancelboolean

unstable_copybooleanunstable

speechboolean

dictationboolean

voiceboolean

attachmentsboolean

feedbackboolean

queueboolean

answerToolCallboolean

Whether the thread can answer a waiting tool call by adding its result, resuming it, or responding to its approval.

messagesreadonly ThreadMessage[]

The messages in the currently selected branch of the thread.

stateReadonlyJSONValueunstable

The thread state.

suggestionsreadonly ThreadSuggestion[]

Follow up message suggestions to show the user.

extrasunknown

Custom extra information provided by the runtime.

speech?SpeechState | undefinedunstable

ThreadRuntimeState["speech"]
messageIdstring

statusSpeechSynthesisAdapter.Status

Status
type"starting" | "running"

voice?VoiceSessionState | undefined

ThreadRuntimeState["voice"]
statusRealtimeVoiceAdapter.Status

Status
type"starting" | "running"

isMutedboolean

modeRealtimeVoiceAdapter.Mode

canSendTextboolean

Whether the running session takes typed text. While true, `append` routes a plain text user message into the session and the thread composer can send.

ThreadsState

ThreadsState
mainThreadIdstring

newThreadIdstring | null

isLoadingboolean

loadErrorunknown

switchError?ThreadsState["switchError"]

The most recent thread switch that failed: the id it was asked to open and the error it threw. Cleared when a later switch starts or that thread opens. A switch to a controlled `threadId` is retried when the browser comes back online or the tab becomes visible.

ThreadsState["switchError"]
threadIdstring

errorunknown

isLoadingMoreboolean

hasMoreboolean

threadIdsreadonly string[]

archivedThreadIdsreadonly string[]

threadItemsreadonly ThreadListItemState[]

mainThreadState

ThreadState
isEmptyboolean

Whether the thread is empty. A thread is considered empty when it has no messages and is not loading.

isDisabledboolean

Whether typing into the composer, adding attachments, sending, and editing messages are disabled for the thread.

isSendDisabledboolean

Whether the runtime's send policy disables composer sends, apart from whether the current draft is ready.

isLoadingboolean

Whether the thread is loading its history.

hasEarlierboolean

Whether messages exist before the first loaded one, for a runtime that pages long threads.

isLoadingEarlierboolean

Whether the page before the first loaded message is being loaded.

isRunningboolean

Whether the thread is running. A thread is considered running when there is an active stream connection to the backend.

capabilitiesRuntimeCapabilities

The capabilities of the thread, such as whether the thread supports editing, branch switching, etc.

RuntimeCapabilities
switchToBranchboolean

switchBranchDuringRunboolean

editboolean

reloadboolean

refetchThreadboolean

Whether the runtime can refetch this thread's remote state in place.

deleteboolean

cancelboolean

unstable_copybooleanunstable

speechboolean

dictationboolean

voiceboolean

attachmentsboolean

feedbackboolean

queueboolean

answerToolCallboolean

Whether the thread can answer a waiting tool call by adding its result, resuming it, or responding to its approval.

messagesreadonly MessageState[]

The messages in the currently selected branch of the thread.

tasksreadonly TaskState[]

Child work derived from the thread's tool calls: every tool call that carries a nested conversation, in document order with nested tasks after their parent. The array keeps its identity while no task changed.

stateReadonlyJSONValueunstable

The thread state.

suggestionsreadonly ThreadSuggestion[]

Follow up message suggestions to show the user.

extrasunknown

Custom extra information provided by the runtime.

speech?SpeechState | undefinedunstable

ThreadState["speech"]
messageIdstring

statusSpeechSynthesisAdapter.Status

Status
type"starting" | "running"

voice?VoiceSessionState | undefined

ThreadState["voice"]
statusRealtimeVoiceAdapter.Status

Status
type"starting" | "running"

isMutedboolean

modeRealtimeVoiceAdapter.Mode

canSendTextboolean

Whether the running session takes typed text. While true, `append` routes a plain text user message into the session and the thread composer can send.

composerComposerState

ComposerState
textstring

roleMessageRole

attachmentsreadonly Attachment[]

runConfigRunConfig

RunConfig
custom?Record<string, unknown>

isEditingboolean

canCancelboolean

Whether the composer can cancel the current run. `true` when the runtime supports cancel and a run is in flight, not merely when cancel is a capability.

canSendboolean

Whether the composer is currently willing to send. `true` when the composer is in editing mode and has non-empty content; for thread composers require the thread to be enabled and its `isSendDisabled` flag to be unset, and, while a voice session is connected, a session that takes typed text (`voice.canSendText`) and a draft without attachments. Edit composers (saving message edits) also require the thread to be enabled, ignore `isSendDisabled` since it is a thread-scoped gate, and never send while a voice session is connected. Cross-thread gating (running, queue capability) is layered on top by `useComposerSend`.

attachmentAcceptstring

isEmptyboolean

type"thread" | "edit"

dictation?DictationState | undefined

The current state of dictation. Undefined when dictation is not active.

ComposerState["dictation"]
statusDictationAdapter.Status

transcript?string

inputDisabled?boolean

quote?QuoteInfo | undefined

The currently quoted text, if any. Undefined when no quote is set.

ComposerState["quote"]
textstring

messageIdstring

queuereadonly QueueItemState[]

The queue of messages waiting to be processed. Empty when no messages are queued.

submission?ComposerSubmission | undefined

The message this composer sent while its attachments are prepared. The thread renders it as its last message until the runtime takes it. Undefined when no send is being prepared.

ComposerState["submission"]
idstring

roleMessageRole

textstring

quote?QuoteInfo | undefined

attachmentsreadonly Attachment[]

inTransit?readonly ComposerSubmission[] | undefined

Messages this composer handed to the runtime that the thread does not show yet, oldest first. The thread renders them after its own messages until the runtime shows each one.

ThreadViewportState

ThreadViewportState
isAtBottomboolean

scrollToBottom(config?: { behavior?: ScrollBehavior | undefined; }) => void

onScrollToBottom( callback: ({ behavior }: { behavior: ScrollBehavior }) => void, ) => Unsubscribe

turnAnchor"top" | "bottom"

Controls scroll anchoring: "top" anchors user messages at top, "bottom" is classic behavior

topAnchorMessageClampThreadViewportState["topAnchorMessageClamp"]

Clamps tall user messages so the assistant response stays in view.

ThreadViewportState["topAnchorMessageClamp"]
tallerThanstring

visibleHeightstring

heightThreadViewportState["height"]

Raw height values from registered elements

ThreadViewportState["height"]
viewportnumber

Total viewport height

insetnumber

Total content inset height (footer, anchor message, etc.)

elementThreadViewportState["element"]

Current DOM elements used for geometry-based top anchoring

ThreadViewportState["element"]
viewportHTMLElement | null

anchorHTMLElement | null

targetHTMLElement | null

targetConfigThreadViewportState["targetConfig"]

Numeric clamp configuration for the active top-anchor target message

ThreadViewportState["targetConfig"]
tallerThannumber

visibleHeightnumber

topAnchorTurnThreadViewportState["topAnchorTurn"]

The current top-anchor turn activated in this viewport session. History-loaded messages do not populate this; it is set when a run creates a live user/assistant pair and remains after the run completes.

ThreadViewportState["topAnchorTurn"]
anchorIdstring

targetIdstring

registerViewport() => SizeHandle

Register a viewport and get a handle to update its height

registerContentInset() => SizeHandle

Register a content inset (footer, anchor message, etc.) and get a handle to update its height

registerViewportElement( element: HTMLElement | null, ) => Unsubscribe

Register the scroll viewport element

registerAnchorElement(element: HTMLElement | null) => Unsubscribe

Register the current anchor user message element

registerAnchorTargetElement( element: HTMLElement | null, config?: { readonly tallerThan: number; readonly visibleHeight: number }, ) => Unsubscribe

Register the current top-anchor target (last assistant response) element along with its numeric clamp configuration. When unregistered, both `element.target` and `targetConfig` clear together.

setTopAnchorTurn( turn: { readonly anchorId: string; readonly targetId: string } | null, ) => void

ThreadState

Warning

Deprecated. Use ThreadRuntimeState. From @assistant-ui/react 0.16, ThreadState names the thread state read through useAuiState.

ThreadState
threadIdstringdeprecated

The thread ID.

Deprecated: This field is deprecated and will be removed in 0.12.0. Use `useThreadListItem().id` instead.

metadataThreadListItemRuntimeStatedeprecated

The thread metadata.

Deprecated: Use `useThreadListItem()` instead. This field is deprecated and will be removed in 0.12.0.

ThreadListItemRuntimeState
isMainboolean

isRunningboolean

Whether this thread has a run in progress, including a run that continues after the user switches to another thread.

idstring

remoteId?string | undefined

externalId?string | undefined

statusThreadListItemStatus

title?string | undefined

lastMessageAt?Date | undefined

custom?Record<string, unknown> | undefined

isDisabledboolean

Whether typing into the composer, adding attachments, sending, and editing messages are disabled for the thread.

isSendDisabledboolean

Whether the runtime's send policy disables composer sends, apart from whether the current draft is ready.

isLoadingboolean

Whether the thread is loading its history.

hasEarlierboolean

Whether messages exist before the first loaded one, for a runtime that pages long threads.

isLoadingEarlierboolean

Whether the page before the first loaded message is being loaded.

isRunningboolean

Whether the thread is running. A thread is considered running when there is an active stream connection to the backend.

capabilitiesRuntimeCapabilities

The capabilities of the thread, such as whether the thread supports editing, branch switching, etc.

RuntimeCapabilities
switchToBranchboolean

switchBranchDuringRunboolean

editboolean

reloadboolean

refetchThreadboolean

Whether the runtime can refetch this thread's remote state in place.

deleteboolean

cancelboolean

unstable_copybooleanunstable

speechboolean

dictationboolean

voiceboolean

attachmentsboolean

feedbackboolean

queueboolean

answerToolCallboolean

Whether the thread can answer a waiting tool call by adding its result, resuming it, or responding to its approval.

messagesreadonly ThreadMessage[]

The messages in the currently selected branch of the thread.

stateReadonlyJSONValueunstable

The thread state.

suggestionsreadonly ThreadSuggestion[]

Follow up message suggestions to show the user.

extrasunknown

Custom extra information provided by the runtime.

speech?SpeechState | undefinedunstable

ThreadState["speech"]
messageIdstring

statusSpeechSynthesisAdapter.Status

Status
type"starting" | "running"

voice?VoiceSessionState | undefined

ThreadState["voice"]
statusRealtimeVoiceAdapter.Status

Status
type"starting" | "running"

isMutedboolean

modeRealtimeVoiceAdapter.Mode

canSendTextboolean

Whether the running session takes typed text. While true, `append` routes a plain text user message into the session and the thread composer can send.