from functools import lru_cache import logging from pathlib import Path from pydantic_settings import BaseSettings logger = logging.getLogger(__name__) class Settings(BaseSettings): # LLM access (OpenRouter / vLLM) llm_base_url: str = "https://openrouter.ai/api/v1" llm_api_key: str = "" llm_model_name: str = "qwen/qwen3.5-35b-a3b" llm_enable_thinking: bool = False vllm_engine: bool = False # Deepseek API (decompose step only, Package 6) dp_base_url: str = "https://api.deepseek.com" dp_api_key: str = "" dp_model_name: str = "deepseek-v4-flash" # Embeddings embedding_model: str = "qwen/qwen3-embedding-4b" embedding_base_url: str = "https://openrouter.ai/api/v1" embedding_api_key: str = "" # ChromaDB chroma_db_path: str = "./chroma_db" # Chunk PDF storage (extracted PDF pages) document_chunk_path: str = "./document_chunk" # SQLite databases (Package 3) prompts_db_path: str = "./data/prompts.db" history_db_path: str = "./data/history.db" # App configuration moved to settings for easier testing/configuration # Cross-origin settings and chunking parameters (Phase 1 plan) cors_origins: list[str] = ["http://localhost:5173", "http://localhost:3000"] chunk_size: int = 1000 chunk_overlap: int = 200 retrieval_n_results: int = 10 relevance_threshold: float = 7.0 llm_timeout: float = 60.0 # Alibaba Cloud DashScope ASR (Phase 2) dashscope_api_key: str = "" asr_model_name: str = "qwen3-asr-flash" asr_realtime_model_name: str = "qwen3-asr-flash-realtime" # Video upload (Phase 2) video_upload_dir: str = "./uploads" max_video_size_mb: int = 300 supported_video_formats: list[str] = [".mp4", ".webm", ".mov", ".avi", ".mkv"] # Phase 4 — Live audio capture toggles system_audio_enabled: bool = True mic_enabled: bool = True # Development helpers model_config = {"env_file": ".env", "env_file_encoding": "utf-8"} @lru_cache def get_settings() -> Settings: s = Settings() logger.info("Settings loaded: llm_model=%s embedding_model=%s", s.llm_model_name, s.embedding_model) return s