Merge pull request #38235 from BerriAI/litellm_router_api_base_resolution

fix(router): resolve provider from api_base in deployment validation and acompletion
This commit is contained in:
Mateo Wang 2026-08-25 11:51:15 -07:00 • committed by GitHub
commit 76e1105f74
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 77 additions and 1 deletions

View file

@ -602,7 +602,7 @@ async def acompletion(
_, custom_llm_provider, _, _ = get_llm_provider(
model=model,
custom_llm_provider=custom_llm_provider,
api_base=base_url,
api_base=kwargs.get("api_base") or base_url,
)
fallbacks = fallbacks or litellm.model_fallbacks

View file

@ -8341,6 +8341,7 @@ class Router:
) = litellm.get_llm_provider(
model=deployment.litellm_params.model,
custom_llm_provider=deployment.litellm_params.get("custom_llm_provider", None),
api_base=deployment.litellm_params.api_base,
)
# done reading model["litellm_params"]
# Check if provider is supported: either in enum or JSON-configured

View file

@ -2944,3 +2944,16 @@ def test_a_stream_that_reported_no_usage_is_still_billed(local_cost_map):
assert cost == pytest.approx(
_priced_at(rebuilt.usage.prompt_tokens, rebuilt.usage.completion_tokens)
)
@pytest.mark.asyncio
async def test_acompletion_resolves_provider_from_api_base():
response = await litellm.acompletion(
model="deepseek-chat",
api_base="https://api.deepseek.com/v1",
api_key="fake-key",
messages=[{"role": "user", "content": "hi"}],
mock_response="resolved",
)
assert response.choices[0].message.content == "resolved"

View file

@ -8921,3 +8921,65 @@ class TestAzureBaseModelFallbackLogging:
deployment=None, received_model_name="my-group", id="azure-base-model-test-id"
)
assert model_info["max_input_tokens"] == litellm.model_cost["azure/gpt-4o-mini"]["max_input_tokens"]
class TestAddDeploymentApiBaseProviderResolution:
def test_bare_model_with_known_api_base_initializes(self):
router = litellm.Router(
model_list=[
{
"model_name": "groq-pinned",
"litellm_params": {
"model": "llama-3.3-70b-versatile",
"api_base": "https://api.groq.com/openai/v1",
"api_key": "fake-key",
},
},
{
"model_name": "deepseek-pinned",
"litellm_params": {
"model": "deepseek-chat",
"api_base": "https://api.deepseek.com/v1",
"api_key": "fake-key",
},
},
]
)
model_list = router.get_model_list()
assert model_list is not None
assert {m["model_name"] for m in model_list} == {"groq-pinned", "deepseek-pinned"}
def test_bare_model_with_unknown_api_base_still_raises(self):
with pytest.raises(litellm.BadRequestError, match="LLM Provider NOT provided"):
litellm.Router(
model_list=[
{
"model_name": "mystery",
"litellm_params": {
"model": "some-unknown-model",
"api_base": "https://llm.internal.example.com/v1",
"api_key": "fake-key",
},
}
]
)
def test_explicit_custom_llm_provider_beats_api_base_endpoint_match(self):
router = litellm.Router(
model_list=[
{
"model_name": "openai-via-gateway",
"litellm_params": {
"model": "gpt-3.5-turbo",
"custom_llm_provider": "openai",
"api_base": "https://api.groq.com/openai/v1",
"api_key": "fake-key",
},
}
]
)
deployment = router.get_deployment_by_model_group_name("openai-via-gateway")
assert deployment is not None
assert deployment.litellm_params.custom_llm_provider == "openai"