Expand description
Cumulative token budget tracking across turns.
§Why tokens and not money
claude-wrapper’s equivalent tracks USD, because that CLI reports a cost
per turn. The codex CLI does not: a completed turn carries token counts and
no monetary field (see the schema block in crate::types). Converting
tokens to dollars needs a per-model price table the CLI does not provide,
and a hardcoded one would go stale silently, which is the failure mode #73
was filed about. So the ceiling here is denominated in what the CLI
actually reports.
§What a budget cannot see
A tracker only counts what it is told, and two codex behaviours mean that is less than everything:
- A
turn.completedevent without ausageobject contributes nothing.TokenBudget::turns_missing_usagecounts those separately, so an unmeasured turn is distinguishable from a genuinely cheap one. - A review reports usage as all zeros. A session of reviews never advances the total at all.
Treat a budget as a floor on consumption rather than an exact measure.
§Example
use codex_wrapper::TokenBudget;
let budget = TokenBudget::builder()
.max_tokens(100_000)
.warn_at_tokens(80_000)
.on_warning(|total| eprintln!("at {total} tokens"))
.build();
budget.record(Some(50_000));
assert_eq!(budget.total_tokens(), 50_000);
assert_eq!(budget.remaining_tokens(), Some(50_000));
assert!(budget.check().is_ok());
budget.record(Some(60_000));
assert!(budget.check().is_err());Structs§
- Token
Budget - Cumulative token budget with threshold callbacks.
- Token
Budget Builder - Builder for
TokenBudget.