use async_trait::async_trait;
use crate::error::AgentResult;
use crate::types::RunContext;
pub use adk_macros::tool_fn;
#[derive(Debug, Clone)]
pub struct ToolResult {
pub tool_name: String,
pub output: String,
}
#[async_trait]
pub trait Tool: Send + Sync {
fn name(&self) -> &str;
fn description(&self) -> &str;
fn parameters_schema(&self) -> serde_json::Value;
async fn execute(&self, context: &mut RunContext, params: &str) -> AgentResult<ToolResult>;
}
type FunctionToolFn = Box<dyn Fn(&mut RunContext, &str) -> AgentResult<ToolResult> + Send + Sync>;
pub struct FunctionTool {
name: String,
description: String,
parameters_schema: serde_json::Value,
function: FunctionToolFn,
}
impl FunctionTool {
pub fn new(
name: impl Into<String>,
description: impl Into<String>,
parameters_schema: serde_json::Value,
function: FunctionToolFn,
) -> Self {
Self {
name: name.into(),
description: description.into(),
parameters_schema,
function,
}
}
}
#[async_trait]
impl Tool for FunctionTool {
fn name(&self) -> &str {
&self.name
}
fn description(&self) -> &str {
&self.description
}
fn parameters_schema(&self) -> serde_json::Value {
self.parameters_schema.clone()
}
async fn execute(&self, context: &mut RunContext, params: &str) -> AgentResult<ToolResult> {
(self.function)(context, params)
}
}
#[macro_export]
macro_rules! function_tool {
($name:expr, $description:expr, $function:expr) => {
$crate::tool::FunctionTool::new(
$name,
$description,
serde_json::json!({
"type": "object",
"properties": {},
"required": []
}),
Box::new($function),
)
};
($name:expr, $description:expr, $schema:expr, $function:expr) => {
$crate::tool::FunctionTool::new(
$name,
$description,
$schema,
Box::new($function),
)
};
}