Runtime Hooks
Hooks for accessing message state and edit composer.
useAui (Message Actions)
Access message actions via useAui:
import { useAui } from "@assistant-ui/react";
const aui = useAui();
// Reload an assistant message (regenerate the response)
aui.message().reload();
// Switch to the previous or next branch
aui.message().switchToBranch({ position: "previous" });
aui.message().switchToBranch({ position: "next" });
// Submit feedback on a message
aui.message().submitFeedback({ type: "positive" });
aui.message().submitFeedback({ type: "negative" });
// Get the plain-text content of the message
const text = aui.message().getCopyText();
// Access a message part by index or tool call ID
aui.message().part({ index: 0 });
aui.message().part({ toolCallId: "call_123" });
// Access an attachment by index
aui.message().attachment({ index: 0 });
// Access the edit composer for this message
aui.message().composer();
// Get a snapshot of the full message state
const state = aui.message().getState();MessageRuntimepath: MessageRuntimePathcomposer: EditComposerRuntimegetState: () => MessageStatereload: (config?: ReloadConfig | undefined) => voidspeak: () => voidstopSpeaking: () => voidsubmitFeedback: ({ type }: { type: "positive" | "negative"; }) => voidswitchToBranch: ({ position, branchId, }: { position?: "previous" | "next" | undefined; branchId?: string | undefined; }) => voidunstable_getCopyTextunstable: () => stringsubscribe: (callback: () => void) => UnsubscribegetMessagePartByIndex: (idx: number) => MessagePartRuntimegetMessagePartByToolCallId: (toolCallId: string) => MessagePartRuntimegetAttachmentByIndex: (idx: number) => AttachmentRuntime & { source: "message"; }useAuiState (Message State)
Access message state reactively:
import { useAuiState } from "@assistant-ui/react";
const role = useAuiState((s) => s.message.role);
const content = useAuiState((s) => s.message.content);
const isLast = useAuiState((s) => s.message.isLast);MessageStatestatus?: { readonly type: "running"; } | { readonly type: "requires-action"; readonly reason: "tool-calls" | "interrupt"; } | { readonly type: "complete"; readonly reason: "stop" | "unknown"; } | { readonly type: "incomplete"; readonly reason: "length" | "tool-calls" | "cancelled" | "content-filter" | "other" | "error"; readonly error?: ReadonlyJSONValue; }metadata: ({ readonly unstable_state?: ReadonlyJSONValue; readonly unstable_annotations?: readonly ReadonlyJSONValue[]; readonly unstable_data?: readonly ReadonlyJSONValue[]; readonly steps?: readonly ThreadStep[]; readonly submittedFeedback?: { readonly type: "positive" | "negative"; }; readonly timing?: MessageTiming; readonly custom: Record<string, unknown>; } & { readonly unstable_state?: undefined; readonly unstable_annotations?: undefined; readonly unstable_data?: undefined; readonly steps?: undefined; readonly submittedFeedback?: undefined; readonly timing?: undefined; readonly custom: Record<string, unknown>; }) | ({ readonly unstable_state?: ReadonlyJSONValue; readonly unstable_annotations?: readonly ReadonlyJSONValue[]; readonly unstable_data?: readonly ReadonlyJSONValue[]; readonly steps?: readonly ThreadStep[]; readonly submittedFeedback?: { readonly type: "positive" | "negative"; }; readonly timing?: MessageTiming; readonly custom: Record<string, unknown>; } & { readonly unstable_state?: undefined; readonly unstable_annotations?: undefined; readonly unstable_data?: undefined; readonly steps?: undefined; readonly submittedFeedback?: undefined; readonly timing?: undefined; readonly custom: Record<string, unknown>; }) | ({ readonly unstable_state?: ReadonlyJSONValue; readonly unstable_annotations?: readonly ReadonlyJSONValue[]; readonly unstable_data?: readonly ReadonlyJSONValue[]; readonly steps?: readonly ThreadStep[]; readonly submittedFeedback?: { readonly type: "positive" | "negative"; }; readonly timing?: MessageTiming; readonly custom: Record<string, unknown>; } & { readonly unstable_state: ReadonlyJSONValue; readonly unstable_annotations: readonly ReadonlyJSONValue[]; readonly unstable_data: readonly ReadonlyJSONValue[]; readonly steps: readonly ThreadStep[]; readonly submittedFeedback?: { readonly type: "positive" | "negative"; }; readonly timing?: MessageTiming; readonly custom: Record<string, unknown>; })attachments?: readonly CompleteAttachment[]id: stringcreatedAt: Daterole: "system" | "user" | "assistant"content: readonly [TextMessagePart] | readonly ThreadUserMessagePart[] | readonly ThreadAssistantMessagePart[]parentId: string | nullindex: numberThe position of this message in the thread (0 for first message)
isLast: booleanbranchNumber: numberbranchCount: numberspeech: SpeechState | undefinedsubmittedFeedback: SubmittedFeedback | undefineduseAuiState (Edit Composer)
Access the edit composer state (used when editing a message):
import { useAuiState } from "@assistant-ui/react";
const editText = useAuiState((s) => s.message.composer.text);
const isEditing = useAuiState((s) => s.message.composer.isEditing);ComposerStatecanCancel: booleanisEditing: booleanisEmpty: booleantext: stringrole: "system" | "user" | "assistant"attachments: readonly Attachment[]runConfig: RunConfigattachmentAccept: stringdictation: DictationState | undefinedThe current state of dictation. Undefined when dictation is not active.
quote: QuoteInfo | undefinedThe currently quoted text, if any. Undefined when no quote is set.
type: "thread" | "edit"