diff --git a/app/main.py b/app/main.py index c88d992..a2b04ca 100644 --- a/app/main.py +++ b/app/main.py @@ -1,5 +1,6 @@ import logging import uuid +from contextlib import asynccontextmanager from fastapi import FastAPI, HTTPException, BackgroundTasks from fastapi.middleware.cors import CORSMiddleware @@ -7,7 +8,7 @@ from fastapi.responses import StreamingResponse from app.auth import ServiceAuthDependency from app.config import settings, MAX_MESSAGE_LENGTH -from app.embeddings import RetrieverDependency, IndexerDependency, get_retriever, reset_retriever +from app.embeddings import RetrieverDependency, IndexerDependency, get_retriever, reset_retriever, get_indexer from app.embeddings.retriever import RetrievedChunk from app.intent import IntentClassifierDependency from app.llm import AdapterDependency, LLMError, llm_exception_to_http @@ -31,11 +32,35 @@ logging.basicConfig( ) logger = logging.getLogger(__name__) + +@asynccontextmanager +async def lifespan(app: FastAPI): + """Startup and shutdown lifecycle management.""" + # Startup: auto-index if FAISS index is missing + retriever = get_retriever() + if not retriever.is_loaded: + logger.info("FAISS index not found, building index on startup...") + try: + indexer = get_indexer() + result = await indexer.build_index() + reset_retriever() # Reset to load newly built index + logger.info(f"Startup indexing completed: {result.chunks_indexed} chunks from {result.artifacts_processed} artifacts") + except Exception as e: + logger.error(f"Startup indexing failed: {e}") + else: + logger.info(f"FAISS index loaded: {retriever.index_size} vectors") + + yield # App runs here + + # Shutdown: nothing to clean up + + # Create FastAPI app app = FastAPI( title="Tyndale AI Service", description="LLM Chat Service for algorithmic trading support", version="0.1.0", + lifespan=lifespan, ) # Add CORS middleware