You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG]: (Incorrect) sampling parameters are hard-coded based on model name/id #42775
opencode automatically adds sampling parameters to chat requests for some model names/ids, even if not configured to do so.
I think that opencode should not be doing this, or there should be a way to opt-out, or it should be changed to an opt-in setting.
The defaults are defined in:
packages/opencode/src/provider/transform.ts
Specifically:
ProviderTransform.temperature()
ProviderTransform.topP()
ProviderTransform.topK()
They are applied in:
packages/opencode/src/session/llm/request.ts
The checks use substring matches against the model name/id (lowercased)
Current defaults include:
Model IDs containing north-mini-code: temperature 1.0
Model IDs containing qwen: temperature 0.55, top_p 1.0
Matching Gemini 2.5, Gemini 3 Flash/Pro, Gemini 3.1, and Gemini 3.5 Flash models: temperature 1.0, top_p 0.95, top_k 64
Model IDs containing glm-4.6 or glm-4.7: temperature 1.0
Model IDs containing minimax-m2: temperature 1.0, top_p 0.95, top_k 20 or 40
Model IDs containing kimi-k2: temperature 0.6 or 1.0
Kimi K2.5 variants: top_p 0.95
DeepSeek V4 Flash models: top_p 0.95 in specific cases
I discovered this when running Qwen 3.8 27B locally in llama.cpp and pointing my opencode config at it. The recommended setting for Qwen 3.8 is top-p 0.95, which is being overridden by these automatically generated sampling parameters. (I specify temperature and top-p settings in llama.cpp for the model)
This means i need to also set top_p in opencode config to work around this hardcoded value.
Plugins
none
OpenCode version
1.18.18
Steps to reproduce
Configure a single local OpenAI-compatible Qwen model:
Confirming this on a second adapter, with the request body captured off the wire.
Setup: Qwen3.8-27B served locally by oMLX (Anthropic-compatible /v1/messages), provider declared with "npm": "@ai-sdk/anthropic", opencode 1.18.18. I put a logging reverse proxy between opencode and the server to see the real body rather than infer it.
Captured request body (agent had "temperature": 0.33, "top_p": 0.77 configured):
top_p: 1 comes from the substring match in ProviderTransform.topP() (transform.ts:550, if (id.includes("qwen")) return 1). Same as reported, so this is not specific to @ai-sdk/openai-compatible.
Two things I ran into that might be worth folding into whatever opt-out lands:
1. The documented workaround does not cover temperature for custom providers. Setting top_p on the agent does win (request.ts:127), but temperature is gated:
and capabilities.temperature defaults to false for user-declared models (provider.ts:1461, model.temperature ?? existingModel?.capabilities.temperature ?? false). So for a locally-declared model, agent-level temperature is silently dropped unless the model entry also sets "temperature": true. That took a packet capture to find — a config-level no-op with no warning.
2. topK has no user override at all. Note the asymmetry at request.ts:127-128:
AgentConfig exposes temperature and top_p but not top_k, so when ProviderTransform.topK() does return a value there is no way to override it from config. It does not bite Qwen today (topK() returns undefined for it), but it would for any model matching the minimax-m2 or gemini branches.
I appreciate this may interact with the v2 direction in specs/v2/config.md ("Do not retain dedicated agent temperature or top_p fields", with agent-local options carrying body overrides instead) — in which case an options.body passthrough would address all three at once. Happy to help test whichever shape you settle on.
Activity
d9beuD commentedon Aug 15, 2026
Confirming this on a second adapter, with the request body captured off the wire.
Setup: Qwen3.8-27B served locally by oMLX (Anthropic-compatible
/v1/messages), provider declared with"npm": "@ai-sdk/anthropic", opencode1.18.18. I put a logging reverse proxy between opencode and the server to see the real body rather than infer it.Captured request body (agent had
"temperature": 0.33, "top_p": 0.77configured):{ "model": "Qwen3.8-27B-oQ6e-mtp", "max_tokens": 32000, "top_p": 1, "stream": true, "tool_choice": { "type": "auto" } }top_p: 1comes from the substring match inProviderTransform.topP()(transform.ts:550,if (id.includes("qwen")) return 1). Same as reported, so this is not specific to@ai-sdk/openai-compatible.Two things I ran into that might be worth folding into whatever opt-out lands:
1. The documented workaround does not cover
temperaturefor custom providers. Settingtop_pon the agent does win (request.ts:127), buttemperatureis gated:and
capabilities.temperaturedefaults tofalsefor user-declared models (provider.ts:1461,model.temperature ?? existingModel?.capabilities.temperature ?? false). So for a locally-declared model, agent-leveltemperatureis silently dropped unless the model entry also sets"temperature": true. That took a packet capture to find — a config-level no-op with no warning.2.
topKhas no user override at all. Note the asymmetry atrequest.ts:127-128:AgentConfigexposestemperatureandtop_pbut nottop_k, so whenProviderTransform.topK()does return a value there is no way to override it from config. It does not bite Qwen today (topK()returnsundefinedfor it), but it would for any model matching theminimax-m2orgeminibranches.I appreciate this may interact with the v2 direction in
specs/v2/config.md("Do not retain dedicated agenttemperatureortop_pfields", with agent-localoptionscarryingbodyoverrides instead) — in which case anoptions.bodypassthrough would address all three at once. Happy to help test whichever shape you settle on.vektorprime commentedon Aug 18, 2026
FYI this works in the config so the top p 1.0 gets overridden with what you have in the model config (in opencode's json file)
"Qwen3.8-27B": {
"name": "Qwen3.8-27B",
"reasoning": true,
"tool_call": true,
"options": {
"top_p": 0.95
},
"limit": {
"context": 260000,
"output": 128535
}
},