seed repo scaffold
This commit is contained in:
parent
7789477e1a
commit
87ffa7ec60
69
services/router/server.py
Normal file
69
services/router/server.py
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
"""Router: mic/WebSocket -> brain -> TTS -> avatar -> RTMP streaming glue."""
|
||||||
|
import os, json, queue, threading, time
|
||||||
|
from pathlib import Path
|
||||||
|
from flask import Flask, request, jsonify
|
||||||
|
from flask_sock import Sock
|
||||||
|
import requests
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
sock = Sock(app)
|
||||||
|
|
||||||
|
BRAIN = os.getenv("BRAIN_URL", "http://brain:11434")
|
||||||
|
TTS = os.getenv("TTS_URL", "http://tts:5002")
|
||||||
|
PERSONA = os.getenv("PERSONA", "/app/persona.yaml")
|
||||||
|
|
||||||
|
response_q = queue.Queue()
|
||||||
|
|
||||||
|
def build_prompt(user_text):
|
||||||
|
return user_text
|
||||||
|
|
||||||
|
def brain_reply(prompt):
|
||||||
|
try:
|
||||||
|
r = requests.post(f"{BRAIN}/api/generate", json={"model":"llama3.2:1b","prompt":prompt,"stream":False}, timeout=20)
|
||||||
|
return r.json().get("response","")
|
||||||
|
except Exception as e:
|
||||||
|
return f"*static from the aether* {e}"
|
||||||
|
|
||||||
|
def tts_synth(text):
|
||||||
|
try:
|
||||||
|
r = requests.post(f"{TTS}/synthesize", json={"text": text}, timeout=20)
|
||||||
|
return r.content
|
||||||
|
except Exception:
|
||||||
|
return b""
|
||||||
|
|
||||||
|
def run_job(text):
|
||||||
|
prompt = build_prompt(text)
|
||||||
|
reply = brain_reply(prompt)
|
||||||
|
audio = tts_synth(reply)
|
||||||
|
response_q.put({"text": reply, "audio": audio})
|
||||||
|
|
||||||
|
@app.post("/say")
|
||||||
|
def say():
|
||||||
|
data = request.get_json(force=True)
|
||||||
|
text = data.get("text", "")
|
||||||
|
if not text:
|
||||||
|
return jsonify({"error": "text required"}), 400
|
||||||
|
threading.Thread(target=run_job, args=(text,), daemon=True).start()
|
||||||
|
return jsonify({"queued": True})
|
||||||
|
|
||||||
|
@app.get("/health")
|
||||||
|
def health():
|
||||||
|
return {"status": "ok", "queued": response_q.qsize()}
|
||||||
|
|
||||||
|
@sock.route("/ws")
|
||||||
|
def ws(ws):
|
||||||
|
while True:
|
||||||
|
msg = ws.receive()
|
||||||
|
if msg is None:
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
data = json.loads(msg)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
if data.get("type") == "text":
|
||||||
|
run_job(data.get("text",""))
|
||||||
|
result = response_q.get()
|
||||||
|
ws.send(json.dumps(result))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(host="0.0.0.0", port=8787)
|
||||||
Loading…
Reference in New Issue
Block a user