mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-04 02:21:47 +00:00
## Problem
Anthropic's adaptive-thinking API exposes five effort levels on
Claude 4.6+ / 4.7 models:
low, medium, high, xhigh, max
(xhigh was added by 4.7; max has existed since 4.6.)
`agent/anthropic_adapter.py` already maps all five correctly via
`ADAPTIVE_EFFORT_MAP` (including a `xhigh → max` downgrade path
for pre-4.7 models) and its `THINKING_BUDGET` + documentation treat
"max" as a first-class value.
However, the user-facing surface only lists four of them.
`VALID_REASONING_EFFORTS` in `hermes_constants.py` stops at
`"xhigh"`, so `parse_reasoning_effort("max")` silently returns
`None`, the caller falls back to the default (medium), and the
adapter never receives the max level.
The same hardcoded shorter list is duplicated in four other places:
`/reasoning` slash-command subcommand tuple, the gateway handler's
allowed-value check, the gateway's help text, the Discord slash
command description, and the CLI effort-picker's canonical order.
## Fix
Add `"max"` to `VALID_REASONING_EFFORTS` and update every duplicated
surface to match. While here, replace the gateway's open-coded
`("minimal", "low", "medium", "high", "xhigh")` tuple with a reference
to `VALID_REASONING_EFFORTS` so future additions (when Anthropic
ships a new level) only need one edit.
No behavior change for existing values — any string that was valid
before remains valid and parses identically. The only new behavior
is that `"max"` is now accepted end-to-end: `/reasoning max` sets
`agent.reasoning_effort: max` in `config.yaml`, which Anthropic's
`output_config.effort` then receives directly.
## Changes Made
- `hermes_constants.py`
- `VALID_REASONING_EFFORTS`: add `"max"`.
- `parse_reasoning_effort()` docstring: list `"max"`.
- `gateway/run.py`
- `_handle_reasoning_command()`: replace hardcoded tuple with
`VALID_REASONING_EFFORTS`; error message now derives the valid
list from the tuple instead of hardcoding a stale copy.
- Docstring + help banner + "_Usage:_" line: mention `max`.
- `_load_reasoning_config()` docstring: mention `max`.
- `hermes_cli/commands.py`: add `"max"` to the `/reasoning`
`CommandDef` subcommand tuple (drives tab-completion).
- `hermes_cli/main.py`: add `"max"` to the canonical-order tuple
in `_prompt_reasoning_effort_selection()` (drives `/reasoning`
picker ordering).
- `gateway/platforms/discord.py`: add `max` to the Discord slash
command's `app_commands.describe(effort=...)` docstring.
- `tests/test_hermes_constants.py`: new `TestParseReasoningEffort`
class with 7 tests covering empty/none/case-insensitivity/unknown
inputs and explicitly verifying `"max"` parses end-to-end and is
present in `VALID_REASONING_EFFORTS`.
## Testing
```bash
pytest tests/test_hermes_constants.py -q
# 18 passed in 1.74s
```
Manually:
```bash
# Before: /reasoning max → "Unknown argument: max" error
# After: /reasoning max → "Reasoning effort set to `max` (saved to config)"
```
Signed-off-by: Andre Kurait <andrekurait@gmail.com>
|
||
|---|---|---|
| .. | ||
| __init__.py | ||
| auth.py | ||
| auth_commands.py | ||
| backup.py | ||
| banner.py | ||
| callbacks.py | ||
| claw.py | ||
| cli_output.py | ||
| clipboard.py | ||
| codex_models.py | ||
| colors.py | ||
| commands.py | ||
| completion.py | ||
| config.py | ||
| copilot_auth.py | ||
| cron.py | ||
| curses_ui.py | ||
| debug.py | ||
| default_soul.py | ||
| dingtalk_auth.py | ||
| doctor.py | ||
| dump.py | ||
| env_loader.py | ||
| gateway.py | ||
| hooks.py | ||
| logs.py | ||
| main.py | ||
| mcp_config.py | ||
| memory_setup.py | ||
| model_normalize.py | ||
| model_switch.py | ||
| models.py | ||
| nous_subscription.py | ||
| pairing.py | ||
| platforms.py | ||
| plugins.py | ||
| plugins_cmd.py | ||
| profiles.py | ||
| providers.py | ||
| runtime_provider.py | ||
| setup.py | ||
| skills_config.py | ||
| skills_hub.py | ||
| skin_engine.py | ||
| status.py | ||
| timeouts.py | ||
| tips.py | ||
| tools_config.py | ||
| uninstall.py | ||
| web_server.py | ||
| webhook.py | ||