Skip to content

feat: enforce tool_choice parameter in chat/completions#992

Open
eloe wants to merge 2 commits intoBlaizzy:mainfrom
eloe:upstream/tool-choice
Open

feat: enforce tool_choice parameter in chat/completions#992
eloe wants to merge 2 commits intoBlaizzy:mainfrom
eloe:upstream/tool-choice

Conversation

@eloe
Copy link
Copy Markdown

@eloe eloe commented Apr 9, 2026

Summary

Adds tool_choice enforcement to /v1/chat/completions and /responses, per the OpenAI API spec.

Supported values

Value Behavior
"auto" (default) Model decides whether to call tools
"none" Tools are stripped from the request; model cannot call tools
"required" A system instruction is injected requiring the model to call at least one tool
{"type": "function", "function": {"name": "X"}} Tools are filtered to only the named function; instruction injected to require it

Implementation

resolve_tool_choice() returns a filtered tool list and an optional system instruction. This approach works with any chat template without requiring model-specific tool_choice handling.

Tests

  • test_tool_choice_none_strips_tools
  • test_tool_choice_required_injects_instruction
  • test_tool_choice_specific_function
  • test_tool_choice_auto_passes_through
python -m pytest mlx_vlm/tests/test_server.py -k "tool_choice" -v

eloe and others added 2 commits April 8, 2026 20:31
Apply tool_choice policy before passing tools to the chat template:
- "none": strip tools entirely (no tool calls possible)
- "auto": pass tools unchanged (default, current behavior)
- "required": keep tools + inject system instruction to force tool use
- {"type":"function","function":{"name":"X"}}: filter to specific tool

New helper: resolve_tool_choice() returns filtered tools and optional
system instruction based on the policy.

Adds tool_choice and tools fields to ChatRequest model.
Adds 9 tests: 7 unit tests for resolve_tool_choice, 2 endpoint tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Validate tool_choice: reject invalid string values with 400
- Unknown tool name now returns 400 instead of falling back
- Skip tool parsing when tool_choice="none"
- Use == instead of is for equality checks in tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant