Merge branch 'main' of github.com:NousResearch/hermes-agent into bb/gui
# Conflicts: # tui_gateway/server.py
This commit is contained in:
@@ -84,8 +84,8 @@ Earlier releases used a one-off `curator.auxiliary.{provider,model}` block. That
|
||||
|
||||
```bash
|
||||
hermes curator status # last run, counts, pinned list, LRU top 5
|
||||
hermes curator run # trigger a review now (background by default)
|
||||
hermes curator run --sync # same, but block until the LLM pass finishes
|
||||
hermes curator run # trigger a review now (blocks until the LLM pass finishes)
|
||||
hermes curator run --background # fire-and-forget: start the LLM pass in a background thread
|
||||
hermes curator run --dry-run # preview only — report without any mutations
|
||||
hermes curator backup # take a manual snapshot of ~/.hermes/skills/
|
||||
hermes curator rollback # restore from the newest snapshot
|
||||
|
||||
@@ -192,6 +192,7 @@ Hermes uses separate lightweight models for side tasks. Each task has its own pr
|
||||
| MCP | MCP helper operations | `auxiliary.mcp` |
|
||||
| Approval | Smart command-approval classification | `auxiliary.approval` |
|
||||
| Title Generation | Session title summaries | `auxiliary.title_generation` |
|
||||
| Triage Specifier | `hermes kanban specify` / dashboard ✨ button — fleshes out a one-liner triage task into a real spec | `auxiliary.triage_specifier` |
|
||||
|
||||
### Auto-Detection Chain
|
||||
|
||||
@@ -384,5 +385,6 @@ See [Scheduled Tasks (Cron)](/docs/user-guide/features/cron) for full configurat
|
||||
| MCP helpers | Auto-detection chain | `auxiliary.mcp` |
|
||||
| Approval classification | Auto-detection chain | `auxiliary.approval` |
|
||||
| Title generation | Auto-detection chain | `auxiliary.title_generation` |
|
||||
| Triage specifier | Auto-detection chain | `auxiliary.triage_specifier` |
|
||||
| Delegation | Provider override only (no automatic fallback) | `delegation.provider` / `delegation.model` |
|
||||
| Cron jobs | Per-job provider override only (no automatic fallback) | Per-job `provider` / `model` |
|
||||
|
||||
@@ -387,6 +387,7 @@ def register(ctx):
|
||||
| [`post_approval_response`](#post_approval_response) | User responded to an approval prompt (or it timed out) | ignored |
|
||||
| [`transform_tool_result`](#transform_tool_result) | After any tool returns, before the result is handed back to the model | `str` to replace the result, `None` to leave unchanged |
|
||||
| [`transform_terminal_output`](#transform_terminal_output) | Inside the `terminal` tool, before truncation/ANSI-strip/redact | `str` to replace the raw output, `None` to leave unchanged |
|
||||
| [`transform_llm_output`](#transform_llm_output) | After the tool-calling loop completes, before the final response is delivered | `str` to replace the response text, `None`/empty to leave unchanged |
|
||||
|
||||
---
|
||||
|
||||
@@ -1093,6 +1094,49 @@ Pairs well with `transform_tool_result` (which covers every other tool).
|
||||
|
||||
---
|
||||
|
||||
### `transform_llm_output`
|
||||
|
||||
Fires **once per turn** after the tool-calling loop completes and the model has produced a final response, **before** that response is delivered to the user (CLI, gateway, or programmatic caller). Lets a plugin rewrite the assistant's final text using classical-programming methods — no extra inference tokens burned on SOUL flavor text or a skill-driven transform.
|
||||
|
||||
**Callback signature:**
|
||||
|
||||
```python
|
||||
def my_callback(
|
||||
response_text: str,
|
||||
session_id: str,
|
||||
model: str,
|
||||
platform: str,
|
||||
**kwargs,
|
||||
) -> str | None:
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `response_text` | `str` | The assistant's final response text for this turn. |
|
||||
| `session_id` | `str` | Session ID for this conversation (may be empty for one-shot runs). |
|
||||
| `model` | `str` | Model name that produced the response (e.g. `anthropic/claude-sonnet-4.6`). |
|
||||
| `platform` | `str` | Delivery platform (`cli`, `telegram`, `discord`, …; empty when unset). |
|
||||
|
||||
**Return value:** Non-empty `str` to replace the response text, `None` or empty string to leave it unchanged. **First non-empty string wins** when multiple plugins register — mirroring `transform_tool_result`.
|
||||
|
||||
**Use cases:** Apply a personality/vocabulary transform (pirate-speak, Spongebob), redact user-specific identifiers from the final text, append a project-specific signature footer, enforce a house style guide without burning tokens on SOUL instructions.
|
||||
|
||||
```python
|
||||
import os, re
|
||||
|
||||
def spongebob(response_text, **kwargs):
|
||||
if os.environ.get("SPONGEBOB_MODE") != "on":
|
||||
return None # pass through unchanged
|
||||
return re.sub(r"!", "!! Tartar sauce!", response_text)
|
||||
|
||||
def register(ctx):
|
||||
ctx.register_hook("transform_llm_output", spongebob)
|
||||
```
|
||||
|
||||
The hook is guarded on a non-empty, non-interrupted response — it will not fire on stop-button interrupts or empty turns. Exceptions are logged as warnings and do not break agent execution.
|
||||
|
||||
---
|
||||
|
||||
## Shell Hooks
|
||||
|
||||
Declare shell-script hooks in your `cli-config.yaml` and Hermes will run them as subprocesses whenever the corresponding plugin-hook event fires — in both CLI and gateway sessions. No Python plugin authoring required.
|
||||
|
||||
@@ -22,7 +22,7 @@ Throughout the tutorial, **code blocks labelled `bash` are commands *you* run.**
|
||||
|
||||
Six columns, left to right:
|
||||
|
||||
- **Triage** — raw ideas, a specifier will flesh out the spec before anyone works on them.
|
||||
- **Triage** — raw ideas, a specifier will flesh out the spec before anyone works on them. Click the **✨ Specify** button on any triage card (or run `hermes kanban specify <id>` / `/kanban specify <id>` from a chat) to have the auxiliary LLM turn a one-liner into a full spec (goal, approach, acceptance criteria) and promote it to `todo` in one shot. Configure which model runs it under `auxiliary.triage_specifier` in `config.yaml`.
|
||||
- **Todo** — created but waiting on dependencies, or not yet assigned.
|
||||
- **Ready** — assigned and waiting for the dispatcher to claim.
|
||||
- **In progress** — a worker is actively running the task. With "Lanes by profile" on (the default), this column sub-groups by assignee so you can see at a glance what each worker is doing.
|
||||
|
||||
@@ -335,10 +335,19 @@ Any profile that should be able to work kanban tasks must load the `kanban-worke
|
||||
3. Call `kanban_heartbeat(note="...")` every few minutes during long operations.
|
||||
4. Complete with `kanban_complete(summary="...", metadata={...})`, or `kanban_block(reason="...")` if stuck.
|
||||
|
||||
Load it with (this one is **you**, installing into a profile — not a tool call):
|
||||
`kanban-worker` is a bundled skill, synced into every profile during install and
|
||||
update — there is no separate Skills Hub install step. Verify it is present in
|
||||
whichever profile you use for kanban workers (`researcher`, `writer`, `ops`,
|
||||
etc.):
|
||||
|
||||
```bash
|
||||
hermes skills install devops/kanban-worker
|
||||
hermes -p <your-worker-profile> skills list | grep kanban-worker
|
||||
```
|
||||
|
||||
If the bundled copy is missing, restore it for that profile:
|
||||
|
||||
```bash
|
||||
hermes -p <your-worker-profile> skills reset kanban-worker --restore
|
||||
```
|
||||
|
||||
The dispatcher also auto-passes `--skills kanban-worker` when spawning every worker, so the worker always has the pattern library available even if a profile's default skills config doesn't include it.
|
||||
@@ -403,10 +412,18 @@ kanban_complete(
|
||||
)
|
||||
```
|
||||
|
||||
Load it into your orchestrator profile:
|
||||
`kanban-orchestrator` is a bundled skill. It is synced into each profile during
|
||||
install and update, so there is no separate Skills Hub install step. Verify it is
|
||||
present in your orchestrator profile:
|
||||
|
||||
```bash
|
||||
hermes skills install devops/kanban-orchestrator
|
||||
hermes -p orchestrator skills list | grep kanban-orchestrator
|
||||
```
|
||||
|
||||
If the bundled copy is missing, restore it for that profile:
|
||||
|
||||
```bash
|
||||
hermes -p orchestrator skills reset kanban-orchestrator --restore
|
||||
```
|
||||
|
||||
For best results, pair it with a profile whose toolsets are restricted to board operations (`kanban`, `gateway`, `memory`) so the orchestrator literally cannot execute implementation tasks even if it tries.
|
||||
@@ -425,7 +442,7 @@ hermes dashboard # "Kanban" tab appears in the nav, after "Skills"
|
||||
### What the plugin gives you
|
||||
|
||||
- A **Kanban** tab showing one column per status: `triage`, `todo`, `ready`, `running`, `blocked`, `done` (plus `archived` when the toggle is on).
|
||||
- `triage` is the parking column for rough ideas a specifier is expected to flesh out. Tasks created with `hermes kanban create --triage` (or via the Triage column's inline create) land here and the dispatcher leaves them alone until a human or specifier promotes them to `todo` / `ready`.
|
||||
- `triage` is the parking column for rough ideas a specifier is expected to flesh out. Tasks created with `hermes kanban create --triage` (or via the Triage column's inline create) land here and the dispatcher leaves them alone until a human or specifier promotes them to `todo` / `ready`. Run `hermes kanban specify <id>` to have the auxiliary LLM expand a triage task into a concrete spec (title + body with goal, approach, acceptance criteria) and promote it to `todo` in one shot; `--all` sweeps every triage task at once. Configure which model runs the specifier under `auxiliary.triage_specifier` in `config.yaml`.
|
||||
- Cards show the task id, title, priority badge, tenant tag, assigned profile, comment/link counts, a **progress pill** (`N/M` children done when the task has dependents), and "created N ago". A per-card checkbox enables multi-select.
|
||||
- **Per-profile lanes inside Running** — toolbar checkbox toggles sub-grouping of the Running column by assignee.
|
||||
- **Live updates via WebSocket** — the plugin tails the append-only `task_events` table on a short poll interval; the board reflects changes the instant any profile (CLI, gateway, or another dashboard tab) acts. Reloads are debounced so a burst of events triggers a single refetch.
|
||||
@@ -437,7 +454,7 @@ hermes dashboard # "Kanban" tab appears in the nav, after "Skills"
|
||||
- **Editable assignee / priority** — click the meta row to rewrite.
|
||||
- **Editable description** — markdown-rendered by default (headings, bold, italic, inline code, fenced code, `http(s)` / `mailto:` links, bullet lists), with an "edit" button that swaps in a textarea. Markdown rendering is a tiny, XSS-safe renderer — every substitution runs on HTML-escaped input, only `http(s)` / `mailto:` links pass through, and `target="_blank"` + `rel="noopener noreferrer"` are always set.
|
||||
- **Dependency editor** — chip list of parents and children, each with an `×` to unlink, plus dropdowns over every other task to add a new parent or child. Cycle attempts are rejected server-side with a clear message.
|
||||
- **Status action row** (→ triage / → ready / → running / block / unblock / complete / archive) with confirm prompts for destructive transitions.
|
||||
- **Status action row** (→ triage / → ready / → running / block / unblock / complete / archive) with confirm prompts for destructive transitions. For cards in the **Triage** column the row also exposes a **✨ Specify** button that calls the auxiliary LLM (`auxiliary.triage_specifier` in `config.yaml`) to expand the one-liner into a concrete spec (title + body with goal, approach, acceptance criteria) and promote the task to `todo`. The same behaviour is reachable from the CLI (`hermes kanban specify <id>` / `--all`), from any gateway platform (`/kanban specify <id>`), and programmatically via `POST /api/plugins/kanban/tasks/:id/specify`.
|
||||
- Result section (also markdown-rendered), comment thread with Enter-to-submit, the last 20 events.
|
||||
- **Toolbar filters** — free-text search, tenant dropdown (defaults to `dashboard.kanban.default_tenant` from `config.yaml`), assignee dropdown, "show archived" toggle, "lanes by profile" toggle, and a **Nudge dispatcher** button so you don't have to wait for the next 60 s tick.
|
||||
|
||||
@@ -479,6 +496,7 @@ All routes are mounted under `/api/plugins/kanban/` and protected by the dashboa
|
||||
| `PATCH` | `/tasks/:id` | Status / assignee / priority / title / body / result |
|
||||
| `POST` | `/tasks/bulk` | Apply the same patch (status / archive / assignee / priority) to every id in `ids`. Per-id failures reported without aborting siblings |
|
||||
| `POST` | `/tasks/:id/comments` | Append a comment |
|
||||
| `POST` | `/tasks/:id/specify` | Run the triage specifier — auxiliary LLM fleshes out the task body and promotes it from `triage` to `todo`. Returns `{ok, task_id, reason, new_title}`; `ok=false` with a human-readable reason on "not in triage" / no aux client / LLM error is a 200, not a 4xx |
|
||||
| `POST` | `/links` | Add a dependency (`parent_id` → `child_id`) |
|
||||
| `DELETE` | `/links?parent_id=…&child_id=…` | Remove a dependency |
|
||||
| `POST` | `/dispatch?max=…&dry_run=…` | Nudge the dispatcher — skip the 60 s wait |
|
||||
@@ -571,6 +589,8 @@ hermes kanban notify-list [<id>] [--json]
|
||||
hermes kanban notify-unsubscribe <id>
|
||||
--platform <name> --chat-id <id> [--thread-id <id>]
|
||||
hermes kanban context <id> # what a worker sees
|
||||
hermes kanban specify [<id> | --all] [--tenant T] # flesh out a triage-column idea
|
||||
[--author NAME] [--json] # into a full spec and promote to todo
|
||||
hermes kanban gc [--event-retention-days N] # workspaces + old events + old logs
|
||||
[--log-retention-days N]
|
||||
```
|
||||
@@ -588,6 +608,8 @@ Every `hermes kanban <action>` verb is also reachable as `/kanban <action>` —
|
||||
/kanban comment t_abcd "looks good, ship it"
|
||||
/kanban unblock t_abcd
|
||||
/kanban dispatch --max 3
|
||||
/kanban specify t_abcd # flesh out a triage one-liner into a real spec
|
||||
/kanban specify --all --tenant engineering # sweep every triage task in one tenant
|
||||
```
|
||||
|
||||
Quote multi-word arguments the same way you would on a shell — `run_slash` parses the rest of the line with `shlex.split`, so `"..."` and `'...'` both work.
|
||||
@@ -641,7 +663,7 @@ The board supports these eight patterns without any new primitives:
|
||||
| **P6 `@mention`** | inline routing from prose | `@reviewer look at this` |
|
||||
| **P7 Thread-scoped workspace** | `/kanban here` in a thread | per-project gateway threads |
|
||||
| **P8 Fleet farming** | one profile, N subjects | 50 social accounts |
|
||||
| **P9 Triage specifier** | rough idea → `triage` → specifier expands body → `todo` | "turn this one-liner into a spec' task" |
|
||||
| **P9 Triage specifier** | rough idea → `triage` → `hermes kanban specify` expands body → `todo` | "turn this one-liner into a spec'd task" |
|
||||
|
||||
For worked examples of each, see `docs/hermes-kanban-v1-spec.pdf`.
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ Controls all color values throughout the CLI. Values are hex color strings.
|
||||
| `session_border` | Session ID dim border color | `#8B8682` |
|
||||
| `status_bar_bg` | Background color for the TUI status / usage bar | `#1a1a2e` |
|
||||
| `voice_status_bg` | Background color for the voice-mode status badge | `#1a1a2e` |
|
||||
| `selection_bg` | Background color for the TUI mouse-selection highlighter. Falls back to `completion_menu_current_bg` when unset. | `#333355` |
|
||||
| `completion_menu_bg` | Background color for the completion menu list | `#1a1a2e` |
|
||||
| `completion_menu_current_bg` | Background color for the active completion row | `#333355` |
|
||||
| `completion_menu_meta_bg` | Background color for the completion meta column | `#1a1a2e` |
|
||||
@@ -139,6 +140,7 @@ colors:
|
||||
session_border: "#8B8682"
|
||||
status_bar_bg: "#1a1a2e"
|
||||
voice_status_bg: "#1a1a2e"
|
||||
selection_bg: "#333355"
|
||||
completion_menu_bg: "#1a1a2e"
|
||||
completion_menu_current_bg: "#333355"
|
||||
completion_menu_meta_bg: "#1a1a2e"
|
||||
|
||||
@@ -1,80 +1,116 @@
|
||||
---
|
||||
title: "Nous Tool Gateway"
|
||||
description: "Route web search, image generation, text-to-speech, and browser automation through your Nous subscription — no extra API keys needed"
|
||||
description: "One subscription, every tool. Web search, image generation, TTS, and cloud browsers — all routed through Nous Portal with no extra API keys."
|
||||
sidebar_label: "Tool Gateway"
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Nous Tool Gateway
|
||||
|
||||
:::tip Get Started
|
||||
The Tool Gateway is included with paid Nous Portal subscriptions. **[Manage your subscription →](https://portal.nousresearch.com/manage-subscription)**
|
||||
:::
|
||||
**One subscription. Every tool built in.**
|
||||
|
||||
The **Tool Gateway** lets paid [Nous Portal](https://portal.nousresearch.com) subscribers use web search, image generation, text-to-speech, and browser automation through their existing subscription — no need to sign up for separate API keys from Firecrawl, FAL, OpenAI, or Browser Use.
|
||||
The Tool Gateway is included with every paid [Nous Portal](https://portal.nousresearch.com) subscription. It routes Hermes' tool calls — web search, image generation, text-to-speech, and cloud browser automation — through infrastructure Nous already runs, so you don't have to sign up with Firecrawl, FAL, OpenAI, Browser Use, or anyone else just to make your agent useful.
|
||||
|
||||
## What's Included
|
||||
<div style={{display: 'flex', gap: '1rem', flexWrap: 'wrap', margin: '1.5rem 0'}}>
|
||||
<a href="https://portal.nousresearch.com/manage-subscription" style={{background: 'var(--ifm-color-primary)', color: 'white', padding: '0.75rem 1.5rem', borderRadius: '6px', textDecoration: 'none', fontWeight: 'bold'}}>Start or manage subscription →</a>
|
||||
</div>
|
||||
|
||||
| Tool | What It Does | Direct Alternative |
|
||||
|------|--------------|--------------------|
|
||||
| **Web search & extract** | Search the web and extract page content via Firecrawl | `FIRECRAWL_API_KEY`, `EXA_API_KEY`, `PARALLEL_API_KEY`, `TAVILY_API_KEY` |
|
||||
| **Image generation** | Generate images via FAL (9 models: FLUX 2 Klein/Pro, GPT-Image 1.5/2, Nano Banana Pro, Ideogram V3, Recraft V4 Pro, Qwen, Z-Image Turbo) | `FAL_KEY` |
|
||||
| **Text-to-speech** | Convert text to speech via OpenAI TTS | `VOICE_TOOLS_OPENAI_KEY`, `ELEVENLABS_API_KEY` |
|
||||
| **Browser automation** | Control cloud browsers via Browser Use | `BROWSER_USE_API_KEY`, `BROWSERBASE_API_KEY` |
|
||||
## What's included
|
||||
|
||||
All four tools bill to your Nous subscription. You can enable any combination — for example, use the gateway for web and image generation while keeping your own ElevenLabs key for TTS.
|
||||
| | Tool | What you get |
|
||||
|---|---|---|
|
||||
| 🔍 | **Web search & extract** | Agent-grade web search and full-page extraction via Firecrawl. No rate limits to worry about — the gateway handles scaling. |
|
||||
| 🎨 | **Image generation** | Nine models under one endpoint: **FLUX 2 Klein 9B**, **FLUX 2 Pro**, **Z-Image Turbo**, **Nano Banana Pro** (Gemini 3 Pro Image), **GPT Image 1.5**, **GPT Image 2**, **Ideogram V3**, **Recraft V4 Pro**, **Qwen Image**. Pick per-generation with a flag, or let Hermes default to FLUX 2 Klein. |
|
||||
| 🔊 | **Text-to-speech** | OpenAI TTS voices wired into the `text_to_speech` tool. Drop voice notes into Telegram, generate audio for pipelines, narrate anything. |
|
||||
| 🌐 | **Cloud browser automation** | Headless Chromium sessions via Browser Use. `browser_navigate`, `browser_click`, `browser_type`, `browser_vision` — all the agent-driving primitives, no Browserbase account required. |
|
||||
|
||||
## Eligibility
|
||||
All four are pay-as-you-use billed against your Nous subscription. Use any combination — run the gateway for web and images while keeping your own ElevenLabs key for TTS, or route everything through Nous.
|
||||
|
||||
The Tool Gateway is available to **paid** [Nous Portal](https://portal.nousresearch.com/manage-subscription) subscribers. Free-tier accounts do not have access — [upgrade your subscription](https://portal.nousresearch.com/manage-subscription) to unlock it.
|
||||
## Why it's here
|
||||
|
||||
To check your status:
|
||||
Building an agent that can actually *do things* means stitching together 5+ API subscriptions — each with their own signup, rate limits, billing, and quirks. The gateway collapses that into one account:
|
||||
|
||||
- **One bill.** Pay Nous; we handle the rest.
|
||||
- **One signup.** No Firecrawl, FAL, Browser Use, or OpenAI audio accounts to manage.
|
||||
- **One key.** Your Nous Portal OAuth covers every tool.
|
||||
- **Same quality.** Same backends the direct-key route uses — just fronted by us.
|
||||
|
||||
Bring your own keys anytime — per-tool, whenever you want to. The gateway isn't a lock-in, it's a shortcut.
|
||||
|
||||
## Get started
|
||||
|
||||
```bash
|
||||
hermes model # Pick Nous Portal as your provider
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Check what's active at any time:
|
||||
|
||||
```bash
|
||||
hermes status
|
||||
```
|
||||
|
||||
Look for the **Nous Tool Gateway** section. It shows which tools are active via the gateway, which use direct keys, and which aren't configured.
|
||||
|
||||
## Enabling the Tool Gateway
|
||||
|
||||
### During model setup
|
||||
|
||||
When you run `hermes model` and select Nous Portal as your provider, Hermes automatically offers to enable the Tool Gateway:
|
||||
You'll see a section like:
|
||||
|
||||
```
|
||||
Your Nous subscription includes the Tool Gateway.
|
||||
|
||||
The Tool Gateway gives you access to web search, image generation,
|
||||
text-to-speech, and browser automation through your Nous subscription.
|
||||
No need to sign up for separate API keys — just pick the tools you want.
|
||||
|
||||
○ Web search & extract (Firecrawl) — not configured
|
||||
○ Image generation (FAL) — not configured
|
||||
○ Text-to-speech (OpenAI TTS) — not configured
|
||||
○ Browser automation (Browser Use) — not configured
|
||||
|
||||
● Enable Tool Gateway
|
||||
○ Skip
|
||||
◆ Nous Tool Gateway
|
||||
Nous Portal ✓ managed tools available
|
||||
Web tools ✓ active via Nous subscription
|
||||
Image gen ✓ active via Nous subscription
|
||||
TTS ✓ active via Nous subscription
|
||||
Browser ○ active via Browser Use key
|
||||
```
|
||||
|
||||
Select **Enable Tool Gateway** and you're done.
|
||||
Tools marked "active via Nous subscription" are going through the gateway. Anything else is using your own keys.
|
||||
|
||||
If you already have direct API keys for some tools, the prompt adapts — you can enable the gateway for all tools (your existing keys are kept in `.env` but not used at runtime), enable only for unconfigured tools, or skip entirely.
|
||||
## Eligibility
|
||||
|
||||
### Via `hermes tools`
|
||||
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.
|
||||
|
||||
You can also enable the gateway tool-by-tool through the interactive tool configuration:
|
||||
## Mix and match
|
||||
|
||||
The gateway is per-tool. Turn it on for just what you want:
|
||||
|
||||
- **All tools through Nous** — easiest; one subscription, done.
|
||||
- **Gateway for web + images, bring your own TTS** — keep your ElevenLabs voice, let Nous handle the rest.
|
||||
- **Gateway only for things you don't have keys for** — "I already pay for Browserbase, but I don't want a Firecrawl account" works fine.
|
||||
|
||||
Switch any tool at any time via:
|
||||
|
||||
```bash
|
||||
hermes tools
|
||||
hermes tools # Interactive picker for each tool category
|
||||
```
|
||||
|
||||
Select a tool category (Web, Browser, Image Generation, or TTS), then choose **Nous Subscription** as the provider. This sets `use_gateway: true` for that tool in your config.
|
||||
Select the tool, pick **Nous Subscription** as the provider (or any direct provider you prefer). No config editing required.
|
||||
|
||||
### Manual configuration
|
||||
## Using individual image models
|
||||
|
||||
Set the `use_gateway` flag directly in `~/.hermes/config.yaml`:
|
||||
Image generation defaults to FLUX 2 Klein 9B for speed. Override per-call by passing the model ID to the `image_generate` tool:
|
||||
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| Qwen Image | `fal-ai/qwen-image` | Alibaba multimodal |
|
||||
|
||||
The set evolves — `hermes tools` → Image Generation shows the current live list.
|
||||
|
||||
---
|
||||
|
||||
## Configuration reference
|
||||
|
||||
Most users never need to touch this — `hermes model` and `hermes tools` cover every workflow interactively. This section is for writing config.yaml directly or scripting setups.
|
||||
|
||||
### Per-tool `use_gateway` flag
|
||||
|
||||
Each tool's config block takes a `use_gateway` boolean:
|
||||
|
||||
```yaml
|
||||
web:
|
||||
@@ -93,95 +129,48 @@ browser:
|
||||
use_gateway: true
|
||||
```
|
||||
|
||||
## How It Works
|
||||
Precedence: `use_gateway: true` routes through Nous regardless of any direct keys in `.env`. `use_gateway: false` (or absent) uses direct keys if available and only falls back to the gateway when none exist.
|
||||
|
||||
When `use_gateway: true` is set for a tool, the runtime routes API calls through the Nous Tool Gateway instead of using direct API keys:
|
||||
|
||||
1. **Web tools** — `web_search` and `web_extract` use the gateway's Firecrawl endpoint
|
||||
2. **Image generation** — `image_generate` uses the gateway's FAL endpoint
|
||||
3. **TTS** — `text_to_speech` uses the gateway's OpenAI Audio endpoint
|
||||
4. **Browser** — `browser_navigate` and other browser tools use the gateway's Browser Use endpoint
|
||||
|
||||
The gateway authenticates using your Nous Portal credentials (stored in `~/.hermes/auth.json` after `hermes model`).
|
||||
|
||||
### Precedence
|
||||
|
||||
Each tool checks `use_gateway` first:
|
||||
|
||||
- **`use_gateway: true`** → route through the gateway, even if direct API keys exist in `.env`
|
||||
- **`use_gateway: false`** (or absent) → use direct API keys if available, fall back to gateway only when no direct keys exist
|
||||
|
||||
This means you can switch between gateway and direct keys at any time without deleting your `.env` credentials.
|
||||
|
||||
## Switching Back to Direct Keys
|
||||
|
||||
To stop using the gateway for a specific tool:
|
||||
|
||||
```bash
|
||||
hermes tools # Select the tool → choose a direct provider
|
||||
```
|
||||
|
||||
Or set `use_gateway: false` in config:
|
||||
### Disabling the gateway
|
||||
|
||||
```yaml
|
||||
web:
|
||||
backend: firecrawl
|
||||
use_gateway: false # Now uses FIRECRAWL_API_KEY from .env
|
||||
use_gateway: false # Hermes now uses FIRECRAWL_API_KEY from .env
|
||||
```
|
||||
|
||||
When you select a non-gateway provider in `hermes tools`, the `use_gateway` flag is automatically set to `false` to prevent contradictory config.
|
||||
`hermes tools` automatically clears the flag when you pick a non-gateway provider, so this usually happens for you.
|
||||
|
||||
## Checking Status
|
||||
### Self-hosted gateway (advanced)
|
||||
|
||||
Running your own Nous-compatible gateway? Override endpoints in `~/.hermes/.env`:
|
||||
|
||||
```bash
|
||||
hermes status
|
||||
TOOL_GATEWAY_DOMAIN=your-domain.example.com
|
||||
TOOL_GATEWAY_SCHEME=https
|
||||
TOOL_GATEWAY_USER_TOKEN=your-token # normally auto-populated from Portal login
|
||||
FIRECRAWL_GATEWAY_URL=https://... # override one endpoint specifically
|
||||
```
|
||||
|
||||
The **Nous Tool Gateway** section shows:
|
||||
|
||||
```
|
||||
◆ Nous Tool Gateway
|
||||
Nous Portal ✓ managed tools available
|
||||
Web tools ✓ active via Nous subscription
|
||||
Image gen ✓ active via Nous subscription
|
||||
TTS ✓ active via Nous subscription
|
||||
Browser ○ active via Browser Use key
|
||||
Modal ○ available via subscription (optional)
|
||||
```
|
||||
|
||||
Tools marked "active via Nous subscription" are routed through the gateway. Tools with their own keys show which provider is active.
|
||||
|
||||
## Advanced: Self-Hosted Gateway
|
||||
|
||||
For self-hosted or custom gateway deployments, you can override the gateway endpoints via environment variables in `~/.hermes/.env`:
|
||||
|
||||
```bash
|
||||
TOOL_GATEWAY_DOMAIN=nousresearch.com # Base domain for gateway routing
|
||||
TOOL_GATEWAY_SCHEME=https # HTTP or HTTPS (default: https)
|
||||
TOOL_GATEWAY_USER_TOKEN=your-token # Auth token (normally auto-populated)
|
||||
FIRECRAWL_GATEWAY_URL=https://... # Override for the Firecrawl endpoint specifically
|
||||
```
|
||||
|
||||
These env vars are always visible in the configuration regardless of subscription status — they're useful for custom infrastructure setups.
|
||||
These knobs exist for custom infrastructure setups (enterprise deployments, dev environments). Regular subscribers never set them.
|
||||
|
||||
## FAQ
|
||||
|
||||
### Do I need to delete my existing API keys?
|
||||
### Does it work with Telegram / Discord / the other messaging gateways?
|
||||
|
||||
No. When `use_gateway: true` is set, the runtime skips direct API keys and routes through the gateway. Your keys stay in `.env` untouched. If you later disable the gateway, they'll be used again automatically.
|
||||
Yes. Tool Gateway operates at the tool-execution layer, not the CLI. Every interface that can call a tool — CLI, Telegram, Discord, Slack, IRC, Teams, the API server, anything — benefits from it transparently.
|
||||
|
||||
### Can I use the gateway for some tools and direct keys for others?
|
||||
### What happens if my subscription expires?
|
||||
|
||||
Yes. The `use_gateway` flag is per-tool. You can mix and match — for example, gateway for web and image generation, your own ElevenLabs key for TTS, and Browserbase for browser automation.
|
||||
Tools routed through the gateway stop working until you renew or swap in direct API keys via `hermes tools`. Hermes shows a clear error pointing at the portal.
|
||||
|
||||
### What if my subscription expires?
|
||||
### Can I see usage or costs per tool?
|
||||
|
||||
Tools that were routed through the gateway will stop working until you [renew your subscription](https://portal.nousresearch.com/manage-subscription) or switch to direct API keys via `hermes tools`.
|
||||
Yes — the [Nous Portal dashboard](https://portal.nousresearch.com) breaks usage down by tool so you can see what's driving your bill.
|
||||
|
||||
### Does the gateway work with the messaging gateway?
|
||||
### Is Modal (serverless terminal) included?
|
||||
|
||||
Yes. The Tool Gateway routes tool API calls regardless of whether you're using the CLI, Telegram, Discord, or any other messaging platform. It operates at the tool runtime level, not the entry point level.
|
||||
Modal is available as an **optional add-on** through the Nous subscription, not part of the default Tool Gateway bundle. Configure it via `hermes setup terminal` or directly in `config.yaml` when you want a remote sandbox for shell execution.
|
||||
|
||||
### Is Modal included?
|
||||
### Do I need to delete my existing API keys when I enable the gateway?
|
||||
|
||||
Modal (serverless terminal backend) is available as an optional add-on through the Nous subscription. It's not enabled by the Tool Gateway prompt — configure it separately via `hermes setup terminal` or in `config.yaml`.
|
||||
No — keep them in `.env`. When `use_gateway: true`, Hermes skips direct keys and uses the gateway. Flip the flag back to `false` and your keys become the source again. The gateway isn't a lock-in.
|
||||
|
||||
@@ -148,8 +148,15 @@ You should see something like `10 results`. If you get a `403 Forbidden`, JSON f
|
||||
**7. Configure Hermes:**
|
||||
|
||||
```bash
|
||||
# ~/.hermes/config.yaml
|
||||
SEARXNG_URL: http://localhost:8888
|
||||
# ~/.hermes/.env
|
||||
SEARXNG_URL=http://localhost:8888
|
||||
```
|
||||
|
||||
Then select SearXNG as the search backend in `~/.hermes/config.yaml`:
|
||||
|
||||
```yaml
|
||||
web:
|
||||
search_backend: "searxng"
|
||||
```
|
||||
|
||||
Or set via `hermes tools` → Web Search & Extract → SearXNG.
|
||||
@@ -161,8 +168,8 @@ Or set via `hermes tools` → Web Search & Extract → SearXNG.
|
||||
Public SearXNG instances are listed at [searx.space](https://searx.space/). Filter by instances that have **JSON format enabled** (shown in the table).
|
||||
|
||||
```bash
|
||||
# ~/.hermes/config.yaml
|
||||
SEARXNG_URL: https://searx.example.com
|
||||
# ~/.hermes/.env
|
||||
SEARXNG_URL=https://searx.example.com
|
||||
```
|
||||
|
||||
:::caution Public instances
|
||||
|
||||
Reference in New Issue
Block a user