From cf33d3f47cb721b1b9534c8d1f5b1618fe418787 Mon Sep 17 00:00:00 2001 From: Dan Lemon Date: Thu, 10 Sep 2026 21:53:51 +0200 Subject: [PATCH] fix(soniox): keep bracket-prefixed free-form context and move types under llms Free-form context such as "[inaudible] consultation" is valid Soniox input, so a string that fails JSON parsing is now forwarded unchanged instead of returning a 400. The Soniox request types live next to the provider code. --- litellm/llms/soniox/audio_transcription/transformation.py | 6 ++---- litellm/{types/llms/soniox.py => llms/soniox/types.py} | 0 .../test_soniox_audio_transcription_transformation.py | 8 +++----- 3 files changed, 5 insertions(+), 9 deletions(-) rename litellm/{types/llms/soniox.py => llms/soniox/types.py} (100%) diff --git a/litellm/llms/soniox/audio_transcription/transformation.py b/litellm/llms/soniox/audio_transcription/transformation.py index f5a2f7d67cc..9f224944073 100644 --- a/litellm/llms/soniox/audio_transcription/transformation.py +++ b/litellm/llms/soniox/audio_transcription/transformation.py @@ -81,10 +81,8 @@ def _decode_form_value(key: str, value: object) -> object: if key in SONIOX_JSON_PARAMS and value.lstrip()[:1] in ("{", "["): try: return _JSON_CONTAINER.validate_json(value) - except ValidationError as exc: - raise SonioxException( - message=f"`{key}` is not valid JSON: {exc.errors()[0]['msg']}", status_code=400, headers=None - ) + except ValidationError: + return value if key == "language_hints": return tuple(hint.strip() for hint in value.split(",") if hint.strip()) return value diff --git a/litellm/types/llms/soniox.py b/litellm/llms/soniox/types.py similarity index 100% rename from litellm/types/llms/soniox.py rename to litellm/llms/soniox/types.py diff --git a/tests/test_litellm/llms/soniox/audio_transcription/test_soniox_audio_transcription_transformation.py b/tests/test_litellm/llms/soniox/audio_transcription/test_soniox_audio_transcription_transformation.py index 64b6fa8a018..73cdd806855 100644 --- a/tests/test_litellm/llms/soniox/audio_transcription/test_soniox_audio_transcription_transformation.py +++ b/tests/test_litellm/llms/soniox/audio_transcription/test_soniox_audio_transcription_transformation.py @@ -707,11 +707,9 @@ class TestDecodeSonioxFormParams: assert result["enable_speaker_diarization"] is True assert result["language_hints"] == ["en", "es"] - def test_should_raise_400_on_malformed_json_context(self): - with pytest.raises(SonioxException) as exc_info: - decode_soniox_form_params({"context": '{"terms": ["Celebrex"'}) - assert exc_info.value.status_code == 400 - assert "context" in str(exc_info.value) + @pytest.mark.parametrize("raw", ["[inaudible] consultation", "{unbalanced", '{"terms": ["Celebrex"']) + def test_should_keep_bracket_prefixed_free_form_context_as_string(self, raw: str): + assert decode_soniox_form_params({"context": raw})["context"] == raw def test_should_decode_json_string_translation(self): result = decode_soniox_form_params({"translation": '{"type": "one_way", "target_language": "es"}'})