use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::analyzer::{AnalysisReport, Insight, Recommendation};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DecisionInput {
pub timestamp: DateTime<Utc>,
pub analysis_reports: Vec<AnalysisReport>,
pub insights: Vec<Insight>,
pub recommendations: Vec<Recommendation>,
pub current_metrics: SystemMetrics,
pub context: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemMetrics {
pub avg_latency_ms: f64,
pub p95_latency_ms: f64,
pub p99_latency_ms: f64,
pub success_rate_pct: f64,
pub error_rate_pct: f64,
pub throughput_rps: f64,
pub total_cost_usd: f64,
pub daily_cost_usd: f64,
pub avg_rating: Option<f64>,
pub cache_hit_rate_pct: Option<f64>,
pub request_count: u64,
pub timestamp: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Decision {
pub id: String,
pub timestamp: DateTime<Utc>,
pub strategy: String,
pub decision_type: DecisionType,
pub confidence: f64,
pub expected_impact: ExpectedImpact,
pub config_changes: Vec<ConfigChange>,
pub justification: String,
pub related_insights: Vec<String>,
pub related_recommendations: Vec<String>,
pub priority: u32,
pub requires_approval: bool,
pub safety_checks: Vec<SafetyCheck>,
pub rollback_plan: Option<RollbackPlan>,
pub metadata: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum DecisionType {
ModelSwitch,
EnableCaching,
AdjustRateLimits,
EnableBatching,
OptimizePrompt,
ScaleResources,
Rollback,
NoAction,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExpectedImpact {
pub cost_change_usd: Option<f64>,
pub latency_change_ms: Option<f64>,
pub quality_change: Option<f64>,
pub throughput_change_rps: Option<f64>,
pub success_rate_change_pct: Option<f64>,
pub time_to_impact: std::time::Duration,
pub confidence: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigChange {
pub config_type: ConfigType,
pub path: String,
pub old_value: Option<serde_json::Value>,
pub new_value: serde_json::Value,
pub description: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ConfigType {
Model,
Cache,
RateLimit,
Batching,
Prompt,
Timeout,
Resource,
Other,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SafetyCheck {
pub name: String,
pub passed: bool,
pub details: String,
pub timestamp: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RollbackPlan {
pub description: String,
pub revert_changes: Vec<ConfigChange>,
pub trigger_conditions: Vec<RollbackCondition>,
pub max_duration: std::time::Duration,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RollbackCondition {
pub metric: String,
pub operator: ComparisonOperator,
pub threshold: f64,
pub description: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ComparisonOperator {
GreaterThan,
LessThan,
GreaterThanOrEqual,
LessThanOrEqual,
Equal,
NotEqual,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DecisionOutcome {
pub decision_id: String,
pub execution_time: DateTime<Utc>,
pub success: bool,
pub error: Option<String>,
pub actual_impact: Option<ActualImpact>,
pub rolled_back: bool,
pub rollback_reason: Option<String>,
pub metrics_before: SystemMetrics,
pub metrics_after: Option<SystemMetrics>,
pub duration: std::time::Duration,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ActualImpact {
pub cost_change_usd: f64,
pub latency_change_ms: f64,
pub quality_change: f64,
pub throughput_change_rps: f64,
pub success_rate_change_pct: f64,
pub time_to_impact: std::time::Duration,
pub variance_from_expected: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DecisionCriteria {
pub min_confidence: f64,
pub max_cost_increase_usd: Option<f64>,
pub max_latency_increase_ms: Option<f64>,
pub min_quality_score: Option<f64>,
pub required_safety_checks: Vec<String>,
pub allow_breaking_changes: bool,
pub max_concurrent_decisions: usize,
pub enabled_strategies: Vec<String>,
pub strategy_priorities: HashMap<String, u32>,
}
impl Default for DecisionCriteria {
fn default() -> Self {
Self {
min_confidence: 0.7,
max_cost_increase_usd: Some(100.0),
max_latency_increase_ms: Some(500.0),
min_quality_score: Some(3.5),
required_safety_checks: vec![
"cost_check".to_string(),
"latency_check".to_string(),
"quality_check".to_string(),
],
allow_breaking_changes: false,
max_concurrent_decisions: 3,
enabled_strategies: vec![
"model_selection".to_string(),
"caching".to_string(),
"rate_limiting".to_string(),
"batching".to_string(),
"prompt_optimization".to_string(),
],
strategy_priorities: {
let mut priorities = HashMap::new();
priorities.insert("model_selection".to_string(), 100);
priorities.insert("caching".to_string(), 90);
priorities.insert("rate_limiting".to_string(), 80);
priorities.insert("batching".to_string(), 70);
priorities.insert("prompt_optimization".to_string(), 85);
priorities
},
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct DecisionStats {
pub total_decisions: u64,
pub decisions_by_type: HashMap<String, u64>,
pub decisions_by_strategy: HashMap<String, u64>,
pub successful_decisions: u64,
pub failed_decisions: u64,
pub rolled_back_decisions: u64,
pub avg_decision_latency_ms: f64,
pub avg_confidence: f64,
pub total_cost_savings_usd: f64,
pub total_latency_improvement_ms: f64,
pub last_decision_time: Option<DateTime<Utc>>,
}