fix(goals): forward standing /goal state on auto-compression session rotation#23530
Merged
Conversation
…rotation
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.
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-attribute |
1 |
First entries
tests/hermes_cli/test_goals.py:1111: [unresolved-attribute] unresolved-attribute: Attribute `goal` is not defined on `None` in union `GoalState | None`
✅ Fixed issues: none
Unchanged: 4269 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
Collaborator
teknium1
added a commit
that referenced
this pull request
May 11, 2026
* Revert "fix(goals): force judge to use tool calls instead of JSON-text replies (#23547)" This reverts commit a63a2b7. * Revert "fix(goals): forward standing /goal state on auto-compression session rotation (#23530)" This reverts commit 4a080b1. * Revert "feat(goals): /goal checklist + /subgoal user controls (#23456)" This reverts commit 404640a.
rmulligan
pushed a commit
to rmulligan/hermes-agent
that referenced
this pull request
May 11, 2026
…rotation (NousResearch#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.
rmulligan
pushed a commit
to rmulligan/hermes-agent
that referenced
this pull request
May 11, 2026
…rch#23813) * Revert "fix(goals): force judge to use tool calls instead of JSON-text replies (NousResearch#23547)" This reverts commit a63a2b7. * Revert "fix(goals): forward standing /goal state on auto-compression session rotation (NousResearch#23530)" This reverts commit 4a080b1. * Revert "feat(goals): /goal checklist + /subgoal user controls (NousResearch#23456)" This reverts commit 404640a.
JinyuID
pushed a commit
to JinyuID/hermes-agent
that referenced
this pull request
May 11, 2026
…rotation (NousResearch#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.
JinyuID
pushed a commit
to JinyuID/hermes-agent
that referenced
this pull request
May 11, 2026
…rch#23813) * Revert "fix(goals): force judge to use tool calls instead of JSON-text replies (NousResearch#23547)" This reverts commit d7d4d91. * Revert "fix(goals): forward standing /goal state on auto-compression session rotation (NousResearch#23530)" This reverts commit 0398de7. * Revert "feat(goals): /goal checklist + /subgoal user controls (NousResearch#23456)" This reverts commit b968856.
02356abc
pushed a commit
to 02356abc/hermes-agent
that referenced
this pull request
May 14, 2026
…rotation (NousResearch#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.
02356abc
pushed a commit
to 02356abc/hermes-agent
that referenced
this pull request
May 14, 2026
…rch#23813) * Revert "fix(goals): force judge to use tool calls instead of JSON-text replies (NousResearch#23547)" This reverts commit a63a2b7. * Revert "fix(goals): forward standing /goal state on auto-compression session rotation (NousResearch#23530)" This reverts commit 4a080b1. * Revert "feat(goals): /goal checklist + /subgoal user controls (NousResearch#23456)" This reverts commit 404640a.
jsboige
pushed a commit
to jsboige/hermes-agent
that referenced
this pull request
May 14, 2026
…rotation (NousResearch#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.
jsboige
pushed a commit
to jsboige/hermes-agent
that referenced
this pull request
May 14, 2026
…rch#23813) * Revert "fix(goals): force judge to use tool calls instead of JSON-text replies (NousResearch#23547)" This reverts commit 4e224c0. * Revert "fix(goals): forward standing /goal state on auto-compression session rotation (NousResearch#23530)" This reverts commit f7865f8. * Revert "feat(goals): /goal checklist + /subgoal user controls (NousResearch#23456)" This reverts commit be5fc05.
AlexFoxD
pushed a commit
to AlexFoxD/hermes-agent
that referenced
this pull request
May 21, 2026
…rotation (NousResearch#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.
AlexFoxD
pushed a commit
to AlexFoxD/hermes-agent
that referenced
this pull request
May 21, 2026
…rch#23813) * Revert "fix(goals): force judge to use tool calls instead of JSON-text replies (NousResearch#23547)" This reverts commit a63a2b7. * Revert "fix(goals): forward standing /goal state on auto-compression session rotation (NousResearch#23530)" This reverts commit 4a080b1. * Revert "feat(goals): /goal checklist + /subgoal user controls (NousResearch#23456)" This reverts commit 404640a.
This was referenced May 28, 2026
2 tasks
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
…rotation (NousResearch#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.
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
…rch#23813) * Revert "fix(goals): force judge to use tool calls instead of JSON-text replies (NousResearch#23547)" This reverts commit a63a2b7. * Revert "fix(goals): forward standing /goal state on auto-compression session rotation (NousResearch#23530)" This reverts commit 4a080b1. * Revert "feat(goals): /goal checklist + /subgoal user controls (NousResearch#23456)" This reverts commit 404640a.
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Auto-compression silently kills any standing
/goal.run_agent._compress_contextrotatesself.session_idto a brand new ID when context fills up, and the goal state lives instate_metakeyed on the old session_id. After rotationload_goal(new_sid)returnsNone,mgr.is_active()flips toFalse, and the continuation loop dies with no message to the user.Fix forwards the
goal:<old>row togoal:<new>in the same transaction that creates the continuation session.Root cause
In
run_agent.py::_compress_context:SessionDB.end_session(self.session_id, "compression")ends the parentself.session_id = <new uuid>rotatesSessionDB.create_session(parent_session_id=old_session_id, ...)creates the childsession_idfor downstream calls_get_goal_manager()rebinds with the new ID →load_goal(new_sid)→None→ goal goneThis is a regression risk for any long-running goal that compresses at least once. The harsher decompose Phase A makes this worse because the checklist is now substantial state worth preserving.
Changes
run_agent.py— inside_compress_context, immediately aftercreate_session, copystate_meta[goal:<old>]tostate_meta[goal:<new>]when present. No-op when no goal is set. Logged at INFO so a stuck loop is debuggable.tests/hermes_cli/test_goals.py— 2 new tests:GoalManager(new_sid)loads identical state.Validation
The full
_compress_contextmethod has ~60 dependencies (sessions, memory provider, system prompt rebuild, title carryover, etc.) so the test mirrors the forwarding block directly rather than running the whole method. The block under test is pure SessionDBget_meta/set_metaso the mirror is faithful.Surfaces affected
CLI, gateway, TUI gateway — all three call into
_compress_contextviarun_conversation. Single rotation site, single fix.