Summary
The Web UI has no way to control reasoning effort. The CLI offers /reasoning [none|minimal|low|medium|high|xhigh] which sets the effort level for the current session, and /reasoning [show|hide] which toggles whether the thinking block is visible in the response. Neither control exists in the Web UI — users get whatever the model defaults to and cannot change it without editing config.yaml on the server and restarting.
Current state
In the CLI, /reasoning high calls _parse_reasoning_config("high") which produces {"enabled": true, "effort": "high"} and stores it in agent.reasoning_effort in config.yaml. On the next turn the agent is re-initialized with reasoning_config set, which flows into the model API call as extra_body["reasoning"] (for OpenRouter), thinking kwargs (for Anthropic direct), or reasoning.effort (for Codex/Responses API).
In the Web UI, _run_agent_streaming() (api/streaming.py) constructs the AIAgent with no reasoning_config argument at all. The streaming endpoint POST /api/chat/start also accepts no reasoning_effort field. The Web UI does correctly stream and render reasoning SSE events (thinking blocks), but it cannot set the effort level that generates them.
Proposed solution
Two surfaces:
1. Per-session slash command — /reasoning [level] and /reasoning [show|hide] in the Web UI command list (static/commands.js). These pass through to the agent as regular messages (same pattern as skill slash commands — issue #460). The agent already handles these correctly when sent as user messages. The dropdown should show the valid levels as autocomplete hints.
2. Persistent setting in the Settings panel — a "Reasoning effort" selector (none / minimal / low / medium / high / xhigh) that writes to /api/settings and is forwarded to the agent config. This lets users set a default level that persists across sessions, not just the current one.
Backend change required: _run_agent_streaming() needs to accept a reasoning_effort parameter and pass it as reasoning_config to AIAgent. The /api/chat/start POST body should accept reasoning_effort. The /api/settings POST handler should accept and persist reasoning_effort to the agent's config.yaml (not just the WebUI settings store).
Reasoning visibility — the existing thinking-block toggle in the UI already handles show/hide at render time, so /reasoning show|hide could just toggle that display setting directly.
Valid effort levels
From hermes_cli/commands.py: none, minimal, low, medium, high, xhigh
none → {"enabled": false} — disables reasoning entirely
minimal–xhigh → {"enabled": true, "effort": "<level>"}
- Empty / unset → model default (currently
medium on OpenRouter)
Files involved
~/.hermes/hermes-agent/hermes_constants.py — parse_reasoning_effort()
~/hermes-webui-public/api/streaming.py — _run_agent_streaming()
~/hermes-webui-public/api/routes.py — /api/chat/start, /api/settings
~/hermes-webui-public/static/commands.js — add /reasoning to COMMANDS
~/hermes-webui-public/static/panels.js — Settings panel reasoning selector
Summary
The Web UI has no way to control reasoning effort. The CLI offers
/reasoning [none|minimal|low|medium|high|xhigh]which sets the effort level for the current session, and/reasoning [show|hide]which toggles whether the thinking block is visible in the response. Neither control exists in the Web UI — users get whatever the model defaults to and cannot change it without editingconfig.yamlon the server and restarting.Current state
In the CLI,
/reasoning highcalls_parse_reasoning_config("high")which produces{"enabled": true, "effort": "high"}and stores it inagent.reasoning_effortinconfig.yaml. On the next turn the agent is re-initialized withreasoning_configset, which flows into the model API call asextra_body["reasoning"](for OpenRouter),thinkingkwargs (for Anthropic direct), orreasoning.effort(for Codex/Responses API).In the Web UI,
_run_agent_streaming()(api/streaming.py) constructs theAIAgentwith noreasoning_configargument at all. The streaming endpointPOST /api/chat/startalso accepts noreasoning_effortfield. The Web UI does correctly stream and renderreasoningSSE events (thinking blocks), but it cannot set the effort level that generates them.Proposed solution
Two surfaces:
1. Per-session slash command —
/reasoning [level]and/reasoning [show|hide]in the Web UI command list (static/commands.js). These pass through to the agent as regular messages (same pattern as skill slash commands — issue #460). The agent already handles these correctly when sent as user messages. The dropdown should show the valid levels as autocomplete hints.2. Persistent setting in the Settings panel — a "Reasoning effort" selector (none / minimal / low / medium / high / xhigh) that writes to
/api/settingsand is forwarded to the agent config. This lets users set a default level that persists across sessions, not just the current one.Backend change required:
_run_agent_streaming()needs to accept areasoning_effortparameter and pass it asreasoning_configtoAIAgent. The/api/chat/startPOST body should acceptreasoning_effort. The/api/settingsPOST handler should accept and persistreasoning_effortto the agent'sconfig.yaml(not just the WebUI settings store).Reasoning visibility — the existing thinking-block toggle in the UI already handles show/hide at render time, so
/reasoning show|hidecould just toggle that display setting directly.Valid effort levels
From
hermes_cli/commands.py:none,minimal,low,medium,high,xhighnone→{"enabled": false}— disables reasoning entirelyminimal–xhigh→{"enabled": true, "effort": "<level>"}mediumon OpenRouter)Files involved
~/.hermes/hermes-agent/hermes_constants.py—parse_reasoning_effort()~/hermes-webui-public/api/streaming.py—_run_agent_streaming()~/hermes-webui-public/api/routes.py—/api/chat/start,/api/settings~/hermes-webui-public/static/commands.js— add/reasoningtoCOMMANDS~/hermes-webui-public/static/panels.js— Settings panel reasoning selector