""" Hermes Relay — Flask bridge tussen Node-RED en Hermes Agent (v2.0). 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: str) -> bool: """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(f"Telegram send failed: {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(f"Received: {prompt[:100]}...") # Roep Hermes aan (direct, geen subprocess) answer = _hermes_query(prompt) elapsed = round(time.time() - start, 1) logger.info(f"Answer ({elapsed}s): {answer[:200]}...") # Stuur ook naar Telegram tg_msg = f"🤖 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", "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)