use std::collections::HashMap;
use std::fs;
use std::path::Path;
use anyhow::{Result, anyhow};
use glob::glob;
use tracing::{info, warn};
use crate::core::agent_parser::{AgentParser, AgentResource};
#[derive(Debug, Clone)]
pub struct AgentRegistry {
agents: HashMap<String, AgentResource>,
}
impl AgentRegistry {
pub fn new() -> Self {
Self {
agents: HashMap::new(),
}
}
pub fn load_from_paths(&mut self, patterns: &[String]) -> Result<()> {
for pattern in patterns {
let paths = glob(pattern).map_err(|e| anyhow!("Invalid glob pattern '{}': {}", pattern, e))?;
for entry in paths {
match entry {
Ok(path) => {
if path.is_file() {
self.load_file(&path)?;
}
}
Err(e) => warn!("Error reading glob entry: {}", e),
}
}
}
Ok(())
}
fn load_file(&mut self, path: &Path) -> Result<()> {
if path.extension().and_then(|s| s.to_str()) != Some("jgagent") {
return Ok(());
}
let content = fs::read_to_string(path)?;
match AgentParser::parse(&content) {
Ok(agent) => {
info!("🤖 Loaded Agent: [{}] from {:?}", agent.slug, path);
self.agents.insert(agent.slug.clone(), agent);
}
Err(e) => {
warn!("Failed to parse agent file {:?}: {}", path, e);
}
}
Ok(())
}
pub fn get(&self, slug: &str) -> Option<&AgentResource> {
self.agents.get(slug)
}
pub fn keys(&self) -> Vec<String> {
self.agents.keys().cloned().collect()
}
}