diff --git a/litellm/llms/zai/chat/transformation.py b/litellm/llms/zai/chat/transformation.py index a3a85934275..d8571fa7132 100644 --- a/litellm/llms/zai/chat/transformation.py +++ b/litellm/llms/zai/chat/transformation.py @@ -68,14 +68,21 @@ class ZAIChatConfig(OpenAIGPTConfig): reasoning_params: Final = MappingProxyType( {k: v for k, v in non_default_params.items() if k in ZAI_REASONING_PARAMS and k in supported_openai_params} ) - optional_params.update( - (k, v) - for k, v in non_default_params.items() - if k in supported_openai_params and k not in ZAI_REASONING_PARAMS - ) - if reasoning_params: - optional_params["extra_body"] = { # mutable-ok: the OpenAI SDK json-encodes extra_body from a plain dict - **(optional_params.get("extra_body") or MappingProxyType({})), - **reasoning_params, + passthrough_params: Final = MappingProxyType( + { + k: v + for k, v in non_default_params.items() + if k in supported_openai_params and k not in ZAI_REASONING_PARAMS } - return optional_params + ) + if not reasoning_params: + return {**optional_params, **passthrough_params} # mutable-ok: base class returns a dict + extra_body: Final = { # mutable-ok: the OpenAI SDK json-encodes extra_body from a plain dict + **(optional_params.get("extra_body") or MappingProxyType({})), + **reasoning_params, + } + return { # mutable-ok: base class returns a dict + **optional_params, + **passthrough_params, + "extra_body": extra_body, + } diff --git a/tests/test_litellm/llms/zai/test_zai_provider.py b/tests/test_litellm/llms/zai/test_zai_provider.py index e513aa5a450..2429e7c05c3 100644 --- a/tests/test_litellm/llms/zai/test_zai_provider.py +++ b/tests/test_litellm/llms/zai/test_zai_provider.py @@ -175,17 +175,25 @@ def test_thinking_and_reasoning_effort_move_into_extra_body(local_model_cost_map assert result["extra_body"] == {"thinking": {"type": "disabled"}, "reasoning_effort": "low"} -def test_existing_extra_body_is_kept_and_not_mutated(local_model_cost_map): +def test_caller_optional_params_and_extra_body_are_not_mutated(local_model_cost_map): from litellm.llms.zai.chat.transformation import ZAIChatConfig caller_extra_body = {"already_here": True} + caller_optional_params = {"stream": False, "extra_body": caller_extra_body} result = ZAIChatConfig()._map_openai_params( - non_default_params={"thinking": {"type": "disabled"}}, - optional_params={"extra_body": caller_extra_body}, + non_default_params={"max_tokens": 100, "thinking": {"type": "disabled"}}, + optional_params=caller_optional_params, model="glm-4.7", drop_params=False, ) - assert result["extra_body"] == {"already_here": True, "thinking": {"type": "disabled"}} + assert result == { + "stream": False, + "max_tokens": 100, + "extra_body": {"already_here": True, "thinking": {"type": "disabled"}}, + } + assert result is not caller_optional_params + assert caller_optional_params == {"stream": False, "extra_body": {"already_here": True}} + assert caller_optional_params["extra_body"] is caller_extra_body assert caller_extra_body == {"already_here": True}