use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentIdentity {
pub agent_id: String,
pub specialization: AgentRole,
pub workspace_path: PathBuf,
pub env_vars: HashMap<String, String>,
pub session_id: String,
pub parent_process_id: String,
pub initialized_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Hash, Eq)]
pub enum AgentRole {
Frontend {
technologies: Vec<String>,
responsibilities: Vec<String>,
boundaries: Vec<String>,
},
Backend {
technologies: Vec<String>,
responsibilities: Vec<String>,
boundaries: Vec<String>,
},
DevOps {
technologies: Vec<String>,
responsibilities: Vec<String>,
boundaries: Vec<String>,
},
QA {
technologies: Vec<String>,
responsibilities: Vec<String>,
boundaries: Vec<String>,
},
Master {
oversight_roles: Vec<String>,
quality_standards: QualityStandards,
},
Search {
technologies: Vec<String>,
responsibilities: Vec<String>,
boundaries: Vec<String>,
},
}
impl AgentRole {
pub fn name(&self) -> &str {
match self {
AgentRole::Frontend { .. } => "Frontend",
AgentRole::Backend { .. } => "Backend",
AgentRole::DevOps { .. } => "DevOps",
AgentRole::QA { .. } => "QA",
AgentRole::Master { .. } => "Master",
AgentRole::Search { .. } => "Search",
}
}
pub fn as_str(&self) -> &str {
self.name()
}
pub fn technologies(&self) -> Vec<String> {
match self {
AgentRole::Frontend { technologies, .. }
| AgentRole::Backend { technologies, .. }
| AgentRole::DevOps { technologies, .. }
| AgentRole::QA { technologies, .. }
| AgentRole::Search { technologies, .. } => technologies.clone(),
AgentRole::Master { .. } => vec!["Orchestration".to_string()],
}
}
pub fn responsibilities(&self) -> Vec<String> {
match self {
AgentRole::Frontend {
responsibilities, ..
}
| AgentRole::Backend {
responsibilities, ..
}
| AgentRole::DevOps {
responsibilities, ..
}
| AgentRole::QA {
responsibilities, ..
}
| AgentRole::Search {
responsibilities, ..
} => responsibilities.clone(),
AgentRole::Master {
oversight_roles, ..
} => oversight_roles.clone(),
}
}
pub fn boundaries(&self) -> Vec<String> {
match self {
AgentRole::Frontend { boundaries, .. }
| AgentRole::Backend { boundaries, .. }
| AgentRole::DevOps { boundaries, .. }
| AgentRole::QA { boundaries, .. }
| AgentRole::Search { boundaries, .. } => boundaries.clone(),
AgentRole::Master { .. } => vec!["No direct code implementation".to_string()],
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct QualityStandards {
pub min_test_coverage: f64,
pub max_complexity: u32,
pub security_scan_required: bool,
pub performance_threshold_secs: u64,
}
impl std::hash::Hash for QualityStandards {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.min_test_coverage.to_bits().hash(state);
self.max_complexity.hash(state);
self.security_scan_required.hash(state);
self.performance_threshold_secs.hash(state);
}
}
impl Eq for QualityStandards {}
impl Default for QualityStandards {
fn default() -> Self {
Self {
min_test_coverage: 0.85, max_complexity: 10,
security_scan_required: true,
performance_threshold_secs: 5,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum IdentityStatus {
Healthy,
DriftDetected(String),
BoundaryViolation(String),
CriticalFailure(String),
}
pub fn default_frontend_role() -> AgentRole {
AgentRole::Frontend {
technologies: vec![
"React".to_string(),
"TypeScript".to_string(),
"Tailwind CSS".to_string(),
"Jest".to_string(),
"Vite".to_string(),
],
responsibilities: vec![
"UI Component Development".to_string(),
"State Management".to_string(),
"Frontend Testing".to_string(),
"User Experience".to_string(),
"Accessibility".to_string(),
],
boundaries: vec![
"No backend API development".to_string(),
"No database operations".to_string(),
"No server-side logic".to_string(),
"No infrastructure changes".to_string(),
"No deployment scripts".to_string(),
],
}
}
pub fn default_backend_role() -> AgentRole {
AgentRole::Backend {
technologies: vec![
"Node.js".to_string(),
"TypeScript".to_string(),
"Express".to_string(),
"PostgreSQL".to_string(),
"Prisma".to_string(),
],
responsibilities: vec![
"API Development".to_string(),
"Database Design".to_string(),
"Authentication".to_string(),
"Business Logic".to_string(),
"Data Validation".to_string(),
],
boundaries: vec![
"No frontend UI code".to_string(),
"No CSS styling".to_string(),
"No infrastructure provisioning".to_string(),
"No deployment automation".to_string(),
],
}
}
pub fn default_devops_role() -> AgentRole {
AgentRole::DevOps {
technologies: vec![
"Docker".to_string(),
"Kubernetes".to_string(),
"Terraform".to_string(),
"AWS".to_string(),
"GitHub Actions".to_string(),
],
responsibilities: vec![
"Infrastructure Provisioning".to_string(),
"CI/CD Pipelines".to_string(),
"Monitoring Setup".to_string(),
"Security Configuration".to_string(),
"Deployment Automation".to_string(),
],
boundaries: vec![
"No application code changes".to_string(),
"No business logic implementation".to_string(),
"No UI development".to_string(),
"No database schema design".to_string(),
],
}
}
pub fn default_qa_role() -> AgentRole {
AgentRole::QA {
technologies: vec![
"Jest".to_string(),
"Cypress".to_string(),
"Playwright".to_string(),
"Postman".to_string(),
"K6".to_string(),
],
responsibilities: vec![
"Test Strategy".to_string(),
"Test Implementation".to_string(),
"Quality Assurance".to_string(),
"Performance Testing".to_string(),
"Security Testing".to_string(),
],
boundaries: vec![
"No production code changes".to_string(),
"No feature implementation".to_string(),
"No infrastructure changes".to_string(),
"No deployment execution".to_string(),
],
}
}
pub fn default_search_role() -> AgentRole {
AgentRole::Search {
technologies: vec![
"Gemini CLI".to_string(),
"Web Search".to_string(),
"Information Retrieval".to_string(),
"Search APIs".to_string(),
],
responsibilities: vec![
"Web Search".to_string(),
"Information Gathering".to_string(),
"Result Filtering".to_string(),
"Query Optimization".to_string(),
"Knowledge Discovery".to_string(),
],
boundaries: vec![
"No code implementation".to_string(),
"No direct file modifications".to_string(),
"Read-only information gathering".to_string(),
"No execution of found code".to_string(),
"No decision making beyond search".to_string(),
],
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_role_functionality() {
let frontend = default_frontend_role();
assert_eq!(frontend.name(), "Frontend");
assert!(!frontend.technologies().is_empty());
assert!(!frontend.responsibilities().is_empty());
assert!(!frontend.boundaries().is_empty());
}
}