fix(gateway): migrate active /goal to new session on context compression - #45065
fix(gateway): migrate active /goal to new session on context compression#45065liuhao1024 wants to merge 1 commit into
Conversation
When context compression creates a child session (rotating session_id), the standing /goal is lost because state_meta key goal:<old_session_id> is never migrated to goal:<new_session_id>. The goal continuation loop silently stops after compression. Add goal migration to both compression paths (agent-result and hygiene): after session_id rotation, copy the active goal from the old session to the new one via load_goal/save_goal. Fixes NousResearch#45059
|
LGTM! The fix covers both compression paths correctly. One suggestion for a follow-up: consider adding a parent-chain fallback in def _goal_still_active_for_session(self, session_id: str) -> bool:
if not session_id:
return False
try:
from hermes_cli.goals import GoalManager
if GoalManager(session_id=session_id).is_active():
return True
# Walk parent chain (compression can create multiple generations)
if self._session_db is not None:
cur = session_id
for _ in range(10):
row = self._session_db._conn.execute(
"SELECT parent_session_id FROM sessions WHERE id = ?", (cur,)
).fetchone()
parent = row[0] if row else None
if not parent:
break
if GoalManager(session_id=parent).is_active():
return True
cur = parent
return False
except Exception:
return FalseThis makes the system resilient to edge cases where the migration in |
|
Thanks for the review and the thoughtful suggestion! The parent-chain fallback in I'll add this as a follow-up PR to keep this one focused on the core migration fix. Appreciate the detailed code snippet! |
|
Closing as duplicate of #18427 by @fadelguy, which implements the same fix for goal migration across compression session splits. That PR was opened earlier (2026-05-01) and covers the same root cause. Thanks to @skycaier for the review and the parent-chain fallback suggestion — I'll note it as a follow-up improvement for whoever lands the canonical fix. Appreciate the detailed code snippet! This cluster has 5 competing PRs (#18427, #18749, #33890, #34035, #45065) — consolidating to the earliest-open canonical PR. |
What does this PR do?
Migrates the active
/goalto the new session when context compression rotatessession_id. Without this fix, the goal continuation loop silently stops after compression becausestate_metakeygoal:<old_session_id>is orphaned.Related Issue
Fixes #45059
Type of Change
Changes Made
gateway/run.py: Added goal migration in both compression paths — agent-result compression (line ~8638) and hygiene compression (line ~8335). After session_id rotation, the active goal is copied from the old session to the new one viaload_goal/save_goal.tests/hermes_cli/test_goals.py: AddedTestGoalMigrationOnCompressionwith 3 tests — active goal migration, cleared goal non-migration, and no-goal safety.How to Test
/goal(e.g.,/goal Research and summarize Q4 earnings)Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/ACode Intelligence
gateway/run.pysession_id rotation in compression (2 call sites: agent-result path + hygiene path)_sync_telegram_topic_bindingpattern already present at both sites