pub struct UsageRecord {
pub turn: usize,
pub model: String,
pub prompt_tokens: u64,
pub completion_tokens: u64,
pub total_tokens: u64,
pub cached_tokens: Option<u64>,
pub timestamp_ms: i64,
pub cost_usd: Option<f64>,
pub served_model: Option<String>,
}Expand description
One model round-trip’s token accounting, with the context a bare
Usage lacks: which turn it was and which model served it (D9 “model
provenance” — obligation 6’s “served-model provenance” row). Deliberately
flat/typed (not a formatted string) so it survives a save/load round trip
byte-for-byte in the fields that matter, and so a future reader (a
doctor/inspect stats command, a cost dashboard) can aggregate it
without re-parsing text.
Fields§
§turn: usize0-based index of the model round-trip this record covers (one per
crate::AgentEvent::TurnCompleted, the same cadence UX-23
already uses).
model: StringThe model id that served this turn (Config.model, or the
mid-session-switched model once obligation 10 lands — recorded
per-turn rather than once per session so a handoff is visible in the
log, not just implied).
prompt_tokens: u64Input tokens.
completion_tokens: u64Output tokens.
total_tokens: u64Total tokens (provider-reported; not always prompt + completion
exactly, so kept as its own field rather than derived).
cached_tokens: Option<u64>Prompt tokens served from the provider’s cache (B7), if reported.
timestamp_ms: i64Unix-ms wall-clock time the record was created.
cost_usd: Option<f64>BP-7 (catalog §4a “Per-turn cost/usage accounting” — the COST half
the row’s semantics name alongside tokens): this round-trip’s dollar
cost at the model’s resolved crate::pricing::ModelPrice.
None when this build cannot price the model — never a guess, and
never zero standing in for “unknown”.
served_model: Option<String>BP-13 (D9 “Model-served-vs-requested provenance”): the model the
PROVIDER reported as having produced the response, when it reported
one at all. Self::model above is what was REQUESTED; these two
can genuinely differ (a gateway resolving a floating name to a dated
snapshot, a routed tier, a fallback hop), and a record that carries
only the request can never show it. None means the provider said
nothing — never “they matched”.
Implementations§
Source§impl UsageRecord
impl UsageRecord
Sourcepub fn from_usage(
turn: usize,
model: &str,
usage: &Usage,
timestamp_ms: i64,
) -> UsageRecord
pub fn from_usage( turn: usize, model: &str, usage: &Usage, timestamp_ms: i64, ) -> UsageRecord
Build a record from a provider Usage plus the per-turn context a
bare Usage doesn’t carry.
Sourcepub fn priced(self, price: Option<ModelPrice>) -> UsageRecord
pub fn priced(self, price: Option<ModelPrice>) -> UsageRecord
BP-7: the same record with cost_usd filled in from price, or
unchanged when the model has no resolvable price.
Sourcepub fn with_served_model(self, served: Option<String>) -> UsageRecord
pub fn with_served_model(self, served: Option<String>) -> UsageRecord
BP-13: attach the provider-reported serving model. None leaves the
record saying nothing about it, which is the honest reading when the
response carried no model field.
Trait Implementations§
Source§impl Clone for UsageRecord
impl Clone for UsageRecord
Source§fn clone(&self) -> UsageRecord
fn clone(&self) -> UsageRecord
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more