fix(compressor): count tool_call envelope in tail-budget token estimate (#23767, #28053) - #50751
Merged
Merged
Conversation
…te (#28053) The tail-protection budget walks estimated an assistant message's tokens from content + function.arguments only, dropping each tool_call's id, type and function.name (plus JSON structure). Assistant turns that fan out into parallel tool calls were undercounted by 2-15x (a 4-tool-call turn measures ~73 vs ~1,090 real tokens), so the protected tail overshot tail_token_budget and compression ran far below its intended ratio — context kept growing. Consolidate the three duplicated budget walks (_prune_old_tool_results and the two passes in _find_tail_cut_by_tokens) into a single _estimate_msg_budget_tokens() helper that counts the full tool_call envelope via len(str(tc)), consistent with how _estimate_message_chars estimates message size elsewhere. Tested on Windows: new tests/agent/test_compressor_tool_call_budget.py plus the existing compression suite (test_context_compressor, compressor_image_tokens, cross_session_guard, infinite_compaction_loop) — 209 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Committer email for the salvaged #43293 commit; required by the contributor attribution check.
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-import |
1 |
First entries
tests/agent/test_compressor_tool_call_budget.py:13: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
✅ Fixed issues: none
Unchanged: 5966 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
kshitijk4poor
enabled auto-merge (rebase)
June 22, 2026 10:55
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The compression tail-protection budget walks estimated each message's tokens from
content + function.argumentsonly — dropping the rest of everytool_callenvelope (id,type,function.name, JSON structure). For assistant turns that fan out into parallel tool calls (Hermes's normal case) this undercounted by 2-15×, so the protected tail overshottail_token_budgetand compression ran well below its intended ratio — context kept growing across turns. (Mode A of #23767; fixes #28053.)Salvage of #43293 by @basilalshukaili, cherry-picked onto current
main(authorship preserved) + AUTHOR_MAP follow-up.Changes
agent/context_compressor.py(contributor): new_estimate_msg_budget_tokens(msg)helper counting the full tool_call envelope (len(str(tc))), consolidating the same walk that was duplicated in 3 places —_prune_old_tool_resultsand the two passes in_find_tail_cut_by_tokens. The three walks can no longer drift apart.tests/agent/test_compressor_tool_call_budget.py(contributor): 5 regression tests.scripts/release.py(maintainer): map the contributor'sgmail.comcommitter email for the attribution check.Plain-content and image handling are unchanged; only the local pre-compression tail estimate changes. Does not touch the prompt-cache path or alter past context.
Sibling-site audit
The 3 budget walks are the only arguments-only token estimators; the remaining
function.argumentsreads in the file are legitimate non-budget uses (_truncate_tool_call_args_json, redaction, call-id mapping) — correctly left unchanged.Validation
tests/agent/test_compressor_tool_call_budget.pytests/agent/test_context_compressor.py+ image tokensPart of #23767 (does not close it — modes B/F still pending).
Closes #43293.
Co-authored-by: Basil Al Shukaili basilalshukaili@gmail.com
Infographic
Image generation is unavailable in this environment (FAL_KEY unset, no managed-provider credits); to be attached once available.