fix(gateway): launch restart watcher windowless on Windows (empty python.exe console after GUI update) - #58152
Conversation
The post-update respawn chain has two process legs: the watcher that polls the old gateway PID, and the gateway it respawns. NousResearch#52239 rewrote the gateway leg through windowless_gateway_restart_spec, but the watcher itself still launched via bare sys.executable — the venv's console python.exe. Under a uv venv that launcher re-execs the base console interpreter with default creationflags, a fresh CreateProcess that inherits none of the watcher's DETACHED / CREATE_NO_WINDOW flags, so a blank console window stays on screen for the whole drain window (up to ~2 minutes) after every GUI update. Route watcher_argv through the same windowless_gateway_restart_spec rewrite and thread the cwd + VIRTUAL_ENV/PYTHONPATH overlay into the watcher Popen so the base pythonw.exe can import hermes_cli and gateway.status without the venv launcher. Reproduced on Windows 11 (uv-managed venv, Desktop GUI auto-update): before the fix an empty python.exe console appears when the updater drains the old gateway and closes when the watcher exits; with the rewrite the whole chain is windowless. Same diagnosis as the reverted NousResearch#53850, adapted to the current _spawn_gateway_restart_watcher structure. Fixes NousResearch#51661.
05cc2e6 to
7a3a4de
Compare
tonydwb
left a comment
There was a problem hiding this comment.
LGTM. Windows GUI fix: launches restart watcher windowless to avoid empty python.exe console. 3 files, targeted fix. No issues.
Reviewed by Hermes Agent
7a3a4de to
9753400
Compare
|
Thanks — the watcher-leg premise is confirmed on current main. Problems
Suggested changes
Automated hermes-sweeper review. |
|
Closing after the class-level fix in PR #70205 (merged as 0dbf639), which supersedes this approach. Your symptom diagnosis was on point — the uv venv launcher re-exec did leave a visible console during the drain window. But the root cause turned out to be one layer up: If you still see a flashing/persistent console on this leg on current main, please re-open with a repro — that would be new signal. Thanks for the careful writeup of the spawn chain; it helped confirm the inventory for the class fix. |
Summary
The post-update gateway respawn chain has two process legs: the watcher that polls the old gateway PID, and the gateway it respawns once that PID exits. #52239 fixed the gateway leg (routing its argv through
windowless_gateway_restart_spec), but the watcher itself is still launched via baresys.executable— the venv's consolepython.exe:Under a uv-managed venv (the default Desktop install), that launcher re-execs the base console interpreter. The re-exec is a fresh
CreateProcessthat inherits none of the watcher'sDETACHED_PROCESS | CREATE_NO_WINDOWflags, so a blank visiblepython.execonsole sits on screen for the whole drain window (up to ~2 minutes) after every Desktop GUI update. This is the surviving leg of the bug #53850 diagnosed before the #53853 revert ("will fix from a real Windows repro").Real Windows repro
Windows 11, uv-managed venv, Desktop GUI auto-update (v0.18.0):
hermes update --gateway.draining gateway PID <n> (up to 195s).......python.exeappears and stays until the old gateway exits and the watcher respawns it, then self-closes.Process-tree evidence during the window: venv
Scripts\python.exe(spawned detached, no window) with a child base...\uv\python\cpython-3.11...\python.exeowning a fresh console — the re-exec leg the creationflags never reach.Fix
_spawn_gateway_restart_watcher: routewatcher_argvthrough the samewindowless_gateway_restart_specrewrite the gateway leg already uses, and thread the resulting cwd +VIRTUAL_ENV/PYTHONPATHoverlay into the watcherPopen(both the breakaway and no-breakaway branches) so the basepythonw.execan importhermes_cli/gateway.statuswithout the venv launcher. Best-effort with fallback to the original argv — a visible watcher window beats a restart that never happens. No-op on POSIX.Tests
test_watcher_process_itself_is_windowless— static check mirroring the existingtest_watcher_rewrites_console_python_to_windowlesspattern.test_watcher_popen_carries_windowless_interpreter_and_overlay— behavioral: mocks the spec +Popenunder awin32platform patch and asserts the watcher argv leads with the windowless interpreter and carries the cwd/env overlay.pytest tests/tools/test_windows_native_support.py— 66 passed; the 2 failures (TestConfigureWindowsStdio::test_no_op_on_posix,TestSigkillFallback::test_getattr_fallback_prefers_sigkill_when_present) are pre-existing on a native Windows runner (they simulate POSIX and pass on Linux CI, where this suite is designed to run).Fixes #51661. Supersedes the watcher-leg half of #53850.