""" LifeFlow AI - Configuration 整合 Agno Agent 系統配置 """ import os from pathlib import Path from dotenv import load_dotenv load_dotenv() # 這行會自動尋找並讀取專案根目錄下的 .env 檔案 # ===== 系統預設值 ===== BASE_DIR = Path(__file__).parent MCP_SERVER_PATH = "mcp_server_lifeflow.py" LOG_LEVEL = "DEBUG" DEFAULT_PROVIDER = "Gemini" DEFAULT_MODEL = "gemini-2.5-flash" # ===== 應用配置 ===== APP_TITLE = "LifeFlow AI - Intelligent Daily Trip Planner" # ===== 模型白名單配置 (Model Allowlist) ===== # 格式: Key 是 Provider 名稱, Value 是 (顯示名稱, API Model ID) 的列表 MODEL_OPTIONS = { "Gemini": [ # 平衡型 (預設) ("Gemini 2.5 Flash (🔥 Best Value)", "gemini-2.5-flash"), # 速度型 (舊版 Flash 其實不用列,除非它有特殊用途,不然建議隱藏) # ("Gemini 2.0 Flash (⚡ High Speed)", "gemini-2.0-flash"), # 智力型 ("Gemini 2.5 Pro (🧠 Max Intelligence)", "gemini-2.5-pro"), ], "OpenAI": [ ("GPT-5 Mini (⚖️ Smart & Fast)", "gpt-5-mini"), #("GPT-4o Mini (💰 Cost Saver)", "gpt-4o-mini"), # 旗艦型 ("GPT-5 (🌟 Ultimate Quality)", "gpt-5"), ], "Groq": [ ("Llama 3.3 70B (🚀 Ultra Fast [Alpha])", "llama-3.3-70b-versatile"), ("GPT-OSS 120B (💪 Reasoning Powerhouse [Alpha])", "openai/gpt-oss-120b"), ("Kimi K2 (💪 Long Context Expert [Alpha])", "moonshotai/kimi-k2-instruct-0905"), ] } GROQ_FAST_MODEL_OPTIONS = [ ("GPT-OSS 20B", "openai/gpt-oss-20b"), #("Llama 3.1 8B", "llama-3.1-8b-instant"), #("Llama 4 scout", "llama-4-scout-17b-16e-instructe"), ("QWEN 3 32B", "qwen/qwen3-32b") ] # ===== Agent 資訊配置 (前端顯示用) ===== AGENTS_INFO = { 'planner': { 'name': 'Planner', 'role': 'Task Analyzer', 'icon': '📋', 'avatar': '📋', 'color': '#f093fb', 'glow': 'rgba(240, 147, 251, 0.3)' }, 'scout': { 'name': 'Scout', 'role': 'POI Searcher', 'icon': '🗺️', 'avatar': '🗺️', 'color': '#4facfe', 'glow': 'rgba(79, 172, 254, 0.3)' }, 'optimizer': { 'name': 'Optimizer', 'role': 'Route Optimizer', 'icon': '⚡', 'avatar': '⚡', 'color': '#43e97b', 'glow': 'rgba(67, 233, 123, 0.3)' }, 'validator': { 'name': 'Validator', 'role': 'Feasibility Checker', 'icon': '✅', 'avatar': '✅', 'color': '#fa709a', 'glow': 'rgba(250, 112, 154, 0.3)' }, 'weather': { 'name': 'Weather', 'role': 'Weather Advisor', 'icon': '🌤️', 'avatar': '🌤️', 'color': '#feca57', 'glow': 'rgba(254, 202, 87, 0.3)' }, 'traffic': { 'name': 'Traffic', 'role': 'Traffic Analyzer', 'icon': '🚗', 'avatar': '🚗', 'color': '#ff6348', 'glow': 'rgba(255, 99, 72, 0.3)' }, 'navigator': { 'name': 'Navigator', 'role': 'Route Navigator', 'icon': '🧭', 'avatar': '🧭', 'color': '#5f27cd', 'glow': 'rgba(95, 39, 205, 0.3)' }, 'weatherman': { 'name': 'Weatherman', 'role': 'Weather Forecaster', 'icon': '⛅', 'avatar': '⛅', 'color': '#00d2d3', 'glow': 'rgba(0, 210, 211, 0.3)' }, 'presenter': { 'name': 'Presenter', 'role': 'Report Generator', 'icon': '📊', 'avatar': '📊', 'color': '#ee5a6f', 'glow': 'rgba(238, 90, 111, 0.3)' }, 'team': { 'name': 'Team Leader', 'role': 'Orchestrator', 'icon': '👨‍✈️', 'avatar': '👨‍✈️', 'color': '#0abde3', 'glow': 'rgba(10, 189, 227, 0.3)' } } # ===== API Keys (從環境變數讀取) ===== DEFAULT_SETTINGS = { 'google_maps_api_key': os.getenv('GOOGLE_MAPS_API_KEY', ''), 'openweather_api_key': os.getenv('OPENWEATHER_API_KEY', ''), 'anthropic_api_key': os.getenv('ANTHROPIC_API_KEY', ''), 'gemini_api_key': os.getenv('GEMINI_API_KEY', ''), 'model': 'gemini-2.5-flash' } # ===== LLM 模型選擇 ===== MODEL_CHOICES = [ 'gemini-2.5-flash', 'gemini-2.5-flash-lite', 'claude-sonnet-4-20250514', 'claude-sonnet-3-5-20241022', 'gpt-4-turbo', 'gpt-4o' ] # ===== Agno Agent 配置 ===== AGENT_CONFIG = { # Planner Agent 配置 'planner': { 'model': 'gemini-2.5-flash', 'thinking_budget': 2048, 'temperature': 0.7, 'debug_mode': False }, # Core Team 配置 'team': { 'model': 'gemini-2.5-flash', 'thinking_budget': 1024, 'temperature': 0.7, 'debug_mode': False, 'debug_level': 1 }, # Member Agents 配置 'scout': { 'model': 'gemini-2.5-flash', 'temperature': 0.5 }, 'optimizer': { 'model': 'gemini-2.5-flash-lite', 'temperature': 0.3 }, 'navigator': { 'model': 'gemini-2.5-flash-lite', 'temperature': 0.3 }, 'weatherman': { 'model': 'gemini-2.5-flash-lite', 'temperature': 0.5 }, 'presenter': { 'model': 'gemini-2.5-flash', 'temperature': 0.7 } } # ===== 資料庫配置 ===== DATABASE_CONFIG = { 'planner_db': 'tmp/planner.db', 'team_db': 'tmp/team.db', 'poi_db': 'storage/lifeflow_payloads.db', 'offload_db': 'storage/offloaded_data.db' } # ===== 路徑配置 ===== BASE_DIR = Path(__file__).parent STORAGE_DIR = BASE_DIR / 'storage' TMP_DIR = BASE_DIR / 'tmp' LOGS_DIR = BASE_DIR / 'logs' # 確保目錄存在 for dir_path in [STORAGE_DIR, TMP_DIR, LOGS_DIR]: dir_path.mkdir(parents=True, exist_ok=True) # ===== 日誌配置 ===== LOGGING_CONFIG = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'default': { 'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s' }, 'detailed': { 'format': '%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s' } }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'level': 'INFO', 'formatter': 'default', 'stream': 'ext://sys.stdout' }, 'file': { 'class': 'logging.handlers.RotatingFileHandler', 'level': 'DEBUG', 'formatter': 'detailed', 'filename': str(LOGS_DIR / 'lifeflow.log'), 'maxBytes': 10485760, # 10MB 'backupCount': 5 } }, 'root': { 'level': 'INFO', 'handlers': ['console', 'file'] } } # ===== Gradio UI 配置 ===== GRADIO_CONFIG = { 'server_name': '0.0.0.0', 'server_port': 7860, 'share': False, 'show_error': True, 'quiet': False } # ===== 預設位置 (台北101) ===== DEFAULT_LOCATION = { 'lat': 25.033, 'lng': 121.565, 'name': 'Taipei 101' } # ===== Tool 配置 ===== TOOL_CONFIG = { 'scout': { 'search_radius': 5000, # 米 'max_results': 10, 'min_rating': 3.5 }, 'optimizer': { 'algorithm': 'ortools_tsptw', 'max_iterations': 1000, 'time_limit_seconds': 30 }, 'navigator': { 'travel_mode': 'driving', 'avoid_highways': False, 'avoid_tolls': False }, 'weather': { 'forecast_hours': 24, 'update_interval_minutes': 60 } } # ===== 功能開關 ===== FEATURE_FLAGS = { 'enable_weather': True, 'enable_traffic': True, 'enable_chat': True, 'enable_map_visualization': True, 'enable_reasoning_display': True, 'enable_celebration_animation': True, 'enable_stream_output': True } # ===== 性能配置 ===== PERFORMANCE_CONFIG = { 'max_concurrent_requests': 10, 'request_timeout_seconds': 120, 'cache_ttl_seconds': 3600, 'enable_caching': True } # ===== 安全配置 ===== SECURITY_CONFIG = { 'max_input_length': 1000, 'max_tasks_per_request': 20, 'rate_limit_per_minute': 60, 'enable_input_validation': True } # ===== 導出配置函數 ===== def get_agent_config(agent_name: str) -> dict: """獲取指定 Agent 的配置""" return AGENT_CONFIG.get(agent_name, {}) def get_tool_config(tool_name: str) -> dict: """獲取指定 Tool 的配置""" return TOOL_CONFIG.get(tool_name, {}) def is_feature_enabled(feature_name: str) -> bool: """檢查功能是否啟用""" return FEATURE_FLAGS.get(feature_name, False) def get_database_path(db_name: str) -> str: """獲取資料庫路徑""" return DATABASE_CONFIG.get(db_name, '') # ===== 環境檢查 ===== def check_environment(): """檢查環境配置是否完整""" missing_keys = [] required_keys = ['GOOGLE_API_KEY', 'GOOGLE_MAPS_API_KEY', "OPENWEATHER_API_KEY", "GROQ_API_KEY"] for key in required_keys: if not os.getenv(key): missing_keys.append(key) if missing_keys: print(f"⚠️ Warning: Missing environment variables: {', '.join(missing_keys)}") print("Please set them in your .env file or environment") return False return True # ===== 初始化配置 ===== def initialize_config(): """初始化配置""" # 檢查環境 check_environment() # 創建必要的目錄 for dir_path in [STORAGE_DIR, TMP_DIR, LOGS_DIR]: dir_path.mkdir(parents=True, exist_ok=True) print("✅ Configuration initialized successfully") # 自動初始化 if __name__ != "__main__": initialize_config()