use crate::types::{Modality, ModelCapabilities};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
pub struct Limits {
pub context: Option<u32>,
pub input: Option<u32>,
pub output: Option<u32>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ContextTier {
pub min_context_tokens: u32,
pub input: Option<f64>,
pub output: Option<f64>,
pub cache_read: Option<f64>,
pub cache_write: Option<f64>,
pub reasoning: Option<f64>,
pub input_audio: Option<f64>,
pub output_audio: Option<f64>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ModelPricing {
pub input: f64,
pub output: f64,
pub cache_read: Option<f64>,
pub cache_write: Option<f64>,
pub reasoning: Option<f64>,
pub input_audio: Option<f64>,
pub output_audio: Option<f64>,
#[serde(default)]
pub tiers: Vec<ContextTier>,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
pub struct CatalogEntry {
pub name: Option<String>,
pub limits: Limits,
pub input_modalities: Vec<Modality>,
pub output_modalities: Vec<Modality>,
pub capabilities: Vec<ModelCapabilities>,
pub pricing: Option<ModelPricing>,
pub aliases: Vec<String>,
}
impl CatalogEntry {
pub fn is_empty(&self) -> bool {
self.name.is_none()
&& self.limits == Limits::default()
&& self.input_modalities.is_empty()
&& self.output_modalities.is_empty()
&& self.capabilities.is_empty()
&& self.pricing.is_none()
&& self.aliases.is_empty()
}
pub fn merge(self, higher: CatalogEntry) -> CatalogEntry {
let mut aliases = self.aliases;
for alias in higher.aliases {
if !aliases.contains(&alias) {
aliases.push(alias);
}
}
CatalogEntry {
name: higher.name.or(self.name),
limits: Limits {
context: higher.limits.context.or(self.limits.context),
input: higher.limits.input.or(self.limits.input),
output: higher.limits.output.or(self.limits.output),
},
input_modalities: if higher.input_modalities.is_empty() {
self.input_modalities
} else {
higher.input_modalities
},
output_modalities: if higher.output_modalities.is_empty() {
self.output_modalities
} else {
higher.output_modalities
},
capabilities: if higher.capabilities.is_empty() { self.capabilities } else { higher.capabilities },
pricing: higher.pricing.or(self.pricing),
aliases,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct CatalogKey {
pub provider_slug: Option<String>,
pub model_id: String,
}