fix(dashscope): route qwen3-tts-vc tts to dashscope handler and cover speech dispatch

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Mubashir Osmani 2026-07-18 22:24:42 +00:00
parent b5f3ea6e06
commit 35b328c46c
2 changed files with 30 additions and 1 deletions

View file

@ -7857,7 +7857,9 @@ def speech(
Coroutine[Any, Any, HttpxBinaryResponseContent],
None,
] = None
if custom_llm_provider == "openai" or custom_llm_provider in litellm.openai_compatible_providers:
if (
custom_llm_provider == "openai" or custom_llm_provider in litellm.openai_compatible_providers
) and custom_llm_provider != "dashscope":
if voice is None or not (isinstance(voice, str)):
raise litellm.BadRequestError(
message="'voice' is required to be passed as a string for OpenAI TTS",

View file

@ -102,3 +102,30 @@ def test_transform_response_raises_without_audio_url(config: DashScopeTextToSpee
config.transform_text_to_speech_response(
model="qwen3-tts-vc", raw_response=raw, logging_obj=MagicMock()
)
def test_speech_dispatches_to_dashscope_handler():
import litellm
fake_audio = MagicMock()
with patch.object(
litellm.main.base_llm_http_handler,
"text_to_speech_handler",
return_value=fake_audio,
) as mock_handler:
result = litellm.speech(
model="dashscope/qwen3-tts-vc",
input="hello world",
voice="my-cloned-voice",
api_key="sk-test",
)
assert result is fake_audio
mock_handler.assert_called_once()
kwargs = mock_handler.call_args.kwargs
assert kwargs["custom_llm_provider"] == "dashscope"
assert kwargs["model"] == "qwen3-tts-vc"
assert kwargs["voice"] == "my-cloned-voice"
assert isinstance(kwargs["text_to_speech_provider_config"], DashScopeTextToSpeechConfig)
assert kwargs["litellm_params"]["api_key"] == "sk-test"