n8n调用openclaw & hermes agents 工作流架构
This commit is contained in:
256
Clippings/Open WebUI Hermes Agent.md
Normal file
256
Clippings/Open WebUI Hermes Agent.md
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
---
|
||||||
|
title: "Open WebUI | Hermes Agent"
|
||||||
|
source: "https://hermes-agent.nousresearch.com/docs/user-guide/messaging/open-webui?_highlight=api_server_enabled#hermes-agent-api-server"
|
||||||
|
author:
|
||||||
|
published:
|
||||||
|
created: 2026-04-20
|
||||||
|
description: "Connect Open WebUI to Hermes Agent via the OpenAI-compatible API server"
|
||||||
|
tags:
|
||||||
|
- "clippings"
|
||||||
|
---
|
||||||
|
[Open WebUI](https://github.com/open-webui/open-webui) (126k★) is the most popular self-hosted chat interface for AI. With Hermes Agent's built-in API server, you can use Open WebUI as a polished web frontend for your agent — complete with conversation management, user accounts, and a modern chat interface.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Open WebUI connects to Hermes Agent's API server just like it would connect to OpenAI. Your agent handles the requests with its full toolset — terminal, file operations, web search, memory, skills — and returns the final response.
|
||||||
|
|
||||||
|
Open WebUI talks to Hermes server-to-server, so you do not need `API_SERVER_CORS_ORIGINS` for this integration.
|
||||||
|
|
||||||
|
## Quick Setup
|
||||||
|
|
||||||
|
### 1\. Enable the API server
|
||||||
|
|
||||||
|
Add to `~/.hermes/.env`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
API_SERVER_ENABLED=true
|
||||||
|
API_SERVER_KEY=your-secret-key
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2\. Start Hermes Agent gateway
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hermes gateway
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
[API Server] API server listening on http://127.0.0.1:8642
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3\. Start Open WebUI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d -p 3000:8080 \
|
||||||
|
-e OPENAI_API_BASE_URL=http://host.docker.internal:8642/v1 \
|
||||||
|
-e OPENAI_API_KEY=your-secret-key \
|
||||||
|
--add-host=host.docker.internal:host-gateway \
|
||||||
|
-v open-webui:/app/backend/data \
|
||||||
|
--name open-webui \
|
||||||
|
--restart always \
|
||||||
|
ghcr.io/open-webui/open-webui:main
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4\. Open the UI
|
||||||
|
|
||||||
|
Go to **[http://localhost:3000](http://localhost:3000/)**. Create your admin account (the first user becomes admin). You should see your agent in the model dropdown (named after your profile, or **hermes-agent** for the default profile). Start chatting!
|
||||||
|
|
||||||
|
## Docker Compose Setup
|
||||||
|
|
||||||
|
For a more permanent setup, create a `docker-compose.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
open-webui:
|
||||||
|
image: ghcr.io/open-webui/open-webui:main
|
||||||
|
ports:
|
||||||
|
- "3000:8080"
|
||||||
|
volumes:
|
||||||
|
- open-webui:/app/backend/data
|
||||||
|
environment:
|
||||||
|
- OPENAI_API_BASE_URL=http://host.docker.internal:8642/v1
|
||||||
|
- OPENAI_API_KEY=your-secret-key
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
open-webui:
|
||||||
|
```
|
||||||
|
|
||||||
|
Then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuring via the Admin UI
|
||||||
|
|
||||||
|
If you prefer to configure the connection through the UI instead of environment variables:
|
||||||
|
|
||||||
|
1. Log in to Open WebUI at **[http://localhost:3000](http://localhost:3000/)**
|
||||||
|
2. Click your **profile avatar** → **Admin Settings**
|
||||||
|
3. Go to **Connections**
|
||||||
|
4. Under **OpenAI API**, click the **wrench icon** (Manage)
|
||||||
|
5. Click **\+ Add New Connection**
|
||||||
|
6. Enter:
|
||||||
|
- **URL**: `http://host.docker.internal:8642/v1`
|
||||||
|
- **API Key**: your key or any non-empty value (e.g., `not-needed`)
|
||||||
|
7. Click the **checkmark** to verify the connection
|
||||||
|
8. **Save**
|
||||||
|
|
||||||
|
Your agent model should now appear in the model dropdown (named after your profile, or **hermes-agent** for the default profile).
|
||||||
|
|
||||||
|
> [!-warning] -warning
|
||||||
|
> warning
|
||||||
|
>
|
||||||
|
> Environment variables only take effect on Open WebUI's **first launch**. After that, connection settings are stored in its internal database. To change them later, use the Admin UI or delete the Docker volume and start fresh.
|
||||||
|
|
||||||
|
## API Type: Chat Completions vs Responses
|
||||||
|
|
||||||
|
Open WebUI supports two API modes when connecting to a backend:
|
||||||
|
|
||||||
|
| Mode | Format | When to use |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| **Chat Completions** (default) | `/v1/chat/completions` | Recommended. Works out of the box. |
|
||||||
|
| **Responses** (experimental) | `/v1/responses` | For server-side conversation state via `previous_response_id`. |
|
||||||
|
|
||||||
|
### Using Chat Completions (recommended)
|
||||||
|
|
||||||
|
This is the default and requires no extra configuration. Open WebUI sends standard OpenAI-format requests and Hermes Agent responds accordingly. Each request includes the full conversation history.
|
||||||
|
|
||||||
|
### Using Responses API
|
||||||
|
|
||||||
|
To use the Responses API mode:
|
||||||
|
|
||||||
|
1. Go to **Admin Settings** → **Connections** → **OpenAI** → **Manage**
|
||||||
|
2. Edit your hermes-agent connection
|
||||||
|
3. Change **API Type** from "Chat Completions" to **"Responses (Experimental)"**
|
||||||
|
4. Save
|
||||||
|
|
||||||
|
With the Responses API, Open WebUI sends requests in the Responses format (`input` array + `instructions`), and Hermes Agent can preserve full tool call history across turns via `previous_response_id`. When `stream: true`, Hermes also streams spec-native `function_call` and `function_call_output` items, which enables custom structured tool-call UI in clients that render Responses events.
|
||||||
|
|
||||||
|
> [!-secondary] -secondary
|
||||||
|
> note
|
||||||
|
>
|
||||||
|
> Open WebUI currently manages conversation history client-side even in Responses mode — it sends the full message history in each request rather than using `previous_response_id`. The main advantage of Responses mode today is the structured event stream: text deltas, `function_call`, and `function_call_output` items arrive as OpenAI Responses SSE events instead of Chat Completions chunks.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
When you send a message in Open WebUI:
|
||||||
|
|
||||||
|
1. Open WebUI sends a `POST /v1/chat/completions` request with your message and conversation history
|
||||||
|
2. Hermes Agent creates an AIAgent instance with its full toolset
|
||||||
|
3. The agent processes your request — it may call tools (terminal, file operations, web search, etc.)
|
||||||
|
4. As tools execute, **inline progress messages stream to the UI** so you can see what the agent is doing (e.g. `` `💻 ls -la` ``, `` `🔍 Python 3.12 release` ``)
|
||||||
|
5. The agent's final text response streams back to Open WebUI
|
||||||
|
6. Open WebUI displays the response in its chat interface
|
||||||
|
|
||||||
|
Your agent has access to all the same tools and capabilities as when using the CLI or Telegram — the only difference is the frontend.
|
||||||
|
|
||||||
|
> [!-success] -success
|
||||||
|
> Tool Progress
|
||||||
|
>
|
||||||
|
> With streaming enabled (the default), you'll see brief inline indicators as tools run — the tool emoji and its key argument. These appear in the response stream before the agent's final answer, giving you visibility into what's happening behind the scenes.
|
||||||
|
|
||||||
|
## Configuration Reference
|
||||||
|
|
||||||
|
### Hermes Agent (API server)
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `==API_SERVER_ENABLED==` | `false` | Enable the API server |
|
||||||
|
| `API_SERVER_PORT` | `8642` | HTTP server port |
|
||||||
|
| `API_SERVER_HOST` | `127.0.0.1` | Bind address |
|
||||||
|
| `API_SERVER_KEY` | *(required)* | Bearer token for auth. Match `OPENAI_API_KEY`. |
|
||||||
|
|
||||||
|
### Open WebUI
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| `OPENAI_API_BASE_URL` | Hermes Agent's API URL (include `/v1`) |
|
||||||
|
| `OPENAI_API_KEY` | Must be non-empty. Match your `API_SERVER_KEY`. |
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### No models appear in the dropdown
|
||||||
|
|
||||||
|
- **Check the URL has `/v1` suffix**: `http://host.docker.internal:8642/v1` (not just `:8642`)
|
||||||
|
- **Verify the gateway is running**: `curl http://localhost:8642/health` should return `{"status": "ok"}`
|
||||||
|
- **Check model listing**: `curl http://localhost:8642/v1/models` should return a list with `hermes-agent`
|
||||||
|
- **Docker networking**: From inside Docker, `localhost` means the container, not your host. Use `host.docker.internal` or `--network=host`.
|
||||||
|
|
||||||
|
### Connection test passes but no models load
|
||||||
|
|
||||||
|
This is almost always the missing `/v1` suffix. Open WebUI's connection test is a basic connectivity check — it doesn't verify model listing works.
|
||||||
|
|
||||||
|
### Response takes a long time
|
||||||
|
|
||||||
|
Hermes Agent may be executing multiple tool calls (reading files, running commands, searching the web) before producing its final response. This is normal for complex queries. The response appears all at once when the agent finishes.
|
||||||
|
|
||||||
|
### "Invalid API key" errors
|
||||||
|
|
||||||
|
Make sure your `OPENAI_API_KEY` in Open WebUI matches the `API_SERVER_KEY` in Hermes Agent.
|
||||||
|
|
||||||
|
## Multi-User Setup with Profiles
|
||||||
|
|
||||||
|
To run separate Hermes instances per user — each with their own config, memory, and skills — use [profiles](https://hermes-agent.nousresearch.com/docs/user-guide/profiles). Each profile runs its own API server on a different port and automatically advertises the profile name as the model in Open WebUI.
|
||||||
|
|
||||||
|
### 1\. Create profiles and configure API servers
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hermes profile create alice
|
||||||
|
hermes -p alice config set API_SERVER_ENABLED true
|
||||||
|
hermes -p alice config set API_SERVER_PORT 8643
|
||||||
|
hermes -p alice config set API_SERVER_KEY alice-secret
|
||||||
|
|
||||||
|
hermes profile create bob
|
||||||
|
hermes -p bob config set API_SERVER_ENABLED true
|
||||||
|
hermes -p bob config set API_SERVER_PORT 8644
|
||||||
|
hermes -p bob config set API_SERVER_KEY bob-secret
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2\. Start each gateway
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hermes -p alice gateway &
|
||||||
|
hermes -p bob gateway &
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3\. Add connections in Open WebUI
|
||||||
|
|
||||||
|
In **Admin Settings** → **Connections** → **OpenAI API** → **Manage**, add one connection per profile:
|
||||||
|
|
||||||
|
| Connection | URL | API Key |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Alice | `http://host.docker.internal:8643/v1` | `alice-secret` |
|
||||||
|
| Bob | `http://host.docker.internal:8644/v1` | `bob-secret` |
|
||||||
|
|
||||||
|
The model dropdown will show `alice` and `bob` as distinct models. You can assign models to Open WebUI users via the admin panel, giving each user their own isolated Hermes agent.
|
||||||
|
|
||||||
|
> [!-success] -success
|
||||||
|
> Custom Model Names
|
||||||
|
>
|
||||||
|
> The model name defaults to the profile name. To override it, set `API_SERVER_MODEL_NAME` in the profile's `.env`:
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> hermes -p alice config set API_SERVER_MODEL_NAME "Alice's Agent"
|
||||||
|
> ```
|
||||||
|
|
||||||
|
## Linux Docker (no Docker Desktop)
|
||||||
|
|
||||||
|
On Linux without Docker Desktop, `host.docker.internal` doesn't resolve by default. Options:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Option 1: Add host mapping
|
||||||
|
docker run --add-host=host.docker.internal:host-gateway ...
|
||||||
|
|
||||||
|
# Option 2: Use host networking
|
||||||
|
docker run --network=host -e OPENAI_API_BASE_URL=http://localhost:8642/v1 ...
|
||||||
|
|
||||||
|
# Option 3: Use Docker bridge IP
|
||||||
|
docker run -e OPENAI_API_BASE_URL=http://172.17.0.1:8642/v1 ...
|
||||||
|
```
|
||||||
@@ -0,0 +1,355 @@
|
|||||||
|
---
|
||||||
|
title: "hermes-agent/website/docs/user-guide/features/api-server.md at main"
|
||||||
|
source: "https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/features/api-server.md"
|
||||||
|
author:
|
||||||
|
published:
|
||||||
|
created: 2026-04-20
|
||||||
|
description: "The agent that grows with you. Contribute to NousResearch/hermes-agent development by creating an account on GitHub."
|
||||||
|
tags:
|
||||||
|
- "clippings"
|
||||||
|
---
|
||||||
|
| sidebar\_position | 14 |
|
||||||
|
| ----------------- | ---------------------------------------------------------------- |
|
||||||
|
| title | API Server |
|
||||||
|
| description | Expose hermes-agent as an OpenAI-compatible API for any frontend |
|
||||||
|
|
||||||
|
## API Server
|
||||||
|
|
||||||
|
The API server exposes hermes-agent as an OpenAI-compatible HTTP endpoint. Any frontend that speaks the OpenAI format — Open WebUI, LobeChat, LibreChat, NextChat, ChatBox, and hundreds more — can connect to hermes-agent and use it as a backend.
|
||||||
|
|
||||||
|
Your agent handles requests with its full toolset (terminal, file operations, web search, memory, skills) and returns the final response. When streaming, tool progress indicators appear inline so frontends can show what the agent is doing.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### 1\. Enable the API server
|
||||||
|
|
||||||
|
Add to `~/.hermes/.env`:
|
||||||
|
|
||||||
|
```
|
||||||
|
API_SERVER_ENABLED=true
|
||||||
|
API_SERVER_KEY=change-me-local-dev
|
||||||
|
# Optional: only if a browser must call Hermes directly
|
||||||
|
# API_SERVER_CORS_ORIGINS=http://localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2\. Start the gateway
|
||||||
|
|
||||||
|
```
|
||||||
|
hermes gateway
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll see:
|
||||||
|
|
||||||
|
```
|
||||||
|
[API Server] API server listening on http://127.0.0.1:8642
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3\. Connect a frontend
|
||||||
|
|
||||||
|
Point any OpenAI-compatible client at `http://localhost:8642/v1`:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Test with curl
|
||||||
|
curl http://localhost:8642/v1/chat/completions \
|
||||||
|
-H "Authorization: Bearer change-me-local-dev" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"model": "hermes-agent", "messages": [{"role": "user", "content": "Hello!"}]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Or connect Open WebUI, LobeChat, or any other frontend — see the [Open WebUI integration guide](https://github.com/NousResearch/hermes-agent/blob/main/docs/user-guide/messaging/open-webui) for step-by-step instructions.
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
### POST /v1/chat/completions
|
||||||
|
|
||||||
|
Standard OpenAI Chat Completions format. Stateless — the full conversation is included in each request via the `messages` array.
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"model": "hermes-agent",
|
||||||
|
"messages": [
|
||||||
|
{"role": "system", "content": "You are a Python expert."},
|
||||||
|
{"role": "user", "content": "Write a fibonacci function"}
|
||||||
|
],
|
||||||
|
"stream": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"id": "chatcmpl-abc123",
|
||||||
|
"object": "chat.completion",
|
||||||
|
"created": 1710000000,
|
||||||
|
"model": "hermes-agent",
|
||||||
|
"choices": [{
|
||||||
|
"index": 0,
|
||||||
|
"message": {"role": "assistant", "content": "Here's a fibonacci function..."},
|
||||||
|
"finish_reason": "stop"
|
||||||
|
}],
|
||||||
|
"usage": {"prompt_tokens": 50, "completion_tokens": 200, "total_tokens": 250}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Streaming** (`"stream": true`): Returns Server-Sent Events (SSE) with token-by-token response chunks. For **Chat Completions**, the stream uses standard `chat.completion.chunk` events plus Hermes' custom `hermes.tool.progress` event for tool-start UX. For **Responses**, the stream uses OpenAI Responses event types such as `response.created`, `response.output_text.delta`, `response.output_item.added`, `response.output_item.done`, and `response.completed`.
|
||||||
|
|
||||||
|
**Tool progress in streams**:
|
||||||
|
|
||||||
|
- **Chat Completions**: Hermes emits `event: hermes.tool.progress` for tool-start visibility without polluting persisted assistant text.
|
||||||
|
- **Responses**: Hermes emits spec-native `function_call` and `function_call_output` output items during the SSE stream, so clients can render structured tool UI in real time.
|
||||||
|
|
||||||
|
### POST /v1/responses
|
||||||
|
|
||||||
|
OpenAI Responses API format. Supports server-side conversation state via `previous_response_id` — the server stores full conversation history (including tool calls and results) so multi-turn context is preserved without the client managing it.
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"model": "hermes-agent",
|
||||||
|
"input": "What files are in my project?",
|
||||||
|
"instructions": "You are a helpful coding assistant.",
|
||||||
|
"store": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"id": "resp_abc123",
|
||||||
|
"object": "response",
|
||||||
|
"status": "completed",
|
||||||
|
"model": "hermes-agent",
|
||||||
|
"output": [
|
||||||
|
{"type": "function_call", "name": "terminal", "arguments": "{\"command\": \"ls\"}", "call_id": "call_1"},
|
||||||
|
{"type": "function_call_output", "call_id": "call_1", "output": "README.md src/ tests/"},
|
||||||
|
{"type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "Your project has..."}]}
|
||||||
|
],
|
||||||
|
"usage": {"input_tokens": 50, "output_tokens": 200, "total_tokens": 250}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Multi-turn with previous\_response\_id
|
||||||
|
|
||||||
|
Chain responses to maintain full context (including tool calls) across turns:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"input": "Now show me the README",
|
||||||
|
"previous_response_id": "resp_abc123"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The server reconstructs the full conversation from the stored response chain — all previous tool calls and results are preserved. Chained requests also share the same session, so multi-turn conversations appear as a single entry in the dashboard and session history.
|
||||||
|
|
||||||
|
#### Named conversations
|
||||||
|
|
||||||
|
Use the `conversation` parameter instead of tracking response IDs:
|
||||||
|
|
||||||
|
```
|
||||||
|
{"input": "Hello", "conversation": "my-project"}
|
||||||
|
{"input": "What's in src/?", "conversation": "my-project"}
|
||||||
|
{"input": "Run the tests", "conversation": "my-project"}
|
||||||
|
```
|
||||||
|
|
||||||
|
The server automatically chains to the latest response in that conversation. Like the `/title` command for gateway sessions.
|
||||||
|
|
||||||
|
### GET /v1/responses/{id}
|
||||||
|
|
||||||
|
Retrieve a previously stored response by ID.
|
||||||
|
|
||||||
|
### DELETE /v1/responses/{id}
|
||||||
|
|
||||||
|
Delete a stored response.
|
||||||
|
|
||||||
|
### GET /v1/models
|
||||||
|
|
||||||
|
Lists the agent as an available model. The advertised model name defaults to the [profile](https://github.com/NousResearch/hermes-agent/blob/main/docs/user-guide/profiles) name (or `hermes-agent` for the default profile). Required by most frontends for model discovery.
|
||||||
|
|
||||||
|
### GET /health
|
||||||
|
|
||||||
|
Health check. Returns `{"status": "ok"}`. Also available at **GET /v1/health** for OpenAI-compatible clients that expect the `/v1/` prefix.
|
||||||
|
|
||||||
|
### GET /health/detailed
|
||||||
|
|
||||||
|
Extended health check that also reports active sessions, running agents, and resource usage. Useful for monitoring/observability tooling.
|
||||||
|
|
||||||
|
## Runs API (streaming-friendly alternative)
|
||||||
|
|
||||||
|
In addition to `/v1/chat/completions` and `/v1/responses`, the server exposes a **runs** API for long-form sessions where the client wants to subscribe to progress events instead of managing streaming themselves.
|
||||||
|
|
||||||
|
### POST /v1/runs
|
||||||
|
|
||||||
|
Create a new agent run. Returns a `run_id` that can be used to subscribe to progress events.
|
||||||
|
|
||||||
|
### GET /v1/runs/{run\_id}/events
|
||||||
|
|
||||||
|
Server-Sent Events stream of the run's tool-call progress, token deltas, and lifecycle events. Designed for dashboards and thick clients that want to attach/detach without losing state.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
### GET /api/jobs
|
||||||
|
|
||||||
|
List all scheduled jobs.
|
||||||
|
|
||||||
|
### POST /api/jobs
|
||||||
|
|
||||||
|
Create a new scheduled job. Body accepts the same shape as `hermes cron` — prompt, schedule, skills, provider override, delivery target.
|
||||||
|
|
||||||
|
### GET /api/jobs/{job\_id}
|
||||||
|
|
||||||
|
Fetch a single job's definition and last-run state.
|
||||||
|
|
||||||
|
### PATCH /api/jobs/{job\_id}
|
||||||
|
|
||||||
|
Update fields on an existing job (prompt, schedule, etc.). Partial updates are merged.
|
||||||
|
|
||||||
|
### DELETE /api/jobs/{job\_id}
|
||||||
|
|
||||||
|
Remove a job. Also cancels any in-flight run.
|
||||||
|
|
||||||
|
### POST /api/jobs/{job\_id}/pause
|
||||||
|
|
||||||
|
Pause a job without deleting it. Next-scheduled-run timestamps are suspended until resumed.
|
||||||
|
|
||||||
|
### POST /api/jobs/{job\_id}/resume
|
||||||
|
|
||||||
|
Resume a previously paused job.
|
||||||
|
|
||||||
|
### POST /api/jobs/{job\_id}/run
|
||||||
|
|
||||||
|
Trigger the job to run immediately, out of schedule.
|
||||||
|
|
||||||
|
## System Prompt Handling
|
||||||
|
|
||||||
|
When a frontend sends a `system` message (Chat Completions) or `instructions` field (Responses API), hermes-agent **layers it on top** of its core system prompt. Your agent keeps all its tools, memory, and skills — the frontend's system prompt adds extra instructions.
|
||||||
|
|
||||||
|
This means you can customize behavior per-frontend without losing capabilities:
|
||||||
|
|
||||||
|
- Open WebUI system prompt: "You are a Python expert. Always include type hints."
|
||||||
|
- The agent still has terminal, file tools, web search, memory, etc.
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Bearer token auth via the `Authorization` header:
|
||||||
|
|
||||||
|
```
|
||||||
|
Authorization: Bearer ***
|
||||||
|
```
|
||||||
|
|
||||||
|
Configure the key via `API_SERVER_KEY` env var. If you need a browser to call Hermes directly, also set `API_SERVER_CORS_ORIGINS` to an explicit allowlist.
|
||||||
|
|
||||||
|
:::warning Security The API server gives full access to hermes-agent's toolset, **including terminal commands**. When binding to a non-loopback address like `0.0.0.0`, `API_SERVER_KEY` is **required**. Also keep `API_SERVER_CORS_ORIGINS` narrow to control browser access.
|
||||||
|
|
||||||
|
The default bind address (`127.0.0.1`) is for local-only use. Browser access is disabled by default; enable it only for explicit trusted origins.:::
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `API_SERVER_ENABLED` | `false` | Enable the API server |
|
||||||
|
| `API_SERVER_PORT` | `8642` | HTTP server port |
|
||||||
|
| `API_SERVER_HOST` | `127.0.0.1` | Bind address (localhost only by default) |
|
||||||
|
| `API_SERVER_KEY` | *(none)* | Bearer token for auth |
|
||||||
|
| `API_SERVER_CORS_ORIGINS` | *(none)* | Comma-separated allowed browser origins |
|
||||||
|
| `API_SERVER_MODEL_NAME` | *(profile name)* | Model name on `/v1/models`. Defaults to profile name, or `hermes-agent` for default profile. |
|
||||||
|
|
||||||
|
### config.yaml
|
||||||
|
|
||||||
|
```
|
||||||
|
# Not yet supported — use environment variables.
|
||||||
|
# config.yaml support coming in a future release.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Headers
|
||||||
|
|
||||||
|
All responses include security headers:
|
||||||
|
|
||||||
|
- `X-Content-Type-Options: nosniff` — prevents MIME type sniffing
|
||||||
|
- `Referrer-Policy: no-referrer` — prevents referrer leakage
|
||||||
|
|
||||||
|
## CORS
|
||||||
|
|
||||||
|
The API server does **not** enable browser CORS by default.
|
||||||
|
|
||||||
|
For direct browser access, set an explicit allowlist:
|
||||||
|
|
||||||
|
```
|
||||||
|
API_SERVER_CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
When CORS is enabled:
|
||||||
|
|
||||||
|
- **Preflight responses** include `Access-Control-Max-Age: 600` (10 minute cache)
|
||||||
|
- **SSE streaming responses** include CORS headers so browser EventSource clients work correctly
|
||||||
|
- **`Idempotency-Key`** is an allowed request header — clients can send it for deduplication (responses are cached by key for 5 minutes)
|
||||||
|
|
||||||
|
Most documented frontends such as Open WebUI connect server-to-server and do not need CORS at all.
|
||||||
|
|
||||||
|
## Compatible Frontends
|
||||||
|
|
||||||
|
Any frontend that supports the OpenAI API format works. Tested/documented integrations:
|
||||||
|
|
||||||
|
| Frontend | Stars | Connection |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| [Open WebUI](https://github.com/NousResearch/hermes-agent/blob/main/docs/user-guide/messaging/open-webui) | 126k | Full guide available |
|
||||||
|
| LobeChat | 73k | Custom provider endpoint |
|
||||||
|
| LibreChat | 34k | Custom endpoint in librechat.yaml |
|
||||||
|
| AnythingLLM | 56k | Generic OpenAI provider |
|
||||||
|
| NextChat | 87k | BASE\_URL env var |
|
||||||
|
| ChatBox | 39k | API Host setting |
|
||||||
|
| Jan | 26k | Remote model config |
|
||||||
|
| HF Chat-UI | 8k | OPENAI\_BASE\_URL |
|
||||||
|
| big-AGI | 7k | Custom endpoint |
|
||||||
|
| OpenAI Python SDK | — | `OpenAI(base_url="http://localhost:8642/v1")` |
|
||||||
|
| curl | — | Direct HTTP requests |
|
||||||
|
|
||||||
|
## Multi-User Setup with Profiles
|
||||||
|
|
||||||
|
To give multiple users their own isolated Hermes instance (separate config, memory, skills), use [profiles](https://github.com/NousResearch/hermes-agent/blob/main/docs/user-guide/profiles):
|
||||||
|
|
||||||
|
```
|
||||||
|
# Create a profile per user
|
||||||
|
hermes profile create alice
|
||||||
|
hermes profile create bob
|
||||||
|
|
||||||
|
# Configure each profile's API server on a different port
|
||||||
|
hermes -p alice config set API_SERVER_ENABLED true
|
||||||
|
hermes -p alice config set API_SERVER_PORT 8643
|
||||||
|
hermes -p alice config set API_SERVER_KEY alice-secret
|
||||||
|
|
||||||
|
hermes -p bob config set API_SERVER_ENABLED true
|
||||||
|
hermes -p bob config set API_SERVER_PORT 8644
|
||||||
|
hermes -p bob config set API_SERVER_KEY bob-secret
|
||||||
|
|
||||||
|
# Start each profile's gateway
|
||||||
|
hermes -p alice gateway &
|
||||||
|
hermes -p bob gateway &
|
||||||
|
```
|
||||||
|
|
||||||
|
Each profile's API server automatically advertises the profile name as the model ID:
|
||||||
|
|
||||||
|
- `http://localhost:8643/v1/models` → model `alice`
|
||||||
|
- `http://localhost:8644/v1/models` → model `bob`
|
||||||
|
|
||||||
|
In Open WebUI, add each as a separate connection. The model dropdown shows `alice` and `bob` as distinct models, each backed by a fully isolated Hermes instance. See the [Open WebUI guide](https://github.com/NousResearch/hermes-agent/blob/main/docs/user-guide/messaging/open-webui#multi-user-setup-with-profiles) for details.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- **Response storage** — stored responses (for `previous_response_id`) are persisted in SQLite and survive gateway restarts. Max 100 stored responses (LRU eviction).
|
||||||
|
- **No file upload** — vision/document analysis via uploaded files is not yet supported through the API.
|
||||||
|
- **Model field is cosmetic** — the `model` field in requests is accepted but the actual LLM model used is configured server-side in config.yaml.
|
||||||
|
|
||||||
|
## Proxy Mode
|
||||||
|
|
||||||
|
The API server also serves as the backend for **gateway proxy mode**. When another Hermes gateway instance is configured with `GATEWAY_PROXY_URL` pointing at this API server, it forwards all messages here instead of running its own agent. This enables split deployments — for example, a Docker container handling Matrix E2EE that relays to a host-side agent.
|
||||||
|
|
||||||
|
See [Matrix Proxy Mode](https://github.com/NousResearch/hermes-agent/blob/main/docs/user-guide/messaging/matrix#proxy-mode-e2ee-on-macos) for the full setup guide.
|
||||||
115
Clippings/n8n 调用openclaw agents的工作流架构.md
Normal file
115
Clippings/n8n 调用openclaw agents的工作流架构.md
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
## OpenClaw API Server 配置
|
||||||
|
|
||||||
|
OpenClaw 的 Gateway 可以提供 OpenAI 兼容的 [Fossies](https://fossies.org/linux/openclaw/docs/gateway/openai-http-api.md) Chat Completions 端点,**默认是关闭的**,需要在配置中手动开启。
|
||||||
|
|
||||||
|
### 第一步:开启端点
|
||||||
|
|
||||||
|
编辑 `~/.openclaw/openclaw.json`,添加:
|
||||||
|
|
||||||
|
json
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"gateway": {
|
||||||
|
"port": 18789,
|
||||||
|
"mode": "local",
|
||||||
|
"bind": "lan",
|
||||||
|
"auth": {
|
||||||
|
"mode": "token",
|
||||||
|
"token": "fb97035a1b62a4f29e5cb2f9ac131bd37f021a10823f66b0"
|
||||||
|
},
|
||||||
|
"tailscale": {
|
||||||
|
"mode": "off",
|
||||||
|
"resetOnExit": false
|
||||||
|
},
|
||||||
|
"remote": {
|
||||||
|
"url": "ws://192.168.3.189:18789"
|
||||||
|
},
|
||||||
|
"nodes": {
|
||||||
|
"denyCommands": [
|
||||||
|
"camera.snap",
|
||||||
|
"camera.clip",
|
||||||
|
"screen.record",
|
||||||
|
"contacts.add",
|
||||||
|
"calendar.add",
|
||||||
|
"reminders.add",
|
||||||
|
"sms.send"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"controlUi": {
|
||||||
|
"allowInsecureAuth": true
|
||||||
|
},
|
||||||
|
"http": {
|
||||||
|
"endpoints": {
|
||||||
|
"chatCompletions": {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> `host: "0.0.0.0"` 是为了让 Docker 容器能访问,和 Hermes 同理。
|
||||||
|
|
||||||
|
然后重启 Gateway:
|
||||||
|
|
||||||
|
bash
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openclaw gateway restart
|
||||||
|
```
|
||||||
|
|
||||||
|
验证:
|
||||||
|
|
||||||
|
bash
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:18789/v1/health
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 与 Hermes 的关键区别
|
||||||
|
|
||||||
|
|项目|Hermes|OpenClaw|
|
||||||
|
|---|---|---|
|
||||||
|
|默认端口|`8642`|**`18789`**|
|
||||||
|
|Agent 指定方式|`"model": "hermes-agent"`|**`"model": "openclaw:main"`**|
|
||||||
|
|默认是否开启|✅ 开启|❌ 需手动开启|
|
||||||
|
|
||||||
|
OpenClaw 通过 `model` 字段来指定 Agent ID,格式为 `"openclaw:<agentId>"`,例如 `"openclaw:main"` 或 `"openclaw:beta"`。 [OpenClaw AI](https://openclaw-ai.com/en/docs/gateway/openai-http-api/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 在 n8n 中调用 OpenClaw
|
||||||
|
|
||||||
|
json
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"model": "openclaw:main",
|
||||||
|
"messages": [
|
||||||
|
{"role": "user", "content": "{{ $json.input }}"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| 字段 | 值 |
|
||||||
|
| ------------- | ------------------------------------------------ |
|
||||||
|
| URL | `http://192.168.3.189:18789/v1/chat/completions` |
|
||||||
|
| Authorization | `Bearer your-secret-key` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 最终架构总结
|
||||||
|
|
||||||
|
```
|
||||||
|
n8n (Docker)
|
||||||
|
│
|
||||||
|
├─ POST 192.168.3.189:8642 → Hermes Agent (port 8642)
|
||||||
|
│
|
||||||
|
└─ POST 192.168.3.189:18789 → OpenClaw Agent (port 18789)
|
||||||
|
```
|
||||||
|
|
||||||
|
两个都用同一个局域网 IP,只是端口不同,在 n8n 里分别建两个 HTTP Request 节点就可以了。你的 OpenClaw 现在是什么状态,已经安装好了吗?
|
||||||
152
Clippings/n8n调用hermes agents的工作流架构.md
Normal file
152
Clippings/n8n调用hermes agents的工作流架构.md
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
---
|
||||||
|
title: "n8n调用openclaw/hermes agents的工作流架构"
|
||||||
|
source: "https://claude.ai/chat/a18d1fa2-7e98-4f86-bac0-1167281eb151"
|
||||||
|
author:
|
||||||
|
published:
|
||||||
|
created: 2026-04-20
|
||||||
|
description: "Claude conversation with 8 messages"
|
||||||
|
tags:
|
||||||
|
- "clippings"
|
||||||
|
---
|
||||||
|
好消息!**Hermes Agent 内置了 OpenAI 兼容的 API Server**,完全不需要额外写任何代码,直接配置开启就行。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 第一步:开启 Hermes API Server
|
||||||
|
|
||||||
|
Hermes 的 API Server 会将 hermes-agent 暴露为一个 OpenAI 兼容的 HTTP 端点,默认端口是 **8642**。 [GitHub](https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/features/api-server.md)
|
||||||
|
|
||||||
|
bash
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 开启 API Server
|
||||||
|
hermes config set API_SERVER_ENABLED true
|
||||||
|
|
||||||
|
# 设置一个访问密钥(必须)
|
||||||
|
hermes config set API_SERVER_KEY your-secret-key
|
||||||
|
|
||||||
|
# 启动 Gateway(API Server 随之运行)
|
||||||
|
hermes gateway install # 安装为系统服务
|
||||||
|
hermes gateway start # 启动
|
||||||
|
```
|
||||||
|
|
||||||
|
验证是否正常运行:
|
||||||
|
|
||||||
|
bash
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8642/v1/health
|
||||||
|
# 返回 {"status": "ok"} 即成功
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
weishen@WeideMac-mini ~ % hermes config set API_SERVER_ENABLED true
|
||||||
|
✓ Set API_SERVER_ENABLED = True in /Users/weishen/.hermes/config.yaml
|
||||||
|
weishen@WeideMac-mini ~ % nano /Users/weishen/.hermes/config.yaml
|
||||||
|
weishen@WeideMac-mini ~ % hermes config set API_SERVER_KEY 01KPN2YYSEV56BZQSQX9XGW6VH
|
||||||
|
✓ Set API_SERVER_KEY = 01KPN2YYSEV56BZQSQX9XGW6VH in /Users/weishen/.hermes/config.yaml
|
||||||
|
weishen@WeideMac-mini ~ % nano /Users/weishen/.hermes/config.yaml
|
||||||
|
weishen@WeideMac-mini ~ % hermes gateway restart
|
||||||
|
✓ Service restarted
|
||||||
|
weishen@WeideMac-mini ~ % curl http://localhost:8642/v1/health
|
||||||
|
{"status": "ok", "platform": "hermes-agent"}% weishen@WeideMac-mini ~ % curl http://localhost:8642/v1/chat/completions \
|
||||||
|
-H "Authorization: Bearer 01KPN2YYSEV56BZQSQX9XGW6VH" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"model": "hermes-agent", "messages": [{"role": "user", "content": "Hello!"}]}'
|
||||||
|
{"id": "chatcmpl-e1569aadb12b4e36aedd9198b29e1", "object": "chat.completion", "created": 1776677020, "model": "hermes-agent", "choices": [{"index": 0, "message": {"role": "assistant", "content": "Hello! How can I help today?"}, "finish_reason": "stop"}], "usage": {"prompt_tokens": 11458, "completion_tokens": 63, "total_tokens": 11521}}%
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## 第二步:为每个 Agent 创建独立 Profile
|
||||||
|
|
||||||
|
你可以用 Profile 的方式为每个用户/角色创建独立的 Hermes 实例,每个 profile 跑在不同端口,配置独立的 API key。 [GitHub](https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/features/api-server.md)
|
||||||
|
|
||||||
|
bash
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建三个专用 Agent(以任务分工为例)
|
||||||
|
hermes profile create agent-researcher
|
||||||
|
hermes profile create agent-writer
|
||||||
|
hermes profile create agent-coder
|
||||||
|
|
||||||
|
# 分别配置端口和 key
|
||||||
|
hermes -p agent-researcher config set API_SERVER_ENABLED true
|
||||||
|
hermes -p agent-researcher config set API_SERVER_PORT 8643
|
||||||
|
hermes -p agent-researcher config set API_SERVER_KEY key-researcher
|
||||||
|
|
||||||
|
hermes -p agent-writer config set API_SERVER_ENABLED true
|
||||||
|
hermes -p agent-writer config set API_SERVER_PORT 8644
|
||||||
|
hermes -p agent-writer config set API_SERVER_KEY key-writer
|
||||||
|
|
||||||
|
hermes -p agent-coder config set API_SERVER_ENABLED true
|
||||||
|
hermes -p agent-coder config set API_SERVER_PORT 8645
|
||||||
|
hermes -p agent-coder config set API_SERVER_KEY key-coder
|
||||||
|
|
||||||
|
# 分别启动三个 gateway
|
||||||
|
hermes -p agent-researcher gateway &
|
||||||
|
hermes -p agent-writer gateway &
|
||||||
|
hermes -p agent-coder gateway &
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 第三步:在 n8n 中调用
|
||||||
|
|
||||||
|
每个 Agent 都是标准的 OpenAI 格式接口,在 n8n 中用 **HTTP Request 节点**:
|
||||||
|
|
||||||
|
|字段|填写内容|
|
||||||
|
|---|---|
|
||||||
|
|Method|POST|
|
||||||
|
|URL|`http://localhost:8643/v1/chat/completions`|
|
||||||
|
|Header: Authorization|`Bearer key-researcher`|
|
||||||
|
|Header: Content-Type|`application/json`|
|
||||||
|
|
||||||
|
Body(JSON):
|
||||||
|
|
||||||
|
json
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"model": "agent-researcher",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": "你是一个专门负责网络调研的Agent,请搜索并总结信息"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "{{ $json.task }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 多轮对话保持上下文(重要)
|
||||||
|
|
||||||
|
v0.7.0 起 API Server 支持通过 `X-Hermes-Session-Id` header 来保持会话连续性,让 chat-completions 客户端也能跨请求共享同一个 session。 [GitHub](https://github.com/mudrii/hermes-agent-docs)
|
||||||
|
|
||||||
|
在 n8n 的 HTTP Request 节点 Header 中加一行:
|
||||||
|
|
||||||
|
```
|
||||||
|
X-Hermes-Session-Id: my-workflow-session-001
|
||||||
|
```
|
||||||
|
|
||||||
|
这样同一个工作流里的多次调用会共享上下文,非常适合需要多步推理的任务链。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 完整架构示意
|
||||||
|
|
||||||
|
```
|
||||||
|
n8n Workflow
|
||||||
|
│
|
||||||
|
├─ [HTTP Request] → localhost:8643 (agent-researcher) → 搜索/调研
|
||||||
|
│
|
||||||
|
├─ [HTTP Request] → localhost:8644 (agent-writer) → 内容生成
|
||||||
|
│
|
||||||
|
└─ [HTTP Request] → localhost:8645 (agent-coder) → 代码任务
|
||||||
|
```
|
||||||
|
|
||||||
|
这套方案完全原生支持,不需要任何额外中间件。你现在的 Hermes 是哪个版本?可以用 `hermes version` 确认一下,部分特性需要 v0.4.0+。
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.0 MiB |
Reference in New Issue
Block a user