Skip to content
Closed
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
4 changes: 2 additions & 2 deletions batch_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,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): OpenRouter reasoning effort level: "none", "minimal", "low", "medium", "high", "xhigh", "max" (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 @@ -1230,7 +1230,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"]
if reasoning_effort not in valid_efforts:
print(f"❌ Error: --reasoning_effort must be one of: {', '.join(valid_efforts)}")
return
Expand Down
4 changes: 2 additions & 2 deletions cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6449,7 +6449,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 reasoning effort (none, minimal, low, medium, high, xhigh, max)
/reasoning show|on Show model thinking/reasoning in output
Comment on lines 6450 to 6453

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/reasoning help text now lists max, but the no-args status output later in this handler still prints Usage: /reasoning <none|minimal|low|medium|high|xhigh|show|hide> (missing max). Please update that usage hint too so all CLI help surfaces are consistent.

Copilot uses AI. Check for mistakes.
/reasoning hide|off Hide model thinking/reasoning from output
"""
Expand Down Expand Up @@ -6493,7 +6493,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{_RST}")
_cprint(f" {_DIM}Display: show, hide{_RST}")
return

Expand Down
8 changes: 4 additions & 4 deletions gateway/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -1189,7 +1189,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". Returns None to use
default (medium).
"""
from hermes_constants import parse_reasoning_effort
Expand Down Expand Up @@ -6371,7 +6371,7 @@ async def _handle_reasoning_command(self, event: MessageEvent) -> str:

Usage:
/reasoning Show current effort level and display state
/reasoning <level> Set reasoning effort (none, minimal, low, medium, high, xhigh)
/reasoning <level> Set reasoning effort (none, minimal, low, medium, high, xhigh, max)
/reasoning show|on Show model reasoning in responses
Comment on lines 6371 to 6375

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The handler docstring/usage now includes max, but the no-args response still returns _Usage:_ /reasoning <none|minimal|low|medium|high|xhigh|show|hide>`` (missing max). Please update that returned usage string as well so gateway help output matches the accepted levels.

Copilot uses AI. Check for mistakes.
/reasoning hide|off Hide model reasoning from responses
"""
Expand Down Expand Up @@ -6438,12 +6438,12 @@ def _save_config_key(key_path: str, value):
effort = args.strip()
if effort == "none":
parsed = {"enabled": False}
elif effort in ("minimal", "low", "medium", "high", "xhigh"):
elif effort in ("minimal", "low", "medium", "high", "xhigh", "max"):
parsed = {"enabled": True, "effort": effort}
else:
return (
f"⚠️ Unknown argument: `{effort}`\n\n"
"**Valid levels:** none, minimal, low, medium, high, xhigh\n"
"**Valid levels:** none, minimal, low, medium, high, xhigh, max\n"
"**Display:** show, hide"
)

Expand Down
2 changes: 1 addition & 1 deletion hermes_cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class CommandDef:
"Configuration"),
CommandDef("reasoning", "Manage reasoning effort and display", "Configuration",
args_hint="[level|show|hide]",
subcommands=("none", "minimal", "low", "medium", "high", "xhigh", "show", "hide", "on", "off")),
subcommands=("none", "minimal", "low", "medium", "high", "xhigh", "max", "show", "hide", "on", "off")),
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
2 changes: 1 addition & 1 deletion hermes_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2872,7 +2872,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")
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
4 changes: 2 additions & 2 deletions hermes_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,13 @@ def get_subprocess_home() -> str | None:
return None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accepting max globally also reaches non-Anthropic transports. Please add provider-boundary normalization: current Codex handling only maps minimal → low, so it otherwise forwards max as reasoning.effort (agent/transports/codex.py:155-166).



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


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

Valid levels: "none", "minimal", "low", "medium", "high", "xhigh".
Valid levels: "none", "minimal", "low", "medium", "high", "xhigh", "max".
Returns None when the input is empty or unrecognized (caller uses default).
Returns {"enabled": False} for "none".
Returns {"enabled": True, "effort": <level>} for valid effort levels.
Expand Down
2 changes: 1 addition & 1 deletion skills/autonomous-ai-agents/hermes-agent/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ Type these during an interactive chat session.
/model [name] Show or change model
/provider Show provider info
/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|show|hide)
/verbose Cycle: off → new → all → verbose
/voice [on|off|tts] Voice mode
/yolo Toggle approval bypass
Expand Down
2 changes: 1 addition & 1 deletion tests/cli/test_reasoning_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -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", "minimal"):
result = self._parse(level)
self.assertIsNotNone(result)
self.assertTrue(result.get("enabled"))
Expand Down
19 changes: 19 additions & 0 deletions tests/gateway/test_reasoning_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,25 @@ async def test_handle_reasoning_command_updates_config_and_cache(self, tmp_path,
assert runner._reasoning_config == {"enabled": True, "effort": "low"}
assert "takes effect on next message" in result

@pytest.mark.asyncio
async def test_handle_reasoning_command_accepts_max(self, tmp_path, monkeypatch):
hermes_home = tmp_path / "hermes"
hermes_home.mkdir()
config_path = hermes_home / "config.yaml"
config_path.write_text("agent:\n reasoning_effort: medium\n", encoding="utf-8")

monkeypatch.setattr(gateway_run, "_hermes_home", hermes_home)

runner = _make_runner()
runner._reasoning_config = {"enabled": True, "effort": "medium"}

result = await runner._handle_reasoning_command(_make_event("/reasoning max"))

saved = yaml.safe_load(config_path.read_text(encoding="utf-8"))
assert saved["agent"]["reasoning_effort"] == "max"
assert runner._reasoning_config == {"enabled": True, "effort": "max"}
assert "takes effect on next message" in result

def test_run_agent_reloads_reasoning_config_per_message(self, tmp_path, monkeypatch):
hermes_home = tmp_path / "hermes"
hermes_home.mkdir()
Expand Down
18 changes: 18 additions & 0 deletions tests/hermes_cli/test_reasoning_effort_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,21 @@ def test_reasoning_menu_orders_minimal_before_low(monkeypatch):
" medium ← currently in use",
" high",
]


def test_reasoning_menu_places_max_after_xhigh(monkeypatch):
fake_module = types.SimpleNamespace(TerminalMenu=_FakeTerminalMenu)
monkeypatch.setitem(sys.modules, "simple_term_menu", fake_module)

selected = _prompt_reasoning_effort_selection(
["max", "medium", "xhigh", "high"],
current_effort="max",
)

assert selected == "max"
assert _FakeTerminalMenu.last_choices[:4] == [
" medium",
" high",
" xhigh",
" max ← currently in use",
]
2 changes: 1 addition & 1 deletion website/docs/user-guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,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 (default). Options: none, minimal, low, medium, high, xhigh, max
```

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.
Expand Down
2 changes: 1 addition & 1 deletion website/docs/user-guide/features/batch-processing.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Entries can optionally include:

| Parameter | Description |
|-----------|-------------|
| `--reasoning_effort` | Effort level: `none`, `minimal`, `low`, `medium`, `high`, `xhigh` |
| `--reasoning_effort` | Effort level: `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` |
| `--reasoning_disabled` | Completely disable reasoning/thinking tokens |

### Advanced Options
Expand Down
Loading