Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions agent/anthropic_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def _get_anthropic_sdk():
# maps to low on every model. See:
# https://platform.claude.com/docs/en/about-claude/models/migration-guide
ADAPTIVE_EFFORT_MAP = {
"ultra": "max",
"max": "max",
"xhigh": "xhigh",
"high": "high",
Expand Down
24 changes: 19 additions & 5 deletions agent/transports/chat_completions.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@
from agent.transports.types import NormalizedResponse, ToolCall, Usage


def _reasoning_config_for_model(model: str, reasoning_config: dict | None) -> dict | None:
"""Return the model's wire-compatible reasoning config."""
if not isinstance(reasoning_config, dict):
return reasoning_config
if (
"gpt-5.6" in (model or "").lower()
and str(reasoning_config.get("effort") or "").strip().lower() == "ultra"
):
normalized = dict(reasoning_config)
normalized["effort"] = "max"
return normalized
return reasoning_config


def _build_gemini_thinking_config(model: str, reasoning_config: dict | None) -> dict | None:
"""Translate Hermes/OpenRouter-style reasoning config to Gemini thinkingConfig."""
if reasoning_config is None or not isinstance(reasoning_config, dict):
Expand Down Expand Up @@ -52,7 +66,7 @@ def _build_gemini_thinking_config(model: str, reasoning_config: dict | None) ->
if normalized_model.startswith("gemini-2.5-"):
return thinking_config

if effort not in {"minimal", "low", "medium", "high", "xhigh"}:
if effort not in {"minimal", "low", "medium", "high", "xhigh", "max", "ultra"}:
effort = "medium"

# Gemini 3 Flash documents low/medium/high thinking levels; Gemini 3 Pro
Expand All @@ -62,13 +76,13 @@ def _build_gemini_thinking_config(model: str, reasoning_config: dict | None) ->
if "flash" in normalized_model:
if effort in {"minimal", "low"}:
thinking_config["thinkingLevel"] = "low"
elif effort in {"high", "xhigh"}:
elif effort in {"high", "xhigh", "max", "ultra"}:
thinking_config["thinkingLevel"] = "high"
else:
thinking_config["thinkingLevel"] = "medium"
elif "pro" in normalized_model:
thinking_config["thinkingLevel"] = (
"high" if effort in {"high", "xhigh"} else "low"
"high" if effort in {"high", "xhigh", "max", "ultra"} else "low"
)

return thinking_config
Expand Down Expand Up @@ -364,7 +378,7 @@ def build_kwargs(
is_nvidia_nim = params.get("is_nvidia_nim", False)
is_kimi = params.get("is_kimi", False)
is_tokenhub = params.get("is_tokenhub", False)
reasoning_config = params.get("reasoning_config")
reasoning_config = _reasoning_config_for_model(model, params.get("reasoning_config"))

if ephemeral is not None and max_tokens_fn:
api_kwargs.update(max_tokens_fn(ephemeral))
Expand Down Expand Up @@ -563,7 +577,7 @@ def _build_kwargs_from_profile(self, profile, model, sanitized, tools, params):
api_kwargs["max_tokens"] = anthropic_max

# Provider-specific api_kwargs extras (reasoning_effort, metadata, etc.)
reasoning_config = params.get("reasoning_config")
reasoning_config = _reasoning_config_for_model(model, params.get("reasoning_config"))
extra_body_from_profile, top_level_from_profile = (
profile.build_api_kwargs_extras(
reasoning_config=reasoning_config,
Expand Down
6 changes: 6 additions & 0 deletions agent/transports/codex.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ def build_kwargs(
reasoning_effort = reasoning_config["effort"]

_effort_clamp = {"minimal": "low"}
if "gpt-5.6" in (model or "").lower():
# Ultra is the Codex product tier; the Responses API wire value is max.
_effort_clamp["ultra"] = "max"
if params.get("is_xai_responses", False):
# xAI Responses tops out at high; keep generic stronger values usable.
_effort_clamp.update({"xhigh": "high", "max": "high", "ultra": "high"})
reasoning_effort = _effort_clamp.get(reasoning_effort, reasoning_effort)

response_tools = _responses_tools(tools)
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/app/settings/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export const ENUM_OPTIONS: Record<string, string[]> = {
'approvals.mode': ['manual', 'smart', 'off'],
'code_execution.mode': ['project', 'strict'],
'context.engine': ['compressor', 'default', 'custom'],
'delegation.reasoning_effort': ['', 'minimal', 'low', 'medium', 'high', 'xhigh'],
'delegation.reasoning_effort': ['', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'ultra'],
'memory.provider': ['', 'builtin', 'hindsight', 'honcho'],
// Terminal execution backends — kept in sync with the dispatch ladder in
// tools/terminal_tool.py::_create_environment (local/docker/singularity/
Expand Down
6 changes: 3 additions & 3 deletions apps/desktop/src/app/settings/model-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export function ModelSettingsSkeleton() {

// Hermes' reasoning levels (VALID_REASONING_EFFORTS); `none` = thinking off.
// Empty config = Hermes default (medium), shown as Medium.
const EFFORT_VALUES = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh'] as const
const EFFORT_VALUES = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'ultra'] as const

// agent.service_tier stores "fast"/"priority"/"on" for fast; anything else is
// normal (mirrors tui_gateway _load_service_tier).
Expand All @@ -93,8 +93,8 @@ const isFastTier = (tier: unknown): boolean =>
.toLowerCase()
)

// Reuse the composer's effort labels (`xhigh` shows as "Max", else 1:1).
const effortLabelKey = (v: string) => (v === 'xhigh' ? 'max' : v) as 'high' | 'low' | 'max' | 'medium' | 'minimal'
// Reuse the composer's effort labels.
const effortLabelKey = (v: string) => v as 'high' | 'low' | 'max' | 'medium' | 'minimal' | 'ultra' | 'xhigh'

// A provider row is "ready" to pick a model from when it reports models. The
// backend now surfaces the full `hermes model` universe (every canonical
Expand Down
4 changes: 3 additions & 1 deletion apps/desktop/src/app/shell/model-edit-submenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ const EFFORT_OPTIONS = [
{ value: 'low', labelKey: 'low' },
{ value: 'medium', labelKey: 'medium' },
{ value: 'high', labelKey: 'high' },
{ value: 'xhigh', labelKey: 'max' }
{ value: 'xhigh', labelKey: 'xhigh' },
{ value: 'max', labelKey: 'max' },
{ value: 'ultra', labelKey: 'ultra' }
] as const

/** How "fast" is achieved for a given model — two different mechanisms:
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2036,7 +2036,9 @@ export const en: Translations = {
low: 'Low',
medium: 'Medium',
high: 'High',
xhigh: 'Extra High',
max: 'Max',
ultra: 'Ultra',
updateFailed: 'Model option update failed',
fastFailed: 'Fast mode update failed'
},
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1981,7 +1981,9 @@ export const ja = defineLocale({
low: '低',
medium: '中',
high: '高',
xhigh: '特高',
max: '最大',
ultra: 'ウルトラ',
updateFailed: 'モデルオプションの更新に失敗しました',
fastFailed: '高速モードの更新に失敗しました'
},
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/i18n/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1668,7 +1668,9 @@ export interface Translations {
low: string
medium: string
high: string
xhigh: string
max: string
ultra: string
updateFailed: string
fastFailed: string
}
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/i18n/zh-hant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1916,7 +1916,9 @@ export const zhHant = defineLocale({
low: '低',
medium: '中',
high: '高',
xhigh: '極高',
max: '最高',
ultra: '超高',
updateFailed: '模型選項更新失敗',
fastFailed: '快速模式更新失敗'
},
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2200,7 +2200,9 @@ export const zh: Translations = {
low: '低',
medium: '中',
high: '高',
xhigh: '极高',
max: '最高',
ultra: '超高',
updateFailed: '模型选项更新失败',
fastFailed: '快速模式更新失败'
},
Expand Down
4 changes: 3 additions & 1 deletion apps/desktop/src/lib/model-status-label.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ describe('model-status-label', () => {

it('maps reasoning effort to compact labels', () => {
expect(reasoningEffortLabel('high')).toBe('High')
expect(reasoningEffortLabel('xhigh')).toBe('Max')
expect(reasoningEffortLabel('xhigh')).toBe('XHigh')
expect(reasoningEffortLabel('max')).toBe('Max')
expect(reasoningEffortLabel('ultra')).toBe('Ultra')
expect(reasoningEffortLabel('')).toBe('')
})

Expand Down
4 changes: 3 additions & 1 deletion apps/desktop/src/lib/model-status-label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ const REASONING_LABELS: Record<string, string> = {
low: 'Low',
medium: 'Med',
high: 'High',
xhigh: 'Max'
xhigh: 'XHigh',
max: 'Max',
ultra: 'Ultra'
}

export function reasoningEffortLabel(effort: string): string {
Expand Down
4 changes: 2 additions & 2 deletions batch_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,7 @@ def main(
providers_order (str): Comma-separated list of OpenRouter providers to try in order (e.g. "anthropic,openai,google")
provider_sort (str): Sort providers by "price", "throughput", or "latency" (OpenRouter only)
max_tokens (int): Maximum tokens for model responses (optional, uses model default if not set)
reasoning_effort (str): OpenRouter reasoning effort level: "none", "minimal", "low", "medium", "high", "xhigh" (default: "medium")
reasoning_effort (str): Reasoning effort: "none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra" (default: "medium")
reasoning_disabled (bool): Completely disable reasoning/thinking tokens (default: False)
prefill_messages_file (str): Path to JSON file containing prefill messages (list of {role, content} dicts)
max_samples (int): Only process the first N samples from the dataset (optional, processes all if not set)
Expand Down Expand Up @@ -1261,7 +1261,7 @@ def main(
print("🧠 Reasoning: DISABLED (effort=none)")
elif reasoning_effort:
# Use specified effort level
valid_efforts = ["none", "minimal", "low", "medium", "high", "xhigh"]
valid_efforts = ["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"]
if reasoning_effort not in valid_efforts:
print(f"❌ Error: --reasoning_effort must be one of: {', '.join(valid_efforts)}")
return
Expand Down
2 changes: 1 addition & 1 deletion gateway/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4792,7 +4792,7 @@ def _load_reasoning_config() -> dict | None:
"""Load reasoning effort from config.yaml.

Reads agent.reasoning_effort from config.yaml. Valid: "none",
"minimal", "low", "medium", "high", "xhigh". Returns None to use
"minimal", "low", "medium", "high", "xhigh", "max", "ultra". Returns None to use
default (medium).
"""
from hermes_constants import parse_reasoning_effort
Expand Down
2 changes: 1 addition & 1 deletion gateway/slash_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2733,7 +2733,7 @@ def _save_config_key(key_path: str, value):
return t("gateway.reasoning.reset_done")
if effort == "none":
parsed = {"enabled": False}
elif effort in {"minimal", "low", "medium", "high", "xhigh"}:
elif effort in {"minimal", "low", "medium", "high", "xhigh", "max", "ultra"}:
parsed = {"enabled": True, "effort": effort}
else:
return t(
Expand Down
6 changes: 3 additions & 3 deletions hermes_cli/cli_commands_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2471,7 +2471,7 @@ def _handle_reasoning_command(self, cmd: str):

Usage:
/reasoning Show current effort level and display state
/reasoning <level> Set reasoning effort (none, minimal, low, medium, high, xhigh)
/reasoning <level> Set effort (none, minimal, low, medium, high, xhigh, max, ultra)
/reasoning show|on Show model thinking/reasoning in output
/reasoning hide|off Hide model thinking/reasoning from output
/reasoning full Show complete thinking (no 10-line clamp)
Expand All @@ -2493,7 +2493,7 @@ def _handle_reasoning_command(self, cmd: str):
full_state = "full" if getattr(self, "reasoning_full", False) else "clamped to 10 lines"
_cprint(f" {_ACCENT}Reasoning effort: {level}{_RST}")
_cprint(f" {_ACCENT}Reasoning display: {display_state} ({full_state}){_RST}")
_cprint(f" {_DIM}Usage: /reasoning <none|minimal|low|medium|high|xhigh|show|hide|full|clamp>{_RST}")
_cprint(f" {_DIM}Usage: /reasoning <none|minimal|low|medium|high|xhigh|max|ultra|show|hide|full|clamp>{_RST}")
return

arg = parts[1].strip().lower()
Expand Down Expand Up @@ -2534,7 +2534,7 @@ def _handle_reasoning_command(self, cmd: str):
parsed = _parse_reasoning_config(arg)
if parsed is None:
_cprint(f" {_DIM}(._.) Unknown argument: {arg}{_RST}")
_cprint(f" {_DIM}Valid levels: none, minimal, low, medium, high, xhigh{_RST}")
_cprint(f" {_DIM}Valid levels: none, minimal, low, medium, high, xhigh, max, ultra{_RST}")
_cprint(f" {_DIM}Display: show, hide{_RST}")
return

Expand Down
2 changes: 1 addition & 1 deletion hermes_cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class CommandDef:
"Configuration"),
CommandDef("reasoning", "Manage reasoning effort and display", "Configuration",
args_hint="[level|show|hide|full|clamp]",
subcommands=("none", "minimal", "low", "medium", "high", "xhigh", "show", "hide", "on", "off", "full", "clamp")),
subcommands=("none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra", "show", "hide", "on", "off", "full", "clamp")),
CommandDef("fast", "Toggle fast mode — OpenAI Priority Processing / Anthropic Fast Mode (Normal/Fast)", "Configuration",
args_hint="[normal|fast|status]",
subcommands=("normal", "fast", "status", "on", "off")),
Expand Down
4 changes: 2 additions & 2 deletions hermes_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2240,8 +2240,8 @@ def _ensure_hermes_home_managed(home: Path):
# (API, tools, iteration budget), never a delegation
# stopwatch. Set a positive number of seconds
# (floor 30s) to enforce a hard cap.
"reasoning_effort": "", # reasoning effort for subagents: "xhigh", "high", "medium",
# "low", "minimal", "none" (empty = inherit parent's level)
"reasoning_effort": "", # subagent effort: "ultra", "max", "xhigh", "high",
# "medium", "low", "minimal", "none" (empty = inherit)
"max_concurrent_children": 3, # unified concurrency cap: max parallel children per batch
# AND max concurrent background (background=true)
# delegation units. New async dispatches beyond the cap
Expand Down
2 changes: 1 addition & 1 deletion hermes_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3925,7 +3925,7 @@ def _prompt_reasoning_effort_selection(efforts, current_effort=""):
str(effort).strip().lower() for effort in efforts if str(effort).strip()
)
)
canonical_order = ("minimal", "low", "medium", "high", "xhigh")
canonical_order = ("minimal", "low", "medium", "high", "xhigh", "max", "ultra")
ordered = [effort for effort in canonical_order if effort in deduped]
ordered.extend(effort for effort in deduped if effort not in canonical_order)
if not ordered:
Expand Down
2 changes: 1 addition & 1 deletion hermes_cli/web_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ async def _token_auth_seam(request: Request, call_next):
"delegation.reasoning_effort": {
"type": "select",
"description": "Reasoning effort for delegated subagents",
"options": ["", "low", "medium", "high"],
"options": ["", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"],
},
"updates.non_interactive_local_changes": {
"type": "select",
Expand Down
7 changes: 5 additions & 2 deletions hermes_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -791,13 +791,16 @@ def apply_subprocess_home_env(env: dict[str, str]) -> None:
env["HOME"] = home


VALID_REASONING_EFFORTS = ("minimal", "low", "medium", "high", "xhigh", "max")
VALID_REASONING_EFFORTS = (
"minimal", "low", "medium", "high", "xhigh", "max", "ultra",
)


def parse_reasoning_effort(effort) -> dict | None:
"""Parse a reasoning effort level into a config dict.

Valid levels: "none", "minimal", "low", "medium", "high", "xhigh", "max".
Valid levels: "none", "minimal", "low", "medium", "high", "xhigh", "max",
"ultra".
Returns None when the input is empty or unrecognized (caller uses default).
Returns {"enabled": False} for "none" (aliases: "false", "disabled", and
YAML boolean False — users write ``reasoning_effort: false``/``off``/``no``
Expand Down
Binary file added infographic/reasoning-max-ultra/infographic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions plugins/model-providers/copilot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ def build_api_kwargs_extras(
supported_efforts = github_model_reasoning_efforts(model)
if supported_efforts and reasoning_config:
effort = reasoning_config.get("effort", "medium")
# Normalize non-standard effort levels to the nearest supported
if effort == "xhigh":
# Normalize stronger generic levels to the nearest supported.
if effort in {"xhigh", "max", "ultra"}:
effort = "high"
if effort in supported_efforts:
extra_body["reasoning"] = {"effort": effort}
Expand Down
4 changes: 2 additions & 2 deletions plugins/model-providers/deepseek/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ def build_api_kwargs_extras(
if not enabled:
return extra_body, top_level

# Effort mapping. Pass low/medium/high through; xhigh/max → max.
# Effort mapping. Pass low/medium/high through; stronger levels → max.
# When no effort is set we omit reasoning_effort so DeepSeek applies
# its server default (currently high).
if isinstance(reasoning_config, dict):
effort = (reasoning_config.get("effort") or "").strip().lower()
if effort in {"xhigh", "max"}:
if effort in {"xhigh", "max", "ultra"}:
top_level["reasoning_effort"] = "max"
elif effort in {"low", "medium", "high"}:
top_level["reasoning_effort"] = effort
Expand Down
2 changes: 1 addition & 1 deletion plugins/model-providers/ollama-cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def build_api_kwargs_extras(
return {}, {}
if effort == "none":
return {}, {} # explicit none → suppress thinking
if effort in ("xhigh", "max"):
if effort in ("xhigh", "max", "ultra"):
top_level["reasoning_effort"] = "max"
elif effort in ("low", "medium", "high"):
top_level["reasoning_effort"] = effort
Expand Down
6 changes: 3 additions & 3 deletions plugins/model-providers/opencode-zen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def build_api_kwargs_extras(
effort = (reasoning_config.get("effort") or "").strip().lower()
if not effort or effort == "none":
return extra_body, top_level
top_level["reasoning_effort"] = "max" if effort in {"xhigh", "max"} else "high"
top_level["reasoning_effort"] = "max" if effort in {"xhigh", "max", "ultra"} else "high"
return extra_body, top_level

if _is_kimi_k2_model(model):
Expand All @@ -90,7 +90,7 @@ def build_api_kwargs_extras(
return extra_body, top_level

effort = (reasoning_config.get("effort") or "").strip().lower()
if effort in {"xhigh", "max"}:
if effort in {"xhigh", "max", "ultra"}:
top_level["reasoning_effort"] = "high"
elif effort in {"low", "medium", "high"}:
top_level["reasoning_effort"] = effort
Expand All @@ -114,7 +114,7 @@ def build_api_kwargs_extras(

if isinstance(reasoning_config, dict):
effort = (reasoning_config.get("effort") or "").strip().lower()
if effort in {"xhigh", "max"}:
if effort in {"xhigh", "max", "ultra"}:
top_level["reasoning_effort"] = "max"
elif effort in {"low", "medium", "high"}:
top_level["reasoning_effort"] = effort
Expand Down
4 changes: 2 additions & 2 deletions plugins/model-providers/zai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def _is_glm_5_2(model: str | None) -> bool:
def _glm_5_2_reasoning_effort(reasoning_config: dict | None) -> str | None:
"""Map Hermes reasoning effort onto GLM-5.2's native ``high``/``max``.

GLM-5.2 only supports two enabled effort levels. ``xhigh``/``max``
GLM-5.2 only supports two enabled effort levels. ``xhigh``/``max``/``ultra``
request the top tier; everything else that is enabled requests ``high``
(its minimum thinking level). When reasoning is explicitly disabled, or
no effort preference is supplied, the server default is left untouched.
Expand All @@ -76,7 +76,7 @@ def _glm_5_2_reasoning_effort(reasoning_config: dict | None) -> str | None:
if not effort or effort == "none":
return None

if effort in {"xhigh", "max"}:
if effort in {"xhigh", "max", "ultra"}:
return "max"
# low / medium / minimal / high all clamp to GLM-5.2's minimum: high.
return "high"
Expand Down
Loading
Loading