From 66a99f8961e7fd063ea9853636e387b99862f0b8 Mon Sep 17 00:00:00 2001 From: Emerson Gomes Date: Wed, 23 Sep 2026 13:16:54 -0500 Subject: [PATCH] fix(vertex-ai): keep Gemini TTS routing with generic provider metadata --- litellm/utils.py | 18 +++++++++++++++++- .../test_gemini_3_1_flash_tts_metadata.py | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/litellm/utils.py b/litellm/utils.py index 1e86b87092b..db04a3e7bb3 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -759,9 +759,25 @@ def is_gemini_tts_model(model: str, custom_llm_provider: str | None = None) -> b ) provider_entry: Final = runtime_model_info.get("provider_specific_entry") - return runtime_model_info.get("litellm_provider") in ("gemini", "vertex_ai-language-models") and ( + if runtime_model_info.get("litellm_provider") in ("gemini", "vertex_ai-language-models") and ( runtime_model_info.get("mode") == "audio_speech" or (isinstance(provider_entry, dict) and provider_entry.get("gemini_tts") == 1) + ): + return True + if runtime_model_info.get("litellm_provider") != "vertex_ai" or runtime_model_info.get("mode") != "audio_speech": + return False + bundled_model_name: Final = model if model.startswith("vertex_ai/") else f"vertex_ai/{model}" + vertex_model_info: Final = _get_bundled_model_cost_map().get(bundled_model_name) + return ( + vertex_model_info is not None + and vertex_model_info.get("litellm_provider") == "vertex_ai-language-models" + and ( + vertex_model_info.get("mode") == "audio_speech" + or ( + isinstance(vertex_model_info.get("provider_specific_entry"), dict) + and vertex_model_info["provider_specific_entry"].get("gemini_tts") == 1 + ) + ) ) diff --git a/tests/test_litellm/test_gemini_3_1_flash_tts_metadata.py b/tests/test_litellm/test_gemini_3_1_flash_tts_metadata.py index 6420b5b9dc3..421c9538a41 100644 --- a/tests/test_litellm/test_gemini_3_1_flash_tts_metadata.py +++ b/tests/test_litellm/test_gemini_3_1_flash_tts_metadata.py @@ -1,5 +1,6 @@ import json from pathlib import Path +from typing import Final import pytest @@ -59,6 +60,20 @@ def test_gemini_tts_detection_uses_model_metadata(monkeypatch): assert is_gemini_tts_model(model) +def test_gemini_tts_detection_uses_bundled_metadata_when_runtime_provider_is_generic(monkeypatch): + model: Final = "gemini-3.1-flash-tts-preview" + monkeypatch.setitem( + litellm.model_cost, + f"vertex_ai/{model}", + {"litellm_provider": "vertex_ai", "mode": "audio_speech"}, + ) + litellm.get_model_info.cache_clear() + _invalidate_model_cost_lowercase_map() + + assert is_gemini_tts_model(model, custom_llm_provider="vertex_ai") + assert not is_gemini_tts_model("lyria-3-clip-preview", custom_llm_provider="vertex_ai") + + @pytest.mark.parametrize( "model", ["gemini-2.5-flash-preview-tts", "gemini-2.5-flash-tts", "gemini-2.5-pro-tts", "gemini-2.5-pro-preview-tts"],