fix(azure_ai): redirect a gpt-5 capability lookup only when the map has a foundry row

gpt-6-astra is the only gpt-5-family name with an azure_ai row. Prefixing the rest
cost them every effort flag, since get_llm_provider sends an azure_ai name down the
azure provider when a global AZURE_AI_API_BASE points at an openai.azure.com host and
azure/<model> is not a key either, which turned temperature, top_p and logprobs on
azure_ai/gpt-5.1-chat-latest from accepted into an UnsupportedParamsError.
This commit is contained in:
mateo-berri 2026-09-05 22:31:33 -07:00
parent e79f3ec520
commit fa2b64878b
2 changed files with 36 additions and 1 deletions

View file

@ -46,7 +46,19 @@ NON_OPENAI_SPEC_MESSAGE_FIELDS: Final = (
class AzureAIGPT5Config(OpenAIGPT5Config):
@classmethod
def _model_map_lookup_name(cls, model: str) -> str:
return model if model.startswith("azure_ai/") else f"azure_ai/{model}"
"""Normalise a Foundry routing name to its cost-map key, when the map has one.
A Foundry deployment and its OpenAI-hosted namesake are different products with
different capabilities, so ``azure_ai/<model>`` is the entry to read whenever the map
carries it. Most gpt-5-family names have no ``azure_ai/`` row, though, and prefixing
those anyway costs them every flag: ``get_llm_provider`` re-resolves an ``azure_ai/``
name to the azure provider when a global AZURE_AI_API_BASE points at an
openai.azure.com host, ``azure/<model>`` is not a key either, so the lookup lands
nowhere and every effort answer degrades to False. A missing key defers to the base
resolver instead.
"""
prefixed: Final = model if model.startswith("azure_ai/") else f"azure_ai/{model}"
return prefixed if prefixed in litellm.model_cost else super()._model_map_lookup_name(model)
azureAIGPT5Config: Final = AzureAIGPT5Config()

View file

@ -157,6 +157,29 @@ def test_foundry_gpt_6_astra_keeps_sampling_params_when_reasoning_effort_is_none
assert optional_params == {"reasoning_effort": "none", "temperature": 0.2, "top_p": 0.9}
def test_a_gpt_5_name_without_a_foundry_row_keeps_reading_its_own_entry(
monkeypatch: pytest.MonkeyPatch, _local_model_cost_map
):
"""gpt-6-astra is the only gpt-5-family name with an azure_ai/ row. Reading an azure_ai/ key for
the rest finds nothing, and an openai.azure.com base sends that name down the azure provider,
which has no key for it either, so every effort answer would silently fall back to false and
take temperature, top_p and logprobs down with it."""
monkeypatch.setenv("AZURE_AI_API_BASE", "https://example-resource.openai.azure.com")
monkeypatch.setenv("AZURE_AI_API_KEY", "placeholder")
optional_params = litellm.utils.get_optional_params(
model="gpt-5.1-chat-latest",
custom_llm_provider="azure_ai",
temperature=0.2,
top_p=0.9,
logprobs=True,
)
assert optional_params["temperature"] == 0.2
assert optional_params["top_p"] == 0.9
assert optional_params["logprobs"] is True
def test_azure_ai_grok_stop_parameter_handling():
"""
Test that Grok models properly handle stop parameter filtering in Azure AI Studio.