Skip to content

fix: replace hardcoded ~/.hermes paths with get_hermes_home() for profile support#3575

Merged
teknium1 merged 3 commits into
mainfrom
hermes/hermes-e6f1d362
Mar 28, 2026
Merged

fix: replace hardcoded ~/.hermes paths with get_hermes_home() for profile support#3575
teknium1 merged 3 commits into
mainfrom
hermes/hermes-e6f1d362

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Prep work for the upcoming profiles feature. Profiles give each agent its own HERMES_HOME directory, so all path references must respect the HERMES_HOME env var rather than hardcoding ~/.hermes.

Changes

Hardcoded path fixes (3 files):

  • gateway/platforms/matrix.py — Matrix E2EE store was hardcoded to ~/.hermes/matrix/store. Now uses get_hermes_home().
  • gateway/platforms/telegram.py — Two locations reading config.yaml via Path.home()/.hermes instead of get_hermes_home(). DM topic persistence and hot-reload would read the wrong config.
  • tools/file_tools.py — Security path for hub index blocking was hardcoded to ~/.hermes.

Service naming improvements (gateway.py):

  • New _profile_suffix() helper: detects ~/.hermes/profiles/<name> → returns profile name; other custom paths → returns hash.
  • get_service_name() now returns hermes-gateway-coder instead of hermes-gateway-a1b2c3d4 for profile dirs.
  • get_launchd_plist_path() now scoped per profile: ai.hermes.gateway-coder.plist.
  • New get_launchd_label() — all launchctl commands in gateway.py, main.py, and status.py updated to use it.

macOS launchd fix (pre-existing bug):

  • Launchd plist was missing HERMES_HOME in EnvironmentVariables. Custom HERMES_HOME has always been broken on macOS launchd — this fixes it.

Test plan

  • Full suite: 6537 passed, 201 skipped (1 pre-existing flaky failure unrelated to this PR)
  • DM topic tests updated to set HERMES_HOME env var alongside Path.home() mock
  • Launchd test updated to use get_launchd_label() for expected commands

Two changes to improve tool reliability, especially for OpenAI GPT models:

1. GPT tool-use enforcement prompt: Adds GPT_TOOL_USE_GUIDANCE to the
   system prompt when the model name contains 'gpt' and tools are loaded.
   This addresses a known behavioral pattern where GPT models describe
   intended actions ('I will run the tests') instead of actually making
   tool calls. Inspired by similar steering in OpenCode (beast.txt) and
   Cline (GPT-5.1 variant).

2. Budget warning history stripping: Budget pressure warnings injected by
   _get_budget_warning() into tool results are now stripped when
   conversation history is replayed via run_conversation(). Previously,
   these turn-scoped signals persisted across turns, causing models to
   avoid tool calls in all subsequent messages after any turn that hit
   the 70-90% iteration threshold.
…file support

Prep for the upcoming profiles feature — each profile is a separate
HERMES_HOME directory, so all paths must respect the env var.

Fixes:
- gateway/platforms/matrix.py: Matrix E2EE store was hardcoded to
  ~/.hermes/matrix/store, ignoring HERMES_HOME. Now uses
  get_hermes_home() so each profile gets its own Matrix state.

- gateway/platforms/telegram.py: Two locations reading config.yaml via
  Path.home()/.hermes instead of get_hermes_home(). DM topic thread_id
  persistence and hot-reload would read the wrong config in a profile.

- tools/file_tools.py: Security path for hub index blocking was
  hardcoded to ~/.hermes, would miss the actual profile's hub cache.

- hermes_cli/gateway.py: Service naming now uses the profile name
  (hermes-gateway-coder) instead of a cryptic hash suffix. Extracted
  _profile_suffix() helper shared by systemd and launchd.

- hermes_cli/gateway.py: Launchd plist path and Label now scoped per
  profile (ai.hermes.gateway-coder.plist). Previously all profiles
  would collide on the same plist file on macOS.

- hermes_cli/gateway.py: Launchd plist now includes HERMES_HOME in
  EnvironmentVariables — was missing entirely, making custom
  HERMES_HOME broken on macOS launchd (pre-existing bug).

- All launchctl commands in gateway.py, main.py, status.py updated
  to use get_launchd_label() instead of hardcoded string.

Test fixes: DM topic tests now set HERMES_HOME env var alongside
Path.home() mock. Launchd test uses get_launchd_label() for expected
commands.
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.

1 participant