From 17734eb621905a301025f5ce0dca4e6eb96e5d2f Mon Sep 17 00:00:00 2001 From: Daniel Yudelevich <4537920+yudelevi@users.noreply.github.com> Date: Fri, 5 Jun 2026 02:10:20 -0700 Subject: [PATCH] fix(moonshot): drop temperature for reasoning models (kimi-k2.5/k2.6) (#29687) Kimi reasoning models reject every temperature except 1; a request with temperature=0.2 returns "invalid temperature: only 1 is allowed for this model". litellm only clamped temperature into [0.3, 1], so any value below 1 still 400'd. Drop the temperature param entirely for reasoning models (gated on supports_reasoning, the same signal transform_request already uses) so the model default is used; the non-reasoning moonshot-v1 models keep the existing clamp. Co-authored-by: Sameer Kankute --- litellm/llms/moonshot/chat/transformation.py | 10 ++++-- .../test_moonshot_chat_transformation.py | 36 +++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/litellm/llms/moonshot/chat/transformation.py b/litellm/llms/moonshot/chat/transformation.py index 4eb00fd81d6..da8687bce72 100644 --- a/litellm/llms/moonshot/chat/transformation.py +++ b/litellm/llms/moonshot/chat/transformation.py @@ -134,11 +134,15 @@ class MoonshotChatConfig(OpenAIGPTConfig): ########################################## # temperature limitations - # 1. `temperature` on KIMI API is [0, 1] but OpenAI is [0, 2] - # 2. If temperature < 0.3 and n > 1, KIMI will raise an exception. + # 1. reasoning models (kimi-k2.5, kimi-k2.6, ...) reject every temperature + # except 1, so the param is dropped and the model's default is used + # 2. `temperature` on KIMI API is [0, 1] but OpenAI is [0, 2] + # 3. If temperature < 0.3 and n > 1, KIMI will raise an exception. # If we enter this condition, we set the temperature to 0.3 as suggested by Moonshot AI ########################################## - if "temperature" in optional_params: + if supports_reasoning(model=model, custom_llm_provider="moonshot"): + optional_params.pop("temperature", None) + elif "temperature" in optional_params: if optional_params["temperature"] > 1: optional_params["temperature"] = 1 if optional_params["temperature"] < 0.3 and optional_params.get("n", 1) > 1: diff --git a/tests/test_litellm/llms/moonshot/test_moonshot_chat_transformation.py b/tests/test_litellm/llms/moonshot/test_moonshot_chat_transformation.py index 1e4d79963c1..95ade4290e9 100644 --- a/tests/test_litellm/llms/moonshot/test_moonshot_chat_transformation.py +++ b/tests/test_litellm/llms/moonshot/test_moonshot_chat_transformation.py @@ -205,6 +205,42 @@ class TestMoonshotConfig: # Temperature should be preserved assert result.get("temperature") == temp + def test_temperature_dropped_for_reasoning_models(self): + """Reasoning models (kimi-k2.5, kimi-k2.6) reject any temperature except 1, + so the param is dropped rather than clamped. A clamp to 0.3/1 would still + 400 when the caller passes e.g. 0.5.""" + config = MoonshotChatConfig() + + with patch( + "litellm.llms.moonshot.chat.transformation.supports_reasoning", + return_value=True, + ): + for temp in [0.0, 0.5, 1.0, 1.5]: + result = config.map_openai_params( + non_default_params={"temperature": temp}, + optional_params={}, + model="kimi-k2.5", + drop_params=False, + ) + assert "temperature" not in result + + def test_temperature_clamped_for_non_reasoning_models(self): + """Non-reasoning models keep the [0.3, 1] clamp behaviour.""" + config = MoonshotChatConfig() + + with patch( + "litellm.llms.moonshot.chat.transformation.supports_reasoning", + return_value=False, + ): + result = config.map_openai_params( + non_default_params={"temperature": 1.5}, + optional_params={}, + model="moonshot-v1-8k", + drop_params=False, + ) + + assert result.get("temperature") == 1 + def test_tool_choice_required_adds_message(self): """Test that tool_choice='required' adds a special message and removes tool_choice""" config = MoonshotChatConfig()