Skip to content

fix(compress): reserve output tokens in the compaction threshold (#23767, #43547) - #50781

Merged
kshitijk4poor merged 1 commit into
mainfrom
salvage/output-token-reservation-threshold
Jun 22, 2026
Merged

fix(compress): reserve output tokens in the compaction threshold (#23767, #43547)#50781
kshitijk4poor merged 1 commit into
mainfrom
salvage/output-token-reservation-threshold

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

The compaction trigger compared estimated input against context_length × threshold, but the provider reserves max_tokens of output out of that same window. With a large max_tokens (e.g. 65536 on a custom provider), the usable input budget is materially smaller than the raw window — so a session could hit a provider 400 ("context length exceeded") before compaction ever fired. The threshold is now based on the effective input budget (context_length − max_tokens). (Mode B of #23767; fixes #43547.)

Salvage of #43651 by @kyssta-exe — reimplemented on the current threshold surface (see below).

Why a fresh commit (partly-superseded)

The original PR edited an inline int(context_length * threshold_percent) in update_model/__init__. That code was since refactored into the static _compute_threshold_tokens() helper (for the small-window 85% guard, #14690), and the threshold reset now runs in update_model alongside the #50137 calibration reset. A cherry-pick would conflict and reintroduce the old shape, so this re-implements the one surviving design point (output-token reservation) on the current surface.

Changes

  • agent/context_compressor.py: _compute_threshold_tokens() gains an optional max_tokens param and subtracts it from the effective window before both the percentage and the #14690 small-window 85% guard; self.max_tokens stored in __init__ and reused by update_model (optional explicit override). max_tokens=None (provider default) → no reservation → full-window behavior, byte-identical to before.
  • agent/agent_init.py: pass max_tokens=agent.max_tokens at construction.
  • tests/agent/test_context_compressor.py: 3 tests (reservation lowers threshold; small-window floor composition; max_tokens ≥ context_length falls back to full window).

Design note vs original PR

The original threaded max_tokens as a required update_model kwarg but updated only the one construction caller — the other 6 update_model callers would have zeroed the reservation on every switch. This version stores max_tokens and reuses it across switches (the output cap is a user setting, not model-specific), so the reservation survives /model switches; an explicit kwarg can still override it.

Validation

Result
threshold/max_tokens/compress tests 117 passed
existing threshold tests (None path) unchanged ✓
ruff (diff vs main) clean
Negative check 3 new tests fail on main without the fix ✓
E2E (real imports) 200K+65536 → threshold 67232 (not 100000); None → 100000 unchanged; switch preserves reservation; explicit override works

Interactions verified orthogonal: #50137 (calibration reset in update_model) and #50136 (tool-output persistence cap, different layer).

Part of #23767this is the last of the 6 failure modes; #23767 can close once this lands.

Credit

Closes #43547.

Infographic

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

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🔎 Lint report: salvage/output-token-reservation-threshold 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: 11356 on HEAD, 11354 on base (🆕 +2)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 5969 pre-existing issues carried over.

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

, #43547)

The compaction trigger compared estimated input against context_length *
threshold, but the provider reserves max_tokens of OUTPUT out of the same
window. With a large max_tokens (e.g. 65536 on a custom provider) the usable
input budget is materially smaller than the raw window, so sessions hit a
provider 400 before compaction ever fired.

_compute_threshold_tokens now subtracts the output reservation
(context_length - max_tokens) before applying the percentage and the
small-window 85% guard. max_tokens is stored on the compressor (threaded from
agent.max_tokens at construction) and reused across update_model() switches;
None = provider default = no reservation (full-window behavior, unchanged).

Reimplemented on the current _compute_threshold_tokens surface (the inline
threshold calc the original PR targeted was since refactored for the
small-window #14690 fix); composes with that 85% guard on the effective budget.

Credit: @kyssta-exe (#43651) — original design for the output-token
reservation in the compaction threshold.

Closes #43547.
@kshitijk4poor
kshitijk4poor force-pushed the salvage/output-token-reservation-threshold branch from 584571a to 623b21b Compare June 22, 2026 11:56
@kshitijk4poor
kshitijk4poor enabled auto-merge June 22, 2026 11:59
@kshitijk4poor
kshitijk4poor merged commit a904ff1 into main Jun 22, 2026
34 checks passed
@kshitijk4poor
kshitijk4poor deleted the salvage/output-token-reservation-threshold branch June 22, 2026 12:03
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…t-token-reservation-threshold

fix(compress): reserve output tokens in the compaction threshold (NousResearch#23767, NousResearch#43547)
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…t-token-reservation-threshold

fix(compress): reserve output tokens in the compaction threshold (NousResearch#23767, NousResearch#43547)
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…t-token-reservation-threshold

fix(compress): reserve output tokens in the compaction threshold (NousResearch#23767, NousResearch#43547)
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…t-token-reservation-threshold

fix(compress): reserve output tokens in the compaction threshold (NousResearch#23767, NousResearch#43547)
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…t-token-reservation-threshold

fix(compress): reserve output tokens in the compaction threshold (NousResearch#23767, NousResearch#43547)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Context compaction trigger ignores the output-token reservation (custom-provider default max_tokens=65536 halves the usable input budget)

1 participant