anomalyco / anomalyco/opencode
opencode-go: spurious low/medium/high reasoning variants for MiMo V2.5 / Hy3; inconsistent with Kimi/Grok
@neriousy is already working on this.
Since Aug 20, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- Avg merge
- 7h 2m
- Merged PRs (30d)
- 384
Description
Summary
OpenCode Go (opencode-go) models show an inconsistent and often inaccurate variant/thinking selector in /models. Several models offer effort levels their catalog says they don't support, several show sets that don't match their declared reasoning_options, and a couple show no selector at all. Which set appears depends on whether a model's catalog entry carries reasoning_options (and which generator resolves it), so the same model behaves differently across installs/snapshots.
Reproduced against the OpenCode TUI (/models → provider OpenCode Go):
| Model | Declared reasoning_options (models.opencode.ai) |
Variant selector shown |
|---|---|---|
mimo-v2.5 |
[] (no effort control) |
low / medium / high |
mimo-v2.5-pro |
[] (no effort control) |
low / medium / high |
hy3 |
effort: [none, low, high] |
low / medium / high |
deepseek-v4-pro |
effort: [high, max] |
default + low / medium / high / max |
deepseek-v4-flash |
effort: [low, high, max] |
low / medium / high / max |
gpt-5.6-luna |
effort: [none, low, medium, high, xhigh, max] |
none / low / medium / high / xhigh |
minimax-m3 |
toggle |
none / thinking (toggle) |
kimi-k3 |
effort: [max] |
(no selector) |
grok-4.5 |
effort: [low, medium, high] |
(no selector) |
Steps to reproduce:
- Open the OpenCode TUI.
- Run
/models, start a session, and selectOpenCode Go. - Pick e.g.
deepseek-v4-proormimo-v2.5→ the model selector asks for a variant (low/medium/high/…). - Pick
grok-4.5orkimi-k3→ no variant selector at all.
Root cause
A model's variants come from two independent generators, and which one is used depends on the catalog's reasoning_options for that model:
packages/opencode/src/provider/provider.ts (fromModelsDevModel):
const variants = ProviderTransform.reasoningVariants(model, base) ?? ProviderTransform.variants(base)
reasoningVariants(...)is catalog-driven. It returnsundefinedwhenmodel.reasoning_optionsis absent,{}when it is[], and effort/toggle/budget variants when declared.- The
??falls through to the generic transport heuristicvariants(...)only whenreasoning_optionsis absent/undefined. That heuristic emits its own effort sets by transport + model id (e.g.@ai-sdk/openai-compatible→WIDELY_SUPPORTED_EFFORTS+maxfordeepseek-v4,@ai-sdk/openai→openaiReasoningEfforts(...)), and hard-excludes some families (deepseek-chat/reasoner/r1/v3,minimax, GLM≠5.2,kimi,qwen, …) →{}.mimo-*andhy3are not on that list.
packages/opencode/src/provider/provider.ts (registry loop):
if (model.variants === undefined) {
model.variants = mapValues(ProviderTransform.variants(model), (v) => v)
}
Effect: whether a selector appears (and which options it has) depends on whether the catalog omits reasoning_options (undefined, → heuristic, → spurious/wrong sets) vs. explicitly sets [] (→ suppressed). Both mean "no declared effort control", but they resolve differently.
Why this is wrong
- Sets don't match declarations — e.g.
deepseek-v4-prodeclares[high, max]but the TUI offerslow/medium/high/max;gpt-5.6-lunadeclares amaxit never shows. These are the heuristic's sets, not the model's. mimo-v2.5/mimo-v2.5-proare always-on reasoning (interleaved: { field: "reasoning_content" }) withreasoning_options: []; offeringlow/medium/highsends areasoningEffortthe model doesn't honor — inert/misleading.- Inconsistency:
minimax-m3(declaredtoggle) correctly gets anone/thinkingtoggle, whilehy3(declared[none,low,high]) showslow/medium/high, andkimi-k3/grok-4.5(declared effort sets) show nothing. - Data-version dependent: the observed sets imply the running build resolved many models through the heuristic fallback (their
reasoning_optionswas absent), while the currentmodels.opencode.aicatalog would suppress some of them. The same model behaves differently across installs/snapshots.
Expected behavior
- A model should expose effort/toggle/budget variants only from what it declares in
reasoning_options(thereasoningVariantspath). - The generic heuristic
variants()should not injectlow/medium/highfor models that declare no effort control — absentreasoning_optionsshould behave like[](no selector) rather than triggering the fallback, or the fallback should consult declared capabilities so returned sets always match the model.
Environment
- OpenCode (opencode-go provider), model catalog sourced from
https://models.opencode.ai/api.json - TUI
/modelsmodel + variant selection flow
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.