fix(compression): rebind context engine before compaction - #58512
fix(compression): rebind context engine before compaction#58512TurgutKural wants to merge 2 commits into
Conversation
264931c to
ab61641
Compare
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the pre-compression ordering concern. Current main still calls compress() directly at agent/conversation_compression.py:721, so the proposed guarantee is not already present.
Problems
agent/conversation_compression.py:629-643derives session state fromcurrent_session_id/_session_id, neither of which is part ofContextEngine's contract (agent/context_engine.py:142-166). This makes the host behavior engine-specific and silently bypassable.on_session_start()is documented as a new-session callback (agent/context_engine.py:144-149), while initialization supplieshermes_home,model, andcontext_length(agent/agent_init.py:1978-1984). The proposed mid-session call supplies only platform and conversation id.- The regression test creates a
MagicMock.current_session_id(tests/run_agent/test_compression_boundary_hook.py:182-201), so it proves the new convention rather than an engine contract.
Suggested changes
- Introduce and test an explicit, documented context-engine rebind/readiness contract instead of reading private state and reusing the new-session lifecycle hook.
- Reconcile this with linked PR #62374's per-agent cloning direction before relying on shared mutable engines.
Automated hermes-sweeper review.
ab61641 to
3b39538
Compare
|
Rebased onto current A known-stale binding now fails closed if Validation: |
3b39538 to
c892047
Compare
|
Rebased onto current |
c892047 to
ad0a5d5
Compare
|
Thanks for the careful triage. Rebased onto current upstream/main (no conflict) and force-pushed. Addressing the substance:
Proposal: keep this targeted fix merged to close the reported wrong-session attribution now, and open a follow-up to formalize the rebind contract (covering PR #62374's cloning direction) as separate, larger work. Happy to draft that follow-up if useful. |
Deep upstream-already-fixed analysis — VERDICT: STILL_OPENI read What main does today
The specific code gap
ConclusionSTILL_OPEN. The stale-binding problem can still occur: the engine is bound once at construction and the only re-bind during compression is post- (Reviewed against 94f8166.) |
ad0a5d5 to
0a37883
Compare
Thanks for the detailed follow-up. Two points where the current head (
The underlying gap is real: on current |
2715a2c to
3944d58
Compare
|
All four items addressed:
On the rebase note: acknowledged — this will conflict with #58495 in the same file/region. Will coordinate landing order. The minimal fix here is scoped to the pre-compress rebind block; the formal rebind contract follow-up (coordinated with #62374) is a separate effort. |
5358fcb to
d4e2f8c
Compare
b930959 to
27a6178
Compare
27a6178 to
0bb452d
Compare
|
Rebased onto current upstream/main (7965462). The CI failure was a pre-existing vercel sandbox test issue now fixed on main — not related to this PR's compression rebind changes. Fail-closed behavior and boundary_reason='rebind' preserved from prior review fixes. |
92fcde2 to
c7601df
Compare
42b5fa9 to
348dc26
Compare
Address GottZ review (4 items): 1. Fail-closed: if on_session_start raises during pre-compress rebind, compression is skipped (messages returned unchanged) instead of running under a stale binding. 2. boundary_reason='rebind' passed to on_session_start so conforming engines can distinguish a mid-session rebind (keep state) from a genuine new-session start (reset state). 3. Precedence: bound_session_id (public) → _session_id (legacy) → current_session_id (older fallback), matching the documented contract-respecting order. 4. Coverage: added test_rebind_failure_skips_compression_fail_closed and test_rebind_uses_bound_session_id_precedence.
348dc26 to
53f5cb4
Compare
Summary
compress()when they are still bound to a stale side-channel session.Why
LCM compaction writes DAG/store state under the engine's current session id. Reverse-engineer profile logs show compression can run while the shared LCM engine is still bound to an older/side-channel session, causing summary nodes to be attributed to the wrong session and later carry-over to skip because
old_session_iddoes not match the bound session.Tests
python -m py_compile agent/conversation_compression.py tests/run_agent/test_compression_boundary_hook.pypython -m pytest tests/run_agent/test_compression_boundary_hook.py -qpython -m pytest tests/run_agent/test_infinite_compaction_loop.py tests/run_agent/test_compression_persistence.py -qpython -m ruff check agent/conversation_compression.py tests/run_agent/test_compression_boundary_hook.py