117 lines
4.1 KiB
Python
117 lines
4.1 KiB
Python
"""
|
|
Hermes Relay v2 — Flask bridge tussen Node-RED en Hermes Agent.
|
|
|
|
Gebruikt een warme Hermes agent (directe Python import) in plaats van
|
|
subprocess per query. Dit bespaart ~3-5 seconden startup tijd per query.
|
|
|
|
Node-RED stuurt POST met msg.payload → Hermes (direct) → Antwoord + Telegram.
|
|
|
|
Endpoints:
|
|
POST /ask — main relay endpoint
|
|
GET /health — health check
|
|
"""
|
|
import os
|
|
import sys
|
|
import time
|
|
import logging
|
|
|
|
# ── Hermes path toevoegen (zodat we Hermes direct kunnen importeren) ───
|
|
_HERMES_SITE = '/usr/local/lib/hermes-agent/venv/lib/python3.11/site-packages'
|
|
if _HERMES_SITE not in sys.path:
|
|
sys.path.insert(0, _HERMES_SITE)
|
|
|
|
from flask import Flask, request, jsonify
|
|
|
|
# ── Config ──────────────────────────────────────────────────────────────
|
|
TIMEOUT = 120 # max seconden voor Hermes query
|
|
TG_TARGET = "telegram" # hermes send target
|
|
PROMPT_PREFIX = "/fast" # wordt aan elke prompt toegevoegd
|
|
MODEL = "qwen3.7-max" # model override (leeg = default uit config)
|
|
|
|
# ── Logging ─────────────────────────────────────────────────────────────
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="[hermes-relay] %(asctime)s %(levelname)s %(message)s",
|
|
stream=sys.stderr,
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# ── Flask app ───────────────────────────────────────────────────────────
|
|
app = Flask(__name__)
|
|
|
|
# ── Hermes warm houden ──────────────────────────────────────────────────
|
|
# Import de Hermes client (triggert eenmalige module laden)
|
|
HERMES_BIN = "/usr/local/bin/hermes" # nog steeds nodig voor hermes send
|
|
from hermes_client import call_hermes as _hermes_query
|
|
|
|
|
|
def send_telegram(text):
|
|
"""Stuur bericht via hermes send subprocess."""
|
|
import subprocess
|
|
try:
|
|
result = subprocess.run(
|
|
[HERMES_BIN, "send", "--to", TG_TARGET, "--quiet", text],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=30,
|
|
)
|
|
return result.returncode == 0
|
|
except Exception as e:
|
|
logger.error("Telegram send failed: %s", e)
|
|
return False
|
|
|
|
|
|
# ── Routes ──────────────────────────────────────────────────────────────
|
|
|
|
@app.route("/ask", methods=["POST"])
|
|
def ask():
|
|
"""Main relay endpoint."""
|
|
start = time.time()
|
|
|
|
# Parse input
|
|
if request.is_json:
|
|
data = request.get_json(silent=True) or {}
|
|
prompt = data.get("payload", "")
|
|
else:
|
|
prompt = request.form.get("payload", "")
|
|
|
|
if not prompt:
|
|
return jsonify({"status": "error", "message": "No payload received"}), 400
|
|
|
|
logger.info("Received: %s...", prompt[:100])
|
|
|
|
# Roep Hermes aan (direct, geen subprocess)
|
|
answer = _hermes_query(prompt)
|
|
elapsed = round(time.time() - start, 1)
|
|
|
|
logger.info("Answer (%.1fs): %s...", elapsed, answer[:200])
|
|
|
|
# Stuur ook naar Telegram
|
|
tg_msg = "🤖 Hermes Relay\n\nVraag: " + prompt + "\n\nAntwoord: " + answer
|
|
tg_sent = send_telegram(tg_msg)
|
|
|
|
return jsonify({
|
|
"status": "ok",
|
|
"answer": answer,
|
|
"elapsed_seconds": elapsed,
|
|
"telegram_sent": tg_sent,
|
|
})
|
|
|
|
|
|
@app.route("/health", methods=["GET"])
|
|
def health():
|
|
"""Health check voor Node-RED monitoring."""
|
|
return jsonify({
|
|
"status": "ok",
|
|
"service": "hermes-relay",
|
|
"version": "2.0",
|
|
"mode": "python-import",
|
|
"model": MODEL or "(default)",
|
|
"prompt_prefix": PROMPT_PREFIX or "(none)",
|
|
})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
logger.info("Starting Hermes Relay v2.0 (warme agent)...")
|
|
app.run(host="0.0.0.0", port=8650, debug=False)
|