mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-12 08:51:53 +00:00
Full-corpus correctness audit of the hand-written docs against the codebase, plus a 2-week merged-PR coverage sweep and one live dashboard screenshot. Correctness (verified against COMMAND_REGISTRY / PROVIDER_REGISTRY / TOOLSETS / tools.registry / DEFAULT_CONFIG / source): - reference: add /version slash command, context_engine toolset, openai-api + novita-ai to --provider; fix tool count 64->71; model_catalog ttl 24->1; add profile describe to summary table; add real provider env vars (LM_API_KEY/LM_BASE_URL, KIMI_CODING_API_KEY, ALIBABA_CODING_PLAN_*, ANTHROPIC_BASE_URL, COPILOT_API_BASE_URL); fix faq "Windows: not natively". - user-guide: fix broken `hermes -w -q` (->-z) and `hermes logs --tail` (->-f); language list 8->16; aux slots 8->11; docker separate-dashboard claim; _SECURITY_ARGS -> _BASE_SECURITY_ARGS. - features: curator prune_builtins truth + missing CLI verbs; codex-runtime aux keys (context_compression->compression, vision_detect->vision); kanban terminate endpoint + promote/reassign/schedule/diagnostics/edit + per-profile cap; mcp mTLS (client_cert/client_key); built-in-plugins nemo_relay + teams_pipeline; api-server run approval endpoint; computer-use frontmatter. - features N-Z + integrations: StepFun step-3-mini->step-3.5-flash; web-search backends 4->8; tool-gateway image-model IDs; voice-mode STT/TTS enums; remove phantom `rl` toolset; nous-portal status subcommand. - messaging: WeCom typing/streaming cols; telegram transport default edit->auto; sms host default; simplex/ntfy `gateway setup` + pairing approve; line smart-chunking; matrix MATRIX_DM_AUTO_THREAD. - developer-guide: build-a-plugin code examples (register_command signature, ContextEngine/ImageGenProvider/MemoryProvider ABCs); model-provider-plugin entry-point group hermes.plugins->hermes_agent.plugins; PLUGIN.yaml->plugin.yaml; agent-loop stale LOC; web-search-provider phantom crawl(). PR coverage (2-week window, 149 feat PRs): - desktop.md refreshed for ~15 shipped features (zh-Hans switcher, rebindable shortcuts + zoom + Cmd+K, status-bar model picker + YOLO toggle, session-by-id + archive, multi-profile concurrent + cross-profile @session, composer history, Providers pane, per-profile remote hosts, Grok OAuth, aux-pin warning). - configuration.md gateway-streaming default corrected to per-platform. - tool-gateway.md free tool pool entitlement note. Media: - New /img/dashboard/admin-config.png — live dashboard Config admin page (captured from a clean profile, no secrets/personalization).
332 lines
9.3 KiB
Markdown
332 lines
9.3 KiB
Markdown
---
|
|
sidebar_position: 4
|
|
---
|
|
|
|
# Running Many Gateways at Once
|
|
|
|
Operate multiple [profiles](./profiles.md) — each with its own bot tokens,
|
|
sessions, and memory — as managed services on a single machine. This page
|
|
covers the operational concerns: starting them all together, viewing logs
|
|
across profiles, preventing the host from sleeping, and recovering from common
|
|
launchd/systemd quirks.
|
|
|
|
If you only run one Hermes agent, you don't need this page — see
|
|
[Profiles](./profiles.md) for the basics.
|
|
|
|
## When to use this
|
|
|
|
You want this setup when you have two or more Hermes agents that should all
|
|
be online at the same time. Common reasons:
|
|
|
|
- A personal assistant on one Telegram bot and a coding agent on another
|
|
- One agent per family member or one per Slack workspace
|
|
- Sandbox + production instances of the same configuration
|
|
- A research agent + a writing agent + a cron-driven bot — each with isolated
|
|
memory and skills
|
|
|
|
Every profile already gets its own per-platform LaunchAgent
|
|
(`ai.hermes.gateway-<name>.plist`) or systemd user service
|
|
(`hermes-gateway-<name>.service`). This guide adds the patterns for managing
|
|
them collectively.
|
|
|
|
## Quick start
|
|
|
|
```bash
|
|
# Create profiles (once)
|
|
hermes profile create coder
|
|
hermes profile create personal-bot
|
|
hermes profile create research
|
|
|
|
# Configure each
|
|
coder setup
|
|
personal-bot setup
|
|
research setup
|
|
|
|
# Install each gateway as a managed service
|
|
coder gateway install
|
|
personal-bot gateway install
|
|
research gateway install
|
|
|
|
# Start them all
|
|
coder gateway start
|
|
personal-bot gateway start
|
|
research gateway start
|
|
```
|
|
|
|
That's it — three independent agents, each on its own process, restarting
|
|
automatically on crash and on user login.
|
|
|
|
## Start, stop, or restart all gateways at once
|
|
|
|
The CLI ships with single-profile lifecycle commands. To act across every
|
|
profile, wrap them in a shell loop. Put the snippet below in
|
|
`~/.local/bin/hermes-gateways` and `chmod +x` it:
|
|
|
|
```sh
|
|
#!/bin/sh
|
|
set -eu
|
|
|
|
# Add or remove profile names here as you create / delete profiles.
|
|
profiles="default coder personal-bot research"
|
|
|
|
usage() {
|
|
echo "Usage: hermes-gateways {start|stop|restart|status|list}"
|
|
}
|
|
|
|
run_for_profile() {
|
|
profile="$1"
|
|
action="$2"
|
|
if [ "$profile" = "default" ]; then
|
|
hermes gateway "$action"
|
|
else
|
|
hermes -p "$profile" gateway "$action"
|
|
fi
|
|
}
|
|
|
|
action="${1:-}"
|
|
case "$action" in
|
|
start|stop|restart|status)
|
|
for profile in $profiles; do
|
|
echo "==> $action $profile"
|
|
run_for_profile "$profile" "$action"
|
|
done
|
|
;;
|
|
list)
|
|
hermes gateway list
|
|
;;
|
|
*)
|
|
usage
|
|
exit 2
|
|
;;
|
|
esac
|
|
```
|
|
|
|
Then:
|
|
|
|
```bash
|
|
hermes-gateways start # start every configured profile
|
|
hermes-gateways stop # stop every configured profile
|
|
hermes-gateways restart # restart all
|
|
hermes-gateways status # status across all
|
|
hermes-gateways list # delegates to `hermes gateway list`
|
|
```
|
|
|
|
:::tip
|
|
The `default` profile is targeted with `hermes gateway <action>` (no `-p`),
|
|
not `hermes -p default gateway <action>`. The wrapper above handles both forms.
|
|
:::
|
|
|
|
## Manage one profile
|
|
|
|
The shortcut commands every profile installs:
|
|
|
|
```bash
|
|
coder gateway run # foreground (Ctrl-C to stop)
|
|
coder gateway start # start the managed service
|
|
coder gateway stop # stop the managed service
|
|
coder gateway restart # restart
|
|
coder gateway status # status
|
|
coder gateway install # create the LaunchAgent / systemd unit
|
|
coder gateway uninstall # remove the service file
|
|
```
|
|
|
|
These are equivalent to `hermes -p coder gateway <action>` — useful if a
|
|
profile alias is not on `PATH` or if you target profiles dynamically from a
|
|
script.
|
|
|
|
## Service files
|
|
|
|
Each profile installs its own service with a unique name, so installations
|
|
never clash:
|
|
|
|
| Platform | Path |
|
|
| -------- | ----------------------------------------------------------------- |
|
|
| macOS | `~/Library/LaunchAgents/ai.hermes.gateway-<profile>.plist` |
|
|
| Linux | `~/.config/systemd/user/hermes-gateway-<profile>.service` |
|
|
|
|
The default profile keeps the historical names: `ai.hermes.gateway.plist` /
|
|
`hermes-gateway.service`.
|
|
|
|
## Viewing logs
|
|
|
|
Each profile writes to its own log files:
|
|
|
|
```bash
|
|
# Default profile
|
|
tail -f ~/.hermes/logs/gateway.log
|
|
tail -f ~/.hermes/logs/gateway.error.log
|
|
|
|
# Named profile
|
|
tail -f ~/.hermes/profiles/<name>/logs/gateway.log
|
|
tail -f ~/.hermes/profiles/<name>/logs/gateway.error.log
|
|
```
|
|
|
|
Stream every profile's log simultaneously:
|
|
|
|
```bash
|
|
tail -f ~/.hermes/logs/gateway.log ~/.hermes/profiles/*/logs/gateway.log
|
|
```
|
|
|
|
The CLI also has a structured log viewer:
|
|
|
|
```bash
|
|
hermes logs -f # follow default profile
|
|
hermes -p coder logs -f # follow one profile
|
|
hermes logs --help # filters, levels, JSON output
|
|
```
|
|
|
|
## Identify what's actually running
|
|
|
|
```bash
|
|
hermes profile list # profiles + model + gateway state
|
|
hermes-gateways status # full status across every profile
|
|
launchctl list | grep hermes # macOS — PIDs and labels
|
|
systemctl --user list-units 'hermes-gateway-*' # Linux — units
|
|
```
|
|
|
|
## Editing configuration
|
|
|
|
Every profile keeps its config inside its own directory:
|
|
|
|
```
|
|
~/.hermes/profiles/<name>/
|
|
├── .env # API keys, bot tokens (chmod 600)
|
|
├── config.yaml # model, provider, toolsets, gateway settings
|
|
└── SOUL.md # personality / system prompt
|
|
```
|
|
|
|
The default profile uses `~/.hermes/` directly with the same three files.
|
|
|
|
Edit them with any editor or via the CLI:
|
|
|
|
```bash
|
|
hermes config set model.model anthropic/claude-sonnet-4 # default profile
|
|
coder config set model.model openai/gpt-5 # named profile
|
|
```
|
|
|
|
After editing `.env` or `config.yaml`, restart the affected gateway:
|
|
|
|
```bash
|
|
coder gateway restart
|
|
# or, for everything:
|
|
hermes-gateways restart
|
|
```
|
|
|
|
## Keeping the host awake
|
|
|
|
The gateway process can run all day, but the operating system will still try
|
|
to sleep when idle. Two patterns:
|
|
|
|
### macOS — `caffeinate`
|
|
|
|
`caffeinate` is built into macOS and prevents sleep while it runs. No install.
|
|
|
|
```bash
|
|
caffeinate -dis # block display, idle, and system sleep
|
|
caffeinate -dis -t 28800 # same, auto-exit after 8 hours
|
|
caffeinate -i -w $(cat ~/.hermes/gateway.pid) & # awake while default gateway runs
|
|
|
|
# Persistent: run in background and forget
|
|
nohup caffeinate -dis >/dev/null 2>&1 &
|
|
disown
|
|
|
|
# Inspect / stop
|
|
pmset -g assertions | grep -iE 'caffeinate|prevent|user is active'
|
|
pkill caffeinate
|
|
```
|
|
|
|
| Flag | Effect |
|
|
| ------ | ------------------------------------------------- |
|
|
| `-d` | block display sleep |
|
|
| `-i` | block idle system sleep (default) |
|
|
| `-m` | block disk sleep |
|
|
| `-s` | block system sleep (AC-powered Macs only) |
|
|
| `-u` | simulate user activity (prevents screen lock) |
|
|
| `-t N` | auto-exit after `N` seconds |
|
|
| `-w P` | exit when PID `P` exits |
|
|
|
|
:::warning Lid-close still sleeps the Mac
|
|
`caffeinate` cannot override the hardware-driven lid-close sleep on MacBooks.
|
|
For lid-closed operation, change your Energy Saver / Battery preferences or
|
|
use a third-party tool.
|
|
:::
|
|
|
|
### Linux — `systemd-inhibit` or `loginctl`
|
|
|
|
```bash
|
|
# Inhibit suspend while a command runs
|
|
systemd-inhibit --what=idle:sleep --who=hermes --why="gateways running" \
|
|
sleep infinity &
|
|
|
|
# Allow user services to keep running after logout (recommended)
|
|
sudo loginctl enable-linger "$USER"
|
|
```
|
|
|
|
After enabling lingering, your systemd user units (including
|
|
`hermes-gateway-<profile>.service`) continue running across SSH disconnects
|
|
and reboots.
|
|
|
|
## Token-conflict safety
|
|
|
|
Each profile must use unique bot tokens for each platform. If two profiles
|
|
share a Telegram, Discord, Slack, WhatsApp, or Signal token, the second
|
|
gateway refuses to start with an error naming the conflicting profile.
|
|
|
|
To audit:
|
|
|
|
```bash
|
|
grep -H 'TELEGRAM_BOT_TOKEN\|DISCORD_BOT_TOKEN' \
|
|
~/.hermes/.env ~/.hermes/profiles/*/.env
|
|
```
|
|
|
|
## Updating the code
|
|
|
|
`hermes update` pulls the latest code once and syncs new bundled skills into
|
|
every profile:
|
|
|
|
```bash
|
|
hermes update
|
|
hermes-gateways restart
|
|
```
|
|
|
|
User-modified skills are never overwritten.
|
|
|
|
## Troubleshooting
|
|
|
|
### "Could not find service in domain for user gui: 501"
|
|
|
|
You ran `hermes gateway start` after a previous `hermes gateway stop`. The
|
|
CLI's `stop` does a full `launchctl unload`, which removes the service from
|
|
launchd's registry. The CLI catches this specific error on `start` and
|
|
automatically re-loads the plist (`↻ launchd job was unloaded; reloading
|
|
service definition`). The service starts normally. Nothing to fix.
|
|
|
|
### Stale PID after a crash
|
|
|
|
If a profile's gateway shows `not running` but a process is still alive:
|
|
|
|
```bash
|
|
ps -ef | grep "hermes_cli.*-p <profile>"
|
|
cat ~/.hermes/profiles/<profile>/gateway.pid
|
|
kill -TERM <pid> # graceful
|
|
kill -KILL <pid> # if that fails after a few seconds
|
|
<profile> gateway start
|
|
```
|
|
|
|
### Forcing a hard reset of one service
|
|
|
|
```bash
|
|
# macOS
|
|
launchctl unload ~/Library/LaunchAgents/ai.hermes.gateway-<profile>.plist
|
|
launchctl load ~/Library/LaunchAgents/ai.hermes.gateway-<profile>.plist
|
|
|
|
# Linux
|
|
systemctl --user restart hermes-gateway-<profile>.service
|
|
```
|
|
|
|
### Health check
|
|
|
|
```bash
|
|
hermes doctor # default profile
|
|
hermes -p <profile> doctor # one profile
|
|
```
|