use super::types::UserMetrics;
use crate::utils::error::gateway_error::Result;
use serde::{Deserialize, Serialize};
pub struct CostOptimizer {
optimization_rules: Vec<OptimizationRule>,
}
#[derive(Debug, Clone)]
pub struct OptimizationRule {
pub name: String,
pub description: String,
pub potential_savings: f64,
pub difficulty: OptimizationDifficulty,
pub rule_type: OptimizationType,
}
#[derive(Debug, Clone)]
pub enum OptimizationDifficulty {
Easy,
Medium,
Hard,
}
#[derive(Debug, Clone)]
pub enum OptimizationType {
ProviderSwitch,
ModelDowngrade,
Caching,
Batching,
PromptOptimization,
PricingTier,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OptimizationSuggestion {
pub title: String,
pub description: String,
pub potential_savings: f64,
pub effort: String,
pub priority: u8,
pub recommendations: Vec<String>,
}
impl Default for CostOptimizer {
fn default() -> Self {
Self::new()
}
}
impl CostOptimizer {
pub fn new() -> Self {
Self {
optimization_rules: Self::default_rules(),
}
}
pub async fn analyze_and_suggest(
&self,
metrics: &UserMetrics,
) -> Result<Vec<OptimizationSuggestion>> {
let mut suggestions = Vec::new();
if metrics.cost_breakdown.total_cost > 100.0 {
suggestions.push(OptimizationSuggestion {
title: "Consider Model Optimization".to_string(),
description:
"Your usage patterns suggest potential savings through model optimization"
.to_string(),
potential_savings: metrics.cost_breakdown.total_cost * 0.2,
effort: "Medium".to_string(),
priority: 8,
recommendations: vec![
"Evaluate if smaller models can meet your needs".to_string(),
"Implement request caching for repeated queries".to_string(),
],
});
}
Ok(suggestions)
}
pub fn rules(&self) -> &[OptimizationRule] {
&self.optimization_rules
}
fn default_rules() -> Vec<OptimizationRule> {
vec![
OptimizationRule {
name: "Provider Cost Comparison".to_string(),
description: "Compare costs across different providers".to_string(),
potential_savings: 0.3,
difficulty: OptimizationDifficulty::Easy,
rule_type: OptimizationType::ProviderSwitch,
},
OptimizationRule {
name: "Model Right-sizing".to_string(),
description: "Use appropriately sized models for tasks".to_string(),
potential_savings: 0.4,
difficulty: OptimizationDifficulty::Medium,
rule_type: OptimizationType::ModelDowngrade,
},
]
}
}