feat: isolated profiles — multiple Hermes instances with independent config, gateway, and data#1750
Closed
teknium1 wants to merge 1 commit into
Closed
feat: isolated profiles — multiple Hermes instances with independent config, gateway, and data#1750teknium1 wants to merge 1 commit into
teknium1 wants to merge 1 commit into
Conversation
…config, gateway, and data Add profile management so users can run multiple fully isolated Hermes instances on the same machine. Each profile gets its own HERMES_HOME with independent config.yaml, .env, memory, sessions, skills, gateway, cron, and logs. New files: - hermes_cli/profiles.py: profile CRUD (create, list, clone, delete) - tests/hermes_cli/test_profiles.py: 40 tests covering profiles - tests/hermes_cli/test_gateway_pid_scoping.py: 3 gateway isolation tests Key changes: - hermes_cli/main.py: --profile/-p flag pre-parsed before any module imports (critical: 30+ modules cache HERMES_HOME at import time). New 'profile' subcommand with create/list/delete/show actions. - hermes_cli/gateway.py: find_gateway_pids() now uses the HERMES_HOME- scoped PID file instead of a greedy ps aux scan. This prevents 'hermes gateway stop' for one profile from killing another profile's gateway. - hermes_cli/banner.py: shows active profile name in CLI banner when not using the default profile. Usage: hermes profile create work # new empty profile hermes profile create work --clone default # clone config+keys hermes -p work setup # configure the profile hermes -p work # chat in work profile hermes -p work gateway start # isolated gateway hermes profile list # see all profiles Design: - Profiles live at ~/.hermes/profiles/<name>/ (separate from default) - Default profile is ~/.hermes (backward compatible, zero migration) - --profile sets HERMES_HOME before any imports, so all downstream code (config, memory, sessions, gateway PID, systemd service names, cron, etc.) naturally scopes to the profile - Systemd service names are already hash-scoped per HERMES_HOME - Token-scoped locks prevent two profiles from binding the same bot Full suite: 5278 passed, 0 new failures.
Contributor
|
related: #2845 — also adds gateway env propagation, instances.json registry, HERMES_BASE_HOME, and .env identity protection |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds profile management so users can run multiple fully isolated Hermes instances on the same machine. Each profile has its own config, API keys, memory, sessions, skills, gateway, cron, and logs — completely independent from other profiles.
Related to #896 (multi-agent architecture), but orthogonal — profiles provide infrastructure-level isolation (separate gateways, separate secrets), while #896 provides application-level routing within a single profile.
The Problem
Today, running two Discord bots on the same machine requires manually juggling
HERMES_HOMEenv vars. Worse,hermes gateway stopuses a greedyps auxscan that kills ALL gateway processes regardless of which instance they belong to.What This Does
New:
hermes_cli/profiles.py(~280 lines)~/.hermes/profiles/<name>/, each a full HERMES_HOME directory--clone defaultcopies config.yaml + .env;--clone-dataalso copies memories/skills/skinsModified:
hermes_cli/main.py--profile/-pflag pre-parsed before any module imports — critical because 30+ modules cache HERMES_HOME at import time via module-level constantsprofilesubcommand:hermes profile create|list|delete|showFixed:
hermes_cli/gateway.pyfind_gateway_pids()now uses the HERMES_HOME-scoped PID file instead of a greedyps auxscanhermes -p work gateway stopfrom killing thepersonalprofile's gatewayModified:
hermes_cli/banner.pyUsage
Architecture
Each profile is just a HERMES_HOME directory. The
-pflag setsHERMES_HOMEbefore anything loads, so all downstream code naturally scopes:{HERMES_HOME}/memories/{HERMES_HOME}/sessions/{HERMES_HOME}/skills/{HERMES_HOME}/gateway.pid(already scoped){HERMES_HOME}/cron/{HERMES_HOME}/state.dbThe default profile is
~/.hermesitself — zero migration, fully backward compatible.Tests
test_profiles.py: validation, create, clone, delete, list, isolation, gateway PID scoping, systemd service name scopingtest_gateway_pid_scoping.py: PID-file based lookup, cross-profile isolationDesign Decisions
--profileis extracted fromsys.argvbefore any hermes modules import, because 30+ files cacheHERMES_HOMEat module level~/.hermes/profiles/— anchored to$HOME, not$HERMES_HOME, so profiles are always discoverable--clonecopies config;--clone-datacopies memories/skillsRelationship to PR #896
PR #896 adds named agents within a single Hermes install (routing, tool policies, personas). This PR adds isolated profiles — separate installs that don't share anything. They compose naturally: