Skip to content

fix(compressor): pin summary role to user when only system prompt is protected (#52160) - #52167

Closed
liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:fix/compressor-system-head-role-52160
Closed

fix(compressor): pin summary role to user when only system prompt is protected (#52160)#52167
liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:fix/compressor-system-head-role-52160

Conversation

@liuhao1024

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes HTTP 400 errors from Anthropic (and Bedrock) after the second context compression. The compressor's summary message was assigned role=assistant when only the system prompt was protected, making it the first visible message in the API request — which Anthropic unconditionally rejects.

Related Issue

Fixes #52160

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • agent/context_compressor.py: When last_head_role == "system" (only the system prompt is protected — typical on second+ compression), force summary_role = "user" and guard the tail-collision flip logic so it cannot revert to "assistant". If the first tail message is also "user", the summary merges into the tail instead.
  • tests/agent/test_context_compressor.py: Two regression tests:
    • test_double_compaction_summary_must_be_user_when_only_system_protected: Verifies the summary is role=user after the second compression.
    • test_double_compaction_user_tail_merges_into_tail: Verifies that when the tail also starts with user, the summary merges into the tail rather than flipping back to assistant.

How to Test

  1. python -m pytest tests/agent/test_context_compressor.py::TestCompressWithClient::test_double_compaction_summary_must_be_user_when_only_system_protected tests/agent/test_context_compressor.py::TestCompressWithClient::test_double_compaction_user_tail_merges_into_tail -v
  2. Run the full compressor test suite: python -m pytest tests/agent/test_context_compressor.py -q (122 tests, all should pass)
  3. To reproduce the original bug: start a long session on an Anthropic provider, trigger two context compressions, and observe that the API call no longer fails with HTTP 400.

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/agent/test_context_compressor.py -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

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

Code Intelligence

  • Analyzed: agent/context_compressor.py ContextCompressor.compress() (lines 2596-2616, role-assignment block)
  • Blast radius: LOW — only affects the summary-role decision when last_head_role == "system", which is a previously-unhandled edge case
  • Related patterns: _effective_protect_first_n() decay after first compression, Anthropic system-message extraction

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

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P1 High — major feature broken, no workaround provider/anthropic Anthropic native Messages API sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(adapter): HTTP 400 after double context compression — first message is assistant, not user

5 participants