vv_agent/tools/base/
spec.rs1use 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 pub kind: ToolSpecKind,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum ToolSpecKind {
25 Function,
26 Agent,
27 BackgroundAgent,
28 Handoff,
29}
30
31impl ToolSpec {
32 pub fn new(
33 name: impl Into<String>,
34 description: impl Into<String>,
35 handler: ToolHandler,
36 ) -> Self {
37 let name = name.into();
38 let fallback_description = description.into();
39 let schema = crate::tools::schemas::schema_for(&name).unwrap_or_else(|| {
40 json!({
41 "type": "function",
42 "function": {
43 "name": name,
44 "description": fallback_description,
45 "parameters": {"type": "object", "properties": {}, "required": []},
46 }
47 })
48 });
49 let description = schema["function"]["description"]
50 .as_str()
51 .unwrap_or(&fallback_description)
52 .to_string();
53 Self {
54 schema,
55 name,
56 handler,
57 description,
58 kind: ToolSpecKind::Function,
59 }
60 }
61}
62
63#[derive(Debug, Clone, thiserror::Error)]
64#[error("tool not found: {0}")]
65pub struct ToolNotFoundError(pub String);