fix(doctor): detect + repair stale HERMES_MAX_ITERATIONS .env ghost shadowing config.yaml (#38222)
* fix(doctor): detect + repair stale HERMES_MAX_ITERATIONS .env ghost shadowing config.yaml hermes doctor now flags when ~/.hermes/.env carries a HERMES_MAX_ITERATIONS value that disagrees with agent.max_turns in config.yaml, and 'hermes doctor --fix' removes the stale .env line so config.yaml is authoritative. 'hermes config show' surfaces the same drift inline under Max turns. The setup wizard stopped dual-writing this value, but users who edited only config.yaml from a pre-fix install keep a .env ghost. The gateway bridge normally overrides it at startup, but if the bridge bails on any earlier config-parse error the ghost silently wins — config says 400 while the gateway activity line reads N/90. The detector reads the .env FILE directly (load_env), not get_env_value/ os.environ, since the startup bridge may already have overwritten os.environ with the config value. Closes #17534. * fix(config): stop offering HERMES_MAX_ITERATIONS as an editable env var Removes HERMES_MAX_ITERATIONS from OPTIONAL_ENV_VARS so the dashboard env editor (PUT /api/env) and any env-var prompt no longer let a user write it to .env — which would recreate the stale ghost that shadows config.yaml's agent.max_turns (issue #17534). The iteration budget is configured only via config.yaml; the env var stays a read-only backward-compat fallback in the gateway/CLI, never a promoted write target. Regression test asserts it is absent from OPTIONAL_ENV_VARS.
This commit is contained in:
+15
-8
@@ -3346,13 +3346,6 @@ OPTIONAL_ENV_VARS = {
|
||||
"password": True,
|
||||
"category": "setting",
|
||||
},
|
||||
"HERMES_MAX_ITERATIONS": {
|
||||
"description": "Maximum tool-calling iterations per conversation (default: 90)",
|
||||
"prompt": "Max iterations",
|
||||
"url": None,
|
||||
"password": False,
|
||||
"category": "setting",
|
||||
},
|
||||
# HERMES_TOOL_PROGRESS and HERMES_TOOL_PROGRESS_MODE are deprecated —
|
||||
# now configured via display.tool_progress in config.yaml (off|new|all|verbose).
|
||||
# Gateway falls back to these env vars for backward compatibility.
|
||||
@@ -5593,7 +5586,21 @@ def show_config():
|
||||
print()
|
||||
print(color("◆ Model", Colors.CYAN, Colors.BOLD))
|
||||
print(f" Model: {config.get('model', 'not set')}")
|
||||
print(f" Max turns: {config.get('agent', {}).get('max_turns', DEFAULT_CONFIG['agent']['max_turns'])}")
|
||||
_cfg_max_turns = config.get('agent', {}).get('max_turns', DEFAULT_CONFIG['agent']['max_turns'])
|
||||
print(f" Max turns: {_cfg_max_turns}")
|
||||
# Warn on stale HERMES_MAX_ITERATIONS ghost in .env that disagrees with
|
||||
# config.yaml (issue #17534). Read the .env FILE directly so we catch the
|
||||
# ghost even when the gateway bridge already overrode os.environ.
|
||||
try:
|
||||
_env_ghost = load_env().get("HERMES_MAX_ITERATIONS")
|
||||
if _env_ghost is not None and str(_env_ghost).strip() != str(_cfg_max_turns).strip():
|
||||
print(color(
|
||||
f" ⚠ .env has stale HERMES_MAX_ITERATIONS={_env_ghost} "
|
||||
f"(run 'hermes doctor --fix' to remove)",
|
||||
Colors.YELLOW,
|
||||
))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Display
|
||||
print()
|
||||
|
||||
Reference in New Issue
Block a user