fix: make relay fast and concurrency-safe
This commit is contained in:
@@ -1,75 +1,95 @@
|
||||
# Hermes Relay
|
||||
# Hermes Relay v3.2
|
||||
|
||||
Flask bridge tussen Node-RED en Hermes Agent.
|
||||
|
||||
## Architectuur
|
||||
Snelle Quart-bridge tussen Node-RED en een warme Hermes Agent.
|
||||
|
||||
```text
|
||||
Node-RED ──POST /ask──▶ Quart relay ──serialized call──▶ warme Hermes-agent
|
||||
│
|
||||
├── JSON direct terug naar Node-RED
|
||||
└── Telegram-bezorging op de achtergrond via `hermes send`
|
||||
```
|
||||
Node-RED (192.168.1.125) ──POST /ask──▶ Hermes Relay (192.168.1.74:8650)
|
||||
│
|
||||
├──▶ hermes chat -q (subprocess)
|
||||
│ │
|
||||
│ ▼
|
||||
│ JSON response ──▶ Node-RED
|
||||
│
|
||||
└──▶ hermes send --to telegram
|
||||
│
|
||||
▼
|
||||
Telegram chat
|
||||
```
|
||||
|
||||
## Gedrag en grenzen
|
||||
|
||||
- **Warme agent:** Hermes wordt tijdens startup geladen/geïnitialiseerd.
|
||||
- **Veilige concurrency:** de gedeelde, mutable agent verwerkt precies één LLM-call tegelijk. Overige HTTP-verzoeken wachten in de queue; ze kunnen niet elkaars `messages` resetten.
|
||||
- **Timeout:** `HERMES_RELAY_TIMEOUT` (standaard 120 s) omvat wachttijd plus LLM-call. Een timeout retourneert HTTP `504`.
|
||||
- **Snelle response:** Telegram ligt niet meer in het HTTP-pad. Een succesvolle `/ask` reageert zodra het model antwoordt.
|
||||
- **Background delivery:** Telegram wordt betrouwbaar gelogd. Bij gecontroleerde shutdown wacht de service op lopende bezorgingen.
|
||||
|
||||
## Endpoints
|
||||
|
||||
### `POST /ask`
|
||||
Verwacht JSON body:
|
||||
|
||||
JSON body:
|
||||
|
||||
```json
|
||||
{ "payload": "Wat is het weer in Best?" }
|
||||
```
|
||||
|
||||
Response:
|
||||
Succesresponse:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"answer": "Het is 22°C en zonnig in Best...",
|
||||
"elapsed_seconds": 8.3,
|
||||
"telegram_sent": true
|
||||
"answer": "...",
|
||||
"elapsed_seconds": 6.213,
|
||||
"llm_elapsed_seconds": 6.213,
|
||||
"request_elapsed_seconds": 6.214,
|
||||
"telegram_queued": true
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /health`
|
||||
Health check voor monitoring.
|
||||
`elapsed_seconds` blijft aanwezig voor compatibiliteit en is de LLM-duur. `request_elapsed_seconds` is de feitelijke HTTP-duur. `telegram_queued` betekent dat bezorging geaccepteerd is voor de achtergrondtaak; raadpleeg journald voor het uiteindelijke bezorgresultaat.
|
||||
|
||||
## Setup
|
||||
Fouten: `400` lege payload, `413` payload groter dan limiet, `504` timeout, `502` onverwachte agentfout.
|
||||
|
||||
### `GET /health`
|
||||
|
||||
Geeft service-status, versie en het aantal lopende Telegram-bezorgingen terug.
|
||||
|
||||
- `/health?detail=true` voegt de **lokale agent-state** toe; dit doet bewust geen dure LLM/provider-call.
|
||||
|
||||
## Configuratie
|
||||
|
||||
| Variabele | Standaard | Betekenis |
|
||||
|---|---:|---|
|
||||
| `HERMES_RELAY_TIMEOUT` | `120` | Max. wachttijd + modelcall per HTTP-request |
|
||||
| `HERMES_RELAY_DELIVERY_WORKERS` | `2` | Begrensde workers voor Telegram-bezorging |
|
||||
| `HERMES_RELAY_MAX_PAYLOAD_CHARS` | `12000` | Maximale lengte van `payload` |
|
||||
| `HERMES_RELAY_MAX_TURNS` | `10` | Agent turn-budget |
|
||||
| `HERMES_RELAY_MODEL` | profieldefault | Optionele modelovertuiging |
|
||||
| `HERMES_RELAY_TOOLSETS` | leeg | Alleen invullen met geldige benodigde toolsets |
|
||||
|
||||
De relay leest zijn Hermes-config via profiel `voice-assistant`. Pas model/provider/config aan en herstart daarna de service:
|
||||
|
||||
```bash
|
||||
cd /root/hermes-relay
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Test
|
||||
python app.py
|
||||
|
||||
# Of als service
|
||||
sudo systemctl enable hermes-relay
|
||||
sudo systemctl start hermes-relay
|
||||
systemctl restart hermes-relay
|
||||
```
|
||||
|
||||
## Node-RED Nodes
|
||||
## Testen
|
||||
|
||||
### Versturen (HTTP Request node)
|
||||
- **Method:** POST
|
||||
```bash
|
||||
curl -s http://127.0.0.1:8650/health
|
||||
curl -s -X POST http://127.0.0.1:8650/ask \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"payload":"Zeg alleen hoi"}'
|
||||
|
||||
journalctl -u hermes-relay -f
|
||||
```
|
||||
|
||||
## Node-RED
|
||||
|
||||
Gebruik een HTTP Request-node:
|
||||
|
||||
- **Method:** `POST`
|
||||
- **URL:** `http://192.168.1.74:8650/ask`
|
||||
- **Return:** a parsed JSON object
|
||||
- **Timeout:** 120000 (ms) — Hermes kan even duren
|
||||
- **Return:** parsed JSON
|
||||
- **Timeout:** `120000` ms
|
||||
|
||||
### Ontvangen
|
||||
Het antwoord komt terug als `msg.payload`:
|
||||
- `msg.payload.answer` — het Hermes antwoord
|
||||
- `msg.payload.elapsed_seconds` — hoe lang het duurde
|
||||
- `msg.payload.telegram_sent` — of het ook naar Telegram is gestuurd
|
||||
- `msg.payload.status` — "ok" of "error"
|
||||
Voorafgaande Function-node:
|
||||
|
||||
### Health check (optioneel)
|
||||
- **Method:** GET
|
||||
- **URL:** `http://192.168.1.74:8650/health`
|
||||
```javascript
|
||||
msg.payload = { payload: msg.payload };
|
||||
return msg;
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user