fix(compression): skip empty summary windows#60579
Conversation
Signed-off-by: Ho Lim <subhoya@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes an edge case in the context compression pipeline where, after rehydrating _previous_summary from a persisted handoff summary, the adjusted compression slice can become empty but the compressor still called _generate_summary([]), wasting an auxiliary model request and triggering the “summary generation failed → abort” path.
Changes:
- Add an early-return guard in
ContextCompressor.compress()to treat a post-handoff-adjustment emptyturns_to_summarizewindow as a no-op (record ineffective attempt, 0% savings, skip model call). - Add a regression test ensuring the compressor does not call
_generate_summarywhen the handoff summary sits at the end of the compression window, and that state counters are updated accordingly.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
agent/context_compressor.py |
Adds a no-op guard after handoff summary rehydration to avoid calling the summarizer with an empty window. |
tests/agent/test_context_compressor_summary_continuity.py |
Adds coverage for the “handoff at window end → no new turns” boundary condition and asserts no model call occurs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Duplicate of #59526 — diff-verified: this PR inserts the identical |
Problem
Fixes #59496. After the latest persisted handoff summary is removed from the compression window, the remaining window can be empty. The compressor still proceeded to
_generate_summary([]), spending one auxiliary model request and then surfacing the empty-window failure path.Solution
After rehydrating
_previous_summaryfrom the latest handoff, return early when there are no new turns left to summarize. The early return mirrors the existing no-compressible-window path: it records an ineffective compression attempt, sets savings to 0%, and avoids the model call.Validation
scripts/run_tests.sh tests/agent/test_context_compressor_summary_continuity.py -qscripts/run_tests.sh tests/agent/test_context_compressor.py tests/agent/test_context_compressor_cross_session_guard.py tests/agent/test_preflight_compression_gate.py tests/agent/test_context_compressor_summary_continuity.py -q.venv/bin/ruff check agent/context_compressor.py tests/agent/test_context_compressor_summary_continuity.pygit diff --checkuv lock --checkImpact
For the affected boundary case,
_generate_summarycalls drop from 1 to 0. That avoids one auxiliary context-engine request, its prompt tokens, and its latency for each no-new-turn compression trigger.Notes
ty check agent/context_compressor.py tests/agent/test_context_compressor_summary_continuity.pystill reports existing annotations/type issues inagent/context_compressor.pyaround nullable defaults andcall_llm(**call_kwargs); this patch does not add new ty diagnostics.