feat(gateway): also gate pre-restart "Gateway restarting" notification

Extend the gateway_restart_notification flag to cover
_notify_active_sessions_of_shutdown — the message that fires just
before drain ("⚠️ Gateway restarting — Your current task will be
interrupted. Send any message after restart and I'll try to resume
where you left off.") sent to active sessions and home channels.

Same operator/end-user reasoning: on a Slack workspace shared with
end users, "Gateway restarting" reads as "the bot is broken" — the
operator should be able to suppress it consistently with the other
two lifecycle pings rather than having a partial opt-out.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Guillaume Meyer 2026-05-06 15:55:01 +00:00 committed by Teknium
parent b71f80e6ce
commit 7df6115199
2 changed files with 50 additions and 0 deletions

View file

@ -2458,6 +2458,14 @@ class GatewayRunner:
if not adapter:
continue
platform_cfg = self.config.platforms.get(platform)
if platform_cfg is not None and not platform_cfg.gateway_restart_notification:
logger.info(
"Shutdown notification suppressed for active session: %s has gateway_restart_notification=false",
platform_str,
)
continue
# Include thread_id if present so the message lands in the
# correct forum topic / thread.
metadata = {"thread_id": thread_id} if thread_id else None
@ -2488,6 +2496,14 @@ class GatewayRunner:
if not home or not home.chat_id:
continue
platform_cfg = self.config.platforms.get(platform)
if platform_cfg is not None and not platform_cfg.gateway_restart_notification:
logger.info(
"Shutdown notification suppressed for home channel: %s has gateway_restart_notification=false",
platform.value,
)
continue
dedup_key = (platform.value, str(home.chat_id), str(home.thread_id) if home.thread_id else None)
if dedup_key in notified:
continue

View file

@ -257,6 +257,40 @@ async def test_shutdown_notification_send_failure_does_not_block():
await runner._notify_active_sessions_of_shutdown()
@pytest.mark.asyncio
async def test_shutdown_notification_suppressed_when_flag_disabled():
"""Active-session ping is muted when gateway_restart_notification=False on the platform."""
from gateway.config import Platform
runner, adapter = make_restart_runner()
runner._restart_requested = True
runner.config.platforms[Platform.TELEGRAM].gateway_restart_notification = False
session_key = "agent:main:telegram:dm:999"
runner._running_agents[session_key] = MagicMock()
await runner._notify_active_sessions_of_shutdown()
assert adapter.sent == []
@pytest.mark.asyncio
async def test_shutdown_notification_home_channel_suppressed_when_flag_disabled():
"""Home-channel ping during shutdown is muted when the flag is False."""
from gateway.config import HomeChannel, Platform
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
await runner._notify_active_sessions_of_shutdown()
assert adapter.sent == []
@pytest.mark.asyncio
async def test_shutdown_notification_uses_persisted_origin_for_colon_ids():
"""Shutdown notifications should route from persisted origin, not reparsed keys."""