"""Kuratierte „erprobte" KI-Modell-Presets fürs Admin-Dropdown (System › Status). Geladen aus ``config/models.yaml``. Jede Auswahl stellt Provider + Modell als Laufzeit-Override um (siehe RUNTIME_SETTABLE) — ohne Neustart. Ein Preset mit ``default: true`` steht für den Config-Standard: seine Auswahl ENTFERNT die LLM-Overrides, sodass wieder Profil/TOML greift. """ from pathlib import Path import yaml from app.runtime_config import RUNTIME_SETTABLE _PATH = Path(__file__).resolve().parent.parent / "config" / "models.yaml" # LLM-Schlüssel, die ein Preset/Reset berührt (Schnittmenge mit RUNTIME_SETTABLE). LLM_KEYS = ("default_llm_provider", "openrouter_llm_model", "local_llm_model") def load_presets() -> list[dict]: """Liest die Presets aus der YAML. Unbekannte/leere Datei -> leere Liste. Nur Keys aus RUNTIME_SETTABLE werden im `set` übernommen (Sicherheit).""" try: data = yaml.safe_load(_PATH.read_text(encoding="utf-8")) or {} except (OSError, yaml.YAMLError): return [] out: list[dict] = [] for i, p in enumerate(data.get("presets", []) or []): if not isinstance(p, dict): continue sets = { k: str(v) for k, v in (p.get("set") or {}).items() if k in RUNTIME_SETTABLE } out.append({ "index": i, "label": str(p.get("label") or f"Preset {i}"), "note": str(p.get("note") or ""), "is_default": bool(p.get("default")), "set": sets, }) return out