ThreadRuntime state and actions for controlling assistant-ui messages, composers, suggestions, model context, and the full thread lifecycle.
API Reference
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
- 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
- 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
- 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
- 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
- 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.
- 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.