fix(agent): fail open on malformed telegram extra config
Guard both extra lookups with isinstance(dict) before merging, so a truthy non-mapping `extra` value (e.g. `extra: "true"`) degrades to the base Telegram hint instead of raising TypeError and aborting system-prompt construction. Keep the narrowed except ImportError. Add an integration test exercising the real config path (HERMES_HOME + gateway.platforms.telegram.extra.rich_messages) and a regression test for the malformed-extra fail-open path. The integration test fails on main and passes with the fix.
This commit is contained in:
parent
9f582aca1d
commit
95520b812f
|
|
@ -454,8 +454,12 @@ def build_system_prompt_parts(agent: Any, system_message: Optional[str] = None)
|
|||
try:
|
||||
from hermes_cli.config import load_config_readonly
|
||||
_cfg = load_config_readonly()
|
||||
_gw_tg_extra = (((_cfg.get("gateway") or {}).get("platforms") or {}).get("telegram") or {}).get("extra") or {}
|
||||
_top_tg_extra = ((_cfg.get("platforms") or {}).get("telegram") or {}).get("extra") or {}
|
||||
_gw_tg_extra = (((_cfg.get("gateway") or {}).get("platforms") or {}).get("telegram") or {}).get("extra")
|
||||
_top_tg_extra = ((_cfg.get("platforms") or {}).get("telegram") or {}).get("extra")
|
||||
if not isinstance(_gw_tg_extra, dict):
|
||||
_gw_tg_extra = {}
|
||||
if not isinstance(_top_tg_extra, dict):
|
||||
_top_tg_extra = {}
|
||||
_tg_extra = {**_gw_tg_extra, **_top_tg_extra}
|
||||
if _tg_extra.get("rich_messages"):
|
||||
_default_hint = _default_hint.rstrip() + " " + TELEGRAM_RICH_MESSAGES_HINT
|
||||
|
|
|
|||
|
|
@ -259,6 +259,48 @@ class TestTelegramRichMessagesHint:
|
|||
assert "lean into it" not in stable
|
||||
|
||||
|
||||
def test_gateway_rich_messages_integration_via_real_config(self, tmp_path, monkeypatch):
|
||||
"""End-to-end through the real config-resolution chain: a config.yaml
|
||||
under HERMES_HOME with ``gateway.platforms.telegram.extra.rich_messages``
|
||||
must activate the rich hint. ``load_config_readonly`` is NOT mocked here,
|
||||
so this guards against the exact path-mismatch bug this PR fixes.
|
||||
"""
|
||||
config_yaml = (
|
||||
"gateway:\n"
|
||||
" platforms:\n"
|
||||
" telegram:\n"
|
||||
" extra:\n"
|
||||
" rich_messages: true\n"
|
||||
)
|
||||
home = tmp_path / "hermes_home"
|
||||
home.mkdir()
|
||||
(home / "config.yaml").write_text(config_yaml)
|
||||
|
||||
monkeypatch.setenv("HERMES_HOME", str(home))
|
||||
# Point config resolution at the temp file without mocking the loader:
|
||||
# mirror the pattern used in test_config_env_expansion.py.
|
||||
from hermes_cli import config as _cfgmod
|
||||
monkeypatch.setattr(_cfgmod, "get_config_path", lambda: home / "config.yaml")
|
||||
|
||||
agent = _make_agent(platform="telegram")
|
||||
stable = _stable_prompt(agent)
|
||||
assert "lean into it" in stable
|
||||
assert "task lists" in stable
|
||||
|
||||
def test_malformed_extra_value_falls_back_to_base_hint(self, tmp_path, monkeypatch):
|
||||
"""A truthy non-mapping ``extra`` must not crash prompt construction —
|
||||
it should fail open to the base hint (Tek's fail-open concern).
|
||||
"""
|
||||
agent = _make_agent(platform="telegram")
|
||||
with patch("hermes_cli.config.load_config_readonly") as mock_cfg:
|
||||
mock_cfg.return_value = {
|
||||
"gateway": {"platforms": {"telegram": {"extra": "not-a-map"}}}
|
||||
}
|
||||
stable = _stable_prompt(agent)
|
||||
assert "Standard Markdown is automatically converted" in stable
|
||||
assert "lean into it" not in stable
|
||||
|
||||
|
||||
_SKILLS = "SKILLS_INDEX_SENTINEL"
|
||||
_CONTEXT = "CONTEXT_FILES_SENTINEL"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue