//! # Agent Evolution Framework //! //! Implements agent-in-the-loop evolution with telemetry-driven proposal generation, //! safe sandbox execution, performance validation, and rollback mechanisms. //! //! ## Features //! - Telemetry analysis for optimization opportunities //! - Safe proposal generation and validation //! - Sandboxed execution environment //! - Performance regression detection //! - Automatic rollback on failures //! - Evolution history tracking use crate::{ Graph, GraphError, NodeId, Result, telemetry::{PerformanceMetrics, TelemetryCollector}, }; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; use std::sync::Arc; use std::time::{Duration, Instant}; use tokio::sync::RwLock; use uuid::Uuid; /// Evolution proposal generated from telemetry analysis #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EvolutionProposal { pub id: Uuid, pub name: String, pub description: String, pub proposal_type: ProposalType, pub confidence_score: f64, pub expected_improvement: ExpectedImprovement, pub implementation: ProposalImplementation, pub validation_criteria: Vec, pub created_at: DateTime, pub telemetry_evidence: TelemetryEvidence, } /// Type of evolution proposal #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum ProposalType { OptimizationPass, GraphRestructure, MemoryOptimization, ComputeOptimization, IOOptimization, CustomTransformation, } /// Expected performance improvement from proposal #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExpectedImprovement { pub throughput_increase: Option, pub latency_reduction: Option, pub memory_reduction: Option, pub energy_reduction: Option, pub reliability_increase: Option, } /// Implementation details of proposal #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProposalImplementation { pub code_changes: Vec, pub configuration_changes: BTreeMap, pub new_dependencies: Vec, pub breaking_changes: bool, } /// Individual code change in proposal #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CodeChange { pub file_path: String, pub change_type: ChangeType, pub before: Option, pub after: String, pub line_number: Option, } /// Type of code change #[derive(Debug, Clone, Serialize, Deserialize)] pub enum ChangeType { Addition, Modification, Deletion, Replacement, } /// Validation criterion for proposal #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ValidationCriterion { pub name: String, pub threshold: ValidationThreshold, pub importance: CriterionImportance, } /// Threshold for validation #[derive(Debug, Clone, Serialize, Deserialize)] pub enum ValidationThreshold { PerformanceRegression(f64), // Maximum acceptable regression percentage MemoryIncrease(f64), // Maximum memory increase percentage LatencyIncrease(Duration), // Maximum latency increase ThroughputDecrease(f64), // Maximum throughput decrease percentage CustomMetric(String, f64), // Custom metric with threshold } /// Importance level of validation criterion #[derive(Debug, Clone, Serialize, Deserialize)] pub enum CriterionImportance { Critical, High, Medium, Low, } /// Evidence from telemetry supporting the proposal #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TelemetryEvidence { pub bottlenecks_identified: Vec, pub performance_patterns: Vec, pub resource_utilization: ResourceUtilization, pub error_patterns: Vec, pub trend_analysis: TrendAnalysis, } /// Performance pattern identified in telemetry #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PerformancePattern { pub pattern_type: String, pub frequency: f64, pub impact: f64, pub nodes_affected: Vec, } /// Resource utilization metrics #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ResourceUtilization { pub cpu_utilization: f64, pub memory_utilization: f64, pub gpu_utilization: Option, pub io_utilization: f64, pub network_utilization: f64, } /// Error pattern in telemetry #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ErrorPattern { pub error_type: String, pub frequency: f64, pub correlation: Option, } /// Trend analysis results #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TrendAnalysis { pub performance_trend: TrendDirection, pub memory_trend: TrendDirection, pub error_trend: TrendDirection, pub prediction_confidence: f64, } /// Direction of trend #[derive(Debug, Clone, Serialize, Deserialize)] pub enum TrendDirection { Improving, Degrading, Stable, Volatile, } /// Result of proposal execution #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExecutionResult { pub proposal_id: Uuid, pub status: ExecutionStatus, pub started_at: DateTime, pub completed_at: Option>, pub performance_impact: PerformanceImpact, pub validation_results: Vec, pub errors: Vec, pub rollback_info: Option, } /// Status of proposal execution #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum ExecutionStatus { Pending, InProgress, Succeeded, Failed, RolledBack, Cancelled, } /// Performance impact measurement #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PerformanceImpact { pub baseline_metrics: PerformanceMetrics, pub post_change_metrics: PerformanceMetrics, pub improvement_percentage: f64, pub regression_detected: bool, } /// Validation result for criterion #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ValidationResult { pub criterion: String, pub passed: bool, pub actual_value: f64, pub threshold_value: f64, pub message: String, } /// Execution error details #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExecutionError { pub error_type: String, pub message: String, pub timestamp: DateTime, pub recoverable: bool, } /// Information for rollback #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RollbackInfo { pub checkpoint_id: Uuid, pub rollback_reason: String, pub rollback_timestamp: DateTime, pub restoration_successful: bool, } /// Evolution history entry #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EvolutionHistoryEntry { pub id: Uuid, pub proposal: EvolutionProposal, pub execution_result: ExecutionResult, pub long_term_impact: Option, pub archived_at: Option>, } /// Long-term impact assessment #[derive(Debug, Clone, Serialize, Deserialize)] pub struct LongTermImpact { pub stability_impact: f64, pub maintenance_burden: f64, pub adaptability_change: f64, pub user_satisfaction_change: f64, } /// Sandbox environment for safe execution #[derive(Debug)] pub struct SandboxEnvironment { pub id: Uuid, graph_snapshot: Arc, resource_limits: ResourceLimits, isolation_level: IsolationLevel, } /// Resource limits for sandbox #[derive(Debug, Clone)] pub struct ResourceLimits { pub max_memory_mb: usize, pub max_cpu_time_ms: u64, pub max_gpu_memory_mb: Option, pub max_disk_space_mb: usize, pub network_allowed: bool, } /// Level of isolation for sandbox #[derive(Debug, Clone)] pub enum IsolationLevel { Process, Container, VirtualMachine, } /// Main evolution framework #[derive(Debug)] pub struct EvolutionFramework { proposal_generator: ProposalGenerator, sandbox_manager: SandboxManager, performance_validator: PerformanceValidator, rollback_manager: RollbackManager, history_tracker: HistoryTracker, telemetry_collector: Arc>, } /// Proposal generation component #[derive(Debug)] pub struct ProposalGenerator { analysis_rules: Vec, confidence_threshold: f64, } /// Analysis rule for proposal generation #[derive(Debug)] pub struct AnalysisRule { pub name: String, pub condition: AnalysisCondition, pub action: ProposalAction, pub confidence_weight: f64, } /// Condition for analysis rule #[derive(Debug)] pub enum AnalysisCondition { BottleneckDetected(String), PerformanceRegression(f64), ResourceUnderutilization(f64), ErrorRateHigh(f64), } /// Action to take when condition is met #[derive(Debug)] pub enum ProposalAction { OptimizeBottleneck, RestructureGraph, AdjustResourceAllocation, ImproveErrorHandling, } /// Sandbox management component #[derive(Debug)] pub struct SandboxManager { active_sandboxes: HashMap, default_limits: ResourceLimits, } /// Performance validation component #[derive(Debug)] pub struct PerformanceValidator { baseline_metrics: Option, validation_duration: Duration, } /// Rollback management component #[derive(Debug)] pub struct RollbackManager { checkpoints: HashMap, } /// Graph checkpoint for rollback #[derive(Debug, Clone)] pub struct GraphCheckpoint { pub id: Uuid, pub graph: Arc, pub metrics: PerformanceMetrics, pub created_at: DateTime, } /// Evolution history tracking #[derive(Debug)] pub struct HistoryTracker { entries: Vec, max_entries: usize, } impl EvolutionFramework { /// Create new evolution framework pub fn new(telemetry_collector: Arc>) -> Self { Self { proposal_generator: ProposalGenerator::new(), sandbox_manager: SandboxManager::new(), performance_validator: PerformanceValidator::new(), rollback_manager: RollbackManager::new(), history_tracker: HistoryTracker::new(), telemetry_collector, } } /// Generate evolution proposals from telemetry pub async fn generate_proposals(&mut self) -> Result> { let telemetry = self.telemetry_collector.read().await; let metrics = PerformanceMetrics::default(); drop(telemetry); self.proposal_generator .analyze_telemetry_and_generate_proposals(metrics) } /// Execute proposal in sandbox pub async fn execute_proposal_safely( &mut self, proposal: EvolutionProposal, graph: Arc, ) -> Result { // Create checkpoint for rollback let checkpoint = self .rollback_manager .create_checkpoint(graph.clone()) .await?; // Create sandbox let sandbox = self.sandbox_manager.create_sandbox(graph)?; // Execute in sandbox let mut result = self.execute_in_sandbox(&proposal, &sandbox).await?; // Validate performance let validation_passed = self .performance_validator .validate_performance(&result) .await?; if !validation_passed { result.status = ExecutionStatus::Failed; result.rollback_info = Some(RollbackInfo { checkpoint_id: checkpoint.id, rollback_reason: "Performance validation failed".to_string(), rollback_timestamp: Utc::now(), restoration_successful: true, }); } // Record in history self.history_tracker.add_entry(EvolutionHistoryEntry { id: Uuid::new_v4(), proposal: proposal.clone(), execution_result: result.clone(), long_term_impact: None, archived_at: None, }); Ok(result) } async fn execute_in_sandbox( &self, proposal: &EvolutionProposal, _sandbox: &SandboxEnvironment, ) -> Result { let _start_time = Instant::now(); let mut result = ExecutionResult { proposal_id: proposal.id, status: ExecutionStatus::InProgress, started_at: Utc::now(), completed_at: None, performance_impact: PerformanceImpact { baseline_metrics: PerformanceMetrics::default(), post_change_metrics: PerformanceMetrics::default(), improvement_percentage: 0.0, regression_detected: false, }, validation_results: Vec::new(), errors: Vec::new(), rollback_info: None, }; // Simulate proposal execution tokio::time::sleep(Duration::from_millis(100)).await; // Check if execution should succeed (simplified logic) let success = proposal.confidence_score > 0.7; if success { result.status = ExecutionStatus::Succeeded; result.performance_impact.improvement_percentage = proposal.confidence_score * 10.0; } else { result.status = ExecutionStatus::Failed; result.errors.push(ExecutionError { error_type: "ValidationFailure".to_string(), message: "Proposal execution failed validation".to_string(), timestamp: Utc::now(), recoverable: true, }); } result.completed_at = Some(Utc::now()); Ok(result) } /// Get evolution history pub fn get_history(&self) -> &[EvolutionHistoryEntry] { self.history_tracker.get_entries() } /// Rollback to checkpoint pub async fn rollback_to_checkpoint(&mut self, checkpoint_id: Uuid) -> Result<()> { self.rollback_manager.restore_checkpoint(checkpoint_id) } } impl ProposalGenerator { pub fn new() -> Self { Self { analysis_rules: vec![ AnalysisRule { name: "High Latency Detection".to_string(), condition: AnalysisCondition::BottleneckDetected("latency".to_string()), action: ProposalAction::OptimizeBottleneck, confidence_weight: 0.8, }, AnalysisRule { name: "Memory Pressure".to_string(), condition: AnalysisCondition::ResourceUnderutilization(0.9), action: ProposalAction::AdjustResourceAllocation, confidence_weight: 0.7, }, ], confidence_threshold: 0.6, } } pub fn analyze_telemetry_and_generate_proposals( &self, _metrics: PerformanceMetrics, ) -> Result> { let mut proposals = Vec::new(); // Generate sample proposal based on analysis let proposal = EvolutionProposal { id: Uuid::new_v4(), name: "Memory Access Optimization".to_string(), description: "Optimize memory access patterns for better cache locality".to_string(), proposal_type: ProposalType::MemoryOptimization, confidence_score: 0.8, expected_improvement: ExpectedImprovement { throughput_increase: Some(15.0), latency_reduction: Some(10.0), memory_reduction: Some(5.0), energy_reduction: Some(8.0), reliability_increase: None, }, implementation: ProposalImplementation { code_changes: vec![CodeChange { file_path: "src/memory.rs".to_string(), change_type: ChangeType::Modification, before: Some("// Old memory layout".to_string()), after: "// Optimized memory layout with better cache locality".to_string(), line_number: Some(42), }], configuration_changes: BTreeMap::new(), new_dependencies: vec![], breaking_changes: false, }, validation_criteria: vec![ ValidationCriterion { name: "No Performance Regression".to_string(), threshold: ValidationThreshold::PerformanceRegression(5.0), importance: CriterionImportance::Critical, }, ValidationCriterion { name: "Memory Usage".to_string(), threshold: ValidationThreshold::MemoryIncrease(10.0), importance: CriterionImportance::High, }, ], created_at: Utc::now(), telemetry_evidence: TelemetryEvidence { bottlenecks_identified: vec!["memory_access".to_string()], performance_patterns: vec![], resource_utilization: ResourceUtilization { cpu_utilization: 0.75, memory_utilization: 0.85, gpu_utilization: None, io_utilization: 0.45, network_utilization: 0.30, }, error_patterns: vec![], trend_analysis: TrendAnalysis { performance_trend: TrendDirection::Degrading, memory_trend: TrendDirection::Stable, error_trend: TrendDirection::Improving, prediction_confidence: 0.8, }, }, }; proposals.push(proposal); Ok(proposals) } } impl SandboxManager { pub fn new() -> Self { Self { active_sandboxes: HashMap::new(), default_limits: ResourceLimits { max_memory_mb: 1024, max_cpu_time_ms: 30000, max_gpu_memory_mb: Some(512), max_disk_space_mb: 100, network_allowed: false, }, } } pub fn create_sandbox(&mut self, graph: Arc) -> Result { let id = Uuid::new_v4(); let sandbox = SandboxEnvironment { id, graph_snapshot: graph, resource_limits: self.default_limits.clone(), isolation_level: IsolationLevel::Process, }; self.active_sandboxes.insert(id, sandbox.clone()); Ok(sandbox) } pub fn destroy_sandbox(&mut self, sandbox_id: Uuid) -> Result<()> { self.active_sandboxes.remove(&sandbox_id); Ok(()) } } impl PerformanceValidator { pub fn new() -> Self { Self { baseline_metrics: None, validation_duration: Duration::from_secs(10), } } pub async fn validate_performance(&self, result: &ExecutionResult) -> Result { // Simplified validation logic let has_critical_regression = result .validation_results .iter() .any(|v| !v.passed && v.criterion.contains("Critical")); Ok(!has_critical_regression && !result.performance_impact.regression_detected) } pub fn set_baseline(&mut self, metrics: PerformanceMetrics) { self.baseline_metrics = Some(metrics); } } impl RollbackManager { pub fn new() -> Self { Self { checkpoints: HashMap::new(), } } pub async fn create_checkpoint(&mut self, graph: Arc) -> Result { let id = Uuid::new_v4(); let checkpoint = GraphCheckpoint { id, graph, metrics: PerformanceMetrics::default(), created_at: Utc::now(), }; self.checkpoints.insert(id, checkpoint.clone()); Ok(checkpoint) } pub fn restore_checkpoint(&mut self, checkpoint_id: Uuid) -> Result<()> { if self.checkpoints.contains_key(&checkpoint_id) { // In a real implementation, this would restore the graph state Ok(()) } else { Err(GraphError::InvalidOperation( "Checkpoint not found".to_string(), )) } } } impl HistoryTracker { pub fn new() -> Self { Self { entries: Vec::new(), max_entries: 1000, } } pub fn add_entry(&mut self, entry: EvolutionHistoryEntry) { self.entries.push(entry); // Keep only the most recent entries if self.entries.len() > self.max_entries { self.entries.remove(0); } } pub fn get_entries(&self) -> &[EvolutionHistoryEntry] { &self.entries } pub fn get_successful_proposals(&self) -> Vec<&EvolutionHistoryEntry> { self.entries .iter() .filter(|entry| matches!(entry.execution_result.status, ExecutionStatus::Succeeded)) .collect() } } impl Clone for SandboxEnvironment { fn clone(&self) -> Self { Self { id: self.id, graph_snapshot: Arc::clone(&self.graph_snapshot), resource_limits: self.resource_limits.clone(), isolation_level: self.isolation_level.clone(), } } } impl Default for EvolutionFramework { fn default() -> Self { let telemetry_collector = Arc::new(RwLock::new(TelemetryCollector::new())); Self::new(telemetry_collector) } } impl Default for ProposalGenerator { fn default() -> Self { Self::new() } } impl Default for SandboxManager { fn default() -> Self { Self::new() } } impl Default for PerformanceValidator { fn default() -> Self { Self::new() } } impl Default for RollbackManager { fn default() -> Self { Self::new() } } impl Default for HistoryTracker { fn default() -> Self { Self::new() } } #[cfg(test)] mod tests { use super::*; use crate::GraphBuilder; #[tokio::test] async fn test_proposal_generation() { let telemetry = Arc::new(RwLock::new(TelemetryCollector::new())); let mut framework = EvolutionFramework::new(telemetry); let proposals = framework.generate_proposals().await.unwrap(); assert!(!proposals.is_empty()); let proposal = &proposals[0]; assert_eq!(proposal.name, "Memory Access Optimization"); assert_eq!(proposal.proposal_type, ProposalType::MemoryOptimization); assert_eq!(proposal.confidence_score, 0.8); assert!(!proposal.implementation.code_changes.is_empty()); assert_eq!(proposal.validation_criteria.len(), 2); } #[tokio::test] async fn test_sandbox_creation() { let mut manager = SandboxManager::new(); let graph = Arc::new(GraphBuilder::new().build().unwrap()); let sandbox = manager.create_sandbox(graph).unwrap(); assert!(manager.active_sandboxes.contains_key(&sandbox.id)); manager.destroy_sandbox(sandbox.id).unwrap(); assert!(!manager.active_sandboxes.contains_key(&sandbox.id)); } #[tokio::test] async fn test_proposal_execution() { let telemetry = Arc::new(RwLock::new(TelemetryCollector::new())); let mut framework = EvolutionFramework::new(telemetry); let graph = Arc::new(GraphBuilder::new().build().unwrap()); let proposal = EvolutionProposal { id: Uuid::new_v4(), name: "Test Proposal".to_string(), description: "Test proposal for execution".to_string(), proposal_type: ProposalType::OptimizationPass, confidence_score: 0.9, expected_improvement: ExpectedImprovement { throughput_increase: Some(10.0), latency_reduction: None, memory_reduction: None, energy_reduction: None, reliability_increase: None, }, implementation: ProposalImplementation { code_changes: vec![], configuration_changes: BTreeMap::new(), new_dependencies: vec![], breaking_changes: false, }, validation_criteria: vec![], created_at: Utc::now(), telemetry_evidence: TelemetryEvidence { bottlenecks_identified: vec![], performance_patterns: vec![], resource_utilization: ResourceUtilization { cpu_utilization: 0.5, memory_utilization: 0.6, gpu_utilization: None, io_utilization: 0.3, network_utilization: 0.2, }, error_patterns: vec![], trend_analysis: TrendAnalysis { performance_trend: TrendDirection::Stable, memory_trend: TrendDirection::Stable, error_trend: TrendDirection::Stable, prediction_confidence: 0.8, }, }, }; let result = framework .execute_proposal_safely(proposal, graph) .await .unwrap(); assert_eq!(result.status, ExecutionStatus::Succeeded); assert!(result.performance_impact.improvement_percentage > 0.0); let history = framework.get_history(); assert_eq!(history.len(), 1); } #[tokio::test] async fn test_failed_proposal_execution() { let telemetry = Arc::new(RwLock::new(TelemetryCollector::new())); let mut framework = EvolutionFramework::new(telemetry); let graph = Arc::new(GraphBuilder::new().build().unwrap()); let proposal = EvolutionProposal { id: Uuid::new_v4(), name: "Failing Proposal".to_string(), description: "Proposal that should fail".to_string(), proposal_type: ProposalType::OptimizationPass, confidence_score: 0.3, // Low confidence should cause failure expected_improvement: ExpectedImprovement { throughput_increase: Some(5.0), latency_reduction: None, memory_reduction: None, energy_reduction: None, reliability_increase: None, }, implementation: ProposalImplementation { code_changes: vec![], configuration_changes: BTreeMap::new(), new_dependencies: vec![], breaking_changes: false, }, validation_criteria: vec![], created_at: Utc::now(), telemetry_evidence: TelemetryEvidence { bottlenecks_identified: vec![], performance_patterns: vec![], resource_utilization: ResourceUtilization { cpu_utilization: 0.5, memory_utilization: 0.6, gpu_utilization: None, io_utilization: 0.3, network_utilization: 0.2, }, error_patterns: vec![], trend_analysis: TrendAnalysis { performance_trend: TrendDirection::Stable, memory_trend: TrendDirection::Stable, error_trend: TrendDirection::Stable, prediction_confidence: 0.3, }, }, }; let result = framework .execute_proposal_safely(proposal, graph) .await .unwrap(); assert_eq!(result.status, ExecutionStatus::Failed); assert!(!result.errors.is_empty()); } #[tokio::test] async fn test_checkpoint_creation_and_rollback() { let mut manager = RollbackManager::new(); let graph = Arc::new(GraphBuilder::new().build().unwrap()); let checkpoint = manager.create_checkpoint(graph).await.unwrap(); assert!(manager.checkpoints.contains_key(&checkpoint.id)); let rollback_result = manager.restore_checkpoint(checkpoint.id); assert!(rollback_result.is_ok()); let invalid_rollback = manager.restore_checkpoint(Uuid::new_v4()); assert!(invalid_rollback.is_err()); } #[test] fn test_history_tracking() { let mut tracker = HistoryTracker::new(); let entry = EvolutionHistoryEntry { id: Uuid::new_v4(), proposal: EvolutionProposal { id: Uuid::new_v4(), name: "Test".to_string(), description: "Test proposal".to_string(), proposal_type: ProposalType::OptimizationPass, confidence_score: 0.8, expected_improvement: ExpectedImprovement { throughput_increase: None, latency_reduction: None, memory_reduction: None, energy_reduction: None, reliability_increase: None, }, implementation: ProposalImplementation { code_changes: vec![], configuration_changes: BTreeMap::new(), new_dependencies: vec![], breaking_changes: false, }, validation_criteria: vec![], created_at: Utc::now(), telemetry_evidence: TelemetryEvidence { bottlenecks_identified: vec![], performance_patterns: vec![], resource_utilization: ResourceUtilization { cpu_utilization: 0.5, memory_utilization: 0.6, gpu_utilization: None, io_utilization: 0.3, network_utilization: 0.2, }, error_patterns: vec![], trend_analysis: TrendAnalysis { performance_trend: TrendDirection::Stable, memory_trend: TrendDirection::Stable, error_trend: TrendDirection::Stable, prediction_confidence: 0.8, }, }, }, execution_result: ExecutionResult { proposal_id: Uuid::new_v4(), status: ExecutionStatus::Succeeded, started_at: Utc::now(), completed_at: Some(Utc::now()), performance_impact: PerformanceImpact { baseline_metrics: PerformanceMetrics::default(), post_change_metrics: PerformanceMetrics::default(), improvement_percentage: 10.0, regression_detected: false, }, validation_results: vec![], errors: vec![], rollback_info: None, }, long_term_impact: None, archived_at: None, }; tracker.add_entry(entry); assert_eq!(tracker.get_entries().len(), 1); let successful = tracker.get_successful_proposals(); assert_eq!(successful.len(), 1); } #[test] fn test_validation_criteria() { let criteria = vec![ ValidationCriterion { name: "Performance".to_string(), threshold: ValidationThreshold::PerformanceRegression(5.0), importance: CriterionImportance::Critical, }, ValidationCriterion { name: "Memory".to_string(), threshold: ValidationThreshold::MemoryIncrease(10.0), importance: CriterionImportance::High, }, ]; assert_eq!(criteria.len(), 2); assert!(matches!( criteria[0].importance, CriterionImportance::Critical )); assert!(matches!(criteria[1].importance, CriterionImportance::High)); } #[test] fn test_telemetry_evidence() { let evidence = TelemetryEvidence { bottlenecks_identified: vec!["memory".to_string(), "io".to_string()], performance_patterns: vec![PerformancePattern { pattern_type: "memory_spike".to_string(), frequency: 0.3, impact: 0.8, nodes_affected: vec![NodeId::new()], }], resource_utilization: ResourceUtilization { cpu_utilization: 0.85, memory_utilization: 0.92, gpu_utilization: Some(0.45), io_utilization: 0.67, network_utilization: 0.23, }, error_patterns: vec![ErrorPattern { error_type: "timeout".to_string(), frequency: 0.1, correlation: Some("high_memory_usage".to_string()), }], trend_analysis: TrendAnalysis { performance_trend: TrendDirection::Degrading, memory_trend: TrendDirection::Volatile, error_trend: TrendDirection::Improving, prediction_confidence: 0.75, }, }; assert_eq!(evidence.bottlenecks_identified.len(), 2); assert_eq!(evidence.performance_patterns.len(), 1); assert_eq!(evidence.error_patterns.len(), 1); assert!(matches!( evidence.trend_analysis.performance_trend, TrendDirection::Degrading )); } }