style(profile): trim verbose comments to one or two lines

This commit is contained in:
Erosika 2026-06-30 20:32:59 +00:00 committed by Teknium
parent bc396dafda
commit a6175d1f93
6 changed files with 26 additions and 78 deletions

View file

@ -564,35 +564,18 @@ async def _ssrf_redirect_guard(response):
# (e.g. Telegram file URLs expire after ~1 hour).
# ---------------------------------------------------------------------------
# Default location: {HERMES_HOME}/cache/images/ (legacy: image_cache/)
#
# NOTE: These module-level constants are the import-time DEFAULTS. They exist
# for two reasons: (1) backward-compatible references elsewhere, and (2) tests
# monkeypatch them (e.g. ``monkeypatch.setattr("...IMAGE_CACHE_DIR", tmp)``).
# The ``get_*_cache_dir()`` getters below re-resolve through ``get_hermes_dir()``
# on every call so the context-local profile override
# (``set_hermes_home_override``) is honored — freezing the resolved path at
# import pinned every profile to whichever one first imported this module
# (cross-profile leak in single-process multi-profile desktop runtime). When a
# test has monkeypatched the constant away from its import-time default, that
# override wins (preserves the existing test seam).
# Import-time default. Tests monkeypatch this; the get_*_cache_dir() getters
# re-resolve per call so the active profile override is honored.
IMAGE_CACHE_DIR = get_hermes_dir("cache/images", "image_cache")
def _resolve_cache_dir(constant_name: str, new_subpath: str, old_name: str) -> Path:
"""Resolve a cache dir, honoring profile override and test monkeypatches.
Precedence:
1. If the module constant ``constant_name`` was monkeypatched away from
its import-time default, return the patched value (test seam).
2. Otherwise resolve fresh via ``get_hermes_dir`` so the active profile's
``set_hermes_home_override`` is reflected per-call.
"""
"""Resolve fresh via get_hermes_dir (active profile), unless a test has
monkeypatched the constant away from its import-time default."""
fresh = get_hermes_dir(new_subpath, old_name)
current = globals().get(constant_name)
default = _CACHE_DIR_IMPORT_DEFAULTS.get(constant_name)
if current is not None and default is not None and current != default:
# A test (or caller) replaced the module constant — respect it.
return Path(current)
return fresh
@ -968,10 +951,8 @@ def cache_video_from_bytes(data: bytes, ext: str = ".mp4") -> str:
DOCUMENT_CACHE_DIR = get_hermes_dir("cache/documents", "document_cache")
SCREENSHOT_CACHE_DIR = get_hermes_dir("cache/screenshots", "browser_screenshots")
# Import-time defaults for the cache-dir constants. ``_resolve_cache_dir``
# compares the live module value against these to detect a test monkeypatch
# (in which case the patched value wins) vs. an unmodified constant (in which
# case it re-resolves through the active profile override).
# Import-time defaults; _resolve_cache_dir compares against these to tell a
# test monkeypatch from an unmodified constant.
_CACHE_DIR_IMPORT_DEFAULTS = {
"IMAGE_CACHE_DIR": IMAGE_CACHE_DIR,
"AUDIO_CACHE_DIR": AUDIO_CACHE_DIR,

View file

@ -25,11 +25,9 @@ _MAX_TEXT_CHARS = 2000
def _store_path() -> str:
# Resolve through get_hermes_home() so the context-local profile override
# (set_hermes_home_override) is honored. Reading os.environ["HERMES_HOME"]
# directly bypassed the override and leaked every profile's rich-sent index
# into the launch/default profile in single-process multi-profile runtimes
# (desktop tui_gateway).
# Resolve via get_hermes_home() so the profile override is honored; reading
# os.environ["HERMES_HOME"] directly bypassed it and leaked the index into
# the launch profile (multi-profile tui_gateway / gateway).
from hermes_constants import get_hermes_home
home = get_hermes_home()

View file

@ -144,12 +144,9 @@ def _run_async(coro):
worker_loop.close()
pool = concurrent.futures.ThreadPoolExecutor(max_workers=1)
# Propagate the parent thread's ContextVars (notably the
# _HERMES_HOME_OVERRIDE profile scope) and approval/sudo callbacks into
# the worker thread. Without this, any async tool that resolves
# get_hermes_home() inside its coroutine falls back to the launch/default
# profile in single-process multi-profile runtimes (desktop tui_gateway),
# leaking one profile's reads/writes into another.
# Propagate the profile override + approval/sudo callbacks into the
# worker so async tools resolving get_hermes_home() see the active
# profile, not the launch one (multi-profile tui_gateway / gateway).
from tools.thread_context import propagate_context_to_thread
future = pool.submit(propagate_context_to_thread(_run_in_worker))

View file

@ -1532,12 +1532,8 @@ class AIAgent:
review_memory=review_memory,
review_skills=review_skills,
)
# Propagate the spawning turn's ContextVars (notably the
# _HERMES_HOME_OVERRIDE profile scope) into the review thread. A bare
# threading.Thread starts with an empty context, so the review would
# resolve get_hermes_home() to the launch/default profile and write
# MEMORY.md / skill review into the wrong profile in single-process
# multi-profile runtimes (desktop tui_gateway) — see #54937.
# Propagate the profile override into the review thread, else it writes
# MEMORY.md / skill review into the launch profile (#54937).
t = threading.Thread(
target=propagate_context_to_thread(target), daemon=True, name="bg-review"
)

View file

@ -249,10 +249,8 @@ def dispatch_async_delegation(
_finalize(delegation_id, result, status)
try:
# Capture the dispatching turn's ContextVars (notably the
# _HERMES_HOME_OVERRIDE profile scope) so the detached child resolves
# get_hermes_home() under the right profile in single-process
# multi-profile runtimes (desktop tui_gateway).
# Propagate the dispatching profile so the detached child resolves
# get_hermes_home() under the right profile.
executor.submit(propagate_context_to_thread(_worker))
except Exception as exc: # pragma: no cover — pool submit failure is rare
with _records_lock:
@ -438,9 +436,7 @@ def dispatch_async_delegation_batch(
_finalize_batch(delegation_id, combined, status)
try:
# Capture the dispatching turn's ContextVars (notably the
# _HERMES_HOME_OVERRIDE profile scope) so the detached batch children
# resolve get_hermes_home() under the right profile.
# Propagate the dispatching profile to the detached batch children.
executor.submit(propagate_context_to_thread(_worker))
except Exception as exc: # pragma: no cover
with _records_lock:

View file

@ -46,30 +46,16 @@ logger = logging.getLogger(__name__)
# ---------------------------------------------------------------------------
# Paths
# ---------------------------------------------------------------------------
#
# These directories MUST resolve through ``get_hermes_home()`` on every access
# so the context-local profile override (``set_hermes_home_override``) is
# honored. Freezing them as module-level constants at import time pinned every
# later profile to whichever profile first imported this module — a cross-
# profile data leak in single-process multi-profile runtimes (desktop
# ``tui_gateway``). See the profile-isolation fix.
#
# Backward compatibility: external callers do ``from tools.skills_hub import
# SKILLS_DIR`` (always inside a function body, re-evaluated per call). The
# module-level ``__getattr__`` below makes those names resolve dynamically, so
# no external call site needs to change.
# Resolved per-call (not frozen at import) so the profile override is honored;
# import-time constants leaked across profiles in single-process multi-profile
# runtimes. Legacy names (SKILLS_DIR, ...) are re-exposed via __getattr__ below
# so external `from tools.skills_hub import SKILLS_DIR` callers still work.
INDEX_CACHE_TTL = 3600 # 1 hour (defined early; referenced below)
INDEX_CACHE_TTL = 3600 # 1 hour
# The legacy path names (SKILLS_DIR, HUB_DIR, ...) are not real module
# attributes — they are synthesized on access by the PEP 562 ``__getattr__``
# below so they reflect the active profile override. Tests, however, set them
# as *real* module attributes via ``patch.object(hub, "SKILLS_DIR", ...)`` /
# ``monkeypatch.setattr``. ``_override`` lets each resolver honor such an
# injected real attribute (the test seam) before falling back to dynamic
# resolution. ``globals().get`` returns None when only the __getattr__-backed
# name exists (no real attribute set), so dynamic resolution wins by default.
# _override lets a test-injected real module attribute (patch.object/monkeypatch
# on SKILLS_DIR etc.) win over dynamic resolution; None means resolve live.
def _override(name: str):
return globals().get(name)
@ -126,14 +112,8 @@ _DYNAMIC_PATH_RESOLVERS = {
def __getattr__(name: str):
"""Resolve the legacy path constants dynamically per access.
PEP 562 module ``__getattr__``: only called for names NOT found as real
module attributes, so it does not slow down ordinary lookups and a test's
``patch.object``-set real attribute shadows it. This lets
``tools.skills_hub.SKILLS_DIR`` (and the rest) reflect the active profile
override instead of an import-time snapshot.
"""
"""Resolve legacy path constants dynamically (PEP 562) so they reflect the
active profile override; a test's patch.object-set real attribute shadows it."""
resolver = _DYNAMIC_PATH_RESOLVERS.get(name)
if resolver is not None:
return resolver()