anomalyco / anomalyco/opencode

[Bug] Variant body-level fields (e.g. chat_template_kwargs) are dropped before the request

Open
#42,876 2 comments 2 reactions 1 assignee View on GitHub

@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
  1. Start any OpenAI/Anthropic-compatible server that accepts extra body fields. I used oMLX serving Qwen3.8-27B on 127.0.0.1:8001.

  2. 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.

  3. 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" } }
}
  1. OPENCODE_CONFIG=<that file> opencode run --agent probe "hi"

  2. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.