Skip to content

Issue: allowed_tools tool_choice is dropped on /v1/responses for chat-bridged providers #1093

Description

@SantiagoDePolonia

AI Generated comment:

Describe the bug

On /v1/responses, a tool_choice of type allowed_tools is dropped for every provider that serves Responses through the chat bridge (ResponsesViaChat). These include Gemini, Vertex, Groq, Ollama, Cohere, Bedrock, the OpenAI-compatible adapters and others. The request succeeds, and the model can call any declared function, including ones the caller excluded.

"tool_choice": {"type": "allowed_tools", "mode": "required", "tools": [{"type": "function", "name": "tool_b"}]}

Root cause

normalizeResponsesToolChoiceForChat (internal/providers/responses_adapter.go:292) keeps only string choices and type: "function". Every other object type returns nil on purpose, because hosted-tool choices have no chat equivalent. allowed_tools over function tools is translatable, but it is dropped along with them.

Why not just keep it in the bridge

The bridge is shared. Converting the choice to the Chat Completions shape ({"type": "allowed_tools", "allowed_tools": {"mode", "tools"}}) would hand it to adapters that cannot express it. The Anthropic chat adapter rejects it as an unsupported tool_choice type, and the OpenAI-compatible adapters forward it to upstreams that may not accept it. Each provider needs its own decision: map it, narrow the declared tools, or reject.

Suggested approach

  • Convert Responses allowed_tools over function tools into the chat shape in the bridge.
  • Gemini native already maps the chat shape (fix(providers): honor allowed_tools, strict and developer role on Gemini and Anthropic #1091): required → ANY + allowedFunctionNames, auto → VALIDATED + allowedFunctionNames.
  • For the other bridged adapters, map the choice where the provider supports it; otherwise reject it with a 400 naming the field. Do not widen silently.
  • Tests: one bridge test per shape, plus a check on each adapter's handling.

Follow-up to #1056 / #1091, which fixed the Chat Completions path only.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions