This commit is contained in:
Ege 2026-10-05 23:29:58 +00:00 • committed by GitHub
commit d6d413ee03
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 25 additions and 0 deletions

View file

@ -8340,6 +8340,12 @@ def validate_chat_completion_tool_choice(
if tool_choice_type in ("auto", "none", "required") and "function" not in tool_choice:
return tool_choice_type
# OpenAI also allows constraining which tools the model may call:
# {"type": "allowed_tools", "allowed_tools": {"mode": ..., "tools": [...]}}.
# Pass it through untouched so downstream providers see the full payload.
if tool_choice_type == "allowed_tools" and isinstance(tool_choice.get("allowed_tools"), dict):
return tool_choice
# Standard OpenAI format: {"type": "function", "function": {...}}
if tool_choice.get("type") is None or tool_choice.get("function") is None:
raise BadRequestError(

View file

@ -36,6 +36,25 @@ def test_validate_tool_choice_cursor_format():
assert validate_chat_completion_tool_choice({"type": "required"}, model=MODEL) == "required"
def test_validate_tool_choice_allowed_tools_passthrough():
"""Chat completions accepts the allowed_tools shape and keeps its payload intact."""
tool_choice = {
"type": "allowed_tools",
"allowed_tools": {
"mode": "required",
"tools": [{"type": "function", "function": {"name": "get_time"}}],
},
}
assert validate_chat_completion_tool_choice(tool_choice, model=MODEL) is tool_choice
def test_validate_tool_choice_allowed_tools_without_payload_is_a_400():
"""allowed_tools without its nested object stays a caller error."""
tool_choice = {"type": "allowed_tools"}
with pytest.raises(litellm.BadRequestError, match="Invalid tool choice"):
validate_chat_completion_tool_choice(tool_choice, model=MODEL)
@pytest.mark.parametrize(
"tool_choice",
[