Jesse A. Green / notebook

Hermes Agent — Administrator & Developer Guide

Generated May 2026 from NousResearch/hermes-agent at 512c328

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Hermes Agent is a production-grade, open-source AI-powered CLI assistant and multi-platform agent built by Nous Research. It provides a unified interface for interacting with large language models through a terminal REPL, a messaging gateway spanning 19 platforms, a web dashboard, IDE integration via the Agent Communication Protocol, and an OpenAI-compatible API server. The system is designed for both interactive use and autonomous operation, with scheduled tasks, batch processing, and delegated sub-agents.

The architecture is modular: a central AIAgent orchestrator manages conversation state, tool dispatch, context compression, and memory, while pluggable terminal backends (local, Docker, SSH, Modal, Singularity, Daytona) execute commands in isolated environments. The gateway layer adapts the agent to messaging platforms including Telegram, Discord, Slack, Matrix, WhatsApp, Signal, Email, SMS, and others. A plugin system supports memory providers and context engines, and a skills framework provides reusable prompt-driven capabilities.

This guide covers architecture, configuration, deployment, operations, security, and developer internals for system administrators and contributors working with Hermes Agent v0.9.0.


1. Architecture Overview

System Architecture

                          ┌─────────────────────────────────┐
                          │         Entry Points            │
                          │  cli.py  hermes_cli/main.py     │
                          │  gateway/run.py  acp/__main__   │
                          └──────────┬──────────────────────┘
                                     │
                          ┌──────────▼──────────────────────┐
                          │        AIAgent Orchestrator      │
                          │         (run_agent.py)           │
                          │  ┌─────────────────────────┐    │
                          │  │ prompt_builder           │    │
                          │  │ context_compressor       │    │
                          │  │ memory_manager           │    │
                          │  │ error_classifier         │    │
                          │  │ credential_pool          │    │
                          │  │ smart_model_routing      │    │
                          │  │ anthropic_adapter        │    │
                          │  │ auxiliary_client          │    │
                          │  └─────────────────────────┘    │
                          └──────────┬──────────────────────┘
                                     │
              ┌──────────────────────┼──────────────────────┐
              │                      │                      │
   ┌──────────▼────────┐  ┌─────────▼─────────┐  ┌────────▼────────┐
   │   Tool Registry    │  │   Gateway Layer    │  │  Cron Scheduler │
   │  (model_tools.py)  │  │  (gateway/run.py)  │  │ (cron/scheduler)│
   └──────────┬─────────┘  └─────────┬──────────┘  └─────────────────┘
              │                      │
   ┌──────────▼─────────┐  ┌────────▼──────────────────────────┐
   │ Terminal Backends   │  │     Platform Adapters (19)        │
   │ ┌───────────────┐  │  │ Telegram  Discord  Slack  Matrix  │
   │ │ Local         │  │  │ WhatsApp  Signal   Email  SMS     │
   │ │ Docker        │  │  │ Mattermost  HASS   DingTalk       │
   │ │ SSH           │  │  │ Feishu  WeCom  Weixin  QQ         │
   │ │ Modal         │  │  │ BlueBubbles  API Server            │
   │ │ Singularity   │  │  │ Copilot (ACP)                     │
   │ │ Daytona       │  │  └───────────────────────────────────┘
   │ └───────────────┘  │
   │ Browser Providers   │  ┌───────────────────────────────────┐
   │ ┌───────────────┐  │  │   Web Dashboard (React/Vite)      │
   │ │ Browserbase   │  │  │   ACP Adapter (IDE integration)   │
   │ │ BrowserUse    │  │  │   MCP Server Mode                 │
   │ │ Firecrawl     │  │  │   Skills Engine                   │
   │ └───────────────┘  │  │   Memory / Plugin System          │
   └────────────────────┘  └───────────────────────────────────┘

Component Inventory

Component Path Role
AIAgent Orchestrator run_agent.py Core agent loop: conversation management, tool dispatch, context compression, delegation
Agent Support Modules agent/ (30 files) Anthropic adapter, prompt builder, context compressor, credential pool, error classifier, memory, routing, display
CLI Layer hermes_cli/ (48 files) CLI subcommands, auth, config, profiles, plugins, gateway management, web server, skills hub
Gateway Core gateway/ (15 files) Multi-platform messaging gateway: config, runner, delivery, hooks, pairing, channel directory
Platform Adapters gateway/platforms/ (24 files) 19 platform-specific messaging adapters
Tool Registry tools/ Tool implementations, toolsets, browser providers
Terminal Backends tools/environments/ (11 files) 6 backends: local, Docker, SSH, Modal, ManagedModal, Singularity, Daytona
Cron Scheduler cron/ (3 files) Scheduled task management and execution
Plugin System plugins/ Memory providers, context engine, extensible plugin architecture
ACP Adapter acp_adapter/ (9 files) Agent Communication Protocol for IDE integration
Web Dashboard web/ React 19 / Vite 7 frontend for browser-based interaction
Documentation Site website/ Docusaurus 3.9 documentation site
Session Store hermes_state.py SQLite-based session persistence
Batch Runner batch_runner.py Parallel batch processing with checkpointing
Skills skills/, optional-skills/ 100+ bundled skill definitions
Training Environments environments/ Atropos RL training, benchmarks (TerminalBench2, TBLite, YC-Bench)

Technology Stack

Technology Version Purpose
Python 3.10+ Core runtime
Node.js 20+ Browser tools, WhatsApp bridge
OpenAI SDK Latest LLM provider interface
prompt_toolkit Latest Interactive REPL
rich Latest Terminal formatting and display
fire Latest CLI framework
httpx Latest Async HTTP client
tenacity Latest Retry logic
pydantic Latest Data validation
aiohttp Latest Async web server (gateway API)
React 19 Web dashboard frontend
Vite 7 Frontend build tooling
Tailwind CSS 4 Dashboard styling
Docusaurus 3.9 Documentation site
SQLite WAL mode Session and state persistence

Data Flow

User Message
    │
    ▼
prompt_builder ──► System prompt + skills + context files + memory + SOUL.md
    │
    ▼
LLM Provider (OpenRouter / Anthropic / Nous / Codex / Ollama / Direct)
    │
    ▼
Tool Dispatch (model_tools.py)
    │
    ├──► Terminal execution (local / Docker / SSH / Modal / Singularity / Daytona)
    ├──► Browser interaction (Browserbase / BrowserUse / Firecrawl)
    ├──► File operations (read / write / search / glob)
    └──► Web requests, memory, delegation
    │
    ▼
Response Display (agent/display.py, rich formatting)
    │
    ▼
Context Compression (if token count > threshold)

2. System Requirements

Runtime Dependencies

Dependency Version Required Purpose
Python 3.10+ Yes Core runtime
pip Latest Yes Package management
Git Latest Yes Repository operations, self-update
Node.js 20+ No Browser tools, WhatsApp bridge
ffmpeg Latest No Voice mode audio processing
Docker Latest No Docker terminal backend
SSH client Latest No SSH terminal backend
Ollama Latest No Local model inference

Install Extras

pip install hermes-agent              # Core
pip install hermes-agent[all]         # All optional dependencies
pip install hermes-agent[web]         # Web dashboard
pip install hermes-agent[voice]       # Voice input/output
pip install hermes-agent[mcp]         # MCP server mode
pip install hermes-agent[bedrock]     # AWS Bedrock adapter
pip install hermes-agent[yc-bench]    # YC-Bench environment

Platform-Specific Notes

Platform Notes
Linux Primary development target. Full feature support.
macOS Full support. Homebrew formula available in packaging/homebrew/.
Windows Requires Git Bash for terminal operations. Native cmd/PowerShell not fully supported.
WSL Fully supported under Windows Subsystem for Linux.
Termux (Android) Supported with caveats; limited terminal backend options.
NixOS flake.nix included in repository root for Nix-based installation.

Hardware

No GPU required for the agent itself. Any modern CPU and 2+ GB RAM suffice. GPU is only relevant when running local models through Ollama or similar inference backends. Browser tools may benefit from additional memory depending on page complexity.


3. Configuration Reference

Important

Configuration is resolved in a strict precedence order: environment variables > config.yaml > legacy files > hardcoded defaults. Environment variables always win.

3.1 Config Files

File Location Purpose
config.yaml ~/.hermes/config.yaml Primary configuration file
.env ~/.hermes/.env Secrets and environment variable overrides
SOUL.md ~/.hermes/SOUL.md System prompt personality customization
auth.json ~/.hermes/auth.json Credential store (file-locked)
gateway.json ~/.hermes/gateway.json Legacy gateway config (merged into config.yaml)
jobs.json ~/.hermes/cron/jobs.json Scheduled task definitions
.hermes.md Project root Per-project context file
HERMES.md Project root Per-project context file (alternative name)
AGENTS.md Project root Per-project agent instructions

3.2 Config YAML Structure

Full annotated ~/.hermes/config.yaml:

# ── Model Configuration ──
model:
  default: ""                              # Model name (e.g., anthropic/claude-sonnet-4)
  base_url: ""                             # Custom OpenAI-compatible endpoint URL
  provider: "auto"                         # Provider: auto|openrouter|anthropic|nous|codex|ollama|direct

# ── Terminal Backend ──
terminal:
  backend: "local"                         # Backend: local|docker|ssh|modal|singularity|daytona
  cwd: "."                                 # Working directory for terminal sessions
  timeout: 60                              # Per-command timeout in seconds
  lifetime_seconds: 300                    # Terminal session lifetime before recycling
  docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"  # Docker image
  docker_forward_env: []                   # Env vars to forward into Docker container
  docker_volumes: []                       # Volume mounts (host:container format)
  docker_mount_cwd_to_workspace: false     # Mount host CWD into container /workspace
  singularity_image: ""                    # Singularity/Apptainer image path
  modal_image: ""                          # Modal cloud image
  daytona_image: ""                        # Daytona workspace image
  ssh_host: ""                             # SSH backend hostname
  ssh_user: ""                             # SSH backend username
  ssh_port: 22                             # SSH backend port
  ssh_key: ""                              # SSH private key path
  container_cpu: ""                        # CPU limit for container backends
  container_memory: ""                     # Memory limit for container backends
  container_disk: ""                       # Disk limit for container backends
  container_persistent: ""                 # Persistent storage mount
  sandbox_dir: ""                          # Sandboxed working directory
  persistent_shell: ""                     # Maintain shell state between commands
  sudo_password: ""                        # Sudo password for privilege escalation

# ── Browser Configuration ──
browser:
  inactivity_timeout: 120                  # Close browser after N seconds idle
  record_sessions: false                   # Record browser sessions for replay

# ── Context Compression ──
compression:
  enabled: true                            # Enable automatic context compression
  threshold: 0.50                          # Compress when usage exceeds this fraction of context window

# ── Smart Model Routing ──
smart_model_routing:
  enabled: false                           # Route simple queries to cheaper model
  max_simple_chars: 160                    # Max character count for "simple" classification
  max_simple_words: 28                     # Max word count for "simple" classification
  cheap_model:                             # Target model for simple queries
    model: ""
    base_url: ""
    api_key: ""

# ── Agent Behavior ──
agent:
  max_turns: 90                            # Maximum conversation turns before stopping
  verbose: false                           # Verbose agent logging
  system_prompt: ""                        # Override default system prompt
  prefill_messages_file: ""                # JSON file with pre-seeded conversation
  reasoning_effort: ""                     # Thinking budget: none|minimal|low|medium|high|xhigh
  service_tier: ""                         # API tier: normal|fast|priority
  personalities:                           # Named personality presets
    default: {}
    concise: {}
    creative: {}

# ── Display Settings ──
display:
  compact: false                           # Compact output formatting
  resume_display: "full"                   # Session resume display: full|summary|none
  show_reasoning: false                    # Show model reasoning/thinking tokens
  streaming: true                          # Stream responses token-by-token
  busy_input_mode: "interrupt"             # Behavior when input arrives mid-generation
  skin: "default"                          # Display skin/theme

# ── Clarification ──
clarify:
  timeout: 120                             # Timeout for clarification prompts (seconds)

# ── Code Execution ──
code_execution:
  timeout: 300                             # Maximum code execution time (seconds)
  max_tool_calls: 50                       # Maximum tool calls per turn

# ── Auxiliary Models ──
auxiliary:
  vision:                                  # Vision model for image analysis
    provider: "auto"
    model: ""
    base_url: ""
    api_key: ""
  web_extract:                             # Model for web content extraction
    provider: "auto"
    model: ""
    base_url: ""
    api_key: ""
  approval:                                # Model for approval/review workflows
    provider: "auto"
    model: ""
    base_url: ""
    api_key: ""

# ── Delegation ──
delegation:
  max_iterations: 45                       # Max iterations for delegated sub-agents
  default_toolsets: ["terminal", "file", "web"]  # Toolsets available to delegates
  model: ""                                # Override model for delegates
  provider: ""                             # Override provider for delegates
  base_url: ""                             # Override endpoint for delegates
  api_key: ""                              # Override API key for delegates

3.3 Environment Variables

Core

Variable Purpose Default
HERMES_HOME Data directory ~/.hermes
HERMES_QUIET Suppress non-essential output unset
HERMES_DEV Development mode (extra logging) unset
HERMES_MANAGED Running in managed/container mode unset
HERMES_YOLO_MODE Skip all confirmation prompts unset
HERMES_REDACT_SECRETS Enable secret redaction in output unset
HERMES_MAX_ITERATIONS Override max agent turns 90
HERMES_RESTART_DRAIN_TIMEOUT Gateway drain timeout on restart (seconds) unset

Model / Provider

Variable Purpose
OPENROUTER_API_KEY OpenRouter API key
OPENROUTER_BASE_URL OpenRouter endpoint override
OPENAI_API_KEY OpenAI API key
OPENAI_BASE_URL OpenAI-compatible endpoint override
ANTHROPIC_API_KEY Anthropic API key
ANTHROPIC_TOKEN Anthropic OAuth/setup token (alternative to API key)
CLAUDE_CODE_OAUTH_TOKEN Claude Code OAuth token
NOUS_INFERENCE_BASE_URL Nous Portal inference endpoint
AI_GATEWAY_API_KEY AI Gateway API key
AI_GATEWAY_BASE_URL AI Gateway base URL
OLLAMA_BASE_URL Ollama endpoint URL
OLLAMA_API_KEY Ollama Cloud API key
CUSTOM_API_KEY Custom provider API key

Terminal

Variable Purpose
TERMINAL_ENV Terminal environment type
TERMINAL_CWD Working directory override
TERMINAL_TIMEOUT Command timeout override
TERMINAL_SSH_HOST SSH backend host
TERMINAL_SSH_USER SSH backend user
TERMINAL_SSH_PORT SSH backend port
TERMINAL_SSH_KEY SSH backend key path
TERMINAL_DOCKER_IMAGE Docker image override
TERMINAL_DOCKER_FORWARD_ENV Env vars to forward to Docker
TERMINAL_DOCKER_VOLUMES Volume mounts for Docker

Browser

Variable Purpose
BROWSER_CDP_URL Chrome DevTools Protocol URL
BROWSER_USE_API_KEY BrowserUse service key
BROWSERBASE_API_KEY Browserbase service key
BROWSERBASE_PROJECT_ID Browserbase project ID
FIRECRAWL_API_KEY Firecrawl service key

Gateway Platform Credentials

Variable Purpose
TELEGRAM_BOT_TOKEN Telegram bot token
TELEGRAM_ALLOWED_USERS Comma-separated allowed user IDs
DISCORD_BOT_TOKEN Discord bot token
DISCORD_ALLOWED_USERS Comma-separated allowed user IDs
SLACK_BOT_TOKEN Slack bot OAuth token
SLACK_APP_TOKEN Slack app-level token (Socket Mode)
SLACK_ALLOWED_USERS Comma-separated allowed user IDs
SIGNAL_HTTP_URL Signal REST API URL
SIGNAL_ACCOUNT Signal account identifier
MATRIX_HOMESERVER Matrix server URL
MATRIX_USER_ID Matrix user ID
MATRIX_PASSWORD Matrix password
MATRIX_ACCESS_TOKEN Matrix access token
MATTERMOST_URL Mattermost server URL
MATTERMOST_TOKEN Mattermost bot token
EMAIL_IMAP_HOST IMAP server hostname
EMAIL_SMTP_HOST SMTP server hostname
EMAIL_ADDRESS Email account address
EMAIL_PASSWORD Email account password
TWILIO_ACCOUNT_SID Twilio account SID
TWILIO_AUTH_TOKEN Twilio auth token
TWILIO_PHONE_NUMBER Twilio phone number
SMS_INSECURE_NO_SIGNATURE Disable Twilio webhook signature validation (testing only)
HASS_URL Home Assistant URL
HASS_TOKEN Home Assistant long-lived token
DINGTALK_CLIENT_ID DingTalk client ID
DINGTALK_CLIENT_SECRET DingTalk client secret
FEISHU_APP_ID Feishu/Lark app ID
FEISHU_APP_SECRET Feishu/Lark app secret
WECOM_BOT_ID WeCom bot ID (bot mode)
WECOM_SECRET WeCom bot secret (bot mode)
WECOM_CALLBACK_CORP_ID WeCom corp ID (callback mode)
WECOM_CALLBACK_CORP_SECRET WeCom corp secret (callback mode)
WECOM_CALLBACK_AGENT_ID WeCom agent ID (callback mode)
WECOM_CALLBACK_TOKEN WeCom callback verification token
WECOM_CALLBACK_ENCODING_AES_KEY WeCom callback AES encryption key
WEIXIN_ACCOUNT_ID Weixin account ID
WEIXIN_TOKEN Weixin token
WEIXIN_BASE_URL Weixin iLink Bot API base URL
QQ_APP_ID QQ bot app ID
QQ_CLIENT_SECRET QQ bot client secret
BLUEBUBBLES_SERVER_URL BlueBubbles server URL
BLUEBUBBLES_PASSWORD BlueBubbles server password
WHATSAPP_ENABLED Enable WhatsApp bridge
WHATSAPP_ALLOWED_USERS Comma-separated allowed WhatsApp users
WHATSAPP_FREE_RESPONSE_CHATS Chats where Hermes responds without mention
WHATSAPP_REQUIRE_MENTION Require mention to respond (default: false)

Gateway Behavior

Variable Purpose
SESSION_IDLE_MINUTES Idle timeout before session reset
SESSION_RESET_HOUR Hour (0-23) for daily session reset
WEBHOOK_SECRET HMAC secret for webhook validation
API_SERVER_PORT API server listen port (default: 8642)
API_SERVER_HOST API server bind address
GATEWAY_ALLOW_ALL_USERS Allow all users without pairing (dangerous)

Memory

Variable Purpose
HONCHO_BASE_URL Honcho memory service URL
HONCHO_API_KEY Honcho API key
HONCHO_ENVIRONMENT Honcho environment (production default)
HONCHO_TIMEOUT Honcho request timeout
HINDSIGHT_API_KEY Hindsight Cloud API key
HINDSIGHT_LLM_API_KEY LLM API key for Hindsight local mode
HINDSIGHT_API_URL Hindsight API endpoint override
HINDSIGHT_MODE Hindsight mode (cloud, local_embedded, local_external)

Display

Variable Purpose
NO_COLOR Disable colored output
TERM Terminal type for capability detection

3.4 CLI Flags

Main Command (hermes)

Flag Short Purpose
--quiet -q Suppress non-essential output
--model -m Override model name
--task -t Non-interactive: run single task and exit
--source -s Source directory to operate on
--verbose -v Enable verbose logging
--quick-task -Q Minimal context task
--resume -r Resume previous session
--continue -c Continue last session
--workspace -w Set working directory
--checkpoints Enable conversation checkpoints
--max-turns Override max conversation turns
--yolo Skip all confirmation prompts
--pass-session-id Provide explicit session ID
--image Attach image to initial prompt

Gateway Commands

Flag Purpose
--config Path to gateway config file
--verbose Verbose gateway logging
--replace Replace existing gateway instance
--system Install as system-level service
--all Apply to all platforms
--deep Deep health check
--force Force operation without confirmation
--run-as-user Run gateway service as specified user

Auth Commands

Flag Purpose
--provider Auth provider name
--portal-url OAuth portal URL
--inference-url Inference endpoint URL
--client-id OAuth client ID
--scope OAuth scope
--no-browser Manual auth flow (no browser launch)
--timeout Auth flow timeout
--ca-bundle CA certificate bundle path
--insecure Skip TLS verification

4. Deployment & Scaling

Docker

The repository includes a Dockerfile and docker/entrypoint.sh for containerized deployment.

docker build -t hermes-agent .
docker run -it \
  -e ANTHROPIC_API_KEY=sk-ant-... \
  -e HERMES_HOME=/opt/data \
  -v ~/.hermes:/opt/data \
  hermes-agent

Note

The entrypoint script handles privilege dropping (via HERMES_UID/HERMES_GID), virtual environment activation, directory creation, and skill synchronization automatically. HERMES_HOME defaults to /opt/data inside the container.

Key Docker behaviors:

  • Security: cap-drop ALL with selective add-back of DAC_OVERRIDE, CHOWN, FOWNER
  • no-new-privileges enforced
  • PID limit of 256
  • Non-root execution via UID/GID mapping

Gateway as System Service

Install the gateway as a persistent systemd service:

# User-level service
hermes gateway install

# System-level service (requires root)
hermes gateway install --system

# Non-root execution
hermes gateway install --run-as-user hermes

Once installed, the gateway starts automatically on boot and restarts on failure. Manage with standard systemctl commands or hermes gateway start/stop/restart/status.

Nix

A flake.nix is provided for NixOS and nix-darwin users:

nix develop           # Enter development shell
nix build             # Build package
nix run .#hermes      # Run directly

Homebrew

A Homebrew formula is available in packaging/homebrew/:

brew install --formula ./packaging/homebrew/hermes-agent.rb

Batch Processing

batch_runner.py enables parallel dataset processing for training data generation and evaluation:

  • Configurable parallelism
  • Automatic checkpointing for resumability
  • Per-item tool call statistics
  • Trajectory saving for analysis
  • Example configs in datagen-config-examples/
hermes batch --config datagen-config-examples/example.yaml

5. Operations

Gateway Management

hermes gateway start                  # Start all configured platforms
hermes gateway stop                   # Graceful shutdown
hermes gateway restart                # Restart with drain period
hermes gateway status                 # Show running platforms
hermes gateway status --deep          # Deep health check (connectivity test)

Tip

Set HERMES_RESTART_DRAIN_TIMEOUT to control how long the gateway waits for in-flight messages to complete before restarting. This prevents message loss during rolling restarts.

Platform-specific management:

hermes gateway pair telegram          # Generate pairing code for Telegram
hermes gateway unpair telegram <user> # Remove paired user
hermes gateway mirror add             # Configure cross-platform message mirroring
hermes gateway channels               # List active channels

Session Management

Sessions are stored in SQLite (WAL mode) via SessionDB in hermes_state.py.

hermes sessions list                  # List all sessions
hermes sessions browse <id>          # Browse session conversation
hermes sessions search "query"       # Full-text search across sessions
hermes sessions export <id>          # Export session as JSON
hermes sessions delete <id>          # Delete specific session
hermes sessions prune --before 30d   # Remove sessions older than 30 days
hermes sessions rename <id> "name"   # Rename a session
hermes sessions analytics            # Cross-session behavioral analytics

Session key format: agent:main:{platform}:{chat_type}:{chat_id}

Cron Operations

Note

Cron jobs support per-job model and provider overrides, a grace window system for missed executions, and a script parameter for injecting dynamic context at execution time.

hermes cron list                     # List all scheduled jobs
hermes cron create                   # Create new job interactively
hermes cron edit <id>                # Edit existing job
hermes cron pause <id>               # Pause job
hermes cron resume <id>              # Resume paused job
hermes cron run <id>                 # Run job immediately
hermes cron remove <id>             # Delete job
hermes cron status                   # Scheduler status
hermes cron tick                     # Manual tick (check and run due jobs)

Job definitions live in ~/.hermes/cron/jobs.json.

Monitoring & Diagnostics

hermes logs agent                    # View agent logs
hermes logs errors                   # View error logs only
hermes logs gateway                  # View gateway logs
hermes logs agent -f                 # Follow (tail) logs
hermes logs agent --level ERROR      # Filter by level
hermes logs agent --since 1h         # Filter by time
hermes logs agent --component gateway # Filter by component

hermes doctor                        # Run diagnostic checks
hermes debug                         # Generate paste-able debug report
hermes status                        # System status overview

Backup & Restore

hermes backup                        # Full backup (zip archive)
hermes backup --quick                # Snapshot of critical files only (config, auth, sessions)
hermes import <zipfile>              # Restore from backup

Tip

Schedule regular backups via hermes cron create with the backup command. The --quick flag is suitable for frequent snapshots while the full backup captures sessions, skills, and plugins.

Updates

hermes update                        # Pull latest from git, auto-stash local changes

The update command automatically stashes local modifications, pulls changes, restores stashed files, and restarts the gateway if it was running.


6. Performance

Context Compression

The ContextCompressor (agent/context_compressor.py) automatically manages conversation context to prevent exceeding model token limits.

Algorithm:

  1. Monitor token usage against context window size
  2. When usage exceeds threshold (default: 50% of context limit), trigger compression
  3. Prune old tool results first (largest token savings)
  4. Protect head of conversation (system prompt, initial context)
  5. Protect tail (~20K tokens of recent context)
  6. Summarize middle section via LLM call
  7. Replace original messages with compressed version

Configure via:

compression:
  enabled: true
  threshold: 0.50    # Trigger at 50% context usage

Manual compression: use the /compress slash command in the REPL.

Smart Model Routing

Routes simple, short queries to a cheaper/faster model to reduce cost and latency.

smart_model_routing:
  enabled: true
  max_simple_chars: 160
  max_simple_words: 28
  cheap_model:
    model: "anthropic/claude-haiku-3"
    base_url: ""
    api_key: ""

Classification: messages under both the character and word thresholds, containing no code blocks or complex formatting, are routed to the cheap model.

Prompt Caching

The Anthropic adapter (agent/anthropic_adapter.py) adds cache_control markers to system prompts and long context blocks. Gateway sessions benefit from per-session agent caching, which maximizes cache hit rates for repeated conversations.

Thinking Budget (Anthropic Models)

Reasoning effort controls the thinking budget for Anthropic models:

Level Budget
none Thinking disabled
minimal Minimal thinking
low ~4K thinking tokens
medium ~8K thinking tokens
high ~16K thinking tokens
xhigh ~32K thinking tokens

For Claude 4.6, the adapter supports adaptive thinking (model self-selects budget). For older models, the budget is set explicitly.

Set via config or CLI:

agent:
  reasoning_effort: "medium"

7. Security

Warning

The gateway exposes your agent to external messaging platforms. Always configure per-platform allowed users and never set GATEWAY_ALLOW_ALL_USERS=true in production.

Secret Redaction

Enable HERMES_REDACT_SECRETS to scrub API keys, tokens, and passwords from agent output and logs. The agent/redact.py module performs pattern-based redaction.

Caution

Issue #11009 documents a race condition where config is not fully applied before the redact module is imported. Secrets in very early startup output may not be redacted. Set the environment variable before process launch rather than relying on config.yaml.

Credential Store

Credentials are stored in ~/.hermes/auth.json with file-level advisory locking to prevent corruption from concurrent access.

The CredentialPool (agent/credential_pool.py) manages multiple API keys per provider with configurable rotation strategies:

Strategy Behavior
fill-first Use primary key until rate-limited, then next
round-robin Cycle through keys sequentially
least-used Route to key with lowest usage count
random Random key selection per request

Gateway Security

DM Pairing System:

  • 8-character alphanumeric pairing codes
  • 1-hour code expiry
  • Rate limiting on pairing attempts
  • Account lockout after 5 failed attempts
  • Pairing file permissions set to chmod 0600

Per-Platform Access Control: Each platform adapter supports an allowed-users list via environment variable (e.g., TELEGRAM_ALLOWED_USERS, DISCORD_ALLOWED_USERS).

SSRF Protection: Media download functions in base.py, feishu.py, wecom.py, weixin.py, qqbot.py, and slack.py include SSRF protection against internal network access via URL validation.

Prompt Injection Detection

Context files (.hermes.md, HERMES.md, AGENTS.md) are scanned on load for:

  • Invisible unicode characters (zero-width spaces, homoglyphs)
  • Data exfiltration patterns (encoded URLs, base64 payloads)
  • System prompt override attempts

File Access Control

  • Sensitive credential files (auth.json, .env, SSH keys) are blocked from context file attachment
  • Path traversal patterns are rejected
  • Workspace boundary enforcement prevents reads outside the designated project directory

Docker Security

When using the Docker terminal backend:

  • cap-drop ALL removes all Linux capabilities
  • Only DAC_OVERRIDE, CHOWN, FOWNER are added back
  • no-new-privileges flag prevents privilege escalation
  • PID limit of 256 constrains fork bombs

Webhook Security

Inbound webhooks require HMAC signature validation via the WEBHOOK_SECRET environment variable. The SMS_INSECURE_NO_SIGNATURE flag disables Twilio signature validation for local testing only.

Warning

Never set SMS_INSECURE_NO_SIGNATURE in production. This completely disables webhook authentication for the SMS/Twilio adapter, allowing anyone to inject messages.

Web Dashboard Security

  • Binds to localhost only by default
  • --insecure flag required to bind to non-localhost addresses
  • Session-token authentication
  • Rate-limited secret reveal endpoints

8. Developer Internals

Repository Structure

hermes-agent/
├── cli.py                          # Legacy CLI entry point
├── run_agent.py                    # AIAgent orchestrator (~3600 lines)
├── model_tools.py                  # Tool registry dispatcher
├── toolsets.py                     # Composable tool groups
├── toolset_distributions.py        # Probabilistic sampling for batch
├── batch_runner.py                 # Parallel batch processing
├── hermes_constants.py             # Shared constants
├── hermes_logging.py               # Centralized logging
├── hermes_state.py                 # SessionDB (SQLite)
├── hermes_time.py                  # Timezone handling
├── mcp_serve.py                    # MCP server mode
├── mini_swe_runner.py              # Minimal SWE runner
├── trajectory_compressor.py        # Trajectory compression
├── utils.py                        # Utilities
├── agent/                          # Agent support modules (30 files)
│   ├── anthropic_adapter.py        # Anthropic API adapter
│   ├── auxiliary_client.py         # Auxiliary model client
│   ├── context_compressor.py       # Context window compression
│   ├── prompt_builder.py           # System prompt assembly
│   ├── model_metadata.py           # Model capability registry
│   ├── display.py                  # Output formatting
│   ├── error_classifier.py         # Error categorization
│   ├── credential_pool.py          # Multi-key rotation
│   ├── rate_limit_tracker.py       # Rate limit tracking
│   ├── usage_pricing.py            # Token cost calculation
│   ├── smart_model_routing.py      # Simple query routing
│   ├── memory_manager.py           # Memory operations
│   ├── trajectory.py               # Conversation trajectory
│   ├── skill_commands.py           # Skill dispatch
│   ├── insights.py                 # Behavioral analytics
│   ├── bedrock_adapter.py          # AWS Bedrock support
│   ├── copilot_acp_client.py       # Copilot ACP client
│   └── redact.py                   # Secret redaction
├── hermes_cli/                     # CLI commands & config (48 files)
│   ├── main.py                     # CLI router and REPL
│   ├── auth.py                     # Authentication management
│   ├── config.py                   # Config file handling
│   ├── profiles.py                 # Named config profiles
│   ├── plugins.py                  # Plugin management
│   ├── web_server.py               # Web dashboard server
│   ├── skills_hub.py               # Skills marketplace
│   ├── mcp_config.py               # MCP configuration
│   ├── doctor.py                   # Diagnostic checks
│   ├── debug.py                    # Debug report generation
│   └── backup.py                   # Backup/restore
├── gateway/                        # Gateway core (15 files)
│   ├── run.py                      # GatewayRunner controller
│   ├── config.py                   # GatewayConfig manager
│   ├── delivery.py                 # Message delivery pipeline
│   ├── hooks.py                    # Lifecycle hooks
│   ├── pairing.py                  # DM pairing system
│   ├── mirror.py                   # Cross-platform mirroring
│   ├── channel_directory.py        # Channel registry
│   ├── display_config.py           # Platform display settings
│   ├── status.py                   # Gateway status tracking
│   └── platforms/                  # Platform adapters (24 files)
│       ├── base.py                 # BasePlatformAdapter ABC
│       ├── telegram.py             # Telegram adapter
│       ├── discord_platform.py     # Discord adapter
│       ├── slack.py                # Slack adapter
│       ├── matrix_platform.py      # Matrix adapter
│       ├── whatsapp.py             # WhatsApp Cloud API
│       ├── whatsapp_baileys.py     # WhatsApp via Baileys
│       ├── signal_platform.py      # Signal adapter
│       ├── email_platform.py       # Email (IMAP/SMTP)
│       ├── sms.py                  # SMS via Twilio
│       ├── mattermost.py          # Mattermost adapter
│       ├── hass.py                 # Home Assistant
│       ├── dingtalk.py             # DingTalk adapter
│       ├── feishu.py               # Feishu/Lark adapter
│       ├── wecom.py                # WeCom adapter
│       ├── weixin.py               # Weixin adapter
│       ├── qqbot.py                # QQ adapter
│       ├── bluebubbles.py          # BlueBubbles (iMessage)
│       └── api_server.py           # OpenAI-compatible API server
├── tools/                          # Tool implementations
│   ├── environments/               # Terminal backends (11 files)
│   │   ├── base.py                 # BaseEnvironment ABC
│   │   ├── local.py                # Local shell execution
│   │   ├── docker_env.py           # Docker container
│   │   ├── ssh_env.py              # SSH remote execution
│   │   ├── modal_env.py            # Modal cloud
│   │   ├── managed_modal_env.py    # Managed Modal
│   │   ├── singularity_env.py      # Singularity/Apptainer
│   │   └── daytona_env.py          # Daytona workspace
│   └── browser_providers/          # Browser cloud providers (5 files)
│       ├── browserbase.py          # Browserbase
│       ├── browseruse.py           # BrowserUse
│       └── firecrawl.py            # Firecrawl
├── cron/                           # Scheduler (3 files)
│   ├── scheduler.py                # CronScheduler
│   ├── job.py                      # Job definition
│   └── manager.py                  # Job CRUD
├── plugins/                        # Plugin system
│   ├── memory/                     # Memory providers
│   └── context_engine/             # Context engine plugin
├── environments/                   # RL training environments
│   ├── benchmarks/                 # TBLite, TB2, YC-Bench
│   └── tool_call_parsers/          # Phase 2 parsers
├── acp_adapter/                    # ACP for IDE integration (9 files)
├── web/                            # React dashboard frontend
├── website/                        # Docusaurus docs site
├── skills/                         # Bundled skills (100+)
├── optional-skills/                # Optional installable skills
├── docker/                         # Docker entrypoint
├── packaging/                      # Homebrew formula
├── nix/                            # Nix support
├── tests/                          # Test suite
└── datagen-config-examples/        # Batch config examples

Module Reference

run_agent.py — AIAgent

The central orchestrator class (~3600 lines). Manages the complete agent lifecycle:

  • Conversation loop: message dispatch, response streaming, tool call handling
  • Tool dispatch: routes tool calls to registered tool implementations via model_tools.py
  • Context management: tracks token usage, triggers compression when threshold exceeded
  • Memory: integrates with memory providers for cross-session recall
  • Delegation: spawns sub-agents with constrained toolsets and iteration limits
  • Session persistence: saves/restores conversation state via SessionDB
  • Checkpoint system: periodic conversation snapshots for recovery

Key methods: run(), process_message(), handle_tool_call(), delegate(), compress_context()

Dependencies: agent/*, model_tools, hermes_state, toolsets

agent/anthropic_adapter.py

Adapter for the Anthropic API. Handles:

  • Message format conversion (OpenAI format to Anthropic format)
  • Prompt caching with cache_control markers
  • Thinking budget management (reasoning effort levels)
  • Streaming response handling
  • Extended thinking token extraction

agent/auxiliary_client.py

Client for auxiliary model calls (vision analysis, web content extraction, approval workflows). Configurable per-task model/provider/endpoint. Falls back through provider chain if primary fails.

agent/context_compressor.py

Implements the ContextCompressor class. Algorithm: monitor token count against context window, prune tool results, protect head and tail (~20K tokens), summarize middle via LLM. Exposes both automatic (threshold-based) and manual (/compress) compression.

agent/prompt_builder.py

Assembles the complete system prompt from components:

  • Base system prompt (or custom override)
  • SOUL.md personality file
  • Active skills with their instructions
  • Context files (.hermes.md, HERMES.md, AGENTS.md)
  • Memory context from providers
  • Tool descriptions for the active toolset
  • Active environment metadata

agent/credential_pool.py

CredentialPool class manages multiple API keys per provider. Supports rotation strategies (fill-first, round-robin, least-used, random). Tracks per-key usage counts and rate limit state. Thread-safe with advisory file locking.

agent/error_classifier.py

Categorizes errors from LLM providers and tool execution into actionable classes: rate limit, authentication failure, context overflow, network error, invalid request, server error, timeout. Used by retry logic in tenacity decorators to determine backoff strategy and whether to rotate credentials.

hermes_cli/main.py

The CLI router. Implements the interactive REPL via prompt_toolkit and routes subcommands (gateway, sessions, cron, auth, config, plugins, skills, doctor, debug, backup, update, etc.) to their respective handler modules. Contains load_cli_config() implementing the full config resolution chain (env > yaml > legacy > defaults).

hermes_cli/auth.py

Authentication management: OAuth flows with browser-based and --no-browser fallback, credential storage in auth.json with file locking, provider-specific login/logout flows, token refresh and expiry tracking.

hermes_cli/config.py

Config file handling: load, save, validate, merge. Implements the multi-layer config resolution chain. Supports hermes config get/set/list/edit/reset subcommands for interactive configuration management.

hermes_cli/profiles.py

Named configuration profiles allowing quick switching between pre-configured sets of model, provider, terminal backend, and behavior settings. Profiles are stored as named sections within the config file.

hermes_cli/plugins.py

Plugin discovery, installation, activation, and lifecycle management. Plugins are Python packages following a defined interface with register() and activate() entry points.

hermes_cli/web_server.py

Serves the React web dashboard. Localhost-only by default, with --insecure override for network access. Handles session-token authentication and proxies API calls to the agent backend.

gateway/run.py — GatewayRunner

The gateway controller. Manages platform adapter lifecycle:

  • Loads GatewayConfig, instantiates configured platform adapters
  • Starts adapters concurrently via asyncio
  • Routes inbound messages to agent sessions (keyed by platform + chat ID)
  • Handles graceful shutdown with configurable drain timeout
  • Restart support with message draining to prevent loss

gateway/config.py — GatewayConfig

Gateway configuration manager. Merges config sources (config.yaml gateway section, legacy gateway.json, environment variables, CLI flags). Validates platform configurations and resolves credential references. Determines which platforms to activate based on available credentials.

gateway/platforms/base.py — BasePlatformAdapter

Abstract base class defining the interface for all 19 platform adapters:

  • start() / stop() — adapter lifecycle management
  • send_message() — outbound message delivery with platform-native formatting
  • on_message() — inbound message callback registration
  • health_check() — connectivity and credential validation
  • Media download with SSRF protection (URL validation against internal networks)
  • Markdown-to-platform format conversion

tools/environments/base.py — BaseEnvironment

Abstract base class for terminal backends:

  • execute(command, timeout) — run command, return stdout/stderr/exit_code
  • start() / stop() — backend lifecycle (container creation, SSH connection, etc.)
  • upload_file() / download_file() — file transfer between host and environment
  • get_cwd() — current working directory query
  • Resource limit properties (CPU, memory, disk)

Code Patterns

Pattern Where Used Description
Filesystem as state machine Sessions, cron, auth, pairing State persisted to files; transitions via atomic file operations
Atomic file operations Auth, config, sessions Write to temp file, then os.replace() for crash safety
File-based advisory locks Credential store, session DB Cross-process coordination without external lock service
Platform adapter pattern gateway/platforms/ BasePlatformAdapter ABC with 19 concrete implementations
Multi-layer config resolution hermes_cli/config.py env > config.yaml > legacy > defaults
Provider fallback chain Model routing OpenRouter > Nous > Codex > Anthropic > Direct
Retry with classification Error handling error_classifier.py categorizes errors; tenacity retries with strategy-specific backoff
Composable toolsets toolsets.py Named groups of tools (terminal, file, web) composed per-session or per-delegation

Testing

Test structure mirrors the source layout:

tests/
├── agent/           # Agent module unit tests
├── cli/             # Legacy CLI tests
├── hermes_cli/      # CLI command tests
├── gateway/         # Gateway and platform adapter tests
├── run_agent/       # AIAgent orchestrator tests
├── plugins/         # Plugin system tests
├── cron/            # Scheduler tests
├── acp/             # ACP adapter tests
├── environments/    # Terminal backend tests
├── skills/          # Skill tests
├── honcho_plugin/   # Honcho memory plugin tests
├── e2e/             # End-to-end tests
└── integration/     # Integration tests

The test suite uses pytest with heavy mocking (fake HTTP servers, fake platform adapters, mock LLM responses). Run with:

pytest tests/
pytest tests/gateway/ -v          # Specific module
pytest tests/ -k "test_pairing"   # Pattern match

API Endpoints — Web Dashboard

The web dashboard API server exposes endpoints for the React frontend:

Method Path Purpose
GET /health Health check
GET /health/detailed Detailed health with subsystem status
GET /v1/models List available models
POST /v1/chat/completions OpenAI-compatible chat completions
POST /v1/responses Responses API
POST /v1/runs Async run with SSE streaming
GET /api/sessions List sessions
GET /api/sessions/:id Get session details
DELETE /api/sessions/:id Delete session
POST /api/sessions/:id/message Send message to session
GET /api/config Get current configuration
PUT /api/config Update configuration
GET /api/status System status
GET /api/skills List available skills
POST /api/skills/install Install skill
DELETE /api/skills/:name Remove skill
GET /api/cron List cron jobs
POST /api/cron Create cron job
PUT /api/cron/:id Update cron job
DELETE /api/cron/:id Delete cron job
POST /api/cron/:id/run Trigger cron job
GET /api/gateway/status Gateway status
POST /api/gateway/start Start gateway
POST /api/gateway/stop Stop gateway
GET /api/gateway/platforms List platforms
GET /api/gateway/paired List paired users
POST /api/gateway/pair Generate pairing code
DELETE /api/gateway/unpair Remove paired user
GET /api/logs Fetch logs
GET /api/logs/stream SSE log stream
GET /api/plugins List plugins
POST /api/plugins/install Install plugin
DELETE /api/plugins/:name Remove plugin
GET /api/profiles List config profiles
POST /api/profiles Create profile
PUT /api/profiles/:name Update profile
DELETE /api/profiles/:name Delete profile
POST /api/profiles/:name/activate Activate profile
GET /api/auth Auth status
POST /api/auth/login Login
POST /api/auth/logout Logout
GET /api/analytics Session analytics
POST /api/backup Create backup
POST /api/import Import backup
GET /api/doctor Run diagnostics
GET /api/debug Debug report

API Server — OpenAI-Compatible

The API Server adapter (gateway/platforms/api_server.py) provides an OpenAI-compatible REST API on port 8642 (configurable via API_SERVER_PORT):

Method Path Purpose
POST /v1/chat/completions Chat completions (streaming and non-streaming)
POST /v1/responses Responses API format
GET /v1/models List available models
POST /v1/runs Async run with SSE events
GET /health Simple health check
GET /health/detailed Detailed subsystem health

Any OpenAI-compatible frontend (Open WebUI, LobeChat, ChatBox, etc.) can connect by pointing to http://localhost:8642.


9. Integration Points

ACP (Agent Communication Protocol)

For IDE and editor integration (VS Code, JetBrains, Cursor, etc.):

hermes acp                           # Start ACP server
  • JSON-RPC over stdio transport
  • Session management (create, resume, list)
  • MCP server registration and forwarding
  • Tool progress events for UI feedback
  • Implementation in acp_adapter/ (9 files)

MCP Server Mode

Run Hermes as an MCP (Model Context Protocol) server for use as a tool provider to other agents:

pip install hermes-agent[mcp]
python -m mcp_serve

Exposes Hermes tools (terminal, file, web, browser) as MCP-compatible tool definitions.

OpenAI-Compatible API

Start the API server for web frontend integration:

hermes gateway start api_server      # As gateway platform
# or configure in config.yaml

Supports streaming and non-streaming chat completions, the Responses API format, and async runs with SSE.

Webhook Subscriptions

hermes webhook add deploy-notify \
  --prompt "Summarize the deployment changes" \
  --events "push,release" \
  --url "https://example.com/webhook"
  • HMAC-authenticated inbound webhooks (requires WEBHOOK_SECRET)
  • Event filtering by type
  • Delivery to any configured platform
  • Retry on delivery failure

Messaging Platform SDKs

Platform SDK / Bridge Transport
WhatsApp Node.js bridge via Baileys library WebSocket
WhatsApp Cloud Direct API REST + Webhooks
Telegram python-telegram-bot Webhook or Long Polling
Discord discord.py WebSocket + Slash Commands
Slack slack-sdk Socket Mode + Events API
Matrix matrix-nio WebSocket, optional E2EE
Signal signal-cli CLI subprocess
Mattermost API client WebSocket
Home Assistant REST API WebSocket
DingTalk DingTalk Open API Webhook
Feishu/Lark Feishu Open API Webhook
WeCom WeCom API Callback
Weixin Weixin MP API Callback
QQ QQ Bot API WebSocket
BlueBubbles BlueBubbles API REST + Polling
Email imaplib / smtplib IMAP + SMTP
SMS Twilio API REST + Webhook