feat(gateway): WSL-aware gateway with smart systemd detection (#7510)

- Add shared is_wsl() to hermes_constants (like is_termux)
- Update supports_systemd_services() to verify systemd is actually
  running on WSL before returning True
- Add WSL-specific guidance in gateway install/start/setup/status
  for both cases: WSL+systemd and WSL without systemd
- Improve help strings: 'run' now says recommended for WSL/Docker,
  'start'/'install' now mention systemd/launchd explicitly
- Add WSL gateway FAQ section with tmux/nohup/Task Scheduler tips
- Update CLI commands docs with WSL tip
- Deduplicate _is_wsl() from clipboard.py to shared hermes_constants
- Fix clipboard tests to reset hermes_constants cache
- 20 new WSL-specific tests covering detection, systemd check,
  supports_systemd_services integration, and command output

Motivated by user feedback: took 1 hour to figure out run vs start
on WSL, Telegram bot kept disconnecting due to flaky WSL systemd.
This commit is contained in:
Teknium 2026-04-10 21:15:47 -07:00 committed by GitHub
parent 830040f937
commit a8fd7257b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 421 additions and 35 deletions

View file

@ -168,6 +168,27 @@ def is_termux() -> bool:
return bool(os.getenv("TERMUX_VERSION") or "com.termux/files/usr" in prefix)
_wsl_detected: bool | None = None
def is_wsl() -> bool:
"""Return True when running inside WSL (Windows Subsystem for Linux).
Checks ``/proc/version`` for the ``microsoft`` marker that both WSL1
and WSL2 inject. Result is cached for the process lifetime.
Import-safe no heavy deps.
"""
global _wsl_detected
if _wsl_detected is not None:
return _wsl_detected
try:
with open("/proc/version", "r") as f:
_wsl_detected = "microsoft" in f.read().lower()
except Exception:
_wsl_detected = False
return _wsl_detected
OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1"
OPENROUTER_MODELS_URL = f"{OPENROUTER_BASE_URL}/models"