anomalyco / anomalyco/opencode
[Bug] Variant body-level fields (e.g. chat_template_kwargs) are dropped before the request
@jlongster is already working on this.
Since Aug 16, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.