MessageRuntime

MessageRuntime state and actions for editing, reloading, copying, rating, speaking, and branching assistant-ui messages.

API Reference

MessageRuntime

MessageRuntime
pathMessageRuntimePath

MessageRuntimePath
refstring

threadSelectorMessageRuntimePath["threadSelector"]

MessageRuntimePath["threadSelector"]
type"main"

messageSelectorMessageRuntimePath["messageSelector"]

MessageRuntimePath["messageSelector"]
type"messageId"

composerEditComposerRuntime

EditComposerRuntime
pathComposerRuntimePath

EditComposerRuntime["path"]
refstring

threadSelectorEditComposerRuntime["path"]["threadSelector"]

EditComposerRuntime["path"]["threadSelector"]
type"main"

messageSelectorEditComposerRuntime["path"]["messageSelector"]

EditComposerRuntime["path"]["messageSelector"]
type"messageId"

composerSource"edit"

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>) => Unsubscribedeprecatedunstable

Deprecated: This API is still under active development and might change without notice.

getState() => EditComposerState

beginEdit() => void

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

getState() => MessageState

delete() => void | Promise<void>

reload(config?: ReloadConfig) => void

speak() => voiddeprecated

Deprecated: This API is still under active development and might change without notice.

stopSpeaking() => voiddeprecated

Deprecated: This API is still under active development and might change without notice.

submitFeedback({ type }: { type: "positive" | "negative"; }) => void

switchToBranch({ position, branchId, }: { position?: "previous" | "next" | undefined; branchId?: string | undefined; }) => void

unstable_getCopyText() => stringunstable

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

getMessagePartByIndex(idx: number) => MessagePartRuntime

getMessagePartByToolCallId(toolCallId: string) => MessagePartRuntime

getAttachmentByIndex(idx: number) => AttachmentRuntime & { source: "message"; }

MessageState

MessageState
status?ThreadAssistantMessage["status"]

MessageState["status"]
type"running"

metadataMessageState["metadata"]

MessageState["metadata"]
unstable_state?ReadonlyJSONValueunstable

unstable_annotations?readonly ReadonlyJSONValue[]unstable

unstable_data?readonly ReadonlyJSONValue[]unstable

steps?readonly ThreadStep[]

submittedFeedback?MessageState["metadata"]["submittedFeedback"]

MessageState["metadata"]["submittedFeedback"]
type"positive" | "negative"

timing?MessageTiming

MessageTiming
streamStartTimenumber

firstTokenTime?number

totalStreamTime?number

tokenCount?number

tokensPerSecond?number

totalChunksnumber

toolCallCountnumber

isOptimistic?boolean

Marks a client-side optimistic placeholder. Such messages are evicted once off the head branch and are never persisted.

customRecord<string, unknown>

attachments?ThreadUserMessage["attachments"]

idstring

createdAtDate

role"system"

contentreadonly [TextMessagePart]

parentIdstring | null

indexnumber

The position of this message in the thread (0 for first message)

isLastboolean

branchNumbernumber

branchCountnumber

speech?SpeechState | undefineddeprecated

Deprecated: This API is still under active development and might change without notice.

MessageState["speech"]
messageIdstring

statusSpeechSynthesisAdapter.Status

Status
type"starting" | "running"