Title: Agent tool_choice config is silently ignored — opencode always sends tool_choice: "auto" (1.17.7)
Summary
Setting tool_choice on an agent in opencode.json has no effect. opencode always sends "tool_choice": "auto" to the provider, regardless of the configured value. This is the exact capability requested in #14090 (closed as completed), but it does not work in 1.17.7 — the key is accepted without error and silently dropped.
For models that don't reliably emit tool calls under auto (the failure mode #14090 itself describes for GPT), this makes autonomous/agentic sessions impossible: the model never gets asked to commit to a tool call, so the agent loop ends with no tool execution.
Environment
- opencode 1.17.7 (also reproduced on 1.17.4)
- Provider: custom OpenAI-compatible (
@ai-sdk/openai-compatible), local vLLM server
- OS: Linux
- Agent:
build (default), invoked via opencode run
Config used
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"myprovider": {
"npm": "@ai-sdk/openai-compatible",
"options": { "baseURL": "http://127.0.0.1:8000/v1", "apiKey": "x" },
"models": { "my-model": { "name": "my-model" } }
}
},
"model": "myprovider/my-model",
"agent": {
"build": {
"tool_choice": "required"
}
}
}
Steps to reproduce
- Configure an OpenAI-compatible provider and set
agent.build.tool_choice: "required" as above.
- Run a tool-requiring task:
opencode run "Run the shell command: echo hello and report its output."
- Capture the outgoing HTTP request to the provider (e.g.
tcpdump -i lo -A 'tcp dst port 8000', since the provider is plaintext HTTP on loopback).
Expected
The request body sent to /v1/chat/completions contains "tool_choice": "required" (or the configured value), per #14090 and the Vercel AI SDK toolChoice parameter.
Actual
The request body always contains:
…even with agent.build.tool_choice: "required" set. No validation error or warning is emitted for the config key. The agent then receives a response with no usable tool call and the loop exits without executing anything.
Wire evidence (captured with tcpdump on the loopback provider port)
Request opencode sent (note auto, not the configured required):
"tool_choice":"auto"
tools: bash, read, write, edit, glob, grep, task, skill, todowrite, webfetch
Same request issued by hand with "tool_choice":"required" returns a valid tool call from the same model/endpoint, confirming the model and server are fine and the only difference is what opencode sends:
# tool_choice: "required" -> finish_reason: tool_calls, arguments: {"command":"echo hello"}
# tool_choice: "auto" -> empty/again no usable call
Apparent root cause (from inspecting the 1.17.7 binary)
- Every
tool_choice schema in the bundle is a provider request schema (OpenAI/Anthropic/Bedrock/Gemini outgoing-request validation): {model, messages, tools, tool_choice: optional(...)}.
- opencode's agent config schema does not include a
tool_choice field (it's not alongside prompt/model/temperature/mode/permission).
- The value sent derives from
ai.prompt.toolChoice, which opencode's session/streamText path leaves unset → the AI SDK / provider defaults to auto.
So the fix from #14090 (add tool_choice to the agent config schema and pass it into the streamText call) does not appear to be wired up in 1.17.7.
Impact
Possible fix
Wire the agent's tool_choice config through to the toolChoice argument of the streamText call (the AI SDK already supports "auto" | "required" | "none" | {type:"tool", toolName}), and add the field to the agent config schema so it validates.
References
Title: Agent
tool_choiceconfig is silently ignored — opencode always sendstool_choice: "auto"(1.17.7)Summary
Setting
tool_choiceon an agent inopencode.jsonhas no effect. opencode always sends"tool_choice": "auto"to the provider, regardless of the configured value. This is the exact capability requested in #14090 (closed as completed), but it does not work in 1.17.7 — the key is accepted without error and silently dropped.For models that don't reliably emit tool calls under
auto(the failure mode #14090 itself describes for GPT), this makes autonomous/agentic sessions impossible: the model never gets asked to commit to a tool call, so the agent loop ends with no tool execution.Environment
@ai-sdk/openai-compatible), local vLLM serverbuild(default), invoked viaopencode runConfig used
{ "$schema": "https://opencode.ai/config.json", "provider": { "myprovider": { "npm": "@ai-sdk/openai-compatible", "options": { "baseURL": "http://127.0.0.1:8000/v1", "apiKey": "x" }, "models": { "my-model": { "name": "my-model" } } } }, "model": "myprovider/my-model", "agent": { "build": { "tool_choice": "required" } } }Steps to reproduce
agent.build.tool_choice: "required"as above.opencode run "Run the shell command: echo hello and report its output."tcpdump -i lo -A 'tcp dst port 8000', since the provider is plaintext HTTP on loopback).Expected
The request body sent to
/v1/chat/completionscontains"tool_choice": "required"(or the configured value), per #14090 and the Vercel AI SDKtoolChoiceparameter.Actual
The request body always contains:
…even with
agent.build.tool_choice: "required"set. No validation error or warning is emitted for the config key. The agent then receives a response with no usable tool call and the loop exits without executing anything.Wire evidence (captured with tcpdump on the loopback provider port)
Request opencode sent (note
auto, not the configuredrequired):Same request issued by hand with
"tool_choice":"required"returns a valid tool call from the same model/endpoint, confirming the model and server are fine and the only difference is what opencode sends:Apparent root cause (from inspecting the 1.17.7 binary)
tool_choiceschema in the bundle is a provider request schema (OpenAI/Anthropic/Bedrock/Gemini outgoing-request validation):{model, messages, tools, tool_choice: optional(...)}.tool_choicefield (it's not alongsideprompt/model/temperature/mode/permission).ai.prompt.toolChoice, which opencode's session/streamTextpath leaves unset → the AI SDK / provider defaults toauto.So the fix from #14090 (add
tool_choiceto the agent config schema and pass it into thestreamTextcall) does not appear to be wired up in 1.17.7.Impact
tool_choice: "required"(ornone, or a named tool) per agent.auto— the documented motivation for [FEATURE]: Expose toolChoice as a configurable agent option in opencode.json #14090.Possible fix
Wire the agent's
tool_choiceconfig through to thetoolChoiceargument of thestreamTextcall (the AI SDK already supports"auto" | "required" | "none" | {type:"tool", toolName}), and add the field to the agent config schema so it validates.References
toolChoice: https://sdk.vercel.ai/docs/reference/ai-sdk-core/stream-text