fix(agent): defer preflight compaction until real usage after a compaction (#23767, #36718) - #50762
Conversation
…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.
🔎 Lint report:
|
|
Duplicate of #36769 — both add the same early-return to |
…-preflight-after-compaction fix(agent): defer preflight compaction until real usage after a compaction (NousResearch#23767, NousResearch#36718)
…-preflight-after-compaction fix(agent): defer preflight compaction until real usage after a compaction (NousResearch#23767, NousResearch#36718)
…-preflight-after-compaction fix(agent): defer preflight compaction until real usage after a compaction (NousResearch#23767, NousResearch#36718)
…-preflight-after-compaction fix(agent): defer preflight compaction until real usage after a compaction (NousResearch#23767, NousResearch#36718)
…-preflight-after-compaction fix(agent): defer preflight compaction until real usage after a compaction (NousResearch#23767, NousResearch#36718)
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 toFalseon the stalelast_real_prompt_tokens(the pre-compaction value, above threshold), so deferral never engaged. This adds the missing guard: defer whileawaiting_real_usage_after_compressionis 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.pyfrom clobbering thelast_prompt_tokens = -1sentinel. That's necessary but not sufficient: the preflight gate isshould_defer_preflight_to_real_usage(), which readslast_real_prompt_tokens(a different field, still stale-high post-compaction). With only #40582,should_deferstill returnsFalseandshould_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-returnTruefromshould_defer_preflight_to_real_usage()whenawaiting_real_usage_after_compressionis set, placed after therough < thresholdcheap-exit (so below-threshold turns never over-defer).tests/agent/test_context_compressor.py: 2 tests inTestPreflightDeferral(defers on stale-real post-compaction; resumes normal logic once the flag clears).Validation
TestPreflightDeferral(+2)update_from_responseclears the flag; below-threshold not over-deferredInteraction 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
last_real_prompt_tokensshort-circuit and designed theshould_deferearly-return this implements.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.