mod types;
use std::ops::{Add, AddAssign};
use crate::harness::usage::Usage;
use crate::registry::catalog::ModelPricing;
pub use types::*;
impl CostTotals {
pub fn new() -> Self {
Self::default()
}
fn recompute_total(&mut self) {
self.total_cost =
self.input_cost + self.output_cost + self.cache_cost + self.reasoning_cost;
}
}
impl Add for CostTotals {
type Output = CostTotals;
fn add(mut self, rhs: CostTotals) -> CostTotals {
self += rhs;
self
}
}
impl AddAssign for CostTotals {
fn add_assign(&mut self, rhs: CostTotals) {
self.input_cost += rhs.input_cost;
self.output_cost += rhs.output_cost;
self.cache_cost += rhs.cache_cost;
self.reasoning_cost += rhs.reasoning_cost;
self.recompute_total();
}
}
pub fn estimate_cost(pricing: &ModelPricing, usage: &Usage) -> CostTotals {
let price = |rate: Option<f64>, tokens: u64| rate.unwrap_or(0.0) * tokens as f64;
let mut totals = CostTotals {
input_cost: price(pricing.input_per_token, usage.input_tokens),
output_cost: price(pricing.output_per_token, usage.output_tokens),
cache_cost: price(pricing.cache_read_input_per_token, usage.cache_read_tokens)
+ price(
pricing.cache_creation_input_per_token,
usage.cache_creation_tokens,
),
reasoning_cost: price(pricing.output_reasoning_per_token, usage.reasoning_tokens),
total_cost: 0.0,
};
totals.recompute_total();
totals
}
#[cfg(test)]
mod test;