Skip to content

5.21 Thinking Depth Configuration

Treat "thinking depth" like gears: shallow for speed, deep for stability.

What You'll Learn

  • Set thinking budget for individual models
  • Understand how the "variants" mechanism controls thinking depth
  • Use Ctrl+T to switch between different thinking depths

Your Current Dilemma

  • Same model, sometimes you want fast, sometimes deep, but don't know how to switch
  • After writing config in opencode.json, unsure if it took effect
  • When using relay/proxy models, unsure if you can still control thinking depth

When to Use This

  • When you need: make "thinking depth" a switchable gear
  • And don't want: change models or modify config every time

🎒 Before You Start


Core Concept

  1. OpenCode uses model variants to save different thinking depths
  2. Variants are model-level configurations with higher priority than defaults
  3. Ctrl+T cycles through variants

ℹ️ What is "Thinking Depth"?

It refers to the model's "available thinking budget", such as Anthropic's thinking.budgetTokens. Higher values mean more tokens available for reasoning, but slower response and higher cost.


Follow Along

Step 1: Confirm Model Supports Thinking Variants

Why Not all models have variants, OpenCode checks capabilities.reasoning first.

How Choose a model that supports reasoning (e.g., Anthropic / Gemini 3 / OpenAI).

You Should See Variants like high / max appear in the model list.


Step 2: Set Thinking Budget for Individual Models in opencode.json

Why Variant config goes under provider.models.[modelID].variants, which can override defaults.

How Fill in the corresponding fields based on your Provider:

Anthropic Example (thinking.budgetTokens)

jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "anthropic": {
      "models": {
        "claude-sonnet-4-5": {
          "variants": {
            "high": {
              "thinking": { "type": "enabled", "budgetTokens": 20000 }
            },
            "max": {
              "thinking": { "type": "enabled", "budgetTokens": 32000 }
            }
          }
        }
      }
    }
  }
}

Gemini 3 Example (thinkingConfig.thinkingBudget)

jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "google": {
      "models": {
        "gemini-3-flash": {
          "variants": {
            "high": {
              "thinkingConfig": { "includeThoughts": true, "thinkingBudget": 16000 }
            },
            "max": {
              "thinkingConfig": { "includeThoughts": true, "thinkingBudget": 24576 }
            }
          }
        }
      }
    }
  }
}

You Should See Variant values take effect after restart.


Step 3: Switch Thinking Depths with Ctrl+T

Why After setting up variants, using a shortcut to switch is more convenient.

How Press Ctrl+T in the chat input box to cycle:

(none) → high → max → (none) → high → ...

You Should See Status bar shows current variant name (e.g., high).


Step 4: Customize Variant Names (Optional)

Why Variant names aren't fixed, you can change them to things like "Deep Think" / "Fast".

How Use custom keys in variants:

jsonc
{
  "provider": {
    "anthropic": {
      "models": {
        "claude-sonnet-4-5": {
          "variants": {
            "fast": { "thinking": { "type": "enabled", "budgetTokens": 8000 } },
            "deep": { "thinking": { "type": "enabled", "budgetTokens": 32000 } }
          }
        }
      }
    }
  }
}

You Should See Ctrl+T switches between "fast/deep".

ℹ️ Custom Variants Are "Added", Not "Replaced"

OpenCode merges the variants you write in opencode.json with default variants. If you only want custom variants, explicitly disable the default high/max:

jsonc
{
  "provider": {
    "anthropic": {
      "models": {
        "claude-sonnet-4-5": {
          "variants": {
            "high": { "disabled": true },
            "max": { "disabled": true },
            "fast": { "thinking": { "type": "enabled", "budgetTokens": 8000 } },
            "deep": { "thinking": { "type": "enabled", "budgetTokens": 32000 } }
          }
        }
      }
    }
  }
}

How to Configure Third-Party Relays

If your relay uses openai-compatible, it defaults to reasoningEffort. Example:

jsonc
{
  "provider": {
    "relay": {
      "options": {
        "baseURL": "https://your-relay.example.com/v1",
        "apiKey": "{env:RELAY_API_KEY}"
      },
      "models": {
        "gpt-5": {
          "variants": {
            "low": { "reasoningEffort": "low" },
            "high": { "reasoningEffort": "high" }
          }
        }
      }
    }
  }
}

If your relay actually forwards to Anthropic (still using openai-compatible SDK), you can directly override with Anthropic fields:

jsonc
{
  "provider": {
    "relay": {
      "options": {
        "baseURL": "https://your-relay.example.com/v1",
        "apiKey": "{env:RELAY_API_KEY}"
      },
      "models": {
        "claude-sonnet-4-5": {
          "variants": {
            "high": {
              "thinking": { "type": "enabled", "budgetTokens": 20000 }
            },
            "max": {
              "thinking": { "type": "enabled", "budgetTokens": 32000 }
            }
          }
        }
      }
    }
  }
}

Prerequisite: your relay server forwards the thinking field to Anthropic as-is.


Checklist ✅

  • [ ] opencode.json contains provider.models.[modelID].variants
  • [ ] Variant name appears in status bar after startup
  • [ ] Ctrl+T can cycle through variants

Common Issues

SymptomCauseSolution
Ctrl+T does nothingCurrent model has no variantsSwitch to a reasoning-capable model or add variants
Variants exist but don't showHaven't switched to a variant yetPress Ctrl+T once
Config doesn't take effectWrong model IDCopy complete ID from model list
Relay shows no changeUsing openai-compatible, only supports reasoningEffortManually override parameters in variants

Lesson Summary

You learned:

  1. Variants are "thinking depth gears", configured in provider.models.[modelID].variants
  2. Default variants are auto-generated by ProviderTransform, can be overridden by config
  3. Ctrl+T cycles through variants

Next Lesson Preview

Next we'll learn Debugging & Diagnostic Tools.

You'll learn:

  • How to use opencode debug commands
  • Diagnose LSP, config, and search issues
  • Analyze OpenCode like a developer

Appendix: Source Code Reference

Click to expand source code locations

Updated: 2026-01-16

FeatureFile PathLines
Variant generation entrysrc/provider/transform.ts297-477
Reasoning filter & exclusionsrc/provider/transform.ts298-301
Anthropic thinking budget defaultssrc/provider/transform.ts371-385
Gemini 3 thinking budget defaultssrc/provider/transform.ts421-439
Variant config Schemasrc/config/config.ts818-833
Variant config mergesrc/provider/provider.ts929-936
Ctrl+T default shortcutsrc/config/config.ts632-688
Ctrl+T command bindingsrc/cli/cmd/tui/app.tsx393-399
Variant cycling logicsrc/cli/cmd/tui/context/local.tsx310-346
Variant display logicsrc/cli/cmd/tui/component/prompt/index.tsx696-700
Variant name renderingsrc/cli/cmd/tui/component/prompt/index.tsx946-950
Variant applied to LLM paramssrc/session/llm.ts96-109
Variant keybind configsrc/config/config.ts632-688

Key Constants:

  • WIDELY_SUPPORTED_EFFORTS = ["low", "medium", "high"]
  • OPENAI_EFFORTS = ["none", "minimal", "low", "medium", "high", "xhigh"]