@assistant-ui/eve

Eve runtime hook and message conversion utilities for assistant-ui React applications.

API Reference

convertEveMessage

Converts a single Eve message into an assistant-ui thread message.

const convertEveMessage: (message: EveMessage, index: number, messages: readonly EveMessage[], options?: ConvertEveMessagesOptions) => ThreadMessage;

convertEveMessages

Converts the full Eve message data object into assistant-ui thread messages.

const convertEveMessages: (data: EveMessageData, options?: ConvertEveMessagesOptions) => ThreadMessage[];

getEveMessageContent

Converts an assistant-ui append message into the message payload accepted by Eve's send API.

const getEveMessageContent: (message: AppendMessage) => EveMessageContent;

toEveInputResponse

Converts an assistant-ui tool approval response into an Eve input response.

When inputRequest is known, every returned response carries either an option the request declares or a free-form answer. A literal option match wins, then the "approve" / "cancel" option the response's boolean decision names, then the response's text (or its reason, for a caller that predates the first-class answer field) when the request takes a free-form answer (display: "text", allowFreeform, or no options at all, and never display: "confirmation") and the response is not a refusal. A one-argument call, or a part with no request, still forwards a caller optionId as it always has, including ids the request never declared.

A response the known request cannot record as the answer it asked for throws instead of being submitted, because eve resolves a request the moment any response for it arrives, and an empty one is recorded as an answer with no content. Not sending leaves the request pending, so the caller can retry or the user can answer it as an ordinary message.

With no request to map against — a one-argument call, or a part carrying no toolMetadata.eve.inputRequest — the response maps as it always has, to the literal "approve" / "cancel" option every eve approval declares. Guessing a display mode is what this mapper stopped doing; an unknown request is not a guess about one.

const toEveInputResponse: (response: RespondToToolApprovalOptions, inputRequest?: EveMessageInputRequest) => InputResponse;

useEveAgentRuntime

Connects Eve's useEveAgent hook to assistant-ui's runtime contract.

The runtime renders Eve messages, forwards new user messages to the Eve session, supports cancellation, and maps Eve input requests to assistant-ui tool approval UI.

useEveAgentRuntime
options?UseEveAgentRuntimeOptions

UseEveAgentRuntimeOptions
onError?(error: Error) => void

resumeboolean= false

Replay the attached durable session after mount and follow its in-flight turn, if any. Requires `initialSession` or `session`.

headers?HeadersValue

onFinish?(snapshot: EveAgentStoreSnapshot<TData>) => void

agent?string

Named agent mounted by a framework integration such as `withEve({ agents })`. `agent: "support"` targets same-origin routes under `/eve/agents/support/eve/v1/...`. Do not combine with `host`.

auth?ClientAuth

ClientAuth
basicClientAuth["basic"]

ClientAuth["basic"]
usernamestring

passwordTokenValue

bearerTokenValue

vercelOidcClientAuth["vercelOidc"]

ClientAuth["vercelOidc"]
tokenTokenValue

hoststring= ""

Base URL for eve client requests. Do not combine with `agent`. Defaults to same-origin eve routes such as `/eve/v1/...`. Pass a same-origin prefix such as `/api` for an app-owned proxy, or an absolute origin to talk to an eve server directly.

initialEvents?readonly MessageStreamEvent[]

Ordered prefix of the session stream used to rehydrate projected state.

initialSession?ClientSessionState

ClientSessionState
sessionIdstring

streamIndexnumber

optimisticboolean= true

Project submitted user messages before eve confirms them with a `message.received` stream event. Optimistic events are reducer-facing projection events only. They are not exposed through `events`, which remains the authoritative eve stream.

session?ClientSession

ClientSession
#privateany

stateClientSessionState

Current fixed session identity and durable stream cursor.

ClientSessionState
sessionIdstring

streamIndexnumber

snapshot(options?: { readonly signal?: AbortSignal; }) => Promise<SessionSnapshot>

Reads a finite prefix through the durable tail without advancing this handle.

send<TOutput = unknown>(message: SendTurnInput<TOutput>["message"], options?: SendTurnOptions<TOutput>) => Promise<MessageResponse<TOutput>>

Sends a message to this exact session ID.

respond<TOutput = unknown>(inputResponses: readonly InputResponse[], options?: RespondTurnOptions<TOutput>) => Promise<MessageResponse<TOutput>>

Answers pending input requests on this exact session ID.

cancel(options?: { readonly signal?: AbortSignal; readonly tasks?: boolean; readonly turnId?: string; }) => Promise<CancelSessionResult>

Requests cooperative cancellation of this session's active turn and optionally its tasks.

clear() => Promise<ClearResult>

Queues removal of this session's durable model-message history.

compact() => Promise<CompactResult>

Queues context compaction without sending model input.

reset(options?: { readonly reason?: string; readonly signal?: AbortSignal; }) => Promise<ResetResult>

Terminally retires this exact session ID. The handle remains pinned to it.

stream(options?: StreamOptions) => AsyncIterable<MessageStreamEvent>

Opens this session's durable event stream from its stored cursor.

onEvent?(event: MessageStreamEvent) => void

onSessionChange?(session: ClientSessionState | undefined) => void

prepareSend?PrepareSend

suggestions?readonly ThreadSuggestion[] | undefined

isDisabled?boolean | undefined

Whether the entire thread is disabled. When `true`, the composer's input is also disabled (the user cannot type, attach files, or submit). For a narrower gate that keeps the input usable but blocks only sending, use `isSendDisabled`.

isSendDisabled?boolean | undefined

Whether sending new messages is currently disabled. When `true`, the thread composer's input remains usable but `send()` becomes a no-op and the thread composer's `canSend` is `false`. Use this to gate sending on external React state (e.g. while tool config is loading) without disabling the input itself the way `isDisabled` does. Edit composers (saving message edits) intentionally ignore this flag.

unstable_capabilities?UseEveAgentRuntimeOptions["unstable_capabilities"]unstable

UseEveAgentRuntimeOptions["unstable_capabilities"]
copy?boolean | undefined

adapters?UseEveAgentRuntimeOptions["adapters"]

UseEveAgentRuntimeOptions["adapters"]
attachments?AttachmentAdapter | undefined

UseEveAgentRuntimeOptions["adapters"]["attachments"]
acceptstring

add(state: { file: File; }) => Promise<PendingAttachment> | AsyncGenerator<PendingAttachment, void>

remove(attachment: Attachment) => Promise<void>

send(attachment: PendingAttachment) => Promise<CompleteAttachment>

speech?SpeechSynthesisAdapter | undefined

UseEveAgentRuntimeOptions["adapters"]["speech"]
speak(text: string) => SpeechSynthesisAdapter.Utterance

dictation?DictationAdapter | undefined

UseEveAgentRuntimeOptions["adapters"]["dictation"]
listen() => DictationAdapter.Session

disableInputDuringDictation?boolean

voice?RealtimeVoiceAdapter | undefined

UseEveAgentRuntimeOptions["adapters"]["voice"]
connect(options: { abortSignal?: AbortSignal; }) => RealtimeVoiceAdapter.Session

feedback?FeedbackAdapter | undefined

UseEveAgentRuntimeOptions["adapters"]["feedback"]
submit(feedback: FeedbackAdapterFeedback) => void

useEveError

Read the last Eve session error from the runtime extras.

const useEveError: () => Error | undefined;

useEveEvents

Read the authoritative Eve server event stream from the runtime extras. Defaults to an empty array outside an Eve runtime.

const useEveEvents: () => EveRuntimeExtras["events"];

useEveReset

Returns a function that resets the Eve session: aborts any in-flight turn, recreates the owned session, and clears events and projected data. Pending staged messages and tool execution state are discarded. Safe to render outside an Eve runtime; invoking the returned function there throws.

const useEveReset: () => () => void;

useEveSession

Read the current Eve session cursor from the runtime extras. Persist it to resume the session later via initialSession. undefined when no session exists yet or outside an Eve runtime.

const useEveSession: () => EveRuntimeExtras["session"] | undefined;