""" Flare – LLM startup notifier ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Projeler açılırken LLM provider'a startup çağrısı yapar. """ from __future__ import annotations import threading, requests, os from typing import Dict, Any from utils import log from config_provider import ConfigProvider, ProjectConfig, VersionConfig from llm_factory import LLMFactory def _select_live_version(p: ProjectConfig) -> VersionConfig | None: """Yayınlanmış en güncel versiyonu getir.""" published = [v for v in p.versions if v.published] return max(published, key=lambda v: v.id) if published else None def notify_startup(): """Notify LLM provider about project startups""" cfg = ConfigProvider.get() # Check if current provider needs startup notification llm_config = cfg.global_config.llm_provider if not llm_config: log("⚠️ No LLM provider configured") return provider_def = cfg.global_config.get_provider_config("llm", llm_config.name) if not provider_def: log(f"⚠️ Unknown LLM provider: {llm_config.name}") return # Currently only Spark variants need startup if llm_config.name not in ("spark", "spark_cloud", "spark_onpremise"): log(f"ℹ️ {llm_config.name} doesn't require startup notification") return # Check if provider requires repo info if not provider_def.requires_repo_info: log(f"ℹ️ {llm_config.name} doesn't require repo info for startup") return # Get endpoint and API key endpoint = llm_config.endpoint if not endpoint: log("⚠️ No LLM endpoint configured for startup") return api_key = cfg.global_config.get_plain_api_key("llm") if not api_key: # Try environment env_var = "SPARK_TOKEN" if os.environ.get("SPACE_ID"): api_key = os.environ.get(env_var) else: from dotenv import load_dotenv load_dotenv() api_key = os.getenv(env_var) if not api_key: log("⚠️ No API key available for startup") return spark_base = str(endpoint).rstrip("/") for p in cfg.projects: if not p.enabled: continue v = _select_live_version(p) if not v: continue # Check if version has LLM config (required for Spark) if not v.llm: log(f"⚠️ No LLM config in version {v.id} for project '{p.name}'") continue body: Dict[str, Any] = { # Required fields for Spark startup "project_name": p.name, "project_version": v.id, "repo_id": v.llm.repo_id, "generation_config": v.llm.generation_config, "use_fine_tune": v.llm.use_fine_tune, "fine_tune_zip": v.llm.fine_tune_zip, } headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } try: log(f"🚀 Notifying {llm_config.name} /startup for project '{p.name}' …") r = requests.post(f"{spark_base}/startup", json=body, headers=headers, timeout=10) if r.status_code >= 400: log(f"❌ LLM provider responded {r.status_code}: {r.text}") r.raise_for_status() log(f"✅ LLM provider acknowledged startup ({r.status_code})") except Exception as e: log(f"⚠️ LLM startup failed: {e}") def run_in_thread(): """Run startup notification in background thread""" threading.Thread(target=notify_startup, daemon=True).start()