google_search_with_functions/
google_search_with_functions.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("GOOGLE_API_KEY")
12        .expect("GOOGLE_API_KEY environment variable not set");
13
14    // Create client
15    let client = Gemini::new(api_key);
16
17    println!("--- Google Search with Function Calling example ---");
18    
19    // Define a calculator function
20    let calculate = FunctionDeclaration::new(
21        "calculate",
22        "Perform a calculation",
23        FunctionParameters::object()
24            .with_property(
25                "operation",
26                PropertyDetails::enum_type(
27                    "The mathematical operation to perform",
28                    ["add", "subtract", "multiply", "divide"]
29                ),
30                true,
31            )
32            .with_property(
33                "a",
34                PropertyDetails::number("The first number"),
35                true,
36            )
37            .with_property(
38                "b",
39                PropertyDetails::number("The second number"),
40                true,
41            ),
42    );
43    
44    // Create function tool
45    let function_tool = Tool::new(calculate);
46    
47    // Create Google Search tool
48    let google_search_tool = Tool::google_search();
49    
50    // Create a request with both tools
51    let response = client
52        .generate_content()
53        .with_user_message("What is the current Google stock price multiplied by 2?")
54        .with_tool(google_search_tool)
55        .with_tool(function_tool)
56        .with_function_calling_mode(FunctionCallingMode::Any)
57        .execute()
58        .await?;
59    
60    // Check if there are function calls
61    if let Some(function_call) = response.function_calls().first() {
62        println!(
63            "Function call: {} with args: {}",
64            function_call.name,
65            function_call.args
66        );
67        
68        // Handle the calculate function
69        if function_call.name == "calculate" {
70            let operation: String = function_call.get("operation")?;
71            let a: f64 = function_call.get("a")?;
72            let b: f64 = function_call.get("b")?;
73            
74            println!("Calculation: {} {} {}", a, operation, b);
75            
76            let result = match operation.as_str() {
77                "add" => a + b,
78                "subtract" => a - b,
79                "multiply" => a * b,
80                "divide" => a / b,
81                _ => panic!("Unknown operation"),
82            };
83            
84            let function_response = json!({
85                "result": result,
86            }).to_string();
87            
88            // Continue the conversation with the function result
89            let final_response = client
90                .generate_content()
91                .with_user_message("What is the current Google stock price multiplied by 2?")
92                .with_function_response_str("calculate", function_response)?
93                .execute()
94                .await?;
95            
96            println!("Final response: {}", final_response.text());
97        } else {
98            println!("Unknown function call: {}", function_call.name);
99        }
100    } else {
101        println!("No function calls in the response.");
102        println!("Direct response: {}", response.text());
103    }
104
105    Ok(())
106}