diff --git a/website/docs/developer-guide/adding-platform-adapters.md b/website/docs/developer-guide/adding-platform-adapters.md index a695c1544d2..9e8340c8e11 100644 --- a/website/docs/developer-guide/adding-platform-adapters.md +++ b/website/docs/developer-guide/adding-platform-adapters.md @@ -34,11 +34,11 @@ The plugin system lets you add a platform adapter without modifying any core Her ``` ~/.hermes/plugins/my-platform/ - PLUGIN.yaml # Plugin metadata + plugin.yaml # Plugin metadata adapter.py # Adapter class + register() entry point ``` -### PLUGIN.yaml +### plugin.yaml Plugin metadata. The `requires_env` and `optional_env` blocks auto-populate `hermes config` UI entries (see [Surfacing Env Vars](#surfacing-env-vars-in-hermes-config) below). diff --git a/website/docs/developer-guide/agent-loop.md b/website/docs/developer-guide/agent-loop.md index 46a100c4766..da904d2ef0a 100644 --- a/website/docs/developer-guide/agent-loop.md +++ b/website/docs/developer-guide/agent-loop.md @@ -6,7 +6,7 @@ description: "Detailed walkthrough of AIAgent execution, API modes, tools, callb # Agent Loop Internals -The core orchestration engine is `run_agent.py`'s `AIAgent` class — a large file (~4,400 lines) that handles everything from prompt assembly to tool dispatch to provider failover. +The core orchestration engine is `run_agent.py`'s `AIAgent` class — a large file that handles everything from prompt assembly to tool dispatch to provider failover. ## Core Responsibilities diff --git a/website/docs/developer-guide/model-provider-plugin.md b/website/docs/developer-guide/model-provider-plugin.md index e720fb28082..7f020798520 100644 --- a/website/docs/developer-guide/model-provider-plugin.md +++ b/website/docs/developer-guide/model-provider-plugin.md @@ -250,7 +250,7 @@ The general `PluginManager` (the thing `hermes plugins` operates on) **sees** mo Like any Hermes plugin, model providers can ship as a pip package. Add an entry point to your `pyproject.toml`: ```toml -[project.entry-points."hermes.plugins"] +[project.entry-points."hermes_agent.plugins"] acme-inference = "acme_hermes_plugin:register" ``` diff --git a/website/docs/developer-guide/web-search-provider-plugin.md b/website/docs/developer-guide/web-search-provider-plugin.md index ba44af8f5f8..880cad8886e 100644 --- a/website/docs/developer-guide/web-search-provider-plugin.md +++ b/website/docs/developer-guide/web-search-provider-plugin.md @@ -43,7 +43,7 @@ plugins/web/my-backend/ ## The WebSearchProvider ABC -Subclass `agent.web_search_provider.WebSearchProvider`. The only required members are `name`, `is_available()`, and whichever of `search()` / `extract()` / `crawl()` you implement. +Subclass `agent.web_search_provider.WebSearchProvider`. The only required members are `name`, `is_available()`, and whichever of `search()` / `extract()` you implement. (Deep crawling is not a separate method — it's a mode of `extract()`.) ```python # plugins/web/my-backend/provider.py @@ -226,7 +226,7 @@ The `web_search` and `web_extract` tools live in `tools/web_tools.py`. At call t 1. Read the relevant config key (`web.search_backend` for `web_search`, `web.extract_backend` for `web_extract`) 2. Ask the registry for the provider with that `name` 3. Check `is_available()` and the matching `supports_*()` flag -4. Dispatch to `search()` / `extract()` / `crawl()`, awaiting if the method is a coroutine +4. Dispatch to `search()` / `extract()` (deep crawl runs as a mode inside `extract()`), awaiting if the method is a coroutine 5. JSON-serialize the response envelope and hand it back to the LLM Errors surface as the tool result; the LLM decides how to explain them. If no provider is registered (or every available one fails the capability gate), the tool returns a helpful error pointing at `hermes tools`. diff --git a/website/docs/guides/build-a-hermes-plugin.md b/website/docs/guides/build-a-hermes-plugin.md index 2e144c7e97a..4b037d52cb0 100644 --- a/website/docs/guides/build-a-hermes-plugin.md +++ b/website/docs/guides/build-a-hermes-plugin.md @@ -272,13 +272,18 @@ def register(ctx): **`dispatch_tool` example — a slash command that runs a tool:** ```python -def handle_scan(ctx, argstr): +def handle_scan(ctx, raw_args: str): """Implement /scan by invoking the terminal tool through the registry.""" - result = ctx.dispatch_tool("terminal", {"command": f"find . -name '{argstr}'"}) + result = ctx.dispatch_tool("terminal", {"command": f"find . -name '{raw_args}'"}) return result # returned to the caller's chat UI def register(ctx): - ctx.register_command("scan", handle_scan, help="Find files matching a glob") + # Handlers receive a single raw_args string; close over ctx via a lambda. + ctx.register_command( + "scan", + lambda raw: handle_scan(ctx, raw), + description="Find files matching a glob", + ) ``` The dispatched tool goes through the normal approval, redaction, and budget pipelines — it's a real tool invocation, not a shortcut around them. @@ -706,7 +711,7 @@ def register(ctx): After registration, users can type `/mystatus` in any session. The command appears in autocomplete, `/help` output, and the Telegram bot menu. -**Signature:** `ctx.register_command(name: str, handler: Callable, description: str = "")` +**Signature:** `ctx.register_command(name: str, handler: Callable, description: str = "", args_hint: str = "")` | Parameter | Type | Description | |-----------|------|-------------| @@ -896,12 +901,16 @@ class MyMemoryProvider(MemoryProvider): def initialize(self, session_id: str, **kwargs) -> None: self._session_id = session_id - def sync_turn(self, user_message, assistant_response, **kwargs) -> None: + def sync_turn(self, user_content, assistant_content, *, + session_id="", messages=None) -> None: ... - def prefetch(self, query: str, **kwargs) -> str | None: + def prefetch(self, query, *, session_id="") -> str: ... + def get_tool_schemas(self) -> list[dict]: + return [] # required @abstractmethod — see full guide + def register(ctx): ctx.register_memory_provider(MyMemoryProvider()) ``` @@ -921,8 +930,9 @@ class MyContextEngine(ContextEngine): def name(self) -> str: return "my-engine" - def should_compress(self, messages, model) -> bool: ... - def compress(self, messages, model) -> list[dict]: ... + def update_from_response(self, usage) -> None: ... + def should_compress(self, prompt_tokens: int = None) -> bool: ... + def compress(self, messages, current_tokens=None, focus_topic=None) -> list: ... def register(ctx): ctx.register_context_engine(MyContextEngine()) @@ -946,7 +956,9 @@ class MyImageGenProvider(ImageGenProvider): return "my-imggen" def is_available(self) -> bool: ... - def generate(self, prompt: str, **kwargs) -> str: ... # returns image path + def generate(self, prompt: str, aspect_ratio="landscape", **kwargs) -> dict: + # returns success_response(...) / error_response(...) + ... def register(ctx): ctx.register_image_gen_provider(MyImageGenProvider()) diff --git a/website/docs/integrations/index.md b/website/docs/integrations/index.md index 4e00a5600c7..e3389b33abd 100644 --- a/website/docs/integrations/index.md +++ b/website/docs/integrations/index.md @@ -26,20 +26,24 @@ Hermes supports multiple AI inference providers out of the box. Use `hermes mode ## Web Search Backends -The `web_search` and `web_extract` tools support four backend providers, configured via `config.yaml` or `hermes tools`: +The `web_search` and `web_extract` tools support eight backend providers, configured via `config.yaml` or `hermes tools`: | Backend | Env Var | Search | Extract | Crawl | |---------|---------|--------|---------|-------| | **Firecrawl** (default) | `FIRECRAWL_API_KEY` | ✔ | ✔ | ✔ | -| **Parallel** | `PARALLEL_API_KEY` | ✔ | ✔ | — | +| **SearXNG** | `SEARXNG_URL` | ✔ | — | — | +| **Brave** (free tier) | `BRAVE_SEARCH_API_KEY` | ✔ | — | — | +| **DuckDuckGo** (ddgs) | _(none)_ | ✔ | — | — | | **Tavily** | `TAVILY_API_KEY` | ✔ | ✔ | ✔ | | **Exa** | `EXA_API_KEY` | ✔ | ✔ | — | +| **Parallel** | `PARALLEL_API_KEY` | ✔ | ✔ | — | +| **xAI** | `XAI_API_KEY` | ✔ | — | — | Quick setup example: ```yaml web: - backend: firecrawl # firecrawl | parallel | tavily | exa + backend: firecrawl # firecrawl | searxng | brave-free | ddgs | tavily | exa | parallel | xai ``` If `web.backend` is not set, the backend is auto-detected from whichever API key is available. Self-hosted Firecrawl is also supported via `FIRECRAWL_API_URL`. diff --git a/website/docs/integrations/nous-portal.md b/website/docs/integrations/nous-portal.md index cd1ceff06ea..1be857b350e 100644 --- a/website/docs/integrations/nous-portal.md +++ b/website/docs/integrations/nous-portal.md @@ -133,6 +133,7 @@ If you use [Hermes profiles](/user-guide/profiles), the Portal refresh token is ```bash hermes portal # log in to Nous Portal + set it up (one-shot onboarding) hermes portal info # login status, subscription info, model + gateway routing +hermes portal status # alias for `portal info` hermes portal tools # detailed Tool Gateway catalog with per-tool routing hermes portal open # open the subscription management page in your browser ``` diff --git a/website/docs/integrations/providers.md b/website/docs/integrations/providers.md index 9673165c8d3..6ab24d0a421 100644 --- a/website/docs/integrations/providers.md +++ b/website/docs/integrations/providers.md @@ -494,7 +494,7 @@ Step-series models via [StepFun](https://platform.stepfun.com) — OpenAI-compat ```bash # StepFun -hermes chat --provider stepfun --model step-3-mini +hermes chat --provider stepfun --model step-3.5-flash # Requires: STEPFUN_API_KEY in ~/.hermes/.env ``` @@ -502,7 +502,7 @@ Or set it permanently in `config.yaml`: ```yaml model: provider: "stepfun" - default: "step-3-mini" + default: "step-3.5-flash" ``` The base URL can be overridden with `STEPFUN_BASE_URL` (default: `https://api.stepfun.com/v1`). diff --git a/website/docs/reference/cli-commands.md b/website/docs/reference/cli-commands.md index 7c37e9d8144..790b4bd35bb 100644 --- a/website/docs/reference/cli-commands.md +++ b/website/docs/reference/cli-commands.md @@ -100,7 +100,7 @@ Common options: | `-q`, `--query "..."` | One-shot, non-interactive prompt. | | `-m`, `--model ` | Override the model for this run. | | `-t`, `--toolsets ` | Enable a comma-separated set of toolsets. | -| `--provider ` | Force a provider: `auto`, `openrouter`, `nous`, `openai-codex`, `copilot-acp`, `copilot`, `anthropic`, `gemini`, `google-gemini-cli`, `huggingface`, `novita`, `zai`, `kimi-coding`, `kimi-coding-cn`, `minimax`, `minimax-cn`, `minimax-oauth`, `kilocode`, `xiaomi`, `arcee`, `gmi`, `alibaba`, `alibaba-coding-plan` (alias `alibaba_coding`), `deepseek`, `nvidia`, `ollama-cloud`, `xai` (alias `grok`), `xai-oauth` (alias `grok-oauth`), `qwen-oauth`, `bedrock`, `opencode-zen`, `opencode-go`, `azure-foundry`, `lmstudio`, `stepfun`, `tencent-tokenhub` (alias `tencent`, `tokenhub`). | +| `--provider ` | Force a provider: `auto`, `openrouter`, `nous`, `openai-codex`, `copilot-acp`, `copilot`, `anthropic`, `gemini`, `google-gemini-cli`, `huggingface`, `novita` (aliases `novita-ai`, `novitaai`), `openai-api`, `zai`, `kimi-coding`, `kimi-coding-cn`, `minimax`, `minimax-cn`, `minimax-oauth`, `kilocode`, `xiaomi`, `arcee`, `gmi`, `alibaba`, `alibaba-coding-plan` (alias `alibaba_coding`), `deepseek`, `nvidia`, `ollama-cloud`, `xai` (alias `grok`), `xai-oauth` (alias `grok-oauth`), `qwen-oauth`, `bedrock`, `opencode-zen`, `opencode-go`, `azure-foundry`, `lmstudio`, `stepfun`, `tencent-tokenhub` (alias `tencent`, `tokenhub`). | | `-s`, `--skills ` | Preload one or more skills for the session (can be repeated or comma-separated). | | `-v`, `--verbose` | Verbose output. | | `-Q`, `--quiet` | Programmatic mode: suppress banner/spinner/tool previews. | diff --git a/website/docs/reference/environment-variables.md b/website/docs/reference/environment-variables.md index 011fa3bcf79..cfd3001e247 100644 --- a/website/docs/reference/environment-variables.md +++ b/website/docs/reference/environment-variables.md @@ -20,6 +20,8 @@ All variables go in `~/.hermes/.env`. You can also set them with `hermes config | `NOUS_INFERENCE_BASE_URL` | Override Nous inference endpoint directly | | `OPENAI_API_KEY` | API key for custom OpenAI-compatible endpoints (used with `OPENAI_BASE_URL`) | | `OPENAI_BASE_URL` | Base URL for custom endpoint (VLLM, SGLang, etc.) | +| `LM_API_KEY` | API key for LM Studio (`lmstudio` provider). Often a placeholder for local servers | +| `LM_BASE_URL` | LM Studio base URL (default: `http://localhost:1234/v1`) | | `COPILOT_GITHUB_TOKEN` | GitHub token for Copilot API — first priority (OAuth `gho_*` or fine-grained PAT `github_pat_*`; classic PATs `ghp_*` are **not supported**) | | `GH_TOKEN` | GitHub token — second priority for Copilot (also used by `gh` CLI) | | `GITHUB_TOKEN` | GitHub token — third priority for Copilot | @@ -27,11 +29,13 @@ All variables go in `~/.hermes/.env`. You can also set them with `hermes config | `COPILOT_CLI_PATH` | Alias for `HERMES_COPILOT_ACP_COMMAND` | | `HERMES_COPILOT_ACP_ARGS` | Override Copilot ACP arguments (default: `--acp --stdio`) | | `COPILOT_ACP_BASE_URL` | Override Copilot ACP base URL | +| `COPILOT_API_BASE_URL` | Override the Copilot API base URL (`copilot` provider) | | `GLM_API_KEY` | z.ai / ZhipuAI GLM API key ([z.ai](https://z.ai)) | | `ZAI_API_KEY` | Alias for `GLM_API_KEY` | | `Z_AI_API_KEY` | Alias for `GLM_API_KEY` | | `GLM_BASE_URL` | Override z.ai base URL (default: `https://api.z.ai/api/paas/v4`) | | `KIMI_API_KEY` | Kimi / Moonshot AI API key ([moonshot.ai](https://platform.moonshot.ai)) | +| `KIMI_CODING_API_KEY` | Alias key for the `kimi-coding` provider (accepted alongside `KIMI_API_KEY`) | | `KIMI_BASE_URL` | Override Kimi base URL (default: `https://api.moonshot.ai/v1`) | | `KIMI_CN_API_KEY` | Kimi / Moonshot China API key ([moonshot.cn](https://platform.moonshot.cn)) | | `ARCEEAI_API_KEY` | Arcee AI API key ([chat.arcee.ai](https://chat.arcee.ai/)) | @@ -67,9 +71,12 @@ All variables go in `~/.hermes/.env`. You can also set them with `hermes config | `HERMES_GEMINI_CLIENT_SECRET` | OAuth client secret for `google-gemini-cli` (optional) | | `HERMES_GEMINI_PROJECT_ID` | GCP project ID for paid Gemini tiers (free tier auto-provisions) | | `ANTHROPIC_API_KEY` | Anthropic Console API key ([console.anthropic.com](https://console.anthropic.com/)) | +| `ANTHROPIC_BASE_URL` | Override the Anthropic API base URL | | `ANTHROPIC_TOKEN` | Manual or legacy Anthropic OAuth/setup-token override | | `DASHSCOPE_API_KEY` | Qwen Cloud (Alibaba DashScope) API key for Qwen models ([modelstudio.console.alibabacloud.com](https://modelstudio.console.alibabacloud.com/)) | | `DASHSCOPE_BASE_URL` | Custom DashScope base URL (default: `https://dashscope-intl.aliyuncs.com/compatible-mode/v1`; use `https://dashscope.aliyuncs.com/compatible-mode/v1` for mainland-China region) | +| `ALIBABA_CODING_PLAN_API_KEY` | Qwen Coding Plan API key (`alibaba-coding-plan` provider) | +| `ALIBABA_CODING_PLAN_BASE_URL` | Override the Qwen Coding Plan base URL | | `DEEPSEEK_API_KEY` | DeepSeek API key for direct DeepSeek access ([platform.deepseek.com](https://platform.deepseek.com/api_keys)) | | `DEEPSEEK_BASE_URL` | Custom DeepSeek API base URL | | `NOVITA_API_KEY` | NovitaAI API key — AI-native cloud for Model API, Agent Sandbox, and GPU Cloud ([novita.ai/settings/key-management](https://novita.ai/settings/key-management)) | diff --git a/website/docs/reference/faq.md b/website/docs/reference/faq.md index d3db90f03b5..36665410a49 100644 --- a/website/docs/reference/faq.md +++ b/website/docs/reference/faq.md @@ -30,7 +30,15 @@ Set your provider with `hermes model` or by editing `~/.hermes/.env`. See the [E ### Does it work on Windows? -**Not natively.** Hermes Agent requires a Unix-like environment. On Windows, install [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) and run Hermes from inside it. The standard install command works perfectly in WSL2: +**Yes, natively.** Hermes supports native Windows via the PowerShell installer — no WSL required. Run in PowerShell: + +```powershell +iex (irm https://hermes-agent.nousresearch.com/install.ps1) +``` + +The installer provisions a PortableGit that backs the terminal tool's shell. See the [Windows (Native) Guide](../user-guide/windows-native.md) for details. + +WSL2 remains a fully supported alternative. To run Hermes inside WSL2, install [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) and use the standard install command: ```bash curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash diff --git a/website/docs/reference/model-catalog.md b/website/docs/reference/model-catalog.md index 3393ffeebfd..4e44543354f 100644 --- a/website/docs/reference/model-catalog.md +++ b/website/docs/reference/model-catalog.md @@ -69,7 +69,7 @@ Cache location: `~/.hermes/cache/model_catalog.json`. model_catalog: enabled: true url: https://hermes-agent.nousresearch.com/docs/api/model-catalog.json - ttl_hours: 24 + ttl_hours: 1 providers: {} ``` diff --git a/website/docs/reference/profile-commands.md b/website/docs/reference/profile-commands.md index c02da55cfd4..922de3790cf 100644 --- a/website/docs/reference/profile-commands.md +++ b/website/docs/reference/profile-commands.md @@ -19,6 +19,7 @@ Top-level command for managing profiles. Running `hermes profile` without a subc | `list` | List all profiles. | | `use` | Set the active (default) profile. | | `create` | Create a new profile. | +| `describe` | Read or set a profile's description (used by the kanban orchestrator for routing). | | `delete` | Delete a profile. | | `show` | Show details about a profile. | | `alias` | Regenerate the shell alias for a profile. | diff --git a/website/docs/reference/slash-commands.md b/website/docs/reference/slash-commands.md index 737bc3a2a7a..44a9a303a62 100644 --- a/website/docs/reference/slash-commands.md +++ b/website/docs/reference/slash-commands.md @@ -101,6 +101,7 @@ Type `/` in the CLI to open the autocomplete menu. Built-in commands are case-in | Command | Description | |---------|-------------| | `/help` | Show this help message | +| `/version` | Show Hermes Agent version, build, and environment info. | | `/usage` | Show token usage, cost breakdown, session duration, and — when available from the active provider — an **Account limits** section with remaining quota / credits / plan usage pulled live from the provider's API. | | `/insights` | Show usage insights and analytics (last 30 days) | | `/platforms` (alias: `/gateway`) | Show gateway/messaging platform status (CLI-only summary view). | @@ -238,7 +239,7 @@ The messaging gateway supports the following built-in commands inside Telegram, - `/skin`, `/snapshot`, `/gquota`, `/reload`, `/tools`, `/toolsets`, `/browser`, `/config`, `/cron`, `/skills`, `/platforms`, `/paste`, `/image`, `/statusbar`, `/plugins`, `/busy`, `/indicator`, `/redraw`, `/clear`, `/history`, `/save`, `/copy`, `/handoff`, and `/quit` are **CLI-only** commands. - `/verbose` is **CLI-only by default**, but can be enabled for messaging platforms by setting `display.tool_progress_command: true` in `config.yaml`. When enabled, it cycles the `display.tool_progress` mode and saves to config. - `/sethome`, `/update`, `/restart`, `/approve`, `/deny`, `/topic`, and `/commands` are **messaging-only** commands. -- `/status`, `/background`, `/queue`, `/steer`, `/voice`, `/reload-mcp`, `/reload-skills`, `/rollback`, `/debug`, `/fast`, `/footer`, `/curator`, `/kanban`, `/sessions`, and `/yolo` work in **both** the CLI and the messaging gateway. +- `/status`, `/version`, `/background`, `/queue`, `/steer`, `/voice`, `/reload-mcp`, `/reload-skills`, `/rollback`, `/debug`, `/fast`, `/footer`, `/curator`, `/kanban`, `/sessions`, and `/yolo` work in **both** the CLI and the messaging gateway. - `/voice join`, `/voice channel`, and `/voice leave` are only meaningful on Discord. - In the TUI, `/sessions` shows live sessions in the current TUI process. Use `/resume [name]` or `hermes --tui --resume ` for saved or closed transcripts. diff --git a/website/docs/reference/tools-reference.md b/website/docs/reference/tools-reference.md index bc0f62043f2..2393a9db7d1 100644 --- a/website/docs/reference/tools-reference.md +++ b/website/docs/reference/tools-reference.md @@ -8,7 +8,7 @@ description: "Authoritative reference for Hermes built-in tools, grouped by tool This page documents Hermes' built-in tools, grouped by toolset. Availability varies by platform, credentials, and enabled toolsets. -**Quick counts (current registry):** ~64 tools — 10 browser tools (core) + 2 CDP-gated browser tools, 4 file tools, 4 Home Assistant tools, 2 terminal tools, 2 web tools, 5 Feishu tools, 7 Spotify tools (registered by the bundled `spotify` plugin), 5 Yuanbao tools, 9 kanban tools (registered when the kanban dispatcher spawns the agent), 2 Discord tools, and a handful of standalone tools (`memory`, `clarify`, `delegate_task`, `execute_code`, `cronjob`, `session_search`, `skill_view`/`skill_manage`/`skills_list`, `text_to_speech`, `image_generate`, `video_generate`, `vision_analyze`, `video_analyze`, `mixture_of_agents`, `send_message`, `todo`, `computer_use`, `process`). +**Quick counts (current registry):** ~71 tools — 10 browser tools (core) + 2 CDP-gated browser tools, 4 file tools, 4 Home Assistant tools, 2 terminal tools, 2 web tools, 5 Feishu tools, 7 Spotify tools (registered by the bundled `spotify` plugin), 5 Yuanbao tools, 9 kanban tools (registered when the kanban dispatcher spawns the agent), 2 Discord tools, and a handful of standalone tools (`memory`, `clarify`, `delegate_task`, `execute_code`, `cronjob`, `session_search`, `skill_view`/`skill_manage`/`skills_list`, `text_to_speech`, `image_generate`, `video_generate`, `vision_analyze`, `video_analyze`, `mixture_of_agents`, `send_message`, `todo`, `computer_use`, `process`). :::tip MCP Tools In addition to built-in tools, Hermes can load tools dynamically from MCP servers. MCP tools appear with the prefix `mcp__` (e.g., `mcp_github_create_issue` for the `github` MCP server). See [MCP Integration](/user-guide/features/mcp) for configuration. diff --git a/website/docs/reference/toolsets-reference.md b/website/docs/reference/toolsets-reference.md index 831416dd026..bba5a491f03 100644 --- a/website/docs/reference/toolsets-reference.md +++ b/website/docs/reference/toolsets-reference.md @@ -65,6 +65,7 @@ Or in-session: | `file` | `patch`, `read_file`, `search_files`, `write_file` | File reading, writing, searching, and editing. | | `homeassistant` | `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services` | Smart home control via Home Assistant. Only available when `HASS_TOKEN` is set. | | `computer_use` | `computer_use` | Background macOS desktop control via cua-driver — does not steal cursor/focus. Works with any tool-capable model. macOS only; requires `cua-driver` on `$PATH`. | +| `context_engine` | (varies) | Runtime tools exposed by the active context-engine plugin (empty until a plugin populates it). | | `image_gen` | `image_generate` | Text-to-image generation via FAL.ai (with opt-in OpenAI / xAI backends). | | `video_gen` | `video_generate` | Text-to-video and image-to-video via plugin-registered backends (xAI Grok-Imagine, FAL.ai Veo 3.1 / Pixverse v6 / Kling O3). Pass `image_url` to animate an image; omit it for text-to-video. | | `kanban` | `kanban_block`, `kanban_comment`, `kanban_complete`, `kanban_create`, `kanban_heartbeat`, `kanban_link`, `kanban_list`, `kanban_show`, `kanban_unblock` | Multi-agent coordination tools. Registered for dispatcher-spawned task workers (`HERMES_KANBAN_TASK`) and for profiles that explicitly list the `kanban` toolset by name (the `all`/`*` wildcard does **not** enable it). Workers mark tasks done, block, heartbeat, comment, and create/link follow-up tasks; orchestrator profiles additionally get board-routing tools like list/unblock. | diff --git a/website/docs/user-guide/cli.md b/website/docs/user-guide/cli.md index 71d1c14af1e..7bbc1fe6ec5 100644 --- a/website/docs/user-guide/cli.md +++ b/website/docs/user-guide/cli.md @@ -48,7 +48,7 @@ hermes chat --verbose # Isolated git worktree (for running multiple agents in parallel) hermes -w # Interactive mode in worktree -hermes -w -q "Fix issue #123" # Single query in worktree +hermes -w -z "Fix issue #123" # Single query in worktree ``` ## Interface Layout diff --git a/website/docs/user-guide/configuration.md b/website/docs/user-guide/configuration.md index 32d707e0852..907e2d90ea7 100644 --- a/website/docs/user-guide/configuration.md +++ b/website/docs/user-guide/configuration.md @@ -1250,7 +1250,7 @@ Set `file_mutation_verifier: false` (or `HERMES_FILE_MUTATION_VERIFIER=0`) to su The `display.language` setting translates a small set of static user-facing messages — the CLI approval prompt, a handful of gateway slash-command replies (e.g. restart-drain notices, "approval expired", "goal cleared"). It does **not** translate agent responses, log lines, tool output, error tracebacks, or slash-command descriptions — those stay in English. If you want the agent itself to reply in another language, just tell it in your prompt or system message. -Supported values: `en` (default), `zh` (Simplified Chinese), `ja` (Japanese), `de` (German), `es` (Spanish), `fr` (French), `tr` (Turkish), `uk` (Ukrainian). Unknown values fall back to English. +Supported values: `en` (default), `zh` (Simplified Chinese), `zh-hant` (Traditional Chinese), `ja` (Japanese), `de` (German), `es` (Spanish), `fr` (French), `tr` (Turkish), `uk` (Ukrainian), `af` (Afrikaans), `ko` (Korean), `it` (Italian), `ga` (Irish), `pt` (Portuguese), `ru` (Russian), `hu` (Hungarian). Unknown values fall back to English. You can also set this per-session with the `HERMES_LANGUAGE` env var, which overrides the config value. @@ -1411,8 +1411,8 @@ For separate natural mid-turn assistant updates without progressive token editin **Fresh final (Telegram):** Telegram's `editMessageText` preserves the original message timestamp, so a long-running streamed reply would keep the first-token timestamp even after completion. When `fresh_final_after_seconds > 0` (default `60`), the completed reply is delivered as a brand-new message (with the stale preview best-effort deleted) so Telegram's visible timestamp reflects completion time. Short previews still finalize in place. Set to `0` to always edit in place. -:::note -Streaming is disabled by default. Enable it in `~/.hermes/config.yaml` to try the streaming UX. +:::note Per-platform streaming defaults +The master `streaming.enabled` switch is `false` by default — nothing streams until you flip it. Once enabled, streaming is decided **per platform**: Telegram ships with `display.platforms.telegram.streaming: true` (streams) and Discord with `display.platforms.discord.streaming: false` (does not). So after enabling streaming, Telegram streams out of the box and Discord stays on whole-message replies until you change its toggle. You can adjust these per-platform switches from the dashboard's **Channels** toggles or directly in `~/.hermes/config.yaml`. ::: ## Group Chat Session Isolation diff --git a/website/docs/user-guide/configuring-models.md b/website/docs/user-guide/configuring-models.md index 018203143a6..3368d5201d8 100644 --- a/website/docs/user-guide/configuring-models.md +++ b/website/docs/user-guide/configuring-models.md @@ -49,7 +49,7 @@ Pick a model, hit **Switch**, and Hermes writes it to `~/.hermes/config.yaml` un ## Setting auxiliary models -Click **Show auxiliary** to reveal the eight task slots: +Click **Show auxiliary** to reveal the 11 task slots: ![Auxiliary panel expanded](/img/docs/dashboard-models/auxiliary-expanded.png) @@ -66,6 +66,10 @@ Every auxiliary task defaults to `auto` — meaning Hermes uses your main model | **Web Extract** | When you use `web_extract` heavily. Same logic as compression — summarization doesn't need reasoning. | | **Skills Hub** | `hermes skills search` uses this. Usually fine at `auto`. | | **MCP** | MCP tool routing. Usually fine at `auto`. | +| **Triage Specifier** | Routes the Kanban triage specifier (`hermes kanban specify`) that expands a rough one-liner into a concrete spec. A cheap, capable model works well. | +| **Kanban Decomposer** | Routes Kanban task decomposition — splits a triage task into a graph of child tasks for specialist profiles. | +| **Profile Describer** | Routes profile-description generation (`hermes profile describe --auto` / the dashboard auto-generate button). Short, cheap call. | +| **Curator** | Routes the curator skill-usage review pass. Can run for minutes on reasoning models, so a cheaper aux model is often worthwhile. | ### Per-task override @@ -84,7 +88,7 @@ Every model card on the page has a **Use as** dropdown. This is the fast path The dropdown has: - **Main model** — same as clicking Change on the main row. -- **All auxiliary tasks** — assigns this model to all 8 aux slots at once. Useful when you just want every side-job on a cheap flash model. +- **All auxiliary tasks** — assigns this model to all 11 aux slots at once. Useful when you just want every side-job on a cheap flash model. - **Individual task options** — Vision, Web Extract, Compression, etc. The currently-assigned model for each task is marked `current`. Cards are badged with `main` or `aux · ` when they're currently assigned to something — so you can see at a glance which of your historical models are wired in where. diff --git a/website/docs/user-guide/desktop.md b/website/docs/user-guide/desktop.md index f0fb2dddab3..9c095c5e099 100644 --- a/website/docs/user-guide/desktop.md +++ b/website/docs/user-guide/desktop.md @@ -44,6 +44,14 @@ The center of the app. You get: - **The same conversation history** as every other Hermes surface — sessions started here resume in the CLI/TUI and vice versa. - **Drag-and-drop files** anywhere in the chat area to attach them to your next message. - **A right-hand preview rail** — render web pages, files, and tool outputs side by side while you keep chatting. +- **Composer history and queue editing** — press the up/down arrow keys in an empty composer to recall and reuse previous prompts, and edit messages you've queued up before they're sent. + +#### Status bar + +The bar along the bottom of the chat shows live session state and exposes quick controls without opening Settings: + +- **Inline model picker** — switch the model for the active session straight from the status bar. +- **Per-session YOLO toggle** — flip YOLO on or off for just this session (matching the TUI). YOLO bypasses the dangerous-command approval prompts, so know what you're turning off — see [Security → YOLO Mode](./security.md#yolo-mode). Chatting against a Hermes instance on another machine instead of the bundled local backend? See [Connecting to a remote backend](#connecting-to-a-remote-backend) below — and for the full picture of how the remote-hosted dashboard connection works (the auth gate, the `/api/ws` chat socket, and WebSocket close-code triage), see [Web Dashboard → Connecting Hermes Desktop to a remote backend](./features/web-dashboard.md#connecting-hermes-desktop-to-a-remote-backend). @@ -59,6 +67,14 @@ Talk to Hermes and hear it back, the same [voice mode](./features/voice-mode.md) Manage providers, models, tools, and credentials from a real UI instead of editing YAML. First-run onboarding gets you to your first message in seconds. The settings panes cover providers/keys, model selection, toolset configuration, MCP servers, the gateway, and session management. +- **Providers settings pane** — a dedicated place to manage inference providers, with an Accounts / API-keys UX for signing in and storing credentials per provider. +- **Every provider and model in the menus** — the GUI surfaces the full provider list and every model that `hermes model` knows about, so you pick from the same catalog the CLI sees rather than a curated subset. +- **xAI Grok OAuth** — Grok is a first-class OAuth provider in the launcher; sign in through the browser flow like the other OAuth providers. +- **Tool-backend installs from the GUI** — run a tool backend's post-setup install steps directly from the app instead of dropping to a terminal. +- **Auxiliary-model warning** — if you switch the main model to a new provider while auxiliary tasks (titling, summarization, and similar helpers) are still pinned to another provider, the app warns you so you don't unknowingly split work across two providers. + +First-run onboarding has been redesigned on a unified overlay design system, and you can pick **Choose provider later** to skip provider setup and get into the app first. + ### Management panes The app also surfaces the broader Hermes management surface so you don't have to drop to a terminal: @@ -69,6 +85,19 @@ The app also surfaces the broader Hermes management surface so you don't have to - **Messaging** — set up gateway channels. - **Agents** and **Command Center** — orchestration surfaces for multi-agent work. +### Keyboard & navigation + +- **Command palette** — press **Cmd+K** (Ctrl+K on Windows/Linux) to jump to actions and navigate the app from the keyboard. +- **Rebindable shortcuts** — a shortcuts panel in Settings lets you remap the app's keyboard shortcuts to your own keys. +- **Custom zoom shortcuts** — zoom the interface in half-step increments for finer control over text size. +- **UI language switcher** — change the app's interface language in-app, including Simplified Chinese (zh-Hans). + +### Sessions & profiles + +- **Session-list overhaul** — a reworked session list with archiving and general session hygiene to keep the list manageable as it grows. +- **Search sessions by id** — find a specific session directly by its id. +- **Concurrent multi-profile sessions** — run sessions across multiple [profiles](./profiles.md) at the same time, and reference a session in another profile with cross-profile `@session` links. + ## Updating The app checks for updates in the background and offers a one-click update when one is ready. @@ -170,6 +199,10 @@ The dashboard reads and writes your `.env` (API keys, secrets) and can run agent You can also set the backend URL without the UI via the `HERMES_DESKTOP_REMOTE_URL` environment variable before launching the app (it overrides the in-app setting); you still sign in from the Gateway settings panel. +:::note Per-profile remote hosts +The remote gateway host is configured per [profile](./profiles.md), so each profile can point at its own remote backend (or stay on its local one). Switching profiles switches which remote host the app connects to. +::: + ### Troubleshooting - **Sign-in fails with 401 / "Invalid credentials"** — the username or password doesn't match the backend's `HERMES_DASHBOARD_BASIC_AUTH_USERNAME` / `HERMES_DASHBOARD_BASIC_AUTH_PASSWORD`. The backend returns the same generic error for an unknown user and a wrong password (no enumeration oracle), so double-check both. Confirm the gate is on with `curl -s http://:9119/api/status | jq '.auth_required, .auth_providers'` — it should report `true` and include `"basic"`. diff --git a/website/docs/user-guide/docker.md b/website/docs/user-guide/docker.md index f564461b2cb..cebfbf397f5 100644 --- a/website/docs/user-guide/docker.md +++ b/website/docs/user-guide/docker.md @@ -132,7 +132,7 @@ If no provider is registered and the bind is non-loopback, the dashboard **fails Opting out of the OAuth gate serves the dashboard's API surface (including model keys and session data) to anyone who can reach the published port. Only enable it when you have your own auth layer in front, or on a trusted LAN you fully control. ::: -Running the dashboard as a separate container is not supported: its gateway-liveness detection requires a shared PID namespace with the gateway process. +Running the dashboard as a separate container **is** supported when that container shares the host PID and network namespace (e.g. `network_mode: host`, as the repo's own `docker-compose.yml` does — see its `dashboard` service). Its gateway-liveness detection requires a shared PID namespace with the gateway process, so the limitation only applies to dashboards run in isolated bridge-network containers without a shared PID namespace. ## Running interactively (CLI chat) diff --git a/website/docs/user-guide/features/api-server.md b/website/docs/user-guide/features/api-server.md index b059e40dff0..4f1db5ab0c2 100644 --- a/website/docs/user-guide/features/api-server.md +++ b/website/docs/user-guide/features/api-server.md @@ -272,6 +272,10 @@ Server-Sent Events stream of the run's tool-call progress, token deltas, and lif Interrupt a running agent turn. The endpoint returns immediately with `{"status": "stopping"}` while Hermes asks the active agent to stop at the next safe interruption point. +### POST /v1/runs/\{run_id\}/approval + +Resolve a pending approval for a run that is waiting on a human decision (for example, a tool call gated behind an approval policy). The body carries the approval decision; the run resumes once the decision is recorded. This endpoint is advertised in `/v1/capabilities` as the `run_approval` feature so external UIs can detect support before surfacing an approval prompt. + ## Jobs API (background scheduled work) The server exposes a lightweight jobs CRUD surface for managing scheduled / background agent runs from a remote client. All endpoints are gated behind the same bearer auth. diff --git a/website/docs/user-guide/features/built-in-plugins.md b/website/docs/user-guide/features/built-in-plugins.md index 60d9680cd3c..b4c1d5ef080 100644 --- a/website/docs/user-guide/features/built-in-plugins.md +++ b/website/docs/user-guide/features/built-in-plugins.md @@ -58,6 +58,8 @@ The repo ships these bundled plugins under `plugins/`. All are opt-in — enable | `disk-cleanup` | hooks + slash command | Auto-track ephemeral files and clean them on session end | | `security-guidance` | hooks | Pattern-match dangerous code on `write_file`/`patch` and append a security warning (or block) — 25 rules (Apache-2.0 fork of Anthropic's `claude-plugins-official` patterns) | | `observability/langfuse` | hooks | Trace turns / LLM calls / tools to [Langfuse](https://langfuse.com) | +| `observability/nemo_relay` | hooks | Relay observability events (turns / LLM calls / tools) to an NVIDIA NeMo endpoint | +| `teams_pipeline` | standalone | Microsoft Teams meeting pipeline — Graph-backed, transcript-first meeting summaries | | `spotify` | backend (7 tools) | Native Spotify playback, queue, search, playlists, albums, library | | `google_meet` | standalone | Join Meet calls, live-caption transcription, optional realtime duplex audio | | `image_gen/openai` | image backend | OpenAI `gpt-image-2` image generation backend (alternative to FAL) | diff --git a/website/docs/user-guide/features/codex-app-server-runtime.md b/website/docs/user-guide/features/codex-app-server-runtime.md index 3a96f604cc3..b4d317ae0cf 100644 --- a/website/docs/user-guide/features/codex-app-server-runtime.md +++ b/website/docs/user-guide/features/codex-app-server-runtime.md @@ -257,10 +257,10 @@ auxiliary: title_generation: provider: openrouter model: google/gemini-3-flash-preview - context_compression: + compression: provider: openrouter model: google/gemini-3-flash-preview - vision_detect: + vision: provider: openrouter model: google/gemini-3-flash-preview goal_judge: diff --git a/website/docs/user-guide/features/computer-use.md b/website/docs/user-guide/features/computer-use.md index d05ff954656..f951c6cc584 100644 --- a/website/docs/user-guide/features/computer-use.md +++ b/website/docs/user-guide/features/computer-use.md @@ -1,3 +1,8 @@ +--- +title: Computer Use +sidebar_position: 16 +--- + # Computer Use (macOS) Hermes Agent can drive your Mac's desktop — clicking, typing, scrolling, diff --git a/website/docs/user-guide/features/curator.md b/website/docs/user-guide/features/curator.md index 3830a8f4f17..6e65f4e226b 100644 --- a/website/docs/user-guide/features/curator.md +++ b/website/docs/user-guide/features/curator.md @@ -10,7 +10,7 @@ The curator is a background maintenance pass for **agent-created skills**. It tr It exists so that skills created via the [self-improvement loop](/user-guide/features/skills#agent-managed-skills-skill_manage-tool) don't pile up forever. Every time the agent solves a novel problem and saves a skill, that skill lands in `~/.hermes/skills/`. Without maintenance, you end up with dozens of narrow near-duplicates that pollute the catalog and waste tokens. -The curator **never touches** bundled skills (shipped with the repo) or hub-installed skills (from [agentskills.io](https://agentskills.io)). It only reviews skills the agent itself authored. It also **never auto-deletes** — the worst outcome is archival into `~/.hermes/skills/.archive/`, which is recoverable. +By default (`prune_builtins: true`) the curator can archive **unused bundled built-in skills** (shipped with the repo) after `archive_after_days` of non-use, alongside the agent-created skills it primarily manages. Hub-installed skills (from [agentskills.io](https://agentskills.io)) are always off-limits. Set `curator.prune_builtins: false` to restore the old agent-created-only behavior, where bundled skills are never touched. The curator also **never auto-deletes** — the worst outcome is archival into `~/.hermes/skills/.archive/`, which is recoverable. Tracks [issue #7816](https://github.com/NousResearch/hermes-agent/issues/7816). @@ -47,6 +47,7 @@ curator: min_idle_hours: 2 stale_after_days: 30 archive_after_days: 90 + prune_builtins: true # archive unused bundled built-in skills too (hub skills always exempt) ``` To disable entirely, set `curator.enabled: false`. @@ -97,6 +98,9 @@ hermes curator resume hermes curator pin # never auto-transition this skill hermes curator unpin hermes curator restore # move an archived skill back to active +hermes curator list-archived # list skills currently in ~/.hermes/skills/.archive/ +hermes curator archive # manually archive a single skill now +hermes curator prune [--days N] # bulk-archive agent-created skills idle >= N days (default 90) ``` ## Backups and rollback @@ -186,7 +190,7 @@ hermes curator unpin The flag is stored as `"pinned": true` on the skill's entry in `~/.hermes/skills/.usage.json`, so it survives across sessions. -Only **agent-created** skills can be pinned — bundled and hub-installed skills are never subject to curator mutation in the first place, and `hermes curator pin` will refuse with an explanatory message if you try. +Only **agent-created** skills can be pinned — `hermes curator pin` refuses on bundled and hub-installed skills with an explanatory message if you try. Hub-installed skills are never subject to curator mutation. Bundled built-in skills are only touched when `curator.prune_builtins: true` (the default), and even then only archived after `archive_after_days` of non-use — never patched, consolidated, or deleted. Set `curator.prune_builtins: false` to exempt bundled skills entirely. If you want a stronger guarantee than "no deletion" — for instance, freezing a skill's content entirely while the agent still reads it — edit `~/.hermes/skills//SKILL.md` directly with your editor. The pin guards tool-driven deletion, not your own filesystem access. diff --git a/website/docs/user-guide/features/kanban.md b/website/docs/user-guide/features/kanban.md index 73a7b88a107..d59438a7171 100644 --- a/website/docs/user-guide/features/kanban.md +++ b/website/docs/user-guide/features/kanban.md @@ -657,6 +657,12 @@ hermes kanban list [--mine] [--assignee P] [--status S] [--tenant T] [--archived [--json] hermes kanban show [--json] hermes kanban assign # or 'none' to unassign +hermes kanban reassign ... # bulk re-assign tasks to a profile +hermes kanban edit [--title ...] [--body ...] # edit task title / body / priority in place + [--priority N] +hermes kanban promote ... # move todo/blocked tasks to ready (recovery) +hermes kanban schedule --at # set/clear a task's scheduled_at start time +hermes kanban diagnostics [--json] # board health snapshot (alias: diag) hermes kanban link hermes kanban unlink hermes kanban claim [--ttl SECONDS] @@ -701,6 +707,7 @@ All commands are also available as a slash command in the interactive CLI and in | Config key | Default | What it does | |------------|---------|--------------| | `kanban.max_in_progress` | unset (unlimited) | Caps the number of simultaneously running tasks. When the board already has N running, the dispatcher skips spawning more — useful for slow workers (local LLMs, resource-constrained hosts) so they finish what they have before more pile up and time out. Invalid or below-1 values log a warning and behave as unlimited. | +| `kanban.max_in_progress_per_profile` | unset (unlimited) | Per-profile variant of `max_in_progress` — caps how many tasks any single assignee profile may run concurrently. Useful when one profile is slow or rate-limited but others should keep flowing. Applies alongside the board-wide `max_in_progress`; both must allow a spawn for it to proceed. | | `kanban.auto_promote_children` | `true` | After `decompose_triage_task()` produces children with no parent-blocker dependencies, they're automatically promoted to `ready` so the dispatcher can pick them up. Set to `false` to require manual review — children stay in `todo` until you promote them. | | `kanban.default_workdir` | unset | Board-level default working directory applied to new tasks when neither `--workspace` nor the task itself overrides it. Per-task `workspace:` still wins. | @@ -730,15 +737,16 @@ The dashboard exposes a **trash drop zone** on the kanban page — drag any card ### Worker visibility endpoints -The dashboard plugin API now exposes three read-only endpoints for external monitors: +The dashboard plugin API now exposes these read-only endpoints (plus a run-control verb) for external monitors: | Endpoint | Returns | |----------|---------| | `GET /api/plugins/kanban/workers/active` | Currently spawned workers with PID, profile, task id, started-at, last heartbeat | | `GET /api/plugins/kanban/runs/{id}` | Single-run detail — task id, status, started/ended, exit code, log path | +| `POST /api/plugins/kanban/runs/{run_id}/terminate` | Terminate a reclaimable run — stops the worker and frees the task for re-dispatch | | `GET /api/plugins/kanban/inspect` | Combined dispatcher snapshot — backlog, in-progress count vs. `max_in_progress`, recent events | -All three are gated by the same dashboard plugin auth as the rest of the kanban plugin API. +All of these are gated by the same dashboard plugin auth as the rest of the kanban plugin API. ### Kanban Swarm topology helper diff --git a/website/docs/user-guide/features/mcp.md b/website/docs/user-guide/features/mcp.md index c2232f11c1a..7d77bf36f51 100644 --- a/website/docs/user-guide/features/mcp.md +++ b/website/docs/user-guide/features/mcp.md @@ -245,6 +245,41 @@ Then run `hermes mcp login googledrive` — with the pre-registered client, Herm **Pitfall — config auto-reload race.** When you edit `~/.hermes/config.yaml` from inside a running Hermes session, the CLI auto-reloads MCP connections with a 30s timeout. That's not enough for an interactive OAuth flow. Add the entry, then run `hermes mcp login ` from a fresh terminal — it waits the full 5 minutes for you to complete auth. +## mTLS / client certificates + +Remote HTTP MCP servers that require mutual TLS (client-certificate authentication) are supported via `client_cert` / `client_key`. Hermes passes the resolved certificate to the underlying HTTP client for the TLS handshake. + +`client_cert` accepts three shapes: + +- **A single combined PEM path** — one file holding both the certificate and the private key: + +```yaml +mcp_servers: + internal_api: + url: "https://mcp.internal.example.com/mcp" + client_cert: "~/.certs/mcp-client.pem" +``` + +- **A `[cert, key]` 2-tuple** — certificate and key in separate files (equivalent to setting `client_cert` + `client_key`): + +```yaml +mcp_servers: + internal_api: + url: "https://mcp.internal.example.com/mcp" + client_cert: ["~/.certs/mcp-client.crt", "~/.certs/mcp-client.key"] +``` + +- **A `[cert, key, password]` 3-tuple** — when the private key is encrypted, the third element is the key passphrase: + +```yaml +mcp_servers: + internal_api: + url: "https://mcp.internal.example.com/mcp" + client_cert: ["~/.certs/mcp-client.crt", "~/.certs/mcp-client.key", "${MCP_KEY_PASSWORD}"] +``` + +You can also keep the cert and key fully separate via `client_cert` (combined PEM) plus an explicit `client_key`. Paths support `~` expansion; a missing file raises a clear, server-scoped error rather than an opaque TLS handshake failure. + ## Basic configuration reference Hermes reads MCP config from `~/.hermes/config.yaml` under `mcp_servers`. @@ -258,6 +293,8 @@ Hermes reads MCP config from `~/.hermes/config.yaml` under `mcp_servers`. | `env` | mapping | Environment variables passed to the stdio server | | `url` | string | HTTP MCP endpoint | | `headers` | mapping | HTTP headers for remote servers | +| `client_cert` | string \| list | Client certificate for mTLS — a combined PEM path, or `[cert, key]` / `[cert, key, password]` | +| `client_key` | string | Client private-key PEM path (when separate from `client_cert`) | | `timeout` | number | Tool call timeout | | `connect_timeout` | number | Initial connection timeout | | `enabled` | bool | If `false`, Hermes skips the server entirely | diff --git a/website/docs/user-guide/features/tool-gateway.md b/website/docs/user-guide/features/tool-gateway.md index 4ad39775d49..43a6c7dcb88 100644 --- a/website/docs/user-guide/features/tool-gateway.md +++ b/website/docs/user-guide/features/tool-gateway.md @@ -82,6 +82,8 @@ Tools marked "active via Nous subscription" are going through the gateway. Anyth The Tool Gateway is a **paid-subscription** feature. Free-tier Nous accounts can use Portal for inference but don't include managed tools — [upgrade your plan](https://portal.nousresearch.com/manage-subscription) to unlock the gateway. +Some accounts are also entitled to a **free tool pool** — a small managed-tool allowance that covers gateway tool calls without a paid subscription. When a free pool is available, the gateway surfaces it and shows a setup prompt on first use, so you can opt in and start using managed tools right away. + ## Mix and match The gateway is per-tool. Turn it on for just what you want: @@ -105,13 +107,13 @@ Image generation defaults to FLUX 2 Klein 9B for speed. Override per-call by pas | Model | ID | Best for | |---|---|---| | FLUX 2 Klein 9B | `fal-ai/flux-2/klein/9b` | Fast, good default | -| FLUX 2 Pro | `fal-ai/flux-2/pro` | Higher fidelity FLUX | +| FLUX 2 Pro | `fal-ai/flux-2-pro` | Higher fidelity FLUX | | Z-Image Turbo | `fal-ai/z-image/turbo` | Stylized, fast | -| Nano Banana Pro | `fal-ai/gemini-3-pro-image` | Google Gemini 3 Pro Image | -| GPT Image 1.5 | `fal-ai/gpt-image-1/5` | OpenAI image gen, text+image | +| Nano Banana Pro | `fal-ai/nano-banana-pro` | Google Gemini 3 Pro Image | +| GPT Image 1.5 | `fal-ai/gpt-image-1.5` | OpenAI image gen, text+image | | GPT Image 2 | `fal-ai/gpt-image-2` | OpenAI latest | | Ideogram V3 | `fal-ai/ideogram/v3` | Strong prompt adherence + typography | -| Recraft V4 Pro | `fal-ai/recraft/v4/pro` | Vector-style, graphic design | +| Recraft V4 Pro | `fal-ai/recraft/v4/pro/text-to-image` | Vector-style, graphic design | | Qwen Image | `fal-ai/qwen-image` | Alibaba multimodal | The set evolves — `hermes tools` → Image Generation shows the current live list. diff --git a/website/docs/user-guide/features/tools.md b/website/docs/user-guide/features/tools.md index 8c9cd4ba99c..55f9ef19add 100644 --- a/website/docs/user-guide/features/tools.md +++ b/website/docs/user-guide/features/tools.md @@ -28,7 +28,7 @@ High-level categories: | **Agent orchestration** | `todo`, `clarify`, `execute_code`, `delegate_task` | Planning, clarification, code execution, and subagent delegation. | | **Memory & recall** | `memory`, `session_search` | Persistent memory and session search. | | **Automation & delivery** | `cronjob`, `send_message` | Scheduled tasks with create/list/update/pause/resume/run/remove actions, plus outbound messaging delivery. | -| **Integrations** | `ha_*`, MCP server tools, `rl_*` | Home Assistant, MCP, RL training, and other integrations. | +| **Integrations** | `ha_*`, MCP server tools | Home Assistant, MCP, and other integrations. | For the authoritative code-derived registry, see [Built-in Tools Reference](/reference/tools-reference) and [Toolsets Reference](/reference/toolsets-reference). @@ -49,7 +49,7 @@ hermes tools hermes tools ``` -Common toolsets include `web`, `search`, `terminal`, `file`, `browser`, `vision`, `image_gen`, `moa`, `skills`, `tts`, `todo`, `memory`, `session_search`, `cronjob`, `code_execution`, `delegation`, `clarify`, `homeassistant`, `messaging`, `spotify`, `discord`, `discord_admin`, `debugging`, `safe`, and `rl`. +Common toolsets include `web`, `search`, `terminal`, `file`, `browser`, `vision`, `image_gen`, `moa`, `skills`, `tts`, `todo`, `memory`, `session_search`, `cronjob`, `code_execution`, `delegation`, `clarify`, `homeassistant`, `messaging`, `spotify`, `discord`, `discord_admin`, `debugging`, and `safe`. See [Toolsets Reference](/reference/toolsets-reference) for the full set, including platform presets such as `hermes-cli`, `hermes-telegram`, and dynamic MCP toolsets like `mcp-`. diff --git a/website/docs/user-guide/features/voice-mode.md b/website/docs/user-guide/features/voice-mode.md index fff3eaa808f..ab0b0a62fed 100644 --- a/website/docs/user-guide/features/voice-mode.md +++ b/website/docs/user-guide/features/voice-mode.md @@ -400,14 +400,14 @@ stt: # passes its path to the agent as part of the # inbound message, useful for custom pipelines # (diarization, alignment, archival, etc.) - provider: "local" # "local" (free) | "groq" | "openai" + provider: "local" # "local" (free) | "groq" | "openai" | "mistral" | "xai" local: model: "base" # tiny, base, small, medium, large-v3 # model: "whisper-1" # Legacy: used when provider is not set # Text-to-Speech tts: - provider: "edge" # "edge" (free) | "elevenlabs" | "openai" | "neutts" | "minimax" + provider: "edge" # "edge" (free) | "elevenlabs" | "openai" | "neutts" | "minimax" | "mistral" | "gemini" | "xai" | "kittentts" | "piper" edge: voice: "en-US-AriaNeural" # 322 voices, 74 languages elevenlabs: @@ -458,6 +458,8 @@ DISCORD_ALLOWED_USERS=... | **Groq** | `whisper-large-v3` | Fast (~1s) | Better | Free tier | Yes | | **OpenAI** | `whisper-1` | Fast (~1s) | Good | Paid | Yes | | **OpenAI** | `gpt-4o-transcribe` | Medium (~2s) | Best | Paid | Yes | +| **Mistral** | `voxtral-mini-latest` | Fast | Good | Paid | Yes | +| **xAI** | `grok-stt` | Fast | Good | Paid | Yes | Provider priority (automatic fallback): **local** > **groq** > **openai** diff --git a/website/docs/user-guide/features/web-dashboard.md b/website/docs/user-guide/features/web-dashboard.md index 0563223aac7..ea2c627e371 100644 --- a/website/docs/user-guide/features/web-dashboard.md +++ b/website/docs/user-guide/features/web-dashboard.md @@ -145,6 +145,9 @@ If `/api/status` shows the gate is on with the `"basic"` provider and Desktop *s A form-based editor for `config.yaml`. All 150+ configuration fields are auto-discovered from `DEFAULT_CONFIG` and organized into tabbed categories: +![Config admin page — section filters on the left, auto-discovered fields on the right](/img/dashboard/admin-config.png) + + - **model** — default model, provider, base URL, reasoning settings - **terminal** — backend (local/docker/ssh/modal), timeout, shell preferences - **display** — skin, tool progress, resume display, spinner settings diff --git a/website/docs/user-guide/git-worktrees.md b/website/docs/user-guide/git-worktrees.md index fdaf7e3de22..56bce3dda80 100644 --- a/website/docs/user-guide/git-worktrees.md +++ b/website/docs/user-guide/git-worktrees.md @@ -155,7 +155,7 @@ Hermes will: This is the easiest way to get worktree isolation. You can also combine it with a single query: ```bash -hermes -w -q "Fix issue #123" +hermes -w -z "Fix issue #123" ``` For parallel agents, open multiple terminals and run `hermes -w` in each — every invocation gets its own worktree and branch automatically. diff --git a/website/docs/user-guide/messaging/index.md b/website/docs/user-guide/messaging/index.md index ff40628544f..c8a6b4a70c8 100644 --- a/website/docs/user-guide/messaging/index.md +++ b/website/docs/user-guide/messaging/index.md @@ -31,7 +31,7 @@ Bots need both a model provider and tool providers (TTS, web). A [Nous Portal](/ | Matrix | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | DingTalk | — | ✅ | ✅ | — | ✅ | — | ✅ | | Feishu/Lark | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| WeCom | ✅ | ✅ | ✅ | — | — | ✅ | ✅ | +| WeCom | ✅ | ✅ | ✅ | — | — | — | — | | WeCom Callback | — | — | — | — | — | — | — | | Weixin | ✅ | ✅ | ✅ | — | — | ✅ | ✅ | | BlueBubbles | — | ✅ | ✅ | — | ✅ | ✅ | — | diff --git a/website/docs/user-guide/messaging/line.md b/website/docs/user-guide/messaging/line.md index 075afdbd9d5..dd468b17586 100644 --- a/website/docs/user-guide/messaging/line.md +++ b/website/docs/user-guide/messaging/line.md @@ -194,7 +194,7 @@ Cron jobs with `deliver: line` route to `LINE_HOME_CHANNEL`. The adapter ships a ## Limitations -* **Single bubble per chunk.** Each LINE text bubble is capped at 5000 characters, and at most 5 bubbles are sent per Reply/Push call. Longer responses are truncated with an ellipsis. +* **Bubble and length caps.** Each LINE text bubble is capped at 5000 characters. Longer responses are smart-chunked at ~4500 characters across up to 5 bubbles per Reply/Push call, splitting on natural boundaries where possible. * **No native message editing.** LINE has no edit-message API — streaming responses always send fresh bubbles, never edit prior ones. * **No Markdown rendering.** Bold (`**`), italics (`*`), code fences, and headings render as literal characters. The adapter strips them before sending; URLs are preserved (`[label](url)` becomes `label (url)`). * **Loading indicator is DM-only.** LINE rejects the chat/loading API for groups and rooms, so the typing indicator only shows in 1:1 chats. diff --git a/website/docs/user-guide/messaging/matrix.md b/website/docs/user-guide/messaging/matrix.md index ea85d5f45f5..9974ff7b918 100644 --- a/website/docs/user-guide/messaging/matrix.md +++ b/website/docs/user-guide/messaging/matrix.md @@ -19,7 +19,7 @@ Before setup, here's the part most people want to know: how Hermes behaves once | **DMs** | Hermes responds to every message. No `@mention` needed. Each DM has its own session. Set `MATRIX_DM_MENTION_THREADS=true` to start a thread when the bot is `@mentioned` in a DM. | | **Rooms** | By default, Hermes requires an `@mention` to respond. Set `MATRIX_REQUIRE_MENTION=false` or add room IDs to `MATRIX_FREE_RESPONSE_ROOMS` for free-response rooms. Room invites are auto-accepted. | | **Threads** | Hermes supports Matrix threads (MSC3440). If you reply in a thread, Hermes keeps the thread context isolated from the main room timeline. Threads where the bot has already participated do not require a mention. | -| **Auto-threading** | By default, Hermes auto-creates a thread for each message it responds to in a room. This keeps conversations isolated. Set `MATRIX_AUTO_THREAD=false` to disable. | +| **Auto-threading** | By default, Hermes auto-creates a thread for each message it responds to in a room. This keeps conversations isolated. Set `MATRIX_AUTO_THREAD=false` to disable. Set `MATRIX_DM_AUTO_THREAD=true` (default false) to also auto-create threads for DM messages — this is distinct from `MATRIX_DM_MENTION_THREADS`, which only starts a thread when the bot is `@mentioned` in a DM. | | **Commands** | Hermes accepts normal `/commands` when your Matrix client sends them. If your client reserves `/` for local commands, use `!commands` instead; Hermes normalizes known `!command` aliases to `/command`. | | **Shared rooms with multiple users** | By default, Hermes isolates session history per user inside the room. Two people talking in the same room do not share one transcript unless you explicitly disable that. | diff --git a/website/docs/user-guide/messaging/msgraph-webhook.md b/website/docs/user-guide/messaging/msgraph-webhook.md index 80ae063b3e6..1badff7a32c 100644 --- a/website/docs/user-guide/messaging/msgraph-webhook.md +++ b/website/docs/user-guide/messaging/msgraph-webhook.md @@ -70,7 +70,7 @@ All settings go under `platforms.msgraph_webhook.extra`: | `max_seen_receipts` | `5000` | Dedupe cache size for notification IDs. Oldest entries evicted when the cap is hit. | | `allowed_source_cidrs` | `[]` | Required for non-loopback binds. Leave empty only when the listener is bound to loopback and fronted by a local tunnel / reverse proxy. | -Each setting also has an equivalent env var (`MSGRAPH_WEBHOOK_*`) that merges into the config at gateway startup — see the [environment variables reference](/reference/environment-variables#microsoft-graph-teams-meetings). +Most settings also have an equivalent env var (`MSGRAPH_WEBHOOK_*`) that merges into the config at gateway startup (the exception is `host`, which is config-only — see the note above) — see the [environment variables reference](/reference/environment-variables#microsoft-graph-teams-meetings). ## Security Hardening diff --git a/website/docs/user-guide/messaging/ntfy.md b/website/docs/user-guide/messaging/ntfy.md index 6bacac84f2b..20a832f47ea 100644 --- a/website/docs/user-guide/messaging/ntfy.md +++ b/website/docs/user-guide/messaging/ntfy.md @@ -19,7 +19,7 @@ That's it. No SDK, no daemon, no Node.js. The adapter uses `httpx` which is alre ### Via setup wizard ```bash -hermes setup gateway +hermes gateway setup ``` Select **ntfy** and follow the prompts. diff --git a/website/docs/user-guide/messaging/simplex.md b/website/docs/user-guide/messaging/simplex.md index 472a629d472..0a5f4f72ca5 100644 --- a/website/docs/user-guide/messaging/simplex.md +++ b/website/docs/user-guide/messaging/simplex.md @@ -34,7 +34,7 @@ The daemon listens on WebSocket at `ws://127.0.0.1:5225` by default. ### Via setup wizard ```bash -hermes setup gateway +hermes gateway setup ``` Select **SimpleX Chat** and follow the prompts. @@ -66,7 +66,7 @@ After starting the daemon, open a conversation with your agent contact. The cont By default **all contacts are denied**. You must either: 1. Set `SIMPLEX_ALLOWED_USERS` to a comma-separated list of contact IDs, or -2. Use **DM pairing** — send any message to the bot and it will reply with a pairing code. Enter that code via `hermes gateway pair`. +2. Use **DM pairing** — send any message to the bot and it will reply with a pairing code. Enter that code via `hermes pairing approve simplex `. ## Using SimpleX with cron jobs diff --git a/website/docs/user-guide/messaging/sms.md b/website/docs/user-guide/messaging/sms.md index 8f58e0bfb8c..a6bbf018cb1 100644 --- a/website/docs/user-guide/messaging/sms.md +++ b/website/docs/user-guide/messaging/sms.md @@ -126,7 +126,7 @@ Text your Twilio number — Hermes will respond via SMS. | `TWILIO_PHONE_NUMBER` | Yes | Your Twilio phone number (E.164 format) | | `SMS_WEBHOOK_URL` | Yes | Public URL for Twilio signature validation — must match the webhook URL in your Twilio Console | | `SMS_WEBHOOK_PORT` | No | Webhook listener port (default: `8080`) | -| `SMS_WEBHOOK_HOST` | No | Webhook bind address (default: `0.0.0.0`) | +| `SMS_WEBHOOK_HOST` | No | Webhook bind address (default: `127.0.0.1`) | | `SMS_INSECURE_NO_SIGNATURE` | No | Set to `true` to disable signature validation (local dev only — **not for production**) | | `SMS_ALLOWED_USERS` | No | Comma-separated E.164 phone numbers allowed to chat | | `SMS_ALLOW_ALL_USERS` | No | Set to `true` to allow anyone (not recommended) | diff --git a/website/docs/user-guide/messaging/telegram.md b/website/docs/user-guide/messaging/telegram.md index aab215cf2e2..a2ac8cb584f 100644 --- a/website/docs/user-guide/messaging/telegram.md +++ b/website/docs/user-guide/messaging/telegram.md @@ -876,9 +876,9 @@ When streaming is enabled (`gateway.streaming.enabled: true`), Hermes picks one | Value | Behaviour | |---|---| -| `auto` | Native draft streaming on supported chats (currently Telegram DMs); legacy edit-based path otherwise. Falls back gracefully if a draft frame fails. | +| `auto` (default) | Native draft streaming on supported chats (currently Telegram DMs); legacy edit-based path otherwise. Falls back gracefully if a draft frame fails. | | `draft` | Force native drafts. Logs a downgrade and falls back to edit if the chat doesn't support drafts (e.g. groups/topics). | -| `edit` (default) | Legacy progressive `editMessageText` polling for every chat type. | +| `edit` | Legacy progressive `editMessageText` polling for every chat type. | | `off` | Disable streaming entirely (final reply only, no progressive updates). | In `~/.hermes/config.yaml`: @@ -887,7 +887,7 @@ In `~/.hermes/config.yaml`: gateway: streaming: enabled: true - transport: edit # edit | auto | draft | off + transport: auto # auto | draft | edit | off ``` **What you'll see in DMs with `edit` (default)** — the gateway sends a normal preview message and progressively updates it via `editMessageText`, avoiding Telegram's draft-preview collapse/rollback effect. diff --git a/website/docs/user-guide/multi-profile-gateways.md b/website/docs/user-guide/multi-profile-gateways.md index 6f00c24cf83..e11c389038f 100644 --- a/website/docs/user-guide/multi-profile-gateways.md +++ b/website/docs/user-guide/multi-profile-gateways.md @@ -170,8 +170,8 @@ tail -f ~/.hermes/logs/gateway.log ~/.hermes/profiles/*/logs/gateway.log The CLI also has a structured log viewer: ```bash -hermes logs --tail # follow default profile -hermes -p coder logs --tail # follow one profile +hermes logs -f # follow default profile +hermes -p coder logs -f # follow one profile hermes logs --help # filters, levels, JSON output ``` diff --git a/website/docs/user-guide/security.md b/website/docs/user-guide/security.md index 54dae3f83ef..5de9497f696 100644 --- a/website/docs/user-guide/security.md +++ b/website/docs/user-guide/security.md @@ -319,7 +319,7 @@ When using the `docker` terminal backend, Hermes applies strict security hardeni Every container runs with these flags (defined in `tools/environments/docker.py`): ```python -_SECURITY_ARGS = [ +_BASE_SECURITY_ARGS = [ "--cap-drop", "ALL", # Drop ALL Linux capabilities "--cap-add", "DAC_OVERRIDE", # Root can write to bind-mounted dirs "--cap-add", "CHOWN", # Package managers need file ownership @@ -328,10 +328,11 @@ _SECURITY_ARGS = [ "--pids-limit", "256", # Limit process count "--tmpfs", "/tmp:rw,nosuid,size=512m", # Size-limited /tmp "--tmpfs", "/var/tmp:rw,noexec,nosuid,size=256m", # No-exec /var/tmp - "--tmpfs", "/run:rw,noexec,nosuid,size=64m", # No-exec /run ] ``` +`SETUID`/`SETGID` are **not** in the base list — they're added conditionally when the container starts as root and an init/entrypoint must drop privileges (the s6 privilege-drop path). They're skipped when the container already runs as a non-root `--user`. The `/run` tmpfs is also split out from the base list and mounted per-image (hardened `noexec` by default, `exec` only for s6-overlay images that exec from `/run`). + ### Resource Limits Container resources are configurable in `~/.hermes/config.yaml`: diff --git a/website/static/img/dashboard/admin-config.png b/website/static/img/dashboard/admin-config.png new file mode 100644 index 00000000000..e2e6dbb8d2b Binary files /dev/null and b/website/static/img/dashboard/admin-config.png differ