Description
tool_call: false in model config is ignored by the prompt loop. The code unconditionally resolves SessionTools and sends them in the LLM request body, with tool_choice defaulting to "auto". Providers that serve models without tool-call support (e.g. morphllm without --enable-auto-tool-choice) reject the request with a 400 error.
Root cause
In packages/opencode/src/session/prompt.ts, the SessionTools.resolve() call and the toolChoice parameter in handle.process() both ignore model.capabilities.toolcall. Setting tool_call: false in model config correctly sets capabilities.toolcall to false in packages/opencode/src/provider/provider.ts:1216, but the prompt loop never reads that field.
Why this is bad
The user explicitly opts out of tool calls via tool_call: false, expecting a model-safe request with no tools sent. Instead the prompt loop sends a full tools array with tool_choice: "auto", which providers reject if they do not support tool calling at all. There is no workaround at the session or request level -- the config field is effectively a no-op.
Steps to reproduce
-
Configure a model with tool_call: false:
{
"provider": {
"morphllm": {
"models": {
"morphllm/Qwen3-30B-A3B": {
"tool_call": false
}
}
}
}
}
-
Start a session with that model and send a message.
-
The prompt loop calls the provider API with "tools": [...] and "tool_choice": "auto", even though tool calls are disabled.
-
Providers that require --enable-auto-tool-choice and --tool-call-parser flags return HTTP 400.
Expected
With tool_call: false, the LLM request body should contain neither tools nor tool_choice keys. The prompt loop should skip SessionTools.resolve() entirely.
OpenCode version
dev (current)
Operating System
Linux
Description
tool_call: falsein model config is ignored by the prompt loop. The code unconditionally resolvesSessionToolsand sends them in the LLM request body, withtool_choicedefaulting to"auto". Providers that serve models without tool-call support (e.g. morphllm without--enable-auto-tool-choice) reject the request with a 400 error.Root cause
In
packages/opencode/src/session/prompt.ts, theSessionTools.resolve()call and thetoolChoiceparameter inhandle.process()both ignoremodel.capabilities.toolcall. Settingtool_call: falsein model config correctly setscapabilities.toolcalltofalseinpackages/opencode/src/provider/provider.ts:1216, but the prompt loop never reads that field.Why this is bad
The user explicitly opts out of tool calls via
tool_call: false, expecting a model-safe request with no tools sent. Instead the prompt loop sends a full tools array withtool_choice: "auto", which providers reject if they do not support tool calling at all. There is no workaround at the session or request level -- the config field is effectively a no-op.Steps to reproduce
Configure a model with
tool_call: false:{ "provider": { "morphllm": { "models": { "morphllm/Qwen3-30B-A3B": { "tool_call": false } } } } }Start a session with that model and send a message.
The prompt loop calls the provider API with
"tools": [...]and"tool_choice": "auto", even though tool calls are disabled.Providers that require
--enable-auto-tool-choiceand--tool-call-parserflags return HTTP 400.Expected
With
tool_call: false, the LLM request body should contain neithertoolsnortool_choicekeys. The prompt loop should skipSessionTools.resolve()entirely.OpenCode version
dev (current)
Operating System
Linux