Skip to main content

tiny_agent_rs/tools/
weather.rs

1use super::Tool;
2use serde::{Deserialize, Serialize};
3use std::pin::Pin;
4
5/// Parameters for weather queries
6#[derive(Debug, Serialize, Deserialize, schemars::JsonSchema)]
7pub struct WeatherParams {
8    pub location: String,
9    pub units: Option<TemperatureUnits>,
10}
11
12/// Temperature units
13#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
14#[serde(rename_all = "lowercase")]
15pub enum TemperatureUnits {
16    Celsius,
17    Fahrenheit,
18    Kelvin,
19}
20
21/// Weather information response
22#[derive(Debug, Serialize, Deserialize)]
23pub struct WeatherInfo {
24    pub location: String,
25    pub temperature: f64,
26    pub condition: String,
27    pub humidity: f64,
28    pub units: String,
29}
30
31/// A mock weather tool for demonstration
32#[derive(Debug)]
33pub struct WeatherTool;
34
35impl Default for WeatherTool {
36    fn default() -> Self {
37        Self::new()
38    }
39}
40
41impl WeatherTool {
42    pub fn new() -> Self {
43        Self
44    }
45}
46
47impl Tool for WeatherTool {
48    fn name(&self) -> &'static str {
49        "weather"
50    }
51
52    fn description(&self) -> &'static str {
53        "Get current weather information for a location (mock implementation)"
54    }
55
56    fn parameters_schema(&self) -> serde_json::Value {
57        serde_json::json!({
58            "type": "object",
59            "properties": {
60                "location": {"type": "string"},
61                "units": {
62                    "type": "string",
63                    "enum": ["celsius", "fahrenheit", "kelvin"]
64                }
65            },
66            "required": ["location"]
67        })
68    }
69
70    fn execute(
71        &self,
72        parameters: serde_json::Value,
73    ) -> Pin<
74        Box<
75            dyn std::future::Future<Output = Result<serde_json::Value, crate::AgentError>>
76                + Send
77                + '_,
78        >,
79    > {
80        Box::pin(async move {
81            let params: WeatherParams = serde_json::from_value(parameters).map_err(|e| {
82                crate::AgentError::ToolExecution(format!("Invalid parameters: {}", e))
83            })?;
84
85            // Mock weather data - in a real implementation, you'd call a weather API
86            let temperature = match params.units.clone().unwrap_or(TemperatureUnits::Celsius) {
87                TemperatureUnits::Celsius => 22.5,
88                TemperatureUnits::Fahrenheit => 72.5,
89                TemperatureUnits::Kelvin => 295.65,
90            };
91
92            let weather_info = WeatherInfo {
93                location: params.location,
94                temperature,
95                condition: "Partly cloudy".to_string(),
96                humidity: 65.0,
97                units: match params.units.unwrap_or(TemperatureUnits::Celsius) {
98                    TemperatureUnits::Celsius => "°C".to_string(),
99                    TemperatureUnits::Fahrenheit => "°F".to_string(),
100                    TemperatureUnits::Kelvin => "K".to_string(),
101                },
102            };
103
104            serde_json::to_value(weather_info).map_err(|e| {
105                crate::AgentError::ToolExecution(format!("Failed to serialize result: {}", e))
106            })
107        })
108    }
109}