"""Cognitive Agent Runtime — modular package. uvicorn entrypoint: agent:app """ import logging from pathlib import Path from dotenv import load_dotenv load_dotenv(Path(__file__).parent.parent / ".env") logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(name)s] %(message)s", datefmt="%H:%M:%S") from fastapi import FastAPI, Request from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from starlette.middleware.base import BaseHTTPMiddleware from .api import register_routes class NoCacheStaticMiddleware(BaseHTTPMiddleware): """Prevent browser/CDN caching of static files during development.""" async def dispatch(self, request: Request, call_next): response = await call_next(request) if request.url.path.startswith("/static/"): response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" response.headers["Pragma"] = "no-cache" return response STATIC_DIR = Path(__file__).parent.parent / "static" app = FastAPI(title="cog") # Register all API + WS routes register_routes(app) # Serve frontend from same process (fallback for non-split deploy) # When running behind cog-frontend nginx, these paths won't be hit @app.get("/") async def index(): resp = FileResponse(STATIC_DIR / "index.html") resp.headers["Cache-Control"] = "no-cache" return resp @app.get("/tests") async def tests_page(): return FileResponse(STATIC_DIR / "tests.html") @app.get("/callback") async def callback(): """OIDC callback — serves the same SPA, JS handles the code exchange.""" return FileResponse(STATIC_DIR / "index.html") app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")