From d8418fff08f1a3f59dbe78318ac9d214fe59a8a5 Mon Sep 17 00:00:00 2001 From: StatPan Date: Fri, 1 May 2026 21:11:57 +0900 Subject: [PATCH] fix(gemini): avoid duplicate model route for full api_base --- litellm/llms/vertex_ai/vertex_llm_base.py | 9 ++++- .../llms/vertex_ai/test_vertex_llm_base.py | 39 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/litellm/llms/vertex_ai/vertex_llm_base.py b/litellm/llms/vertex_ai/vertex_llm_base.py index 6f687dae7e8..80f1a96f854 100644 --- a/litellm/llms/vertex_ai/vertex_llm_base.py +++ b/litellm/llms/vertex_ai/vertex_llm_base.py @@ -412,7 +412,14 @@ class VertexBase: raise ValueError( "Model parameter is required for Gemini custom API base URLs" ) - url = "{}/models/{}:{}".format(api_base, model, endpoint) + if api_base.endswith(f"/models/{model}:{endpoint}"): + url = api_base + elif api_base.endswith(f"/models/{model}"): + url = f"{api_base}:{endpoint}" + else: + url = "{}/models/{}:{}".format( + api_base.rstrip("/"), model, endpoint + ) if gemini_api_key is None: raise ValueError( "Missing Gemini API key. Set the GEMINI_API_KEY or GOOGLE_API_KEY environment variable." diff --git a/tests/test_litellm/llms/vertex_ai/test_vertex_llm_base.py b/tests/test_litellm/llms/vertex_ai/test_vertex_llm_base.py index 88aac07a0c9..88212ded130 100644 --- a/tests/test_litellm/llms/vertex_ai/test_vertex_llm_base.py +++ b/tests/test_litellm/llms/vertex_ai/test_vertex_llm_base.py @@ -891,6 +891,45 @@ class TestVertexBase: result_url == expected_url ), f"Expected {expected_url}, got {result_url} for model {model}" + @pytest.mark.parametrize( + "api_base, endpoint, expected_url", + [ + ( + "https://proxy.example.com/generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent", + "generateContent", + "https://proxy.example.com/generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent", + ), + ( + "https://proxy.example.com/generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite", + "generateContent", + "https://proxy.example.com/generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent", + ), + ( + "https://proxy.example.com/generativelanguage.googleapis.com/v1beta/", + "generateContent", + "https://proxy.example.com/generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent", + ), + ], + ) + def test_check_custom_proxy_gemini_prebuilt_route_handling( + self, api_base, endpoint, expected_url + ): + """Test that Gemini custom api_base values are not double-appended when they already include model routing.""" + vertex_base = VertexBase() + + _, result_url = vertex_base._check_custom_proxy( + api_base=api_base, + custom_llm_provider="gemini", + gemini_api_key="test-api-key", + endpoint=endpoint, + stream=False, + auth_header=None, + url="https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent", + model="gemini-2.5-flash-lite", + ) + + assert result_url == expected_url + def test_check_custom_proxy_streaming_parameter(self): """Test that streaming parameter correctly adds ?alt=sse to URLs""" vertex_base = VertexBase()