custom_tool/
custom_tool.rs

1//! # Example: Custom Tool
2//!
3//! This example demonstrates how to create and use a custom tool with an agent.
4//! We define a `WeatherTool` that can "fetch" the weather for a given location.
5
6use async_trait::async_trait;
7use helios_engine::{Agent, Config, Tool, ToolParameter, ToolResult};
8use serde_json::Value;
9use std::collections::HashMap;
10
11/// A custom tool to get the weather for a location.
12struct WeatherTool;
13
14#[async_trait]
15impl Tool for WeatherTool {
16    /// The name of the tool.
17    fn name(&self) -> &str {
18        "get_weather"
19    }
20
21    /// A description of what the tool does.
22    fn description(&self) -> &str {
23        "Get the current weather for a location"
24    }
25
26    /// The parameters the tool accepts.
27    fn parameters(&self) -> HashMap<String, ToolParameter> {
28        let mut params = HashMap::new();
29        params.insert(
30            "location".to_string(),
31            ToolParameter {
32                param_type: "string".to_string(),
33                description: "The city and state, e.g. San Francisco, CA".to_string(),
34                required: Some(true),
35            },
36        );
37        params.insert(
38            "unit".to_string(),
39            ToolParameter {
40                param_type: "string".to_string(),
41                description: "Temperature unit: 'celsius' or 'fahrenheit'".to_string(),
42                required: Some(false),
43            },
44        );
45        params
46    }
47
48    /// Executes the tool with the given arguments.
49    async fn execute(&self, args: Value) -> helios_engine::Result<ToolResult> {
50        let location = args
51            .get("location")
52            .and_then(|v| v.as_str())
53            .unwrap_or("Unknown");
54
55        let unit = args
56            .get("unit")
57            .and_then(|v| v.as_str())
58            .unwrap_or("fahrenheit");
59
60        // In a real implementation, you would call a weather API here.
61        let temp = if unit == "celsius" { "22" } else { "72" };
62        let weather = format!(
63            "The weather in {} is sunny with a temperature of {}°{}",
64            location,
65            temp,
66            if unit == "celsius" { "C" } else { "F" }
67        );
68
69        Ok(ToolResult::success(weather))
70    }
71}
72
73#[tokio::main]
74async fn main() -> helios_engine::Result<()> {
75    // Load configuration from `config.toml`.
76    let config = Config::from_file("config.toml")?;
77
78    // Create an agent named "WeatherAgent" and equip it with the `WeatherTool`.
79    let mut agent = Agent::builder("WeatherAgent")
80        .config(config)
81        .system_prompt("You are a helpful weather assistant. Use the weather tool to answer questions about weather.")
82        .tool(Box::new(WeatherTool))
83        .build()
84        .await?;
85
86    // --- Ask the agent about the weather ---
87    let response = agent.chat("What's the weather like in New York?").await?;
88    println!("Agent: {}\n", response);
89
90    // --- Ask again, but with a different unit ---
91    let response = agent.chat("How about in London, but in celsius?").await?;
92    println!("Agent: {}\n", response);
93
94    Ok(())
95}