EffortNEW
Choose how hard a model thinks before it answers. Levels, Auto, where to set it, what each reply shows, and what Sophon sends to each provider.
New in 2.2. Effort sets how hard a model thinks before it answers. It replaces the Thinking setting of v2.1.x (Auto, Off, Fast, Full). A higher level gives the model more room to reason, and costs more output tokens and more time. Effort is set next to the model, in the same layers as model routing: per chat, per agent, per user and per host. Every reply shows the level it ran at and why.
The provider behaviour on this page describes what Sophon sends for each level. It is covered by request-body tests and has not yet been run against every provider's live API. How a model uses its level, and whether a higher level gives a better answer, is up to the model.
Levels
| Level | CLI and API value | Meant for |
|---|---|---|
| Auto | auto | Let Sophon choose Low, Medium or High for each turn. The default. |
| Low | low | Quick answers, small talk, routine automation |
| Medium | medium | Everyday chat and agent work |
| High | high | Coding, research, multi-step tasks |
| Extra high | xhigh | Hard problems where the answer matters more than the cost |
| Max | max | The model's deepest setting |
A level is clamped to what the model accepts. If a model has no Extra high, Sophon uses the nearest level below it (or the model's lowest level). Levels a model does not accept are greyed out in the pickers. A model with no effort control shows "Not supported by <model>", and no level is sent or shown on its replies.
| Models | Levels they accept |
|---|---|
| Claude Opus 4.7 and later, every Claude 5.x model, Fable and Mythos | Low to Max |
| Claude Opus and Sonnet 4.6 | Low, Medium, High, Max (Extra high runs as High) |
| Claude 4.5, Haiku 4.5, 4.0/4.1 and 3.7 | Low to Max, sent as a thinking budget from Medium up; Low, and any call with tools, sends no thinking |
| OpenAI o3, o4-mini, GPT-5 to 5.3 (and 5.4 mini and nano) | Low to High |
| OpenAI GPT-5.4 and 5.5 | Low to Extra high |
| OpenAI GPT-5.6 and GPT-6 | Low to Max |
OpenAI -codex models | Low to High; Extra high on 5.4 and later and on -codex-max |
OpenAI -pro models | High only |
| Gemini 2.5, Gemini 3 and later | Low to High (gemini-3-pro-preview: Low and High) |
| OpenAI-compatible models | The levels in the routed model's catalog row; a custom endpoint with "effortWire" gets Low to High |
| Claude 3.5 and older, non-reasoning models, plugin model providers | None ("Not supported") |
A model Sophon knows nothing about (no catalog row and no provider rule) shows every level as "Clamped to the model". See Limits for what that means on the wire.
Auto
Auto picks one level per turn, keeps it for every model call of that turn (tool calls and a fallback model included), and may pick a different level on the next turn. It never makes an extra model call to decide. It starts from the kind of turn:
| Starts at | Turns |
|---|---|
| Low | Heartbeat, cron, webhook, voice and channel turns; utility and vision sub-agents |
| Medium | Interactive chat; Sophon's internal turns (workflows, canvas, MCP); other sub-agents and plan steps |
| High | Coding turns in a bound workspace; research sub-agents |
From there it goes up one step for a complex request, one step for code blocks, stack traces or long text (over 1,500 characters), and one step for attached documents or images. It goes down one step for short small talk or a short command such as "fix it", and never when something raised it.
Auto's ceiling. Auto stays between Low and Sophon:Models:EffortAutoCeiling, which defaults to high. Extra high and Max are used only when someone chooses them. An administrator can set the ceiling from low to max in config/appsettings.user.json; an unknown value reads as high, and a change needs no restart. No Dashboard screen or API route writes it.
Background calls that are not an agent turn get a fixed level whatever the layers say: Low for titles, agent routing, the home feed, insights, memory jobs, captions, document OCR and summaries, translation and compaction; Medium for plan generation and replans and for turning a document into a skill. Workflows' llm_prompt node and embeddings send no level and run at the model's own default.
Where to set it
Effort lives next to the model in the routing layers. The narrowest setting wins: a level sent with one message, then the chat, then the agent, then your default, then the host default, then Auto.
| Scope | Dashboard | CLI | Mobile |
|---|---|---|---|
| This chat | The Effort select in the inspector's Model section, and the Effort group in the model chip's menu | /effort <level> | The Effort chip (this screen only, sent with each message) |
| An agent | Agents → [agent] → Models | sophon agents models <id> --effort <level> | — |
| Your default | Settings → Models → Model roles & Auto, My default | /effort save | — |
| The host | Settings → Models → Model roles & Auto, Host default (admins) | — | — |
An explicit level (low to max) on a chat, agent, user or host applies to every turn that scope covers, unattended turns included, and an explicit level on a chat or agent also applies to its sub-agents, plan steps and heartbeat. A scope set to auto lets Auto choose. Clearing a scope (the Dashboard's Default or Inherit, /effort reset, or "effort": "inherit" over the API) hands the decision to the next layer.
Dashboard
The controls show only when the Gateway lists effort.v1 in GET /api/system/info.
- The chat. The inspector's Model section has an Effort select under the model, and the model chip above the composer has the same choices in its menu: Default, Auto, Low, Medium, High, Extra high and Max. Default clears the chat's own level and names what the chat runs on instead, for example "Default · High (your default)". The choice is stored with the conversation on the Gateway, so it survives a reload, shows on every device and carries to New chat. Changing the effort keeps the model, and changing the model keeps the effort.
- What the select offers. When one model answers the chat (a pinned model, or the default model), the levels it does not accept are greyed out. Under Auto routing the model can change per turn, so every level shows, marked "Clamped to the model".
- Above the chat. The host and My default cards in Settings → Models → Model roles & Auto, and an agent's Models tab, each have an Effort row. Reset to Default on My default also clears your default effort. The setup wizard's Models step has an Effort select that starts on "Keep as is".
The former Thinking section of the chat is gone, and the Dashboard no longer sends a level with each message.
CLI
Every form needs a Gateway that lists effort.v1; an older one says so and nothing is written.
/effort # this chat's effort, where it comes from, and what the model accepts
/effort high # set this chat's level: auto | low | medium | high | xhigh | max
/effort reset # clear it; the agent's, your or the host's level applies again
/effort save # make this chat's level your default effort- Bare
/effortopens a choice list on the classic and pinned surfaces, with the levels the chat's model does not accept greyed out. On the full-screen surface it opens the/modeloverlay on its Effort row, whereesteps to the next accepted level andxclears the chat's own level. Where no list can be shown (redirected input or output, a screen reader,SOPHON_CLI_ACCESSIBLE=1) it prints the effort. - At launch.
sophon -e high,sophon chat -e maxandsophon exec -e low "…"(--effort; a level,autoorinherit) set the chat's own level as it starts. - For chats this CLI creates.
sophon config set defaultEffort highstores a default incli.json. It never applies to a resumed session, and-ewins over it. /model savesaves the model routing without the effort.sophon models roles --resetandsophon agents models --resetclear the stored effort with the rest.
See Interactive Chat for how the level shows in the full-screen footer and /context.
Mobile
The chat screen's header has an Effort chip where the Thinking chip was, shown only when the Gateway lists effort.v1. It starts on "Effort: Default", which sends nothing, so the chat's, agent's or your default effort applies (else Auto). Tapping it opens Default, Auto, Low, Medium, High, Extra high and Max. A pick shows as "Effort: high (this device)" and is sent with each message from that screen, so it outranks the chat's stored effort for those messages. It is not stored: leaving the screen returns it to Default.
API
- Every routing layer carries
effortnext to the model:PUT /api/sessions/{id}/model-routing(and the hub'sSetSessionModelRouting),PUT /api/agents/{id}/model-routing,PUT /api/preferences/model-routingandPUT /api/models/routing-defaults. - A write without
effort(or withnull) keeps the stored level, so an older client never erases it."inherit"clears it;auto,low,medium,high,xhighandmaxset it; anything else is refused withinvalid_argument. - The host's level is
Sophon:Models:Routing:Effort. Saving the host defaults never touchesSophon:Models:EffortAutoCeiling. GET /api/models/candidateslists each model'seffortLevels([]with no effort control) andeffortUnknown.- The agent tools (
agent.create,agent.update) cannot set an agent's effort.
What each reply shows
| Surface | Shows |
|---|---|
| Dashboard | Effort: Auto · high when Auto chose it, else the level and who set it: Effort: max (chat), Effort: high (agent), Effort: medium (your default), Effort: low (host default) or Effort: low (this message) |
| CLI | ▲ auto·high or ▲ max at the end of the reply's route ([effort auto.high] without Unicode) |
| Mobile | Nothing yet |
| Hub and REST clients | routing.effort and routing.effortSource on the final StreamChunk, TaskCompleted, TaskFailed, AgentActivity and the stored reply |
| Headless runs | effort and effortSource on message.completed and turn.completed |
The level shown is the one the answering model applied, after clamping. Nothing is shown when no level was sent. The "Thinking…" trace under a reply is the model's own reasoning summary, not this setting, and keeps its name.
Provider support
| Provider | What Sophon sends |
|---|---|
| Anthropic and Claude subscription | Opus 4.7 and later, every 5.x model, Fable and Mythos: adaptive thinking with an effort level, also with tools; a tool reply's thinking is sent back unchanged inside the tool loop. Models with per-message effort carry each turn's level as its own entry, so a level that changes between turns keeps the prompt cache. 4.6: the same, without Extra high. Older models: a thinking budget per level (4,096 to 32,000 tokens), none at Low or with tools. No temperature while the model thinks. Since v2.2.0 the Anthropic provider uses Anthropic's official .NET SDK. |
| OpenAI | GPT-5.5 and earlier, o3 and o4-mini: reasoning_effort on Chat Completions (no Max there). GPT-5.6, GPT-6 and the -pro and -codex models: the Responses API (POST /v1/responses) with reasoning.effort, Max included. |
| Azure OpenAI | Stays on Chat Completions. Sophon's built-in api-version (2024-08-01-preview) predates reasoning_effort, so Azure gets no level today, only the sampling change below. |
| Google Gemini | Gemini 3 and later: thinking_level (Low to High; Extra high and Max send High). Gemini 2.5: thinking_budget per level (Low turns thinking off on Flash and Flash-Lite and sends 128 on Pro, Medium 8,192, High and above 24,576). Never both fields. The request's temperature is still sent. |
| AWS Bedrock | Claude models only, mapped as for Anthropic and sent in Converse's additionalModelRequestFields, with no temperature while thinking. Other Bedrock models get the same request as in v2.1.2. |
| GitHub Copilot | Claude models: thinking and output_config.effort. GPT models: reasoning.effort. If the proxy refuses a request that carried these fields, Sophon sends it again without them and leaves them off that model until the Copilot token is next refreshed. |
| OpenAI Codex (ChatGPT subscription) | reasoning.effort, clamped as on OpenAI's Responses API (Max only on GPT-5.6 and GPT-6) |
Claude Code CLI (claude-code, claude-code-agent) | claude --effort <level>, when the installed CLI lists the flag. Sophon checks claude --help once an hour per CLI path; an older CLI gets no flag and runs at its own default. |
| OpenAI-compatible (xAI, DeepSeek, Mistral, Groq, Together, Fireworks, OpenRouter, Ollama, Moonshot, Zhipu, Qwen and the rest) | The field the model's catalog row names (reasoning_effort, reasoning: {effort}, thinking: {type}, enable_thinking or chat_template_kwargs: {enable_thinking}), clamped to the row's levels. On/off models think from Medium up. Nothing is sent for a model with no row. DeepSeek with tools always runs with thinking off. |
Custom endpoints (custom-openai, LM Studio, vLLM and other servers without catalog rows) | Nothing, until the provider entry in ~/.sophon/config/models.json sets "effortWire": reasoning_effort, reasoning.effort, thinking.type, enable_thinking or chat_template_kwargs. Its models then get Low to High (Extra high and Max send High). "effortWire": "none" turns every effort field off for a server that rejects them. Edit the file and restart. |
| Plugin model providers | Not supported in v2.2.0 |
{
"id": "custom-openai-1a2b3c",
"name": "vLLM box",
"providerType": "custom-openai",
"endpoint": "http://localhost:8000/v1",
"effortWire": "reasoning_effort"
}Reasoning models no longer get a temperature. Every OpenAI and Azure OpenAI reasoning model (o-series, GPT-5.x, GPT-6) now receives no temperature or top_p and gets max_completion_tokens instead of max_tokens, with or without a level. A model or agent temperature setting applies only to non-reasoning models there. Claude models drop temperature whenever they think.
Cost and what changes on upgrade
Thinking and reasoning tokens are billed as output, so a higher level usually costs more and takes longer.
- Every agent turn now gets a level. In v2.1.x a turn without a Thinking pick sent nothing and ran at each model's own default. Now unattended turns (heartbeat, cron, webhook, voice, channels) and background calls run at Low, interactive chat at Medium, and coding turns in a bound workspace at High, one step up or down from the content. Models that did not think unless asked now think on some of those turns; models whose own default is higher think less on Low and Medium turns.
- The reply-length ceiling follows the level.
max_tokensis 16K up to Medium, 32K at High and 64K at Extra high and Max, never above the model's own limit. Above 16K applies only to streaming replies, and it is lowered toward 16K as a long conversation fills the context window. A ceiling is not a request, but a model that thinks by default may use the room. - Subscriptions. Copilot, Codex and the Claude Code CLI draw on their plan's limits, which a higher level uses faster.
- Holding it down. Set a lower level on the chat, agent, your default or the host, or lower
Sophon:Models:EffortAutoCeiling(for example tomedium) to cap Auto alone. Background calls keep their fixed levels either way.
Migrating from Thinking
Thinking was removed in v2.2.0. The old values map to Effort as off → Low, fast → Medium, full → High. Thinking's Auto sent nothing and maps to no level.
| v2.1.x | v2.2.0 |
|---|---|
| Dashboard chat: the Thinking section, reset on every reload | The Effort select in the model picker, stored with the conversation |
| Mobile: the Thinking chip | The Effort chip |
CLI: /thinking | /effort. /thinking now answers "replaced by /effort". |
CLI: sophon exec --thinking | -e / --effort on sophon, sophon chat and sophon exec. --thinking exits 1 and names --effort. |
cli.json defaultThinking | defaultEffort. An existing defaultThinking is read as its level until sophon config set defaultEffort replaces it. |
Hub SendMessage / SendMessageWithAttachments: the Thinking string | The same string slot now carries an effort value. off, fast and full are still accepted; an unknown value is refused with EFFORT_INVALID. |
Webhook, cron and plugin-channel metadata thinking | Not read. An effort key in that metadata is stripped. |
In-process code: LlmRequest.Thinking | LlmRequest.Effort |
Upgrade every client. A v2.1.x CLI whose defaultThinking is off, fast or full, and an explicit Thinking pick in a v2.1.x Dashboard or Mobile app, send that level with every message. A per-message level outranks the chat, agent, user and host effort until the client is upgraded. A Dashboard or Mobile app that does not see effort.v1 (one newer than its Gateway) shows neither Thinking nor Effort.
Limits
- Not verified live. The provider wires above are pinned by request-body tests. The owner's live run against each provider has not been done yet.
- Auto chooses once per turn. It never raises the level within a turn, for example after a failed tool call.
- Azure OpenAI gets no level today, while the reply still shows one.
- Unknown models can show a level that was not sent. A model nothing knows keeps the turn's level and its reply shows it, but an OpenAI-compatible provider without
effortWire(Ollama, LM Studio,custom-openai) and a Gemini id with no known family send no effort field for it. - Hand-written catalog rows. A
models-catalog.jsonrow without aneffortblock, for a provider type with no built-in effort rule, reads as a model with no effort control. - Copilot can drop the level silently when its proxy refuses the effort fields (see the table above).
- No cross-turn reasoning replay for DeepSeek, Kimi k3 and OpenRouter: DeepSeek with tools runs with thinking off, and on OpenRouter a model that does not think by default gets no level with tools.
- No OpenAI reasoning summary. OpenAI requests ask for no reasoning summary, so the "Thinking…" trace stays empty on OpenAI.
- No effort setting for Workflows'
llm_promptnode or for plugin model providers. - Mobile greys no levels, shows no level on replies, and cannot set the chat's, agent's, user's or host's effort.
- Dashboard and CLI grey levels by the orchestrator role's model only. The CLI's full-screen Effort row edits the chat's own level only.
Related
- Routing, Failover & Budgets: the layers Effort rides on
- Supported Providers: provider ids, and where
effortWiregoes - Interactive Chat:
/effort, the footer badge and/context - Mobile App: the Effort chip
- Insights: token and reasoning-token tracking