diff --git a/apps/robo-pest/robopest-0.1.0.ehpk b/apps/robo-pest/robopest-0.1.0.ehpk index 3a494c9..b2f6235 100644 Binary files a/apps/robo-pest/robopest-0.1.0.ehpk and b/apps/robo-pest/robopest-0.1.0.ehpk differ diff --git a/apps/robo-pest/server/stt_relay.py b/apps/robo-pest/server/stt_relay.py index 526bb46..0a36b94 100644 --- a/apps/robo-pest/server/stt_relay.py +++ b/apps/robo-pest/server/stt_relay.py @@ -2,22 +2,34 @@ """Robo Pest STT relay — faster-whisper on nightmare's RTX 4080 SUPER. POST /transcribe (body: raw PCM 16kHz s16le mono bytes) -> {"text": "..."} -GET /health -> {"status": "ok", "model": ...} +GET /health -> {"status": "ok", ...} + +Auth: X-Auth-Token header required (set via STT_AUTH_TOKEN env var). +Health endpoint is open (no secrets). """ import io import os import struct import numpy as np -from fastapi import FastAPI, Request +from fastapi import FastAPI, Request, HTTPException from faster_whisper import WhisperModel MODEL_NAME = os.environ.get("STT_MODEL", "small.en") DEVICE = os.environ.get("STT_DEVICE", "cuda") +AUTH_TOKEN = os.environ.get("STT_AUTH_TOKEN", "") app = FastAPI() model = WhisperModel(MODEL_NAME, device=DEVICE, compute_type="float16") +def check_auth(request: Request): + if not AUTH_TOKEN: + return + token = request.headers.get("X-Auth-Token", "") + if token != AUTH_TOKEN: + raise HTTPException(status_code=401, detail="bad token") + + def pcm16_to_float32(data: bytes) -> np.ndarray: n = len(data) // 2 ints = struct.unpack(f"<{n}h", data[: n * 2]) @@ -31,6 +43,7 @@ def health(): @app.post("/transcribe") async def transcribe(request: Request): + check_auth(request) body = await request.body() if not body: return {"text": ""} diff --git a/apps/robo-pest/src/main.ts b/apps/robo-pest/src/main.ts index 8026d18..b82b208 100644 --- a/apps/robo-pest/src/main.ts +++ b/apps/robo-pest/src/main.ts @@ -10,6 +10,7 @@ import { TextContainerProperty, CreateStartUpPageContainer } from '@evenrealitie // Endpoints — public via Cloudflare fleet tunnel (work anywhere); LAN fallbacks in comments const STT_URL = 'https://robopest.thetempleofdoom.com/transcribe' const WORKBRAIN_URL = 'https://pestcontroller.thetempleofdoom.com/api/chat' +const AUTH_TOKEN = 'rp-EiluwonVC5JiqfNtec1253LPPvNvxLXV' // LAN: STT http://10.30.20.5:8765/transcribe | WorkBrain http://10.30.20.249/api/chat interface AskResult { @@ -20,7 +21,7 @@ interface AskResult { async function askWorkbrain(query: string, convId: string): Promise { const res = await fetch(WORKBRAIN_URL, { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers: { 'Content-Type': 'application/json', 'X-Auth-Token': AUTH_TOKEN }, body: JSON.stringify({ query, conv_id: convId }), }) const data = await res.json() @@ -36,7 +37,7 @@ async function askWorkbrain(query: string, convId: string): Promise { async function transcribe(pcm: ArrayBuffer): Promise { const res = await fetch(STT_URL, { method: 'POST', - headers: { 'Content-Type': 'application/octet-stream' }, + headers: { 'Content-Type': 'application/octet-stream', 'X-Auth-Token': AUTH_TOKEN }, body: pcm, }) const data = await res.json()