lean_ctx/core/value_gate/
cost_tracker.rs1const TOKENS_PER_MILLION: u128 = 1_000_000;
4
5#[derive(Debug, Clone, Default, PartialEq, Eq)]
7pub struct ExecutionCost {
8 pub input_tokens: u64,
9 pub output_tokens: u64,
10 pub cache_read_tokens: u64,
11 pub model: String,
12 pub provider: String,
13 pub estimated_cost_micros: u64,
14}
15
16pub fn calculate_cost(input: u64, output: u64, cache: u64, model: &str) -> u64 {
18 let (input_rate, output_rate) = match model {
19 "gpt-4o" => (2_500_000u128, 10_000_000u128),
20 "claude-sonnet" => (3_000_000u128, 15_000_000u128),
21 _ => (5_000_000u128, 15_000_000u128),
22 };
23 let total = input as u128 * input_rate
24 + output as u128 * output_rate
25 + cache as u128 * (input_rate / 10);
26 u64::try_from(total / TOKENS_PER_MILLION).unwrap_or(u64::MAX)
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32
33 #[test]
34 fn cost_calculation_gpt4o() {
35 assert_eq!(
36 calculate_cost(1_000_000, 1_000_000, 0, "gpt-4o"),
37 12_500_000
38 );
39 }
40
41 #[test]
42 fn cost_calculation_claude() {
43 assert_eq!(
44 calculate_cost(1_000_000, 1_000_000, 0, "claude-sonnet"),
45 18_000_000
46 );
47 }
48
49 #[test]
50 fn cost_calculation_unknown() {
51 assert_eq!(calculate_cost(1_000_000, 1_000_000, 0, "other"), 20_000_000);
52 }
53
54 #[test]
55 fn cache_uses_ten_percent_of_input_rate() {
56 assert_eq!(calculate_cost(0, 0, 1_000_000, "gpt-4o"), 250_000);
57 }
58}