diff --git a/src/providers/gemini.rs b/src/providers/gemini.rs index a2f1f78e..e59d14b5 100644 --- a/src/providers/gemini.rs +++ b/src/providers/gemini.rs @@ -57,6 +57,8 @@ struct GeminiPart { function_response: Option, #[serde(skip_serializing_if = "Option::is_none")] thought: Option, + #[serde(skip_serializing_if = "Option::is_none", rename = "thought_signature")] + thought_signature: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -70,8 +72,6 @@ struct GeminiInlineData { struct GeminiFunctionCall { name: String, args: Value, - #[serde(skip_serializing_if = "Option::is_none", rename = "thought_signature")] - thought_signature: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -231,6 +231,7 @@ impl GeminiProvider { function_call: None, function_response: None, thought: None, + thought_signature: None, }); } } @@ -270,6 +271,7 @@ impl GeminiProvider { response: response_value, }), thought: None, + thought_signature: None, }); } else if msg.role == "assistant" { // Assistant messages: handle text, thought (reasoning), and tool_calls @@ -282,6 +284,7 @@ impl GeminiProvider { function_call: None, function_response: None, thought: None, + thought_signature: None, }); } } @@ -296,6 +299,7 @@ impl GeminiProvider { function_call: None, function_response: None, thought: Some(reasoning.clone()), + thought_signature: None, }); } } @@ -320,10 +324,10 @@ impl GeminiProvider { function_call: Some(GeminiFunctionCall { name: tc.function.name.clone(), args, - thought_signature, }), function_response: None, thought: None, + thought_signature, }); } } @@ -339,6 +343,7 @@ impl GeminiProvider { function_call: None, function_response: None, thought: None, + thought_signature: None, }); } } @@ -357,6 +362,7 @@ impl GeminiProvider { function_call: None, function_response: None, thought: None, + thought_signature: None, }); } } @@ -392,6 +398,7 @@ impl GeminiProvider { function_call: None, function_response: None, thought: None, + thought_signature: None, }], }); } @@ -518,10 +525,11 @@ impl GeminiProvider { fn extract_tool_calls(parts: &[GeminiPart]) -> Option> { let calls: Vec = parts .iter() - .filter_map(|p| p.function_call.as_ref()) - .map(|fc| { - // CAPTURE: Use thought_signature from functionCall as the ID if available - let id = fc.thought_signature.clone().unwrap_or_else(|| format!("call_{}", Uuid::new_v4().simple())); + .filter(|p| p.function_call.is_some()) + .map(|p| { + let fc = p.function_call.as_ref().unwrap(); + // CAPTURE: Use thought_signature from Part as the ID if available + let id = p.thought_signature.clone().unwrap_or_else(|| format!("call_{}", Uuid::new_v4().simple())); ToolCall { id, @@ -541,11 +549,12 @@ impl GeminiProvider { fn extract_tool_call_deltas(parts: &[GeminiPart]) -> Option> { let deltas: Vec = parts .iter() - .filter_map(|p| p.function_call.as_ref()) .enumerate() - .map(|(i, fc)| { - // CAPTURE: Use thought_signature from functionCall as the ID if available - let id = fc.thought_signature.clone().unwrap_or_else(|| format!("call_{}", Uuid::new_v4().simple())); + .filter(|(_, p)| p.function_call.is_some()) + .map(|(i, p)| { + let fc = p.function_call.as_ref().unwrap(); + // CAPTURE: Use thought_signature from Part as the ID if available + let id = p.thought_signature.clone().unwrap_or_else(|| format!("call_{}", Uuid::new_v4().simple())); ToolCallDelta { index: i as u32,