fix(goals): forward standing /goal state on auto-compression session rotation (#23530)

When run_agent's _compress_context fires mid-turn it ends the parent
session in SessionDB and creates a new continuation session with a
fresh session_id. The /goal state is keyed on session_id in
state_meta ("goal:<sid>"), so without forwarding the goal silently
disappears: _get_goal_manager() rebinds for the new session_id,
load_goal() returns None, mgr.is_active() is False, and the
continuation loop dies with no user-visible signal.

Fix: in the same SessionDB transaction block that creates the
continuation session, copy state_meta[goal:<old>] →
state_meta[goal:<new>] when present. No-op when the user has no
active goal. Logged at INFO so a stuck loop is debuggable.

Tests cover the round-trip via SessionDB and the no-op path.

Affects all three run-conversation surfaces (CLI, gateway, TUI
gateway) because _compress_context is the single rotation site.
This commit is contained in:
Teknium 2026-05-10 20:41:53 -07:00 committed by GitHub
parent 68d081f570
commit 4a080b1d5a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 75 additions and 0 deletions

View file

@ -10080,6 +10080,25 @@ class AIAgent:
parent_session_id=old_session_id,
)
self._session_db_created = True
# Forward any standing /goal state from the parent session to
# the continuation session so the goal loop survives
# auto-compression. Without this rebind, _get_goal_manager()
# constructs a fresh manager keyed on the new session_id,
# load_goal() returns None, mgr.is_active() is False, and
# the loop silently dies mid-task. The goal is stored in
# state_meta under "goal:<sid>" by hermes_cli.goals.
try:
_goal_meta_key_old = f"goal:{old_session_id}"
_goal_meta_key_new = f"goal:{self.session_id}"
_goal_blob = self._session_db.get_meta(_goal_meta_key_old)
if _goal_blob:
self._session_db.set_meta(_goal_meta_key_new, _goal_blob)
logger.info(
"goal: forwarded standing goal from %s%s on compression",
old_session_id, self.session_id,
)
except Exception as exc:
logger.debug("goal forward on compression failed: %s", exc)
# Auto-number the title for the continuation session
if old_title:
try: