fix(gemini): correct sibling positioning and snake_case naming of thought_signature
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled

This commit is contained in:
2026-03-05 17:04:36 +00:00
parent f7f6768333
commit 90a3f5d7f8

View File

@@ -57,6 +57,8 @@ struct GeminiPart {
function_response: Option<GeminiFunctionResponse>,
#[serde(skip_serializing_if = "Option::is_none")]
thought: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "thought_signature")]
thought_signature: Option<String>,
}
#[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<String>,
}
#[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<Vec<ToolCall>> {
let calls: Vec<ToolCall> = 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<Vec<ToolCallDelta>> {
let deltas: Vec<ToolCallDelta> = 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,