feat(gateway-chat): auto-voice quoted dialogue via mOrpheus TTS

Gateway-chat now auto-plays quoted text from each assistant reply through the mOrpheus
TTS endpoint. Sidebar gains a 🔊 toggle + endpoint/voice fields (persist in localStorage,
prefilled to irv-ml1:8299 / baddy). On reply-complete, straight and typographic double
quotes are extracted, joined, POSTed to /tts, and the returned WAV plays (click 🔊 to
replay; a new reply interrupts the prior clip).

Requires CORS on the wrapper (page served from ana-docker:8091 fetches irv-ml1:8299
cross-origin) — added CORSMiddleware(allow_origins=[*]) to the mOrpheus tts app (internal-
only endpoint). Verified end-to-end: preflight + POST return ACAO=*, valid 24kHz WAV.

Deployed: tts container rebuilt/recreated on irv-ml1; page pushed to ana-docker conf
(bind-mounted, live on next request).
This commit is contained in:
vh
2026-07-09 00:58:13 -07:00
parent 01eedd8d27
commit c948013a36
3 changed files with 87 additions and 4 deletions
+5
View File
@@ -16,6 +16,7 @@ import numpy as np, torch, soundfile as sf, requests
from scipy.signal import resample_poly
from fastapi import FastAPI, HTTPException
from fastapi.responses import Response
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from transformers import AutoTokenizer
from snac import SNAC
@@ -33,6 +34,10 @@ AUDIO_BASE, SOS, EOS_SP, SOH, SOA, EOT, BOS = 128266, 128257, 128258, 128259, 12
tok = AutoTokenizer.from_pretrained(MODEL_DIR)
snac_model = SNAC.from_pretrained(SNAC_DIR).to(SNAC_DEVICE).eval()
app = FastAPI(title="mOrpheus TTS", version="0.1.0")
# INTERNAL RESEARCH: browser callers (e.g. gateway-chat on ana-docker:8091) fetch this
# cross-origin; allow all origins on this internal-only endpoint.
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"],
allow_headers=["*"], expose_headers=["X-Audio-Seconds"])
class TTSReq(BaseModel):