Skip to Content
Sophon Docs
Features

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

LevelCLI and API valueMeant for
AutoautoLet Sophon choose Low, Medium or High for each turn. The default.
LowlowQuick answers, small talk, routine automation
MediummediumEveryday chat and agent work
HighhighCoding, research, multi-step tasks
Extra highxhighHard problems where the answer matters more than the cost
MaxmaxThe 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.

ModelsLevels they accept
Claude Opus 4.7 and later, every Claude 5.x model, Fable and MythosLow to Max
Claude Opus and Sonnet 4.6Low, Medium, High, Max (Extra high runs as High)
Claude 4.5, Haiku 4.5, 4.0/4.1 and 3.7Low 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.5Low to Extra high
OpenAI GPT-5.6 and GPT-6Low to Max
OpenAI -codex modelsLow to High; Extra high on 5.4 and later and on -codex-max
OpenAI -pro modelsHigh only
Gemini 2.5, Gemini 3 and laterLow to High (gemini-3-pro-preview: Low and High)
OpenAI-compatible modelsThe 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 providersNone ("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 atTurns
LowHeartbeat, cron, webhook, voice and channel turns; utility and vision sub-agents
MediumInteractive chat; Sophon's internal turns (workflows, canvas, MCP); other sub-agents and plan steps
HighCoding 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.

ScopeDashboardCLIMobile
This chatThe 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 agentAgents → [agent] → Modelssophon agents models <id> --effort <level>—
Your defaultSettings → Models → Model roles & Auto, My default/effort save—
The hostSettings → 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 /effort opens 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 /model overlay on its Effort row, where e steps to the next accepted level and x clears 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 max and sophon exec -e low "…" (--effort; a level, auto or inherit) set the chat's own level as it starts.
  • For chats this CLI creates. sophon config set defaultEffort high stores a default in cli.json. It never applies to a resumed session, and -e wins over it.
  • /model save saves the model routing without the effort. sophon models roles --reset and sophon agents models --reset clear 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 effort next to the model: PUT /api/sessions/{id}/model-routing (and the hub's SetSessionModelRouting), PUT /api/agents/{id}/model-routing, PUT /api/preferences/model-routing and PUT /api/models/routing-defaults.
  • A write without effort (or with null) keeps the stored level, so an older client never erases it. "inherit" clears it; auto, low, medium, high, xhigh and max set it; anything else is refused with invalid_argument.
  • The host's level is Sophon:Models:Routing:Effort. Saving the host defaults never touches Sophon:Models:EffortAutoCeiling.
  • GET /api/models/candidates lists each model's effortLevels ([] with no effort control) and effortUnknown.
  • The agent tools (agent.create, agent.update) cannot set an agent's effort.

What each reply shows

SurfaceShows
DashboardEffort: 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)
MobileNothing yet
Hub and REST clientsrouting.effort and routing.effortSource on the final StreamChunk, TaskCompleted, TaskFailed, AgentActivity and the stored reply
Headless runseffort 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

ProviderWhat Sophon sends
Anthropic and Claude subscriptionOpus 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.
OpenAIGPT-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 OpenAIStays 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 GeminiGemini 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 BedrockClaude 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 CopilotClaude 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 providersNot 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_tokens is 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 to medium) 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.xv2.2.0
Dashboard chat: the Thinking section, reset on every reloadThe Effort select in the model picker, stored with the conversation
Mobile: the Thinking chipThe 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 defaultThinkingdefaultEffort. An existing defaultThinking is read as its level until sophon config set defaultEffort replaces it.
Hub SendMessage / SendMessageWithAttachments: the Thinking stringThe 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 thinkingNot read. An effort key in that metadata is stripped.
In-process code: LlmRequest.ThinkingLlmRequest.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.json row without an effort block, 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_prompt node 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.