Skip to main content

tiny_agent_rs/tools/
calculator.rs

1use super::Tool;
2use serde::{Deserialize, Serialize};
3use std::pin::Pin;
4
5/// Parameters for calculator operations
6#[derive(Debug, Serialize, Deserialize, schemars::JsonSchema)]
7pub struct CalculatorParams {
8    pub operation: Operation,
9    pub a: f64,
10    pub b: f64,
11}
12
13/// Supported calculator operations
14#[derive(Debug, Serialize, Deserialize, schemars::JsonSchema)]
15#[serde(rename_all = "lowercase")]
16pub enum Operation {
17    Add,
18    Subtract,
19    Multiply,
20    Divide,
21    Power,
22}
23
24/// A calculator tool for basic arithmetic operations
25#[derive(Debug)]
26pub struct CalculatorTool;
27
28impl Default for CalculatorTool {
29    fn default() -> Self {
30        Self::new()
31    }
32}
33
34impl CalculatorTool {
35    pub fn new() -> Self {
36        Self
37    }
38}
39
40impl Tool for CalculatorTool {
41    fn name(&self) -> &'static str {
42        "calculator"
43    }
44
45    fn description(&self) -> &'static str {
46        "Perform basic arithmetic operations (add, subtract, multiply, divide, power)"
47    }
48
49    fn parameters_schema(&self) -> serde_json::Value {
50        serde_json::json!({
51            "type": "object",
52            "properties": {
53                "operation": {
54                    "type": "string",
55                    "enum": ["add", "subtract", "multiply", "divide", "power"]
56                },
57                "a": {"type": "number"},
58                "b": {"type": "number"}
59            },
60            "required": ["operation", "a", "b"]
61        })
62    }
63
64    fn execute(
65        &self,
66        parameters: serde_json::Value,
67    ) -> Pin<
68        Box<
69            dyn std::future::Future<Output = Result<serde_json::Value, crate::AgentError>>
70                + Send
71                + '_,
72        >,
73    > {
74        Box::pin(async move {
75            let params: CalculatorParams = serde_json::from_value(parameters).map_err(|e| {
76                crate::AgentError::ToolExecution(format!("Invalid parameters: {}", e))
77            })?;
78
79            let result = match params.operation {
80                Operation::Add => params.a + params.b,
81                Operation::Subtract => params.a - params.b,
82                Operation::Multiply => params.a * params.b,
83                Operation::Divide => {
84                    if params.b == 0.0 {
85                        return Err(crate::AgentError::ToolExecution(
86                            "Division by zero is not allowed".to_string(),
87                        ));
88                    }
89                    params.a / params.b
90                }
91                Operation::Power => params.a.powf(params.b),
92            };
93
94            Ok(serde_json::json!({
95                "result": result,
96                "operation": format!("{:?} {} {}", params.operation, params.a, params.b)
97            }))
98        })
99    }
100}