mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-07 08:02:23 +00:00
Merge branch 'main' into docker_s6
This commit is contained in:
commit
59da190512
417 changed files with 26434 additions and 3321 deletions
|
|
@ -11,6 +11,10 @@ Hermes uses two kinds of model slots:
|
|||
|
||||
This page covers configuring both from the dashboard. If you prefer config files or the CLI, jump to [Alternative methods](#alternative-methods) at the bottom.
|
||||
|
||||
:::tip Fastest path: Nous Portal
|
||||
[Nous Portal](/docs/user-guide/features/tool-gateway) provides 300+ models under one subscription. On a fresh install, run `hermes setup --portal` to log in and set Nous as your provider in one command. Inspect what's wired up with `hermes portal status`.
|
||||
:::
|
||||
|
||||
## The Models page
|
||||
|
||||
Open the dashboard and click **Models** in the sidebar. You get two sections:
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ docker run -d \
|
|||
-p 8642:8642 \
|
||||
-e API_SERVER_ENABLED=true \
|
||||
-e API_SERVER_HOST=0.0.0.0 \
|
||||
-e API_SERVER_KEY=your_api_key_here \
|
||||
-e API_SERVER_KEY="$(openssl rand -hex 32)" \
|
||||
-e API_SERVER_CORS_ORIGINS='*' \
|
||||
nousresearch/hermes-agent gateway run
|
||||
```
|
||||
|
|
@ -60,7 +60,7 @@ Opening any port on an internet facing machine is a security risk. You should no
|
|||
|
||||
## Running the dashboard
|
||||
|
||||
The built-in web dashboard runs as an optional side-process inside the same container as the gateway. Set `HERMES_DASHBOARD=1` and expose port `9119` alongside the gateway's `8642`:
|
||||
The built-in web dashboard runs as an optional side-process inside the same container as the gateway. Set `HERMES_DASHBOARD=1` to run the dashboard on container loopback (`127.0.0.1`) by default:
|
||||
|
||||
```sh
|
||||
docker run -d \
|
||||
|
|
@ -68,7 +68,6 @@ docker run -d \
|
|||
--restart unless-stopped \
|
||||
-v ~/.hermes:/opt/data \
|
||||
-p 8642:8642 \
|
||||
-p 9119:9119 \
|
||||
-e HERMES_DASHBOARD=1 \
|
||||
nousresearch/hermes-agent gateway run
|
||||
```
|
||||
|
|
@ -78,11 +77,11 @@ The entrypoint starts `hermes dashboard` in the background (running as the non-r
|
|||
| Environment variable | Description | Default |
|
||||
|---------------------|-------------|---------|
|
||||
| `HERMES_DASHBOARD` | Set to `1` (or `true` / `yes`) to launch the dashboard alongside the main command | *(unset — dashboard not started)* |
|
||||
| `HERMES_DASHBOARD_HOST` | Bind address for the dashboard HTTP server | `0.0.0.0` |
|
||||
| `HERMES_DASHBOARD_HOST` | Bind address for the dashboard HTTP server | `127.0.0.1` |
|
||||
| `HERMES_DASHBOARD_PORT` | Port for the dashboard HTTP server | `9119` |
|
||||
| `HERMES_DASHBOARD_TUI` | Set to `1` to expose the in-browser Chat tab (embedded `hermes --tui` via PTY/WebSocket) | *(unset)* |
|
||||
|
||||
The default `HERMES_DASHBOARD_HOST=0.0.0.0` is required for the host to reach the dashboard through the published port; the entrypoint automatically passes `--insecure` to `hermes dashboard` in that case. Override to `127.0.0.1` if you want to restrict the dashboard to in-container access only (e.g. behind a reverse proxy in a sidecar).
|
||||
By default, the dashboard stays on loopback to avoid exposing the unauthenticated web surface over the network. To publish it intentionally, set `HERMES_DASHBOARD_HOST=0.0.0.0` and configure your own trusted network boundary/reverse proxy. In that case you must explicitly add `--insecure` behavior by passing host/flags in your command path (the entrypoint no longer auto-enables insecure mode).
|
||||
|
||||
:::note
|
||||
The dashboard runs as a supervised s6 service inside the container. If
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ The API server exposes hermes-agent as an OpenAI-compatible HTTP endpoint. Any f
|
|||
|
||||
Your agent handles requests with its full toolset (terminal, file operations, web search, memory, skills) and returns the final response. When streaming, tool progress indicators appear inline so frontends can show what the agent is doing.
|
||||
|
||||
:::tip One backend covers models + tools
|
||||
Hermes itself needs a configured provider and tool backends for the API server to be useful. A [Nous Portal](/docs/user-guide/features/tool-gateway) subscription handles both — 300+ models plus web/image/TTS/browser via the Tool Gateway. Run `hermes setup --portal` once before starting the API server and frontends like Open WebUI or LobeChat get a fully tool-equipped backend.
|
||||
:::
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Enable the API server
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ python batch_runner.py \
|
|||
python batch_runner.py --list_distributions
|
||||
```
|
||||
|
||||
:::tip Predictable cost at scale
|
||||
Batch runs spin up many concurrent agent sessions, each making model calls and tool calls. A [Nous Portal](/docs/user-guide/features/tool-gateway) subscription bundles model access plus web search, image gen, TTS, and cloud browsers under one bill — useful when you want stable cost-per-trajectory without juggling rate limits across five vendor accounts. Set up with `hermes setup --portal`, then point `--model` at a Nous model.
|
||||
:::
|
||||
|
||||
## Dataset Format
|
||||
|
||||
The input dataset is a JSONL file (one JSON object per line). Each entry must have a `prompt` field:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ Key capabilities:
|
|||
## Setup
|
||||
|
||||
:::tip Nous Subscribers
|
||||
If you have a paid [Nous Portal](https://portal.nousresearch.com) subscription, you can use browser automation through the **[Tool Gateway](tool-gateway.md)** without any separate API keys. Run `hermes model` or `hermes tools` to enable it.
|
||||
If you have a paid [Nous Portal](https://portal.nousresearch.com) subscription, you can use browser automation through the **[Tool Gateway](tool-gateway.md)** without any separate API keys. New installs can run `hermes setup --portal` to log in and turn on every gateway tool at once; existing installs can pick **Nous Subscription** as the browser provider via `hermes model` or `hermes tools`.
|
||||
:::
|
||||
|
||||
### Browserbase cloud mode
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ Both `provider` and `model` are **required**. If either is missing, the fallback
|
|||
|----------|-------|-------------|
|
||||
| AI Gateway | `ai-gateway` | `AI_GATEWAY_API_KEY` |
|
||||
| OpenRouter | `openrouter` | `OPENROUTER_API_KEY` |
|
||||
| Nous Portal | `nous` | `hermes auth` (OAuth) |
|
||||
| Nous Portal | `nous` | `hermes setup --portal` (fresh) or `hermes auth add nous` (OAuth) |
|
||||
| OpenAI Codex | `openai-codex` | `hermes model` (ChatGPT OAuth) |
|
||||
| GitHub Copilot | `copilot` | `COPILOT_GITHUB_TOKEN`, `GH_TOKEN`, or `GITHUB_TOKEN` |
|
||||
| GitHub Copilot ACP | `copilot-acp` | External process (editor integration) |
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Prices are FAL's pricing at time of writing; check [fal.ai](https://fal.ai/) for
|
|||
## Setup
|
||||
|
||||
:::tip Nous Subscribers
|
||||
If you have a paid [Nous Portal](https://portal.nousresearch.com) subscription, you can use image generation through the **[Tool Gateway](tool-gateway.md)** without a FAL API key. Your model selection persists across both paths.
|
||||
If you have a paid [Nous Portal](https://portal.nousresearch.com) subscription, you can use image generation through the **[Tool Gateway](tool-gateway.md)** without a FAL API key. Your model selection persists across both paths. New installs can run `hermes setup --portal` to log in and turn on every gateway tool at once; existing installs can pick **Nous Subscription** as the image-gen backend via `hermes tools`.
|
||||
|
||||
If the managed gateway returns `HTTP 4xx` for a specific model, that model isn't yet proxied on the portal side — the agent will tell you so, with remediation steps (set `FAL_KEY` for direct access, or pick a different model).
|
||||
:::
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ They coexist: a kanban worker may call `delegate_task` internally during its run
|
|||
- **Link** — `task_links` row recording a parent → child dependency. The dispatcher promotes `todo → ready` when all parents are `done`.
|
||||
- **Comment** — the inter-agent protocol. Agents and humans append comments; when a worker is (re-)spawned it reads the full comment thread as part of its context.
|
||||
- **Workspace** — the directory a worker operates in. Three kinds:
|
||||
- `scratch` (default) — fresh tmp dir under `~/.hermes/kanban/workspaces/<id>/` (or `~/.hermes/kanban/boards/<slug>/workspaces/<id>/` on non-default boards).
|
||||
- `dir:<path>` — an existing shared directory (Obsidian vault, mail ops dir, per-account folder). **Must be an absolute path.** Relative paths like `dir:../tenants/foo/` are rejected at dispatch because they'd resolve against whatever CWD the dispatcher happens to be in, which is ambiguous and a confused-deputy escape vector. The path is otherwise trusted — it's your box, your filesystem, the worker runs with your uid. This is the trusted-local-user threat model; kanban is single-host by design.
|
||||
- `worktree` — a git worktree under `.worktrees/<id>/` for coding tasks. Use `worktree:<path>` to pin the exact target path. Worker-side `git worktree add` creates it, using `--branch` when provided.
|
||||
- `scratch` (default) — fresh tmp dir under `~/.hermes/kanban/workspaces/<id>/` (or `~/.hermes/kanban/boards/<slug>/workspaces/<id>/` on non-default boards). **Deleted when the task completes** — scratch is ephemeral by design, so the dir is wiped the moment the worker (or `hermes kanban complete <id>`) marks the task done. If you want to keep the worker's output, use `worktree:` or `dir:<path>` instead. The first time a scratch workspace is created on an install, the dispatcher logs a warning and emits a `tip_scratch_workspace` event on the task (visible via `hermes kanban show <id>`).
|
||||
- `dir:<path>` — an existing shared directory (Obsidian vault, mail ops dir, per-account folder). **Must be an absolute path.** Relative paths like `dir:../tenants/foo/` are rejected at dispatch because they'd resolve against whatever CWD the dispatcher happens to be in, which is ambiguous and a confused-deputy escape vector. The path is otherwise trusted — it's your box, your filesystem, the worker runs with your uid. This is the trusted-local-user threat model; kanban is single-host by design. **Preserved on completion.**
|
||||
- `worktree` — a git worktree under `.worktrees/<id>/` for coding tasks. Use `worktree:<path>` to pin the exact target path. Worker-side `git worktree add` creates it, using `--branch` when provided. **Preserved on completion.**
|
||||
- **Dispatcher** — a long-lived loop that, every N seconds (default 60): reclaims stale claims, reclaims crashed workers (PID gone but TTL not yet expired), promotes ready tasks, atomically claims, spawns assigned profiles. Runs **inside the gateway** by default (`kanban.dispatch_in_gateway: true`). One dispatcher sweeps all boards per tick; workers are spawned with `HERMES_KANBAN_BOARD` pinned so they can't see other boards. After `kanban.failure_limit` consecutive spawn failures on the same task (default: 2) the dispatcher auto-blocks it with the last error as the reason — prevents thrashing on tasks whose profile doesn't exist, workspace can't mount, etc.
|
||||
- **Tenant** — optional string namespace *within* a board. One specialist fleet can serve multiple businesses (`--tenant business-a`) with data isolation by workspace path and memory key prefix. Tenants are a soft filter; boards are the hard isolation boundary.
|
||||
|
||||
|
|
|
|||
|
|
@ -39,8 +39,16 @@ Bring your own keys anytime — per-tool, whenever you want to. The gateway isn'
|
|||
|
||||
## Get started
|
||||
|
||||
The fastest path for a fresh install:
|
||||
|
||||
```bash
|
||||
hermes model # Pick Nous Portal as your provider
|
||||
hermes setup --portal # Nous OAuth, set Nous as provider, and turn on the Tool Gateway in one go
|
||||
```
|
||||
|
||||
Already have Hermes configured? Just switch your provider:
|
||||
|
||||
```bash
|
||||
hermes model # Pick Nous Portal — Hermes will offer to turn on the Tool Gateway
|
||||
```
|
||||
|
||||
When you select Nous Portal, Hermes offers to turn on the Tool Gateway. Accept, and you're done — every supported tool is live on the next run.
|
||||
|
|
@ -48,10 +56,12 @@ When you select Nous Portal, Hermes offers to turn on the Tool Gateway. Accept,
|
|||
Check what's active at any time:
|
||||
|
||||
```bash
|
||||
hermes status
|
||||
hermes portal status # Portal auth + Tool Gateway routing summary
|
||||
hermes portal tools # Gateway catalog with current routing per tool
|
||||
hermes status # Full system status (Tool Gateway is one section)
|
||||
```
|
||||
|
||||
You'll see a section like:
|
||||
`hermes portal status` shows a section like:
|
||||
|
||||
```
|
||||
◆ Nous Tool Gateway
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ description: "Text-to-speech and voice message transcription across all platform
|
|||
Hermes Agent supports both text-to-speech output and voice message transcription across all messaging platforms.
|
||||
|
||||
:::tip Nous Subscribers
|
||||
If you have a paid [Nous Portal](https://portal.nousresearch.com) subscription, OpenAI TTS is available through the **[Tool Gateway](tool-gateway.md)** without a separate OpenAI API key. Run `hermes model` or `hermes tools` to enable it.
|
||||
If you have a paid [Nous Portal](https://portal.nousresearch.com) subscription, OpenAI TTS is available through the **[Tool Gateway](tool-gateway.md)** without a separate OpenAI API key. New installs can run `hermes setup --portal` to log in and turn on every gateway tool at once; existing installs can pick **Nous Subscription** for just TTS via `hermes model` or `hermes tools`.
|
||||
:::
|
||||
|
||||
## Text-to-Speech
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@ Before using voice features, make sure you have:
|
|||
The `~/.hermes/` directory and default `config.yaml` are created automatically the first time you run `hermes`. You only need to create `~/.hermes/.env` manually for API keys.
|
||||
:::
|
||||
|
||||
:::tip Nous Portal covers both
|
||||
A paid [Nous Portal](/docs/user-guide/features/tool-gateway) subscription supplies the LLM (step 2) **and** OpenAI TTS via the Tool Gateway — no separate OpenAI key needed. On a fresh install, `hermes setup --portal` wires both up at once.
|
||||
:::
|
||||
|
||||
## Overview
|
||||
|
||||
| Feature | Platform | Description |
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ Brave Search, DDGS, and xAI are **search-only** — pair any of them with Firecr
|
|||
**Per-capability split:** you can use different providers for search and extract independently — for example SearXNG (free) for search and Firecrawl for extract. See [Per-capability configuration](#per-capability-configuration) below.
|
||||
|
||||
:::tip Nous Subscribers
|
||||
If you have a paid [Nous Portal](https://portal.nousresearch.com) subscription, web search and extract are available through the **[Tool Gateway](tool-gateway.md)** via managed Firecrawl — no API key needed. Run `hermes tools` to enable it.
|
||||
If you have a paid [Nous Portal](https://portal.nousresearch.com) subscription, web search and extract are available through the **[Tool Gateway](tool-gateway.md)** via managed Firecrawl — no API key needed. New installs can run `hermes setup --portal` to log in and turn on all gateway tools at once; existing installs can flip just web via `hermes tools`.
|
||||
:::
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ FEISHU_WEBHOOK_PORT=8765 # default: 8765
|
|||
FEISHU_WEBHOOK_PATH=/feishu/webhook # default: /feishu/webhook
|
||||
```
|
||||
|
||||
When Feishu sends a URL verification challenge (`type: url_verification`), the webhook responds automatically so you can complete the subscription setup in the Feishu developer console.
|
||||
When Feishu sends a URL verification challenge (`type: url_verification`), the webhook responds automatically so you can complete the subscription setup in the Feishu developer console. The challenge response is gated on `FEISHU_VERIFICATION_TOKEN` when set — challenge requests with a missing or mismatched token are rejected so an unauthenticated remote cannot prove endpoint control by echoing attacker-controlled challenge data.
|
||||
|
||||
## Step 3: Configure Hermes
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ description: "Chat with Hermes from Telegram, Discord, Slack, WhatsApp, Signal,
|
|||
|
||||
# Messaging Gateway
|
||||
|
||||
Chat with Hermes from Telegram, Discord, Slack, WhatsApp, Signal, SMS, Email, Home Assistant, Mattermost, Matrix, DingTalk, Feishu/Lark, WeCom, Weixin, BlueBubbles (iMessage), QQ, Yuanbao, Microsoft Teams, LINE, or your browser. The gateway is a single background process that connects to all your configured platforms, handles sessions, runs cron jobs, and delivers voice messages.
|
||||
Chat with Hermes from Telegram, Discord, Slack, WhatsApp, Signal, SMS, Email, Home Assistant, Mattermost, Matrix, DingTalk, Feishu/Lark, WeCom, Weixin, BlueBubbles (iMessage), QQ, Yuanbao, Microsoft Teams, LINE, ntfy, or your browser. The gateway is a single background process that connects to all your configured platforms, handles sessions, runs cron jobs, and delivers voice messages.
|
||||
|
||||
For the full voice feature set — including CLI microphone mode, spoken replies in messaging, and Discord voice-channel conversations — see [Voice Mode](/docs/user-guide/features/voice-mode) and [Use Voice Mode with Hermes](/docs/guides/use-voice-mode-with-hermes).
|
||||
|
||||
|
|
@ -35,6 +35,7 @@ For the full voice feature set — including CLI microphone mode, spoken replies
|
|||
| Yuanbao | ✅ | ✅ | ✅ | — | — | ✅ | ✅ |
|
||||
| Microsoft Teams | — | ✅ | — | ✅ | — | ✅ | — |
|
||||
| LINE | — | ✅ | ✅ | — | — | ✅ | — |
|
||||
| ntfy | — | — | — | — | — | — | — |
|
||||
|
||||
**Voice** = TTS audio replies and/or voice message transcription. **Images** = send/receive images. **Files** = send/receive file attachments. **Threads** = threaded conversations. **Reactions** = emoji reactions on messages. **Typing** = typing indicator while processing. **Streaming** = progressive message updates via editing.
|
||||
|
||||
|
|
|
|||
155
website/docs/user-guide/messaging/ntfy.md
Normal file
155
website/docs/user-guide/messaging/ntfy.md
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
# ntfy
|
||||
|
||||
[ntfy](https://ntfy.sh/) is a simple HTTP-based pub-sub notification service. It works with the free public server at `ntfy.sh` or any self-hosted instance, and supports any client that can make HTTP requests — phones, browsers, scripts, watches.
|
||||
|
||||
ntfy makes a great lightweight push channel for Hermes: subscribe to a topic from the [ntfy mobile app](https://ntfy.sh/docs/subscribe/phone/), send messages to the topic to talk to the agent, get the response back on your phone.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A topic name (any unique string — `hermes-myname-2026` works fine)
|
||||
- The [ntfy mobile app](https://ntfy.sh/docs/subscribe/phone/) installed and subscribed to that topic
|
||||
- Optional: a self-hosted ntfy server, or an `ntfy.sh` account token for private/reserved topics
|
||||
|
||||
That's it. No SDK, no daemon, no Node.js. The adapter uses `httpx` which is already a Hermes dependency.
|
||||
|
||||
## Configure Hermes
|
||||
|
||||
### Via setup wizard
|
||||
|
||||
```bash
|
||||
hermes setup gateway
|
||||
```
|
||||
|
||||
Select **ntfy** and follow the prompts.
|
||||
|
||||
### Via environment variables
|
||||
|
||||
Add these to `~/.hermes/.env`:
|
||||
|
||||
```
|
||||
NTFY_TOPIC=hermes-myname-2026
|
||||
NTFY_ALLOWED_USERS=hermes-myname-2026
|
||||
NTFY_HOME_CHANNEL=hermes-myname-2026
|
||||
```
|
||||
|
||||
| Variable | Required | Description |
|
||||
|---|---|---|
|
||||
| `NTFY_TOPIC` | Yes | Topic to subscribe to (incoming messages) |
|
||||
| `NTFY_SERVER_URL` | Optional | Server URL (default: `https://ntfy.sh`) — point to a self-hosted ntfy for privacy |
|
||||
| `NTFY_TOKEN` | Optional | Bearer token (e.g. `tk_xyz`) or `user:pass` for Basic auth |
|
||||
| `NTFY_PUBLISH_TOPIC` | Optional | Different topic for outgoing replies (defaults to `NTFY_TOPIC`) |
|
||||
| `NTFY_MARKDOWN` | Optional | Set `true` to send replies with `X-Markdown: true` header |
|
||||
| `NTFY_ALLOWED_USERS` | Recommended | Comma-separated topic names allowed (treated as user IDs; see below) |
|
||||
| `NTFY_ALLOW_ALL_USERS` | Optional | Set `true` to allow every publisher — only safe for private topics with read tokens |
|
||||
| `NTFY_HOME_CHANNEL` | Optional | Default topic for cron / notification delivery |
|
||||
| `NTFY_HOME_CHANNEL_NAME` | Optional | Human label for the home channel |
|
||||
|
||||
## Identity model — read this before deploying
|
||||
|
||||
ntfy has no native authenticated user identity. The `title` field on a published message is **publisher-controlled** and can be anything the sender wants. The Hermes adapter does NOT use `title` for authorization — it would let any publisher who knows the topic spoof an allowed user.
|
||||
|
||||
Instead, **the topic name itself is the identity**. Every message published to the topic is treated as coming from the same logical user (the topic). `NTFY_ALLOWED_USERS` is therefore typically just the topic name itself — a single-entry allowlist that gates the whole channel.
|
||||
|
||||
This means **anyone who knows the topic can talk to the agent**. To make that a real trust boundary:
|
||||
|
||||
- **Self-host ntfy** and lock the topic down with [Access Control](https://docs.ntfy.sh/config/#access-control). Only authorized clients with the read/write token can publish.
|
||||
- Or **use a private topic on ntfy.sh** ([reserved topics](https://docs.ntfy.sh/publish/#reserved-topics) require an account) and protect it with a `NTFY_TOKEN`.
|
||||
- Or **pick a long, unguessable topic name** (`hermes-7d4f9c8b-2026`) and treat it as the shared secret. This is the lightest setup but the topic name leaks via any logs or screenshots.
|
||||
|
||||
In all cases, do not put sensitive data through ntfy unless the underlying topic is access-controlled.
|
||||
|
||||
## Quick start — talk to your agent from your phone
|
||||
|
||||
1. Pick a topic name: `hermes-myname-2026`
|
||||
2. On your phone: install the [ntfy app](https://ntfy.sh/docs/subscribe/phone/), tap **+**, enter `hermes-myname-2026`
|
||||
3. On the host:
|
||||
```bash
|
||||
echo 'NTFY_TOPIC=hermes-myname-2026' >> ~/.hermes/.env
|
||||
echo 'NTFY_ALLOWED_USERS=hermes-myname-2026' >> ~/.hermes/.env
|
||||
hermes gateway restart
|
||||
```
|
||||
4. From the ntfy app, send a message to the topic. The agent's reply lands as a push notification.
|
||||
|
||||
## Using ntfy with cron jobs
|
||||
|
||||
Once `NTFY_HOME_CHANNEL` is set, cron jobs can deliver to ntfy:
|
||||
|
||||
```python
|
||||
cronjob(
|
||||
action="create",
|
||||
schedule="every 1h",
|
||||
deliver="ntfy", # uses NTFY_HOME_CHANNEL
|
||||
prompt="Check for alerts and summarise."
|
||||
)
|
||||
```
|
||||
|
||||
Or target a specific topic explicitly:
|
||||
|
||||
```python
|
||||
send_message(target="ntfy:alerts-channel", message="Done!")
|
||||
```
|
||||
|
||||
This works even when the cron runs out-of-process from the gateway — the plugin registers a `standalone_sender_fn` that opens its own HTTP connection.
|
||||
|
||||
## Self-hosting ntfy
|
||||
|
||||
If you want full control:
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
docker run -p 80:80 -it binwiederhier/ntfy serve
|
||||
|
||||
# Native
|
||||
go install heckel.io/ntfy/v2@latest
|
||||
ntfy serve
|
||||
```
|
||||
|
||||
Then point Hermes at it:
|
||||
|
||||
```
|
||||
NTFY_SERVER_URL=https://ntfy.mydomain.com
|
||||
NTFY_TOPIC=hermes
|
||||
NTFY_TOKEN=tk_abc123 # if you've set up access control
|
||||
```
|
||||
|
||||
Self-hosting gives you topic access control, message persistence policies, attachments, and emoji tags. See the [ntfy server docs](https://docs.ntfy.sh/install/).
|
||||
|
||||
## Markdown formatting
|
||||
|
||||
ntfy clients render markdown when the publisher sets the `X-Markdown: true` header. To enable for outgoing Hermes replies:
|
||||
|
||||
```
|
||||
NTFY_MARKDOWN=true
|
||||
```
|
||||
|
||||
Or in `config.yaml`:
|
||||
|
||||
```yaml
|
||||
platforms:
|
||||
ntfy:
|
||||
extra:
|
||||
markdown: true
|
||||
```
|
||||
|
||||
The mobile app supports a subset of CommonMark — bold, italic, lists, links, fenced code blocks. See [ntfy's markdown docs](https://docs.ntfy.sh/publish/#markdown-formatting) for the exact set.
|
||||
|
||||
## Outgoing-only setup (notifications without inbound)
|
||||
|
||||
If you only want Hermes to *push* notifications to ntfy (cron summaries, alerts) and never accept messages back, set both `NTFY_TOPIC` and `NTFY_PUBLISH_TOPIC` to the same value and skip `NTFY_ALLOWED_USERS` entirely. With no allowlist, the agent never responds to inbound messages — your phone gets the pushes, but the conversation is one-way.
|
||||
|
||||
## Limits
|
||||
|
||||
- **Message size**: ntfy caps message bodies at 4096 chars. Hermes truncates with a warning when this is exceeded.
|
||||
- **No typing indicators**: the protocol doesn't expose one; `send_typing` is a no-op.
|
||||
- **No threads or attachments**: ntfy is plain push notifications. Long replies stay in the message body, no thread fanout.
|
||||
- **No native user identity**: see the identity-model section above.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Auth failure / 401** — `NTFY_TOKEN` is wrong, or the token doesn't have publish/subscribe rights on this topic. The adapter halts its reconnect loop on 401 and the gateway runtime status will show `fatal: ntfy_unauthorized`. Fix the token and restart the gateway.
|
||||
|
||||
**Topic not found / 404** — `NTFY_TOPIC` doesn't exist on the configured server. For ntfy.sh, topics are auto-created on first publish, so a 404 means you're pointed at a self-hosted server that doesn't have the topic provisioned. The adapter halts its reconnect loop with `fatal: ntfy_topic_not_found`.
|
||||
|
||||
**Connected but no messages** — Check that `NTFY_ALLOWED_USERS` includes the topic name itself. With ntfy's identity model, the topic IS the user; leaving the allowlist empty rejects everything.
|
||||
|
||||
**Reconnects every 60s** — The stream keepalive default is 55s; ntfy may have intermittent network issues. The adapter applies exponential backoff (2 → 5 → 10 → 30 → 60s) and resets to 0 once a stream stays alive ≥60s.
|
||||
|
|
@ -9,17 +9,16 @@
|
|||
|
||||
## Install simplex-chat
|
||||
|
||||
Download the latest release from the [simplex-chat GitHub releases](https://github.com/simplex-chat/simplex-chat/releases) page, or via Docker:
|
||||
Download the latest release from the [simplex-chat GitHub releases](https://github.com/simplex-chat/simplex-chat/releases) page:
|
||||
|
||||
```bash
|
||||
# Linux / macOS binary
|
||||
curl -L https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-chat-ubuntu-22_04-x86-64 -o simplex-chat
|
||||
chmod +x simplex-chat
|
||||
|
||||
# Or Docker
|
||||
docker run -p 5225:5225 simplexchat/simplex-chat -p 5225
|
||||
```
|
||||
|
||||
The SimpleX Chat project does not publish a prebuilt Docker image for the chat client; to run it under Docker, build from source from the [simplex-chat repository](https://github.com/simplex-chat/simplex-chat).
|
||||
|
||||
## Start the daemon
|
||||
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ You set up the machine account *in the web app*, where your normal 2FA applies.
|
|||
|
||||
### 1. Create a machine account and access token
|
||||
|
||||
In the [Bitwarden web app](https://vault.bitwarden.com):
|
||||
In the [Bitwarden web app](https://vault.bitwarden.com) (or [vault.bitwarden.eu](https://vault.bitwarden.eu) for EU accounts):
|
||||
|
||||
1. Switch to **Secrets Manager** from the product switcher.
|
||||
2. Create or pick a **Project** (e.g. "Hermes keys").
|
||||
|
|
@ -41,9 +41,19 @@ It will:
|
|||
|
||||
1. Download and verify `bws v2.0.0` into `~/.hermes/bin/bws`.
|
||||
2. Prompt you for the access token (input is hidden). Stored in `~/.hermes/.env` as `BWS_ACCESS_TOKEN`.
|
||||
3. List the projects the machine account can see; pick one. Stored in `config.yaml` as `secrets.bitwarden.project_id`.
|
||||
4. Test-fetch the project's secrets and show you which env vars will resolve.
|
||||
5. Flip `secrets.bitwarden.enabled: true`.
|
||||
3. Ask which Bitwarden region your machine account belongs to — **US Cloud**, **EU Cloud**, or **self-hosted / custom URL**. Stored in `config.yaml` as `secrets.bitwarden.server_url` and passed to `bws` as `BWS_SERVER_URL`.
|
||||
4. List the projects the machine account can see; pick one. Stored in `config.yaml` as `secrets.bitwarden.project_id`.
|
||||
5. Test-fetch the project's secrets and show you which env vars will resolve.
|
||||
6. Flip `secrets.bitwarden.enabled: true`.
|
||||
|
||||
Non-interactive setup is also supported via flags:
|
||||
|
||||
```bash
|
||||
hermes secrets bitwarden setup \
|
||||
--access-token "$BWS_ACCESS_TOKEN" \
|
||||
--server-url https://vault.bitwarden.eu \
|
||||
--project-id <project-uuid>
|
||||
```
|
||||
|
||||
### 3. Confirm
|
||||
|
||||
|
|
@ -74,6 +84,7 @@ secrets:
|
|||
enabled: false
|
||||
access_token_env: BWS_ACCESS_TOKEN
|
||||
project_id: ""
|
||||
server_url: ""
|
||||
cache_ttl_seconds: 300
|
||||
override_existing: true
|
||||
auto_install: true
|
||||
|
|
@ -84,6 +95,7 @@ secrets:
|
|||
| `enabled` | `false` | Master switch. When false, Bitwarden is never contacted. |
|
||||
| `access_token_env` | `BWS_ACCESS_TOKEN` | Env var name that holds the bootstrap token. Change this if you already use `BWS_ACCESS_TOKEN` for something else. |
|
||||
| `project_id` | `""` | UUID of the project to sync from. |
|
||||
| `server_url` | `""` | Bitwarden region or self-hosted endpoint. Empty = `bws` default (US Cloud, `https://vault.bitwarden.com`). Set to `https://vault.bitwarden.eu` for EU Cloud, or your own URL for self-hosted. Plumbed into the `bws` subprocess as `BWS_SERVER_URL`. |
|
||||
| `cache_ttl_seconds` | `300` | How long an in-process fetch result is reused. Set to `0` to disable caching. Cache is per-process; new `hermes` invocations start fresh. |
|
||||
| `override_existing` | `true` | When true, Bitwarden values overwrite anything already in env (so rotation in the web app actually takes effect). Flip to `false` if you want `.env` / shell exports to win locally. |
|
||||
| `auto_install` | `true` | When true, `bws` is auto-downloaded into `~/.hermes/bin/` on first use. |
|
||||
|
|
@ -96,7 +108,8 @@ Bitwarden never blocks Hermes startup. If anything goes wrong, you'll see a one-
|
|||
|---|---|---|
|
||||
| `BWS_ACCESS_TOKEN is not set` | Enabled in config but token cleared from `.env` | Re-run `hermes secrets bitwarden setup` |
|
||||
| `bws exited 1: invalid access token` | Token revoked or wrong | Generate a new token, re-run setup |
|
||||
| `bws timed out` | Network blocked or Bitwarden API slow | Check connectivity to `api.bitwarden.com` |
|
||||
| `[400 Bad Request] {"error":"invalid_client"}` | Token is for a Bitwarden region other than the one `bws` is calling (e.g. EU token hitting the US identity endpoint) | Re-run setup and pick the right region, or set `secrets.bitwarden.server_url` to `https://vault.bitwarden.eu` (or your self-hosted URL) |
|
||||
| `bws timed out` | Network blocked or Bitwarden API slow | Check connectivity to `api.bitwarden.com` (or your `server_url`) |
|
||||
| `bws binary not available` | `auto_install: false` and `bws` not on PATH | Install manually from [github.com/bitwarden/sdk-sm/releases](https://github.com/bitwarden/sdk-sm/releases) or flip `auto_install` back on |
|
||||
| `Checksum mismatch` | Download corrupted or tampered | Re-run, will retry; if it persists, file an issue |
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ Top-to-bottom, in order:
|
|||
9. **Adds `%LOCALAPPDATA%\hermes\bin` to User PATH** — exposes the `hermes` command after you open a new terminal.
|
||||
10. **Runs `hermes setup`** — the normal first-run wizard (model, provider, toolsets). Skip with `-SkipSetup`.
|
||||
|
||||
:::tip Skip provider hunting on Windows
|
||||
Native Windows is still early beta, and per-tool API key setup (Firecrawl, FAL, Browser Use, OpenAI TTS) is the highest-friction part of getting a useful agent. A [Nous Portal](/docs/user-guide/features/tool-gateway) subscription covers the model **and** all of those tools through one OAuth login. After the installer finishes, run `hermes setup --portal` to wire everything up.
|
||||
:::
|
||||
|
||||
## Feature matrix
|
||||
|
||||
Everything except the dashboard's embedded terminal pane runs natively on Windows.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue