From dd86a5d56faecf0bf64890d8fcf6f33436f670f2 Mon Sep 17 00:00:00 2001 From: bahtya Date: Thu, 9 Apr 2026 00:48:34 +0800 Subject: [PATCH] fix(gemini): restrict thoughtSignature fallback to thought parts only Address P1 review: _all_signatures was collecting signatures from ALL parts including functionCall parts, which could bleed the first function call's signature into parallel function calls. Now only collect signatures from parts where thought=true, preventing cross-contamination between parallel function calls. Signed-off-by: bahtya --- .../gemini/vertex_and_google_ai_studio_gemini.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py b/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py index 3088da30994..b49cb58decc 100644 --- a/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py +++ b/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py @@ -1585,12 +1585,14 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig): ]: function: Optional[ChatCompletionToolCallFunctionChunk] = None _tools: List[ChatCompletionToolCallChunk] = [] - # Collect all thoughtSignature values from any part (Gemini may place - # the signature on a separate thought part, not the functionCall part) - _all_signatures = [ + # Collect thoughtSignature values only from thought parts (thought: true). + # Gemini may place thoughtSignature on a separate thought part rather than + # the functionCall part. We exclude functionCall parts to avoid bleeding + # signatures across parallel function calls. + _thought_signatures = [ p.get("thoughtSignature") for p in parts - if p.get("thoughtSignature") + if p.get("thought") and p.get("thoughtSignature") ] for part in parts: if "functionCall" in part: @@ -1603,7 +1605,7 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig): # Extract thought signature: prefer this part's own, fallback to # a signature from a sibling thought part thought_signature = part.get("thoughtSignature") or ( - _all_signatures[0] if _all_signatures else None + _thought_signatures[0] if _thought_signatures else None ) if is_function_call is True: