systemprompt_api/services/gateway/
pricing.rs1#[derive(Debug, Clone, Copy)]
2pub struct ModelPricing {
3 pub input_cost_per_1k: f32,
4 pub output_cost_per_1k: f32,
5}
6
7impl ModelPricing {
8 pub const fn zero() -> Self {
9 Self {
10 input_cost_per_1k: 0.0,
11 output_cost_per_1k: 0.0,
12 }
13 }
14}
15
16pub fn lookup(provider: &str, model: &str) -> ModelPricing {
17 let model_lc = model.to_ascii_lowercase();
18 let m = model_lc.as_str();
19
20 if provider.eq_ignore_ascii_case("anthropic") {
21 return match m {
22 x if x.starts_with("claude-opus-4-7") => ModelPricing {
23 input_cost_per_1k: 15.0,
24 output_cost_per_1k: 75.0,
25 },
26 x if x.starts_with("claude-opus-4") => ModelPricing {
27 input_cost_per_1k: 15.0,
28 output_cost_per_1k: 75.0,
29 },
30 x if x.starts_with("claude-sonnet-4") => ModelPricing {
31 input_cost_per_1k: 3.0,
32 output_cost_per_1k: 15.0,
33 },
34 x if x.starts_with("claude-haiku-4") => ModelPricing {
35 input_cost_per_1k: 1.0,
36 output_cost_per_1k: 5.0,
37 },
38 _ => unknown(provider, model),
39 };
40 }
41
42 if provider.eq_ignore_ascii_case("minimax") {
43 return match m {
44 x if x.contains("minimax-m") => ModelPricing {
45 input_cost_per_1k: 0.2,
46 output_cost_per_1k: 1.1,
47 },
48 _ => ModelPricing {
49 input_cost_per_1k: 0.2,
50 output_cost_per_1k: 1.1,
51 },
52 };
53 }
54
55 if provider.eq_ignore_ascii_case("openai") {
56 return match m {
57 x if x.starts_with("gpt-4o-mini") => ModelPricing {
58 input_cost_per_1k: 0.15,
59 output_cost_per_1k: 0.6,
60 },
61 x if x.starts_with("gpt-4o") => ModelPricing {
62 input_cost_per_1k: 2.5,
63 output_cost_per_1k: 10.0,
64 },
65 _ => unknown(provider, model),
66 };
67 }
68
69 unknown(provider, model)
70}
71
72fn unknown(provider: &str, model: &str) -> ModelPricing {
73 tracing::warn!(
74 provider = provider,
75 model = model,
76 "Gateway pricing lookup: no entry for (provider, model) — cost_microdollars will be 0"
77 );
78 ModelPricing::zero()
79}
80
81pub fn cost_microdollars(pricing: ModelPricing, input_tokens: u32, output_tokens: u32) -> i64 {
82 let input = f64::from(input_tokens);
83 let output = f64::from(output_tokens);
84 let input_cost = (input / 1000.0) * f64::from(pricing.input_cost_per_1k);
85 let output_cost = (output / 1000.0) * f64::from(pricing.output_cost_per_1k);
86 ((input_cost + output_cost) * 1_000_000.0).round() as i64
87}