Skip to main content

AgentEvent

Enum AgentEvent 

Source
#[non_exhaustive]
pub enum AgentEvent {
Show 20 variants Start { thread_id: ThreadId, turn: usize, emitter_task_id: Option<String>, }, UserInput { thread_id: ThreadId, content: Vec<ContentBlock>, }, Thinking { message_id: String, text: String, }, ThinkingDelta { message_id: String, delta: String, }, TextDelta { message_id: String, delta: String, }, Text { message_id: String, text: String, }, ToolCallStart { id: String, name: String, display_name: String, input: Value, tier: ToolTier, }, ToolCallEnd { id: String, name: String, display_name: String, result: ToolResult, }, ToolProgress { id: String, name: String, display_name: String, stage: String, message: String, data: Option<Value>, }, ToolRequiresConfirmation { id: String, name: String, display_name: String, input: Value, description: String, }, TurnComplete { turn: usize, usage: TokenUsage, emitter_task_id: Option<String>, }, Done { thread_id: ThreadId, total_turns: usize, total_usage: TokenUsage, duration: Duration, estimated_cost_usd: Option<f64>, emitter_task_id: Option<String>, }, BudgetExceeded { thread_id: ThreadId, total_turns: usize, total_usage: TokenUsage, duration: Duration, estimated_cost_usd: Option<f64>, limit: BudgetLimitKind, emitter_task_id: Option<String>, }, Error { message: String, recoverable: bool, emitter_task_id: Option<String>, }, AutoRetryStart { attempt: u32, max_attempts: u32, delay_ms: u64, error_message: String, }, AutoRetryEnd { attempt: u32, success: bool, final_error: Option<String>, }, Refusal { message_id: String, text: Option<String>, }, Cancelled { turn: usize, usage: TokenUsage, emitter_task_id: Option<String>, }, ContextCompacted { original_count: usize, new_count: usize, original_tokens: usize, new_tokens: usize, }, SubagentProgress {
Show 15 fields subagent_id: String, subagent_name: String, nickname: Option<String>, child_thread_id: Option<ThreadId>, child_root_task_id: Option<String>, subagent_task_id: Option<String>, max_turns: Option<u32>, current_turn: Option<u32>, model: Option<String>, tool_name: String, tool_context: String, completed: bool, success: bool, tool_count: u32, total_tokens: u64,
},
}
Expand description

Events emitted by the agent loop during execution. These are streamed to the client for real-time UI updates.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Start

Agent loop has started

Fields

§thread_id: ThreadId
§turn: usize
§emitter_task_id: Option<String>

Durable task that committed this event. See AgentEvent::with_emitter_task_id.

§

UserInput

The user prompt that opens a turn.

Committed by the worker on the first attempt of each root-turn task, immediately before the matching AgentEvent::Start. Carries the task’s admitted submitted_input lifted into the LLM-content shape (Vec<ContentBlock> — text, image, document) so consumers can render the prompt without reaching into the projection or the task store. Retries of the same turn do not re-emit the event; downstream readers can pair UserInput 1:1 with the first Start { turn: N } per turn.

This is the durable, sequence-numbered admission event the projection never carried — MessageProjection::messages still holds the same prompt as an llm::Message, but it has no sequence and commingles with tool-result and compaction-summary user-role rows. Replay clients that need a clean, chronological “this is what the user typed” signal read this event instead.

Fields

§thread_id: ThreadId
§content: Vec<ContentBlock>

Lifted from the admitted task’s submitted_input. Only Text, Image, and Document blocks appear — the runtime never admits user prompts containing tool blocks, but the broader ContentBlock type lets the field round-trip through the same wire shapes the projection uses.

§

Thinking

Agent is “thinking” - complete thinking text after stream ends

Fields

§message_id: String
§text: String
§

ThinkingDelta

A thinking delta for streaming thinking content

Fields

§message_id: String
§delta: String
§

TextDelta

A text delta for streaming responses

Fields

§message_id: String
§delta: String
§

Text

Complete text block from the agent

Fields

§message_id: String
§text: String
§

ToolCallStart

Agent is about to call a tool

Fields

§name: String
§display_name: String
§input: Value
§

ToolCallEnd

Tool execution completed

Fields

§name: String
§display_name: String
§result: ToolResult
§

ToolProgress

Progress update from an async tool operation

Fields

§id: String

Tool call ID

§name: String

Tool name

§display_name: String

Human-readable display name

§stage: String

Progress stage

§message: String

Human-readable progress message

§data: Option<Value>

Optional tool-specific data

§

ToolRequiresConfirmation

Tool requires confirmation before execution. The application determines the confirmation type (normal, PIN, biometric).

Fields

§name: String
§display_name: String
§input: Value
§description: String
§

TurnComplete

Agent turn completed (one LLM round-trip)

Fields

§turn: usize
§emitter_task_id: Option<String>

Durable task that committed this event. See AgentEvent::with_emitter_task_id.

§

Done

Agent loop completed successfully

Fields

§thread_id: ThreadId
§total_turns: usize
§total_usage: TokenUsage
§duration: Duration

Wall-clock run duration.

Serialized on the wire as duration_ms (a millisecond integer) to match TurnSummary::duration_ms — the flattened envelope previously encoded this as a nested {"secs":..,"nanos":..} object, inconsistent with the rest of the streaming contract. The Rust field keeps the Duration type.

§estimated_cost_usd: Option<f64>

Estimated cost of the run in USD, when the run’s provider/model has pricing metadata. Omitted from the wire form when None so the streaming contract stays compatible with consumers that predate cost accounting.

§emitter_task_id: Option<String>

Durable task that committed this event. See AgentEvent::with_emitter_task_id.

§

BudgetExceeded

The run was stopped because a run-level usage budget was exceeded.

This is a terminal event, emitted once on the budget-exceeded return site in place of AgentEvent::Done, so a streaming consumer always receives a closing marker. limit identifies which budget tripped.

Fields

§thread_id: ThreadId
§total_turns: usize
§total_usage: TokenUsage
§duration: Duration

Wall-clock run duration up to the moment the budget tripped.

Serialized on the wire as duration_ms (a millisecond integer), mirroring AgentEvent::Done.

§estimated_cost_usd: Option<f64>

Estimated cost of the run in USD at the moment the budget was hit, when pricing metadata is available.

§limit: BudgetLimitKind

Which budget limit was exceeded.

§emitter_task_id: Option<String>

Durable task that committed this event. See AgentEvent::with_emitter_task_id.

§

Error

An error occurred during execution

Fields

§message: String
§recoverable: bool
§emitter_task_id: Option<String>

Durable task that committed this event. See AgentEvent::with_emitter_task_id.

§

AutoRetryStart

Auto-retry was initiated for a recoverable LLM error (rate limit, server error, connectivity loss). The delay_ms field gives the runtime’s chosen backoff before re-attempting; consumers can render a “Retrying X/N in Ys…” indicator and clear it on the matching AutoRetryEnd.

Fields

§attempt: u32

1-based failure ordinal within the turn (first failure = 1).

Not necessarily contiguous across events: a connectivity streak emits one AutoRetryStart (on its first failure) while later failures in the streak still consume ordinals, so consecutive events can read e.g. 1, 2, 4.

§max_attempts: u32

Maximum retry attempts configured for this run.

u32::MAX is a sentinel: the runtime is waiting for provider connectivity to return and will retry until it does (or the run is cancelled). Render it as an indefinite “waiting for connection…” state, never as a literal X/4294967295 counter.

§delay_ms: u64

Backoff before the next attempt in milliseconds.

§error_message: String

Human-readable reason the retry was triggered.

§

AutoRetryEnd

Auto-retry settled. success = true means a subsequent attempt succeeded; success = false means the retry budget was exhausted and final_error carries the last error.

Fields

§attempt: u32

The attempt of the last emitted AutoRetryStart, so the envelope pairs even when later failures were folded into an already-open connectivity streak.

§success: bool

Whether a follow-up attempt eventually succeeded.

§final_error: Option<String>

Last error when the retry budget ran out.

§

Refusal

The model refused the request (safety/policy).

Fields

§message_id: String
§

Cancelled

The run was cancelled via its CancellationToken.

This is a terminal event, emitted exactly once on every cancellation return site (mirroring AgentEvent::Done and AgentEvent::Refusal). Cancellation can land at the top of a turn, mid-stream while the model is still producing tokens, while a tool is in flight, or during context compaction — in every case the run closes with this event so a streaming consumer receives a closing marker and never hangs waiting for Done.

turn is the turn number reached when the cancel was honored and usage is the partial token usage accumulated so far.

Fields

§turn: usize
§emitter_task_id: Option<String>

Durable task that committed this event — the cancelled root, not the promoted successor. See AgentEvent::with_emitter_task_id.

§

ContextCompacted

Context was compacted to reduce size

Fields

§original_count: usize

Number of messages before compaction

§new_count: usize

Number of messages after compaction

§original_tokens: usize

Estimated tokens before compaction

§new_tokens: usize

Estimated tokens after compaction

§

SubagentProgress

Progress update from a running subagent

Fields

§subagent_id: String

ID of the parent tool call that spawned this subagent

§subagent_name: String

Name of the subagent (e.g., “explore”, “plan”)

§nickname: Option<String>

Human-friendly nickname assigned by the parent (e.g., “Zara”)

§child_thread_id: Option<ThreadId>

Durable child thread reference, when available.

§child_root_task_id: Option<String>

Durable child root task reference, when available.

§subagent_task_id: Option<String>

Durable parent-visible invocation task reference, when available.

§max_turns: Option<u32>

Maximum turns configured for this subagent

§current_turn: Option<u32>

Current turn number of the subagent

§model: Option<String>

Model being used by the subagent

§tool_name: String

Summary label associated with the latest subagent update.

§tool_context: String

Brief context associated with the latest subagent update.

§completed: bool

Whether the summarized update represents terminal completion.

§success: bool

Whether the subagent succeeded (only meaningful if completed)

§tool_count: u32

Current total tool count for this subagent

§total_tokens: u64

Current total tokens used by this subagent

Implementations§

Source§

impl AgentEvent

Source

pub const fn start(thread_id: ThreadId, turn: usize) -> AgentEvent

Source

pub fn with_emitter_task_id(self, task_id: impl Into<String>) -> AgentEvent

Attribute a lifecycle event to the durable task whose execution committed it (the task id in its string form).

Only the lifecycle variants (Start, TurnComplete, Done, BudgetExceeded, Error, Cancelled) carry the attribution; every other variant is returned unchanged. Attribution is therefore always the emitter’s own identity, never a successor’s: a cancelled root’s late salvage commit still names the cancelled root, which is what lets a reader tell a superseded frame apart from the thread’s live one.

Runs without a durable task behind them (the embedded SDK loop) leave the field None, as do events journaled before the field existed.

Source

pub fn emitter_task_id(&self) -> Option<&str>

The durable task that committed this event, when the event is a lifecycle variant that was stamped. See AgentEvent::with_emitter_task_id.

Source

pub const fn user_input( thread_id: ThreadId, content: Vec<ContentBlock>, ) -> AgentEvent

Source

pub fn thinking( message_id: impl Into<String>, text: impl Into<String>, ) -> AgentEvent

Source

pub fn thinking_delta( message_id: impl Into<String>, delta: impl Into<String>, ) -> AgentEvent

Source

pub fn text_delta( message_id: impl Into<String>, delta: impl Into<String>, ) -> AgentEvent

Source

pub fn text( message_id: impl Into<String>, text: impl Into<String>, ) -> AgentEvent

Source

pub fn tool_call_start( id: impl Into<String>, name: impl Into<String>, display_name: impl Into<String>, input: Value, tier: ToolTier, ) -> AgentEvent

Source

pub fn tool_call_end( id: impl Into<String>, name: impl Into<String>, display_name: impl Into<String>, result: ToolResult, ) -> AgentEvent

Source

pub fn tool_progress( id: impl Into<String>, name: impl Into<String>, display_name: impl Into<String>, stage: impl Into<String>, message: impl Into<String>, data: Option<Value>, ) -> AgentEvent

Source

pub fn tool_requires_confirmation( id: impl Into<String>, name: impl Into<String>, display_name: impl Into<String>, input: Value, description: impl Into<String>, ) -> AgentEvent

Source

pub const fn turn_complete(turn: usize, usage: TokenUsage) -> AgentEvent

Source

pub const fn done( thread_id: ThreadId, total_turns: usize, total_usage: TokenUsage, duration: Duration, ) -> AgentEvent

Source

pub const fn done_with_cost( thread_id: ThreadId, total_turns: usize, total_usage: TokenUsage, duration: Duration, estimated_cost_usd: Option<f64>, ) -> AgentEvent

Source

pub const fn budget_exceeded( thread_id: ThreadId, total_turns: usize, total_usage: TokenUsage, duration: Duration, estimated_cost_usd: Option<f64>, limit: BudgetLimitKind, ) -> AgentEvent

Source

pub fn error(message: impl Into<String>, recoverable: bool) -> AgentEvent

Source

pub fn refusal( message_id: impl Into<String>, text: Option<String>, ) -> AgentEvent

Source

pub const fn cancelled(turn: usize, usage: TokenUsage) -> AgentEvent

Source

pub const fn context_compacted( original_count: usize, new_count: usize, original_tokens: usize, new_tokens: usize, ) -> AgentEvent

Trait Implementations§

Source§

impl Clone for AgentEvent

Source§

fn clone(&self) -> AgentEvent

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for AgentEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for AgentEvent

Source§

fn deserialize<__D>( __deserializer: __D, ) -> Result<AgentEvent, <__D as Deserializer<'de>>::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for AgentEvent

Source§

fn serialize<__S>( &self, __serializer: __S, ) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more