---
title: Per-model thinking level (a default reasoning level per model)
---

# Per-model thinking level (a default reasoning level for each model)

## What it is

**One-paragraph answer:** "Per-model thinking level" is a setting (**Settings → Session**, just under the single **Thinking Level**) that lets you give **each model its own default reasoning/effort level** — e.g. Opus → **Max**, Haiku → **Low**, Codex GPT-5.5 → **High** — so every new session inherits the right level based on _which model it uses_, without you setting it by hand each time. It's a **supplement**, not a replacement: any model left on **"Inherit default"** falls back to your single Thinking Level (for Claude) or the model's own default (for Codex), so nothing changes until you customize a model. It covers **every engine that has a reasoning knob** — today Claude and Codex — and your per-session and per-project choices always win over it.

## Where to find it

### Where to find it

- **Settings → Session → "Per-model thinking level"** (the card directly below **Thinking Level**).
- It lists one row per **current** model of each engine that exposes a reasoning knob: Claude (Fable 5.1 / Fable 5 / Opus 5.5 / Opus 5 / Sonnet 5.5 / Sonnet 5 / Haiku 4.5) and Codex (GPT-6.1 Sol / GPT-6 Astra / GPT-6 Sol / GPT-6 Luna / GPT-5.6 Sol / GPT-5.6 Terra / GPT-5.6 Luna / GPT-5.5). Legacy Claude versions aren't listed here (you can still override them per-session).
- Each row is a dropdown: **"Inherit default (…)"** plus that engine's own levels — Claude offers Auto / Low / Medium / High / Max; Codex offers Minimal / Low / Medium / High.
- Searchable in the Settings search bar as **"per-model thinking level"** (also "per model", "reasoning", the model names).
- **Or set one model at a time from a fresh session** — pick a non-default thinking level, then open the **Thinking** pill's dropdown: below the level list sits a small **defaults editor** with one row per scope — **This model**, **All (engine) sessions** / **All (harness) sessions** (named for the actual engine / harness), **Only this project**, and **Everywhere** (Claude's flat level). Each row shows what it's currently set to, tags the one that's **actually in effect** (and marks any outranked row **"Overridden above"**), and gives you **Set / Change / Clear** — so **This model** writes _that model's_ per-model default (this same map), the quick way to set the level for the model you're looking at, and you can save at whatever breadth you want. See [start-a-new-session.md](start-a-new-session.md).

## How it behaves

### Why it exists

Different models have different sweet spots. Opus benefits from maximum reasoning; Haiku is meant to be fast, so heavy thinking is wasted on it; Codex has its own effort scale. Before this, Omniscio had **one** thinking level for all Claude sessions, so you had to override thinking by hand whenever you switched models. Now you set it once per model and forget it.

### "Inherit default" vs "Auto" — they're different

- **Inherit default** removes the model's own setting, so it falls back down the chain (to your single Thinking Level for Claude, or the model's own default for Codex). Pick this to un-customize a model.
- **Auto** (Claude only) is an _explicit_ choice that pins the model to the _model's own_ default reasoning — it ignores your single global Thinking Level. Pick this when you specifically want "let the model decide" for that model even though your global default is, say, Max.

### What wins (precedence)

`your per-session pick → the project's default → the per-model default → the per-provider default → the per-harness default → your single global Thinking Level`

The per-model default only fills in when you haven't chosen something more specific for that session or project. A per-project thinking default (set in Edit Project, or via the fresh-session Thinking **defaults editor**'s **Only this project** row) still wins over all of the per-model / per-provider / per-harness defaults, because a project setting is the narrower, more deliberate scope. The per-provider and per-harness layers (set from that same defaults editor) sit just under the per-model default and above your single global Thinking Level.

### Both engines, and the safety net

- **Claude** sessions read the level through `CLAUDE_CODE_EFFORT_LEVEL`. The per-model default folds into the "global" slot alongside the newer **per-provider** and **per-harness** defaults — the order inside that slot is per-model → per-provider → per-harness → your single Thinking Level — and the whole fold still loses to a session/project pick.
- **Codex** sessions read it through their `model_reasoning_effort` config. Codex has no single global thinking level of its own, so the per-model default is simply its lowest layer (session → project → per-model).
- **Validation:** each engine only offers levels it actually supports, and the resolver **re-validates** at read time — so a Claude-only level like `Max` can never leak onto a Codex model, and a Codex-only level like `Minimal` can never leak onto a Claude model. An invalid or stale entry is silently dropped, never sent to a session.

### What is never affected

Engines with no reasoning knob (Gemini, DeepSeek, Kimi, GLM, MiniMax, Meta, Grok, Cursor, OpenCode, Pi, Anti-Gravity, Hermes) don't appear here and are unaffected — Cursor bakes effort into the model id, and the rest expose no effort control. Existing installs are unchanged until you set a per-model level (the setting starts empty), so there's no migration and no surprise.

## For agents

### For agents with repo access — where this lives

- Setting: `modelDefaultThinkingLevels` (a `modelId → level` map, default `{}`) — plus the sibling conditional-thinking maps `providerDefaultThinkingLevels` (`providerId → level`) and `harnessDefaultThinkingLevels` (`toolId → level`), both default `{}` — in `AppSettings`, schema in [src/shared/types/settings/accounts-providers-settings.ts](../../src/shared/types/settings/accounts-providers-settings.ts).
- Resolution: [src/shared/providers/provider-default-model.ts](../../src/shared/providers/provider-default-model.ts) — `getModelDefaultEffort` / `getProviderDefaultThinking` / `getHarnessDefaultThinking` (the validated per-scope lookups) and `resolveModelGlobalThinking` (the one shared fold — per-model → per-provider → per-harness → flat-global — that the spawn and the chip both read, so the pill can't drift from what launches; `toolIdForProvider` in [tool-grouping.ts](../../src/shared/providers/tool-grouping.ts) keys the harness layer). Effort-capable engines come from `providersWithReasoningEffort` in [src/shared/providers/provider-models.ts](../../src/shared/providers/provider-models.ts).
- Claude spawn: `resolveSpawnThinking` in [src/main/process/spawn-build.ts](../../src/main/process/spawn-build.ts) (takes the resolved model, folds the per-model default into the global slot; the model param is required so every spawn path — local / SSH / aside — supplies it). Codex spawn: `ensureStarted` in [src/main/services/engines/codex-session-manager.ts](../../src/main/services/engines/codex-session-manager.ts).
- UI: the `PerModelThinkingSection` card in [src/renderer/src/features/settings/sections/session/SessionSettings.tsx](../../src/renderer/src/features/settings/sections/session/SessionSettings.tsx) writes the map, as does the fresh-session **"Save as default" banner** ([SetDefaultHint](../../src/renderer/src/features/sessions/SetDefaultHints.tsx), rendered below the Model/Thinking pickers) — **This model** via `buildModelDefaultThinkingPatch`, **This provider** / **This harness** via `buildProviderDefaultThinkingPatch` / `buildHarnessDefaultThinkingPatch`, **This project** / **Everywhere** via the project + flat writers — wired in [src/renderer/src/features/sessions/SessionModelThinkingChips.tsx](../../src/renderer/src/features/sessions/SessionModelThinkingChips.tsx); the chip also shows a **Project / Session source badge**, and reads the same resolver there; search entry in [src/renderer/src/features/settings/SessionsSettings-search.ts](../../src/renderer/src/features/settings/SessionsSettings-search.ts).
- Contract: [.claude/memory/contracts/provider-registry-contract.md](../../.claude/memory/contracts/provider-registry-contract.md) (PART 3, invariant **the-per-model-effort-default-is-validated**) + [start-config-staging-contract.md](../../.claude/memory/contracts/start-config-staging-contract.md) (**`set-default-hint-is-the-one-surface`** — `SetDefaultHint` is the one surface for a Model/Thinking default; the per-level editor `superseded-per-level-editor` introduced is retired).
- Tests: [tests/unit/shared/provider-default-model.test.ts](../../tests/unit/shared/provider-default-model.test.ts), [tests/unit/process/spawn-build.test.ts](../../tests/unit/process/spawn-build.test.ts), [tests/unit/codex-session-manager.test.ts](../../tests/unit/codex-session-manager.test.ts), [tests/unit/features/settings/per-model-thinking-section.test.tsx](../../tests/unit/features/settings/per-model-thinking-section.test.tsx).

## Related

- [model-vendors.md](model-vendors.md) — who pays for a non-Claude session and which company serves it, the other choice Settings makes for you without changing the model.
- [ai-providers.md](ai-providers.md) — the models and engines this setting covers.
- [per-window-zoom.md](per-window-zoom.md) — another per-scope default that stacks with a global one.

