Skip to main content

TurnEvent

Enum TurnEvent 

#[non_exhaustive]
pub enum TurnEvent { Chunk { delta: String, }, Thinking { delta: String, }, ToolCall { id: String, name: String, args: Value, }, ToolResult { id: String, name: String, output: String, artifact: Option<ToolArtifact>, }, Plan { entries: Vec<PlanEntry>, }, ApprovalRequest { request_id: String, tool_name: String, arguments_summary: String, timeout_secs: u64, }, HistoryTrimmed { dropped_messages: usize, dropped_turns: usize, kept_turns: usize, reason: String, token_budget: Option<u64>, tokens_before: Option<u64>, tokens_after: Option<u64>, tokens_before_source: Option<TokenCountSource>, tokens_after_source: Option<TokenCountSource>, unsatisfiable_floor: Option<bool>, retained_context: Option<RetainedContextSnapshot>, }, BudgetWarning { current_usd: f64, limit_usd: f64, period: BudgetWarningPeriod, }, Usage { input_tokens: Option<u64>, cached_input_tokens: Option<u64>, output_tokens: Option<u64>, cost_usd: Option<f64>, context_token_budget: Option<u64>, model_context_window: Option<u64>, provider_ref: String, model: String, accepted: bool, estimated_input_tokens: Option<u64>, }, }

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.
§

Chunk

A text chunk from the LLM response (may arrive many times).

Fields

§delta: String
§

Thinking

A reasoning/thinking chunk from a thinking model (may arrive many times).

Fields

§delta: String
§

ToolCall

The agent is invoking a tool.

Fields

§id: String

Stable correlation ID shared with the matching TurnEvent::ToolResult.

§name: String
§args: Value
§

ToolResult

A tool has returned a result.

Fields

§id: String

Stable correlation ID shared with the originating TurnEvent::ToolCall.

§name: String
§output: String
§artifact: Option<ToolArtifact>

Typed metadata for a file-producing tool (e.g. deliver_file), so channels attach the file structurally instead of parsing output. None for ordinary tools.

§

Plan

Fields

§entries: Vec<PlanEntry>
§

ApprovalRequest

Fields

§request_id: String

Correlation ID. The matching response frame must echo it.

§tool_name: String
§arguments_summary: String

Human-readable, secret-redacted summary of the tool arguments. Synthesised by crate::approval::summarize_args; never the raw args value.

§timeout_secs: u64

How long the channel will wait before auto-denying.

§

HistoryTrimmed

Older whole turns were dropped to fit either the context token budget or the configured turn limit. Surfaces a user-visible “context was cut here” marker so trimming is never silent. Emitted whenever a trim occurs.

Fields

§dropped_messages: usize
§dropped_turns: usize
§kept_turns: usize
§reason: String
§token_budget: Option<u64>

Configured context token budget in effect at trim time. None for message-limit trims, which carry no token accounting.

§tokens_before: Option<u64>

Token count before trimming.

§tokens_after: Option<u64>

Token count after trimming.

§tokens_before_source: Option<TokenCountSource>

Provenance of tokens_before.

§tokens_after_source: Option<TokenCountSource>

Provenance of tokens_after.

§unsatisfiable_floor: Option<bool>

The retained provider-facing request cannot be brought under the configured budget because only the protected newest turn (plus tool schemas) remains. History MAY have been trimmed on the way to that floor, so this flag — not dropped_messages == 0 — is the authoritative “unsatisfiable” signal. None/absent for ordinary trims.

§retained_context: Option<RetainedContextSnapshot>

Native RPC-only provider context captured by the owning turn before the trim is announced. Wire and observer adapters deliberately ignore this field; it is never serialized as a turn event.

§

BudgetWarning

Recorded spend has reached cost.warn_at_percent of a shared daily or monthly limit. Non-blocking: the turn continues. Emitted at most once per turn, before the first provider call that sees the warning.

Fields

§current_usd: f64

Spend recorded in period before this turn’s next call.

§limit_usd: f64

Configured limit for period.

§period: BudgetWarningPeriod

Which limit is near.

§

Usage

Per-LLM-call token usage and cost; a turn may emit several, one per model call. None means “unavailable for this call”, not zero. The provider_ref and model identify the provider and model used for cost attribution and context window resolution.

For vision routing and reliable fallback, these carry the actual served provider and model. For dynamic routing models (e.g. openrouter/auto) where the provider selects the concrete model and the ModelProvider trait cannot expose the response-reported model, model carries the requested routing model (e.g. openrouter/auto) rather than the upstream-selected concrete model. This is a known limitation of the current provider trait.

Fields

§input_tokens: Option<u64>
§cached_input_tokens: Option<u64>

Tokens served from the provider’s prompt cache (e.g. Anthropic cache_read_input_tokens, OpenAI cached_tokens). Subset of input_tokens — adding would double-count.

§output_tokens: Option<u64>
§cost_usd: Option<f64>
§context_token_budget: Option<u64>

Proactive trim threshold resolved for the provider/model route that produced this usage sample. Zero means proactive trimming is disabled.

§model_context_window: Option<u64>

Configured full context capacity for that same provider/model route. None means the runtime used the compatibility fallback because no authoritative capacity was configured.

§provider_ref: String

The <type>.<alias> config reference of the provider that served this call. Used for accurate context window resolution and cost attribution when vision routing or provider switches are active.

§model: String

The model that actually served this call. When vision routing or a reliable fallback selects a different model, this carries the served model — not the turn-start model.

§accepted: bool

Whether this usage event corresponds to the semantically accepted response (true) or a rejected physical attempt (false). Rejected attempts are billing-only telemetry; they do not update the accepted context snapshot (ACP session token count, context-meter ceiling).

§estimated_input_tokens: Option<u64>

Locally estimated prompt size, published only when the provider omitted input_tokens. Local OpenAI-compatible servers (llama.cpp and similar) routinely omit usage, which leaves a context meter with a budget but no numerator.

This is not measured usage and carries a different contract from every other field on this event:

  • It must never be billed, summed into provider usage totals, or persisted as a provider token count. Accounting and persistence consumers read input_tokens, which stays None exactly when the provider reported nothing.
  • A consumer rendering a context meter may use it as a display numerator, and must label it as an estimate (TokenCountSource::Estimated) rather than provider-reported.
  • It is an approximation in both directions, not a bound. The history heuristic does not price separately supplied native tool schemas, so a tool-heavy request reads low; its byte-count and fixed-per-image costs can also read high against a provider’s real tokenizer. That is acceptable for a labelled display value and is not acceptable for accounting — another reason it is kept off input_tokens.
  • When the provider reported cached_input_tokens without a total, that subset is a known minimum for the prompt and the estimate is floored at it, so the meter cannot read near-zero for a prompt already known to be large.

None means either the provider reported a real count (use input_tokens) or no estimate could be formed.

Trait Implementations§

Source§

impl Clone for TurnEvent

Source§

fn clone(&self) -> TurnEvent

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

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

Performs copy-assignment from source. Read more
Source§

impl Debug for TurnEvent

Source§

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

Formats the value using the given formatter. 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<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> 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, 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> 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.