mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix(gateway): key-presence precedence for session_reset/stt nested fallback
Follow-up for salvaged PR #59779: the session_reset and stt fallbacks used truthiness/type checks, so a present-but-empty top-level value was silently replaced by the nested gateway.* form — inconsistent with the key-presence precedence every other key in the block uses. Switch both to 'key not in yaml_cfg' gating and add precedence regression tests.
This commit is contained in:
parent
e9bd3b6eeb
commit
73543744bc
2 changed files with 48 additions and 2 deletions
|
|
@ -1188,8 +1188,12 @@ def load_gateway_config() -> GatewayConfig:
|
|||
|
||||
# Map config.yaml keys → GatewayConfig.from_dict() schema.
|
||||
# Each key overwrites whatever gateway.json may have set.
|
||||
# Precedence contract: key-presence at the TOP LEVEL wins; the
|
||||
# nested gateway.* form is consulted only when the top-level key
|
||||
# is absent (not merely falsy/mistyped), so a present-but-empty
|
||||
# top-level value is never silently replaced by the nested one.
|
||||
sr = yaml_cfg.get("session_reset")
|
||||
if not (sr and isinstance(sr, dict)) and isinstance(gateway_section, dict):
|
||||
if "session_reset" not in yaml_cfg and isinstance(gateway_section, dict):
|
||||
sr = gateway_section.get("session_reset")
|
||||
if sr and isinstance(sr, dict):
|
||||
gw_data["default_reset_policy"] = sr
|
||||
|
|
@ -1208,7 +1212,7 @@ def load_gateway_config() -> GatewayConfig:
|
|||
)
|
||||
|
||||
stt_cfg = yaml_cfg.get("stt")
|
||||
if not isinstance(stt_cfg, dict) and isinstance(gateway_section, dict):
|
||||
if "stt" not in yaml_cfg and isinstance(gateway_section, dict):
|
||||
stt_cfg = gateway_section.get("stt")
|
||||
if isinstance(stt_cfg, dict):
|
||||
gw_data["stt"] = stt_cfg
|
||||
|
|
|
|||
|
|
@ -827,6 +827,48 @@ class TestLoadGatewayConfig:
|
|||
|
||||
assert config.always_log_local is True
|
||||
|
||||
def test_present_empty_top_level_session_reset_blocks_nested_fallback(self, tmp_path, monkeypatch):
|
||||
"""Key-presence precedence: a present (even empty) top-level
|
||||
session_reset must NOT be replaced by gateway.session_reset —
|
||||
the fallback fires only when the top-level key is absent."""
|
||||
hermes_home = tmp_path / ".hermes"
|
||||
hermes_home.mkdir()
|
||||
config_path = hermes_home / "config.yaml"
|
||||
config_path.write_text(
|
||||
"session_reset: {}\n"
|
||||
"gateway:\n"
|
||||
" session_reset:\n"
|
||||
" mode: idle\n"
|
||||
" idle_minutes: 30\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setenv("HERMES_HOME", str(hermes_home))
|
||||
|
||||
config = load_gateway_config()
|
||||
|
||||
# The nested value must not leak through the present top-level key.
|
||||
assert config.default_reset_policy.mode != "idle"
|
||||
|
||||
def test_present_top_level_stt_blocks_nested_fallback(self, tmp_path, monkeypatch):
|
||||
"""Key-presence precedence for stt: a present top-level stt (even
|
||||
mistyped/non-dict) must not be replaced by gateway.stt."""
|
||||
hermes_home = tmp_path / ".hermes"
|
||||
hermes_home.mkdir()
|
||||
config_path = hermes_home / "config.yaml"
|
||||
config_path.write_text(
|
||||
"stt: {}\n"
|
||||
"gateway:\n"
|
||||
" stt:\n"
|
||||
" enabled: false\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setenv("HERMES_HOME", str(hermes_home))
|
||||
|
||||
config = load_gateway_config()
|
||||
|
||||
# gateway.stt.enabled=false must NOT win over the present top-level stt.
|
||||
assert config.stt_enabled is True
|
||||
|
||||
def test_relay_platform_enabled_from_env_url(self, tmp_path, monkeypatch):
|
||||
"""GATEWAY_RELAY_URL must enable Platform.RELAY in config.platforms so
|
||||
start_gateway()'s connect loop actually dials the connector. Registering
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue