perf(cold-start): mitigate ~14s GIL stall during backend init (#60800)

Three fixes for the Desktop/TUI cold-start stall where the event loop
is blocked for ~14s between HERMES_BACKEND_READY and the first
prompt (#60800):

1. copilot_auth: skip  subprocess fallback when any
   Copilot env var is explicitly set (even if invalid). The user
   expressed token intent via env var; silently substituting a CLI
   token is surprising and the subprocess adds up to 5s on Windows.

2. tui_gateway/ws: run resolve_skin() via asyncio.to_thread so config
   loading + skin engine init do not block the WS read loop during
   the cold-start RPC burst.

3. web_server: extend _warm_gateway_module to pre-import the heavy
   module chains (auth, copilot_auth, runtime_provider, skin_engine,
   inventory, model_switch) that the first WS connection + RPC burst
   would otherwise import on the loop thread. These trigger .pyc
   compilation and Defender scans on Windows (15-30s per the existing
   comment) and were not covered by the original gateway-only warm.

Tests: 5 new tests in test_cold_start_gil_stall.py + 2 new tests in
test_copilot_auth.py. All 36 copilot_auth tests + 16 ws/web_server
tests pass.
This commit is contained in:
jinglun010
2026-07-08 17:10:00 +08:00
committed by kshitij
parent 733e7d26c0
commit 25a9c2c245
5 changed files with 232 additions and 6 deletions
+14 -1
View File
@@ -79,9 +79,11 @@ def resolve_copilot_token() -> tuple[str, str]:
Raises ValueError if only a classic PAT is available.
"""
# 1. Check env vars in priority order
any_env_var_set = False
for env_var in COPILOT_ENV_VARS:
val = os.getenv(env_var, "").strip()
if val:
any_env_var_set = True
valid, msg = validate_copilot_token(val)
if not valid:
logger.warning(
@@ -90,7 +92,18 @@ def resolve_copilot_token() -> tuple[str, str]:
continue
return val, env_var
# 2. Fall back to gh auth token
# 2. Fall back to gh auth token — but ONLY when no Copilot env var was
# explicitly set. When the user exported GITHUB_TOKEN (even an
# unsupported classic PAT), their intent is to use *that* token, not
# to silently substitute one from the gh CLI credential store.
# Skipping the subprocess here also avoids a slow `gh auth token`
# call (up to 5s timeout on Windows) on every cold start that scans
# Copilot auth state — a measurable contributor to the ~14s
# cold-start stall (#60800). The user can run `copilot login` or
# set a supported token (gho_*/github_pat_*/ghu_) explicitly.
if any_env_var_set:
return "", ""
token = _try_gh_cli_token()
if token:
valid, msg = validate_copilot_token(token)