"""Model profile configuration utilities for A1 bootstrap.""" from __future__ import annotations import json from pathlib import Path from typing import Any def _unique_preserve_order(values: list[str]) -> list[str]: seen: set[str] = set() unique: list[str] = [] for raw in values: value = str(raw).strip() if not value or value in seen: continue seen.add(value) unique.append(value) return unique def load_model_ids_from_config( config_path: Path, profile: str | None, ) -> tuple[list[str], dict[str, Any]]: """Load model IDs from a profile inside the model config JSON.""" config_path = config_path.resolve() if not config_path.exists(): raise FileNotFoundError(f"Model config not found: {config_path}") with config_path.open("r", encoding="utf-8") as handle: payload = json.load(handle) profiles = payload.get("profiles") if not isinstance(profiles, dict) or not profiles: raise ValueError(f"Invalid model config (missing non-empty 'profiles'): {config_path}") profile_name = profile or payload.get("active_profile") if profile_name is None: profile_name = sorted(profiles.keys())[0] profile_name = str(profile_name) if profile_name not in profiles: available = ", ".join(sorted(str(key) for key in profiles.keys())) raise ValueError( f"Requested model profile '{profile_name}' not found in {config_path}. " f"Available profiles: {available}" ) profile_payload = profiles[profile_name] if not isinstance(profile_payload, dict): raise ValueError( f"Invalid model profile payload for '{profile_name}' in {config_path}" ) raw_model_ids = profile_payload.get("model_ids") if not isinstance(raw_model_ids, list): raise ValueError( f"Model profile '{profile_name}' must contain a list field 'model_ids'" ) model_ids = _unique_preserve_order([str(value) for value in raw_model_ids]) if not model_ids: raise ValueError( f"Model profile '{profile_name}' resolved to an empty model list" ) selection_info = { "source": "model_config", "config_path": str(config_path), "profile": profile_name, "description": str(profile_payload.get("description", "")), } return model_ids, selection_info