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
Chunk
A text chunk from the LLM response (may arrive many times).
Thinking
A reasoning/thinking chunk from a thinking model (may arrive many times).
ToolCall
The agent is invoking a tool.
Fields
id: StringStable correlation ID shared with the matching TurnEvent::ToolResult.
ToolResult
A tool has returned a result.
Fields
id: StringStable correlation ID shared with the originating TurnEvent::ToolCall.
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
ApprovalRequest
Fields
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
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_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
period: BudgetWarningPeriodWhich 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
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.
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: StringThe <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: StringThe 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: boolWhether 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 staysNoneexactly 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_tokenswithout 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§
Auto Trait Implementations§
impl Freeze for TurnEvent
impl RefUnwindSafe for TurnEvent
impl Send for TurnEvent
impl Sync for TurnEvent
impl Unpin for TurnEvent
impl UnsafeUnpin for TurnEvent
impl UnwindSafe for TurnEvent
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more