| 462 | # ==================== Profiles ==================== |
| 463 | |
| 464 | def _load_profiles(self) -> None: |
| 465 | if not self.profiles_file.exists(): |
| 466 | self._profiles = {} |
| 467 | return |
| 468 | try: |
| 469 | with open(self.profiles_file, "r", encoding="utf-8") as f: |
| 470 | data = json.load(f) |
| 471 | version = data.get("version", 1) |
| 472 | if version != PROFILES_VERSION: |
| 473 | logger.warning( |
| 474 | f"Profiles file version {version} differs from current {PROFILES_VERSION}" |
| 475 | ) |
| 476 | self._profiles = data.get("profiles", {}) or {} |
| 477 | # Migration: strip ttl_seconds from existing profile settings |
| 478 | for model_id, profiles in self._profiles.items(): |
| 479 | for name, profile in profiles.items(): |
| 480 | settings = profile.get("settings") |
| 481 | if settings and "ttl_seconds" in settings: |
| 482 | del settings["ttl_seconds"] |
| 483 | except Exception as e: |
| 484 | logger.error(f"Failed to load profiles file: {e}") |
| 485 | self._profiles = {} |
| 486 | |
| 487 | def _save_profiles(self) -> None: |
| 488 | """Write profiles to disk atomically (temp file + rename).""" |