Skip to content

fix(compressor): batch salvage \u2014 orphan tool_calls, cooldown abort flags, system-head summary role (#51225 #52056 #52167) - #56197

Merged
kshitijk4poor merged 4 commits into
NousResearch:mainfrom
kshitijk4poor:salvage-compressor
Jul 1, 2026
Merged

fix(compressor): batch salvage \u2014 orphan tool_calls, cooldown abort flags, system-head summary role (#51225 #52056 #52167)#56197
kshitijk4poor merged 4 commits into
NousResearch:mainfrom
kshitijk4poor:salvage-compressor

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

User-requested batch salvage of three complementary P1 bug fixes to agent/context_compressor.py, rebased onto current main. All three targeted bugs are confirmed still present on main; the three fixes touch non-overlapping regions and compose cleanly.

Note: the original PR branches predated a since-landed cooldown-helper refactor (_record_/_clear_compression_failure_cooldown), so their raw diffs would have reverted that refactor. This salvage re-applies only the genuine fix intent on top of current main's helper-based code — the refactor is left intact (verified).

Included PRs (authorship preserved per commit)

Follow-up commit (mine)

  • test(compressor): tidy blank-line spacing + assert placeholder never overwrites text — review-driven test cleanup only, no production change.

Verification

  • pytest tests/agent/test_context_compressor.py141 passed (includes 8 new tests across TestSanitizerStripsOrphanedToolCalls, TestCooldownReentryAbort, TestDoubleCompactionSummaryRole).
  • Mutation-checked: reverting each of the three source fixes fails its corresponding tests — the tests are genuine behavior contracts, not change-detectors.
  • Stale-revert check: the cooldown-helper refactor is intact (no raw _summary_failure_cooldown_until assignments reintroduced in compress()/_generate_summary).

Closes #51225. Closes #52056. Closes #52167.

Co-authored-by: liuhao1024 sunsky.lau@gmail.com
Co-authored-by: srojk34 286497132+srojk34@users.noreply.github.com

liuhao1024 and others added 4 commits July 1, 2026 14:11
…ousResearch#51218)

_sanitize_tool_pairs inserted stub role="tool" results for orphaned
tool_calls. The pre-API repair_message_sequence() tracks known call IDs by
tc.get("id") while this sanitizer keys on call_id||id; when they disagree
(Codex Responses API: id != call_id) the stubs are silently dropped by the
repair pass, re-exposing the original orphans. Strip the orphaned tool_calls
at the source instead (preserving any text content, adding a placeholder for
an otherwise-empty assistant turn) to avoid the mismatch class entirely.

Salvaged from NousResearch#51225.

Co-authored-by: liuhao1024 <sunsky.lau@gmail.com>
…e-entry (NousResearch#29559)

compress() eagerly reset _last_summary_auth_failure and
_last_summary_network_failure at the top of every call. On a second
compress() during the failure cooldown, _generate_summary() returns None from
the cooldown early-return WITHOUT re-asserting those flags, so the abort guard
saw False and fell through to the destructive static-fallback that drops the
middle window — the data-loss NousResearch#29559/NousResearch#25585 describe. Stop resetting them
eagerly; a successful summary already clears both, so letting them persist
across calls is safe and keeps the cooldown abort protection intact.

Salvaged from NousResearch#52056.

Co-authored-by: srojk34 <286497132+srojk34@users.noreply.github.com>
…protected (NousResearch#52160)

After the first compaction protect_first_n decays, so on a later compaction
the only protected head message can be the system prompt. Adapters like
Anthropic and Bedrock send the system prompt as a separate parameter, so the
summary becomes the first message in messages[] — and Anthropic rejects any
request whose first message is not role=user (HTTP 400). Pin the summary to
role=user when the head is system-only, and stop the collision-flip logic from
reverting it back to assistant.

Salvaged from NousResearch#52167.

Co-authored-by: liuhao1024 <sunsky.lau@gmail.com>
…overwrites text

Review follow-up on the batch salvage: normalize the inter-class spacing to two
blank lines (PEP8) between the three new test classes, and add an explicit
assertion in test_sanitizer_strips_orphaned_preserves_text_content that the
'(tool call removed)' placeholder does NOT overwrite existing assistant text.
No production change.
@kshitijk4poor
kshitijk4poor enabled auto-merge (rebase) July 1, 2026 08:50
@kshitijk4poor
kshitijk4poor disabled auto-merge July 1, 2026 08:50
@kshitijk4poor
kshitijk4poor merged commit 6e97f5c into NousResearch:main Jul 1, 2026
31 checks passed
@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state P1 High — major feature broken, no workaround labels Jul 1, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.
Batch salvage of three complementary open compressor fixes — #51225 (@liuhao1024, orphan tool_calls), #52056 (@srojk34, cooldown abort-flag reset), #52167 (@liuhao1024, system-head summary role) — rebased onto current main. Related to each, not a duplicate.

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 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.

4 participants