From 88cc687278e7352b1a395c5133bf23b7a3f0a5e5 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Mon, 6 Jul 2026 09:38:14 +0800 Subject: [PATCH] fix(qqbot): accept gateway reconnect flag Match the BasePlatformAdapter.connect(is_reconnect=...) contract so QQBot can be started by the gateway reconnect path. Add a regression test that calls QQAdapter.connect(is_reconnect=True). --- gateway/platforms/qqbot/adapter.py | 9 +++++++-- tests/gateway/test_qqbot.py | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/gateway/platforms/qqbot/adapter.py b/gateway/platforms/qqbot/adapter.py index 2639ab52fdd32..718d66be47f8f 100644 --- a/gateway/platforms/qqbot/adapter.py +++ b/gateway/platforms/qqbot/adapter.py @@ -278,8 +278,13 @@ def enforces_own_access_policy(self) -> bool: # Connection lifecycle # ------------------------------------------------------------------ - async def connect(self) -> bool: - """Authenticate, obtain gateway URL, and open the WebSocket.""" + async def connect(self, *, is_reconnect: bool = False) -> bool: + """Authenticate, obtain gateway URL, and open the WebSocket. + + ``is_reconnect`` is accepted for compatibility with the gateway's + common PlatformAdapter.connect() contract. QQBot manages resume vs. + cold identify internally from its stored session state. + """ if not AIOHTTP_AVAILABLE: message = "QQ startup failed: aiohttp not installed" self._set_fatal_error("qq_missing_dependency", message, retryable=True) diff --git a/tests/gateway/test_qqbot.py b/tests/gateway/test_qqbot.py index d250a119e7416..1b57dd74cf42d 100644 --- a/tests/gateway/test_qqbot.py +++ b/tests/gateway/test_qqbot.py @@ -190,6 +190,20 @@ def test_connect_uses_redirect_guard_hook(self): assert kwargs.get("follow_redirects") is True assert kwargs.get("event_hooks", {}).get("response") == [_ssrf_redirect_guard] + def test_connect_accepts_gateway_reconnect_flag(self): + """QQBot must match BasePlatformAdapter.connect(is_reconnect=...).""" + from gateway.platforms.qqbot import QQAdapter + + adapter = QQAdapter(_make_config(app_id="a", client_secret="b")) + adapter._ensure_token = mock.AsyncMock(side_effect=RuntimeError("stop after client creation")) + + # Regression guard: gateway.run calls this exact keyword during cold + # boot and reconnect. QQBot may ignore the flag internally, but it must + # accept it to satisfy the platform adapter contract. + connected = asyncio.run(adapter.connect(is_reconnect=True)) + + assert connected is False + # --------------------------------------------------------------------------- # WebSocket proxy handling