"""Sliced upstream fixture: the exact api/profiles.py fragments the Atlas voice patcher grafts into (session-continuity 409 resilience). Mirrors the pinned Hermes WebUI deployment byte-for-byte for the anchored regions; see dockerfiles/hermes-webui-atlas-patch.py.""" import logging import threading logger = logging.getLogger(__name__) _root_profile_name_cache = {'default'} _root_profile_name_cache_lock = threading.Lock() _root_profile_name_cache_loaded = False def list_profiles_api(): """Fixture stand-in for the hermes_cli-backed profile listing.""" return [] def _is_root_profile(name: str) -> bool: """True if *name* resolves to the Hermes Agent root profile (~/.hermes). Matches the legacy 'default' alias plus any name where list_profiles_api() reports is_default=True. Memoized; call _invalidate_root_profile_cache() after mutating profile metadata. """ global _root_profile_name_cache_loaded if not name: return False if name == 'default': return True with _root_profile_name_cache_lock: if _root_profile_name_cache_loaded: return name in _root_profile_name_cache # Cache miss — populate from list_profiles_api(). Done outside the lock to # avoid holding it across a hermes_cli subprocess call. try: infos = list_profiles_api() except Exception: logger.debug("Failed to list profiles for root-profile lookup", exc_info=True) return False with _root_profile_name_cache_lock: _root_profile_name_cache.clear() _root_profile_name_cache.add('default') for p in infos: try: if p.get('is_default') and p.get('name'): _root_profile_name_cache.add(p['name']) except (AttributeError, TypeError): continue _root_profile_name_cache_loaded = True return name in _root_profile_name_cache def _profiles_match(row_profile, active_profile) -> bool: """Return True if a session/project row's profile matches the active profile. Treats both the literal alias 'default' and any renamed-root display name (per _is_root_profile) as equivalent, so legacy rows tagged 'default' still surface when the user has renamed the root profile to e.g. 'kinni', and vice versa. A row with no profile (`None` or empty string) is treated as belonging to the root profile — that's the convention used by the legacy backfill at api/models.py::all_sessions, and matches the default seen in `static/sessions.js` (`S.activeProfile||'default'`). Originally lived in api/routes.py; relocated here so both routes.py and out-of-process consumers (mcp_server.py) can import the canonical helper instead of duplicating the body. See #1614 for the visibility model. """ row = row_profile or 'default' active = active_profile or 'default' if row == active: return True # Cross-alias the renamed root. if _is_root_profile(row) and _is_root_profile(active): return True return False