juglans 0.1.0

Compiler and runtime for Juglans Workflow Language (JWL)
Documentation
// src/services/agent_loader.rs
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};

/// Agent 注册表 (类似于 PromptRegistry)
#[derive(Debug, Clone)]
pub struct AgentRegistry {
    // slug -> AgentResource
    agents: HashMap<String, AgentResource>,
}

impl AgentRegistry {
    pub fn new() -> Self {
        Self {
            agents: HashMap::new(),
        }
    }

    /// 根据配置的 glob patterns 加载本地 agents
    pub fn load_from_paths(&mut self, patterns: &[String]) -> Result<()> {
        for pattern in patterns {
            // 处理 glob,如 ./agents/*.jgagent
            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(())
    }

    /// 读取并解析单个 .jgagent 文件
    fn load_file(&mut self, path: &Path) -> Result<()> {
        // 1. 检查扩展名
        if path.extension().and_then(|s| s.to_str()) != Some("jgagent") {
            return Ok(());
        }

        // 2. 读取文件
        let content = fs::read_to_string(path)?;

        // 3. 解析
        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(())
    }

    /// 获取 Agent 定义
    pub fn get(&self, slug: &str) -> Option<&AgentResource> {
        self.agents.get(slug)
    }
    
    /// 获取所有加载的 Slug (用于调试或验证)
    pub fn keys(&self) -> Vec<String> {
        self.agents.keys().cloned().collect()
    }
}