mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
refactor: migrate 10 config.yaml inline loaders to read_raw_config()
Replace 10 callsites across 6 files that manually opened config.yaml,
called yaml.safe_load(), and handled missing-file/parse-error fallbacks
with the new read_raw_config() helper from hermes_cli/config.py.
Each migrated site previously had 5-8 lines of boilerplate:
config_path = get_hermes_home() / 'config.yaml'
if config_path.exists():
import yaml
with open(config_path) as f:
cfg = yaml.safe_load(f) or {}
Now reduced to:
from hermes_cli.config import read_raw_config
cfg = read_raw_config()
Migrated files:
- tools/browser_tool.py (4 sites): command_timeout, cloud_provider,
allow_private_urls, record_sessions
- tools/env_passthrough.py: terminal.env_passthrough
- tools/credential_files.py: terminal.credential_files
- tools/transcription_tools.py: stt.model
- hermes_cli/commands.py: config-gated command resolution
- hermes_cli/auth.py (2 sites): model config read + provider reset
Skipped (intentionally):
- gateway/run.py: 10+ sites with local aliases, critical path
- hermes_cli/profiles.py: profile-specific config path
- hermes_cli/doctor.py: reads raw then writes fixes back
- agent/model_metadata.py: different file (context_length_cache.yaml)
- tools/website_policy.py: custom config_path param + error types
This commit is contained in:
parent
0d41fb0827
commit
b1a66d55b4
6 changed files with 68 additions and 114 deletions
|
|
@ -37,7 +37,7 @@ from typing import Any, Dict, List, Optional
|
||||||
import httpx
|
import httpx
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from hermes_cli.config import get_hermes_home, get_config_path
|
from hermes_cli.config import get_hermes_home, get_config_path, read_raw_config
|
||||||
from hermes_constants import OPENROUTER_BASE_URL
|
from hermes_constants import OPENROUTER_BASE_URL
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
@ -2214,14 +2214,7 @@ def _update_config_for_provider(
|
||||||
config_path = get_config_path()
|
config_path = get_config_path()
|
||||||
config_path.parent.mkdir(parents=True, exist_ok=True)
|
config_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
config: Dict[str, Any] = {}
|
config = read_raw_config()
|
||||||
if config_path.exists():
|
|
||||||
try:
|
|
||||||
loaded = yaml.safe_load(config_path.read_text()) or {}
|
|
||||||
if isinstance(loaded, dict):
|
|
||||||
config = loaded
|
|
||||||
except Exception:
|
|
||||||
config = {}
|
|
||||||
|
|
||||||
current_model = config.get("model")
|
current_model = config.get("model")
|
||||||
if isinstance(current_model, dict):
|
if isinstance(current_model, dict):
|
||||||
|
|
@ -2258,12 +2251,8 @@ def _reset_config_provider() -> Path:
|
||||||
if not config_path.exists():
|
if not config_path.exists():
|
||||||
return config_path
|
return config_path
|
||||||
|
|
||||||
try:
|
config = read_raw_config()
|
||||||
config = yaml.safe_load(config_path.read_text()) or {}
|
if not config:
|
||||||
except Exception:
|
|
||||||
return config_path
|
|
||||||
|
|
||||||
if not isinstance(config, dict):
|
|
||||||
return config_path
|
return config_path
|
||||||
|
|
||||||
model = config.get("model")
|
model = config.get("model")
|
||||||
|
|
|
||||||
|
|
@ -293,14 +293,8 @@ def _resolve_config_gates() -> set[str]:
|
||||||
if not gated:
|
if not gated:
|
||||||
return set()
|
return set()
|
||||||
try:
|
try:
|
||||||
import yaml
|
from hermes_cli.config import read_raw_config
|
||||||
from hermes_constants import get_hermes_home
|
cfg = read_raw_config()
|
||||||
config_path = str(get_hermes_home() / "config.yaml")
|
|
||||||
if os.path.exists(config_path):
|
|
||||||
with open(config_path, encoding="utf-8") as f:
|
|
||||||
cfg = yaml.safe_load(f) or {}
|
|
||||||
else:
|
|
||||||
cfg = {}
|
|
||||||
except Exception:
|
except Exception:
|
||||||
return set()
|
return set()
|
||||||
result: set[str] = set()
|
result: set[str] = set()
|
||||||
|
|
|
||||||
|
|
@ -146,15 +146,11 @@ def _get_command_timeout() -> int:
|
||||||
``DEFAULT_COMMAND_TIMEOUT`` (30s) if unset or unreadable.
|
``DEFAULT_COMMAND_TIMEOUT`` (30s) if unset or unreadable.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
hermes_home = get_hermes_home()
|
from hermes_cli.config import read_raw_config
|
||||||
config_path = hermes_home / "config.yaml"
|
cfg = read_raw_config()
|
||||||
if config_path.exists():
|
val = cfg.get("browser", {}).get("command_timeout")
|
||||||
import yaml
|
if val is not None:
|
||||||
with open(config_path) as f:
|
return max(int(val), 5) # Floor at 5s to avoid instant kills
|
||||||
cfg = yaml.safe_load(f) or {}
|
|
||||||
val = cfg.get("browser", {}).get("command_timeout")
|
|
||||||
if val is not None:
|
|
||||||
return max(int(val), 5) # Floor at 5s to avoid instant kills
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug("Could not read command_timeout from config: %s", e)
|
logger.debug("Could not read command_timeout from config: %s", e)
|
||||||
return DEFAULT_COMMAND_TIMEOUT
|
return DEFAULT_COMMAND_TIMEOUT
|
||||||
|
|
@ -259,23 +255,19 @@ def _get_cloud_provider() -> Optional[CloudBrowserProvider]:
|
||||||
|
|
||||||
_cloud_provider_resolved = True
|
_cloud_provider_resolved = True
|
||||||
try:
|
try:
|
||||||
hermes_home = get_hermes_home()
|
from hermes_cli.config import read_raw_config
|
||||||
config_path = hermes_home / "config.yaml"
|
cfg = read_raw_config()
|
||||||
if config_path.exists():
|
browser_cfg = cfg.get("browser", {})
|
||||||
import yaml
|
provider_key = None
|
||||||
with open(config_path) as f:
|
if isinstance(browser_cfg, dict) and "cloud_provider" in browser_cfg:
|
||||||
cfg = yaml.safe_load(f) or {}
|
provider_key = normalize_browser_cloud_provider(
|
||||||
browser_cfg = cfg.get("browser", {})
|
browser_cfg.get("cloud_provider")
|
||||||
provider_key = None
|
)
|
||||||
if isinstance(browser_cfg, dict) and "cloud_provider" in browser_cfg:
|
if provider_key == "local":
|
||||||
provider_key = normalize_browser_cloud_provider(
|
_cached_cloud_provider = None
|
||||||
browser_cfg.get("cloud_provider")
|
return None
|
||||||
)
|
if provider_key and provider_key in _PROVIDER_REGISTRY:
|
||||||
if provider_key == "local":
|
_cached_cloud_provider = _PROVIDER_REGISTRY[provider_key]()
|
||||||
_cached_cloud_provider = None
|
|
||||||
return None
|
|
||||||
if provider_key and provider_key in _PROVIDER_REGISTRY:
|
|
||||||
_cached_cloud_provider = _PROVIDER_REGISTRY[provider_key]()
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug("Could not read cloud_provider from config: %s", e)
|
logger.debug("Could not read cloud_provider from config: %s", e)
|
||||||
|
|
||||||
|
|
@ -326,13 +318,9 @@ def _allow_private_urls() -> bool:
|
||||||
_allow_private_urls_resolved = True
|
_allow_private_urls_resolved = True
|
||||||
_cached_allow_private_urls = False # safe default
|
_cached_allow_private_urls = False # safe default
|
||||||
try:
|
try:
|
||||||
hermes_home = get_hermes_home()
|
from hermes_cli.config import read_raw_config
|
||||||
config_path = hermes_home / "config.yaml"
|
cfg = read_raw_config()
|
||||||
if config_path.exists():
|
_cached_allow_private_urls = bool(cfg.get("browser", {}).get("allow_private_urls"))
|
||||||
import yaml
|
|
||||||
with open(config_path) as f:
|
|
||||||
cfg = yaml.safe_load(f) or {}
|
|
||||||
_cached_allow_private_urls = bool(cfg.get("browser", {}).get("allow_private_urls"))
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug("Could not read allow_private_urls from config: %s", e)
|
logger.debug("Could not read allow_private_urls from config: %s", e)
|
||||||
return _cached_allow_private_urls
|
return _cached_allow_private_urls
|
||||||
|
|
@ -1626,14 +1614,10 @@ def _maybe_start_recording(task_id: str):
|
||||||
if task_id in _recording_sessions:
|
if task_id in _recording_sessions:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
|
from hermes_cli.config import read_raw_config
|
||||||
hermes_home = get_hermes_home()
|
hermes_home = get_hermes_home()
|
||||||
config_path = hermes_home / "config.yaml"
|
cfg = read_raw_config()
|
||||||
record_enabled = False
|
record_enabled = cfg.get("browser", {}).get("record_sessions", False)
|
||||||
if config_path.exists():
|
|
||||||
import yaml
|
|
||||||
with open(config_path) as f:
|
|
||||||
cfg = yaml.safe_load(f) or {}
|
|
||||||
record_enabled = cfg.get("browser", {}).get("record_sessions", False)
|
|
||||||
|
|
||||||
if not record_enabled:
|
if not record_enabled:
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -137,40 +137,36 @@ def _load_config_files() -> List[Dict[str, str]]:
|
||||||
|
|
||||||
result: List[Dict[str, str]] = []
|
result: List[Dict[str, str]] = []
|
||||||
try:
|
try:
|
||||||
|
from hermes_cli.config import read_raw_config
|
||||||
hermes_home = _resolve_hermes_home()
|
hermes_home = _resolve_hermes_home()
|
||||||
config_path = hermes_home / "config.yaml"
|
cfg = read_raw_config()
|
||||||
if config_path.exists():
|
cred_files = cfg.get("terminal", {}).get("credential_files")
|
||||||
import yaml
|
if isinstance(cred_files, list):
|
||||||
|
hermes_home_resolved = hermes_home.resolve()
|
||||||
with open(config_path) as f:
|
for item in cred_files:
|
||||||
cfg = yaml.safe_load(f) or {}
|
if isinstance(item, str) and item.strip():
|
||||||
cred_files = cfg.get("terminal", {}).get("credential_files")
|
rel = item.strip()
|
||||||
if isinstance(cred_files, list):
|
if os.path.isabs(rel):
|
||||||
hermes_home_resolved = hermes_home.resolve()
|
logger.warning(
|
||||||
for item in cred_files:
|
"credential_files: rejected absolute config path %r", rel,
|
||||||
if isinstance(item, str) and item.strip():
|
)
|
||||||
rel = item.strip()
|
continue
|
||||||
if os.path.isabs(rel):
|
host_path = (hermes_home / rel).resolve()
|
||||||
logger.warning(
|
try:
|
||||||
"credential_files: rejected absolute config path %r", rel,
|
host_path.relative_to(hermes_home_resolved)
|
||||||
)
|
except ValueError:
|
||||||
continue
|
logger.warning(
|
||||||
host_path = (hermes_home / rel).resolve()
|
"credential_files: rejected config path traversal %r "
|
||||||
try:
|
"(resolves to %s, outside HERMES_HOME %s)",
|
||||||
host_path.relative_to(hermes_home_resolved)
|
rel, host_path, hermes_home_resolved,
|
||||||
except ValueError:
|
)
|
||||||
logger.warning(
|
continue
|
||||||
"credential_files: rejected config path traversal %r "
|
if host_path.is_file():
|
||||||
"(resolves to %s, outside HERMES_HOME %s)",
|
container_path = f"/root/.hermes/{rel}"
|
||||||
rel, host_path, hermes_home_resolved,
|
result.append({
|
||||||
)
|
"host_path": str(host_path),
|
||||||
continue
|
"container_path": container_path,
|
||||||
if host_path.is_file():
|
})
|
||||||
container_path = f"/root/.hermes/{rel}"
|
|
||||||
result.append({
|
|
||||||
"host_path": str(host_path),
|
|
||||||
"container_path": container_path,
|
|
||||||
})
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug("Could not read terminal.credential_files from config: %s", e)
|
logger.debug("Could not read terminal.credential_files from config: %s", e)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,18 +66,13 @@ def _load_config_passthrough() -> frozenset[str]:
|
||||||
|
|
||||||
result: set[str] = set()
|
result: set[str] = set()
|
||||||
try:
|
try:
|
||||||
from hermes_constants import get_hermes_home
|
from hermes_cli.config import read_raw_config
|
||||||
config_path = get_hermes_home() / "config.yaml"
|
cfg = read_raw_config()
|
||||||
if config_path.exists():
|
passthrough = cfg.get("terminal", {}).get("env_passthrough")
|
||||||
import yaml
|
if isinstance(passthrough, list):
|
||||||
|
for item in passthrough:
|
||||||
with open(config_path) as f:
|
if isinstance(item, str) and item.strip():
|
||||||
cfg = yaml.safe_load(f) or {}
|
result.add(item.strip())
|
||||||
passthrough = cfg.get("terminal", {}).get("env_passthrough")
|
|
||||||
if isinstance(passthrough, list):
|
|
||||||
for item in passthrough:
|
|
||||||
if isinstance(item, str) and item.strip():
|
|
||||||
result.add(item.strip())
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug("Could not read tools.env_passthrough from config: %s", e)
|
logger.debug("Could not read tools.env_passthrough from config: %s", e)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,12 +98,8 @@ def get_stt_model_from_config() -> Optional[str]:
|
||||||
Silently returns ``None`` on any error (missing file, bad YAML, etc.).
|
Silently returns ``None`` on any error (missing file, bad YAML, etc.).
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
import yaml
|
from hermes_cli.config import read_raw_config
|
||||||
cfg_path = get_hermes_home() / "config.yaml"
|
return read_raw_config().get("stt", {}).get("model")
|
||||||
if cfg_path.exists():
|
|
||||||
with open(cfg_path) as f:
|
|
||||||
data = yaml.safe_load(f) or {}
|
|
||||||
return data.get("stt", {}).get("model")
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue