"""Load and schema-validate all configs at startup (spec P1 refinement). Invalid entries are reported precisely and skipped — the app never guesses at a malformed entry, and never rejects a well-formed entry because of its name. """ import pathlib import yaml from pydantic import ValidationError from src.schemas import DomainEntry, HardwareProfile, ModelEntry, ProviderEntry CONFIG_DIR = pathlib.Path(__file__).resolve().parent.parent / "configs" class Configs: def __init__(self): self.errors: list[str] = [] self.models: list[ModelEntry] = self._load_list("models.yaml", "models", ModelEntry) self.providers: list[ProviderEntry] = self._load_list("providers.yaml", "providers", ProviderEntry) self.domains: list[DomainEntry] = self._load_list("domains.yaml", "domains", DomainEntry) self.hardware: list[HardwareProfile] = self._load_list("hardware.yaml", "profiles", HardwareProfile) self.limits: dict = self._load_raw("limits.yaml") raw_providers = self._load_raw("providers.yaml") self.default_provider: str = raw_providers.get("default", self.providers[0].id if self.providers else "") def _load_raw(self, fname): try: with open(CONFIG_DIR / fname) as f: return yaml.safe_load(f) or {} except Exception as e: # noqa: BLE001 self.errors.append(f"{fname}: {e}") return {} def _load_list(self, fname, key, model_cls): raw = self._load_raw(fname) out = [] for i, entry in enumerate(raw.get(key, [])): try: out.append(model_cls(**entry)) except ValidationError as e: name = entry.get("name") or entry.get("id") or f"#{i}" self.errors.append(f"{fname}[{name}]: {e.errors()[0]['msg']} ({e.errors()[0]['loc']})") return out def model_by_name(self, name): return next((m for m in self.models if m.name == name), None) def provider_by_id(self, pid): return next((p for p in self.providers if p.id == pid), None) def domain_by_id(self, did): return next((d for d in self.domains if d.id == did), None) _CONFIGS = None def get_configs() -> Configs: global _CONFIGS if _CONFIGS is None: _CONFIGS = Configs() return _CONFIGS