diff --git a/litellm/utils.py b/litellm/utils.py index db1d7784f41..68f4278c87a 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -7708,7 +7708,6 @@ def validate_chat_completion_tool_choice( if tool_choice is None or isinstance(tool_choice, str): return tool_choice elif isinstance(tool_choice, dict): - # Handle Cursor IDE format: {"type": "auto"} -> unwrap to the bare string tool_choice_type = tool_choice.get("type") if tool_choice_type in ("auto", "none", "required") and "function" not in tool_choice: return tool_choice_type diff --git a/tests/litellm_utils_tests/test_validate_tool_choice.py b/tests/litellm_utils_tests/test_validate_tool_choice.py index c3f80f31864..0e6294a7cd4 100644 --- a/tests/litellm_utils_tests/test_validate_tool_choice.py +++ b/tests/litellm_utils_tests/test_validate_tool_choice.py @@ -28,12 +28,7 @@ def test_validate_tool_choice_standard_dict(): def test_validate_tool_choice_cursor_format(): - """Cursor IDE format {"type": "auto"} must be unwrapped to the bare string. - - No OpenAI surface accepts the object form of these values. Forwarding it - verbatim makes the provider reject the call with - "Invalid value: 'auto' ... param: tool_choice.type". - """ + """Cursor IDE format {"type": "auto"} is unwrapped to the bare string.""" assert validate_chat_completion_tool_choice({"type": "auto"}) == "auto" assert validate_chat_completion_tool_choice({"type": "none"}) == "none" assert validate_chat_completion_tool_choice({"type": "required"}) == "required" diff --git a/tests/test_litellm/completion_extras/litellm_responses_transformation/test_completion_extras_litellm_responses_transformation_transformation.py b/tests/test_litellm/completion_extras/litellm_responses_transformation/test_completion_extras_litellm_responses_transformation_transformation.py index c2484970ed9..5508931b35d 100644 --- a/tests/test_litellm/completion_extras/litellm_responses_transformation/test_completion_extras_litellm_responses_transformation_transformation.py +++ b/tests/test_litellm/completion_extras/litellm_responses_transformation/test_completion_extras_litellm_responses_transformation_transformation.py @@ -3419,14 +3419,7 @@ async def test_acompletion_bridge_normalizes_tool_choice_on_the_wire( tool_choice: str | dict[str, object], expected_wire_tool_choice: str | dict[str, str], ) -> None: - """Object-wrapped tool_choice must never reach /v1/responses. - - Clients (Cursor, Claude Code via /v1/messages) send ``{"type": "auto"}``. - The Responses API only accepts a hosted-tool name in ``tool_choice.type``, - so forwarding the wrapper verbatim fails the whole call with - ``Invalid value: 'auto' ... param: tool_choice.type`` -- which broke every - tool call, including web search, on responses-mode models. - """ + """Object-wrapped tool_choice must never reach /v1/responses.""" from unittest.mock import AsyncMock from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler