Summary
OpenCode's streamText call in src/session/llm.ts never passes toolChoice, so the Vercel AI SDK defaults to { type: "auto" } for all models. There is currently no way for users to configure this — not through opencode.json agent options, not through the additional passthrough (which routes to providerOptions, not toolChoice).
This matters most for OpenAI models. GPT's RLHF prior defaults to conversational text response; tool calling is additive. With tool_choice: "auto", GPT is free to narrate intended tool use instead of executing it — a failure mode that makes autonomous agentic sessions unreliable.
Root cause (from source)
src/session/llm.ts — toolChoice is absent from the streamText call:
const result = streamText({
model,
messages,
tools,
// toolChoice is never set — defaults to { type: "auto" }
maxSteps: ...,
...
})
src/config/config.ts — agent additional options flow to providerOptions, not toolChoice:
// extras from agent.options go here:
experimental_providerMetadata: { ... }
// toolChoice is a separate, first-class streamText parameter
Requested change
Add a tool_choice field to the agent config schema that maps directly to the toolChoice parameter of streamText:
// opencode.json
{
"agents": {
"my-agent": {
"model": "openai/gpt-4.1",
"tool_choice": "required"
}
}
}
Accepted values should follow the Vercel AI SDK's toolChoice type: "auto" (default, current behaviour), "required", "none", or { type: "tool", toolName: "..." }.
Why this matters
The Vercel AI SDK already supports toolChoice: "required" — OpenCode just never exposes it. This is the canonical fix for GPT models that default to text response instead of calling tools. OpenAI's own agentic system prompt guide calls out this failure mode explicitly and recommends tool_choice: "required" as the API-level solution.
Workarounds (stronger system prompts) help but are model-specific and fragile. A first-class config option would let users opt into reliable tool use on a per-agent basis, without touching prompt engineering.
Vercel AI SDK reference
Summary
OpenCode's
streamTextcall insrc/session/llm.tsnever passestoolChoice, so the Vercel AI SDK defaults to{ type: "auto" }for all models. There is currently no way for users to configure this — not throughopencode.jsonagent options, not through theadditionalpassthrough (which routes toproviderOptions, nottoolChoice).This matters most for OpenAI models. GPT's RLHF prior defaults to conversational text response; tool calling is additive. With
tool_choice: "auto", GPT is free to narrate intended tool use instead of executing it — a failure mode that makes autonomous agentic sessions unreliable.Root cause (from source)
src/session/llm.ts—toolChoiceis absent from thestreamTextcall:src/config/config.ts— agentadditionaloptions flow toproviderOptions, nottoolChoice:Requested change
Add a
tool_choicefield to the agent config schema that maps directly to thetoolChoiceparameter ofstreamText:Accepted values should follow the Vercel AI SDK's
toolChoicetype:"auto"(default, current behaviour),"required","none", or{ type: "tool", toolName: "..." }.Why this matters
The Vercel AI SDK already supports
toolChoice: "required"— OpenCode just never exposes it. This is the canonical fix for GPT models that default to text response instead of calling tools. OpenAI's own agentic system prompt guide calls out this failure mode explicitly and recommendstool_choice: "required"as the API-level solution.Workarounds (stronger system prompts) help but are model-specific and fragile. A first-class config option would let users opt into reliable tool use on a per-agent basis, without touching prompt engineering.
Vercel AI SDK reference
toolChoiceinstreamText"auto","required","none",{ type: "tool", toolName: string }