Skip to content

fix: count tool call arguments in the compaction tail budget - #258

Merged
Zongwei9888 merged 1 commit into
HKUDS:mainfrom
liuzhengyang699:fix/compaction-tool-call-budget
Oct 12, 2026
Merged

Zongwei9888 merged 1 commit into
HKUDS:mainfrom
liuzhengyang699:fix/compaction-tool-call-budget

Conversation

@liuzhengyang699

Copy link
Copy Markdown
Contributor

Compaction counts only message content when deciding which history fits in the retained tail. Assistant tool calls commonly have empty content but large arguments, so an old file-writing call can be retained as if it consumed no context.

Include the serialized tool calls in the character estimate, as the runtime token estimator already does. The current-user-turn retention rule and tool-call pairing still apply.

Validation: 9 tests passed across tests/test_compaction_tool_call_budget.py and tests/test_session_compaction.py. The new old-call regression fails before the fix; a second case verifies that a large call in the active turn keeps its matching tool result. Ruff 0.15.21 check/format and git diff --check passed on the changed files.

@Zongwei9888
Zongwei9888 merged commit a6a7949 into HKUDS:main Oct 12, 2026
@Zongwei9888

Copy link
Copy Markdown
Collaborator

Merged in a6a7949. Thank you for the fix, @liuzhengyang699.

Checked against main before merging:

  • Reproduced with the messages from your first test. _message_chars counted the 50,000-character write_file call as 0, the tail budget came out at 141 characters, and the old call stayed in the retained tail (retain = 4, roughly 12.5k estimated tokens).
  • The added term matches the json.dumps(..., ensure_ascii=False) used by estimate_prompt_tokens and estimate_message_tokens in core/agent_runtime/helpers.py. History tool_calls come from to_openai_tool_call(), so they are always serializable, and the budget total and each unit's cost both go through _message_chars.
  • The first test fails on main (retain 4 instead of 2) and passes with the change. The second one guards the current-turn floor and the call/result pairing.

A related gap outside this PR: the runner's shrink gate, AgentRunner._history_chars (core/agent_runtime/runner.py:1915-1916, used at lines 1810 and 1966), also counts message content only. When the dropped history is mostly tool-call arguments, it can still refuse the compaction this change now produces. For example, three old write_file rounds with 40k-character arguments measure 84 characters before and about 1,157 after an 800-character summary. We'll track that separately, and a follow-up PR would be welcome if you're interested.

Zongwei9888 added a commit that referenced this pull request Oct 12, 2026
…rinkage

/compact refuses a summary that does not shrink the history, but the check
counted message content only. In a coding session most of the volume is
tool-call arguments (a write_file call carries the whole file), so a real
session with one 11,142-byte write and two short explanations measured
2,539 characters, and any summary over about 1,000 characters was refused
as "would not shrink". The report the TUI prints had the same blind spot
and announced "~-267 chars ... replaced".

Both now use compaction's message_chars, which #258 introduced for the
tail budget: content plus the serialized tool calls. On DeepSeek the same
session now compacts 9 -> 3 messages and reports about 11,500 characters
replaced.
@Zongwei9888

Copy link
Copy Markdown
Collaborator

A follow-up on the related gap I mentioned: a real session hit it right after the merge. One 11 KB write_file call plus two short answers measured 2,539 characters in the shrink check, so /compact refused the summary as "would not shrink". It is fixed on main in 5c0f5f2, which reuses the message_chars helper from your change for the runner's check and for the /compact report. No follow-up PR is needed. Thanks again.

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.

2 participants