Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,7 @@ def _map_audio_params(self, value: dict) -> dict:
{
"voice": "alloy",
"format": "mp3",
"language_code": "en-US",
}

Expected output:
Expand All @@ -1119,7 +1120,8 @@ def _map_audio_params(self, value: dict) -> dict:
prebuiltVoiceConfig: {
voiceName: "alloy",
}
}
},
languageCode: "en-US",
}
"""
from litellm.types.llms.vertex_ai import (
Expand All @@ -1145,6 +1147,9 @@ def _map_audio_params(self, value: dict) -> dict:
voice_config: VoiceConfig = {"prebuiltVoiceConfig": prebuilt_voice_config}
speech_config["voiceConfig"] = voice_config

if "language_code" in value:
speech_config["languageCode"] = value["language_code"]

return cast(dict, speech_config)

def map_openai_params( # noqa: PLR0915
Expand Down
1 change: 1 addition & 0 deletions litellm/types/llms/vertex_ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ class VoiceConfig(TypedDict):

class SpeechConfig(TypedDict, total=False):
voiceConfig: VoiceConfig
languageCode: str


class GenerationConfig(TypedDict, total=False):
Expand Down
92 changes: 92 additions & 0 deletions tests/test_litellm/llms/gemini/test_gemini_tts.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,46 @@ def test_gemini_tts_audio_parameter_mapping(self):
assert "responseModalities" in result
assert "AUDIO" in result["responseModalities"]

def test_gemini_tts_audio_parameter_mapping_with_language_code(self):
config = GoogleAIStudioGeminiConfig()

non_default_params = {
"audio": {"voice": "Kore", "format": "pcm16", "language_code": "en-US"}
}
optional_params = {}

result = config.map_openai_params(
non_default_params=non_default_params,
optional_params=optional_params,
model="gemini-2.5-flash-preview-tts",
drop_params=False,
)

assert "speechConfig" in result
assert result["speechConfig"]["languageCode"] == "en-US"
assert (
result["speechConfig"]["voiceConfig"]["prebuiltVoiceConfig"]["voiceName"]
== "Kore"
)

def test_map_audio_params_language_code(self):
config = GoogleAIStudioGeminiConfig()

result = config._map_audio_params(
{"voice": "Kore", "format": "pcm16", "language_code": "de-DE"}
)

assert result["languageCode"] == "de-DE"
assert result["voiceConfig"]["prebuiltVoiceConfig"]["voiceName"] == "Kore"

def test_map_audio_params_no_language_code(self):
config = GoogleAIStudioGeminiConfig()

result = config._map_audio_params({"voice": "Kore", "format": "pcm16"})

assert "languageCode" not in result
assert result["voiceConfig"]["prebuiltVoiceConfig"]["voiceName"] == "Kore"

def test_gemini_tts_audio_parameter_with_existing_modalities(self):
"""Test audio parameter mapping when modalities already exist"""
config = GoogleAIStudioGeminiConfig()
Expand Down Expand Up @@ -328,5 +368,57 @@ def test_speechconfig_end_to_end_mapping(self, model, custom_llm_provider):
assert "AUDIO" in generation_config["responseModalities"]


@pytest.mark.parametrize(
"model,custom_llm_provider",
[
("gemini-2.5-flash-tts", "vertex_ai"),
("gemini-2.5-flash-tts", "gemini"),
("gemini-2.5-flash-preview-tts", "vertex_ai"),
],
)
def test_language_code_end_to_end_mapping(self, model, custom_llm_provider):
from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import (
VertexGeminiConfig,
)
from litellm.llms.vertex_ai.gemini.transformation import (
_transform_request_body,
)

config = VertexGeminiConfig()

non_default_params = {
"audio": {"voice": "Puck", "format": "pcm16", "language_code": "pt-BR"}
}
optional_params = {}

mapped_params = config.map_openai_params(
non_default_params=non_default_params,
optional_params=optional_params,
model=model,
drop_params=False,
)

assert mapped_params["speechConfig"]["languageCode"] == "pt-BR"

request_body = _transform_request_body(
messages=[{"role": "user", "content": "Hello world"}],
model=model,
optional_params=mapped_params,
custom_llm_provider=custom_llm_provider,
litellm_params={},
cached_content=None,
)

generation_config = request_body["generationConfig"]
assert generation_config["speechConfig"]["languageCode"] == "pt-BR"
assert (
generation_config["speechConfig"]["voiceConfig"]["prebuiltVoiceConfig"][
"voiceName"
]
== "Puck"
)
assert "AUDIO" in generation_config["responseModalities"]


if __name__ == "__main__":
pytest.main([__file__])
Loading