Skip to main content

vv_agent/tools/base/
spec.rs

1use std::sync::Arc;
2
3use serde_json::{json, Value};
4
5use super::ToolContext;
6use crate::types::{ToolArguments, ToolExecutionResult};
7
8pub type ToolHandler =
9    Arc<dyn Fn(&mut ToolContext, &ToolArguments) -> ToolExecutionResult + Send + Sync + 'static>;
10pub type SubTaskRunner = Arc<
11    dyn Fn(crate::types::SubTaskRequest) -> crate::types::SubTaskOutcome + Send + Sync + 'static,
12>;
13
14#[derive(Clone)]
15pub struct ToolSpec {
16    pub name: String,
17    pub handler: ToolHandler,
18    pub description: String,
19    pub schema: Value,
20}
21
22impl ToolSpec {
23    pub fn new(
24        name: impl Into<String>,
25        description: impl Into<String>,
26        handler: ToolHandler,
27    ) -> Self {
28        let name = name.into();
29        let fallback_description = description.into();
30        let schema = crate::tools::schemas::schema_for(&name).unwrap_or_else(|| {
31            json!({
32                "type": "function",
33                "function": {
34                    "name": name,
35                    "description": fallback_description,
36                    "parameters": {"type": "object", "properties": {}, "required": []},
37                }
38            })
39        });
40        let description = schema["function"]["description"]
41            .as_str()
42            .unwrap_or(&fallback_description)
43            .to_string();
44        Self {
45            schema,
46            name,
47            handler,
48            description,
49        }
50    }
51}
52
53#[derive(Debug, Clone, thiserror::Error)]
54#[error("tool not found: {0}")]
55pub struct ToolNotFoundError(pub String);