docs(sessions): recency wording matches the freshest-of rule
Prune recency is now the freshest of last_activity_at / latest message /
started_at (via _sql_session_last_active), but four doc sites still said
"latest message, else started_at": the list_prune_candidates docstring,
the --older-than/--newer-than help in session_filters, and two comments
in config_defaults. Reword them to the phrasing archive_stale_sessions
already uses so operators are not told live activity is ignored.
Also make archive_stale_sessions use the module constant _LAST_ACTIVE_SQL
instead of an inline _sql_session_last_active("s") call — same alias,
identical SQL, one fewer place to drift.
This commit is contained in:
@@ -2086,15 +2086,15 @@ DEFAULT_CONFIG = {
|
|||||||
# Automatic cleanup of ~/.hermes/state.db, which otherwise grows without bound and slows FTS5
|
# Automatic cleanup of ~/.hermes/state.db, which otherwise grows without bound and slows FTS5
|
||||||
# inserts, /resume listing, and insights queries.
|
# inserts, /resume listing, and insights queries.
|
||||||
"sessions": {
|
"sessions": {
|
||||||
# Prune ENDED sessions inactive for retention_days (activity = latest message, else
|
# Prune ENDED sessions inactive for retention_days (activity = freshest of live activity /
|
||||||
# creation) about once per min_interval_hours at startup. Open, pinned, or mid-turn sessions
|
# latest message / creation) about once per min_interval_hours at startup. Open, pinned, or mid-turn sessions
|
||||||
# are never deleted; stale automation sessions whose process died are *closed*, then get a
|
# are never deleted; stale automation sessions whose process died are *closed*, then get a
|
||||||
# full retention window before removal.
|
# full retention window before removal.
|
||||||
"auto_prune": True,
|
"auto_prune": True,
|
||||||
# Inactive days of ended-session history to keep (= `hermes sessions prune`).
|
# Inactive days of ended-session history to keep (= `hermes sessions prune`).
|
||||||
# When true, prune ENDED sessions inactive for retention_days once per (roughly) min_interval_hours
|
# When true, prune ENDED sessions inactive for retention_days once per (roughly) min_interval_hours
|
||||||
# at CLI/gateway/cron startup. Activity is the latest message timestamp, falling back to creation
|
# at CLI/gateway/cron startup. Activity is the freshest of live activity (last_activity_at) / latest
|
||||||
# time for empty sessions. Sessions that are still open, pinned, or mid-turn are never deleted — the
|
# message timestamp / creation time. Sessions that are still open, pinned, or mid-turn are never deleted — the
|
||||||
# only open rows the sweep touches are stale automation sessions (cron/kanban/subagent/one-shot CLI)
|
# only open rows the sweep touches are stale automation sessions (cron/kanban/subagent/one-shot CLI)
|
||||||
# whose process died without closing them; those are *closed*, not deleted, and get a further full
|
# whose process died without closing them; those are *closed*, not deleted, and get a further full
|
||||||
# retention window before removal. Default true since #54189: without it state.db grows without
|
# retention window before removal. Default true since #54189: without it state.db grows without
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ _ARG_FILTERS = (
|
|||||||
def build_prune_filters(args: Any) -> Dict[str, Any]:
|
def build_prune_filters(args: Any) -> Dict[str, Any]:
|
||||||
"""Translate argparse Namespace flags into SessionDB filter kwargs.
|
"""Translate argparse Namespace flags into SessionDB filter kwargs.
|
||||||
|
|
||||||
``--older-than`` / ``--newer-than`` bound last activity (latest message timestamp, falling back
|
``--older-than`` / ``--newer-than`` bound last activity (freshest of ``last_activity_at`` /
|
||||||
to ``started_at`` for empty sessions); ``--before`` / ``--after`` bound session start time.
|
latest message / ``started_at``); ``--before`` / ``--after`` bound session start time.
|
||||||
"""
|
"""
|
||||||
bounds: Dict[str, Optional[float]] = {
|
bounds: Dict[str, Optional[float]] = {
|
||||||
key: None if (raw := getattr(args, attr, None)) is None else parse_point_in_time(raw, flag)
|
key: None if (raw := getattr(args, attr, None)) is None else parse_point_in_time(raw, flag)
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ class SessionMaintenanceMixin:
|
|||||||
def list_prune_candidates(self, older_than_days: Optional[float] = None, source: str = None,
|
def list_prune_candidates(self, older_than_days: Optional[float] = None, source: str = None,
|
||||||
**filters) -> List[Dict[str, Any]]:
|
**filters) -> List[Dict[str, Any]]:
|
||||||
"""Dry-run: sessions a matching prune/archive would touch, oldest first (``older_than_days``
|
"""Dry-run: sessions a matching prune/archive would touch, oldest first (``older_than_days``
|
||||||
= inactivity threshold: latest message, else ``started_at``)."""
|
= inactivity threshold: freshest of ``last_activity_at`` / latest message / ``started_at``)."""
|
||||||
where, params = self._prune_where(older_than_days, source, filters)
|
where, params = self._prune_where(older_than_days, source, filters)
|
||||||
return [dict(row) for row in self._read_all(
|
return [dict(row) for row in self._read_all(
|
||||||
f"""SELECT s.id, s.source, s.title, s.model, s.started_at,
|
f"""SELECT s.id, s.source, s.title, s.model, s.started_at,
|
||||||
@@ -253,7 +253,7 @@ class SessionMaintenanceMixin:
|
|||||||
AND COALESCE(s.end_reason, '') <> 'compression'
|
AND COALESCE(s.end_reason, '') <> 'compression'
|
||||||
{pin_clause}
|
{pin_clause}
|
||||||
AND NOT (COALESCE(s.hidden, 0) <> 0 AND COALESCE(s.title, '') = ?)
|
AND NOT (COALESCE(s.hidden, 0) <> 0 AND COALESCE(s.title, '') = ?)
|
||||||
AND {_sql_session_last_active("s")} < ?
|
AND {_LAST_ACTIVE_SQL} < ?
|
||||||
ORDER BY s.started_at ASC
|
ORDER BY s.started_at ASC
|
||||||
""", (self.CANONICAL_BOT_CHAT_TITLE, cutoff))
|
""", (self.CANONICAL_BOT_CHAT_TITLE, cutoff))
|
||||||
for row in rows:
|
for row in rows:
|
||||||
|
|||||||
Reference in New Issue
Block a user