use bitrouter_core::models::language::usage::LanguageModelUsage;
use bitrouter_core::routers::routing_table::ModelPricing;
pub trait PricingLookup {
fn model_pricing(&self, provider: &str, model_id: &str) -> ModelPricing;
}
impl PricingLookup for bitrouter_config::ConfigRoutingTable {
fn model_pricing(&self, provider: &str, model_id: &str) -> ModelPricing {
self.model_pricing(provider, model_id)
}
}
impl<T: PricingLookup> PricingLookup for bitrouter_core::routers::dynamic::DynamicRoutingTable<T> {
fn model_pricing(&self, provider: &str, model_id: &str) -> ModelPricing {
self.read_inner().model_pricing(provider, model_id)
}
}
pub fn calculate_usage_cost(usage: &LanguageModelUsage, pricing: &ModelPricing) -> f64 {
bitrouter_core::pricing::calculate_cost(usage, pricing)
}
pub fn cost_to_micro_units(cost_usd: f64) -> u128 {
if cost_usd <= 0.0 {
return 0;
}
(cost_usd * 1_000_000.0).round() as u128
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn zero_cost() {
assert_eq!(cost_to_micro_units(0.0), 0);
}
#[test]
fn negative_cost() {
assert_eq!(cost_to_micro_units(-1.5), 0);
}
#[test]
fn one_dollar() {
assert_eq!(cost_to_micro_units(1.0), 1_000_000);
}
#[test]
fn fractional_cost() {
assert_eq!(cost_to_micro_units(0.015), 15_000);
}
#[test]
fn sub_micro_unit_rounds() {
assert_eq!(cost_to_micro_units(0.0000004), 0);
assert_eq!(cost_to_micro_units(0.0000006), 1);
}
#[test]
fn large_cost() {
assert_eq!(cost_to_micro_units(100.0), 100_000_000);
}
}