From c0ee5da44476da0ba973e1ec6e7febb6eff94b15 Mon Sep 17 00:00:00 2001 From: Justas Brazauskas Date: Fri, 9 Jan 2026 10:03:45 +0200 Subject: [PATCH] Fix: Add thought_signatures to VertexGeminiConfig and test --- .../vertex_and_google_ai_studio_gemini.py | 1 + .../test_vertex_gemini_unbound_local_error.py | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/test_litellm/llms/vertex_ai/gemini/test_vertex_gemini_unbound_local_error.py 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 ba1788a217..b9f46b540a 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 @@ -1811,6 +1811,7 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig): functions: Optional[ChatCompletionToolCallFunctionChunk] = None thinking_blocks: Optional[List[ChatCompletionThinkingBlock]] = None reasoning_content: Optional[str] = None + thought_signatures: Optional[Any] = None for idx, candidate in enumerate(_candidates): if "content" not in candidate: diff --git a/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_gemini_unbound_local_error.py b/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_gemini_unbound_local_error.py new file mode 100644 index 0000000000..0a1ac7e2a5 --- /dev/null +++ b/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_gemini_unbound_local_error.py @@ -0,0 +1,38 @@ +import pytest +from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import VertexGeminiConfig +from litellm import ModelResponse + +def test_process_candidates_unbound_local_error_fix(): + # Setup + candidates = [ + { + "content": { + "role": "model" + # "parts" is missing intentionally to trigger the issue + }, + "finishReason": "STOP" + } + ] + model_response = ModelResponse() + + # Execution + try: + VertexGeminiConfig._process_candidates( + _candidates=candidates, + model_response=model_response, + standard_optional_params={}, + cumulative_tool_call_index=0 + ) + except UnboundLocalError as e: + pytest.fail(f"UnboundLocalError raised: {e}") + except Exception as e: + # Other exceptions might be okay if they are not UnboundLocalError, + # but ideally it should pass without error or raise a specific error if parts are required. + # However, the goal is to verify thought_signatures doesn't crash. + pass + + # Verify that we didn't crash with UnboundLocalError + +if __name__ == "__main__": + test_process_candidates_unbound_local_error_fix() + print("Test passed!")