Skip to content

opencode Agent config is silently ignored — opencode always sends (1.17.7) #32465

@hous

Description

@hous

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

  1. Configure an OpenAI-compatible provider and set agent.build.tool_choice: "required" as above.
  2. Run a tool-requiring task: opencode run "Run the shell command: echo hello and report its output."
  3. 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:

"tool_choice": "auto"

…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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions