Time-triggered conversation rotation was removed in 1d5d059410 and core
has read nothing under session_reset since. Nothing told users whose
config still asked for it: their gateway conversations silently stopped
resetting, and a household that never types /new pays for an
ever-growing context.
Gateway startup (for every served profile) and `hermes doctor` now
report a session_reset block whose mode is idle, daily or both, and
point at the hermes-session-reset-policy catalog plugin, which reads
the same top-level block unchanged. The notice stays quiet while that
plugin is enabled. The config key is reported, never rewritten, since
the plugin consumes it. The gateway: form the old loader also accepted
is detected too, with a hint to move it to the top level.
49 lines
2.1 KiB
Python
49 lines
2.1 KiB
Python
"""Point configs that still declare an idle/daily ``session_reset`` at the plugin that restores it.
|
|
|
|
Core stopped rotating gateway conversations on timers (1d5d059410) and reads nothing under
|
|
``session_reset``. A household that relied on it silently gets conversations that never end and
|
|
a bill that grows with them, so gateway startup and ``hermes doctor`` say so. The
|
|
``hermes-session-reset-policy`` catalog plugin reads the top-level block unchanged, which is why
|
|
this module reports and never rewrites or drops the key.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Optional, Tuple
|
|
|
|
PLUGIN_NAME = "hermes-session-reset-policy"
|
|
_TIMED_MODES = frozenset({"idle", "daily", "both"})
|
|
|
|
|
|
def retired_reset_policy(config: Any) -> Optional[Tuple[str, str]]:
|
|
"""``(config_path, mode)`` for a timed ``session_reset`` the config still declares, else None.
|
|
|
|
Looks at the top-level block and the ``gateway:`` form the pre-removal loader also accepted.
|
|
"""
|
|
if not isinstance(config, dict):
|
|
return None
|
|
gateway = config.get("gateway")
|
|
for path, block in (
|
|
("session_reset", config.get("session_reset")),
|
|
("gateway.session_reset", gateway.get("session_reset") if isinstance(gateway, dict) else None),
|
|
):
|
|
if isinstance(block, dict):
|
|
mode = str(block.get("mode") or "").strip().lower()
|
|
if mode in _TIMED_MODES:
|
|
return path, mode
|
|
return None
|
|
|
|
|
|
def reset_plugin_enabled() -> bool:
|
|
"""Whether the restoring plugin is installed and enabled in this process's plugin set."""
|
|
from hermes_cli.plugins import discover_plugins, get_plugin_manager
|
|
discover_plugins()
|
|
return any(p["name"] == PLUGIN_NAME and p["enabled"] for p in get_plugin_manager().list_plugins())
|
|
|
|
|
|
def format_notice(path: str, mode: str) -> str:
|
|
move = "" if path == "session_reset" else " (move the block to top-level session_reset first)"
|
|
return (
|
|
f"{path}.mode: {mode} is no longer applied: gateway conversations reset only on /new or "
|
|
f"/reset. To keep idle/daily resets, run `hermes plugins install {PLUGIN_NAME}`{move}."
|
|
)
|