use once_cell::sync::Lazy;
use serde_json::Value;
use crate::reroute::{CODEX_MODELS, KIMI_MODEL, SubProvider};
static PRICING: Lazy<Value> = Lazy::new(|| {
serde_json::from_str(include_str!("../../bench/pricing.json")).unwrap_or(Value::Null)
});
pub struct CatalogEntry {
pub id: String, pub input: Option<f64>, pub output: Option<f64>, pub cache_read: Option<f64>,
}
pub fn models_for(provider: SubProvider) -> Vec<CatalogEntry> {
match provider {
SubProvider::Codex => CODEX_MODELS
.iter()
.map(|id| entry_for(id, &["openai/"]))
.collect(),
SubProvider::Kimi => {
vec![entry_for(KIMI_MODEL, &["moonshotai/", "moonshot/"])]
}
}
}
fn entry_for(id: &str, prefixes: &[&str]) -> CatalogEntry {
let models = PRICING.get("models");
let price = lookup(models, id, prefixes);
CatalogEntry {
id: id.to_string(),
input: price.and_then(|p| field(p, "input")),
output: price.and_then(|p| field(p, "output")),
cache_read: price.and_then(|p| field(p, "cache_read")),
}
}
fn lookup<'a>(models: Option<&'a Value>, id: &str, prefixes: &[&str]) -> Option<&'a Value> {
let map = models?.as_object()?;
for p in prefixes {
if let Some(v) = map.get(&format!("{p}{id}")) {
return Some(v);
}
}
if let Some(v) = map.get(id) {
return Some(v);
}
let want = id.to_ascii_lowercase();
let want_slash = format!("/{want}");
map.iter()
.find(|(k, _)| {
let k = k.to_ascii_lowercase();
k == want || k.ends_with(&want_slash)
})
.map(|(_, v)| v)
}
fn field(price: &Value, key: &str) -> Option<f64> {
price.get(key).and_then(Value::as_f64)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn embedded_pricing_is_a_models_object() {
let models = PRICING
.get("models")
.expect("pricing.json must have a `models` key");
assert!(models.is_object(), "`models` must be an object");
assert!(
!models.as_object().unwrap().is_empty(),
"`models` map must not be empty"
);
}
#[test]
fn codex_returns_exactly_curated_ids() {
let ids: Vec<String> = models_for(SubProvider::Codex)
.into_iter()
.map(|e| e.id)
.collect();
assert_eq!(ids, CODEX_MODELS.to_vec());
}
#[test]
fn kimi_returns_single_entry() {
let entries = models_for(SubProvider::Kimi);
assert_eq!(entries.len(), 1);
assert_eq!(entries[0].id, KIMI_MODEL);
}
#[test]
fn known_id_has_pricing_matching_snapshot() {
let gpt55 = models_for(SubProvider::Codex)
.into_iter()
.find(|e| e.id == "gpt-5.5")
.expect("gpt-5.5 in the Codex catalog");
let expected = PRICING["models"]["openai/gpt-5.5"]["input"]
.as_f64()
.expect("gpt-5.5 input price in snapshot");
assert_eq!(gpt55.input, Some(expected));
assert!(gpt55.output.is_some());
assert!(gpt55.cache_read.is_some());
}
#[test]
fn bogus_id_yields_all_none() {
let e = entry_for("totally-not-a-real-model-xyz", &["openai/"]);
assert_eq!(e.input, None);
assert_eq!(e.output, None);
assert_eq!(e.cache_read, None);
}
}