diff --git a/gateway/run.py b/gateway/run.py index 16127aae24..a38a81bd98 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -19424,10 +19424,21 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew except Exception: _bg_procs = None - decision = mgr.evaluate_after_turn( - final_response or "", - user_initiated=True, - background_processes=_bg_procs, + # evaluate_after_turn calls judge_goal() which makes a synchronous + # HTTP request to the auxiliary LLM. Running it on the event-loop + # thread would block Discord heartbeats for 10-40 s and cause + # connection flaps, so we offload it to a thread-pool executor. + # _run_in_executor_with_context (not bare run_in_executor): the + # profile secret scope and auxiliary runtime context are contextvars, + # and a default-executor hop would drop them — aux-client provider + # resolution would then read credentials unscoped and fail under + # multiplexing (same pattern as compression in slash_commands.py). + decision = await self._run_in_executor_with_context( + lambda: mgr.evaluate_after_turn( + final_response or "", + user_initiated=True, + background_processes=_bg_procs, + ), ) msg = decision.get("message") or ""