fix(azure_ai): only reclassify as azure when api_base is a classic Azure OpenAI endpoint

This commit is contained in:
mateo-berri 2026-08-31 10:00:55 -07:00
parent d6cce13308
commit 1072de94de
3 changed files with 56 additions and 15 deletions

View file

@ -207,20 +207,22 @@ class AzureAIStudioConfig(OpenAIConfig):
message["content"] = texts
return stripped_messages
def _is_azure_openai_model(self, model: str, api_base: str | None) -> bool:
try:
if "/" in model:
model = model.split("/", 1)[1]
if (
model in litellm.open_ai_chat_completion_models
or model in litellm.open_ai_text_completion_models
or model in litellm.open_ai_embedding_models
):
return True
except Exception:
def _is_foundry_model_inference_base(self, api_base: str) -> bool:
parsed: Final = urlparse(api_base)
host: Final = parsed.hostname
if host is None or not host.endswith(".services.ai.azure.com"):
return False
return False
return "/openai/deployments" not in parsed.path
def _is_azure_openai_model(self, model: str, api_base: str | None) -> bool:
if api_base is None or self._is_foundry_model_inference_base(api_base):
return False
stripped_model: Final = model.split("/", 1)[1] if "/" in model else model
return (
stripped_model in litellm.open_ai_chat_completion_models
or stripped_model in litellm.open_ai_text_completion_models
or stripped_model in litellm.open_ai_embedding_models
)
def _get_openai_compatible_provider_info(
self,

View file

@ -31,6 +31,46 @@ async def test_get_openai_compatible_provider_info():
assert custom_llm_provider == "azure"
@pytest.mark.parametrize(
"model, api_base, expected_provider",
[
("azure_ai/gpt-4o", "https://my-resource.services.ai.azure.com", "azure_ai"),
("azure_ai/gpt-4o", "https://my-resource.services.ai.azure.com/models", "azure_ai"),
("azure_ai/gpt-5.4-nano", "https://my-resource.services.ai.azure.com", "azure_ai"),
("azure_ai/gpt-4o", "https://my-resource.openai.azure.com", "azure"),
(
"azure_ai/gpt-4o",
"https://my-resource.services.ai.azure.com/openai/deployments/gpt-4o/chat/completions"
"?api-version=2024-08-01-preview",
"azure",
),
("azure_ai/mistral-large-latest", "https://my-resource.services.ai.azure.com", "azure_ai"),
("azure_ai/mistral-large-latest", "https://my-resource.openai.azure.com", "azure_ai"),
],
)
def test_foundry_base_keeps_azure_ai_provider(model: str, api_base: str, expected_provider: str):
"""Regression for #38276: a Foundry .services.ai.azure.com base must not be reclassified as azure."""
config = AzureAIStudioConfig()
(
_,
_,
custom_llm_provider,
) = config._get_openai_compatible_provider_info(
model=model,
api_base=api_base,
api_key="my-key",
custom_llm_provider="azure_ai",
)
assert custom_llm_provider == expected_provider
def test_is_azure_openai_model_without_api_base_keeps_azure_ai():
"""Metadata lookups (get_model_info, supports_* checks) carry no api_base and must not flip the provider."""
config = AzureAIStudioConfig()
assert config._is_azure_openai_model(model="azure_ai/gpt-4o", api_base=None) is False
assert config._is_azure_openai_model(model="azure_ai/gpt-4o", api_base="https://my-res.openai.azure.com") is True
def test_azure_ai_validate_environment():
config = AzureAIStudioConfig()
headers = config.validate_environment(

View file

@ -47,8 +47,7 @@ def test_azure_ai_gpt_5_5_model_info(model):
routed_model, provider, _, _ = get_llm_provider(model=model)
assert routed_model == model.split("/", 1)[1]
# azure_ai/* models resolve under the azure provider in get_llm_provider
assert provider == "azure"
assert provider == "azure_ai"
def test_azure_ai_gpt_5_5_backup_matches_main():