NousResearch/hermes-agent

Expanding max/ultra reasoning effort support across stack

Cluster 29248 · agent. Data as of

2 open items. Fix merged in #65651 on 16 Jul 2026. Check it covers your case.

The short answer

0open issues
2open PRs
11items grouped
Known?
Yes. 11 related items grouped here, 3 issues already closed.
Fix event
A fix was merged to main in PR #65651. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this unresolved. That is separate from the fix event.
Still open
0 issues and 2 PRs.

These issues and pull requests address gaps where 'max' and 'ultra' reasoning effort levels were supported in some adapters but rejected or ignored by frontend validators, gateways, and CLI layers. Work spans Anthropic and OpenAI models, input validation, budget clamping, and multi-agent integration.

Open issues0

No open issues.

Open PRs2

  • PR#53679fix(anthropic): honor 'max' effort on manual thinking path + clamp budget to output ceiling
  • PR#62156feat(agent): add OpenAI Ultra multi-agent mode

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #62650 feat(reasoning): add max and ultra effort levels

    merged to main

    files: agent/anthropic_adapter.py, agent/transports/chat_completions.py, agent/transports/codex.py, apps/desktop/src/app/settings/constants.ts, apps/desktop/src/app/settings/model-settings.tsx, apps/desktop/src/app/shell/model-edit-submenu.tsx, apps/desktop/src/i18n/en.ts, apps/desktop/src/i18n/ja.ts, apps/desktop/src/i18n/types.ts, apps/desktop/src/i18n/zh-hant.ts, apps/desktop/src/i18n/zh.ts, apps/desktop/src/lib/model-status-label.test.ts, apps/desktop/src/lib/model-status-label.ts, batch_runner.py, gateway/run.py, gateway/slash_commands.py, hermes_cli/cli_commands_mixin.py, hermes_cli/commands.py, hermes_cli/config.py, hermes_cli/main.py (+27 more)

    Show the diff
    • agent/anthropic_adapter.py
      @@ -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",
    • agent/transports/chat_completions.py
      @@ -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):
      @@ -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
      @@ -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
      @@ -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:
                   [redacted:secret-assignment]
      @@ -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,
    • agent/transports/codex.py
      @@ -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)
    • apps/desktop/src/app/settings/constants.ts
      @@ -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/
    • apps/desktop/src/app/settings/model-settings.tsx
      @@ -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).
      @@ -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
    • apps/desktop/src/app/shell/model-edit-submenu.tsx
      @@ -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:
    • apps/desktop/src/i18n/en.ts
      @@ -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'
           },
    • apps/desktop/src/i18n/ja.ts
      @@ -1981,7 +1981,9 @@ export const ja = defineLocale({
             low: '低',
             medium: '中',
             high: '高',
      +      xhigh: '特高',
             max: '最大',
      +      ultra: 'ウルトラ',
             updateFailed: 'モデルオプションの更新に失敗しました',
             fastFailed: '高速モードの更新に失敗しました'
           },
    • apps/desktop/src/i18n/types.ts
      @@ -1668,7 +1668,9 @@ export interface Translations {
             low: string
             medium: string
             high: string
      +      xhigh: string
             max: string
      +      ultra: string
             updateFailed: string
             fastFailed: string
           }
    • apps/desktop/src/i18n/zh-hant.ts
      @@ -1916,7 +1916,9 @@ export const zhHant = defineLocale({
             low: '低',
             medium: '中',
             high: '高',
      +      xhigh: '極高',
             max: '最高',
      +      ultra: '超高',
             updateFailed: '模型選項更新失敗',
             fastFailed: '快速模式更新失敗'
           },
    • apps/desktop/src/i18n/zh.ts
      @@ -2200,7 +2200,9 @@ export const zh: Translations = {
             low: '低',
             medium: '中',
             high: '高',
      +      xhigh: '极高',
             max: '最高',
      +      ultra: '超高',
             updateFailed: '模型选项更新失败',
             fastFailed: '快速模式更新失败'
           },
    • apps/desktop/src/lib/model-status-label.test.ts
      @@ -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('')
         })
       
    • apps/desktop/src/lib/model-status-label.ts
      @@ -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 {
    • batch_runner.py
      @@ -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)
      @@ -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
    • gateway/run.py
      @@ -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
    • gateway/slash_commands.py
      @@ -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(
    • hermes_cli/cli_commands_mixin.py
      @@ -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)
      @@ -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()
      @@ -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
       
    • hermes_cli/commands.py
      @@ -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")),
    • hermes_cli/config.py
      @@ -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
    • hermes_cli/main.py
      @@ -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:
    • hermes_cli/web_server.py
      @@ -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",
    • hermes_constants.py
      @@ -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``
    • plugins/model-providers/copilot/__init__.py
      @@ -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}
    • plugins/model-providers/deepseek/__init__.py
      @@ -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
    • plugins/model-providers/ollama-cloud/__init__.py
      @@ -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
    • plugins/model-providers/opencode-zen/__init__.py
      @@ -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):
      @@ -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
      @@ -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
    • plugins/model-providers/zai/__init__.py
      @@ -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.
      @@ -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"
    • plugins/platforms/discord/adapter.py
      @@ -4085,7 +4085,7 @@ async def slash_model(interaction: discord.Interaction, name: str = ""):
                   await self._run_simple_slash(interaction, f"/model {name}".strip())
       
               @tree.command(name="reasoning", description="Show or change reasoning effort")
      -        @discord.app_commands.describe(effort="Reasoning effort: none, minimal, low, medium, high, or xhigh.")
      +        @discord.app_commands.describe(effort="Effort: none, minimal, low, medium, high, xhigh, max, or ultra.")
               async def slash_reasoning(interaction: discord.Interaction, effort: str = ""):
                   await self._run_simple_slash(interaction, f"/reasoning {effort}".strip())
       
    • skills/autonomous-ai-agents/hermes-agent/SKILL.md
      @@ -294,7 +294,7 @@ The registry of record is `hermes_cli/commands.py` — every consumer
       /config              Show config (CLI)
       /model [name]        Show or change model
       /personality [name]  Set personality
      -/reasoning [level]   Set reasoning (none|minimal|low|medium|high|xhigh|show|hide)
      +/reasoning [level]   Set reasoning (none|minimal|low|medium|high|xhigh|max|ultra|show|hide)
       /verbose             Cycle: off → new → all → verbose
       /voice [on|off|tts]  Voice mode
       /yolo                Toggle approval bypass
    • tests/agent/test_anthropic_adapter.py
      @@ -1448,6 +1448,16 @@ def test_reasoning_config_preserves_xhigh_for_4_7_models(self):
               assert kwargs["thinking"] == {"type": "adaptive", "display": "summarized"}
               assert kwargs["output_config"] == {"effort": "xhigh"}
       
      +    def test_reasoning_config_clamps_generic_ultra_to_anthropic_max(self):
      +        kwargs = build_anthropic_kwargs(
      +            model="claude-opus-4.8",
      +            messages=[{"role": "user", "content": "think harder"}],
      +            tools=None,
      +            max_tokens=4096,
      +            reasoning_config={"enabled": True, "effort": "ultra"},
      +        )
      +        assert kwargs["output_config"] == {"effort": "max"}
      +
           def test_reasoning_config_maps_max_effort_for_4_7_models(self):
               kwargs = build_anthropic_kwargs(
                   model="claude-opus-4-7",
    • tests/agent/transports/test_chat_completions.py
      @@ -21,6 +21,23 @@ def test_api_mode(self, transport):
           def test_registered(self, transport):
               assert transport is not None
       
      +    @pytest.mark.parametrize("provider", ["nous", "openrouter"])
      +    def test_gpt56_ultra_uses_max_wire_effort(self, transport, provider):
      +        from providers import get_provider_profile
      +
      +        profile = get_provider_profile(provider)
      +        kw = transport.build_kwargs(
      +            model="openai/gpt-5.6-sol",
      +            messages=[{"role": "user", "content": "Hi"}],
      +            tools=[],
      +            reasoning_config={"enabled": True, "effort": "ultra"},
      +            supports_reasoning=True,
      +            provider_profile=profile,
      +            provider_name=provider,
      +            base_url=profile.base_url,
      +        )
      +        assert kw["extra_body"]["reasoning"] == {"enabled": True, "effort": "max"}
      +
           def test_convert_tools_identity(self, transport):
               tools = [{"type": "function", "function": {"name": "test", "parameters": {}}}]
               assert transport.convert_tools(tools) is tools
    • tests/agent/transports/test_codex_transport.py
      @@ -75,6 +75,16 @@ def test_reasoning_config(self, transport):
               )
               assert kw.get("reasoning", {}).get("effort") == "high"
       
      +    @pytest.mark.parametrize("effort, wire_effort", [("max", "max"), ("ultra", "max")])
      +    def test_extended_reasoning_efforts_use_api_wire_value(self, transport, effort, wire_effort):
      +        kw = transport.build_kwargs(
      +            model="gpt-5.6-sol",
      +            messages=[{"role": "user", "content": "Hi"}],
      +            tools=[],
      +            reasoning_config={"enabled": True, "effort": effort},
      +        )
      +        assert kw.get("reasoning", {}).get("effort") == wire_effort
      +
           def test_reasoning_disabled(self, transport):
               messages = [{"role": "user", "content": "Hi"}]
               kw = transport.build_kwargs(
      @@ -401,6 +411,17 @@ def test_xai_reasoning_effort_passed(self, transport):
               # full history.
               assert "reasoning.encrypted_content" in kw.get("include", [])
       
      +    @pytest.mark.parametrize("effort", ["xhigh", "max", "ultra"])
      +    def test_xai_stronger_generic_efforts_clamp_to_high(self, transport, effort):
      +        kw = transport.build_kwargs(
      +            model="grok-4.3",
      +            messages=[{"role": "user", "content": "Hi"}],
      +            tools=[],
      +            is_xai_responses=True,
      +            reasoning_config={"enabled": True, "effort": effort},
      +        )
      +        assert kw.get("reasoning") == {"effort": "high"}
      +
           def test_xai_injects_native_web_search_when_client_web_search_present(self, transport):
               """xAI path swaps a client-side ``web_search`` function for xAI's
               native server-side ``web_search`` built-in so grok server-side search
    • tests/cli/test_reasoning_command.py
      @@ -30,7 +30,7 @@ def test_none_disables(self):
               self.assertEqual(result, {"enabled": False})
       
           def test_valid_levels(self):
      -        for level in ("low", "medium", "high", "xhigh", "minimal"):
      +        for level in ("low", "medium", "high", "xhigh", "max", "ultra", "minimal"):
                   result = self._parse(level)
                   self.assertIsNotNone(result)
                   self.assertTrue(result.get("enabled"))
      @@ -41,7 +41,6 @@ def test_empty_returns_none(self):
               self.assertIsNone(self._parse("  "))
       
           def test_unknown_returns_none(self):
      -        self.assertIsNone(self._parse("ultra"))
               self.assertIsNone(self._parse("turbo"))
       
           def test_case_insensitive(self):
    • tests/gateway/test_reasoning_command.py
      @@ -148,6 +148,29 @@ async def test_handle_reasoning_command_defaults_to_session_only(self, tmp_path,
               assert runner._reasoning_config == {"enabled": True, "effort": "high"}
               assert "session only" in result
       
      +    @pytest.mark.asyncio
      +    @pytest.mark.parametrize("effort", ["max", "ultra"])
      +    async def test_handle_reasoning_command_accepts_extended_efforts(
      +        self, tmp_path, monkeypatch, effort
      +    ):
      +        hermes_home = tmp_path / "hermes"
      +        hermes_home.mkdir()
      +        (hermes_home / "config.yaml").write_text(
      +            "agent:\n  reasoning_effort: medium\n", encoding="utf-8"
      +        )
      +        monkeypatch.setattr(gateway_run, "_hermes_home", hermes_home)
      +
      +        runner = _make_runner()
      +        event = _make_event(f"/reasoning {effort}")
      +        session_key = runner._session_key_for_source(event.source)
      +
      +        await runner._handle_reasoning_command(event)
      +
      +        assert runner._session_reasoning_overrides[session_key] == {
      +            "enabled": True,
      +            "effort": effort,
      +        }
      +
           @pytest.mark.asyncio
           async def test_reasoning_global_clears_existing_session_override(self, tmp_path, monkeypatch):
               hermes_home = tmp_path / "hermes"
    • tests/hermes_cli/test_commands.py
      @@ -75,13 +75,15 @@ def test_every_entry_has_valid_category(self):
       
           def test_reasoning_subcommands_are_in_logical_order(self):
               reasoning = next(cmd for cmd in COMMAND_REGISTRY if cmd.name == "reasoning")
      -        assert reasoning.subcommands[:6] == (
      +        assert reasoning.subcommands[:8] == (
                   "none",
                   "minimal",
                   "low",
                   "medium",
                   "high",
                   "xhigh",
      +            "max",
      +            "ultra",
               )
       
           def test_cli_only_and_gateway_only_are_mutually_exclusive(self):
    • tests/plugins/model_providers/test_ollama_cloud_profile.py
      @@ -106,9 +106,9 @@ def test_no_effort_key_emits_nothing(self, ollama_cloud_profile):
       
           def test_unknown_effort_forwarded(self, ollama_cloud_profile):
               _, top_level = ollama_cloud_profile.build_api_kwargs_extras(
      -            reasoning_config={"enabled": True, "effort": "ultra"},
      +            reasoning_config={"enabled": True, "effort": "future-tier"},
               )
      -        assert top_level == {"reasoning_effort": "ultra"}
      +        assert top_level == {"reasoning_effort": "future-tier"}
       
       
       class TestOllamaCloudFullKwargsIntegration:
    • tests/providers/test_provider_profiles.py
      @@ -314,12 +314,12 @@ def test_mandatory_anthropic_effort_routes_to_verbosity(self):
       
               Covers the full real config range produced by
               ``hermes_constants.parse_reasoning_effort`` —
      -        ``VALID_REASONING_EFFORTS = (minimal, low, medium, high, xhigh)``.
      +        ``VALID_REASONING_EFFORTS`` (including max and ultra).
               """
               p = get_provider_profile("openrouter")
               model = "anthropic/claude-fable-5"
               assert self._is_mandatory(model)  # fixture really is mandatory
      -        for effort in ("minimal", "low", "medium", "high", "xhigh"):
      +        for effort in ("minimal", "low", "medium", "high", "xhigh", "max", "ultra"):
                   eb, tl = p.build_api_kwargs_extras(
                       reasoning_config={"enabled": True, "effort": effort},
                       supports_reasoning=True,
      @@ -342,14 +342,12 @@ def test_mandatory_anthropic_effort_without_enabled_key_routes(self):
       
           def test_mandatory_anthropic_verbosity_is_value_agnostic_passthrough(self):
               """The mapping passes the effort value through verbatim — it must NOT
      -        clamp or whitelist. ``xhigh`` is a real config value; ``max`` is not
      -        producible by ``parse_reasoning_effort`` today but OpenRouter accepts it
      -        for Claude (live-proven in #43432), so a forward value must survive
      +        clamp or whitelist. Extended values must survive
               rather than be silently dropped. The OpenAI SDK type only literals
               ``low|medium|high`` but it's a TypedDict (no runtime validation), so the
               extended scale reaches the wire untouched."""
               p = get_provider_profile("openrouter")
      -        for effort in ("xhigh", "max"):
      +        for effort in ("xhigh", "max", "ultra"):
                   _, tl = p.build_api_kwargs_extras(
                       reasoning_config={"enabled": True, "effort": effort},
                       supports_reasoning=True,
    • tests/test_hermes_constants.py
      @@ -483,10 +483,10 @@ def test_known_supported_levels_are_documented(self):
               """Guard against silently dropping a documented level.
       
               The docstring promises "minimal", "low", "medium", "high", "xhigh",
      -        "max". If someone removes one from VALID_REASONING_EFFORTS without
      +        "max", "ultra". If someone removes one from VALID_REASONING_EFFORTS without
               updating the docstring, this test will fail and force the call out.
               """
      -        documented = {"minimal", "low", "medium", "high", "xhigh", "max"}
      +        documented = {"minimal", "low", "medium", "high", "xhigh", "max", "ultra"}
               assert documented.issubset(set(VALID_REASONING_EFFORTS))
       
       
    • web/src/lib/reasoning-effort.test.ts
      @@ -14,7 +14,7 @@ describe("normalizeEffort", () => {
         });
       
         it("passes through every valid effort level", () => {
      -    for (const level of ["none", "minimal", "low", "medium", "high", "xhigh"]) {
      +    for (const level of ["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"]) {
             expect(normalizeEffort(level)).toBe(level);
           }
         });
      @@ -26,7 +26,6 @@ describe("normalizeEffort", () => {
       
         it("falls back to medium for unknown values", () => {
           expect(normalizeEffort("turbo")).toBe("medium");
      -    expect(normalizeEffort("max")).toBe("medium"); // 'max' is a label, not a value
           expect(normalizeEffort(42)).toBe("medium");
         });
       });
      @@ -41,7 +40,7 @@ describe("EFFORT_OPTIONS", () => {
         it("covers the real reasoning levels plus thinking-off", () => {
           // Invariant against hermes_constants.VALID_REASONING_EFFORTS + 'none'.
           const values = new Set(EFFORT_OPTIONS.map((o) => o.value));
      -    for (const level of ["none", "minimal", "low", "medium", "high", "xhigh"]) {
      +    for (const level of ["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"]) {
             expect(values.has(level)).toBe(true);
           }
         });
    • web/src/lib/reasoning-effort.ts
      @@ -20,7 +20,9 @@ export const EFFORT_OPTIONS: ReadonlyArray<EffortOption> = [
         { value: "low", label: "Low" },
         { value: "medium", label: "Medium" },
         { value: "high", label: "High" },
      -  { value: "xhigh", label: "Max" },
      +  { value: "xhigh", label: "Extra High" },
      +  { value: "max", label: "Max" },
      +  { value: "ultra", label: "Ultra" },
       ];
       
       export const VALID_EFFORTS: ReadonlySet<string> = new Set(
    • website/docs/user-guide/configuration.md
      @@ -1276,7 +1276,7 @@ Control how much "thinking" the model does before responding:
       
       ```yaml
       agent:
      -  reasoning_effort: ""   # empty = medium (default). Options: none, minimal, low, medium, high, xhigh (max)
      +  reasoning_effort: ""   # empty = medium. Options: none, minimal, low, medium, high, xhigh, max, ultra
       ```
       
       When unset (default), reasoning effort defaults to "medium" — a balanced level that works well for most tasks. Setting a value overrides it — higher reasoning effort gives better results on complex tasks at the cost of more tokens and latency.
      @@ -1285,10 +1285,9 @@ When unset (default), reasoning effort defaults to "medium" — a balanced level
       These models use *adaptive* thinking and don't accept the usual `reasoning.effort`
       field — OpenRouter ignores it for them. Hermes transparently routes your
       `reasoning_effort` to OpenRouter's `verbosity` parameter instead (which maps to
      -Anthropic's `output_config.effort`), so the same `low`/`medium`/`high`/`xhigh`
      -knob keeps working — no extra configuration needed. `none` (or unset) leaves the
      -model on its own adaptive default. (`max` is accepted on the wire but is not a
      -selectable `reasoning_effort` value; `xhigh` is the configurable ceiling.) The
      +Anthropic's `output_config.effort`), so the same effort knob keeps working with
      +the levels supported by the selected model. `none` (or unset) leaves the model
      +on its own adaptive default. The
       native Anthropic provider already controls effort directly and is unaffected.
       :::
       
    • website/docs/user-guide/features/batch-processing.md
      @@ -83,7 +83,7 @@ Entries can optionally include:
       
       | Parameter | Description |
       |-----------|-------------|
      -| `--reasoning_effort` | Effort level: `none`, `minimal`, `low`, `medium`, `high`, `xhigh` |
      +| `--reasoning_effort` | Reasoning effort: `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`, `ultra` |
       | `--reasoning_disabled` | Completely disable reasoning/thinking tokens |
       
       ### Advanced Options
    • website/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent.md
      @@ -286,7 +286,7 @@ The registry of record is `hermes_cli/commands.py` — every consumer
       /config              Show config (CLI)
       /model [name]        Show or change model
       /personality [name]  Set personality
      -/reasoning [level]   Set reasoning (none|minimal|low|medium|high|xhigh|show|hide)
      +/reasoning [level]   Set reasoning (none|minimal|low|medium|high|xhigh|max|ultra|show|hide)
       /verbose             Cycle: off → new → all → verbose
       /voice [on|off|tts]  Voice mode
       /yolo                Toggle approval bypass
    • website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/configuration.md
      @@ -1044,7 +1044,7 @@ auxiliary:
       
       ```yaml
       agent:
      -  reasoning_effort: ""   # 空 = 中等(默认)。选项:none、minimal、low、medium、high、xhigh(最大)
      +  reasoning_effort: ""   # 空 = 中等。选项:none、minimal、low、medium、high、xhigh、max、ultra
       ```
       
       未设置时(默认),推理努力程度默认为"medium" —— 适合大多数任务的平衡级别。设置值会覆盖它 —— 更高的推理努力程度在复杂任务上提供更好的结果,但代价是更多 token 和延迟。
    • website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/batch-processing.md
      @@ -83,7 +83,7 @@ python batch_runner.py --list_distributions
       
       | 参数 | 说明 |
       |-----------|-------------|
      -| `--reasoning_effort` | 推理力度:`none`、`minimal`、`low`、`medium`、`high`、`xhigh` |
      +| `--reasoning_effort` | 推理力度:`none`、`minimal`、`low`、`medium`、`high`、`xhigh`、`max`、`ultra` |
       | `--reasoning_disabled` | 完全禁用推理/思考 token |
       
       ### 高级选项
    • website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent.md
      @@ -275,7 +275,7 @@ hermes uninstall            Uninstall Hermes
       /config              Show config (CLI)
       /model [name]        Show or change model
       /personality [name]  Set personality
      -/reasoning [level]   Set reasoning (none|minimal|low|medium|high|xhigh|show|hide)
      +/reasoning [level]   Set reasoning (none|minimal|low|medium|high|xhigh|max|ultra|show|hide)
       /verbose             Cycle: off → new → all → verbose
       /voice [on|off|tts]  Voice mode
       /yolo                Toggle approval bypass
  • #65651 fix(gateway,moa): surface and preserve extended reasoning efforts (salvage #64012)

    merged to main

    files: gateway/slash_commands.py, hermes_cli/moa_config.py, locales/af.yaml, locales/de.yaml, locales/en.yaml, locales/es.yaml, locales/fr.yaml, locales/ga.yaml, locales/hu.yaml, locales/it.yaml, locales/ja.yaml, locales/ko.yaml, locales/pt.yaml, locales/ru.yaml, locales/tr.yaml, locales/uk.yaml, locales/zh-hant.yaml, locales/zh.yaml, scripts/release.py, tests/hermes_cli/test_moa_config.py (+2 more)

4 PRs closed without merging

From the close comments: done elsewhere 3 · other 1

  • #29269 fix: accept max reasoning effort (#29248) · done elsewhere → 7550c59, #62650, #34199, #61638
  • #49644 feat(reasoning): accept "max" reasoning effort end-to-end with nearest-down clamp · other → #62650, #65651
  • #61638 fix(gateway): accept max reasoning effort · done elsewhere → #62650, #65651, #64012, #12211
  • #61996 fix(reasoning): expose max effort for GPT-5.6 · done elsewhere → #62650, #65651, #64012, #12211
Closed issues · 3
  • Closed#29248`/reasoning max` rejected by frontend even though Anthropic adapter already supports it end-to-end
  • Closed#49580Feature gap: `max` reasoning effort supported in Anthropic adapter but rejected by all input validators
  • Closed#61634[Bug]: GPT-5.6 reasoning support is incomplete: gateway/CLI block max; Ultra needs Multi-agent integration
How this cluster was grouped
  • Link evidence (partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
  • Members outside that structural core may belong to a different underlying problem.
  • Pairwise link density 0.19: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
agent
Merged PRs
#62650, #65651
Closed issues
3
Attempts
4 PRs closed without merging
Fix link checked
16 Jul 2026

For your agent

The same facts, typed.