fix(#3263): init _skip_cc_cl/_cc_cl before compressor block (UnboundLocalError on no-compressor path) + relax brittle #1318 source-assertion

The threshold-rescale block runs unconditionally after the fallback and
references _skip_cc_cl/_cc_cl, which were only defined inside 'if _cc_for_save:'.
On the no-compressor path (fresh agent / interrupted stream) that raised
UnboundLocalError (caught by test_issue1857_usage_overwrite). Hoist both inits
above the block (no-op rescale when no compressor). Also widen the #1318
source-assertion test to accept the widened fallback gate (still asserts the
falsy-check invariant).

Co-authored-by: allenliang2022 <allenliang2022@users.noreply.github.com>
This commit is contained in:
nesquena-hermes 2026-06-01 00:14:13 +00:00
parent 18a459726b
commit 17e7794923
2 changed files with 17 additions and 7 deletions

View file

@ -5868,6 +5868,12 @@ def _run_agent_streaming(
# block writes them to the session itself so GET /api/session
# returns them on reload instead of falling back to 0.
_cc_for_save = getattr(agent, 'context_compressor', None)
# Initialized before the compressor block so the #3256/#3263
# threshold-rescale below is safe even when there is no
# compressor (fresh agent / interrupted stream): _skip_cc_cl
# stays False and _cc_cl stays 0, so the rescale is a no-op.
_skip_cc_cl = False
_cc_cl = 0
if _cc_for_save:
_cc_cl = getattr(_cc_for_save, 'context_length', 0) or 0
# Same guard as routes._resolve_context_length_for_session_model:

View file

@ -47,17 +47,21 @@ def test_fallback_uses_model_metadata():
def test_fallback_gates_on_falsy_context_length():
"""Fallback runs only when the compressor didn't populate s.context_length.
"""Fallback runs when the compressor didn't populate s.context_length.
The gate must check s.context_length (not _cc_for_save) — if the compressor
set context_length but it was 0, we still want the fallback to fire.
The gate must still check s.context_length being falsy — if the compressor
set context_length but it was 0, we want the fallback to fire. (#3256/#3263
widened the gate to ALSO fire on `_skip_cc_cl` — a non-default model whose
compressor carried the stale global cap — so the gate is now
`(not getattr(s, 'context_length', 0)) or _skip_cc_cl`. The falsy-check
remains; this test asserts that invariant is intact, not the exact spelling.)
"""
block = _persistence_block()
# The conditional must reference s.context_length (or getattr(s, 'context_length', 0))
# The conditional must still reference s.context_length being falsy.
assert (
"if not getattr(s, 'context_length'" in block
or "if not s.context_length" in block
), "Fallback must gate on s.context_length being falsy"
"not getattr(s, 'context_length'" in block
or "not s.context_length" in block
), "Fallback must still gate on s.context_length being falsy"
def test_fallback_passes_model_and_base_url():