Add archived/hermes-api-server-setup

This commit is contained in:
2026-07-10 16:10:50 +08:00
parent 780f5cab31
commit 3cf99647c1
@@ -0,0 +1,139 @@
---
name: hermes-api-server-setup
description: "Set up Hermes Agent built-in OpenAI-compatible API server on a custom port with external access. Includes the critical extra nesting pitfall."
version: 1.0
category: devops
---
# Hermes API Server Setup
Hermes has a built-in OpenAI-compatible API server (`gateway/platforms/api_server.py`) that exposes endpoints like `/v1/chat/completions`, `/v1/responses`, `/v1/models`, `/health`, etc. Any OpenAI-compatible frontend (Open WebUI, LobeChat, LibreChat, ChatBox, etc.) can connect.
## Critical Pitfall - extra Nesting
**Host, port, key, cors_origins MUST be nested under `extra:` in config.yaml.** If placed directly under the platform name, `PlatformConfig.from_dict()` silently ignores them (it only reads `enabled`, `token`, `api_key`, `home_channel`, `reply_to_mode`, `extra`).
WRONG - binds to 127.0.0.1 only (silently ignores host/port):
```yaml
platforms:
api_server:
enabled: true
host: "0.0.0.0"
port: 8642
key: "my-secret"
```
CORRECT - binds to 0.0.0.0:
```yaml
platforms:
api_server:
enabled: true
extra:
host: "0.0.0.0"
port: 8642
key: "my-secret"
cors_origins:
- "*"
```
## Defaults
- `DEFAULT_HOST`: `127.0.0.1` (localhost only - NOT externally accessible)
- `DEFAULT_PORT`: `8642`
## Setup Steps
1. Add the `platforms:` block at the TOP LEVEL of `~/.hermes/config.yaml` (not nested under `display:` or `agent:`).
2. Ensure host is `0.0.0.0` for external access, set a `key` for API auth, and `cors_origins: ["*"]` for browser clients.
3. Restart the gateway:
```bash
systemctl --user restart hermes-gateway.service
```
4. Verify:
```bash
# Check port is listening on 0.0.0.0
ss -tlnp | grep 8642
# Health check
curl http://localhost:8642/health
# Model list (auth required)
curl http://localhost:8642/v1/models -H "Authorization: Bearer YOUR_KEY"
```
5. If `ss` shows `127.0.0.1:8642` instead of `0.0.0.0:8642`, the `extra:` nesting is wrong - recheck step 1.
## Client Connection
| Field | Value |
|------------|----------------------------------|
| Base URL | `http://YOUR_HOST:8642/v1` |
| API Key | Value of `extra.key` in config |
| Model ID | `hermes-agent` (or active profile name) |
## Available Endpoints
- `GET /health` - Health check
- `GET /v1/models` - Model list
- `POST /v1/chat/completions` - OpenAI Chat Completions (SSE streaming supported)
- `POST /v1/responses` - OpenAI Responses API (stateful)
- `GET /v1/responses/{id}` - Retrieve stored response
- `DELETE /v1/responses/{id}` - Delete stored response
- `POST /v1/runs` - Async run (returns 202 + run_id)
- `GET /v1/runs/{id}/events` - SSE stream of run lifecycle events
### Session Management Endpoints
- `GET /v1/sessions` - List sessions (query: `limit`, `offset`, `source`, `include_children`, `order_by_last_active`)
- `DELETE /v1/sessions/{session_id}` - Delete a session and its messages
- `POST /v1/sessions/prune` - Delete ended sessions older than N days (body: `older_than_days`, `source`)
- `GET /v1/capabilities` - Advertises all endpoints including sessions (third-party UIs use this for discovery)
Session IDs are validated (hex + underscore/dash only) to prevent path traversal. All session endpoints require the same `Authorization: Bearer KEY` as other endpoints.
## Troubleshooting: API Server Unresponsive
If the API server returns connection refused or times out:
1. **Check if gateway service is running:**
```bash
systemctl --user status hermes-gateway.service
```
2. **Check if port is listening:**
```bash
ss -tlnp | grep 8642
```
No output = gateway not running or API Server not started.
3. **Check gateway logs for startup errors or SIGTERM:**
```bash
cat ~/.hermes/logs/gateway.log
```
Look for `Received SIGTERM` (systemd or user killed it) or `api_server connected` (started OK).
4. **Restart gateway:**
```bash
systemctl --user restart hermes-gateway.service
# or: hermes gateway start
```
5. **Verify after restart:**
```bash
sleep 5 && curl -s http://localhost:8642/health
```
Common cause: Gateway received SIGTERM (e.g. from `hermes gateway stop`, system reboot, or OOM). The API Server is NOT a separate process — it runs inside the gateway. If the gateway dies, API Server dies with it.
## Environment Variable Alternative
Instead of config.yaml, you can also use env vars (checked at gateway startup):
- `API_SERVER_ENABLED=true`
- `API_SERVER_HOST=0.0.0.0`
- `API_SERVER_PORT=8642`
- `API_SERVER_KEY=my-secret`
- `API_SERVER_CORS_ORIGINS=*`
- `API_SERVER_MODEL_NAME=custom-name`
These are read in `gateway/config.py` and take effect if `API_SERVER_ENABLED=true` OR `API_SERVER_KEY` is set.