diff --git a/app/core/config.py b/app/core/config.py index fb9b9c8..a3c86a9 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -38,6 +38,7 @@ class Config(metaclass=ConfigMeta): SIMILARITY_TOP_K: int = int(os.getenv("SIMILARITY_TOP_K", "20")) # Reranking Configuration + ENABLE_RERANKER: bool = os.getenv("ENABLE_RERANKER", "false").lower() in ("true", "1", "yes") RERANK_MODEL: str = os.getenv("RERANK_MODEL", "cross-encoder/mmarco-mMiniLMv2-L12-H384") RERANK_TOP_K: int = int(os.getenv("RERANK_TOP_K", "10")) @@ -199,3 +200,42 @@ class Config(metaclass=ConfigMeta): upload_path.mkdir(parents=True, exist_ok=True) return upload_path + @classmethod + def validate_config(cls) -> None: + """ + Validate required configuration and environment variables. + Raises ValueError if critical configuration is missing or invalid. + """ + errors = [] + + # Validate Ollama host is set + if not cls.OLLAMA_HOST: + errors.append("OLLAMA_HOST must be set") + + # Validate database path is valid + try: + db_path = Path(cls.get_db_path()) + if not db_path.parent.exists(): + try: + db_path.parent.mkdir(parents=True, exist_ok=True) + except Exception as e: + errors.append(f"Cannot create database directory: {e}") + except Exception as e: + errors.append(f"Invalid database path: {e}") + + # Validate MCP server port is valid + if not (1 <= cls.MCP_SERVER_PORT <= 65535): + errors.append(f"MCP_SERVER_PORT must be between 1-65535, got {cls.MCP_SERVER_PORT}") + + # Validate RAG configuration values + if cls.CHUNK_SIZE <= 0: + errors.append(f"CHUNK_SIZE must be positive, got {cls.CHUNK_SIZE}") + if cls.CHUNK_OVERLAP < 0 or cls.CHUNK_OVERLAP >= cls.CHUNK_SIZE: + errors.append(f"CHUNK_OVERLAP must be between 0 and CHUNK_SIZE, got {cls.CHUNK_OVERLAP}") + if cls.TOP_K_RETRIEVAL <= 0: + errors.append(f"TOP_K_RETRIEVAL must be positive, got {cls.TOP_K_RETRIEVAL}") + + if errors: + error_msg = "Configuration validation failed:\n" + "\n".join(f" - {e}" for e in errors) + raise ValueError(error_msg) + diff --git a/app/core/rag_engine.py b/app/core/rag_engine.py index a4d6ae4..36c93bb 100644 --- a/app/core/rag_engine.py +++ b/app/core/rag_engine.py @@ -131,9 +131,20 @@ class RAGEngine: similarity_top_k=Config.TOP_K_RETRIEVAL ) - # Initialize reranker (DISABLED by default due to performance issues) + # Initialize reranker (configurable via ENABLE_RERANKER environment variable) self.reranker = None - logger.info("Reranker disabled for performance (enable in code if needed)") + if Config.ENABLE_RERANKER: + try: + self.reranker = SentenceTransformerRerank( + model=Config.RERANK_MODEL, + top_n=Config.RERANK_TOP_K + ) + logger.info(f"Reranker enabled: {Config.RERANK_MODEL}") + except Exception as e: + logger.warning(f"Failed to initialize reranker: {e}. Continuing without reranker.") + self.reranker = None + else: + logger.info("Reranker disabled (set ENABLE_RERANKER=true to enable)") # Create comprehensive prompt template optimized for M4 Pro performance qa_prompt_template = PromptTemplate( diff --git a/requirements.txt b/requirements.txt index 594516e..44a002a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,6 +27,7 @@ mcp>=1.0.0 fastapi>=0.104.0 uvicorn>=0.24.0 pydantic>=2.0.0 +slowapi>=0.1.9 # Rate limiting # Authentication passlib[bcrypt]>=1.7.4