docs: fix 40+ discrepancies between documentation and codebase (#5818)
Comprehensive audit of all ~100 doc pages against the actual code, fixing: Reference docs: - HERMES_API_TIMEOUT default 900 -> 1800 (env-vars) - TERMINAL_DOCKER_IMAGE default python:3.11 -> nikolaik/python-nodejs (env-vars) - compression.summary_model default shown as gemini -> actually empty string (env-vars) - Add missing GOOGLE_API_KEY, GEMINI_API_KEY, GEMINI_BASE_URL env vars (env-vars) - Add missing /branch (/fork) slash command (slash-commands) - Fix hermes-cli tool count 39 -> 38 (toolsets-reference) - Fix hermes-api-server drop list to include text_to_speech (toolsets-reference) - Fix total tool count 47 -> 48, standalone 14 -> 15 (tools-reference) User guide: - web_extract.timeout default 30 -> 360 (configuration) - Remove display.theme_mode (not implemented in code) (configuration) - Remove display.background_process_notifications (not in defaults) (configuration) - Browser inactivity timeout 300/5min -> 120/2min (browser) - Screenshot path browser_screenshots -> cache/screenshots (browser) - batch_runner default model claude-sonnet-4-20250514 -> claude-sonnet-4.6 - Add minimax to TTS provider list (voice-mode) - Remove credential_pool_strategies from auth.json example (credential-pools) - Fix Slack token path platforms/slack/ -> root ~/.hermes/ (slack) - Fix Matrix store path for new installs (matrix) - Fix WhatsApp session path for new installs (whatsapp) - Fix HomeAssistant config from gateway.json to config.yaml (homeassistant) - Fix WeCom gateway start command (wecom) Developer guide: - Fix tool/toolset counts in architecture overview - Update line counts: main.py ~5500, setup.py ~3100, run.py ~7500, mcp_tool ~2200 - Replace nonexistent agent/memory_store.py with memory_manager.py + memory_provider.py - Update _discover_tools() list: remove honcho_tools, add skill_manager_tool - Add session_search and delegate_task to intercepted tools list (agent-loop) - Fix budget warning: two-tier system (70% caution, 90% warning) (agent-loop) - Fix gateway auth order (per-platform first, global last) (gateway-internals) - Fix email_adapter.py -> email.py, add webhook.py + api_server.py (gateway-internals) - Add 7 missing providers to provider-runtime list Other: - Add Docker --cap-add entries to security doc - Fix Python version 3.10+ -> 3.11+ (contributing) - Fix AGENTS.md discovery claim (not hierarchical walk) (tips) - Fix cron 'add' -> canonical 'create' (cron-internals) - Add pre_api_request/post_api_request hooks to plugin guide - Add Google/Gemini provider to providers page - Clarify OPENAI_BASE_URL deprecation (providers)
This commit is contained in:
@@ -151,9 +151,11 @@ for each tool_call in response.tool_calls:
|
||||
Some tools are intercepted by `run_agent.py` *before* reaching `handle_function_call()`:
|
||||
|
||||
| Tool | Why intercepted |
|
||||
|------|-----------------|
|
||||
|------|--------------------|
|
||||
| `todo` | Reads/writes agent-local task state |
|
||||
| `memory` | Writes to persistent memory files with character limits |
|
||||
| `session_search` | Queries session history via the agent's session DB |
|
||||
| `delegate_task` | Spawns subagent(s) with isolated context |
|
||||
|
||||
These tools modify agent state directly and return synthetic tool results without going through the registry.
|
||||
|
||||
@@ -180,7 +182,9 @@ The agent tracks iterations via `IterationBudget`:
|
||||
|
||||
- Default: 90 iterations (configurable via `agent.max_turns`)
|
||||
- Shared across parent and child agents — a subagent consumes from the parent's budget
|
||||
- At 70%+ usage, `_get_budget_warning()` appends a `[BUDGET WARNING: ...]` to the last tool result
|
||||
- Two-tier budget pressure via `_get_budget_warning()`:
|
||||
- At 70%+ usage (caution tier): appends `[BUDGET: Iteration X/Y. N iterations left. Start consolidating your work.]` to the last tool result
|
||||
- At 90%+ usage (warning tier): appends `[BUDGET WARNING: Iteration X/Y. Only N iteration(s) left. Provide your final response NOW.]`
|
||||
- At 100%, the agent stops and returns a summary of work done
|
||||
|
||||
### Fallback Model
|
||||
|
||||
@@ -32,8 +32,8 @@ This page is the top-level map of Hermes Agent internals. Use it to orient yours
|
||||
│ ┌──────┴───────┐ ┌──────┴───────┐ ┌──────┴───────┐ │
|
||||
│ │ Compression │ │ 3 API Modes │ │ Tool Registry│ │
|
||||
│ │ & Caching │ │ chat_compl. │ │ (registry.py)│ │
|
||||
│ │ │ │ codex_resp. │ │ 47 tools │ │
|
||||
│ │ │ │ anthropic │ │ 37 toolsets │ │
|
||||
│ │ │ │ codex_resp. │ │ 48 tools │ │
|
||||
│ │ │ │ anthropic │ │ 40 toolsets │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
│ │
|
||||
@@ -70,18 +70,19 @@ hermes-agent/
|
||||
│ ├── anthropic_adapter.py # Anthropic Messages API format conversion
|
||||
│ ├── display.py # KawaiiSpinner, tool preview formatting
|
||||
│ ├── skill_commands.py # Skill slash commands
|
||||
│ ├── memory_store.py # Persistent memory read/write
|
||||
│ ├── memory_manager.py # Memory manager orchestration
|
||||
│ ├── memory_provider.py # Memory provider ABC
|
||||
│ └── trajectory.py # Trajectory saving helpers
|
||||
│
|
||||
├── hermes_cli/ # CLI subcommands and setup
|
||||
│ ├── main.py # Entry point — all `hermes` subcommands (~4,200 lines)
|
||||
│ ├── main.py # Entry point — all `hermes` subcommands (~5,500 lines)
|
||||
│ ├── config.py # DEFAULT_CONFIG, OPTIONAL_ENV_VARS, migration
|
||||
│ ├── commands.py # COMMAND_REGISTRY — central slash command definitions
|
||||
│ ├── auth.py # PROVIDER_REGISTRY, credential resolution
|
||||
│ ├── runtime_provider.py # Provider → api_mode + credentials
|
||||
│ ├── models.py # Model catalog, provider model lists
|
||||
│ ├── model_switch.py # /model command logic (CLI + gateway shared)
|
||||
│ ├── setup.py # Interactive setup wizard (~3,500 lines)
|
||||
│ ├── setup.py # Interactive setup wizard (~3,100 lines)
|
||||
│ ├── skin_engine.py # CLI theming engine
|
||||
│ ├── skills_config.py # hermes skills — enable/disable per platform
|
||||
│ ├── skills_hub.py # /skills slash command
|
||||
@@ -100,14 +101,14 @@ hermes-agent/
|
||||
│ ├── browser_tool.py # 11 browser automation tools
|
||||
│ ├── code_execution_tool.py # execute_code sandbox
|
||||
│ ├── delegate_tool.py # Subagent delegation
|
||||
│ ├── mcp_tool.py # MCP client (~1,050 lines)
|
||||
│ ├── mcp_tool.py # MCP client (~2,200 lines)
|
||||
│ ├── credential_files.py # File-based credential passthrough
|
||||
│ ├── env_passthrough.py # Env var passthrough for sandboxes
|
||||
│ ├── ansi_strip.py # ANSI escape stripping
|
||||
│ └── environments/ # Terminal backends (local, docker, ssh, modal, daytona, singularity)
|
||||
│
|
||||
├── gateway/ # Messaging platform gateway
|
||||
│ ├── run.py # GatewayRunner — message dispatch (~5,800 lines)
|
||||
│ ├── run.py # GatewayRunner — message dispatch (~7,500 lines)
|
||||
│ ├── session.py # SessionStore — conversation persistence
|
||||
│ ├── delivery.py # Outbound message delivery
|
||||
│ ├── pairing.py # DM pairing authorization
|
||||
|
||||
@@ -33,7 +33,7 @@ We value contributions in this order:
|
||||
| Requirement | Notes |
|
||||
|-------------|-------|
|
||||
| **Git** | With `--recurse-submodules` support |
|
||||
| **Python 3.10+** | uv will install it if missing |
|
||||
| **Python 3.11+** | uv will install it if missing |
|
||||
| **uv** | Fast Python package manager ([install](https://docs.astral.sh/uv/)) |
|
||||
| **Node.js 18+** | Optional — needed for browser tools and WhatsApp bridge |
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ The `hermes cron` CLI provides direct job management:
|
||||
|
||||
```bash
|
||||
hermes cron list # Show all jobs
|
||||
hermes cron add # Interactive job creation
|
||||
hermes cron create # Interactive job creation (alias: add)
|
||||
hermes cron edit <job_id> # Edit job configuration
|
||||
hermes cron pause <job_id> # Pause a running job
|
||||
hermes cron resume <job_id> # Resume a paused job
|
||||
|
||||
@@ -12,7 +12,7 @@ The messaging gateway is the long-running process that connects Hermes to 14+ ex
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `gateway/run.py` | `GatewayRunner` — main loop, slash commands, message dispatch (~7,200 lines) |
|
||||
| `gateway/run.py` | `GatewayRunner` — main loop, slash commands, message dispatch (~7,500 lines) |
|
||||
| `gateway/session.py` | `SessionStore` — conversation persistence and session key construction |
|
||||
| `gateway/delivery.py` | Outbound message delivery to target platforms/channels |
|
||||
| `gateway/pairing.py` | DM pairing flow for user authorization |
|
||||
@@ -91,10 +91,11 @@ Commands that must reach the runner while the agent is blocked (like `/approve`)
|
||||
|
||||
The gateway uses a multi-layer authorization check, evaluated in order:
|
||||
|
||||
1. **Gateway-wide allow-all** (`GATEWAY_ALLOW_ALL_USERS`) — if set, all users are authorized
|
||||
1. **Per-platform allow-all flag** (e.g., `TELEGRAM_ALLOW_ALL_USERS`) — if set, all users on that platform are authorized
|
||||
2. **Platform allowlist** (e.g., `TELEGRAM_ALLOWED_USERS`) — comma-separated user IDs
|
||||
3. **DM pairing** — authenticated users can pair new users via a pairing code
|
||||
4. **Admin escalation** — some commands require admin status beyond basic authorization
|
||||
4. **Global allow-all** (`GATEWAY_ALLOW_ALL_USERS`) — if set, all users across all platforms are authorized
|
||||
5. **Default: deny** — unauthorized users are rejected
|
||||
|
||||
### DM Pairing Flow
|
||||
|
||||
@@ -154,11 +155,13 @@ gateway/platforms/
|
||||
├── signal.py # Signal via signal-cli REST API
|
||||
├── matrix.py # Matrix via matrix-nio (optional E2EE)
|
||||
├── mattermost.py # Mattermost WebSocket API
|
||||
├── email_adapter.py # Email via IMAP/SMTP
|
||||
├── email.py # Email via IMAP/SMTP
|
||||
├── sms.py # SMS via Twilio
|
||||
├── dingtalk.py # DingTalk WebSocket
|
||||
├── feishu.py # Feishu/Lark WebSocket or webhook
|
||||
├── wecom.py # WeCom (WeChat Work) callback
|
||||
├── webhook.py # Inbound/outbound webhook adapter
|
||||
├── api_server.py # REST API server adapter
|
||||
└── homeassistant.py # Home Assistant conversation integration
|
||||
```
|
||||
|
||||
|
||||
@@ -42,11 +42,18 @@ Current provider families include:
|
||||
- OpenRouter
|
||||
- Nous Portal
|
||||
- OpenAI Codex
|
||||
- Copilot / Copilot ACP
|
||||
- Anthropic (native)
|
||||
- Google / Gemini
|
||||
- Alibaba / DashScope
|
||||
- DeepSeek
|
||||
- Z.AI
|
||||
- Kimi / Moonshot
|
||||
- MiniMax
|
||||
- MiniMax China
|
||||
- Kilo Code
|
||||
- Hugging Face
|
||||
- OpenCode Zen / OpenCode Go
|
||||
- Custom (`provider: custom`) — first-class provider for any OpenAI-compatible endpoint
|
||||
- Named custom providers (`custom_providers` list in config.yaml)
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ _modules = [
|
||||
"tools.mixture_of_agents_tool",
|
||||
"tools.image_generation_tool",
|
||||
"tools.skills_tool",
|
||||
"tools.skill_manager_tool",
|
||||
"tools.browser_tool",
|
||||
"tools.cronjob_tools",
|
||||
"tools.rl_training_tool",
|
||||
@@ -67,7 +68,7 @@ _modules = [
|
||||
"tools.delegate_tool",
|
||||
"tools.process_registry",
|
||||
"tools.send_message_tool",
|
||||
"tools.honcho_tools",
|
||||
# "tools.honcho_tools", # Removed — Honcho is now a memory provider plugin
|
||||
"tools.homeassistant_tool",
|
||||
]
|
||||
```
|
||||
|
||||
@@ -405,6 +405,8 @@ Each hook is documented in full on the **[Event Hooks reference](/docs/user-guid
|
||||
| [`post_llm_call`](/docs/user-guide/features/hooks#post_llm_call) | Once per turn, after the tool-calling loop (successful turns only) | `session_id: str, user_message: str, assistant_response: str, conversation_history: list, model: str, platform: str` | ignored |
|
||||
| [`on_session_start`](/docs/user-guide/features/hooks#on_session_start) | New session created (first turn only) | `session_id: str, model: str, platform: str` | ignored |
|
||||
| [`on_session_end`](/docs/user-guide/features/hooks#on_session_end) | End of every `run_conversation` call + CLI exit | `session_id: str, completed: bool, interrupted: bool, model: str, platform: str` | ignored |
|
||||
| [`pre_api_request`](/docs/user-guide/features/hooks#pre_api_request) | Before each HTTP request to the LLM provider | `method: str, url: str, headers: dict, body: dict` | ignored |
|
||||
| [`post_api_request`](/docs/user-guide/features/hooks#post_api_request) | After each HTTP response from the LLM provider | `method: str, url: str, status_code: int, response: dict` | ignored |
|
||||
|
||||
Most hooks are fire-and-forget observers — their return values are ignored. The exception is `pre_llm_call`, which can inject context into the conversation.
|
||||
|
||||
|
||||
@@ -95,9 +95,9 @@ Use `SOUL.md` for durable personality. Use `AGENTS.md` for project-specific inst
|
||||
|
||||
Already have a `.cursorrules` or `.cursor/rules/*.mdc` file? Hermes reads those too. No need to duplicate your coding conventions — they're loaded automatically from the working directory.
|
||||
|
||||
### Hierarchical Discovery
|
||||
### Discovery
|
||||
|
||||
Hermes walks the directory tree and discovers **all** `AGENTS.md` files at every level. In a monorepo, put project-wide conventions at the root and team-specific ones in subdirectories — they're all concatenated together with path headers.
|
||||
Hermes loads the top-level `AGENTS.md` from the current working directory at session start. Subdirectory `AGENTS.md` files are discovered lazily during tool calls (via `subdirectory_hints.py`) and injected into tool results — they are not loaded upfront into the system prompt.
|
||||
|
||||
:::tip
|
||||
Keep context files focused and concise. Every character counts against your token budget since they're injected into every single message.
|
||||
|
||||
@@ -31,7 +31,8 @@ You need at least one way to connect to an LLM. Use `hermes model` to switch pro
|
||||
| **OpenCode Go** | `OPENCODE_GO_API_KEY` in `~/.hermes/.env` (provider: `opencode-go`) |
|
||||
| **DeepSeek** | `DEEPSEEK_API_KEY` in `~/.hermes/.env` (provider: `deepseek`) |
|
||||
| **Hugging Face** | `HF_TOKEN` in `~/.hermes/.env` (provider: `huggingface`, aliases: `hf`) |
|
||||
| **Custom Endpoint** | `hermes model` (saved in `config.yaml`) or `OPENAI_BASE_URL` + `OPENAI_API_KEY` in `~/.hermes/.env` |
|
||||
| **Google / Gemini** | `GOOGLE_API_KEY` (or `GEMINI_API_KEY`) in `~/.hermes/.env` (provider: `gemini`) |
|
||||
| **Custom Endpoint** | `hermes model` → choose "Custom endpoint" (saved in `config.yaml`) |
|
||||
|
||||
:::tip Model key alias
|
||||
In the `model:` config section, you can use either `default:` or `model:` as the key name for your model ID. Both `model: { default: my-model }` and `model: { model: my-model }` work identically.
|
||||
@@ -219,7 +220,7 @@ model:
|
||||
```
|
||||
|
||||
:::warning Legacy env vars
|
||||
`OPENAI_BASE_URL` and `LLM_MODEL` in `.env` are **deprecated**. The CLI ignores `LLM_MODEL` entirely (only the gateway reads it). Use `hermes model` or edit `config.yaml` directly — both persist correctly across restarts and Docker containers.
|
||||
`OPENAI_BASE_URL` and `LLM_MODEL` in `.env` are **deprecated**. `OPENAI_BASE_URL` is no longer consulted for endpoint resolution — `config.yaml` is the single source of truth. The CLI ignores `LLM_MODEL` entirely (only the gateway reads it as a fallback). Use `hermes model` or edit `config.yaml` directly — both persist correctly across restarts and Docker containers.
|
||||
:::
|
||||
|
||||
Both approaches persist to `config.yaml`, which is the source of truth for model, provider, and base URL.
|
||||
|
||||
@@ -39,6 +39,9 @@ All variables go in `~/.hermes/.env`. You can also set them with `hermes config
|
||||
| `KILOCODE_BASE_URL` | Override Kilo Code base URL (default: `https://api.kilo.ai/api/gateway`) |
|
||||
| `HF_TOKEN` | Hugging Face token for Inference Providers ([huggingface.co/settings/tokens](https://huggingface.co/settings/tokens)) |
|
||||
| `HF_BASE_URL` | Override Hugging Face base URL (default: `https://router.huggingface.co/v1`) |
|
||||
| `GOOGLE_API_KEY` | Google AI Studio API key ([aistudio.google.com/app/apikey](https://aistudio.google.com/app/apikey)) |
|
||||
| `GEMINI_API_KEY` | Alias for `GOOGLE_API_KEY` |
|
||||
| `GEMINI_BASE_URL` | Override Google AI Studio base URL |
|
||||
| `ANTHROPIC_API_KEY` | Anthropic Console API key ([console.anthropic.com](https://console.anthropic.com/)) |
|
||||
| `ANTHROPIC_TOKEN` | Manual or legacy Anthropic OAuth/setup-token override |
|
||||
| `DASHSCOPE_API_KEY` | Alibaba Cloud DashScope API key for Qwen models ([modelstudio.console.alibabacloud.com](https://modelstudio.console.alibabacloud.com/)) |
|
||||
@@ -108,7 +111,7 @@ For native Anthropic auth, Hermes prefers Claude Code's own credential files whe
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `TERMINAL_ENV` | Backend: `local`, `docker`, `ssh`, `singularity`, `modal`, `daytona` |
|
||||
| `TERMINAL_DOCKER_IMAGE` | Docker image (default: `python:3.11`) |
|
||||
| `TERMINAL_DOCKER_IMAGE` | Docker image (default: `nikolaik/python-nodejs:python3.11-nodejs20`) |
|
||||
| `TERMINAL_DOCKER_FORWARD_ENV` | JSON array of env var names to explicitly forward into Docker terminal sessions. Note: skill-declared `required_environment_variables` are forwarded automatically — you only need this for vars not declared by any skill. |
|
||||
| `TERMINAL_DOCKER_VOLUMES` | Additional Docker volume mounts (comma-separated `host:container` pairs) |
|
||||
| `TERMINAL_DOCKER_MOUNT_CWD_TO_WORKSPACE` | Advanced opt-in: mount the launch cwd into Docker `/workspace` (`true`/`false`, default: `false`) |
|
||||
@@ -262,7 +265,7 @@ For cloud sandbox backends, persistence is filesystem-oriented. `TERMINAL_LIFETI
|
||||
| `HERMES_HUMAN_DELAY_MIN_MS` | Custom delay range minimum (ms) |
|
||||
| `HERMES_HUMAN_DELAY_MAX_MS` | Custom delay range maximum (ms) |
|
||||
| `HERMES_QUIET` | Suppress non-essential output (`true`/`false`) |
|
||||
| `HERMES_API_TIMEOUT` | LLM API call timeout in seconds (default: `900`) |
|
||||
| `HERMES_API_TIMEOUT` | LLM API call timeout in seconds (default: `1800`) |
|
||||
| `HERMES_EXEC_ASK` | Enable execution approval prompts in gateway mode (`true`/`false`) |
|
||||
| `HERMES_ENABLE_PROJECT_PLUGINS` | Enable auto-discovery of repo-local plugins from `./.hermes/plugins/` (`true`/`false`, default: `false`) |
|
||||
| `HERMES_BACKGROUND_NOTIFICATIONS` | Background process notification mode in gateway: `all` (default), `result`, `error`, `off` |
|
||||
@@ -283,7 +286,7 @@ Context compression is configured exclusively through the `compression` section
|
||||
compression:
|
||||
enabled: true
|
||||
threshold: 0.50
|
||||
summary_model: google/gemini-3-flash-preview
|
||||
summary_model: "" # empty = use main configured model
|
||||
summary_provider: auto
|
||||
summary_base_url: null # Custom OpenAI-compatible endpoint for summaries
|
||||
```
|
||||
|
||||
@@ -37,6 +37,7 @@ Type `/` in the CLI to open the autocomplete menu. Built-in commands are case-in
|
||||
| `/background <prompt>` (alias: `/bg`) | Run a prompt in a separate background session. The agent processes your prompt independently — your current session stays free for other work. Results appear as a panel when the task finishes. See [CLI Background Sessions](/docs/user-guide/cli#background-sessions). |
|
||||
| `/btw <question>` | Ephemeral side question using session context (no tools, not persisted). Useful for quick clarifications without affecting the conversation history. |
|
||||
| `/plan [request]` | Load the bundled `plan` skill to write a markdown plan instead of executing the work. Plans are saved under `.hermes/plans/` relative to the active workspace/backend working directory. |
|
||||
| `/branch [name]` (alias: `/fork`) | Branch the current session (explore a different path) |
|
||||
|
||||
### Configuration
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ description: "Authoritative reference for Hermes built-in tools, grouped by tool
|
||||
|
||||
# Built-in Tools Reference
|
||||
|
||||
This page documents all 47 built-in tools in the Hermes tool registry, grouped by toolset. Availability varies by platform, credentials, and enabled toolsets.
|
||||
This page documents all 48 built-in tools in the Hermes tool registry, grouped by toolset. Availability varies by platform, credentials, and enabled toolsets.
|
||||
|
||||
**Quick counts:** 11 browser tools, 4 file tools, 10 RL tools, 4 Home Assistant tools, 2 terminal tools, 2 web tools, and 14 standalone tools across other toolsets.
|
||||
**Quick counts:** 11 browser tools, 4 file tools, 10 RL tools, 4 Home Assistant tools, 2 terminal tools, 2 web tools, and 15 standalone tools across other toolsets.
|
||||
|
||||
:::tip MCP Tools
|
||||
In addition to built-in tools, Hermes can load tools dynamically from MCP servers. MCP tools appear with a server-name prefix (e.g., `github_create_issue` for the `github` MCP server). See [MCP Integration](/docs/user-guide/features/mcp) for configuration.
|
||||
|
||||
@@ -88,9 +88,9 @@ Platform toolsets define the complete tool configuration for a deployment target
|
||||
|
||||
| Toolset | Differences from `hermes-cli` |
|
||||
|---------|-------------------------------|
|
||||
| `hermes-cli` | Full toolset — all 39 tools including `clarify`. The default for interactive CLI sessions. |
|
||||
| `hermes-cli` | Full toolset — all 38 tools including `clarify`. The default for interactive CLI sessions. |
|
||||
| `hermes-acp` | Drops `clarify`, `cronjob`, `image_generate`, `mixture_of_agents`, `send_message`, `text_to_speech`, homeassistant tools. Focused on coding tasks in IDE context. |
|
||||
| `hermes-api-server` | Drops `clarify` and `send_message`. Adds everything else — suitable for programmatic access where user interaction isn't possible. |
|
||||
| `hermes-api-server` | Drops `clarify`, `send_message`, and `text_to_speech`. Adds everything else — suitable for programmatic access where user interaction isn't possible. |
|
||||
| `hermes-telegram` | Same as `hermes-cli`. |
|
||||
| `hermes-discord` | Same as `hermes-cli`. |
|
||||
| `hermes-slack` | Same as `hermes-cli`. |
|
||||
|
||||
@@ -574,7 +574,7 @@ auxiliary:
|
||||
model: "" # e.g. "google/gemini-2.5-flash"
|
||||
base_url: ""
|
||||
api_key: ""
|
||||
timeout: 30 # seconds
|
||||
timeout: 360 # seconds (6min) — per-attempt LLM summarization
|
||||
|
||||
# Dangerous command approval classifier
|
||||
approval:
|
||||
@@ -622,7 +622,7 @@ auxiliary:
|
||||
```
|
||||
|
||||
:::tip
|
||||
Each auxiliary task has a configurable `timeout` (in seconds). Defaults: vision 30s, web_extract 30s, approval 30s, compression 120s. Increase these if you use slow local models for auxiliary tasks. Vision also has a separate `download_timeout` (default 30s) for the HTTP image download — increase this for slow connections or self-hosted image servers.
|
||||
Each auxiliary task has a configurable `timeout` (in seconds). Defaults: vision 30s, web_extract 360s, approval 30s, compression 120s. Increase these if you use slow local models for auxiliary tasks. Vision also has a separate `download_timeout` (default 30s) for the HTTP image download — increase this for slow connections or self-hosted image servers.
|
||||
:::
|
||||
|
||||
:::info
|
||||
@@ -804,30 +804,16 @@ display:
|
||||
tool_progress: all # off | new | all | verbose
|
||||
tool_progress_command: false # Enable /verbose slash command in messaging gateway
|
||||
skin: default # Built-in or custom CLI skin (see user-guide/features/skins)
|
||||
theme_mode: auto # auto | light | dark — color scheme for skin-aware rendering
|
||||
personality: "kawaii" # Legacy cosmetic field still surfaced in some summaries
|
||||
compact: false # Compact output mode (less whitespace)
|
||||
resume_display: full # full (show previous messages on resume) | minimal (one-liner only)
|
||||
bell_on_complete: false # Play terminal bell when agent finishes (great for long tasks)
|
||||
show_reasoning: false # Show model reasoning/thinking above each response (toggle with /reasoning show|hide)
|
||||
streaming: false # Stream tokens to terminal as they arrive (real-time output)
|
||||
background_process_notifications: all # all | result | error | off (gateway only)
|
||||
show_cost: false # Show estimated $ cost in the CLI status bar
|
||||
tool_preview_length: 0 # Max chars for tool call previews (0 = no limit, show full paths/commands)
|
||||
```
|
||||
|
||||
### Theme mode
|
||||
|
||||
The `theme_mode` setting controls whether skins render in light or dark mode:
|
||||
|
||||
| Mode | Behavior |
|
||||
|------|----------|
|
||||
| `auto` (default) | Detects your terminal's background color automatically. Falls back to `dark` if detection fails. |
|
||||
| `light` | Forces light-mode skin colors. Skins that define a `colors_light` override use those colors instead of the default dark-mode palette. |
|
||||
| `dark` | Forces dark-mode skin colors. |
|
||||
|
||||
This works with any skin — built-in or custom. Skin authors can provide `colors_light` in their skin definition for optimal light-terminal appearance.
|
||||
|
||||
| Mode | What you see |
|
||||
|------|-------------|
|
||||
| `off` | Silent — just the final response |
|
||||
|
||||
@@ -20,7 +20,7 @@ python batch_runner.py \
|
||||
--dataset_file=data/prompts.jsonl \
|
||||
--batch_size=10 \
|
||||
--run_name=my_first_run \
|
||||
--model=anthropic/claude-sonnet-4-20250514 \
|
||||
--model=anthropic/claude-sonnet-4.6 \
|
||||
--num_workers=4
|
||||
|
||||
# Resume an interrupted run
|
||||
@@ -56,7 +56,7 @@ Entries can optionally include:
|
||||
| `--batch_size` | (required) | Prompts per batch |
|
||||
| `--run_name` | (required) | Name for this run (used for output dir and checkpointing) |
|
||||
| `--distribution` | `"default"` | Toolset distribution to sample from |
|
||||
| `--model` | `claude-sonnet-4-20250514` | Model to use |
|
||||
| `--model` | `claude-sonnet-4.6` | Model to use |
|
||||
| `--base_url` | `https://openrouter.ai/api/v1` | API base URL |
|
||||
| `--api_key` | (env var) | API key for model |
|
||||
| `--max_turns` | `10` | Maximum tool-calling iterations per prompt |
|
||||
@@ -127,7 +127,7 @@ Each line in `trajectories.jsonl` is a JSON object:
|
||||
"metadata": {
|
||||
"batch_num": 2,
|
||||
"timestamp": "2026-01-15T10:30:00",
|
||||
"model": "anthropic/claude-sonnet-4-20250514"
|
||||
"model": "anthropic/claude-sonnet-4.6"
|
||||
},
|
||||
"completed": true,
|
||||
"partial": false,
|
||||
@@ -193,7 +193,7 @@ python batch_runner.py \
|
||||
--dataset_file=data/coding_prompts.jsonl \
|
||||
--batch_size=20 \
|
||||
--run_name=coding_v1 \
|
||||
--model=anthropic/claude-sonnet-4-20250514 \
|
||||
--model=anthropic/claude-sonnet-4.6 \
|
||||
--num_workers=8 \
|
||||
--distribution=default \
|
||||
--max_turns=15
|
||||
|
||||
@@ -174,8 +174,8 @@ BROWSERBASE_KEEP_ALIVE=true
|
||||
# Examples: 600000 (10min), 1800000 (30min)
|
||||
BROWSERBASE_SESSION_TIMEOUT=600000
|
||||
|
||||
# Inactivity timeout before auto-cleanup in seconds (default: 300)
|
||||
BROWSER_INACTIVITY_TIMEOUT=300
|
||||
# Inactivity timeout before auto-cleanup in seconds (default: 120)
|
||||
BROWSER_INACTIVITY_TIMEOUT=120
|
||||
```
|
||||
|
||||
### Install agent-browser CLI
|
||||
@@ -265,7 +265,7 @@ The screenshot is saved persistently and the file path is returned alongside the
|
||||
What does the chart on this page show?
|
||||
```
|
||||
|
||||
Screenshots are stored in `~/.hermes/browser_screenshots/` and automatically cleaned up after 24 hours.
|
||||
Screenshots are stored in `~/.hermes/cache/screenshots/` and automatically cleaned up after 24 hours.
|
||||
|
||||
### `browser_console`
|
||||
|
||||
@@ -333,7 +333,7 @@ If paid features aren't available on your plan, Hermes automatically falls back
|
||||
## Session Management
|
||||
|
||||
- Each task gets an isolated browser session via Browserbase
|
||||
- Sessions are automatically cleaned up after inactivity (default: 5 minutes)
|
||||
- Sessions are automatically cleaned up after inactivity (default: 2 minutes)
|
||||
- A background thread checks every 30 seconds for stale sessions
|
||||
- Emergency cleanup runs on process exit to prevent orphaned sessions
|
||||
- Sessions are released via the Browserbase API (`REQUEST_RELEASE` status)
|
||||
|
||||
@@ -215,9 +215,6 @@ Pool state is stored in `~/.hermes/auth.json` under the `credential_pool` key:
|
||||
}
|
||||
]
|
||||
},
|
||||
"credential_pool_strategies": {
|
||||
"openrouter": "round_robin"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -395,7 +395,7 @@ stt:
|
||||
|
||||
# Text-to-Speech
|
||||
tts:
|
||||
provider: "edge" # "edge" (free) | "elevenlabs" | "openai" | "neutts"
|
||||
provider: "edge" # "edge" (free) | "elevenlabs" | "openai" | "neutts" | "minimax"
|
||||
edge:
|
||||
voice: "en-US-AriaNeural" # 322 voices, 74 languages
|
||||
elevenlabs:
|
||||
|
||||
@@ -130,22 +130,25 @@ The Home Assistant gateway adapter connects via WebSocket and subscribes to `sta
|
||||
By default, **no events are forwarded**. You must configure at least one of `watch_domains`, `watch_entities`, or `watch_all` to receive events. Without filters, a warning is logged at startup and all state changes are silently dropped.
|
||||
:::
|
||||
|
||||
Configure which events the agent sees in `~/.hermes/gateway.json` under the Home Assistant platform's `extra` section:
|
||||
Configure which events the agent sees in `~/.hermes/config.yaml` under the Home Assistant platform's `extra` section:
|
||||
|
||||
```json
|
||||
{
|
||||
"platforms": {
|
||||
"homeassistant": {
|
||||
"enabled": true,
|
||||
"extra": {
|
||||
"watch_domains": ["climate", "binary_sensor", "alarm_control_panel", "light"],
|
||||
"watch_entities": ["sensor.front_door_battery"],
|
||||
"ignore_entities": ["sensor.uptime", "sensor.cpu_usage", "sensor.memory_usage"],
|
||||
"cooldown_seconds": 30
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```yaml
|
||||
platforms:
|
||||
homeassistant:
|
||||
enabled: true
|
||||
extra:
|
||||
watch_domains:
|
||||
- climate
|
||||
- binary_sensor
|
||||
- alarm_control_panel
|
||||
- light
|
||||
watch_entities:
|
||||
- sensor.front_door_battery
|
||||
ignore_entities:
|
||||
- sensor.uptime
|
||||
- sensor.cpu_usage
|
||||
- sensor.memory_usage
|
||||
cooldown_seconds: 30
|
||||
```
|
||||
|
||||
| Setting | Default | Description |
|
||||
|
||||
@@ -265,13 +265,13 @@ MATRIX_ENCRYPTION=true
|
||||
|
||||
When E2EE is enabled, Hermes:
|
||||
|
||||
- Stores encryption keys in `~/.hermes/matrix/store/`
|
||||
- Stores encryption keys in `~/.hermes/platforms/matrix/store/` (legacy installs: `~/.hermes/matrix/store/`)
|
||||
- Uploads device keys on first connection
|
||||
- Decrypts incoming messages and encrypts outgoing messages automatically
|
||||
- Auto-joins encrypted rooms when invited
|
||||
|
||||
:::warning
|
||||
If you delete the `~/.hermes/matrix/store/` directory, the bot loses its encryption keys. You'll need to verify the device again in your Matrix client. Back up this directory if you want to preserve encrypted sessions.
|
||||
If you delete the `~/.hermes/platforms/matrix/store/` directory, the bot loses its encryption keys. You'll need to verify the device again in your Matrix client. Back up this directory if you want to preserve encrypted sessions.
|
||||
:::
|
||||
|
||||
:::info
|
||||
|
||||
@@ -384,7 +384,7 @@ platforms:
|
||||
In addition to tokens in the environment or config, Hermes also loads tokens from an **OAuth token file** at:
|
||||
|
||||
```
|
||||
~/.hermes/platforms/slack/slack_tokens.json
|
||||
~/.hermes/slack_tokens.json
|
||||
```
|
||||
|
||||
This file is a JSON object mapping team IDs to token entries:
|
||||
|
||||
@@ -50,7 +50,7 @@ WECOM_HOME_CHANNEL=chat_id
|
||||
### 3. Start the gateway
|
||||
|
||||
```bash
|
||||
hermes gateway start
|
||||
hermes gateway
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
@@ -134,7 +134,7 @@ The gateway starts the WhatsApp bridge automatically using the saved session.
|
||||
|
||||
## Session Persistence
|
||||
|
||||
The Baileys bridge saves its session under `~/.hermes/whatsapp/session`. This means:
|
||||
The Baileys bridge saves its session under `~/.hermes/platforms/whatsapp/session`. This means:
|
||||
|
||||
- **Sessions survive restarts** — you don't need to re-scan the QR code every time
|
||||
- The session data includes encryption keys and device credentials
|
||||
@@ -180,7 +180,7 @@ whatsapp:
|
||||
|---------|----------|
|
||||
| **QR code not scanning** | Ensure terminal is wide enough (60+ columns). Try a different terminal. Make sure you're scanning from the correct WhatsApp account (bot number, not personal). |
|
||||
| **QR code expires** | QR codes refresh every ~20 seconds. If it times out, restart `hermes whatsapp`. |
|
||||
| **Session not persisting** | Check that `~/.hermes/whatsapp/session` exists and is writable. If containerized, mount it as a persistent volume. |
|
||||
| **Session not persisting** | Check that `~/.hermes/platforms/whatsapp/session` exists and is writable. If containerized, mount it as a persistent volume. |
|
||||
| **Logged out unexpectedly** | WhatsApp unlinks devices after long inactivity. Keep the phone on and connected to the network, then re-pair with `hermes whatsapp` if needed. |
|
||||
| **Bridge crashes or reconnect loops** | Restart the gateway, update Hermes, and re-pair if the session was invalidated by a WhatsApp protocol change. |
|
||||
| **Bot stops working after WhatsApp update** | Update Hermes to get the latest bridge version, then re-pair. |
|
||||
@@ -206,8 +206,8 @@ whatsapp:
|
||||
unauthorized_dm_behavior: ignore
|
||||
```
|
||||
|
||||
- The `~/.hermes/whatsapp/session` directory contains full session credentials — protect it like a password
|
||||
- Set file permissions: `chmod 700 ~/.hermes/whatsapp/session`
|
||||
- The `~/.hermes/platforms/whatsapp/session` directory contains full session credentials — protect it like a password
|
||||
- Set file permissions: `chmod 700 ~/.hermes/platforms/whatsapp/session`
|
||||
- Use a **dedicated phone number** for the bot to isolate risk from your personal account
|
||||
- If you suspect compromise, unlink the device from WhatsApp → Settings → Linked Devices
|
||||
- Phone numbers in logs are partially redacted, but review your log retention policy
|
||||
|
||||
@@ -277,6 +277,9 @@ Every container runs with these flags (defined in `tools/environments/docker.py`
|
||||
```python
|
||||
_SECURITY_ARGS = [
|
||||
"--cap-drop", "ALL", # Drop ALL Linux capabilities
|
||||
"--cap-add", "DAC_OVERRIDE", # Root can write to bind-mounted dirs
|
||||
"--cap-add", "CHOWN", # Package managers need file ownership
|
||||
"--cap-add", "FOWNER", # Package managers need file ownership
|
||||
"--security-opt", "no-new-privileges", # Block privilege escalation
|
||||
"--pids-limit", "256", # Limit process count
|
||||
"--tmpfs", "/tmp:rw,nosuid,size=512m", # Size-limited /tmp
|
||||
|
||||
Reference in New Issue
Block a user