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