fix(utils): keep a non-string tool_choice type a 400, not a TypeError

A list or dict in tool_choice["type"] is unhashable, so the hosted tool lookup needs the string check first. The bridge test that used file_search as an untranslatable choice now uses a type that really is unknown.
This commit is contained in:
devin-ai-integration[bot] 2026-11-08 00:06:38 +00:00
parent ff0ec0f195
commit 54dd6668d0
3 changed files with 7 additions and 3 deletions

View file

@ -9758,9 +9758,12 @@ def validate_chat_completion_tool_choice(
)
# Standard OpenAI format: {"type": "function", "function": {...}}
forces_hosted_tool: Final[bool] = (
isinstance(tool_choice_type, str) and tool_choice_type in HOSTED_TOOL_CHOICE_TYPES
)
if (
tool_choice_type != "allowed_tools"
and tool_choice_type not in HOSTED_TOOL_CHOICE_TYPES
and not forces_hosted_tool
and (tool_choice_type is None or tool_choice.get("function") is None)
):
raise BadRequestError(

View file

@ -5949,12 +5949,12 @@ async def test_bridge_rejects_untranslatable_tool_choice_with_a_400(stream: bool
model="anthropic/claude-haiku-4-5",
input="Which fruit is red?",
tools=[{"type": "function", "name": "lookup_fruit", "parameters": {"type": "object"}}],
tool_choice={"type": "file_search"},
tool_choice={"type": "web_search_tool"},
stream=stream,
api_key="sk-unused",
)
assert exc_info.value.status_code == 400
assert "tool_choice={'type': 'file_search'}" in str(exc_info.value)
assert "tool_choice={'type': 'web_search_tool'}" in str(exc_info.value)
def test_cache_control_on_user_message():

View file

@ -8810,6 +8810,7 @@ def test_validate_tool_choice_cursor_format():
{"type": "function"},
{"name": "lookup_fruit"},
{"type": "web_search_tool"},
{"type": ["web_search"]},
],
)
def test_validate_tool_choice_invalid_dict_is_a_400(tool_choice):