Skip to content

fix(compression): preserve context when summary fails#25588

Open
franksong2702 wants to merge 2 commits into
NousResearch:mainfrom
franksong2702:franksong2702/fix-compression-summary-failure-preserves-context
Open

fix(compression): preserve context when summary fails#25588
franksong2702 wants to merge 2 commits into
NousResearch:mainfrom
franksong2702:franksong2702/fix-compression-summary-failure-preserves-context

Conversation

@franksong2702

Copy link
Copy Markdown

What does this PR do?

Prevents automatic context compression from discarding conversation turns when summary generation fails.

Previously, if the summary LLM/provider failed, ContextCompressor.compress() inserted a static "summary unavailable" marker and still dropped the middle turns. That is risky for long-running sessions because the visible transcript can remain available while the model-facing context loses recent work and keeps an old protected head.

This changes failed-summary compression to fail closed: record warning state for callers, but return the original messages unchanged.

Related Issue

Fixes #25585

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • agent/context_compressor.py
    • Return the original message list when _generate_summary() returns no summary.
    • Keep _last_summary_fallback_used, _last_summary_dropped_count, and _last_summary_error available so callers can surface warnings.
    • Do not increment compression_count for failed compression.
    • Update no-provider warning text so it no longer claims middle turns will be dropped.
  • tests/agent/test_context_compressor.py
    • Replace the old static-fallback truncation expectation with a regression test that failed summaries preserve the original messages.
    • Keep successful-summary compression coverage explicit by mocking call_llm where tests expect compression.
  • tests/agent/test_context_compressor_summary_continuity.py
    • Keep continuity tests exercising the actual summary window instead of sitting on the minimum-message boundary.

How to Test

  1. scripts/run_tests.sh tests/agent/test_context_compressor.py tests/agent/test_context_compressor_summary_continuity.py tests/agent/test_compress_focus.py tests/gateway/test_compress_command.py tests/gateway/test_compress_focus.py tests/run_agent/test_compressor_fallback_update.py tests/run_agent/test_compression_persistence.py
  2. python3 - <<'PY'\nimport py_compile\npy_compile.compile('agent/context_compressor.py', doraise=True)\nprint('py_compile ok')\nPY
  3. git diff --check

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS, Python 3.11.15

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

N/A

Screenshots / Logs

Focused test run:

100 passed in 6.59s

git diff --check completed with no output.

@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent loop, run_agent.py, prompt builder P1 High — major feature broken, no workaround labels May 14, 2026
@franksong2702

Copy link
Copy Markdown
Author

Follow-up pushed after the duplicate note on #25585:

  • Failed summary compression now returns the exact caller-provided message list captured before the tool-result pruning pass.
  • Added a regression test where pruning would rewrite an old tool output, then summary generation fails; compress() returns the original list and keeps the tool output intact.
  • Focused validation: scripts/run_tests.sh tests/agent/test_context_compressor.py tests/agent/test_context_compressor_summary_continuity.py tests/agent/test_compress_focus.py tests/gateway/test_compress_command.py tests/gateway/test_compress_focus.py tests/run_agent/test_compressor_fallback_update.py tests/run_agent/test_compression_persistence.py -> 101 passed.
  • py_compile and git diff --check passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P1 High — major feature broken, no workaround type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(compression): failed summaries should not discard conversation context

2 participants