Skip to content

fix(setup+gateway): defer config write, PID-based gateway kill, scoped systemd service names#1499

Merged
teknium1 merged 5 commits intomainfrom
hermes/hermes-6360cdf9
Mar 16, 2026
Merged

fix(setup+gateway): defer config write, PID-based gateway kill, scoped systemd service names#1499
teknium1 merged 5 commits intomainfrom
hermes/hermes-6360cdf9

Conversation

@teknium1
Copy link
Contributor

@teknium1 teknium1 commented Mar 16, 2026

Summary

Three related setup/gateway fixes for multi-install safety:

1. Defer config.yaml write until after model selection (setup.py)

_update_config_for_provider() was called before model selection, creating a race where the gateway picks up a new provider with the old model. Now deferred to right before save_config().

Cherry-picked from PR #1188 by @ygd58 (authorship preserved). Closes #1182.

2. Kill gateway via PID file before restart on update (main.py)

hermes update only ran systemctl restart, leaving manually-started gateways alive (duplicates). Now uses get_running_pid() (scoped to HERMES_HOME) to SIGTERM this installation's gateway first.

Based on PR #1131 by @teknium1.

3. Scope systemd service name to HERMES_HOME (NEW)

Multiple installations on the same machine now get unique systemd service names:

  • Default ~/.hermeshermes-gateway (backward compatible)
  • Custom HERMES_HOME → hermes-gateway-<8-char-hash>

get_service_name() derives a deterministic name via SHA256 of the resolved HERMES_HOME path. All systemd references across gateway.py, main.py, status.py, and uninstall.py now use it.

The systemd unit template also now sets Environment="HERMES_HOME=..." so the gateway process knows which installation it belongs to.

Test Plan

pytest tests/ -n0 -q  # 4537 passed, 1 pre-existing failure (unrelated)

_update_config_for_provider() was called immediately after provider
selection for zai, kimi-coding, minimax, minimax-cn, and anthropic —
before model selection happened. Since the gateway re-reads config.yaml
per-message, this created a race where the gateway would pick up the
new provider but still use the old (incompatible) model name.

Capture selected_base_url in each provider block, then call
_update_config_for_provider() once, after model selection completes,
right before save_config(). The in-memory _set_model_provider() calls
stay in place so the config object remains consistent during setup.

Closes #1182
@ygd58
Copy link
Contributor

ygd58 commented Mar 16, 2026

Thanks for the cherry-pick and the test coverage! Glad the fix made it in.

cmd_update only ran 'systemctl --user restart hermes-gateway', which
left manually-started gateway processes alive, causing duplicates.

Now uses get_running_pid() from gateway/status.py (scoped to
HERMES_HOME) to find and SIGTERM this installation's gateway before
restarting. Safe with multiple Hermes installations since each
HERMES_HOME has its own PID file.

If no systemd service exists, informs the user to restart manually.

Based on PR #1131 by teknium1. Dropped the cli.py Rich from_ansi
changes (already on main).
@teknium1 teknium1 changed the title fix(setup): defer config.yaml write until after model selection fix(setup): defer config write + kill gateway via PID file on update Mar 16, 2026
Multiple Hermes installations on the same machine now get unique
systemd service names:
- Default ~/.hermes → hermes-gateway (backward compatible)
- Custom HERMES_HOME → hermes-gateway-<8-char-hash>

Changes:
- Add get_service_name() in hermes_cli/gateway.py that derives a
  deterministic service name from HERMES_HOME via SHA256
- Replace all hardcoded 'hermes-gateway' systemd references with
  get_service_name() across gateway.py, main.py, status.py, uninstall.py
- Add HERMES_HOME env var to both user and system systemd unit templates
  so the gateway process uses the correct installation
- Update tests to use get_service_name() in assertions
@teknium1 teknium1 changed the title fix(setup): defer config write + kill gateway via PID file on update fix(setup+gateway): defer config write, PID-based gateway kill, scoped systemd service names Mar 16, 2026
- Update messaging guide to use 'hermes gateway' CLI commands instead
  of raw systemctl (auto-resolves the correct service name)
- Add info callout explaining multi-install service name scoping
- Update HERMES_HOME env var docs to mention PID + service name scoping
@teknium1 teknium1 merged commit caa944e into main Mar 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: setup flow writes provider to config.yaml before model selection, causing gateway race condition

2 participants