fix(multiplex): per-profile catalog, skin and guest-mint state in hermes_cli

DeepInfra catalog (fetched with the launch env's key via os.getenv), Copilot
context limits (api_key ignored on hit), Nous reasoning caps + once-per-process
guards, the curated OpenRouter list, the model-catalog in-process copy (mtime
without path), banner skills, the guest-mint back-off flag and the active skin
were single slots read under per-profile overrides by the gateway and the TUI
gateway; the SWR refresh thread ran without the caller's ContextVars.

Under an override each lives per home key (hermes_cli/models_profile_cache.py
holds the shared slot helper so models.py does not grow), credentials are read
through the scope-aware dotenv reader and keyed by fingerprint, and background
refreshes run under copy_context(). Unscoped behaviour is byte-identical.
This commit is contained in:
Teknium
2026-09-12 01:03:46 -07:00
parent 4b8c01f691
commit 5ff34f565e
8 changed files with 442 additions and 37 deletions

View File

@@ -342,6 +342,23 @@ _BUILTIN_SKINS: Dict[str, Dict[str, Any]] = {
_active_skin: Optional[SkinConfig] = None
_active_skin_name: str = "default"
# Routed multiplex profiles: (name, skin) per home key. ``display.skin`` and ``<home>/skins/*.yaml``
# are per profile, and the relay display name / TUI skin payload are read under each profile's
# override — one module slot would be last-writer-wins across profiles. Unscoped keeps the module slot.
_active_skin_by_home: Dict[str, Tuple[str, SkinConfig]] = {}
def _routed_home_key() -> Optional[str]:
from hermes_constants import get_hermes_home_override, hermes_home_key
return None if get_hermes_home_override() is None else hermes_home_key()
def _profile_config() -> dict:
try:
from hermes_cli.config import load_config_readonly
return load_config_readonly() or {}
except Exception:
return {}
def _skins_dir() -> Path:
@@ -414,6 +431,14 @@ def load_skin(name: str) -> SkinConfig:
def get_active_skin() -> SkinConfig:
"""Currently active skin config (cached)."""
global _active_skin
home_key = _routed_home_key()
if home_key is not None:
entry = _active_skin_by_home.get(home_key)
if entry is None:
# Cold routed profile: its own ``display.skin`` (nobody ran init_skin_from_config for it).
init_skin_from_config(_profile_config())
entry = _active_skin_by_home[home_key]
return entry[1]
if _active_skin is None:
_active_skin = load_skin(_active_skin_name)
return _active_skin
@@ -422,12 +447,21 @@ def get_active_skin() -> SkinConfig:
def set_active_skin(name: str) -> SkinConfig:
"""Switch the active skin. Returns the new SkinConfig."""
global _active_skin, _active_skin_name
skin = load_skin(name)
home_key = _routed_home_key()
if home_key is not None:
_active_skin_by_home[home_key] = (name, skin)
return skin
_active_skin_name = name
_active_skin = load_skin(name)
_active_skin = skin
return _active_skin
def get_active_skin_name() -> str:
home_key = _routed_home_key()
if home_key is not None:
entry = _active_skin_by_home.get(home_key)
return entry[0] if entry else "default"
return _active_skin_name