mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-10 03:22:05 +00:00
feat(gateway): per-platform gateway_restart_notification flag
Adds an opt-out toggle on PlatformConfig that gates both restart
lifecycle pings: the "♻ Gateway restarted" message sent to the chat
that issued /restart, and the "♻️ Gateway online" home-channel
startup notification. Defaults to True so existing deployments are
unaffected.
The motivating split is operator vs. end-user surfaces: a back-channel
like Telegram should keep these pings, while a Slack workspace shared
with end users should not surface gateway lifecycle noise.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
33bf5f6292
commit
b71f80e6ce
4 changed files with 120 additions and 4 deletions
|
|
@ -57,6 +57,19 @@ class TestPlatformConfigRoundtrip:
|
|||
restored = PlatformConfig.from_dict({"enabled": "false"})
|
||||
assert restored.enabled is False
|
||||
|
||||
def test_gateway_restart_notification_defaults_true(self):
|
||||
assert PlatformConfig().gateway_restart_notification is True
|
||||
assert PlatformConfig.from_dict({}).gateway_restart_notification is True
|
||||
|
||||
def test_gateway_restart_notification_roundtrip_false(self):
|
||||
pc = PlatformConfig(enabled=True, gateway_restart_notification=False)
|
||||
restored = PlatformConfig.from_dict(pc.to_dict())
|
||||
assert restored.gateway_restart_notification is False
|
||||
|
||||
def test_gateway_restart_notification_coerces_quoted_false(self):
|
||||
restored = PlatformConfig.from_dict({"gateway_restart_notification": "false"})
|
||||
assert restored.gateway_restart_notification is False
|
||||
|
||||
|
||||
class TestGetConnectedPlatforms:
|
||||
def test_returns_enabled_with_token(self):
|
||||
|
|
|
|||
|
|
@ -496,6 +496,82 @@ async def test_send_restart_notification_logs_warning_on_sendresult_failure(
|
|||
assert not notify_path.exists()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_home_channel_startup_notification_skipped_when_flag_disabled(
|
||||
tmp_path, monkeypatch
|
||||
):
|
||||
"""Per-platform opt-out: gateway_restart_notification=False mutes the home-channel ping."""
|
||||
monkeypatch.setattr(gateway_run, "_hermes_home", tmp_path)
|
||||
|
||||
runner, adapter = make_restart_runner()
|
||||
runner.config.platforms[Platform.TELEGRAM].home_channel = HomeChannel(
|
||||
platform=Platform.TELEGRAM,
|
||||
chat_id="home-42",
|
||||
name="Ops Home",
|
||||
)
|
||||
runner.config.platforms[Platform.TELEGRAM].gateway_restart_notification = False
|
||||
adapter.send = AsyncMock()
|
||||
|
||||
delivered = await runner._send_home_channel_startup_notifications()
|
||||
|
||||
assert delivered == set()
|
||||
adapter.send.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_home_channel_startup_notification_default_flag_true(
|
||||
tmp_path, monkeypatch
|
||||
):
|
||||
"""Default behavior is unchanged: missing flag means notifications still fire."""
|
||||
monkeypatch.setattr(gateway_run, "_hermes_home", tmp_path)
|
||||
|
||||
runner, adapter = make_restart_runner()
|
||||
# Sanity-check the dataclass default — guards against future refactors
|
||||
# silently flipping the default to False.
|
||||
assert runner.config.platforms[Platform.TELEGRAM].gateway_restart_notification is True
|
||||
|
||||
runner.config.platforms[Platform.TELEGRAM].home_channel = HomeChannel(
|
||||
platform=Platform.TELEGRAM,
|
||||
chat_id="home-42",
|
||||
name="Ops Home",
|
||||
)
|
||||
adapter.send = AsyncMock(return_value=SendResult(success=True, message_id="home"))
|
||||
|
||||
delivered = await runner._send_home_channel_startup_notifications()
|
||||
|
||||
assert delivered == {("telegram", "home-42", None)}
|
||||
adapter.send.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_restart_notification_skipped_when_flag_disabled(
|
||||
tmp_path, monkeypatch
|
||||
):
|
||||
"""The /restart originator's notification also honors the per-platform flag.
|
||||
|
||||
Slack used by end users → flag off → no "Gateway restarted" message even
|
||||
when an end user accidentally triggers /restart. The marker file is still
|
||||
cleaned up so the notification doesn't leak into the next boot.
|
||||
"""
|
||||
monkeypatch.setattr(gateway_run, "_hermes_home", tmp_path)
|
||||
|
||||
notify_path = tmp_path / ".restart_notify.json"
|
||||
notify_path.write_text(json.dumps({
|
||||
"platform": "telegram",
|
||||
"chat_id": "42",
|
||||
}))
|
||||
|
||||
runner, adapter = make_restart_runner()
|
||||
runner.config.platforms[Platform.TELEGRAM].gateway_restart_notification = False
|
||||
adapter.send = AsyncMock()
|
||||
|
||||
delivered_target = await runner._send_restart_notification()
|
||||
|
||||
assert delivered_target is None
|
||||
adapter.send.assert_not_called()
|
||||
assert not notify_path.exists()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_restart_notification_logs_info_on_sendresult_success(
|
||||
tmp_path, monkeypatch, caplog
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue