use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::fmt;
use uuid::Uuid;
use crate::Result;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct AgentId(Uuid);
impl AgentId {
pub fn new() -> Self {
Self(Uuid::new_v4())
}
}
impl Default for AgentId {
fn default() -> Self {
Self::new()
}
}
impl fmt::Display for AgentId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum AgentCapability {
Parsing,
TypeInference,
ApiExtraction,
SpecificationGeneration,
CodeGeneration,
Compilation,
Testing,
Packaging,
}
#[async_trait]
pub trait Agent: Send + Sync {
type Input: Send + Sync;
type Output: Send + Sync;
async fn execute(&self, input: Self::Input) -> Result<Self::Output>;
fn id(&self) -> AgentId;
fn name(&self) -> &str;
fn capabilities(&self) -> Vec<AgentCapability>;
fn validate_input(&self, _input: &Self::Input) -> Result<()> {
Ok(())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentMetadata {
pub id: AgentId,
pub name: String,
pub capabilities: Vec<AgentCapability>,
pub version: String,
}
impl AgentMetadata {
pub fn new(id: AgentId, name: impl Into<String>, capabilities: Vec<AgentCapability>) -> Self {
Self {
id,
name: name.into(),
capabilities,
version: env!("CARGO_PKG_VERSION").to_string(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_agent_id_creation() {
let id1 = AgentId::new();
let id2 = AgentId::new();
assert_ne!(id1, id2);
}
#[test]
fn test_agent_id_display() {
let id = AgentId::new();
let display = format!("{}", id);
assert!(!display.is_empty());
}
#[test]
fn test_agent_metadata_creation() {
let id = AgentId::new();
let metadata = AgentMetadata::new(
id,
"TestAgent",
vec![AgentCapability::Parsing],
);
assert_eq!(metadata.id, id);
assert_eq!(metadata.name, "TestAgent");
assert_eq!(metadata.capabilities.len(), 1);
}
}