Repository navigation
Description
Description
Body-level fields declared in a model's variants entry never reach the HTTP request. The variant is merged into options correctly inside opencode, but the fields are lost before the wire.
I verified this with a logging reverse proxy between opencode and the server, so this is the actual request body, not an inference.
Config declares a variant carrying chat_template_kwargs (needed to enable thinking on Qwen3.8 via its chat template):
"variants": {
"low": {
"temperature": 1.0, "top_p": 0.95, "top_k": 20,
"chat_template_kwargs": { "enable_thinking": true, "reasoning_effort": "low" }
}
}Agent uses "variant": "low". Captured request body:
{
"model": "Qwen3.8-27B-oQ6e-mtp",
"max_tokens": 32000,
"top_p": 1,
"stream": true
}chat_template_kwargs, temperature and top_k are all gone; top_p is the hardcoded value from ProviderTransform.topP(), not the variant's.
Sending the same chat_template_kwargs straight to the same endpoint with curl works, so the server accepts it:
POST /v1/messages {"chat_template_kwargs":{"enable_thinking":true,"reasoning_effort":"banana"}}
-> {"error":{"message":"Chat template error: Unexpected reasoning effort banana. ..."}}
As far as I can tell the loss happens at packages/opencode/src/provider/transform.ts:1405:
const key = sdkKey(model.api.npm) ?? (usesDotSplitOptions ? model.providerID.split(".")[0] : model.providerID)
return { [key]: normalized }Options are handed to the AI SDK as providerOptions[key], and the adapter validates that object against its own schema, so keys it does not know are dropped. mergeOptions at session/llm/request.ts:91 does include the variant, so this is not a merge bug.
This may affect shipped functionality, not just custom providers. ProviderTransform.variants() (transform.ts:729) returns chat_template_kwargs for MiniMax-M3 on @ai-sdk/anthropic and @ai-sdk/openai-compatible:
return {
none: { chat_template_kwargs: { thinking_mode: "disabled" } },
thinking: { chat_template_kwargs: { thinking_mode: "enabled" } },
}If the analysis above is right those built-in variants go the same way. I have not tested MiniMax-M3 myself, so I am flagging it rather than asserting it.
Previously reported in #42300 for @ai-sdk/openai-compatible; that issue was auto-closed for template non-compliance rather than on merit. This report adds a second adapter and a captured request body.
specs/v2/config.md:265 mentions agent-local options carrying body overrides, which would be a natural place to fix this.
Plugins
none (reproduced with a minimal standalone config)
OpenCode version
1.18.18
Steps to reproduce
-
Start any OpenAI/Anthropic-compatible server that accepts extra body fields. I used oMLX serving Qwen3.8-27B on
127.0.0.1:8001. -
Put a logging proxy in front of it that dumps the request body and forwards to the server (any tiny HTTP proxy will do), listening on
127.0.0.1:8009. -
Minimal config pointing at the proxy:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"px": {
"npm": "@ai-sdk/anthropic",
"options": { "baseURL": "http://127.0.0.1:8009/v1", "apiKey": "x" },
"models": {
"Qwen3.8-27B-oQ6e-mtp": {
"reasoning": true,
"limit": { "context": 262144, "output": 262144 },
"variants": {
"low": { "chat_template_kwargs": { "enable_thinking": true, "reasoning_effort": "low" } }
}
}
}
}
},
"model": "px/Qwen3.8-27B-oQ6e-mtp",
"agent": { "probe": { "model": "px/Qwen3.8-27B-oQ6e-mtp", "variant": "low" } }
}-
OPENCODE_CONFIG=<that file> opencode run --agent probe "hi" -
Look at the proxy log: the body has no
chat_template_kwargs.
Screenshot and/or share link
n/a — captured request bodies are inline above.
Operating System
macOS (Darwin 25.5.0), Apple Silicon
Terminal
n/a — reproduced headless with opencode run
Activity
github-actions commentedon Aug 16, 2026
This issue might be a duplicate of, or closely related to, existing issues. Please check:
) for @ai-sdk/openai-compatible provider#42300: Same root cause — variant body-level fields dropped before the HTTP request for@ai-sdk/openai-compatible(auto-closed for template non-compliance, not on merit). This report extends the analysis to@ai-sdk/anthropicand adds captured request-body evidence.If these are considered the same underlying issue, it may be worth reopening or linking #42300 rather than tracking it separately.
AnshulJ999 commentedon Aug 30, 2026
Encountered the same issue (#46314) and is breaking effort levels for me. Effort levels are basically a no-op until this gets fixed; every model defaults to provider-set default effort.
thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊
huornlmj commentedon Oct 27, 2026
But v2 is a hugely sub-par compared to v1. I've tried v2 and it's a show stopper in the new bugs it brings, so moving to v2 isn't a solution to this.
Using opencode 1.18.35 and local qwen3.8:27b, trying to control reasoning via variant yields:
but it needs to actually be the following for qwen3.8:27b: