mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-29 06:33:28 +00:00
fix(decisions): honor base_url alias for custom backends (#48505)
Co-authored-by: Azmi Muwahid <azmimuwahid@gmail.com>
This commit is contained in:
parent
bdfe7ae195
commit
9ed502f375
2 changed files with 68 additions and 2 deletions
|
|
@ -456,10 +456,14 @@ def prepare_call(
|
|||
extra_headers: Mapping[str, str] | None,
|
||||
kwargs: Mapping[str, object],
|
||||
) -> DecisionsCall:
|
||||
base_url_alias: Final = kwargs.get("base_url")
|
||||
call_api_base: Final = (
|
||||
base_url_alias if api_base is None and isinstance(base_url_alias, str) and base_url_alias else api_base
|
||||
)
|
||||
upstream_model, provider, dynamic_api_key, dynamic_api_base = litellm.get_llm_provider(
|
||||
model=model,
|
||||
custom_llm_provider=custom_llm_provider,
|
||||
api_base=api_base,
|
||||
api_base=call_api_base,
|
||||
api_key=api_key,
|
||||
)
|
||||
provider_config: Final = _provider_config(upstream_model, provider)
|
||||
|
|
@ -488,7 +492,7 @@ def prepare_call(
|
|||
|
||||
try:
|
||||
resolved_api_base, static_api_key = provider_config.resolve_connection(
|
||||
dynamic_api_base or api_base, dynamic_api_key or api_key
|
||||
dynamic_api_base or call_api_base, dynamic_api_key or api_key
|
||||
)
|
||||
except ValueError as error:
|
||||
raise litellm.BadRequestError(message=str(error), model=model, llm_provider=provider) from error
|
||||
|
|
|
|||
|
|
@ -400,6 +400,68 @@ async def test_systemone_uses_evaluation_pricing(respx_mock: respx.MockRouter, d
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("base_url", "expected_api_base"),
|
||||
[
|
||||
("https://onprem.example/v1", "https://onprem.example/v1"),
|
||||
("", "https://fallback.example/v1"),
|
||||
(None, "https://fallback.example/v1"),
|
||||
(123, "https://fallback.example/v1"),
|
||||
],
|
||||
)
|
||||
async def test_openai_decisions_honors_base_url_alias(
|
||||
respx_mock: respx.MockRouter,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
base_url: str | int | None,
|
||||
expected_api_base: str,
|
||||
) -> None:
|
||||
monkeypatch.setenv("OPENAI_BASE_URL", "https://fallback.example/v1")
|
||||
route: Final = respx_mock.post(f"{expected_api_base}/decisions").respond(json=_OPENAI_RESPONSE)
|
||||
response: Final = await litellm.adecisions(
|
||||
model="openai/gpt-6-luna",
|
||||
input="The package arrived broken.",
|
||||
questions=[{"type": "predicate", "name": "is_defect", "instructions": "Is this a defect?"}],
|
||||
api_key="backend-secret-key",
|
||||
base_url=base_url,
|
||||
)
|
||||
|
||||
assert route.called
|
||||
assert route.calls[0].request.headers["authorization"] == "Bearer backend-secret-key"
|
||||
assert response._hidden_params["model"] == "openai/gpt-6-luna"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_openai_systemone_honors_base_url_alias(respx_mock: respx.MockRouter) -> None:
|
||||
route: Final = respx_mock.post("https://onprem.example/v1/decisions").respond(json=_OPENAI_RESPONSE)
|
||||
response: Final = await litellm.asystemone(
|
||||
model="openai/gpt-6-luna",
|
||||
state="The package arrived broken.",
|
||||
questions=_QUESTIONS,
|
||||
api_key="backend-secret-key",
|
||||
base_url="https://onprem.example/v1",
|
||||
)
|
||||
|
||||
assert route.called
|
||||
assert route.calls[0].request.headers["authorization"] == "Bearer backend-secret-key"
|
||||
assert response._hidden_params["model"] == "openai/gpt-6-luna"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_openai_decisions_api_base_wins_over_base_url_alias(respx_mock: respx.MockRouter) -> None:
|
||||
route: Final = respx_mock.post("https://api.openai.com/v1/decisions").respond(json=_OPENAI_RESPONSE)
|
||||
await litellm.adecisions(
|
||||
model="openai/gpt-6-luna",
|
||||
input="The package arrived broken.",
|
||||
questions=[{"type": "predicate", "name": "is_defect", "instructions": "Is this a defect?"}],
|
||||
api_key="test-key",
|
||||
api_base="https://api.openai.com/v1",
|
||||
base_url="https://onprem.example/v1",
|
||||
)
|
||||
|
||||
assert route.called
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_systemone_falls_back_to_plain_pricing_without_decisions_row(
|
||||
respx_mock: respx.MockRouter,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue