From 242ec45f456ebfc0f5e4a67e49ccde3863e2167a Mon Sep 17 00:00:00 2001 From: xxxigm Date: Sun, 21 Jun 2026 19:35:27 +0700 Subject: [PATCH] fix(gateway): don't lazy-install SDKs for unconfigured platforms on startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For adapter plugins, ``PlatformEntry.check_fn`` doubles as a lazy installer: calling it pip-installs the platform SDK as a side effect (see e.g. ``plugins/platforms/discord/adapter.py::check_discord_requirements``). The enablement sweep in ``_apply_env_overrides`` called ``check_fn`` for every registered plugin platform unconditionally, so a single ``load_gateway_config()`` — which the desktop/dashboard readiness probe ``GET /api/status`` awaits synchronously — pip-installed Discord, Telegram, Slack, Feishu and Dingtalk even when the user configured none of them (``platforms: none``). On a slow or restricted network the installs ran long enough to block the event loop past the desktop's readiness timeouts, so the app timed out, killed and re-spawned the backend, and boot-looped (stuck at 94%). Consult the cheap ``is_connected`` credential check FIRST and only run the install-triggering ``check_fn`` for platforms that are already enabled or actually configured. Auto-enable-by-credentials is unchanged: a platform with its token set still gets its SDK installed and enabled. --- gateway/config.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/gateway/config.py b/gateway/config.py index a29f7306924..d3c85e86818 100644 --- a/gateway/config.py +++ b/gateway/config.py @@ -1907,12 +1907,10 @@ def _apply_env_overrides(config: GatewayConfig) -> None: from gateway.platform_registry import platform_registry for entry in platform_registry.plugin_entries(): try: - if not entry.check_fn(): - continue + platform = Platform(entry.name) except Exception as e: - logger.debug("check_fn for %s raised: %s", entry.name, e) + logger.debug("unknown platform name %r: %s", entry.name, e) continue - platform = Platform(entry.name) existing_cfg = config.platforms.get(platform) # Respect an explicit ``enabled: false`` (YAML / gateway.json / # dashboard PUT). ``_enabled_explicit`` is set in @@ -1996,6 +1994,22 @@ def _apply_env_overrides(config: GatewayConfig) -> None: entry.name, ) continue + # Verify dependencies LAST — only for platforms that are already + # enabled or passed the credential gate above. For adapter plugins + # ``check_fn`` lazy-INSTALLS the platform SDK (pip) as a side + # effect, so running it as an unconditional sweep over every + # registered platform made ``load_gateway_config()`` pip-install + # Discord/Telegram/Slack/Feishu/Dingtalk on every call — including + # the desktop/dashboard readiness probe (``GET /api/status``, which + # awaits this synchronously) — even when the user configured none + # of them. That blocked startup until every install finished and + # caused the desktop app to time out and boot-loop (stuck at 94%). + try: + if not entry.check_fn(): + continue + except Exception as e: + logger.debug("check_fn for %s raised: %s", entry.name, e) + continue if platform not in config.platforms: config.platforms[platform] = PlatformConfig() config.platforms[platform].enabled = True