feat: spirit engine — seance WS, entity minting/Codex, Piper TTS voices, wire telemetry
- WS /ws/session: modes, summon, anomaly fragments, streaming direct contact,
passive wire-ghost ambient loop, per-user rate limits, event transcript
- entities: anomaly-signature fingerprinting, LLM minting + procedural
fallback, Codex matching with contact counts and sightings
- tts: 8 local Piper voices (EN/ES), per-entity voice profiles, numpy
effects chain (pitch/rate/bitcrush/echo/static)
- llm: streaming client, submit_stream in bounded queue, SpiritService
with offline fallbacks for every channel
- routes: public /api/codex, /api/codex/{id}, /api/stats; /audio static mount
- models: Entity, EntitySighting, Event, ContactSession(entity_id, language)
This commit is contained in:
@@ -6,14 +6,19 @@ from fastapi.responses import FileResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
import app.models # noqa: F401 — registers models on Base.metadata before create_all
|
||||
from app.config import settings
|
||||
from app.db import Base, engine
|
||||
from app.routes.auth import router as auth_router
|
||||
from app.routes.codex import router as codex_router
|
||||
from app.ws import AUDIO_DIR
|
||||
from app.ws import router as ws_router
|
||||
|
||||
FRONTEND_DIST = Path(__file__).resolve().parent.parent.parent / "frontend" / "dist"
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
AUDIO_DIR.mkdir(parents=True, exist_ok=True)
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
yield
|
||||
@@ -21,6 +26,8 @@ async def lifespan(app: FastAPI):
|
||||
|
||||
app = FastAPI(title="Quantumancy", lifespan=lifespan)
|
||||
app.include_router(auth_router)
|
||||
app.include_router(codex_router)
|
||||
app.include_router(ws_router)
|
||||
|
||||
|
||||
@app.get("/healthz")
|
||||
@@ -33,6 +40,11 @@ app.mount(
|
||||
StaticFiles(directory=FRONTEND_DIST / "assets", check_dir=False),
|
||||
name="frontend-assets",
|
||||
)
|
||||
app.mount(
|
||||
"/audio",
|
||||
StaticFiles(directory=AUDIO_DIR, check_dir=False),
|
||||
name="spirit-audio",
|
||||
)
|
||||
|
||||
|
||||
@app.get("/{full_path:path}")
|
||||
|
||||
Reference in New Issue
Block a user