#[derive(Clone)]
pub struct Tool {
name: String,
description: String,
input_schema: Value,
handler: ToolHandler,
}
impl Tool {
pub fn new<F, Fut>(
name: impl Into<String>,
description: impl Into<String>,
input_schema: Value,
handler: F,
) -> Self
where
F: Fn(Value) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<Value>> + Send + 'static,
{
let name = name.into();
let description = description.into();
let input_schema = convert_schema_to_openai(input_schema);
Self {
name,
description,
input_schema,
handler: Arc::new(move |args| Box::pin(handler(args))),
}
}
pub async fn execute(&self, arguments: Value) -> Result<Value> {
(self.handler)(arguments).await
}
pub fn to_openai_format(&self) -> Value {
serde_json::json!({
"type": "function",
"function": {
"name": self.name,
"description": self.description,
"parameters": self.input_schema
}
})
}
pub fn name(&self) -> &str {
&self.name
}
pub fn description(&self) -> &str {
&self.description
}
pub fn input_schema(&self) -> &Value {
&self.input_schema
}
}
impl std::fmt::Debug for Tool {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Tool")
.field("name", &self.name)
.field("description", &self.description)
.field("input_schema", &self.input_schema)
.finish()
}
}