Feature: Automatic reasoning effort escalation (default + escalated levels)
Feature Request: Automatic reasoning effort escalation (default + escalated levels)
Problem
Reasoning models from multiple providers now expose a parameter to control how deeply the model thinks before responding. nanobot already supports this — reasoningEffort is a config field in agents.defaults and per-fallback-model entries in fallbackModels. But it's static: every request runs at that one configured level regardless of whether it's a trivial lookup or a complex analysis.
The cost implication is real. Running at max effort on a simple question wastes tokens and adds latency with no quality benefit. Running at low effort on a complex task degrades output. There's no way for the agent to adjust effort per request.
Proposal: Two-level escalation
Keep it simple. Instead of trying to map every provider's full set of effort levels, define just two per model:
- Default effort — what the agent normally runs at (the existing
reasoningEffortfield) - Escalated effort — what the agent switches to when it decides the task needs deeper reasoning
One new field in config:
{
"agents": {
"defaults": {
"reasoningEffort": "high",
"reasoningEffortEscalated": "max"
}
}
}
The agent defaults to reasoningEffort for normal requests and escalates to reasoningEffortEscalated when it evaluates the task as needing more. No manual switching, no slash commands — the model itself decides when to escalate.
This sidesteps the problem that providers have non-uniform level sets:
| Provider | Parameter | Example default → escalated |
|---|---|---|
| OpenAI (GPT-5.4) | reasoning_effort |
low → high |
| Anthropic (Claude Opus 4.6) | effort |
medium → max |
| Google (Gemini 3.x) | thinking_level |
low → high |
| Z.ai (GLM-5.2) | reasoning_effort |
high → max |
The user picks the two values based on whatever their model supports. nanobot doesn't need to know the full level set — just the two endpoints.
How escalation would work
The agent loop makes a quick complexity assessment (either via a lightweight pre-pass or the model's own judgment on the first turn) and uses the escalated level for the actual response call when the task demands it. A quick lookup stays at default; a complex debugging task or long-form research generation escalates.
Most requests don't need deep reasoning — defaulting low and escalating only when needed is the real cost-saver. The agent decides; the user doesn't have to.
Why this matters now
Reasoning effort is becoming a standard API feature across providers. Claude has had effort levels since Opus 4.5/4.6 (replacing budget_tokens). GLM-5.2 shipped with two thinking effort levels (high and max). Gemini 3.x supports low/medium/high via thinking_level. Open models are adopting the pattern too. nanobot's multi-provider architecture is well-positioned to abstract over the differences — and two-level escalation is the simplest way to do it without over-engineering.
Related
- Discussion #409 — Runtime reasoning effort control via Telegram commands (community interest already exists)
- Issue #1530 — Per-message model routing with @prefix (related — that's about dynamic model selection, which nanobot also lacks; this is about effort within a model)
Use case
I run a personal assistant agent on nanobot that handles everything from quick lookups to long-form research generation. The quick lookups don't need deep reasoning — they're paying for tokens that add latency with no quality benefit. The research tasks do. Right now I can define an effort level in config, but it's static — every request runs at that one setting regardless of whether it's a trivial lookup or a complex research task. Two-level automatic escalation would let the agent default to a cheaper/faster effort level and escalate only when the task actually demands it.
Source: HKUDS/nanobot