thinking_advanced/
thinking_advanced.rs

1use futures_util::StreamExt;
2use gemini_rust::{
3    FunctionDeclaration, FunctionParameters, Gemini, PropertyDetails, ThinkingConfig,
4};
5use std::env;
6
7#[tokio::main]
8async fn main() -> Result<(), Box<dyn std::error::Error>> {
9    // Get API key from environment variable
10    let api_key = env::var("GEMINI_API_KEY").expect("GEMINI_API_KEY environment variable not set");
11
12    // Create client
13    let client = Gemini::with_model(api_key, "models/gemini-2.5-pro".to_string());
14
15    println!("=== Gemini 2.5 Thinking Advanced Example ===\n");
16
17    // Example 1: Streaming with thinking
18    println!("--- Example 1: Streaming with thinking ---");
19    let mut stream = client
20        .generate_content()
21        .with_system_prompt("You are a mathematics expert skilled at solving complex mathematical problems.")
22        .with_user_message("Solve this math problem: Find the sum of the first 50 prime numbers. Please explain your solution process in detail.")
23        .with_thinking_budget(2048)
24        .with_thoughts_included(true)
25        .execute_stream()
26        .await?;
27
28    println!("Streaming response:");
29    let mut thoughts_shown = false;
30    while let Some(chunk_result) = stream.next().await {
31        match chunk_result {
32            Ok(chunk) => {
33                // Check if there's thinking content
34                let thoughts = chunk.thoughts();
35                if !thoughts.is_empty() && !thoughts_shown {
36                    println!("\nThinking process:");
37                    for (i, thought) in thoughts.iter().enumerate() {
38                        println!("Thought {}: {}", i + 1, thought);
39                    }
40                    println!("\nAnswer:");
41                    thoughts_shown = true;
42                }
43
44                // Display general text content
45                print!("{}", chunk.text());
46                std::io::Write::flush(&mut std::io::stdout())?;
47            }
48            Err(e) => eprintln!("Streaming error: {}", e),
49        }
50    }
51    println!("\n");
52
53    // Example 2: Thinking combined with function calls
54    println!("--- Example 2: Thinking combined with function calls ---");
55
56    // Define a calculator function
57    let calculator = FunctionDeclaration::new(
58        "calculate",
59        "Perform basic mathematical calculations",
60        FunctionParameters::object()
61            .with_property(
62                "expression",
63                PropertyDetails::string(
64                    "The mathematical expression to calculate, e.g., '2 + 3 * 4'",
65                ),
66                true,
67            )
68            .with_property(
69                "operation_type",
70                PropertyDetails::enum_type("Type of calculation", ["arithmetic", "advanced"]),
71                false,
72            ),
73    );
74
75    let response = client
76        .generate_content()
77        .with_system_prompt("You are a mathematics assistant. When calculations are needed, use the provided calculator function.")
78        .with_user_message("Calculate the result of (15 + 25) * 3 - 8 and explain the calculation steps.")
79        .with_function(calculator)
80        .with_thinking_budget(1024)
81        .with_thoughts_included(true)
82        .execute()
83        .await?;
84
85    // Display thinking process
86    let thoughts = response.thoughts();
87    if !thoughts.is_empty() {
88        println!("Thinking process:");
89        for (i, thought) in thoughts.iter().enumerate() {
90            println!("Thought {}: {}\n", i + 1, thought);
91        }
92    }
93
94    // Check for function calls
95    let function_calls = response.function_calls();
96    if !function_calls.is_empty() {
97        println!("Function calls:");
98        for (i, call) in function_calls.iter().enumerate() {
99            println!("Call {}: {} Args: {}", i + 1, call.name, call.args);
100        }
101        println!();
102    }
103
104    println!("Answer: {}\n", response.text());
105
106    // Example 3: Complex reasoning task
107    println!("--- Example 3: Complex reasoning task ---");
108    let complex_response = client
109        .generate_content()
110        .with_system_prompt("You are a logical reasoning expert.")
111        .with_user_message(
112            "There are three people: Alice, Bob, and Carol, who live in red, green, and blue houses respectively.\
113            Given:\
114            1. The person in the red house owns a cat\
115            2. Bob does not live in the green house\
116            3. Carol owns a dog\
117            4. The green house is to the left of the red house\
118            5. Alice does not own a cat\
119            Please reason out which color house each person lives in and what pets they own.",
120        )
121        .with_thinking_config(
122            ThinkingConfig::new()
123                .with_thinking_budget(3072)
124                .with_thoughts_included(true),
125        )
126        .execute()
127        .await?;
128
129    // Display thinking process
130    let complex_thoughts = complex_response.thoughts();
131    if !complex_thoughts.is_empty() {
132        println!("Reasoning process:");
133        for (i, thought) in complex_thoughts.iter().enumerate() {
134            println!("Reasoning step {}: {}\n", i + 1, thought);
135        }
136    }
137
138    println!("Conclusion: {}\n", complex_response.text());
139
140    // Display token usage statistics
141    if let Some(usage) = &complex_response.usage_metadata {
142        println!("Token usage statistics:");
143        println!("  Prompt tokens: {}", usage.prompt_token_count);
144        println!(
145            "  Response tokens: {}",
146            usage.candidates_token_count.unwrap_or(0)
147        );
148        if let Some(thinking_tokens) = usage.thoughts_token_count {
149            println!("  Thinking tokens: {}", thinking_tokens);
150        }
151        println!("  Total tokens: {}", usage.total_token_count);
152    }
153
154    Ok(())
155}