use super::{AgentId, AgentResult, AgentTask, TaskType};
use anyhow::Result;
use dashmap::DashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
use tracing::{debug, info};
pub struct AgentExecutor {
results: DashMap<AgentId, AgentResult>,
metrics: Arc<RwLock<ExecutionMetrics>>,
}
#[derive(Default)]
struct ExecutionMetrics {
total_executed: usize,
successful: usize,
failed: usize,
total_duration_ms: u64,
}
impl AgentExecutor {
pub fn new() -> Self {
Self {
results: DashMap::new(),
metrics: Arc::new(RwLock::new(ExecutionMetrics::default())),
}
}
pub async fn execute(&self, task: AgentTask) -> Result<AgentResult> {
let start = std::time::Instant::now();
debug!("Executing task: {:?}", task.task_type);
let result = match task.task_type {
TaskType::ScanRepository => {
self.execute_repo_scan(&task).await
}
TaskType::AnalyzeCode => {
self.execute_code_analysis(&task).await
}
TaskType::ExtractPatterns => {
self.execute_pattern_extraction(&task).await
}
TaskType::SummarizeWork => {
self.execute_work_summary(&task).await
}
TaskType::UpdateKnowledge => {
self.execute_knowledge_update(&task).await
}
TaskType::QueryKnowledge => {
self.execute_knowledge_query(&task).await
}
};
let duration = start.elapsed().as_millis() as u64;
{
let mut metrics = self.metrics.write().await;
metrics.total_executed += 1;
metrics.total_duration_ms += duration;
if result.is_ok() {
metrics.successful += 1;
} else {
metrics.failed += 1;
}
}
result
}
pub async fn store_result(&self, agent_id: AgentId, result: AgentResult) {
self.results.insert(agent_id, result);
}
pub async fn collect_results(&self) -> Vec<(AgentId, AgentResult)> {
self.results
.iter()
.map(|entry| (entry.key().clone(), entry.value().clone()))
.collect()
}
pub async fn get_metrics(&self) -> ExecutionMetricsSnapshot {
let metrics = self.metrics.read().await;
ExecutionMetricsSnapshot {
total_executed: metrics.total_executed,
successful: metrics.successful,
failed: metrics.failed,
average_duration_ms: if metrics.total_executed > 0 {
metrics.total_duration_ms / metrics.total_executed as u64
} else {
0
},
}
}
async fn execute_repo_scan(&self, task: &AgentTask) -> Result<AgentResult> {
info!("Scanning repository: {:?}", task.metadata.source);
Ok(AgentResult {
task_id: task.id.clone(),
success: true,
data: serde_json::json!({ "status": "scanned" }),
summary: "Repository scanned successfully".to_string(),
confidence: 1.0,
})
}
async fn execute_code_analysis(&self, task: &AgentTask) -> Result<AgentResult> {
info!("Analyzing code from: {:?}", task.metadata.source);
Ok(AgentResult {
task_id: task.id.clone(),
success: true,
data: serde_json::json!({ "status": "analyzed" }),
summary: "Code analysis completed".to_string(),
confidence: 0.95,
})
}
async fn execute_pattern_extraction(&self, task: &AgentTask) -> Result<AgentResult> {
info!("Extracting patterns from: {:?}", task.metadata.source);
Ok(AgentResult {
task_id: task.id.clone(),
success: true,
data: serde_json::json!({ "status": "patterns_extracted" }),
summary: "Patterns extracted successfully".to_string(),
confidence: 0.9,
})
}
async fn execute_work_summary(&self, task: &AgentTask) -> Result<AgentResult> {
info!("Summarizing work");
Ok(AgentResult {
task_id: task.id.clone(),
success: true,
data: serde_json::json!({ "status": "summarized" }),
summary: "Work summary generated".to_string(),
confidence: 0.85,
})
}
async fn execute_knowledge_update(&self, task: &AgentTask) -> Result<AgentResult> {
info!("Updating knowledge base");
Ok(AgentResult {
task_id: task.id.clone(),
success: true,
data: serde_json::json!({ "status": "updated" }),
summary: "Knowledge base updated".to_string(),
confidence: 1.0,
})
}
async fn execute_knowledge_query(&self, task: &AgentTask) -> Result<AgentResult> {
info!("Querying knowledge base");
Ok(AgentResult {
task_id: task.id.clone(),
success: true,
data: serde_json::json!({ "status": "queried" }),
summary: "Knowledge query completed".to_string(),
confidence: 0.9,
})
}
}
#[derive(Debug, Clone)]
pub struct ExecutionMetricsSnapshot {
pub total_executed: usize,
pub successful: usize,
pub failed: usize,
pub average_duration_ms: u64,
}
impl Default for AgentExecutor {
fn default() -> Self {
Self::new()
}
}