Skip to main content

function_calling/
function_calling.rs

1use gemini_client_api::gemini::ask::Gemini;
2use gemini_client_api::gemini::types::request::Tool;
3use gemini_client_api::gemini::types::sessions::Session;
4use gemini_client_api::gemini::utils::{GeminiSchema, execute_function_calls, gemini_function};
5use std::env;
6use std::error::Error;
7
8/// This function will be made available to Gemini.
9/// The doc comments are used as descriptions for the tool.
10#[gemini_function]
11/// Returns the result of adding two numbers.
12fn add_numbers(
13    /// The first number.
14    a: f64,
15    /// The second number.
16    b: f64,
17) -> f64 {
18    println!("[Executing Tool] adding {} + {}", a, b);
19    a + b
20}
21
22#[gemini_function]
23/// Mock function to get the current temperature.
24fn get_temperature(location: String) -> String {
25    println!("[Executing Tool] getting temperature for {}", location);
26    format!("25°C in {}", location)
27}
28
29#[tokio::main]
30async fn main() -> Result<(), Box<dyn Error>> {
31    let mut session = Session::new(10);
32    let api_key = env::var("GEMINI_API_KEY").expect("GEMINI_API_KEY must be set");
33
34    // 1. Initialize Gemini and register tools
35    let ai =
36        Gemini::new(api_key, "gemini-2.5-flash", None).set_tools(vec![Tool::FunctionDeclarations(
37            vec![
38                add_numbers::gemini_schema(),
39                get_temperature::gemini_schema(),
40            ],
41        )]);
42
43    println!("--- Function Calling Example ---");
44    let prompt = "What is 123.45 plus 678.9, and what's the weather like in London?";
45    println!("User: {}\n", prompt);
46
47    // 2. Ask Gemini. It might reply with one or more function calls.
48    let mut response = ai.ask(session.ask(prompt)).await?;
49
50    // 3. Loop to handle potential multiple rounds of function calls
51    loop {
52        if response.get_chat().has_function_call() {
53            println!("Gemini requested function calls...");
54
55            // 4. Use the macro to execute all requested calls and update the session
56            // NOTE: session is not updated for Err() results. See below to handle it.
57            let results = execute_function_calls!(session, add_numbers, get_temperature);
58
59            for (idx, res) in results.iter().enumerate() {
60                if let Some(r) = res {
61                    println!("  Call #{} result: {:?}", idx, r);
62                }
63            }
64
65            // 5. Send the results back to Gemini to get the final natural language response
66            response = ai.ask(&mut session).await?;
67        } else {
68            // No more function calls, show the final response
69            println!("\nGemini: {}", response.get_chat().get_text_no_think(""));
70            break;
71        }
72    }
73
74    Ok(())
75}
76
77#[tokio::test]
78async fn function_calls_with_erros() {
79    use gemini_proc_macros::execute_function_calls_with_callback;
80    use serde_json::json;
81
82    let mut session = Session::new(10);
83    let api_key = env::var("GEMINI_API_KEY").expect("GEMINI_API_KEY must be set");
84
85    // 1. Initialize Gemini and register tools
86    let ai =
87        Gemini::new(api_key, "gemini-2.5-flash", None).set_tools(vec![Tool::FunctionDeclarations(
88            vec![
89                add_numbers::gemini_schema(),
90                get_temperature::gemini_schema(),
91            ],
92        )]);
93
94    println!("--- Function Calling Example ---");
95    let prompt = "What is 123.45 plus 678.9, and what's the weather like in London?";
96    println!("User: {}\n", prompt);
97
98    // 2. Ask Gemini. It might reply with one or more function calls.
99    let mut response = ai.ask(session.ask(prompt)).await.unwrap();
100
101    // 3. Loop to handle potential multiple rounds of function calls
102    loop {
103        if response.get_chat().has_function_call() {
104            println!("Gemini requested function calls...");
105
106            // 4. Use the macro to execute all requested calls and update the session
107            // NOTE: session is updated with callback's value
108            let results = execute_function_calls_with_callback!(
109                session,
110                |result| {
111                    match result {
112                        Ok(value) => value,
113                        Err(e) => json!({"Error":e}),
114                    }
115                },
116                add_numbers,
117                get_temperature
118            );
119
120            for (idx, res) in results.iter().enumerate() {
121                if let Some(r) = res {
122                    println!("  Call #{} result: {:?}", idx, r);
123                }
124            }
125
126            // 5. Send the results back to Gemini to get the final natural language response
127            response = ai.ask(&mut session).await.unwrap();
128        } else {
129            // No more function calls, show the final response
130            println!("\nGemini: {}", response.get_chat().get_text_no_think(""));
131            break;
132        }
133    }
134}