From 429da6cbcedb891b25f92dc6a34c01e86a36c79e Mon Sep 17 00:00:00 2001 From: Tranquil-Flow Date: Fri, 10 Apr 2026 13:22:38 +1000 Subject: [PATCH] fix(gateway): route /background through active-session bypass When /background was sent during an active run, it was not in the platform adapter's bypass list and fell through to the interrupt path instead of spawning a parallel background task. Add "background" to the active-session command bypass in the platform adapter, and add an early return in the gateway runner's running-agent guard to route /background to _handle_background_command() before it reaches the default interrupt logic. Fixes #6827 --- gateway/platforms/base.py | 2 +- gateway/run.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/gateway/platforms/base.py b/gateway/platforms/base.py index e57a84bb33..7ba1679fc6 100644 --- a/gateway/platforms/base.py +++ b/gateway/platforms/base.py @@ -1303,7 +1303,7 @@ class BasePlatformAdapter(ABC): # session lifecycle and its cleanup races with the running task # (see PR #4926). cmd = event.get_command() - if cmd in ("approve", "deny", "status", "stop", "new", "reset"): + if cmd in ("approve", "deny", "status", "stop", "new", "reset", "background"): logger.debug( "[%s] Command '/%s' bypassing active-session guard for %s", self.name, cmd, session_key, diff --git a/gateway/run.py b/gateway/run.py index b16374a5b8..982b9f321d 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -1991,6 +1991,11 @@ class GatewayRunner: return await self._handle_approve_command(event) return await self._handle_deny_command(event) + # /background must bypass the running-agent guard — it starts a + # parallel task and must never interrupt the active conversation. + if _cmd_def_inner and _cmd_def_inner.name == "background": + return await self._handle_background_command(event) + if event.message_type == MessageType.PHOTO: logger.debug("PRIORITY photo follow-up for session %s — queueing without interrupt", _quick_key[:20]) adapter = self.adapters.get(source.platform)