use super::{SubagentError, SubagentResult};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DelegatedTask {
pub id: String,
pub description: String,
pub prompt: String,
pub subagent_type: String,
#[serde(default)]
pub context: HashMap<String, serde_json::Value>,
#[serde(default)]
pub priority: TaskPriority,
#[serde(default)]
pub expected_outputs: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Default)]
pub enum TaskPriority {
Low,
#[default]
Medium,
High,
Critical,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskResult {
pub task_id: String,
pub success: bool,
pub result: serde_json::Value,
pub error: Option<String>,
#[serde(default)]
pub metadata: HashMap<String, serde_json::Value>,
}
pub struct DelegationManager {
active_tasks: HashMap<String, DelegatedTask>,
completed_tasks: HashMap<String, TaskResult>,
}
impl DelegationManager {
pub fn new() -> Self {
Self {
active_tasks: HashMap::new(),
completed_tasks: HashMap::new(),
}
}
pub fn create_task(
&mut self,
description: String,
prompt: String,
subagent_type: String,
priority: TaskPriority,
) -> DelegatedTask {
let task_id = format!("task-{}", uuid::Uuid::new_v4());
let task = DelegatedTask {
id: task_id.clone(),
description,
prompt,
subagent_type,
context: HashMap::new(),
priority,
expected_outputs: Vec::new(),
};
self.active_tasks.insert(task_id, task.clone());
task
}
pub fn analyze_for_delegation(&self, request: &str) -> SubagentResult<Vec<DelegatedTask>> {
let mut tasks = Vec::new();
let needs_frontend = self.detect_frontend_work(request);
let needs_backend = self.detect_backend_work(request);
let needs_devops = self.detect_devops_work(request);
let needs_qa = self.detect_qa_work(request);
let needs_semantic = self.detect_semantic_analysis(request);
if needs_frontend {
tasks.push(self.create_frontend_task(request));
}
if needs_backend {
tasks.push(self.create_backend_task(request));
}
if needs_devops {
tasks.push(self.create_devops_task(request));
}
if needs_qa {
tasks.push(self.create_qa_task(request));
}
if needs_semantic {
tasks.push(self.create_semantic_task(request));
}
if tasks.is_empty() {
tasks.push(self.create_general_task(request));
}
Ok(tasks)
}
fn detect_frontend_work(&self, request: &str) -> bool {
let frontend_keywords = [
"ui",
"frontend",
"react",
"vue",
"component",
"style",
"css",
"layout",
"responsive",
"design",
"interface",
"form",
"button",
];
let request_lower = request.to_lowercase();
frontend_keywords
.iter()
.any(|keyword| request_lower.contains(keyword))
}
fn detect_backend_work(&self, request: &str) -> bool {
let backend_keywords = [
"api",
"backend",
"database",
"server",
"endpoint",
"rest",
"graphql",
"authentication",
"authorization",
"model",
"schema",
];
let request_lower = request.to_lowercase();
backend_keywords
.iter()
.any(|keyword| request_lower.contains(keyword))
}
fn detect_devops_work(&self, request: &str) -> bool {
let devops_keywords = [
"docker",
"kubernetes",
"deploy",
"ci/cd",
"pipeline",
"container",
"infrastructure",
"aws",
"azure",
"gcp",
"terraform",
"ansible",
];
let request_lower = request.to_lowercase();
devops_keywords
.iter()
.any(|keyword| request_lower.contains(keyword))
}
fn detect_qa_work(&self, request: &str) -> bool {
let qa_keywords = [
"test",
"testing",
"qa",
"quality",
"coverage",
"unit test",
"integration test",
"e2e",
"bug",
"validation",
"verification",
];
let request_lower = request.to_lowercase();
qa_keywords
.iter()
.any(|keyword| request_lower.contains(keyword))
}
fn detect_semantic_analysis(&self, request: &str) -> bool {
let semantic_keywords = [
"analyze",
"understand",
"refactor",
"optimize",
"pattern",
"architecture",
"structure",
"dependency",
"complexity",
"metrics",
];
let request_lower = request.to_lowercase();
semantic_keywords
.iter()
.any(|keyword| request_lower.contains(keyword))
}
fn create_frontend_task(&self, request: &str) -> DelegatedTask {
DelegatedTask {
id: format!("task-frontend-{}", uuid::Uuid::new_v4()),
description: "Frontend implementation".to_string(),
prompt: format!(
"As a frontend specialist, implement the following:\n\n{}\n\n\
Focus on UI/UX, component architecture, and responsive design.",
request
),
subagent_type: "frontend-specialist".to_string(),
context: HashMap::new(),
priority: TaskPriority::High,
expected_outputs: vec![
"Component implementation".to_string(),
"Style definitions".to_string(),
"State management".to_string(),
],
}
}
fn create_backend_task(&self, request: &str) -> DelegatedTask {
DelegatedTask {
id: format!("task-backend-{}", uuid::Uuid::new_v4()),
description: "Backend development".to_string(),
prompt: format!(
"As a backend specialist, implement the following:\n\n{}\n\n\
Focus on API design, database optimization, and business logic.",
request
),
subagent_type: "backend-specialist".to_string(),
context: HashMap::new(),
priority: TaskPriority::High,
expected_outputs: vec![
"API endpoints".to_string(),
"Database schemas".to_string(),
"Business logic".to_string(),
],
}
}
fn create_devops_task(&self, request: &str) -> DelegatedTask {
DelegatedTask {
id: format!("task-devops-{}", uuid::Uuid::new_v4()),
description: "DevOps configuration".to_string(),
prompt: format!(
"As a DevOps specialist, implement the following:\n\n{}\n\n\
Focus on containerization, CI/CD, and infrastructure.",
request
),
subagent_type: "devops-specialist".to_string(),
context: HashMap::new(),
priority: TaskPriority::Medium,
expected_outputs: vec![
"Docker configuration".to_string(),
"CI/CD pipeline".to_string(),
"Deployment scripts".to_string(),
],
}
}
fn create_qa_task(&self, request: &str) -> DelegatedTask {
DelegatedTask {
id: format!("task-qa-{}", uuid::Uuid::new_v4()),
description: "Quality assurance".to_string(),
prompt: format!(
"As a QA specialist, implement the following:\n\n{}\n\n\
Focus on comprehensive testing and quality metrics.",
request
),
subagent_type: "qa-specialist".to_string(),
context: HashMap::new(),
priority: TaskPriority::Medium,
expected_outputs: vec![
"Test suites".to_string(),
"Coverage reports".to_string(),
"Quality metrics".to_string(),
],
}
}
fn create_semantic_task(&self, request: &str) -> DelegatedTask {
DelegatedTask {
id: format!("task-semantic-{}", uuid::Uuid::new_v4()),
description: "Semantic analysis".to_string(),
prompt: format!(
"Perform semantic analysis:\n\n{}\n\n\
Use semantic tools to understand code structure and patterns.",
request
),
subagent_type: "semantic-analyst".to_string(),
context: HashMap::new(),
priority: TaskPriority::High,
expected_outputs: vec![
"Code analysis".to_string(),
"Pattern identification".to_string(),
"Improvement suggestions".to_string(),
],
}
}
fn create_general_task(&self, request: &str) -> DelegatedTask {
DelegatedTask {
id: format!("task-general-{}", uuid::Uuid::new_v4()),
description: "General task".to_string(),
prompt: request.to_string(),
subagent_type: "general-purpose".to_string(),
context: HashMap::new(),
priority: TaskPriority::Medium,
expected_outputs: vec!["Task completion".to_string()],
}
}
pub fn complete_task(&mut self, task_id: &str, result: TaskResult) -> SubagentResult<()> {
if self.active_tasks.remove(task_id).is_none() {
return Err(SubagentError::NotFound(task_id.to_string()));
}
self.completed_tasks.insert(task_id.to_string(), result);
Ok(())
}
pub fn get_task_status(&self) -> (Vec<&DelegatedTask>, Vec<&TaskResult>) {
let active: Vec<&DelegatedTask> = self.active_tasks.values().collect();
let completed: Vec<&TaskResult> = self.completed_tasks.values().collect();
(active, completed)
}
}
impl Default for DelegationManager {
fn default() -> Self {
Self::new()
}
}