Skip to content

fix(agent): reset stale token calibration on model switch (#23767) - #50137

Merged
kshitijk4poor merged 1 commit into
mainfrom
fix/reset-calibration-on-model-switch
Jun 21, 2026
Merged

fix(agent): reset stale token calibration on model switch (#23767)#50137
kshitijk4poor merged 1 commit into
mainfrom
fix/reset-calibration-on-model-switch

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

ContextCompressor.update_model() now clears the cross-call token-calibration state captured under the previous model. Without this, after switching an active session onto a smaller-context model, the old model's "this prompt fit / preflight can be deferred" history suppressed a preflight compression the new model actually needed — sending an oversized prompt the provider rejects (part of #23767).

Root cause

update_model() recomputed context_length / threshold_tokens / budgets on a switch, but kept last_real_prompt_tokens, last_rough_tokens_when_real_prompt_fit, last_compression_rough_tokens, awaiting_real_usage_after_compression, and _ineffective_compression_count from the old model. should_defer_preflight_to_real_usage() then used the old model's "it fit" signal to skip compression on the new, smaller model.

Changes

  • agent/context_compressor.py: update_model() resets the calibration/usage fields above (and last_prompt_tokens/last_completion_tokens/last_total_tokens) after recomputing budgets. The new model's first response repopulates them via update_from_response(). Setting last_prompt_tokens=0 is the documented "no data → use rough estimate" state, so the post-response path falls back safely rather than skipping compression.

Validation

Result
tests/agent/test_context_compressor.py (+2 new) 106 passed
affected classes (update-model / deferral / should_compress) 13 passed
ruff + ty (diff vs main) clean, no new diagnostics
E2E (real imports) after a 200K→65,536 switch all stale state clears, threshold recomputes to 64,000, defer no longer suppresses, should_compress(threshold+5k) fires → preflight compresses instead of sending oversized

Part of #23767 (does not close it on its own — sibling fixes tracked separately).

Infographic

Image generation is unavailable in this environment (FAL_KEY unset, no managed-provider credits), so the infographic could not be generated here. To be attached once image generation is available.

ContextCompressor.update_model() recomputed context_length/threshold/budgets
but kept the cross-call calibration state (last_real_prompt_tokens,
last_rough_tokens_when_real_prompt_fit, last_compression_rough_tokens,
awaiting_real_usage_after_compression, _ineffective_compression_count) from the
PREVIOUS model.

Those fields encode 'the provider proved this prompt fit' / 'preflight can be
deferred' decisions valid only for the model that produced them. Carried across
a switch to a smaller-context model, should_defer_preflight_to_real_usage() used
the old model's 'it fit' history to SKIP a preflight compression the new model
actually needed — sending an oversized prompt the provider rejects (#23767).

update_model() now clears that state; the new model's first response repopulates
it via update_from_response(). Verified E2E: after a 200K->65,536 switch, defer
no longer suppresses and should_compress fires on an over-threshold estimate.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: fix/reset-calibration-on-model-switch 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: 11297 on HEAD, 11299 on base (✅ -2)

🆕 New issues (1):

Rule Count
invalid-assignment 1
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`

✅ Fixed issues (2):

Rule Count
unresolved-attribute 2
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`
run_agent.py:2984: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`

Unchanged: 5919 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 comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists labels Jun 21, 2026
@kshitijk4poor
kshitijk4poor merged commit c6a0929 into main Jun 21, 2026
35 checks passed
@kshitijk4poor
kshitijk4poor deleted the fix/reset-calibration-on-model-switch branch June 21, 2026 14:32
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…ibration-on-model-switch

fix(agent): reset stale token calibration on model switch (NousResearch#23767)
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…ibration-on-model-switch

fix(agent): reset stale token calibration on model switch (NousResearch#23767)
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…ibration-on-model-switch

fix(agent): reset stale token calibration on model switch (NousResearch#23767)
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…ibration-on-model-switch

fix(agent): reset stale token calibration on model switch (NousResearch#23767)
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…ibration-on-model-switch

fix(agent): reset stale token calibration on model switch (NousResearch#23767)
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 P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants