agent_diva_tooling/
base.rs1use async_trait::async_trait;
4use serde_json::Value;
5
6#[async_trait]
8pub trait Tool: Send + Sync {
9 fn name(&self) -> &str;
11
12 fn description(&self) -> &str;
14
15 fn parameters(&self) -> Value;
17
18 async fn execute(&self, args: Value) -> Result<String>;
20
21 fn validate_params(&self, params: &Value) -> Vec<String> {
23 let schema = self.parameters();
24
25 if !params.is_object() {
26 return vec!["Parameters must be an object".to_string()];
27 }
28
29 let mut errors = Vec::new();
30
31 if let Some(required) = schema.get("required").and_then(|r| r.as_array()) {
32 let params_obj = params.as_object().expect("validated object");
33 for field in required {
34 if let Some(field_name) = field.as_str() {
35 if !params_obj.contains_key(field_name) {
36 errors.push(format!("Missing required field: {}", field_name));
37 }
38 }
39 }
40 }
41
42 errors
43 }
44
45 fn to_schema(&self) -> Value {
47 serde_json::json!({
48 "type": "function",
49 "function": {
50 "name": self.name(),
51 "description": self.description(),
52 "parameters": self.parameters(),
53 }
54 })
55 }
56}
57
58#[derive(Debug, thiserror::Error)]
60pub enum ToolError {
61 #[error("Tool error: {0}")]
62 Error(String),
63
64 #[error("Invalid parameters: {0}")]
65 InvalidParams(String),
66
67 #[error("Invalid arguments: {0}")]
68 InvalidArguments(String),
69
70 #[error("Execution failed: {0}")]
71 ExecutionFailed(String),
72
73 #[error("IO error: {0}")]
74 Io(#[from] std::io::Error),
75}
76
77pub type Result<T> = std::result::Result<T, ToolError>;