Files
hermes-agent/tools/lazy_deps.py
kshitijk4poor af26acab73 fix(deps): gate the runtime takeover on genuinely historical updater frames
The salvaged matcher accepted any cmd_update/_cmd_update_impl frame in
hermes_cli.update_cmd/main, so the CURRENT updater's entrypoints (which
carry pre_update_version on opts, not as a local) would also hand off and
exit the process mid-`hermes update`. Extract
_old_updater.in_historical_update() sharing _historical_context's exact
frame matcher (module, name, and pre_update_version in co_varnames) so the
shim and the context detector cannot drift apart.

- tools/lazy_deps: use the shared predicate; accept the constraints/
  dry_run kwargs historical updaters pass so they reach the handoff
  instead of dying on TypeError; drop the vague message advice.
- tests: collapse 29 parametrize cases to the real invariants and add the
  missing one — the frame walk is now exercised through a nested helper
  (a getframe(1)-only implementation fails), and a current-updater-shaped
  frame (no pre_update_version local) is asserted NOT to hand off.
2026-09-29 15:08:07 +05:30

27 lines
1.2 KiB
Python

"""Shims to suppress old updater work until relaunch. New code must not use these."""
from typing import NoReturn
from hermes_cli._old_updater import in_historical_update, stop_for_relaunch
def ensure(feature: str, *, prompt: bool = True) -> NoReturn:
# Shim to suppress old updater work until relaunch. Do not claim readiness.
# Preserve the dependency-unavailable failure without claiming a completed install.
raise ImportError("Dependencies are unknown to this old updater. Please relaunch Hermes.")
def install_specs(specs: list[str] | tuple[str, ...], *, timeout: int = 300,
constraints: list | None = None, dry_run: bool = False) -> NoReturn:
# Plugins still call this retired API during normal agent construction.
# Only an actual updater call stack may transfer control to the updater;
# argv can still say "serve" or "gateway" when /update runs in-process.
# Historical updaters also passed constraints/dry_run; accepted and ignored.
if in_historical_update():
# never returns: hands off to the takeover child and exits
stop_for_relaunch()
raise ImportError(
"tools.lazy_deps.install_specs is retired; runtime dependency "
"installation is unavailable."
)