use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use anyhow::Result;
use serde_json::Value;
use async_trait::async_trait;
use crate::services::prompt_loader::PromptRegistry;
use crate::services::agent_loader::AgentRegistry;
use crate::services::interface::JuglansRuntime; use crate::core::context::WorkflowContext;
#[async_trait]
pub trait Tool: Send + Sync {
fn name(&self) -> &str;
async fn execute(&self, params: &HashMap<String, String>, context: &WorkflowContext) -> Result<Option<Value>>;
}
pub struct BuiltinRegistry {
tools: RwLock<HashMap<String, Arc<Box<dyn Tool>>>>,
}
impl BuiltinRegistry {
pub fn new(
prompts: Arc<PromptRegistry>,
agents: Arc<AgentRegistry>,
runtime: Arc<dyn JuglansRuntime> ) -> Arc<Self> {
let mut tool_map: HashMap<String, Arc<Box<dyn Tool>>> = HashMap::new();
macro_rules! reg {
($t:expr) => { tool_map.insert($t.name().to_string(), Arc::new(Box::new($t))); };
}
reg!(network::FetchUrl);
reg!(system::Timer);
reg!(system::Notify);
reg!(system::SetContext);
reg!(ai::Prompt::new(prompts.clone(), runtime.clone()));
reg!(ai::MemorySearch::new(runtime.clone()));
let registry_arc = Arc::new(Self { tools: RwLock::new(tool_map) });
let mut chat_tool = ai::Chat::new(agents, prompts, runtime);
chat_tool.set_registry(Arc::downgrade(®istry_arc));
{
let mut guard = registry_arc.tools.write().expect("Lock poisoned");
guard.insert("chat".to_string(), Arc::new(Box::new(chat_tool)));
}
registry_arc
}
pub fn get(&self, name: &str) -> Option<Arc<Box<dyn Tool>>> {
self.tools.read().ok()?.get(name).cloned()
}
}
pub mod network;
pub mod ai;
pub mod system;