ThreadRuntime state and actions for controlling assistant-ui messages, composers, suggestions, model context, and the full thread lifecycle.
API Reference
ThreadComposerRuntime
ThreadComposerRuntimepath: ComposerRuntimePathref: stringthreadSelector: 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) => voidSet the text of the composer.
setRole: (role: MessageRole) => voidSet 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) => voidSet 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) => voidSend a message. This will send whatever text or attachments are in the composer.
cancel: () => voidCancel the current run. In edit mode, this will exit edit mode.
subscribe: (callback: () => void) => UnsubscribeListens for changes to the composer state.
startDictation: () => voidStart dictation to convert voice to text input. Requires a DictationAdapter to be configured.
stopDictation: () => voidStop the current dictation session.
setQuote: (quote: QuoteInfo | undefined) => voidSet a quote for the next message. Pass undefined to clear.
unstable_ondeprecatedunstable: <E extends ComposerRuntimeEventType>(event: E, callback: ComposerRuntimeEventCallback<E>) => UnsubscribeDeprecated: This API is still under active development and might change without notice.
getState: () => ThreadComposerStategetAttachmentByIndex: (idx: number) => AttachmentRuntime & { source: "thread-composer"; }
ThreadComposerState
ThreadComposerStatecanCancel: booleancanSend: booleanisEditing: booleanisEmpty: booleantext: stringrole: MessageRoleattachments: readonly Attachment[]runConfig: RunConfigcustom?: Record<string, unknown>
attachmentAccept: stringdictation?: DictationStateThe current state of dictation. Undefined when dictation is not active.
status: DictationAdapter.Statustype: "starting" | "running"
transcript?: stringinputDisabled?: boolean
quote?: QuoteInfoThe currently quoted text, if any. Undefined when no quote is set.
text: stringmessageId: string
type: "thread"
ThreadRuntime
ThreadRuntimepath: ThreadRuntimePathThe selector for the thread runtime.
ref: stringthreadSelector: ThreadRuntimePath["threadSelector"]type: "main"
composer: ThreadComposerRuntimeThe thread composer runtime.
path: ComposerRuntimePathref: stringthreadSelector: 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) => voidSet the text of the composer.
setRole: (role: MessageRole) => voidSet 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) => voidSet 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) => voidSend a message. This will send whatever text or attachments are in the composer.
cancel: () => voidCancel the current run. In edit mode, this will exit edit mode.
subscribe: (callback: () => void) => UnsubscribeListens for changes to the composer state.
startDictation: () => voidStart dictation to convert voice to text input. Requires a DictationAdapter to be configured.
stopDictation: () => voidStop the current dictation session.
setQuote: (quote: QuoteInfo | undefined) => voidSet a quote for the next message. Pass undefined to clear.
unstable_ondeprecatedunstable: <E extends ComposerRuntimeEventType>(event: E, callback: ComposerRuntimeEventCallback<E>) => UnsubscribeDeprecated: This API is still under active development and might change without notice.
getState: () => ThreadComposerStategetAttachmentByIndex: (idx: number) => AttachmentRuntime & { source: "thread-composer"; }
getState: () => ThreadStateGets a snapshot of the thread state.
append: (message: CreateAppendMessage) => voidAppend a new message to the thread.
startRun: (config: CreateStartRunConfig) => voidStart a new run with the given configuration.
resumeRun: (config: CreateResumeRunConfig) => voidResume a run with the given configuration.
exportExternalState: () => anyExport 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) => voidImport 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) => UnsubscribecancelRun: () => voidgetModelContext: () => ModelContextexport: () => ExportedMessageRepositoryimport: (repository: ExportedMessageRepository) => voidreset: (initialMessages?: readonly ThreadMessageLike[]) => voidReset the thread with optional initial messages.
getMessageByIndex: (idx: number) => MessageRuntimegetMessageById: (messageId: string) => MessageRuntimestopSpeakingdeprecated: () => voidDeprecated: This API is still under active development and might change without notice.
connectVoice: () => voiddisconnectVoice: () => voidgetVoiceVolume: () => numbersubscribeVoiceVolume: (callback: () => void) => UnsubscribemuteVoice: () => voidunmuteVoice: () => voidunstable_onunstable: <E extends ThreadRuntimeEventType>(event: E, callback: ThreadRuntimeEventCallback<E>) => Unsubscribe
ThreadState
ThreadStatethreadIddeprecated: stringThe thread ID.
Deprecated: This field is deprecated and will be removed in 0.12.0. Use `useThreadListItem().id` instead.
metadatadeprecated: ThreadListItemStateThe thread metadata.
Deprecated: Use `useThreadListItem()` instead. This field is deprecated and will be removed in 0.12.0.
isMain: booleanid: stringremoteId?: stringexternalId?: stringstatus: ThreadListItemStatustitle?: stringcustom?: Record<string, unknown>
isDisabled: booleanWhether the thread is disabled. Disabled threads cannot receive new messages.
isLoading: booleanWhether the thread is loading its history.
isRunning: booleanWhether the thread is running. A thread is considered running when there is an active stream connection to the backend.
capabilities: RuntimeCapabilitiesThe capabilities of the thread, such as whether the thread supports editing, branch switching, etc.
switchToBranch: booleanswitchBranchDuringRun: booleanedit: booleanreload: booleancancel: booleanunstable_copyunstable: booleanspeech: booleandictation: booleanvoice: booleanattachments: booleanfeedback: booleanqueue: boolean
messages: readonly ThreadMessage[]The messages in the currently selected branch of the thread.
statedeprecated: ReadonlyJSONValueThe thread state.
Deprecated: This feature is experimental
suggestions: readonly ThreadSuggestion[]Follow up message suggestions to show the user.
extras: unknownCustom extra information provided by the runtime.
speechdeprecated?: SpeechStateDeprecated: This API is still under active development and might change without notice.
messageId: stringstatus: SpeechSynthesisAdapter.Statustype: "starting" | "running"
voice?: VoiceSessionStatestatus: RealtimeVoiceAdapter.Statustype: "starting" | "running"
isMuted: booleanmode: RealtimeVoiceAdapter.Mode
ThreadViewportState
ThreadViewportStateisAtBottom: booleanscrollToBottom: (config?: { behavior?: ScrollBehavior | undefined; }) => voidonScrollToBottom: ( callback: ({ behavior }: { behavior: ScrollBehavior }) => void, ) => UnsubscribeturnAnchor: "top" | "bottom"Controls scroll anchoring: "top" anchors user messages at top, "bottom" is classic behavior
topAnchorMessageClamp: ThreadViewportState["topAnchorMessageClamp"]Clamps tall user messages so the assistant response stays in view.
tallerThan: stringvisibleHeight: string
height: ThreadViewportState["height"]Raw height values from registered elements
viewport: numberTotal viewport height
inset: numberTotal content inset height (footer, anchor message, etc.)
element: ThreadViewportState["element"]Current DOM elements used for geometry-based top anchoring
viewport: HTMLElement | nullanchor: HTMLElement | nulltarget: HTMLElement | null
targetConfig: ThreadViewportState["targetConfig"]Numeric clamp configuration for the active top-anchor target message
tallerThan: numbervisibleHeight: number
topAnchorTurn: ThreadViewportState["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.
anchorId: stringtargetId: string
registerViewport: () => SizeHandleRegister a viewport and get a handle to update its height
registerContentInset: () => SizeHandleRegister a content inset (footer, anchor message, etc.) and get a handle to update its height
registerViewportElement: ( element: HTMLElement | null, ) => UnsubscribeRegister the scroll viewport element
registerAnchorElement: (element: HTMLElement | null) => UnsubscribeRegister the current anchor user message element
registerAnchorTargetElement: ( element: HTMLElement | null, config?: { readonly tallerThan: number; readonly visibleHeight: number }, ) => UnsubscribeRegister 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