tools/
tools.rs

1use gemini_rust::{
2    FunctionDeclaration, Gemini, PropertyDetails, FunctionParameters,
3    FunctionCallingMode, Tool
4};
5use serde_json::json;
6use std::env;
7
8#[tokio::main]
9async fn main() -> Result<(), Box<dyn std::error::Error>> {
10    // Get API key from environment variable
11    let api_key = env::var("GEMINI_API_KEY")
12        .expect("GEMINI_API_KEY environment variable not set");
13
14    // Create client
15    let client = Gemini::new(api_key);
16
17    println!("--- Tools example with multiple functions ---");
18    
19    // Define a weather function
20    let get_weather = FunctionDeclaration::new(
21        "get_weather",
22        "Get the current weather for a location",
23        FunctionParameters::object()
24            .with_property(
25                "location",
26                PropertyDetails::string("The city and state, e.g., San Francisco, CA"),
27                true,
28            )
29            .with_property(
30                "unit",
31                PropertyDetails::enum_type(
32                    "The unit of temperature", 
33                    ["celsius", "fahrenheit"]
34                ),
35                false,
36            ),
37    );
38    
39    // Define a calculator function
40    let calculate = FunctionDeclaration::new(
41        "calculate",
42        "Perform a calculation",
43        FunctionParameters::object()
44            .with_property(
45                "operation",
46                PropertyDetails::enum_type(
47                    "The mathematical operation to perform",
48                    ["add", "subtract", "multiply", "divide"]
49                ),
50                true,
51            )
52            .with_property(
53                "a",
54                PropertyDetails::number("The first number"),
55                true,
56            )
57            .with_property(
58                "b",
59                PropertyDetails::number("The second number"),
60                true,
61            ),
62    );
63    
64    // Create a tool with multiple functions
65    let tool = Tool::with_functions(vec![get_weather, calculate]);
66
67    // Create a request with tool functions
68    let response = client
69        .generate_content()
70        .with_system_prompt("You are a helpful assistant that can check weather and perform calculations.")
71        .with_user_message("What's 42 times 12?")
72        .with_tool(tool)
73        .with_function_calling_mode(FunctionCallingMode::Any)
74        .execute()
75        .await?;
76
77    // Process function calls
78    if let Some(function_call) = response.function_calls().first() {
79        println!(
80            "Function call: {} with args: {}",
81            function_call.name,
82            function_call.args
83        );
84        
85        // Handle different function calls
86        match function_call.name.as_str() {
87            "calculate" => {
88                let operation: String = function_call.get("operation")?;
89                let a: f64 = function_call.get("a")?;
90                let b: f64 = function_call.get("b")?;
91                
92                println!("Calculation: {} {} {}", a, operation, b);
93                
94                let result = match operation.as_str() {
95                    "add" => a + b,
96                    "subtract" => a - b,
97                    "multiply" => a * b,
98                    "divide" => a / b,
99                    _ => panic!("Unknown operation"),
100                };
101                
102                let function_response = json!({
103                    "result": result,
104                }).to_string();
105                
106                // Continue the conversation with the function result
107                let final_response = client
108                    .generate_content()
109                    .with_system_prompt("You are a helpful assistant that can check weather and perform calculations.")
110                    .with_user_message("What's 42 times 12?")
111                    .with_function_response_str("calculate", function_response)?
112                    .execute()
113                    .await?;
114                
115                println!("Final response: {}", final_response.text());
116            },
117            "get_weather" => {
118                let location: String = function_call.get("location")?;
119                let unit = function_call.get::<String>("unit").unwrap_or_else(|_| String::from("celsius"));
120                
121                println!("Weather request for: {}, Unit: {}", location, unit);
122                
123                let weather_response = json!({
124                    "temperature": 22,
125                    "unit": unit,
126                    "condition": "sunny"
127                }).to_string();
128                
129                // Continue the conversation with the function result
130                let final_response = client
131                    .generate_content()
132                    .with_system_prompt("You are a helpful assistant that can check weather and perform calculations.")
133                    .with_user_message("What's 42 times 12?")
134                    .with_function_response_str("get_weather", weather_response)?
135                    .execute()
136                    .await?;
137                
138                println!("Final response: {}", final_response.text());
139            },
140            _ => println!("Unknown function"),
141        }
142    } else {
143        println!("No function calls in the response.");
144        println!("Response: {}", response.text());
145    }
146
147    Ok(())
148}