1use std::collections::HashMap;
4#[cfg(any(
5 feature = "provider-openai",
6 feature = "provider-mistral",
7 feature = "provider-gemini",
8 feature = "provider-anthropic-api",
9 feature = "provider-nvidia"
10))]
11use std::sync::LazyLock;
12
13#[derive(Debug, Clone, Copy)]
15pub struct CostEntry {
16 pub input_per_mtok: f64,
18 pub output_per_mtok: f64,
20}
21
22#[derive(Debug)]
24pub struct CostTable {
25 entries: HashMap<&'static str, CostEntry>,
26}
27
28impl CostTable {
29 pub fn compute(&self, model: &str, input_tokens: u64, output_tokens: u64) -> Option<f64> {
31 self.entries.get(model).map(|e| {
32 (input_tokens as f64 / 1_000_000.0) * e.input_per_mtok
33 + (output_tokens as f64 / 1_000_000.0) * e.output_per_mtok
34 })
35 }
36}
37
38#[cfg(feature = "provider-openai")]
40pub static OPENAI_COSTS: LazyLock<CostTable> = LazyLock::new(|| {
41 use crate::providers::http::openai_compat::config::OpenAiModel;
42
43 let entries = HashMap::from([
44 (
45 OpenAiModel::GPT_5_5,
46 CostEntry {
47 input_per_mtok: 5.00,
48 output_per_mtok: 30.00,
49 },
50 ),
51 (
52 OpenAiModel::GPT_5_4,
53 CostEntry {
54 input_per_mtok: 2.50,
55 output_per_mtok: 15.00,
56 },
57 ),
58 (
59 OpenAiModel::GPT_5_4_MINI,
60 CostEntry {
61 input_per_mtok: 0.75,
62 output_per_mtok: 4.50,
63 },
64 ),
65 (
66 OpenAiModel::GPT_5_4_NANO,
67 CostEntry {
68 input_per_mtok: 0.20,
69 output_per_mtok: 1.25,
70 },
71 ),
72 (
73 OpenAiModel::GPT_4_1,
74 CostEntry {
75 input_per_mtok: 2.00,
76 output_per_mtok: 8.00,
77 },
78 ),
79 (
80 OpenAiModel::GPT_4_1_MINI,
81 CostEntry {
82 input_per_mtok: 0.40,
83 output_per_mtok: 1.60,
84 },
85 ),
86 (
87 OpenAiModel::GPT_4_1_NANO,
88 CostEntry {
89 input_per_mtok: 0.10,
90 output_per_mtok: 0.40,
91 },
92 ),
93 (
94 OpenAiModel::GPT_4O,
95 CostEntry {
96 input_per_mtok: 2.50,
97 output_per_mtok: 10.00,
98 },
99 ),
100 (
101 OpenAiModel::GPT_4O_MINI,
102 CostEntry {
103 input_per_mtok: 0.15,
104 output_per_mtok: 0.60,
105 },
106 ),
107 ]);
108 CostTable { entries }
109});
110
111#[cfg(feature = "provider-mistral")]
113pub static MISTRAL_COSTS: LazyLock<CostTable> = LazyLock::new(|| {
114 use crate::providers::http::openai_compat::config::MistralModel;
115
116 let entries = HashMap::from([
117 (
118 MistralModel::MEDIUM_3_5,
119 CostEntry {
120 input_per_mtok: 1.50,
121 output_per_mtok: 7.50,
122 },
123 ),
124 (
125 MistralModel::LARGE,
126 CostEntry {
127 input_per_mtok: 0.50,
128 output_per_mtok: 1.50,
129 },
130 ),
131 (
132 MistralModel::SMALL,
133 CostEntry {
134 input_per_mtok: 0.10,
135 output_per_mtok: 0.30,
136 },
137 ),
138 (
139 MistralModel::MEDIUM,
140 CostEntry {
141 input_per_mtok: 1.00,
142 output_per_mtok: 3.00,
143 },
144 ),
145 (
146 MistralModel::CODESTRAL,
147 CostEntry {
148 input_per_mtok: 0.30,
149 output_per_mtok: 0.90,
150 },
151 ),
152 ]);
153 CostTable { entries }
154});
155
156#[cfg(feature = "provider-anthropic-api")]
158pub static ANTHROPIC_COSTS: LazyLock<CostTable> = LazyLock::new(|| {
159 use crate::providers::http::anthropic::adapter::AnthropicModel;
160
161 let entries = HashMap::from([
162 (
163 AnthropicModel::FABLE_5,
164 CostEntry {
165 input_per_mtok: 10.00,
166 output_per_mtok: 50.00,
167 },
168 ),
169 (
170 AnthropicModel::MYTHOS_5,
171 CostEntry {
172 input_per_mtok: 10.00,
173 output_per_mtok: 50.00,
174 },
175 ),
176 (
177 AnthropicModel::OPUS_5,
178 CostEntry {
179 input_per_mtok: 5.00,
180 output_per_mtok: 25.00,
181 },
182 ),
183 (
185 AnthropicModel::SONNET_5,
186 CostEntry {
187 input_per_mtok: 3.00,
188 output_per_mtok: 15.00,
189 },
190 ),
191 (
192 AnthropicModel::OPUS_4_8,
193 CostEntry {
194 input_per_mtok: 5.00,
195 output_per_mtok: 25.00,
196 },
197 ),
198 (
199 AnthropicModel::OPUS_4_7,
200 CostEntry {
201 input_per_mtok: 5.00,
202 output_per_mtok: 25.00,
203 },
204 ),
205 (
206 AnthropicModel::SONNET_4_6,
207 CostEntry {
208 input_per_mtok: 3.00,
209 output_per_mtok: 15.00,
210 },
211 ),
212 (
213 AnthropicModel::HAIKU_4_5,
214 CostEntry {
215 input_per_mtok: 1.00,
216 output_per_mtok: 5.00,
217 },
218 ),
219 (
220 AnthropicModel::OPUS_4_6,
221 CostEntry {
222 input_per_mtok: 5.00,
223 output_per_mtok: 25.00,
224 },
225 ),
226 (
227 AnthropicModel::SONNET_4_5,
228 CostEntry {
229 input_per_mtok: 3.00,
230 output_per_mtok: 15.00,
231 },
232 ),
233 ]);
234 CostTable { entries }
235});
236
237#[cfg(feature = "provider-nvidia")]
239pub static NVIDIA_COSTS: LazyLock<CostTable> = LazyLock::new(|| {
240 use crate::providers::http::openai_compat::config::NvidiaModel;
241
242 let entries = HashMap::from([
243 (
244 NvidiaModel::NEMOTRON_NANO_9B,
245 CostEntry {
246 input_per_mtok: 0.04,
247 output_per_mtok: 0.16,
248 },
249 ),
250 (
251 NvidiaModel::NEMOTRON_SUPER_49B,
252 CostEntry {
253 input_per_mtok: 0.10,
254 output_per_mtok: 0.40,
255 },
256 ),
257 (
258 NvidiaModel::NEMOTRON_ULTRA_253B,
259 CostEntry {
260 input_per_mtok: 0.90,
261 output_per_mtok: 0.90,
262 },
263 ),
264 ]);
265 CostTable { entries }
266});
267
268#[cfg(feature = "provider-gemini")]
270pub static GEMINI_COSTS: LazyLock<CostTable> = LazyLock::new(|| {
271 use crate::providers::http::gemini::adapter::GeminiModel;
272
273 let entries = HashMap::from([
274 (
275 GeminiModel::FLASH_3_5,
276 CostEntry {
277 input_per_mtok: 0.15,
278 output_per_mtok: 0.60,
279 },
280 ),
281 (
282 GeminiModel::FLASH_LITE_3_1,
283 CostEntry {
284 input_per_mtok: 0.05,
285 output_per_mtok: 0.20,
286 },
287 ),
288 (
289 GeminiModel::PRO_2_5,
290 CostEntry {
291 input_per_mtok: 1.25,
292 output_per_mtok: 10.00,
293 },
294 ),
295 (
296 GeminiModel::FLASH_2_5,
297 CostEntry {
298 input_per_mtok: 0.15,
299 output_per_mtok: 0.60,
300 },
301 ),
302 (
303 GeminiModel::FLASH_LITE_2_5,
304 CostEntry {
305 input_per_mtok: 0.05,
306 output_per_mtok: 0.20,
307 },
308 ),
309 ]);
310 CostTable { entries }
311});