pub mod builtin;
use async_trait::async_trait;
use serde_json::Value;
use crate::error::Result;
use crate::llm::types::ToolDef;
#[derive(Debug, Clone)]
pub struct ToolResult {
pub content: String,
}
impl ToolResult {
pub fn ok(content: impl Into<String>) -> Self {
Self {
content: content.into(),
}
}
pub fn error(msg: impl Into<String>) -> Self {
Self {
content: format!("Error: {}", msg.into()),
}
}
}
#[async_trait]
pub trait Tool: Send + Sync {
fn name(&self) -> &str;
fn needs_confirmation(&self) -> bool {
false
}
fn def(&self) -> ToolDef;
async fn call(&self, args: Value) -> Result<ToolResult>;
}
pub struct ToolRegistry {
tools: Vec<Box<dyn Tool>>,
}
impl ToolRegistry {
pub fn new() -> Self {
Self { tools: Vec::new() }
}
pub fn register(&mut self, tool: Box<dyn Tool>) {
self.tools.push(tool);
}
pub fn defs(&self) -> Vec<ToolDef> {
self.tools.iter().map(|t| t.def()).collect()
}
pub fn find(&self, name: &str) -> Option<&dyn Tool> {
self.tools
.iter()
.find(|t| t.name() == name)
.map(|t| t.as_ref())
}
}
impl Default for ToolRegistry {
fn default() -> Self {
Self::new()
}
}