From f3e0db68594d3f7f990545b8a50ddda80fc33fb8 Mon Sep 17 00:00:00 2001 From: Baojiang Lee <101562714+libaojiang@users.noreply.github.com> Date: Mon, 31 Aug 2026 10:19:26 +0800 Subject: [PATCH] fix(vertex_ai): satisfy TRY300 gate and pin extractor scope The strict-rule gate hard-failed PR #38333 because the new `_is_valid_thought_signature` returned inside the ``try`` body (TRY300). Move the success return into a trailing statement so ruff sees the canonical shape and the budget stays base-neutral. Also add a regression test that pins what the ID-embedded fallback actually guarantees: it rejects wire-encoding damage, not semantic integrity. Documents Greptile's observation on the PR that a client normalizer preserving standard base64 characters can still produce a value Vertex will reject as an unauthenticated signature; callers that need semantic verification must compare against the provider-issued signature. Co-authored-by: Cursor --- .../litellm_core_utils/prompt_templates/factory.py | 2 +- .../gemini/test_thought_signature_in_tool_call_id.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/litellm/litellm_core_utils/prompt_templates/factory.py b/litellm/litellm_core_utils/prompt_templates/factory.py index 536ec175c16..2714c0f29c5 100644 --- a/litellm/litellm_core_utils/prompt_templates/factory.py +++ b/litellm/litellm_core_utils/prompt_templates/factory.py @@ -1177,9 +1177,9 @@ def _is_valid_thought_signature(signature: str) -> bool: try: padding = "=" * (-len(signature) % 4) base64.b64decode(signature + padding, validate=True) - return True except (binascii.Error, ValueError): return False + return True def _get_thought_signature_from_tool(tool: dict) -> str | None: diff --git a/tests/test_litellm/llms/vertex_ai/gemini/test_thought_signature_in_tool_call_id.py b/tests/test_litellm/llms/vertex_ai/gemini/test_thought_signature_in_tool_call_id.py index de053a11f9e..ef1002c8399 100644 --- a/tests/test_litellm/llms/vertex_ai/gemini/test_thought_signature_in_tool_call_id.py +++ b/tests/test_litellm/llms/vertex_ai/gemini/test_thought_signature_in_tool_call_id.py @@ -322,6 +322,18 @@ def test_is_valid_thought_signature_tolerates_missing_padding(): assert _is_valid_thought_signature(encoded) is True +def test_is_valid_thought_signature_scope_is_syntactic(): + """The extractor validates the wire encoding, not semantic integrity: a + client normalizer that keeps standard base64 characters produces a value + that still decodes even though Vertex will reject it as an unauthenticated + signature. Callers that need semantic verification have to compare against + the provider-issued signature; the ID-embedded fallback can only catch + encoding damage. Documented so future readers understand issue #37849's + guarantee is bounded.""" + decodable_but_wrong = base64.b64encode(b"not-the-real-signature").decode("ascii") + assert _is_valid_thought_signature(decodable_but_wrong) is True + + def test_get_thought_signature_drops_client_mangled_id_suffix(): """When the segment after ``__thought__`` isn't valid base64, the extractor must return ``None`` so the caller can either fall back to the dummy