From 00a9df8e9725518489050e02bc12ef83c9feeb80 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Fri, 12 Jun 2026 06:12:28 +0000 Subject: [PATCH] fix(translation): azure family detection uses v1's truthiness base_model-or-model (critic-azure M1, verifier-azure S1) detection_model kept an empty-string base_model, so base_model: '' in a deployment's litellm_params disabled the o-series/gpt-5 family and response_format gates (fail-open: v2 served max_tokens where v1 routes AzureOpenAIO1Config and emits max_completion_tokens). One-token fix to 'deps.base_model or model'; the docstring's 'exactly like v1' claim is now true. Pinning corpus row uses base_model='' with the non-prefix family substring deployment name prod-o3-mini per verifier-azure (the shared openai prefix gate cannot catch it); row fails without the fix. --- litellm/translation/providers/azure/params.py | 5 ++++- .../test_differential_azure_request.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/litellm/translation/providers/azure/params.py b/litellm/translation/providers/azure/params.py index 6ed27c6ec9..8f76359ec0 100644 --- a/litellm/translation/providers/azure/params.py +++ b/litellm/translation/providers/azure/params.py @@ -30,7 +30,10 @@ _RESPONSE_FORMAT_SUPPORTED_MONTH = 8 def detection_model(model: str, deps: TranslationDeps) -> str: - return deps.base_model if deps.base_model is not None else model + # v1 is truthiness, not None-ness (azure.py:246 `base_model or model`): + # base_model: "" in a config must fall to the deployment name, or the + # family/response_format gates fail OPEN (verifier-azure S1). + return deps.base_model or model def unsupported_model_family(model: str, deps: TranslationDeps) -> str | None: diff --git a/tests/test_litellm/translation/test_differential_azure_request.py b/tests/test_litellm/translation/test_differential_azure_request.py index f4b6f4419e..e85c099885 100644 --- a/tests/test_litellm/translation/test_differential_azure_request.py +++ b/tests/test_litellm/translation/test_differential_azure_request.py @@ -285,6 +285,23 @@ EXPECTED_FALLBACKS = { "o1-mini", "AzureOpenAIO1Config", ), + "o_series_empty_base_model_falls_to_deployment": ( + # base_model: "" (a one-character YAML slip) must behave like v1's + # `base_model or model`: detection falls to the deployment name, + # whose NON-PREFIX o3 substring only azure's substring predicate + # catches (the shared openai prefix gate misses it). Proven divergent + # before the fix: v2 served max_tokens while v1 routed + # AzureOpenAIO1Config and emitted max_completion_tokens + # (verifier-azure S1). + { + "model": "prod-o3-mini", + "max_tokens": 100, + "messages": [{"role": "user", "content": "hi"}], + }, + DEFAULT_API_VERSION, + "", + "AzureOpenAIO1Config", + ), "gpt5_model": ( {"model": "gpt-5", "messages": [{"role": "user", "content": "hi"}]}, DEFAULT_API_VERSION,