refactor: consolidate get_hermes_home() and parse_reasoning_effort() (#3062)

Centralizes two widely-duplicated patterns into hermes_constants.py:

1. get_hermes_home() — Path resolution for ~/.hermes (HERMES_HOME env var)
   - Was copy-pasted inline across 30+ files as:
     Path(os.getenv("HERMES_HOME", Path.home() / ".hermes"))
   - Now defined once in hermes_constants.py (zero-dependency module)
   - hermes_cli/config.py re-exports it for backward compatibility
   - Removed local wrapper functions in honcho_integration/client.py,
     tools/website_policy.py, tools/tirith_security.py, hermes_cli/uninstall.py

2. parse_reasoning_effort() — Reasoning effort string validation
   - Was copy-pasted in cli.py, gateway/run.py, cron/scheduler.py
   - Same validation logic: check against (xhigh, high, medium, low, minimal, none)
   - Now defined once in hermes_constants.py, called from all 3 locations
   - Warning log for unknown values kept at call sites (context-specific)

31 files changed, net +31 lines (125 insertions, 94 deletions)
Full test suite: 6179 passed, 0 failed
This commit is contained in:
Teknium
2026-03-25 15:54:28 -07:00
committed by GitHub
parent e0cfc089da
commit 77bcaba2d7
31 changed files with 125 additions and 94 deletions

View File

@@ -76,7 +76,8 @@ _ensure_ssl_certs()
sys.path.insert(0, str(Path(__file__).parent.parent))
# Resolve Hermes home directory (respects HERMES_HOME override)
_hermes_home = Path(os.getenv("HERMES_HOME", Path.home() / ".hermes"))
from hermes_constants import get_hermes_home
_hermes_home = get_hermes_home()
# Load environment variables from ~/.hermes/.env first.
# User-managed env files should override stale shell exports on restart.
@@ -805,6 +806,7 @@ class GatewayRunner:
"medium", "low", "minimal", "none". Returns None to use default
(medium).
"""
from hermes_constants import parse_reasoning_effort
effort = ""
try:
import yaml as _y
@@ -817,16 +819,10 @@ class GatewayRunner:
pass
if not effort:
effort = os.getenv("HERMES_REASONING_EFFORT", "")
if not effort:
return None
effort = effort.lower().strip()
if effort == "none":
return {"enabled": False}
valid = ("xhigh", "high", "medium", "low", "minimal")
if effort in valid:
return {"enabled": True, "effort": effort}
logger.warning("Unknown reasoning_effort '%s', using default (medium)", effort)
return None
result = parse_reasoning_effort(effort)
if effort and effort.strip() and result is None:
logger.warning("Unknown reasoning_effort '%s', using default (medium)", effort)
return result
@staticmethod
def _load_show_reasoning() -> bool:
@@ -5743,7 +5739,7 @@ async def start_gateway(config: Optional[GatewayConfig] = None, replace: bool =
except Exception:
pass
else:
hermes_home = os.getenv("HERMES_HOME", "~/.hermes")
hermes_home = str(get_hermes_home())
logger.error(
"Another gateway instance is already running (PID %d, HERMES_HOME=%s). "
"Use 'hermes gateway restart' to replace it, or 'hermes gateway stop' first.",

View File

@@ -17,6 +17,7 @@ import os
import sys
from datetime import datetime, timezone
from pathlib import Path
from hermes_constants import get_hermes_home
from typing import Any, Optional
_GATEWAY_KIND = "hermes-gateway"
@@ -26,7 +27,7 @@ _LOCKS_DIRNAME = "gateway-locks"
def _get_pid_path() -> Path:
"""Return the path to the gateway PID file, respecting HERMES_HOME."""
home = Path(os.getenv("HERMES_HOME", Path.home() / ".hermes"))
home = get_hermes_home()
return home / "gateway.pid"