use crate::core::{Agent, Tool};
use anyhow::Result;
use std::collections::HashMap;
use std::path::PathBuf;
use tracing::{info, warn};
#[derive(Debug, Default)]
pub struct Registry {
tools: HashMap<String, Tool>,
agents: HashMap<String, Agent>,
}
impl Registry {
pub fn new() -> Self {
Self::default()
}
pub async fn load_tools(&mut self, tool_dirs: &[PathBuf]) -> Result<()> {
info!(dirs = ?tool_dirs, "Loading tools from directories");
for dir in tool_dirs {
if !dir.exists() {
warn!(dir = %dir.display(), "Tool directory not found, skipping");
continue;
}
if dir.is_dir() {
let mut entries = tokio::fs::read_dir(dir).await?;
while let Some(entry) = entries.next_entry().await? {
let path = entry.path();
if path.is_file() {
if let Some(ext) = path.extension() {
if matches!(ext.to_str(), Some("sh" | "js" | "py")) {
match Tool::from_file(&path).await {
Ok(tool) => {
info!(name = %tool.name, "Loaded tool");
self.tools.insert(tool.name.clone(), tool);
}
Err(e) => {
warn!(path = %path.display(), error = ?e, "Failed to load tool");
}
}
}
}
}
}
}
}
Ok(())
}
pub async fn load_agents(&mut self, agent_dirs: &[PathBuf]) -> Result<()> {
info!(dirs = ?agent_dirs, "Loading agents from directories");
for dir in agent_dirs {
if !dir.exists() {
warn!(dir = %dir.display(), "Agent directory not found, skipping");
continue;
}
if dir.is_dir() {
let mut entries = tokio::fs::read_dir(dir).await?;
while let Some(entry) = entries.next_entry().await? {
let path = entry.path();
if path.is_dir() {
match Agent::from_directory(&path).await {
Ok(agent) => {
info!(name = %agent.name, "Loaded agent");
self.agents.insert(agent.name.clone(), agent);
}
Err(e) => {
warn!(path = %path.display(), error = ?e, "Failed to load agent");
}
}
}
}
}
}
Ok(())
}
pub fn get_tool(&self, name: &str) -> Option<&Tool> {
self.tools.get(name)
}
pub fn get_agent(&self, name: &str) -> Option<&Agent> {
self.agents.get(name)
}
pub fn list_tools(&self) -> Vec<String> {
self.tools.keys().cloned().collect()
}
pub fn list_agents(&self) -> Vec<String> {
self.agents.keys().cloned().collect()
}
}