"""Chat Service — LLM orchestration, domain agents, memory. Consumes chat requests from Redis, executes deep_agent (home/floating), streams responses back via Redis pub/sub to WS Gateway. Owns: memory_core, memory_associative, memory_episodic, memory_proactive tables. """ import sys from contextlib import asynccontextmanager import logging from pathlib import Path # Ensure the repo root is on sys.path so "shared" is importable in local dev. _repo_root = str(Path(__file__).resolve().parents[3]) if _repo_root not in sys.path: sys.path.insert(0, _repo_root) from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from shared.config import settings logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s", ) logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING) logging.getLogger("sqlalchemy.pool").setLevel(logging.WARNING) @asynccontextmanager async def lifespan(app: FastAPI): # Start Redis consumer in background from app.redis_consumer import start_consumer consumer_task = start_consumer() yield consumer_task.cancel() from app.tracing import shutdown as shutdown_langfuse shutdown_langfuse() from shared.db import engine await engine.dispose() from shared.redis import redis_client await redis_client.aclose() def create_app() -> FastAPI: app = FastAPI( title="Adiuva Chat Service", version="0.1.0", docs_url="/docs" if settings.ENV == "dev" else None, redoc_url=None, lifespan=lifespan, ) app.add_middleware( CORSMiddleware, allow_origins=settings.CORS_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) from app.routes import router app.include_router(router, prefix="/api/v1") @app.get("/api/v1/health", tags=["health"]) async def health() -> dict: return {"status": "ok", "service": "chat", "version": app.version} return app app = create_app()