diff --git a/gateway/config_loader.py b/gateway/config_loader.py index 2c97082b9f..10bc91fa90 100644 --- a/gateway/config_loader.py +++ b/gateway/config_loader.py @@ -385,13 +385,15 @@ def read_yaml_layers(home: Path) -> dict: (``gateway.relay.relay_explicitly_disabled``) reads through here so it cannot disagree with ``load_gateway_config()`` on which files count. """ - import yaml - config_yaml_path = home / "config.yaml" yaml_cfg: dict = {} if config_yaml_path.exists(): + # The installer seeds config.yaml by copying cli-config.yaml.example (~120 KB, almost all + # comments), and nothing caches this loader — so the pure-Python parser dominates the load. + from utils import fast_safe_load + with open(config_yaml_path, encoding="utf-8") as f: - yaml_cfg = yaml.safe_load(f) or {} + yaml_cfg = fast_safe_load(f) or {} from hermes_cli.config import _expand_env_vars diff --git a/hermes_cli/managed_scope.py b/hermes_cli/managed_scope.py index 888080075d..8f9b0804ec 100644 --- a/hermes_cli/managed_scope.py +++ b/hermes_cli/managed_scope.py @@ -15,7 +15,6 @@ import threading from pathlib import Path from typing import Dict, Optional -import yaml # Stale-module bridge: this module binds ``utils.file_signature`` at import time, so a fresh # import in a post-pull updater process (pre-handoff purge keeps root modules cached) dies @@ -107,7 +106,9 @@ def _load_managed_file(name: str, cache: Dict[str, tuple], parse) -> dict: def load_managed_config() -> dict: """Parsed managed config.yaml, or {} when absent/malformed (fail-open).""" - return _load_managed_file("config.yaml", _CONFIG_CACHE, lambda p: yaml.safe_load(p.read_text(encoding="utf-8")) or {}) + from utils import fast_safe_load + + return _load_managed_file("config.yaml", _CONFIG_CACHE, lambda p: fast_safe_load(p.read_text(encoding="utf-8")) or {}) def load_managed_env() -> Dict[str, str]: diff --git a/hermes_cli/plugins_cmd.py b/hermes_cli/plugins_cmd.py index cc84dc7662..760331751c 100644 --- a/hermes_cli/plugins_cmd.py +++ b/hermes_cli/plugins_cmd.py @@ -280,9 +280,10 @@ def _has_portable_manifest(plugin_dir: Path) -> bool: def _load_yaml_manifest(manifest_file: Path): """``yaml.safe_load`` of *manifest_file* (``{}`` when empty); raises on any read/parse error.""" - import yaml + from utils import fast_safe_load + with open(manifest_file, encoding="utf-8") as f: - return yaml.safe_load(f) or {} + return fast_safe_load(f) or {} def _read_manifest(plugin_dir: Path) -> dict: diff --git a/plugins/plugin_loader.py b/plugins/plugin_loader.py index 9c93a12644..f21c1a5eff 100644 --- a/plugins/plugin_loader.py +++ b/plugins/plugin_loader.py @@ -56,9 +56,10 @@ def iter_plugin_dirs(root: Path) -> List[Path]: def read_plugin_description(plugin_dir: Path) -> str: """Return ``description`` from ``plugin.yaml`` (empty string if absent/unreadable).""" try: - import yaml + from utils import fast_safe_load + with open(plugin_dir / "plugin.yaml", encoding="utf-8-sig") as f: - meta = yaml.safe_load(f) or {} + meta = fast_safe_load(f) or {} return meta.get("description", "") except Exception: return "" diff --git a/providers/__init__.py b/providers/__init__.py index 66b276770b..8719a4f8e7 100644 --- a/providers/__init__.py +++ b/providers/__init__.py @@ -288,9 +288,9 @@ def _declares_model_provider_kind(plugin_dir: Path) -> bool: except Exception: return False try: - import yaml + from utils import fast_safe_load - data = yaml.safe_load(text) + data = fast_safe_load(text) if isinstance(data, dict): return str(data.get("kind", "")).strip() == "model-provider" except Exception: diff --git a/tests/gateway/test_gateway_streaming_nested_config.py b/tests/gateway/test_gateway_streaming_nested_config.py index 54a8c56565..14530f49af 100644 --- a/tests/gateway/test_gateway_streaming_nested_config.py +++ b/tests/gateway/test_gateway_streaming_nested_config.py @@ -18,7 +18,7 @@ def _load_with_yaml_dict(yaml_dict: dict): patch("builtins.open", create=True) as mock_file: mock_file.return_value.__enter__ = lambda s: s mock_file.return_value.__exit__ = MagicMock(return_value=False) - with patch("yaml.safe_load", return_value=yaml_dict): + with patch("utils.fast_safe_load", return_value=yaml_dict): return load_gateway_config()