diff --git a/website/docs/developer-guide/adding-platform-adapters.md b/website/docs/developer-guide/adding-platform-adapters.md index 5bab2fc4bee3e..e89b2aefe956c 100644 --- a/website/docs/developer-guide/adding-platform-adapters.md +++ b/website/docs/developer-guide/adding-platform-adapters.md @@ -9,7 +9,7 @@ This guide covers adding a new messaging platform to the Hermes gateway. A platf :::tip There are two ways to add a platform: - **Plugin** (recommended for community/third-party): Drop a plugin directory into `~/.hermes/plugins/` — zero core code changes needed. See [Plugin Path](#plugin-path-recommended) below. -- **Built-in**: Modify 20+ files across code, config, and docs. Use the [Built-in Checklist](#step-by-step-checklist) below. +- **Built-in**: Modify 20+ files across code, config, and docs. Use the [Built-in Checklist](#step-by-step-checklist-built-in-path) below. ::: ## Architecture Overview diff --git a/website/docs/guides/cron-script-only.md b/website/docs/guides/cron-script-only.md index 06fa28800674a..963c57599031d 100644 --- a/website/docs/guides/cron-script-only.md +++ b/website/docs/guides/cron-script-only.md @@ -10,18 +10,10 @@ Sometimes you already know exactly what message you want to send. You don't need Hermes calls this **no-agent mode**. It's the cron system minus the LLM. -``` - ┌──────────────────┐ ┌──────────────────┐ - │ scheduler tick │ every │ run script │ - │ (every N minutes)│ ──────▶ │ (bash or python) │ - └──────────────────┘ └──────────────────┘ - │ - │ stdout - ▼ - ┌──────────────────┐ - │ delivery router │ - │ (telegram/disc…) │ - └──────────────────┘ +```mermaid +flowchart LR + tick["scheduler tick
(every N minutes)"] -->|every| script["run script
(bash or python)"] + script -->|stdout| router["delivery router
(telegram / discord / ...)"] ``` - **No LLM call.** Zero tokens, zero agent loop, zero model spend. @@ -242,5 +234,4 @@ For critical system-health watchdogs that must fire *even when the gateway is do - [Automate Anything with Cron](/docs/guides/automate-with-cron) — LLM-driven cron patterns. - [Scheduled Tasks (Cron) reference](/docs/user-guide/features/cron) — full schedule syntax, lifecycle, delivery routing. -- [Pipe Script Output with `hermes send`](/docs/guides/pipe-script-output) — the one-shot counterpart for ad-hoc scripts. - [Gateway Internals](/docs/developer-guide/gateway-internals) — delivery-router internals. diff --git a/website/docs/integrations/providers.md b/website/docs/integrations/providers.md index 1f7d0b403a19f..b9d8c46c755ac 100644 --- a/website/docs/integrations/providers.md +++ b/website/docs/integrations/providers.md @@ -1372,24 +1372,24 @@ provider_routing: **Shortcuts:** Append `:nitro` to any model name for throughput sorting (e.g., `anthropic/claude-sonnet-4:nitro`), or `:floor` for price sorting. -## Fallback Model +## Fallback Providers -Configure a backup provider:model that Hermes switches to automatically when your primary model fails (rate limits, server errors, auth failures): +Configure a backup provider:model chain that Hermes switches to automatically when your primary model fails (rate limits, server errors, auth failures): ```yaml -fallback_model: - provider: openrouter # required - model: anthropic/claude-sonnet-4 # required - # base_url: http://localhost:8000/v1 # optional, for custom endpoints - # key_env: MY_CUSTOM_KEY # optional, env var name for custom endpoint API key +fallback_providers: + - provider: openrouter # required + model: anthropic/claude-sonnet-4 # required + # base_url: http://localhost:8000/v1 # optional, for custom endpoints + # key_env: MY_CUSTOM_KEY # optional, env var name for custom endpoint API key ``` -When activated, the fallback swaps the model and provider mid-session without losing your conversation. It fires **at most once** per session. +When activated, the fallback swaps the model and provider mid-turn without losing your conversation. The primary model is restored for the next user message. Supported providers: `openrouter`, `nous`, `openai-codex`, `copilot`, `copilot-acp`, `anthropic`, `gemini`, `google-gemini-cli`, `qwen-oauth`, `huggingface`, `zai`, `kimi-coding`, `kimi-coding-cn`, `minimax`, `minimax-cn`, `minimax-oauth`, `deepseek`, `nvidia`, `xai`, `ollama-cloud`, `bedrock`, `ai-gateway`, `opencode-zen`, `opencode-go`, `kilocode`, `xiaomi`, `arcee`, `gmi`, `stepfun`, `alibaba`, `tencent-tokenhub`, `custom`. :::tip -Fallback is configured exclusively through `config.yaml` — there are no environment variables for it. For full details on when it triggers, supported providers, and how it interacts with auxiliary tasks and delegation, see [Fallback Providers](/docs/user-guide/features/fallback-providers). +Fallback is configured exclusively through `config.yaml` — there are no environment variables for it. The older top-level `fallback_model` object is still read for backward compatibility, but new configs should use `fallback_providers`. For full details on when it triggers, supported providers, and how it interacts with auxiliary tasks and delegation, see [Fallback Providers](/docs/user-guide/features/fallback-providers). ::: --- diff --git a/website/docs/user-guide/configuration.md b/website/docs/user-guide/configuration.md index b370c628e2aed..eff6d98773e7b 100644 --- a/website/docs/user-guide/configuration.md +++ b/website/docs/user-guide/configuration.md @@ -819,7 +819,7 @@ Available providers for auxiliary tasks: `auto`, `main`, plus any provider in th ::: :::warning `"main"` is for auxiliary tasks only -The `"main"` provider option means "use whatever provider my main agent uses" — it's only valid inside `auxiliary:`, `compression:`, and `fallback_model:` configs. It is **not** a valid value for your top-level `model.provider` setting. If you use a custom OpenAI-compatible endpoint, set `provider: custom` in your `model:` section. See [AI Providers](/docs/integrations/providers) for all main model provider options. +The `"main"` provider option means "use whatever provider my main agent uses" — it's only valid inside `auxiliary:`, `compression:`, and fallback-provider entries. It is **not** a valid value for your top-level `model.provider` setting. If you use a custom OpenAI-compatible endpoint, set `provider: custom` in your `model:` section. See [AI Providers](/docs/integrations/providers) for all main model provider options. ::: ### Full auxiliary config reference @@ -887,7 +887,7 @@ Each auxiliary task has a configurable `timeout` (in seconds). Defaults: vision ::: :::info -Context compression has its own `compression:` block for thresholds and an `auxiliary.compression:` block for model/provider settings — see [Context Compression](#context-compression) above. The fallback model uses a `fallback_model:` block — see [Fallback Model](/docs/integrations/providers#fallback-model). All three follow the same provider/model/base_url pattern. +Context compression has its own `compression:` block for thresholds and an `auxiliary.compression:` block for model/provider settings — see [Context Compression](#context-compression) above. The primary fallback chain uses top-level `fallback_providers:` — see [Fallback Providers](/docs/integrations/providers#fallback-providers). All three follow the same provider/model/base_url pattern. ::: ### Session Search Tuning @@ -936,7 +936,7 @@ AUXILIARY_VISION_MODEL=openai/gpt-4o ### Provider Options -These options apply to **auxiliary task configs** (`auxiliary:`, `compression:`, `fallback_model:`), not to your main `model.provider` setting. +These options apply to **auxiliary task configs** (`auxiliary:`, `compression:`) and fallback-provider entries, not to your main `model.provider` setting. | Provider | Description | Requirements | |----------|-------------|-------------| diff --git a/website/docs/user-guide/features/fallback-providers.md b/website/docs/user-guide/features/fallback-providers.md index df52eb1a66799..a75d1d3862de1 100644 --- a/website/docs/user-guide/features/fallback-providers.md +++ b/website/docs/user-guide/features/fallback-providers.md @@ -27,20 +27,20 @@ The easiest path is the interactive manager: hermes fallback ``` -`hermes fallback` reuses the provider picker from `hermes model` — same provider list, same credential prompts, same validation. Press `a` to add a fallback, `↑`/`↓` to reorder, `d` to remove, `q` to save and exit. Changes persist under `model.fallback_providers` in `config.yaml`. +`hermes fallback` reuses the provider picker from `hermes model` — same provider list, same credential prompts, same validation. Press `a` to add a fallback, `↑`/`↓` to reorder, `d` to remove, `q` to save and exit. Changes persist under top-level `fallback_providers` in `config.yaml`. -If you'd rather edit the YAML directly, add a `fallback_model` section to `~/.hermes/config.yaml`: +If you'd rather edit the YAML directly, add a top-level `fallback_providers` list to `~/.hermes/config.yaml`: ```yaml -fallback_model: - provider: openrouter - model: anthropic/claude-sonnet-4 +fallback_providers: + - provider: openrouter + model: anthropic/claude-sonnet-4 ``` -Both `provider` and `model` are **required**. If either is missing, the fallback is disabled. +Each entry requires both `provider` and `model`. Entries missing either value are ignored. :::note `fallback_model` vs `fallback_providers` -`fallback_model` (singular) is the legacy single-fallback key — Hermes still honors it for back-compat. `fallback_providers` (plural, list) supports multiple fallbacks tried in order; `hermes fallback` writes to this key. When both are set, Hermes merges them with `fallback_providers` taking priority. +`fallback_model` (singular) is the legacy single-fallback key — Hermes still honors it for back-compat. `fallback_providers` (plural, list) is the current format and supports multiple fallbacks tried in order; `hermes fallback` writes to this top-level key. When both are set, `fallback_providers` takes priority. ::: ### Supported Providers @@ -90,11 +90,11 @@ Both `provider` and `model` are **required**. If either is missing, the fallback For a custom OpenAI-compatible endpoint, add `base_url` and optionally `key_env`: ```yaml -fallback_model: - provider: custom - model: my-local-model - base_url: http://localhost:8000/v1 - key_env: MY_LOCAL_KEY # env var name containing the API key +fallback_providers: + - provider: custom + model: my-local-model + base_url: http://localhost:8000/v1 + key_env: MY_LOCAL_KEY # env var name containing the API key ``` ### When Fallback Triggers @@ -128,9 +128,9 @@ model: provider: anthropic default: claude-sonnet-4-6 -fallback_model: - provider: openrouter - model: anthropic/claude-sonnet-4 +fallback_providers: + - provider: openrouter + model: anthropic/claude-sonnet-4 ``` **Nous Portal as fallback for OpenRouter:** @@ -139,25 +139,25 @@ model: provider: openrouter default: anthropic/claude-opus-4 -fallback_model: - provider: nous - model: nous-hermes-3 +fallback_providers: + - provider: nous + model: nous-hermes-3 ``` **Local model as fallback for cloud:** ```yaml -fallback_model: - provider: custom - model: llama-3.1-70b - base_url: http://localhost:8000/v1 - key_env: LOCAL_API_KEY +fallback_providers: + - provider: custom + model: llama-3.1-70b + base_url: http://localhost:8000/v1 + key_env: LOCAL_API_KEY ``` **Codex OAuth as fallback:** ```yaml -fallback_model: - provider: openai-codex - model: gpt-5.3-codex +fallback_providers: + - provider: openai-codex + model: gpt-5.3-codex ``` ### Where Fallback Works @@ -171,7 +171,7 @@ fallback_model: | Auxiliary tasks (vision, compression) | ✘ (use their own provider chain — see below) | :::tip -There are no environment variables for `fallback_model` — it is configured exclusively through `config.yaml`. This is intentional: fallback configuration is a deliberate choice, not something a stale shell export should override. +There are no environment variables for `fallback_providers` — it is configured exclusively through `config.yaml`. This is intentional: fallback configuration is a deliberate choice, not something a stale shell export should override. ::: --- @@ -259,13 +259,13 @@ auxiliary: base_url: null # Custom OpenAI-compatible endpoint ``` -And the fallback model uses: +And the primary fallback chain uses: ```yaml -fallback_model: - provider: openrouter - model: anthropic/claude-sonnet-4 - # base_url: http://localhost:8000/v1 # Optional custom endpoint +fallback_providers: + - provider: openrouter + model: anthropic/claude-sonnet-4 + # base_url: http://localhost:8000/v1 # Optional custom endpoint ``` For `auxiliary.session_search`, Hermes also supports: @@ -287,11 +287,11 @@ auxiliary: If your provider does not support a native OpenAI-compatible reasoning-control field, `extra_body` will not help for that part; in that case `max_concurrency` is still useful for reducing request-burst 429s. -All three — auxiliary, compression, fallback — work the same way: set `provider` to pick who handles the request, `model` to pick which model, and `base_url` to point at a custom endpoint (overrides provider). +Auxiliary, compression, and each fallback entry use the same provider fields: set `provider` to pick who handles the request, `model` to pick which model, and `base_url` to point at a custom endpoint (overrides provider). ### Provider Options for Auxiliary Tasks -These options apply to `auxiliary:`, `compression:`, and `fallback_model:` configs only — `"main"` is **not** a valid value for your top-level `model.provider`. For custom endpoints, use `provider: custom` in your `model:` section (see [AI Providers](/docs/integrations/providers)). +These options apply to `auxiliary:`, `compression:`, and fallback-provider entries only — `"main"` is **not** a valid value for your top-level `model.provider`. For custom endpoints, use `provider: custom` in your `model:` section (see [AI Providers](/docs/integrations/providers)). | Provider | Description | Requirements | |----------|-------------|-------------| @@ -375,7 +375,7 @@ See [Scheduled Tasks (Cron)](/docs/user-guide/features/cron) for full configurat | Feature | Fallback Mechanism | Config Location | |---------|-------------------|----------------| -| Main agent model | `fallback_model` in config.yaml — per-turn failover on errors (primary restored each turn) | `fallback_model:` (top-level) | +| Main agent model | `fallback_providers` in config.yaml — per-turn failover on errors (primary restored each turn) | `fallback_providers:` (top-level) | | Vision | Auto-detection chain + internal OpenRouter retry | `auxiliary.vision` | | Web extraction | Auto-detection chain + internal OpenRouter retry | `auxiliary.web_extract` | | Context compression | Auto-detection chain, degrades to no-summary if unavailable | `auxiliary.compression` | diff --git a/website/docs/user-guide/features/kanban.md b/website/docs/user-guide/features/kanban.md index c82311538de6a..a48f037039714 100644 --- a/website/docs/user-guide/features/kanban.md +++ b/website/docs/user-guide/features/kanban.md @@ -447,25 +447,17 @@ Visually the target is the familiar Linear / Fusion layout: dark theme, column h The GUI is strictly a **read-through-the-DB + write-through-kanban_db** layer with no domain logic of its own: +```mermaid +flowchart TD + UI["React SPA plugin
HTML5 drag-and-drop"] + API["FastAPI router
plugins/kanban/dashboard/plugin_api.py"] + DB["~/.hermes/kanban.db
WAL, shared"] + + UI -->|REST over fetchJSON| API + API -->|writes call kanban_db.*
same code path CLI /kanban verbs use| DB + DB -->|append task_events| UI ``` -┌────────────────────────┐ WebSocket (tails task_events) -│ React SPA (plugin) │ ◀──────────────────────────────────┐ -│ HTML5 drag-and-drop │ │ -└──────────┬─────────────┘ │ - │ REST over fetchJSON │ - ▼ │ -┌────────────────────────┐ writes call kanban_db.* │ -│ FastAPI router │ directly — same code path │ -│ plugins/kanban/ │ the CLI /kanban verbs use │ -│ dashboard/plugin_api.py │ -└──────────┬─────────────┘ │ - │ │ - ▼ │ -┌────────────────────────┐ │ -│ ~/.hermes/kanban.db │ ───── append task_events ──────────┘ -│ (WAL, shared) │ -└────────────────────────┘ -``` + ### REST surface