diff --git a/litellm/llms/openai/chat/gpt_5_transformation.py b/litellm/llms/openai/chat/gpt_5_transformation.py index 05c003c8b7..e491770a24 100644 --- a/litellm/llms/openai/chat/gpt_5_transformation.py +++ b/litellm/llms/openai/chat/gpt_5_transformation.py @@ -40,11 +40,16 @@ class OpenAIGPT5Config(OpenAIGPTConfig): gpt-5.1/5.2 support temperature when reasoning_effort="none", unlike base gpt-5 which only supports temperature=1. Excludes - pro variants which keep stricter knobs. + pro variants which keep stricter knobs and gpt-5.2-chat variants + which only support temperature=1. """ model_name = model.split("/")[-1] is_gpt_5_1 = model_name.startswith("gpt-5.1") - is_gpt_5_2 = model_name.startswith("gpt-5.2") and "pro" not in model_name + is_gpt_5_2 = ( + model_name.startswith("gpt-5.2") + and "pro" not in model_name + and not model_name.startswith("gpt-5.2-chat") + ) return is_gpt_5_1 or is_gpt_5_2 @classmethod diff --git a/litellm/proxy/middleware/in_flight_requests_middleware.py b/litellm/proxy/middleware/in_flight_requests_middleware.py index e5e405fb07..d615640d87 100644 --- a/litellm/proxy/middleware/in_flight_requests_middleware.py +++ b/litellm/proxy/middleware/in_flight_requests_middleware.py @@ -6,7 +6,7 @@ Prometheus gauge `litellm_in_flight_requests`. """ import os -from typing import Any, Optional +from typing import Optional from starlette.types import ASGIApp, Receive, Scope, Send @@ -27,7 +27,7 @@ class InFlightRequestsMiddleware: """ _in_flight: int = 0 - _gauge: Optional[Any] = None + _gauge: Optional[object] = None _gauge_init_attempted: bool = False def __init__(self, app: ASGIApp) -> None: @@ -41,13 +41,13 @@ class InFlightRequestsMiddleware: InFlightRequestsMiddleware._in_flight += 1 gauge = InFlightRequestsMiddleware._get_gauge() if gauge is not None: - gauge.inc() # type: ignore[attr-defined] + gauge.inc() # type: ignore[union-attr] try: await self.app(scope, receive, send) finally: InFlightRequestsMiddleware._in_flight -= 1 if gauge is not None: - gauge.dec() # type: ignore[attr-defined] + gauge.dec() # type: ignore[union-attr] @staticmethod def get_count() -> int: @@ -55,14 +55,14 @@ class InFlightRequestsMiddleware: return InFlightRequestsMiddleware._in_flight @staticmethod - def _get_gauge() -> Optional[Any]: + def _get_gauge() -> Optional[object]: if InFlightRequestsMiddleware._gauge_init_attempted: return InFlightRequestsMiddleware._gauge InFlightRequestsMiddleware._gauge_init_attempted = True try: from prometheus_client import Gauge - kwargs: dict[str, Any] = {} + kwargs = {} if "PROMETHEUS_MULTIPROC_DIR" in os.environ: # livesum aggregates across all worker processes in the scrape response kwargs["multiprocess_mode"] = "livesum" diff --git a/tests/test_litellm/llms/openai/test_gpt5_transformation.py b/tests/test_litellm/llms/openai/test_gpt5_transformation.py index 386f264a4d..4ccde67409 100644 --- a/tests/test_litellm/llms/openai/test_gpt5_transformation.py +++ b/tests/test_litellm/llms/openai/test_gpt5_transformation.py @@ -267,7 +267,8 @@ def test_gpt5_1_model_detection(gpt5_config: OpenAIGPT5Config): assert gpt5_config.is_model_gpt_5_1_model("gpt-5.1-chat") assert gpt5_config.is_model_gpt_5_1_model("gpt-5.2") assert gpt5_config.is_model_gpt_5_1_model("gpt-5.2-2025-12-11") - assert gpt5_config.is_model_gpt_5_1_model("gpt-5.2-chat-latest") + assert not gpt5_config.is_model_gpt_5_1_model("gpt-5.2-chat") + assert not gpt5_config.is_model_gpt_5_1_model("gpt-5.2-chat-latest") assert not gpt5_config.is_model_gpt_5_1_model("gpt-5.2-pro") assert not gpt5_config.is_model_gpt_5_1_model("gpt-5") assert not gpt5_config.is_model_gpt_5_1_model("gpt-5-mini") @@ -395,7 +396,38 @@ def test_gpt5_temperature_still_restricted(config: OpenAIConfig): assert params["temperature"] == 1.0 -def test_gpt5_2_pro_allows_reasoning_effort_xhigh(config: OpenAIConfig): +def test_gpt5_2_chat_temperature_restricted(config: OpenAIConfig): + """Test that gpt-5.2-chat only supports temperature=1, like base gpt-5. + + Regression test for https://github.com/BerriAI/litellm/issues/21911 + """ + # gpt-5.2-chat should reject non-1 temperature when drop_params=False + for model in ["gpt-5.2-chat", "gpt-5.2-chat-latest"]: + with pytest.raises(litellm.utils.UnsupportedParamsError): + config.map_openai_params( + non_default_params={"temperature": 0.7}, + optional_params={}, + model=model, + drop_params=False, + ) + + # temperature=1 should still work + params = config.map_openai_params( + non_default_params={"temperature": 1.0}, + optional_params={}, + model=model, + drop_params=False, + ) + assert params["temperature"] == 1.0 + + # drop_params=True should silently drop non-1 temperature + params = config.map_openai_params( + non_default_params={"temperature": 0.5}, + optional_params={}, + model=model, + drop_params=True, + ) + assert "temperature" not in params params = config.map_openai_params( non_default_params={"reasoning_effort": "xhigh"}, optional_params={},