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.
33 lines
1.4 KiB
Python
33 lines
1.4 KiB
Python
"""Per-profile view of ``hermes_cli.models``' module-level catalog slots.
|
|
|
|
Several caches on the facade (curated OpenRouter list, reasoning-capability catalogs and their
|
|
once-per-process guards) hold values derived from ONE profile's config, ``.env`` and ``<home>/cache``
|
|
files. In a multiplexed gateway every turn runs under a HERMES_HOME override, so a single module slot
|
|
would hand the launch profile's value to every other profile. Under an override the slot is read and
|
|
written per home key (routed profiles start cold, never from the launch profile's warmed value);
|
|
without one the module attribute stays the slot, so single-profile behaviour and the tests that reset
|
|
``models._X = None`` are untouched. Same shape as ``tools.approval._permanent_set``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from hermes_constants import get_hermes_home_override, hermes_home_key
|
|
|
|
_SLOTS_BY_HOME: dict[tuple[str, str], Any] = {}
|
|
|
|
|
|
def profile_slot_get(module: Any, attr: str, default: Any = None) -> Any:
|
|
"""``module.<attr>`` for the active profile; ``default`` is a routed profile's cold value."""
|
|
if get_hermes_home_override() is None:
|
|
return getattr(module, attr)
|
|
return _SLOTS_BY_HOME.get((hermes_home_key(), attr), default)
|
|
|
|
|
|
def profile_slot_set(module: Any, attr: str, value: Any) -> None:
|
|
if get_hermes_home_override() is None:
|
|
setattr(module, attr, value)
|
|
else:
|
|
_SLOTS_BY_HOME[(hermes_home_key(), attr)] = value
|