Skip to content

fix(agent): defer preflight compaction until real usage after a compaction (#23767, #36718) - #50762

Merged
kshitijk4poor merged 1 commit into
mainfrom
salvage/defer-preflight-after-compaction
Jun 22, 2026
Merged

fix(agent): defer preflight compaction until real usage after a compaction (#23767, #36718)#50762
kshitijk4poor merged 1 commit into
mainfrom
salvage/defer-preflight-after-compaction

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

After a compaction, preflight could fire a second compaction before the provider ever reported real token usage for the now-shorter conversation. should_defer_preflight_to_real_usage() — the gate the preflight path consults — short-circuited to False on the stale last_real_prompt_tokens (the pre-compaction value, above threshold), so deferral never engaged. This adds the missing guard: defer while awaiting_real_usage_after_compression is set (exactly one turn, until real usage arrives). (Mode F of #23767; hardens #36718.)

Relationship to #40582 (already merged)

#36718 was closed by #40582, which fixed a different mechanism for the same symptom — it stopped turn_context.py from clobbering the last_prompt_tokens = -1 sentinel. That's necessary but not sufficient: the preflight gate is should_defer_preflight_to_real_usage(), which reads last_real_prompt_tokens (a different field, still stale-high post-compaction). With only #40582, should_defer still returns False and should_compress(rough_estimate) fires a second compaction. This PR closes that residual gate. Verified: the new regression test fails on current main (post-#40582) and passes with this fix.

Changes

  • agent/context_compressor.py: early-return True from should_defer_preflight_to_real_usage() when awaiting_real_usage_after_compression is set, placed after the rough < threshold cheap-exit (so below-threshold turns never over-defer).
  • tests/agent/test_context_compressor.py: 2 tests in TestPreflightDeferral (defers on stale-real post-compaction; resumes normal logic once the flag clears).

Validation

Result
TestPreflightDeferral (+2) 5 passed
compressor defer/compress/update_model subset 114 passed
ruff (diff vs main) clean
Negative check new test fails on main without the fix ✓
E2E (real imports) defers exactly one turn post-compaction; update_from_response clears the flag; below-threshold not over-deferred

Interaction with #50137 (resets the flag on model switch): orthogonal — a switch deliberately recalibrates, so post-switch the guard correctly doesn't fire on stale post-compaction state.

Part of #23767 (does not close it — mode B still pending).

Credit

Both PRs' branches also carried the flag-setting half (now on main via #40582's path) plus stale summary-prompt reverts, so this is a fresh commit of just the still-missing gate, credited above.

Closes #36718.

Infographic

Image generation is unavailable in this environment (FAL_KEY unset, no managed-provider credits); to be attached once available.

…ction (#23767, #36718)

After a compaction, the post-compression path parks last_prompt_tokens=-1 and
sets awaiting_real_usage_after_compression=True, but last_real_prompt_tokens
still holds the stale pre-compression value (above threshold). should_defer_
preflight_to_real_usage() hit the 'last_real_prompt_tokens >= threshold => False'
short-circuit and let preflight fire a SECOND compaction before the provider
reported real post-compaction usage. Add an early-return on the awaiting flag so
deferral holds for exactly one turn; update_from_response() clears it.

The flag-setting half (#36718) already landed on main via the in-place
compaction path (conversation_compression.py); this adds the missing
should_defer guard that consumes it.

Credit:
- @ashishpatel26 (#38133) — diagnosis + the should_defer early-return design
- @Tranquil-Flow (#36769) — same #36718 fix, identical guard placement

Closes #36718.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: salvage/defer-preflight-after-compaction vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 11351 on HEAD, 11351 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 5967 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint duplicate This issue or pull request already exists labels Jun 22, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #36769 — both add the same early-return to should_defer_preflight_to_real_usage() in agent/context_compressor.py so a stale-high last_real_prompt_tokens no longer defeats deferral while awaiting_real_usage_after_compression is set (Mode F of #23767 / hardening #36718). #36769 is the earliest open PR for this exact gate; #38133 is a competing fix for the same gate, and #40582 already merged the related turn_context.py sentinel-clobber fix. Maintainer to choose the canonical implementation.

@kshitijk4poor
kshitijk4poor merged commit 065946d into main Jun 22, 2026
35 checks passed
@kshitijk4poor
kshitijk4poor deleted the salvage/defer-preflight-after-compaction branch June 22, 2026 11:40
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…-preflight-after-compaction

fix(agent): defer preflight compaction until real usage after a compaction (NousResearch#23767, NousResearch#36718)
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…-preflight-after-compaction

fix(agent): defer preflight compaction until real usage after a compaction (NousResearch#23767, NousResearch#36718)
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…-preflight-after-compaction

fix(agent): defer preflight compaction until real usage after a compaction (NousResearch#23767, NousResearch#36718)
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…-preflight-after-compaction

fix(agent): defer preflight compaction until real usage after a compaction (NousResearch#23767, NousResearch#36718)
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…-preflight-after-compaction

fix(agent): defer preflight compaction until real usage after a compaction (NousResearch#23767, NousResearch#36718)
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 duplicate This issue or pull request already exists 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: Context compression triggers repeatedly after fresh compress — last_prompt_tokens=-1 not updated until next API call

2 participants