[Bugfix][Frontend] Reject Cohere REQUIRED tool choice without tools (#61825)

Signed-off-by: Kevin <jia__kuan@163.com>
This commit is contained in:
Jovan
2026-10-15 16:37:08 +00:00
committed by GitHub
parent d6f0b7a416
commit a9e90b9d1d
3 changed files with 47 additions and 1 deletions
@@ -598,6 +598,21 @@ class TestCohereErrorEnvelope:
assert "message" in body
assert isinstance(body["message"], str) and body["message"]
@pytest.mark.parametrize("path", ["/cohere/v2/chat", "/cohere/v2/chat/render"])
def test_required_tool_choice_without_tools_returns_400(self, path):
"""Reject an impossible tool choice before reaching either handler."""
app = _build_app_with_vllm_handlers(handler=None)
with TestClient(app) as client:
response = client.post(
path,
json={**_minimal_request_body(), "tool_choice": "REQUIRED"},
)
assert response.status_code == HTTPStatus.BAD_REQUEST
body = response.json()
assert "error" not in body
assert "REQUIRED" in body["message"]
assert "tools" in body["message"]
def test_http_error_body_is_cohere_shaped(self):
# A raised ``HTTPException`` from anywhere in the request cycle
# is routed through ``http_exception_handler`` (producing the
+21
View File
@@ -95,6 +95,27 @@ class TestCohereChatV2Request:
tool_choice="ANY", # not REQUIRED/NONE
)
@pytest.mark.parametrize("tool_fields", [{}, {"tools": None}, {"tools": []}])
def test_required_tool_choice_requires_tools(self, tool_fields):
with pytest.raises(VLLMValidationError, match="REQUIRED.*tools") as exc_info:
CohereChatV2Request(
model="m",
messages=[{"role": "user", "content": "hi"}],
tool_choice="REQUIRED",
**tool_fields,
)
assert exc_info.value.parameter == "tool_choice"
@pytest.mark.parametrize("tool_choice", [None, "NONE"])
def test_nonrequired_tool_choice_allows_empty_tools(self, tool_choice):
request = CohereChatV2Request(
model="m",
messages=[{"role": "user", "content": "hi"}],
tool_choice=tool_choice,
tools=[],
)
assert request.tool_choice == tool_choice
def test_stop_sequences_bounded_by_env_limit(self):
messages = [{"role": "user", "content": "hi"}]
limit = envs.VLLM_MAX_STOP_STRINGS
+11 -1
View File
@@ -44,7 +44,7 @@ from cohere.types import (
ToolV2,
UserChatMessageV2,
)
from pydantic import BaseModel, Field, field_validator
from pydantic import BaseModel, Field, field_validator, model_validator
import vllm.envs as envs
from vllm.exceptions import VLLMValidationError
@@ -211,6 +211,16 @@ class CohereChatV2Request(BaseModel):
)
return v
@model_validator(mode="after")
def _validate_tool_choice(self) -> CohereChatV2Request:
if self.tool_choice == "REQUIRED" and not self.tools:
raise VLLMValidationError(
'tool_choice="REQUIRED" requires at least one tool in tools.',
parameter="tool_choice",
value=self.tool_choice,
)
return self
@field_validator("messages", mode="before")
@classmethod
def _normalize_message_roles(cls, v: Any) -> Any: