From 01b0451909eaada46c455387706ddf21ca1e113c Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Thu, 23 Jul 2026 08:17:16 -0700 Subject: [PATCH] fix(compression): compose the blocked-warning probe with engine preflight MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two composition fixes vs the merged #69865 engine-preflight arm: 1. should_compress_info probe getattr-guarded — minimal compressor doubles (SimpleNamespace) and plugin engines lack it; absence means no block reason, no warning. 2. Engine maintenance hook stays un-consulted when any skip-branch fired (failure cooldown / deferred estimate / codex-native) — restoring the #20316 contract the warn-chain restructure broke. --- agent/turn_context.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/agent/turn_context.py b/agent/turn_context.py index b6b9789d29c7..c5a392eb9207 100644 --- a/agent/turn_context.py +++ b/agent/turn_context.py @@ -784,7 +784,15 @@ def build_turn_context( # Context is over threshold but compression is blocked # (summary-LLM cooldown or anti-thrashing). Ask should_compress_info # for the human-readable reason so we can surface a warning below. - _compress_block_reason = _compressor.should_compress_info(_preflight_tokens)[1] + # getattr guard: minimal compressor doubles (SimpleNamespace in + # the engine-preflight tests) and older plugin engines lack the + # method — absence means no block reason, no warning. + _info = getattr(_compressor, "should_compress_info", None) + if callable(_info): + try: + _compress_block_reason = _info(_preflight_tokens)[1] + except Exception: + _compress_block_reason = None if _should_compress_now: _preflight_compressed = True # Compression is actually running (block cleared / was never @@ -886,6 +894,16 @@ def build_turn_context( _clear_warn = getattr(agent, "_clear_context_overflow_warn", None) if callable(_clear_warn): _clear_warn() + # Engine maintenance only when NO skip-branch fired: a failure + # cooldown, deferred estimate, or codex-native route must keep + # the engine hook un-consulted (#20316 contract — the cooldown + # exists precisely because compression recently failed). + if _compression_cooldown or _preflight_deferred or _codex_native_auto: + _engine_preflight = None + else: + _engine_preflight = getattr( + _compressor, "should_compress_preflight", None + ) # ── Engine-driven sub-threshold preflight maintenance (#20316) ── # None of the threshold-path branches fired (not deferred, no # failure cooldown, not codex-native, and should_compress() said @@ -907,9 +925,7 @@ def build_turn_context( # must neither set nor clear ``_preflight_compression_blocked`` # (#64382) — and being in the ``else`` arm it can never run after # the threshold loop has proven a retry ineffective. - _engine_preflight = getattr( - _compressor, "should_compress_preflight", None - ) + # (resolved above, gated on no skip-branch having fired) _wants_engine_preflight = False if callable(_engine_preflight): try: