# Hermina Hermina is a self-hosted control plane for creating, configuring, and operating multiple AI agents powered by [Hermes Agent](https://hermes-agent.nousresearch.com). Each agent has its own identity, model, memory, tools, schedules, and messaging channels. > **Fastest path:** install Hermina, run `hermina onboard`, connect the Web, Desktop, or Android app, and create your first agent. Start with one agent and one channel; add automation after a normal conversation works. ## Install Hermina currently targets Debian or Ubuntu servers with `systemd`. Run the installer as root: ```bash curl -fsSL https://raw.githubusercontent.com/moonixt/hermina/master/install.sh | sudo bash ``` The installer prepares Docker, Hermes Agent, the Hermina CLI, the management API, the Web/Desktop build, and the base agent image. The default installation directory is `/opt/hermina`. After installation: ```bash hermina onboard ``` See [Installation](/hermina/docs/getting-started/installation/) for prerequisites and verification, or go directly to the [Quickstart](/hermina/docs/getting-started/quickstart/). ## What Hermina adds to Hermes Hermes Agent is the intelligence and tool runtime inside each agent. Hermina adds the operational layer around it: - **Multi-agent management** — run independent agents instead of one global profile. - **Isolated profiles** — each agent owns its `config.yaml`, `.env`, `SOUL.md`, sessions, skills, and schedules. - **Multiple interfaces** — operate the same server from Web, Electron, Android, CLI, or TUI. - **Messaging channels** — connect WhatsApp, Telegram, Matrix, and other Hermes-compatible channels. - **Remote control API** — manage agents from authenticated clients without SSH. - **Automation** — queue work, schedule Hermes cron jobs, and review results in Inbox and Feed. ## Choose your path | Goal | Start here | Then read | |---|---|---| | Install a new server | [Installation](/hermina/docs/getting-started/installation/) | [Quickstart](/hermina/docs/getting-started/quickstart/) | | Use an existing server | [Connect your apps](/hermina/docs/user-guide/connect-apps/) | [Manage agents](/hermina/docs/user-guide/agents/) | | Configure agent behavior | [Providers and models](/hermina/docs/configuration/providers/) | [Personas and behavior](/hermina/docs/configuration/personas/) | | Put an agent on WhatsApp | [Channels and messaging](/hermina/docs/user-guide/channels/) | [Access and permissions](/hermina/docs/configuration/access/) | | Schedule recurring work | [Tasks and schedules](/hermina/docs/automation/tasks-and-schedules/) | [Troubleshooting](/hermina/docs/reference/troubleshooting/) | ## How the pieces fit A Hermina server has three layers: 1. **Clients** — the Web dashboard, Electron app, Android app, browser extension, CLI, and TUI. 2. **Control plane** — an authenticated HTTP API that applies configuration, streams chat, and controls runtimes. 3. **Agents** — Hermes profiles running in isolated Docker containers or, for advanced deployments, as `angel` services on the host. Remote clients should use the `/api/*` contract. The CLI and TUI run locally and can access Docker, `systemd`, and the agent files directly. ## Recommended learning path For a first installation, follow this order: 1. Install and verify the server. 2. Connect one management client. 3. Create one agent and confirm its model responds. 4. Add a persona and one messaging channel. 5. Restrict access and slash commands. 6. Add schedules or queued tasks only after the base setup is stable. ## Documentation for agents The source of this site is plain Markdown. Machine-readable indexes are also available at [`/hermina/docs/llms.txt`](/hermina/docs/llms.txt) and [`/hermina/docs/llms-full.txt`](/hermina/docs/llms-full.txt). --- # Installation Install the complete Hermina stack on a Debian or Ubuntu server. The standard installer is designed for a root-managed machine with Docker and `systemd`. ## Before you begin You need: - A Debian or Ubuntu host with `apt-get` and `systemd`. - Root or `sudo` access. - Internet access to GitHub, Docker, Node.js, Python packages, and your chosen model provider. - Enough resources for the control plane and at least one agent. A practical starting point is 2 CPU cores, 4 GB RAM, and 20 GB free disk. - A trusted way to reach the server: local network, Tailscale, or an HTTPS reverse proxy. Each default container is limited to 1 CPU and 1 GB RAM. Plan additional capacity for each concurrently active agent. ## One-command installation ```bash curl -fsSL https://raw.githubusercontent.com/moonixt/hermina/master/install.sh | sudo bash ``` The installer performs nine stages: 1. Installs system prerequisites. 2. Installs or verifies Docker. 3. Installs Hermes Agent. 4. Clones Hermina into `/opt/hermina` by default. 5. Creates a Python environment and installs the `hermina` command. 6. Builds the Web/Desktop application. 7. Builds the base agent image. 8. Generates an API key and starts the management service. 9. Verifies the CLI, API, build output, and Docker image. > The installer downloads and executes third-party installation scripts for Docker and Hermes Agent. Review `install.sh` first when your environment requires a controlled software supply chain. ## Verify the installation Run these checks in order: ```bash hermina --help hermina angels status hermina status curl -fsS http://127.0.0.1:3456/health ``` A healthy local API returns a JSON response with `"status": "ok"`. The installer also creates at least one management key in: ```text /opt/hermina/api-keys.txt ``` Treat that file as a secret. ## Run guided onboarding ```bash hermina onboard ``` The wizard checks the environment, starts or configures the backend, helps with remote access, selects a provider and model, creates an optional first agent, configures channels, and prints client connection instructions. If you prefer a minimal setup, skip the optional agent and channel steps. You can add them later from the dashboard or CLI. ## Custom installation paths The installer supports environment overrides. The most common is `HERMINA_HOME`: ```bash curl -fsSL https://raw.githubusercontent.com/moonixt/hermina/master/install.sh \ | sudo HERMINA_HOME=/srv/hermina bash ``` The CLI uses `HERMINA_HOME` to find agents and project files. Keep the same value in service units and administrative shells if you change the default. Advanced installer switches include `HERMINA_SKIP_DOCKER`, `HERMINA_SKIP_HERMES`, `HERMINA_SKIP_DESKTOP`, `HERMINA_SKIP_AGENT_IMAGE`, and `HERMINA_SKIP_SERVICES`. Use them only when the skipped component is already managed by your infrastructure. ## Network access By default, the API listens on port `3456`. Do not expose that port directly to the public internet. Use one of these patterns: | Pattern | Best for | Notes | |---|---|---| | Loopback only | Single-machine Desktop/Electron use | Lowest exposure | | Tailscale or private VPN | Personal and small-team remote use | Recommended for most self-hosted setups | | HTTPS reverse proxy + firewall | Publicly reachable server | Preserve `Authorization` and WebSocket upgrade headers | Continue with [Quickstart](/hermina/docs/getting-started/quickstart/) to connect a client and create an agent. ## Updating an installation The installer can update an existing Git checkout only when it can fast-forward the configured branch. Back up persistent data before updating: - `agents/` - `profile/`, `groups/`, `workspace/`, and `settings/` - `personas/custom/` - `api-keys.txt` - Custom reverse-proxy and service configuration Docker images and application builds can be recreated from source; agent profiles and databases cannot. --- # Quickstart This tutorial gets one agent responding in the Hermina dashboard and, optionally, on WhatsApp. It assumes the server is already installed. ## 1. Confirm the server is healthy ```bash hermina angels status hermina status ``` If the API is not running, inspect it before creating agents: ```bash hermina angels logs --lines 100 ``` ## 2. Connect a management app If the dashboard will be available on a public domain, configure TOTP first: ```bash hermina mfa ``` The public login will require the passphrase plus the authenticator code. Generate a single-use pairing code: ```bash hermina connect --code ``` Open the Web, Desktop, or Android login screen, enter the server URL shown by the CLI, then enter the six-character code. For a QR that contains the server URL and a full API key: ```bash hermina connect --qr ``` > A connection QR contains administrative credentials for the whole instance. Display it privately and rotate the key if the QR is shared or captured. See [Connect your apps](/hermina/docs/user-guide/connect-apps/) for manual login and remote-access details. ## 3. Create your first agent Choose a short lowercase name and the agent's phone number in international format, without `+`, spaces, or punctuation: ```bash hermina add support 5511999999999 --lang=en --start=true ``` The default runtime is a Docker container and the default provider preset is `opencode-go`. To create an agent with a persona immediately: ```bash hermina add support 5511999999999 \ --persona=retail/ecommerce-support \ --lang=en \ --start=true ``` List agents and confirm the new runtime is present: ```bash hermina list ``` ## 4. Configure a provider and model View the active model: ```bash hermina model support ``` Configure a provider with an API key: ```bash hermina model support \ --provider=openai \ --model=gpt-4o-mini \ --api-key=YOUR_API_KEY ``` The key is stored in the agent's `.env`; non-secret model settings go to `config.yaml`. If the agent is running, the command applies the change by restarting it. You can also configure the model from the agent detail screen. See [Providers and models](/hermina/docs/configuration/providers/) for presets, local endpoints, and reasoning levels. ## 5. Send a dashboard message In the Web/Desktop app: 1. Open **Agents**. 2. Select `support`. 3. Open **Chat**. 4. Send a simple, verifiable prompt such as: `Reply with your name and one sentence about your role.` Success means the reply streams normally, the selected model is shown, and the session remains available after navigating away and returning. Test dashboard chat before connecting a messaging channel. This separates model problems from channel problems. ## 6. Pair WhatsApp If the agent uses the standard WhatsApp transport: ```bash hermina qr support hermina logs support --follow ``` On the **agent's WhatsApp account**, open **Linked devices**, choose **Link a device**, and scan the QR displayed in the logs. Then check: ```bash hermina bridge support hermina list ``` The bridge should report connected and the agent should appear paired. WhatsApp Cloud does not use QR pairing; it requires Meta credentials and a webhook instead. ## 7. Lock down access Before inviting users, set an allowlist and command administrators: ```bash hermina allowlist support --numbers=5511888888888,5511777777777 hermina commands support --allow-admin=5511888888888 hermina commands support --user-commands=help,whoami,status ``` In WhatsApp, send `/whoami` and prefer the exact returned user ID for admin configuration. Some WhatsApp sessions identify users with an `@lid` value instead of a phone number. ## What to do next - Learn the full [agent lifecycle](/hermina/docs/user-guide/agents/). - Add or change [channels](/hermina/docs/user-guide/channels/). - Shape behavior with [personas and SOUL.md](/hermina/docs/configuration/personas/). - Add [tasks and schedules](/hermina/docs/automation/tasks-and-schedules/) only after normal chat is reliable. --- # Choose an interface Every Hermina interface controls the same server, but each is optimized for a different job. Start with Web/Desktop for daily work and keep the CLI available for installation and recovery. ## Interface matrix | Interface | Best for | Runs where | Important differences | |---|---|---|---| | Web dashboard | Daily administration and chat | Browser | Full workspace; requires server URL and API key | | Electron desktop | Daily use on Linux desktop | Local app | Adds native notifications, tray, overlay, media controls, and updates | | Android app | Monitoring and administration away from a computer | Android 8+ | Supports QR/code login, background status checks, and most agent settings | | CLI | Installation, recovery, scripts, and precise local changes | Hermina server | Direct access to files, Docker, and `systemd`; does not use the HTTP API | | TUI | Keyboard-driven local administration | Hermina server | Wraps common CLI operations in an interactive terminal UI | | Browser extension | Page-aware chat and browser workflows | Chromium browser | Uses broad browser permissions; connect only to a trusted server | ## Web and Electron The Web dashboard and Electron app share the same Next.js interface. Use them for: - Agent lifecycle and status. - Streaming chat and session history. - Model, media, tools, channel, permission, and schedule settings. - Workspace files and returned attachments. - Groups, Messenger, Secretary, Feed, Inbox, and saved messages. - Interactive shell access when administrative terminal work is required. Electron adds native capabilities that a browser page cannot provide: system tray, global overlay, desktop notifications, media integration, window controls, and packaged updates. Run the local launcher: ```bash hermina desktop ``` On a graphical machine it opens the newest packaged Electron app when available, otherwise it falls back to Electron source or the Web URL. On a headless server it prints connection details instead. ## Android The Android app is an administrative client; it does not run Hermes or Docker on the phone. It connects to the management API and can operate agents, chat, view logs, configure channels, manage schedules and queues, browse workspace files, and use Messenger features. Use Android when you need: - A compact remote status view. - Native notifications when an agent or bridge goes down. - Quick QR or pairing-code setup. - Chat and common administrative actions without opening a laptop. For a server reached over the public internet, use HTTPS. Plain HTTP is intended only for trusted LAN or VPN environments. ## CLI and TUI Run the TUI with either command: ```bash hermina hermina tui ``` Use the CLI when a dashboard is unavailable, when diagnosing the host, or when you need a command that maps directly to Docker, `systemd`, or an agent profile. > Avoid changing the same agent from the CLI and a remote client at the same time. Configuration spans YAML, dotenv files, runtime state, and SQLite databases; there is no distributed transaction across those stores. ## Browser extension The extension adds the current browser page as context and exposes a lightweight chat surface. It is useful for research and page-specific tasks, but it is not the main lifecycle or configuration interface. Because it needs tab, scripting, and broad host permissions, install it only from a trusted build and rotate the server key if the browser profile is compromised. ## A practical default For most installations: 1. Use the CLI to install and recover the server. 2. Use Web or Electron for normal operations. 3. Add Android for monitoring and quick interventions. 4. Add the browser extension only when page context is part of the workflow. --- # Manage agents An agent is an independent Hermes profile with its own identity, provider, tools, data, channels, and runtime. Most daily operations are available from the Agents workspace and the CLI. ## Agent lifecycle The normal lifecycle is: 1. **Create** the profile and runtime definition. 2. **Configure** model, persona, channels, and permissions. 3. **Start** the container or service. 4. **Pair** channels that require interactive authentication. 5. **Operate** through chat, schedules, queues, and tools. 6. **Stop, restart, or remove** the runtime when needed. The default runtime is a Docker container. Advanced `angel` agents run as `systemd` services on the host and should be treated as higher-trust workloads. ## Create an agent From the dashboard, open **Agents**, choose **New agent**, and work through the identity, model, persona, and channel steps. From the CLI: ```bash hermina add analyst 5511999999999 \ --display-name="Research Analyst" \ --lang=en \ --start=true ``` Then set the provider separately: ```bash hermina model analyst \ --provider=openrouter \ --model=openai/gpt-4o-mini \ --api-key=YOUR_API_KEY ``` Agent names should be lowercase and stable. The name becomes part of the profile directory, container name, service name, API routes, and saved references. ## Start, stop, and restart ```bash hermina start analyst hermina stop analyst hermina restart analyst ``` Use **restart** after manual file edits. Task-specific commands such as `hermina model`, `hermina media`, and `hermina commands` normally restart an active runtime when required. Inspect all agents: ```bash hermina list hermina status ``` The list distinguishes runtime state from channel state. A running container can still have a disconnected WhatsApp bridge or invalid model credentials. ## Chat and sessions Dashboard chat calls the Hermina control plane, which starts Hermes in the selected agent profile and streams events back as newline-delimited JSON. The UI displays tool steps and response text as they arrive. Sessions are persistent. Use the session sidebar to resume earlier work, create a clean session, or pin and save important messages. From the CLI, inspect or clear channel sessions: ```bash hermina sessions analyst hermina sessions analyst --json-output=true hermina sessions analyst --clear=true ``` Clearing sessions can remove channel state or conversation continuity. Review the displayed session list before destructive actions. ## Logs and health ```bash hermina logs analyst hermina logs analyst --follow hermina bridge analyst ``` Use logs to separate these failure classes: - Container or service failed to start. - Hermes configuration could not load. - Provider authentication or model request failed. - Channel adapter started but is not connected. - A tool or scheduled task failed after the agent was otherwise healthy. ## Shell access The dashboard shell and `hermina shell` are administrative capabilities: ```bash hermina shell analyst "pwd && ls -la" ``` For container agents, commands execute inside the agent runtime. For `angel` or root profiles, the effective access can reach the host. Do not grant shell access to untrusted operators or clients. ## Remove an agent ```bash hermina remove analyst ``` To remove the runtime while preserving its profile data: ```bash hermina remove analyst --keep-data=true ``` Back up the agent directory before permanent deletion. It contains identity, model settings, secrets, channel credentials, history, queue data, cron jobs, and skills. ## Data owned by an agent The important profile files are: | Path | Purpose | |---|---| | `agents//config.yaml` | Hermes settings, model, tools, gateways, and policies | | `agents//.env` | Provider and channel secrets | | `agents//SOUL.md` | Identity, tone, boundaries, and behavior | | `agents//whatsapp/session/` | WhatsApp device credentials | | `agents//queue.db` | Persistent queued tasks | | `agents//cron/` | Scheduled jobs and execution history | | `agents//skills/` | Skills available to this profile | See [Configuration overview](/hermina/docs/configuration/) before editing these files directly. --- # Connect your apps Web, Electron, Android, and the browser extension connect to a Hermina server with a base URL and an instance-wide API key. Pairing codes and QR codes make that setup easier. ## Before connecting Confirm the management API is healthy: ```bash hermina angels status curl -fsS http://127.0.0.1:3456/health ``` The client must be able to reach the same base URL. `127.0.0.1` works only on the server itself. For another device, use a private IP, Tailscale address, or HTTPS domain. Before opening a public HTTPS domain, enroll an authenticator over SSH: ```bash hermina mfa ``` Public web login then asks for the instance passphrase and the current TOTP code. Pairing-code and approval-QR login remain intended for private/direct connections. ## Pair with a short code ```bash hermina connect --code ``` The CLI prints: - The server URL. - A six-character one-time code. - The remaining validity period. On the client login screen, enter the URL and choose pairing-code login. The server exchanges the code for an API key and the client stores the connection. Pairing codes are held in server memory and expire. Generate a new code if the API restarts or the displayed code is rejected. ## Pair with a QR On the Web/Desktop login screen, choose **Approve in app**. The browser displays a QR that contains a short approval request, not an API key. In an Android app that is already connected to the same server, open the scanner, scan the QR, and approve the session. The browser connects automatically. Only the browser that created the QR can retrieve the approval result. ## Connect a new app directly with a QR ```bash hermina connect --qr ``` Scan the QR from the Android setup screen or a compatible client. The QR contains two lines: the server URL and an API key. > The app-connection QR is not the WhatsApp QR. The first authenticates a management client to Hermina; the second links a WhatsApp account to one agent. ## Enter the URL and key manually List the server's keys locally: ```bash hermina angels key ``` Then enter the base URL and one key on the client login screen. A client validates the connection by checking server health and loading the agent list. Do not append `/api` in the Web/Desktop or Android login screen unless that client explicitly asks for an API base. The standard clients add `/api` to protected routes themselves. ## Manage API keys Generate a key for a new device or operator: ```bash hermina angels key generate ``` Delete a lost or retired key by a unique prefix of at least eight characters: ```bash hermina angels key delete ``` Restart is not required after editing the key file through the CLI. Test every remaining client after rotation. Keys are instance-wide: they are not restricted to a user, agent, or role. Anyone holding a valid key can reach administrative endpoints, including configuration and shell capabilities. ## Multiple servers Web/Desktop and Android can save more than one server connection. Use clear connection names such as `Home`, `Production`, and `Lab`. Some multi-server views aggregate lists, but not every action is guaranteed to route across all servers in the same way. Avoid duplicate agent names across connected instances and verify the active server before performing destructive operations. ## Remote access patterns Use one of these approaches: ### Tailscale or private VPN This is the recommended default for personal and small-team installations. The Hermina CLI prefers a detected Tailscale IPv4 address when printing connection information. ### LAN Use the server's private address only on a trusted network. Android supports cleartext HTTP for LAN compatibility, but keys remain visible to anyone able to inspect that traffic. ### Public HTTPS Put Nginx or Caddy in front of the API, terminate TLS, restrict the origin with a firewall, preserve the `Authorization` header, and support WebSocket upgrades for the interactive shell. Enable `hermina mfa`, keep port `3456` closed publicly, and ensure the proxy sets `X-Forwarded-For`. The domain accepts short-lived MFA sessions instead of raw long-lived API keys. Never expose port `3456` directly to the public internet. ## Connection troubleshooting If login fails: 1. Open `/health` from the client device. 2. Confirm the URL has the correct scheme, host, port, and optional path. 3. Generate a new pairing code. 4. Verify the key still exists with `hermina angels key`. 5. Check `hermina angels logs --lines 100`. 6. Inspect reverse-proxy forwarding and CORS only after direct network reachability works. --- # Channels and messaging Each agent can receive messages through its own Hermes Gateway configuration. Hermina currently exposes guided flows for WhatsApp, Telegram, and Matrix, with room for other Hermes-supported platforms. ## Choose a channel | Channel | Setup style | Best for | Key consideration | |---|---|---|---| | WhatsApp (Baileys) | Linked-device QR | Fast personal or business-number setup | Session credentials must persist | | WhatsApp Cloud | Meta app credentials + webhook | Official API deployments | Requires a public HTTPS webhook | | Telegram | Bot token | Bots, groups, and simple deployment | Group mention policy matters | | Matrix | Homeserver, user, token, room policy | Self-hosted/open messaging | Treat the access token as a secret | Configure channels from the agent detail screen or during `hermina onboard`. Use the CLI commands below for common operations. ## WhatsApp linked device The default WhatsApp transport uses a linked device session. ```bash hermina start support hermina qr support hermina logs support --follow ``` On the WhatsApp account that will represent the agent: 1. Open **Settings** or the main menu. 2. Open **Linked devices**. 3. Choose **Link a device**. 4. Scan the terminal QR. Credentials are stored under `agents//whatsapp/session/`. Preserve that directory during updates and backups. Check the connection: ```bash hermina bridge support ``` If the QR has expired, restart the agent and follow the new QR from the logs. ## WhatsApp Cloud WhatsApp Cloud uses Meta credentials and a webhook instead of a device QR. Configure the transport and secrets through the dashboard or `hermina channel`: ```bash hermina channel support \ --transport=whatsapp-cloud \ --cloud-phone-number-id=PHONE_NUMBER_ID \ --cloud-access-token=ACCESS_TOKEN \ --cloud-app-secret=APP_SECRET \ --cloud-verify-token=VERIFY_TOKEN \ --cloud-waba-id=WABA_ID ``` The webhook must be reachable over HTTPS and routed to the published Cloud webhook port. If the port mapping changes after the container was created, recreate the runtime so Docker publishes the new port. ## Telegram Create a bot with BotFather, then add its token from the agent's **Channels** settings or guided onboarding. After saving, restart the agent and send the bot a direct message. Control group behavior with: ```bash hermina telegram-groups support on ``` With mention mode on, the bot responds in a group only when mentioned or when a message replies to it. With it off, it can respond to every group message; use that mode carefully in busy rooms. ## Matrix ```bash hermina matrix support \ --homeserver=https://matrix.example.com \ --user-id=@support:example.com \ --access-token=YOUR_ACCESS_TOKEN \ --allowed-rooms='!roomid:example.com' \ --require-mention=true \ --restart=true ``` Restrict users or rooms before joining public spaces. A Matrix access token grants the permissions of its account. ## Direct messages, groups, and allowlists Channel connectivity and message authorization are separate. A healthy bridge can still ignore a sender because of allowlist, group, or command policy. Set allowed WhatsApp users: ```bash hermina allowlist support --numbers=5511888888888,5511777777777 ``` Enable or disable WhatsApp group replies: ```bash hermina groups support on hermina groups support off ``` When WhatsApp groups are enabled, the generated policy requires a mention by default. See [Access and permissions](/hermina/docs/configuration/access/) for slash-command administrators and network security. ## Channel troubleshooting order 1. Confirm the agent runtime is running with `hermina list`. 2. Confirm the model responds in dashboard chat. 3. Check the channel status or bridge health. 4. Inspect agent logs. 5. Check allowlist and group policy. 6. Send `/whoami` to learn the platform's exact sender ID. 7. Re-pair or rotate the platform token only after the previous checks pass. --- # Configuration overview Hermina keeps each agent's configuration and data in one persistent profile directory. Use the dashboard or task-specific CLI commands for normal changes; edit files directly only when you need an advanced Hermes option. ## Configuration layers There are three distinct layers: | Layer | Scope | Examples | |---|---|---| | Hermina instance | Whole server | API keys, proxy, workspaces, Messenger, shared settings | | Agent profile | One agent | Model, tools, persona, channels, permissions, schedules | | Client preferences | One app or browser | Theme, scale, selected session, wallpaper, sidebar width | Changing a client preference does not alter the agent. Changing an agent profile does not change other agents. ## Agent profile files The default installation stores agents under `$HERMINA_HOME/agents/`. With the standard installer, `$HERMINA_HOME` is `/opt/hermina`. ```text agents// ├── config.yaml # Non-secret Hermes and Hermina settings ├── .env # Provider and channel secrets ├── SOUL.md # Identity, behavior, and boundaries ├── type.txt # container or angel ├── profile.json # Display metadata ├── skills/ # Agent-specific skills ├── cron/ # Scheduled jobs and history ├── whatsapp/session/ # Linked-device credentials ├── queue.db # Persistent task queue └── sessions/ # Gateway conversation state ``` The profile is mounted into a container at `/root/.hermes`. The container filesystem can remain read-only while this profile stays writable and persistent. ## Use the task-specific controls Prefer these commands over manual YAML changes: ```bash hermina model # Provider, model, endpoint, reasoning, API key hermina media # Vision, transcription, and speech hermina edit # SOUL.md hermina env # .env secrets and compatibility values hermina channel # WhatsApp transport hermina allowlist # Allowed senders hermina groups # WhatsApp group policy hermina commands # Slash-command administrators and user commands hermina matrix # Matrix account and room policy ``` Without change flags, most configuration commands display the current value and usage examples. ## Secrets versus normal settings Store secrets only in `.env` or the management key file. Typical secrets include: - LLM provider API keys. - WhatsApp Cloud access tokens and app secrets. - Telegram bot tokens. - Matrix access tokens. - Hermina API keys in `api-keys.txt`. Normal settings belong in `config.yaml`: provider name, model, reasoning level, media choices, group policy, tool settings, and gateway behavior. Never commit `.env`, `api-keys.txt`, WhatsApp session credentials, OAuth tokens, or database backups to Git. ## When a restart is required An active agent normally needs a restart after changing model, media, channel, permissions, or group policy. The corresponding CLI and API operations attempt to apply that restart automatically. After a manual edit: ```bash hermina restart hermina logs --follow ``` Confirm three states independently: 1. The runtime is running. 2. The model responds in dashboard chat. 3. Each enabled channel is connected and accepts the intended senders. ## Direct YAML editing For an advanced Hermes feature that is not exposed in the dashboard, edit: ```text $HERMINA_HOME/agents//config.yaml ``` Before editing: 1. Back up the file. 2. Stop simultaneous dashboard or CLI configuration changes. 3. Keep indentation and YAML types intact. 4. Restart the agent. 5. Inspect logs immediately. Hermes evolves independently, so confirm unfamiliar keys against the [current Hermes configuration reference](https://hermes-agent.nousresearch.com/docs/user-guide/configuration). ## Backup and restore For a complete operational backup, preserve: - `agents/` - `profile/`, `groups/`, `workspace/`, and `settings/` - `personas/custom/` - `api-keys.txt` in a separate secret store - Custom Nginx, Caddy, firewall, and service configuration Stop write-heavy workloads or use a filesystem/database-aware snapshot to avoid copying SQLite files mid-transaction. --- # Providers and models Every agent needs a model provider. Provider choice affects quality, latency, cost, privacy, context length, tool calling, and which media features are available. ## Recommended setup flow View the current configuration: ```bash hermina model ``` Set a hosted provider: ```bash hermina model \ --provider=openai \ --model=gpt-4o-mini \ --api-key=YOUR_API_KEY \ --reasoning=medium ``` The provider key is written to `.env`. Model, endpoint, API mode, and reasoning settings are written to `config.yaml`. Test a plain dashboard conversation immediately after changing providers. Add tools, channels, and schedules only after the base model works. ## Built-in provider presets Hermina currently includes presets for: | Provider ID | Default or example model | Secret | |---|---|---| | `opencode-go` | `deepseek-v4-flash` | None in the default preset | | `opencode-zen` | `claude-sonnet-4-5` | `OPENCODE_API_KEY` | | `openai` | `gpt-4o-mini` | `OPENAI_API_KEY` | | `anthropic` | `claude-sonnet-4-5` | `ANTHROPIC_API_KEY` | | `google` | `gemini-2.5-pro` | `GEMINI_API_KEY` | | `openrouter` | `openai/gpt-4o-mini` | `OPENROUTER_API_KEY` | | `deepseek` | `deepseek-chat` | `DEEPSEEK_API_KEY` | | `xai` | `grok-4` | `XAI_API_KEY` | | `groq` | Provider catalog | `GROQ_API_KEY` | | `mistral` | Provider catalog | `MISTRAL_API_KEY` | | `cerebras` | Provider catalog | `CEREBRAS_API_KEY` | | `deepinfra` | User selected | `DEEPINFRA_API_KEY` | | `fireworks` | User selected | `FIREWORKS_API_KEY` | | `github-copilot` | User selected | `GITHUB_TOKEN` | | `xiaomi` | User selected | `XIAOMI_API_KEY` | | `ollama` | `llama3` | None | | `lmstudio` | User selected | None | Provider catalogs change over time. A preset proves the expected protocol and default endpoint, not that every listed model is available on your account. ## Reasoning level Supported values are: ```text xhigh, high, medium, low, minimal, none ``` Higher reasoning can improve difficult multi-step work but usually costs more and responds more slowly. Use `medium` as a starting point, lower it for high-volume routine conversations, and raise it only for tasks that benefit from deeper planning. ```bash hermina model --reasoning=low ``` ## Custom OpenAI-compatible endpoints Override the base URL and API mode when using a self-hosted or compatible endpoint: ```bash hermina model \ --provider=openrouter \ --model=my-org/my-model \ --base-url=https://models.example.com/v1 \ --api-mode=chat_completions \ --api-key=YOUR_API_KEY ``` The provider ID still selects defaults and the environment variable used for the key. Verify the endpoint separately before debugging Hermina. ## Local models For Ollama: ```bash hermina model \ --provider=ollama \ --model=qwen3:latest \ --base-url=http://HOST_REACHABLE_FROM_AGENT:11434/v1 ``` `127.0.0.1` inside a Docker agent refers to that container, not the host. Use a host address reachable from the container network or run an appropriate network configuration. Choose a model with a large enough context window and reliable tool calling. Hermes workflows can fail in subtle ways on small-context or weak tool-use models even when simple chat appears normal. ## Media models Model configuration and media configuration are separate: ```bash hermina media ``` Example: ```bash hermina media \ --vision-provider=opencode-go \ --vision-model=mimo-v2.5 \ --stt-enabled=true \ --stt-provider=local \ --stt-model=base \ --stt-language=en \ --tts-provider=edge \ --tts-voice=en-US-GuyNeural ``` Vision analyzes images, STT transcribes incoming audio, and TTS produces spoken replies. Each provider may require its own key in `.env`. ## Common provider failures | Symptom | Likely cause | First check | |---|---|---| | Empty or immediate failure | Missing or invalid key | `hermina model ` and agent logs | | Model not found | Wrong provider-specific model name | Provider catalog/account access | | 404 from custom endpoint | Incorrect base URL or API mode | Test `/v1` endpoint separately | | Simple chat works, tools fail | Model has weak tool calling | Try a known tool-capable model | | Replies stop on long tasks | Context or timeout too small | Model context and runtime logs | | Local model is unreachable | Container cannot reach host loopback | Use a container-reachable host address | --- # Personas and behavior A persona gives an agent a durable role, tone, language policy, operating rules, and boundaries. In Hermina, the effective identity lives in the agent's `SOUL.md`. ## Browse persona templates List categories: ```bash hermina personas --lang=en ``` List one category: ```bash hermina personas business --lang=en hermina personas technology --lang=en ``` Templates are organized by language and category. Current categories include business, technology, finance, HR, education, retail, and fun. ## Apply a persona at creation ```bash hermina add helpdesk 5511999999999 \ --persona=technology/tech-support \ --lang=en \ --start=true ``` The persona files are copied into the new agent profile, so later edits affect only that agent. ## Edit an existing agent ```bash hermina edit helpdesk ``` This opens `SOUL.md` in `$EDITOR`, falling back to `nano`. Restart the agent after editing: ```bash hermina restart helpdesk ``` You can also edit persona and profile fields from the agent detail screen. ## Write an effective SOUL.md Use a short, explicit structure: ```markdown # Northwind Support You are the customer support assistant for Northwind Bikes. ## Language - Reply in the same language as the customer. - Keep product names unchanged. ## Responsibilities - Answer product and order questions. - Collect the order number before investigating delivery. - Escalate refunds above $100 to a human. ## Style - Warm, concise, and specific. - Prefer short paragraphs and clear next actions. ## Boundaries - Never invent order status or policy. - Never expose internal notes, credentials, or other customers' data. - If a request is outside scope, explain the limit and offer escalation. ``` Good persona instructions are observable. “Be helpful” is vague; “ask for the order number before investigating delivery” can be tested. ## Keep knowledge out of personality Use `SOUL.md` for stable identity and behavioral rules. Put changing product data, procedures, or domain references in workspace files or skills instead. This separation makes it easier to: - Update business knowledge without rewriting identity. - Reuse one skill across multiple agents. - Test whether a failure came from behavior, data, or tools. - Keep the system prompt concise. ## Custom persona templates Create a reusable custom template: ```bash hermina personas --create=northwind-support ``` Edit the generated files under: ```text $HERMINA_HOME/personas/custom/northwind-support/ ``` List and apply custom templates: ```bash hermina personas --custom=true hermina add support 5511999999999 --persona=custom/northwind-support ``` Delete only the reusable template, not agents that already copied it: ```bash hermina personas --delete=northwind-support ``` ## Test persona changes After every meaningful edit, start a clean chat session and test: 1. Identity: `Who are you and what do you handle?` 2. Language: send the same request in each supported language. 3. Boundary: ask for something the agent must refuse or escalate. 4. Procedure: exercise one required multi-step workflow. 5. Uncertainty: provide missing information and verify it asks instead of inventing. Test through dashboard chat first, then repeat one case through the real messaging channel. --- # Access and permissions Hermina has two access boundaries: management access to the server and conversation access to each agent. Configure both before exposing an instance or inviting users. ## Management API keys Protected API routes expect: ```http Authorization: Bearer ``` Manage keys locally: ```bash hermina angels key hermina angels key generate hermina angels key delete ``` API keys are instance-wide and unscoped. A valid key can administer every agent and reach privileged features such as environment settings, workspace files, and shell access. Use a separate key per device or operator when practical. That makes rotation possible without disconnecting everyone. The Web/Desktop login screen supports three access paths: - A passphrase entered directly. - A one-time code created by an authenticated `hermina connect --code` command. - A QR approval confirmed in an Android app that already has access to the server. For a public HTTPS domain, enable mandatory two-factor login from an SSH shell: ```bash hermina mfa hermina mfa --status ``` Until enrollment is complete, public access stays locked instead of falling back to passphrase-only authentication. The public web flow then requires the passphrase followed by a six-digit TOTP code. The server returns a random 12-hour session token, kept in browser session storage and revoked whenever the API restarts. Raw long-lived API keys remain compatible with direct loopback, LAN, and Tailscale clients, but are rejected on the reverse-proxied public path. If the authenticator is lost, use `hermina mfa --reset` over SSH. This replaces the TOTP secret and revokes current sessions. The QR approval request does not contain an API key. Its result can only be read by the browser that created it, using a separate random polling token. ## Safe network exposure Follow these rules: - Do not expose port `3456` directly to the internet. - Prefer Tailscale or another private VPN. - If public reachability is required, use an HTTPS reverse proxy and firewall. - Preserve `Authorization` and WebSocket upgrade headers at the proxy. - Ensure the proxy manages `X-Forwarded-For`; Hermina uses it to enforce MFA on the public path. - Restrict access to `.env`, `api-keys.txt`, session directories, and backups. - Never log connection QR contents, API keys, provider tokens, or authorization headers. The Web client stores MFA sessions in `sessionStorage`. Private connections may still persist long-lived keys; Android uses app preferences and the extension uses browser extension storage. Treat a compromised device profile as a compromised Hermina credential. ## Sender allowlist Restrict who can message an agent: ```bash hermina allowlist support --numbers=5511888888888,5511777777777 ``` Show the current policy: ```bash hermina allowlist support ``` An open allowlist allows every sender who can reach the channel. Use it only for intentionally public agents whose tools and data are safe for public use. ## Slash-command administrators Administrators can run all supported slash commands. Regular users can run only the configured list. ```bash hermina commands support \ --allow-admin=5511888888888 \ --user-commands=help,whoami,status ``` Use the exact platform ID returned by `/whoami`. WhatsApp may identify an account as a phone-number JID or as a value ending in `@lid`. To intentionally configure no administrators: ```bash hermina commands support --allow-admin='' ``` Hermina stores an internal sentinel so command gating remains enabled rather than treating an empty list as unrestricted. ## Group policy For WhatsApp: ```bash hermina groups support on hermina groups support off ``` Enabled WhatsApp groups require a mention by default. Keep that behavior in active group chats to prevent the agent from responding to unrelated conversation. For Telegram: ```bash hermina telegram-groups support on ``` Here, `on` means mention-only mode. Confirm the current status before assuming the same wording maps to the same underlying setting on every platform. ## Tool and shell risk Permissions inside the messaging layer do not make every tool safe. Review which tools are enabled for each platform and persona. In particular: - Shell can execute commands in a container or, for host-based agents, on the server. - File tools can read profile or workspace data available to the runtime. - Browser and web tools can send information to external services. - Messaging tools can act in connected accounts. - Scheduled jobs continue to run without an interactive user present. Use container agents for untrusted conversations, keep host-based `angel` agents tightly restricted, and follow least privilege for channel accounts and API credentials. ## Key rotation after device loss 1. List keys locally and identify the lost device's key. 2. Generate a replacement key if needed. 3. Delete the compromised key by prefix. 4. Reconnect the intended client. 5. Review API and proxy logs without printing secret values. 6. Rotate provider or channel tokens too if they were exposed through the device or shell. See [Connect your apps](/hermina/docs/user-guide/connect-apps/) for pairing workflows. --- # Tasks and schedules Hermina provides two automation mechanisms: a persistent queue for discrete work and Hermes cron jobs for time-based execution. Use the queue when another system submits work; use cron when time is the trigger. ## Choose the right mechanism | Need | Use | Why | |---|---|---| | Run something at a specific time or interval | Agent cron | The schedule belongs to Hermes and follows the agent profile | | Submit work from a script or integration | Task queue | Persistent status, result, and failure state | | Schedule work for the host Hermes profile | Host cron | Runs outside one named agent profile | | Review automation output in the UI | Cron + Inbox/Feed | Designed for operator visibility and delivery | Start with a manually triggered prompt. Schedule it only after the prompt, model, tools, and delivery destination work interactively. ## Agent cron jobs List jobs for one agent: ```bash hermina agent-cron analyst list ``` Create a recurring job: ```bash hermina agent-cron analyst create \ "every 1h" \ "Summarize new activity and highlight anything that needs attention" \ --cron-name=hourly-summary \ --deliver=local ``` Common lifecycle actions include `list`, `create`, `remove`, `pause`, `resume`, and `run`. Use the job ID printed by the list command for lifecycle actions: ```bash hermina agent-cron analyst run --job-id= hermina agent-cron analyst pause --job-id= hermina agent-cron analyst resume --job-id= hermina agent-cron analyst remove --job-id= ``` The dashboard and Android app expose the same per-agent schedule management with execution history and notification state. ## Host cron jobs Host cron uses the host Hermes profile rather than an agent profile: ```bash hermina host-cron list hermina host-cron create \ "every day at 09:00" \ "Review the server status and summarize failures" \ --cron-name=daily-health \ --deliver=local ``` Host jobs have the permissions and context of the host profile. Use them for infrastructure-level work, not as a substitute for an isolated agent. ## Persistent task queue Each container agent has a SQLite queue, an internal Queue API, and a worker. The data remains in `agents//queue.db` across container restarts. Check health and recent tasks: ```bash hermina queue health analyst hermina queue list analyst hermina queue status analyst ``` Enqueue a goal: ```bash hermina queue enqueue analyst goal \ '{"goal":"Review the latest workspace report and produce three next actions"}' ``` Enqueue a command: ```bash hermina queue enqueue analyst command \ '{"command":"ls -la /root/.hermes"}' ``` Supported queue types include `noop`, `command`, `webhook`, `send_message`, and `goal`. Payloads are JSON. If a plain string is supplied, the CLI wraps it as a `text` field. Inspect or cancel a task: ```bash hermina queue status analyst hermina queue cancel analyst hermina queue logs analyst --lines=50 ``` Only pending tasks can be cancelled reliably; a processing task may already be executing. ## Delivery and operator visibility Cron output can feed the dashboard Inbox, activity Feed, or a configured channel depending on its delivery setting. Check both job execution status and final delivery status—a successful model run can still fail to reach a channel. Use clear names such as `hourly-summary`, `daily-health`, and `weekly-report`. Include the expected output and failure behavior in the prompt. ## Reliable automation checklist Before enabling a recurring job: 1. Run the prompt manually in a clean chat. 2. Confirm every required tool and credential. 3. Use an explicit timezone and verify the server timezone. 4. Keep the prompt idempotent when retries are possible. 5. Choose a delivery destination and test it. 6. Define what the agent should do when source data is missing. 7. Review the first several executions in Inbox or history. ## Troubleshooting automation | Symptom | Check | |---|---| | Job never starts | Schedule syntax, pause state, server time, agent runtime | | Job starts but fails | Agent logs, provider credentials, tool permissions | | Queue remains pending | `hermina queue health`, worker logs, running container | | Result exists but no notification | Delivery target and channel connection | | Duplicate side effects | Idempotency, retry behavior, overlapping schedules | --- # CLI reference The `hermina` CLI is the local administrative interface. It reads `$HERMINA_HOME` (default `/root/hermina` for source checkouts; `/opt/hermina` with the standard installer) and can directly access profiles, Docker, `systemd`, and Hermes. Run `hermina --help` for the commands available in your installed version. With no arguments, `hermina` opens the TUI. ## Onboarding and connection | Command | Purpose | |---|---| | `hermina onboard` | Guided server, model, agent, channel, and client setup | | `hermina connect` | Show server URL and current connection instructions | | `hermina connect --qr` | Show a client QR containing URL and API key | | `hermina connect --code` | Generate a short-lived pairing code | | `hermina desktop` | Open Electron/Web or print the URL on a headless server | | `hermina tui` | Open the interactive terminal UI | ## Agent lifecycle | Command | Purpose | |---|---| | `hermina list` | List agents, runtime status, channel state, type, and port | | `hermina status` | Show general stack and agent status | | `hermina add ` | Create an agent profile and runtime | | `hermina start ` | Start a container or angel service | | `hermina stop ` | Stop the runtime | | `hermina restart ` | Restart the runtime | | `hermina remove ` | Remove an agent; use `--keep-data=true` to preserve profile data | | `hermina build [name]` | Rebuild an agent image or all required images | | `hermina logs ` | Show runtime logs; add `--follow` to stream | | `hermina shell ` | Execute a command in the selected runtime | | `hermina cat ` | Read a file from an agent profile/runtime | ## Model, identity, and media | Command | Purpose | |---|---| | `hermina model ` | View or set provider, model, key, endpoint, and reasoning | | `hermina media ` | View or set vision, STT, and TTS | | `hermina edit ` | Edit the agent's `SOUL.md` | | `hermina env ` | Edit the agent's `.env` | | `hermina personas` | List persona categories and manage custom templates | Run a configuration command without flags to show the current values and examples. ## Channels and permissions | Command | Purpose | |---|---| | `hermina channel ` | View or set WhatsApp transport and Cloud settings | | `hermina qr ` | Show WhatsApp pairing guidance | | `hermina bridge ` | Check the linked-device bridge health | | `hermina allowlist ` | View or set allowed senders | | `hermina groups [on/off]` | Control WhatsApp group replies | | `hermina telegram-groups [on/off]` | Control Telegram mention-only group mode | | `hermina matrix ` | Configure Matrix and its room/user policy | | `hermina commands ` | Configure admin IDs and regular-user slash commands | | `hermina sessions ` | List, clear, or delete channel sessions | ## Automation | Command | Purpose | |---|---| | `hermina agent-cron ` | Manage cron jobs in one agent profile | | `hermina host-cron ` | Manage cron jobs in the host Hermes profile | | `hermina queue enqueue ` | Add a persistent task | | `hermina queue list ` | List queued work | | `hermina queue status [task-id]` | Inspect recent or specific task state | | `hermina queue cancel ` | Cancel pending work | | `hermina queue health ` | Check the internal queue service | | `hermina queue logs ` | Show queue API and worker logs | ## Management API service | Command | Purpose | |---|---| | `hermina angels status` | Check service and HTTP health | | `hermina angels start/stop/restart` | Control the management service | | `hermina angels logs` | Show service logs | | `hermina angels key` | List management keys locally | | `hermina angels key generate` | Add a new key | | `hermina angels key delete ` | Remove one key | | `hermina angels qr ` | Generate a client QR for a specific URL | ## Boolean and structured values The CLI is powered by Python Fire. For automation, prefer explicit values: ```bash hermina add support 5511999999999 --start=true --lang=en hermina sessions support --json-output=true hermina remove support --keep-data=true --yes=true ``` Comma-separated lists are used for sender IDs and commands: ```bash hermina allowlist support --numbers=5511888888888,5511777777777 hermina commands support --user-commands=help,whoami,status ``` Quote JSON payloads and values that contain spaces. ## Scripting guidance The CLI was designed primarily for human operation. Some commands prompt, some print formatted text, and not every error is exposed as structured JSON. For reliable scripts: - Pass confirmation and boolean flags explicitly. - Use JSON output when a command offers it. - Prefer the authenticated HTTP API for remote or concurrent automation. - Do not mutate the same agent through the CLI and API concurrently. - Validate the installed CLI help instead of assuming a command from newer documentation exists. --- # Troubleshooting Diagnose Hermina from the outside in: network, management API, agent runtime, model, channel policy, and finally automation. Changing several layers at once makes the original failure harder to identify. ## Recovery order Run these checks in order: ```bash hermina angels status curl -fsS http://127.0.0.1:3456/health hermina status hermina list hermina logs --lines=100 hermina model hermina bridge ``` Then test a plain dashboard message. Only after that works should you test WhatsApp, Telegram, Matrix, tools, queues, or cron delivery. ## Client cannot connect ### Symptoms - Login times out. - Health works on the server but not on the client device. - Pairing code is rejected. - WebSocket shell fails while normal pages work. ### Checks 1. Open `/health` from the client device. 2. Replace `127.0.0.1` with a reachable private/VPN address for remote clients. 3. Generate a new code with `hermina connect --code`. 4. Verify the key exists with `hermina angels key`. 5. Inspect `hermina angels logs --lines=100`. 6. Confirm the proxy preserves `Authorization` and WebSocket upgrade headers. 7. Check firewall, TLS certificate, and CORS only after basic routing succeeds. ## Agent will not start ```bash hermina logs --lines=150 hermina build hermina restart ``` Common causes include: - Missing Docker image. - Invalid YAML or environment values. - Host port conflict. - Stale container definition after a webhook-port change. - Missing profile files or incorrect permissions. - `systemd` failure for a host-based angel. Do not repeatedly recreate the agent before copying its profile data. Logs normally identify whether the failure happens in the queue wrapper, channel bridge, or Hermes Gateway. ## Model fails or returns no useful answer ```bash hermina model hermina logs --follow ``` Verify: - The correct key exists in the agent's `.env`. - The provider and model name match the account. - The base URL includes the expected API path. - The selected API mode matches the endpoint. - A local model is reachable from inside the container. - The model supports a sufficient context window and tool calling. Test with a simple prompt that does not require tools. If that works, test one tool at a time. ## WhatsApp is disconnected ```bash hermina bridge hermina logs --follow hermina qr ``` If no valid session exists, restart the agent and scan the new QR from the agent account's **Linked devices** screen. Preserve `agents//whatsapp/session/` across updates. If the bridge is connected but the bot ignores a user, inspect allowlist, group, and slash-command policy rather than re-pairing: ```bash hermina allowlist hermina groups hermina commands ``` Send `/whoami` and use the exact returned identifier. WhatsApp LID identifiers can differ from the visible phone number. ## Telegram or Matrix ignores groups For Telegram, check mention-only mode: ```bash hermina telegram-groups ``` For Matrix, confirm allowed users, allowed rooms, and `require_mention`. Also verify the bot account has joined the room and that its access token is valid. ## Queue is stuck ```bash hermina queue health hermina queue list hermina queue logs --lines=100 ``` The agent container must be running. A task can remain pending when the worker is unhealthy; it can remain processing when the worker stopped during execution. Inspect the task and worker logs before manually changing the SQLite database. ## Cron job did not run or deliver ```bash hermina agent-cron list ``` Check: - The job is not paused. - The schedule and server timezone match your expectation. - The agent runtime and model were available at execution time. - Required tools and credentials still work. - The delivery channel is connected. - Inbox or execution history contains a result even if delivery failed. ## Configuration change appears ignored 1. Confirm you edited the intended agent and server. 2. Restart the agent after a direct file edit. 3. Inspect the effective values with the task-specific CLI command. 4. Check logs for YAML parse errors or compatibility overrides. 5. Make sure another client did not write stale configuration at the same time. For container agents, remember that the persistent host profile is mounted at `/root/.hermes` inside the container. ## Collect a useful issue report Include: - Hermina commit or installed version. - Operating system and installation path. - Agent runtime type: container or angel. - Exact command or UI action. - Expected and actual behavior. - Relevant log excerpt with secrets removed. - Whether dashboard chat, channel messaging, and other agents still work. Never include API keys, provider tokens, authorization headers, connection QR contents, `.env`, or WhatsApp session files in an issue.