fix: resolve raw language strings through Language enum for proper service conversion

Raw strings like "de-DE" passed as the language parameter to TTS/STT services
were bypassing the Language enum resolution logic, causing silent failures
(e.g. ElevenLabs expects "de" not "de-DE"). Now raw strings are first converted
to Language enums so they go through the same resolve_language() path, with a
warning logged for unrecognized strings.
This commit is contained in:
Mark Backman
2026-03-17 12:00:28 -04:00
parent fa345a510f
commit 4171a75f79
3 changed files with 303 additions and 2 deletions

View File

@@ -124,6 +124,18 @@ class STTService(AIService):
# Convert Language enum to service-specific format at init time.
# Runtime updates are handled by _update_settings(), but init-time
# settings bypass that path and need explicit conversion.
# Raw strings (e.g. "de-DE") are first converted to Language enums
# so they go through the same resolution logic.
if isinstance(self._settings.language, str) and not isinstance(
self._settings.language, Language
):
try:
self._settings.language = Language(self._settings.language)
except ValueError:
logger.warning(
f"Language string '{self._settings.language}' is not a recognized "
f"Language code. It will be passed to the service as-is."
)
if isinstance(self._settings.language, Language):
converted = self.language_to_service_language(self._settings.language)
if converted is not None:
@@ -294,7 +306,20 @@ class STTService(AIService):
Returns:
Dict mapping changed field names to their previous values.
"""
# Translate language *before* applying so the stored value is canonical
# Translate language *before* applying so the stored value is canonical.
# Raw strings are first converted to Language enums for proper resolution.
if (
is_given(delta.language)
and isinstance(delta.language, str)
and not isinstance(delta.language, Language)
):
try:
delta.language = Language(delta.language)
except ValueError:
logger.warning(
f"Language string '{delta.language}' is not a recognized "
f"Language code. It will be passed to the service as-is."
)
if is_given(delta.language) and isinstance(delta.language, Language):
converted = self.language_to_service_language(delta.language)
if converted is not None:

View File

@@ -248,6 +248,18 @@ class TTSService(AIService):
# Convert Language enum to service-specific format at init time.
# Runtime updates are handled by _update_settings(), but init-time
# settings bypass that path and need explicit conversion.
# Raw strings (e.g. "de-DE") are first converted to Language enums
# so they go through the same resolution logic.
if isinstance(self._settings.language, str) and not isinstance(
self._settings.language, Language
):
try:
self._settings.language = Language(self._settings.language)
except ValueError:
logger.warning(
f"Language string '{self._settings.language}' is not a recognized "
f"Language code. It will be passed to the service as-is."
)
if isinstance(self._settings.language, Language):
converted = self.language_to_service_language(self._settings.language)
if converted is not None:
@@ -610,7 +622,20 @@ class TTSService(AIService):
Returns:
Dict mapping changed field names to their previous values.
"""
# Translate language *before* applying so the stored value is canonical
# Translate language *before* applying so the stored value is canonical.
# Raw strings are first converted to Language enums for proper resolution.
if (
is_given(delta.language)
and isinstance(delta.language, str)
and not isinstance(delta.language, Language)
):
try:
delta.language = Language(delta.language)
except ValueError:
logger.warning(
f"Language string '{delta.language}' is not a recognized "
f"Language code. It will be passed to the service as-is."
)
if is_given(delta.language) and isinstance(delta.language, Language):
converted = self.language_to_service_language(delta.language)
if converted is not None: