diff --git a/litellm/proxy/common_request_processing.py b/litellm/proxy/common_request_processing.py index e812b03385d..c72b92d3aee 100644 --- a/litellm/proxy/common_request_processing.py +++ b/litellm/proxy/common_request_processing.py @@ -3066,7 +3066,7 @@ class ProxyBaseLLMRequestProcessing: """ Common request processing logic for both chat completions and responses API endpoints """ - client_model: Final = get_client_requested_model(request) or self.data.get("model") + client_model: Final = get_client_requested_model(request) or self.data.get("model") or model requested_model_from_client: Final[str | None] = client_model if isinstance(client_model, str) else None self._debug_log_request_payload() diff --git a/tests/unit/proxy/test_common_request_processing.py b/tests/unit/proxy/test_common_request_processing.py index 8143636a435..dc07161944b 100644 --- a/tests/unit/proxy/test_common_request_processing.py +++ b/tests/unit/proxy/test_common_request_processing.py @@ -5684,12 +5684,20 @@ class TestDisconnectGatherCleanup: @pytest.mark.asyncio -@pytest.mark.parametrize("client_model, expected", [("AgentX-LLM", "AgentX-LLM"), (None, "gpt-mini")]) +@pytest.mark.parametrize( + "client_model, body_model, endpoint_model, expected", + [ + ("AgentX-LLM", "gpt-mini", None, "AgentX-LLM"), + (None, "gpt-mini", None, "gpt-mini"), + (None, None, "team-model", "team-model"), + ], +) async def test_response_model_echoes_the_name_the_client_sent_before_auth_rewrote_it( - monkeypatch, client_model, expected + monkeypatch, client_model, body_model, endpoint_model, expected ): """LIT-3054: auth resolves router_settings.model_group_alias in the body, so the alias the - client sent only survives in the request scope. The response must still echo it.""" + client sent only survives in the request scope. The response must still echo it. Azure-style + routes carry the name in the path alone, and the response must echo that too (#49932).""" import litellm.proxy.common_request_processing as cpr async def llm(): @@ -5708,9 +5716,11 @@ async def test_response_model_echoes_the_name_the_client_sent_before_auth_rewrot proxy_logging._callback_capabilities_cache = {} monkeypatch.setattr(cpr, "route_request", fake_route_request) - processor = ProxyBaseLLMRequestProcessing(data={"model": "gpt-mini", "messages": []}) + processor = ProxyBaseLLMRequestProcessing(data={"messages": [], **({"model": body_model} if body_model else {})}) monkeypatch.setattr( - processor, "common_processing_pre_call_logic", AsyncMock(return_value=({"model": "gpt-mini"}, logging_obj)) + processor, + "common_processing_pre_call_logic", + AsyncMock(return_value=({"model": body_model or endpoint_model}, logging_obj)), ) monkeypatch.setattr(processor, "_has_post_call_guardrails", MagicMock(return_value=False)) scope = {"type": "http", "method": "POST", "path": "/v1/chat/completions", "headers": [], "query_string": b""} @@ -5725,6 +5735,7 @@ async def test_response_model_echoes_the_name_the_client_sent_before_auth_rewrot proxy_config=MagicMock(spec=ProxyConfig), route_type="acompletion", version=None, + model=endpoint_model, ) assert response.model == expected