Skip to main content

SessionStats

Struct SessionStats 

Source
pub struct SessionStats {
    pub turns: u64,
    pub input_tokens: u64,
    pub output_tokens: u64,
    pub cache_read_tokens: u64,
    pub cache_write_tokens: u64,
    pub cache_turns: u64,
    pub tools: Vec<ToolStat>,
    pub tool_errors: u64,
    pub last_input_tokens: Option<u64>,
    pub cost: Option<Cost>,
}
Expand description

Aggregate view of a conversation for /usage: how many turns reported usage, the summed token counts, and which tools ran.

Pure data — no timing, and no cost OF ITS OWN: cost is filled by the caller that knows the provider (pricing::cost_of, called from the actor’s Request::Usage reply), because pricing keys on a base_url/model pair that an AgentMessage cannot carry. Every other field folds from the transcript alone. Derive order is fixed so tests can compare by value.

Fields§

§turns: u64

Assistant messages that carried Some(usage).

§input_tokens: u64§output_tokens: u64§cache_read_tokens: u64

Cache counts absent on a call are treated as 0.

§cache_write_tokens: u64§cache_turns: u64

Assistant messages that reported AT LEAST ONE cache field — the honest denominator for cache_hit_pct(). A provider that reports nothing must OMIT the rate rather than print 0% (streamfn.rs:1255 cache_read_tokens: (usage.cached_input_tokens > 0).then_some(...): zero is rig’s sentinel for “not reported”).

§tools: Vec<ToolStat>

One entry per distinct tool name, sorted by calls descending, ties by name ascending. Empty when no tool has been called. (WAS Vec<(String, u64)> — same sort, more facts.)

§tool_errors: u64

Σ tools[..].errors — the headline count summary() prints.

§last_input_tokens: Option<u64>

Provider-reported input tokens of the most recent Assistant message with Some(usage). None until a turn reports usage. NOT summed by aggregate() (see below): it is a “how full was the last request” fact.

§cost: Option<Cost>

The session’s $ cost. None from the pure fold (the fold has no provider); Some once the actor prices it. skip_serializing_if keeps it off the wire when absent — mandatory for an additive variant.

Implementations§

Source§

impl SessionStats

Source

pub fn summary(&self) -> String

The one-line summary both front-ends print: plain text — no colors, no layout, no context; front-ends add chrome.

Contract:

  • turns == 0 ⇒ "(no usage reported)".
  • otherwise ⇒ "usage: N turns, X in, Y out[, C cache read][, W cache write][, tools: …]" where the cache fields are omitted when 0, the tools: segment is omitted when no tool ran, and the tool names are capped at TOOL_LIST_CAP, the remainder folded into "+K more".
  • appends , N% cache when cache_hit_pct() is Some, , N tool error(s) when tool_errors > 0, and , ~$d.dddd when cost is Some — (N turns unpriced) when Cost::unpriced_turns > 0. % cache sits right after the cache tokens, tool error(s) after tools:, and ~$ last.
  • The trailing context U/L readout is intentionally NOT here: its limit comes from the front-end (REPL model_limit, TUI status.context_limit), so each wraps/appends it.
Source

pub fn cache_hit_pct(&self) -> Option<u8>

Cache hit rate as an integer percent, rounded to the nearest percent.

Contract:

  • Some((cache_read * 100 + input / 2) / input) when input_tokens > 0 && cache_turns > 0, else None: a session that reported no cache OMITS the clause instead of claiming 0%.
  • the denominator is input_tokens ALONE. On the chat-completions wire a cached read is a SUBSET of input_tokens (rig maps prompt_tokens_details.cached_tokens), so adding cache_read back would double-count. A provider on the Anthropic wire — where input_tokens EXCLUDES cache reads/writes — would understate here; wcode speaks the OpenAI-compatible wire only, and that is the documented assumption (D028).
  • saturates at 100: more cached tokens than input is a provider bug, and 120% on screen would be worse than the clamp.
  • cache_write is not a hit: it is reported separately and priced.
Source

pub fn tool_error_pct(&self) -> Option<u8>

Share of tool calls that did not succeed, rounded to the nearest percent.

Some((tool_errors * 100 + calls / 2) / calls) over Σcalls when a tool ran at all, else None. errors counts hook-blocked and synthesized aborts (see ToolStat), so this is “not a success”, never “the tool is buggy”; saturates at 100 for the same reason as cache_hit_pct.

Trait Implementations§

Source§

impl Clone for SessionStats

Source§

fn clone(&self) -> Self

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 SessionStats

Source§

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

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

impl Default for SessionStats

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for SessionStats

Source§

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

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

impl Eq for SessionStats

Source§

impl PartialEq for SessionStats

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for SessionStats

Source§

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

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for SessionStats

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> 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<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> 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> IntoToolOutput for T
where T: Serialize + 'static,

Source§

fn into_tool_output(self) -> Result<ToolOutput, ToolExecutionError>

Convert this value without routing structured data through a string.
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> 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 = !

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

fn try_from(value: U) -> Result<T, !>

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<T> WasmCompatSend for T
where T: Send,

Source§

impl<T> WasmCompatSync for T
where T: Sync,

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