Skip to main content

ironflow_core/providers/http/
cost.rs

1//! Token cost tables per provider and model.
2
3use 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/// Cost per million tokens (input and output) for a model.
14#[derive(Debug, Clone, Copy)]
15pub struct CostEntry {
16    /// USD per million input tokens.
17    pub input_per_mtok: f64,
18    /// USD per million output tokens.
19    pub output_per_mtok: f64,
20}
21
22/// Lookup table mapping model identifiers to their token costs.
23#[derive(Debug)]
24pub struct CostTable {
25    entries: HashMap<&'static str, CostEntry>,
26}
27
28impl CostTable {
29    /// Compute cost in USD for the given token counts.
30    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/// OpenAI model costs.
39#[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/// Mistral model costs.
112#[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/// Anthropic model costs.
157#[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        // Standard rate; introductory pricing ($2 / $10) applies through 2026-08-31.
184        (
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/// NVIDIA NIM model costs (Nemotron models with known pricing).
238#[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/// Google Gemini model costs.
269#[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});