From e17c2ac016fdd0a19cb4e872ecf35dc3dc6dcce2 Mon Sep 17 00:00:00 2001 From: JingHao-Leon <102573344+JingHao-Leon@users.noreply.github.com> Date: Tue, 29 Sep 2026 04:50:06 +0800 Subject: [PATCH] fix(cohere,replicate): stop declaring silently-dropped params as supported Cohere v1/v2 declared tool_choice and Replicate declared tools/tool_choice/functions/function_call/seed in get_supported_openai_params, but map_openai_params has no branch for any of them and no later layer picks them up, so the params vanished without error even with drop_params=False. Replicate's tools case silently degraded tool-calling requests to plain completions. Remove them from the supported lists so get_optional_params raises UnsupportedParamsError by default (explicit drop with drop_params=True), consistent with litellm's drop_params contract. Regression tests included; ReplicateConfig remains the path for model-specific inputs like seed. Fixes #43613 --- litellm/llms/cohere/chat/transformation.py | 1 - litellm/llms/cohere/chat/v2_transformation.py | 1 - litellm/llms/replicate/chat/transformation.py | 5 --- .../chat/test_cohere_chat_transformation.py | 33 +++++++++++++++ tests/unit/llms/replicate/chat/__init__.py | 0 .../test_replicate_chat_transformation.py | 42 +++++++++++++++++++ 6 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 tests/unit/llms/cohere/chat/test_cohere_chat_transformation.py create mode 100644 tests/unit/llms/replicate/chat/__init__.py create mode 100644 tests/unit/llms/replicate/chat/test_replicate_chat_transformation.py diff --git a/litellm/llms/cohere/chat/transformation.py b/litellm/llms/cohere/chat/transformation.py index a26cdc81695..5ac9175fa4e 100644 --- a/litellm/llms/cohere/chat/transformation.py +++ b/litellm/llms/cohere/chat/transformation.py @@ -144,7 +144,6 @@ class CohereChatConfig(BaseConfig): "stop", "n", "tools", - "tool_choice", "seed", "extra_headers", ] diff --git a/litellm/llms/cohere/chat/v2_transformation.py b/litellm/llms/cohere/chat/v2_transformation.py index 37c53640d18..8d9d9e758a3 100644 --- a/litellm/llms/cohere/chat/v2_transformation.py +++ b/litellm/llms/cohere/chat/v2_transformation.py @@ -128,7 +128,6 @@ class CohereV2ChatConfig(OpenAIGPTConfig): "stop", "n", "tools", - "tool_choice", "seed", "extra_headers", ] diff --git a/litellm/llms/replicate/chat/transformation.py b/litellm/llms/replicate/chat/transformation.py index f7e09b7bec0..21d50275483 100644 --- a/litellm/llms/replicate/chat/transformation.py +++ b/litellm/llms/replicate/chat/transformation.py @@ -91,11 +91,6 @@ class ReplicateConfig(BaseConfig): "max_tokens", "top_p", "stop", - "seed", - "tools", - "tool_choice", - "functions", - "function_call", ] def map_openai_params( diff --git a/tests/unit/llms/cohere/chat/test_cohere_chat_transformation.py b/tests/unit/llms/cohere/chat/test_cohere_chat_transformation.py new file mode 100644 index 00000000000..9ca34163d59 --- /dev/null +++ b/tests/unit/llms/cohere/chat/test_cohere_chat_transformation.py @@ -0,0 +1,33 @@ +import pytest +from litellm.llms.cohere.chat.transformation import CohereChatConfig +from litellm.llms.cohere.chat.v2_transformation import CohereV2ChatConfig +from litellm.utils import UnsupportedParamsError, get_optional_params + + +@pytest.mark.parametrize("config_cls", [CohereChatConfig, CohereV2ChatConfig]) +def test_tool_choice_not_declared(config_cls): + params = config_cls().get_supported_openai_params(model="command-r") + assert "tool_choice" not in params + + +def test_tool_choice_raises_unsupported_params_error(): + # tool_choice used to be declared but silently dropped; with drop_params=False + # (the default) litellm must surface that instead of ignoring it + with pytest.raises(UnsupportedParamsError): + get_optional_params( + model="command-r", + custom_llm_provider="cohere", + tool_choice="auto", + request_timeout=10, + num_retries=0, + ) + + +def test_stop_still_maps_to_stop_sequences(): + result = CohereChatConfig().map_openai_params( + non_default_params={"stop": ["X"]}, + optional_params={}, + model="command-r", + drop_params=False, + ) + assert result["stop_sequences"] == ["X"] diff --git a/tests/unit/llms/replicate/chat/__init__.py b/tests/unit/llms/replicate/chat/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/unit/llms/replicate/chat/test_replicate_chat_transformation.py b/tests/unit/llms/replicate/chat/test_replicate_chat_transformation.py new file mode 100644 index 00000000000..122a14759c3 --- /dev/null +++ b/tests/unit/llms/replicate/chat/test_replicate_chat_transformation.py @@ -0,0 +1,42 @@ +import pytest +from litellm.llms.replicate.chat.transformation import ReplicateConfig +from litellm.utils import UnsupportedParamsError, get_optional_params + +REMOVED_PARAMS = { + "tools": [{"type": "function", "function": {"name": "f", "parameters": {"type": "object", "properties": {}}}}], + "tool_choice": "auto", + "functions": [{"name": "f", "parameters": {}}], + "function_call": "auto", + "seed": 42, +} + + +def test_tool_params_not_declared(): + supported = ReplicateConfig().get_supported_openai_params(model="meta/meta-llama-3-70b-instruct") + for param in REMOVED_PARAMS: + assert param not in supported + + +@pytest.mark.parametrize("param,value", sorted(REMOVED_PARAMS.items())) +def test_removed_params_raise_unsupported_params_error(param, value): + # these used to be declared but were silently dropped, degrading tool-calling + # requests to plain completions; with drop_params=False (the default) litellm + # must surface that instead of ignoring it + with pytest.raises(UnsupportedParamsError): + get_optional_params( + model="meta/meta-llama-3-70b-instruct", + custom_llm_provider="replicate", + **{param: value}, + request_timeout=10, + num_retries=0, + ) + + +def test_stop_still_maps_to_stop_sequences(): + result = ReplicateConfig().map_openai_params( + non_default_params={"stop": ["X"]}, + optional_params={}, + model="meta/meta-llama-3-70b-instruct", + drop_params=False, + ) + assert result["stop_sequences"] == ["X"]