Conversation
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 2 selected item(s). |
Qiyuanqiii
left a comment
There was a problem hiding this comment.
This appears to substantially overlap with #1413, which is already open for the same issue (#1411) and addresses the same messageTokens under-counting of ToolCalls, including the active-zone regression coverage.
The implementation strategy is somewhat different: #1413 centralizes the extra accounting in Message.EstimatedTokens() / ToolCall.EstimatedTokens() and also applies it to the agent/session fallback estimates, while this PR counts ToolCalls directly in llmloop and removes tool-call accounting from NativeTurn.
Before reviewing these as two independent fixes, could you clarify what gap in #1413 this PR is intended to address, or why this implementation should replace that one?
|
Thanks for pointing that out @Qiyuanqiii! I hadn't realized #1413 was already in flight for #1411. Closing this in favor of #1413 to respect the earlier PR. |
Fixes #1411
AI Disclosure
This PR was developed with assistance from Google DeepMind's Antigravity coding assistant using Gemini 2.5 Pro. The implementation and tests were reviewed manually, and the changes were verified with the project's test suite.
Background & Root Cause
In
internal/llmloop/compression.go, context budgeting (specificallymessageTokens(m)inCountMessagesTokensandcomputeActiveZoneSize) estimated token usage using:However:
m.ExtractText()only readsm.Content. For assistant turns containing tool calls,m.Contentis typically empty or contains only brief text.m.ToolCalls.NativeTurn.EstimatedTokens()only accounted for tool use for Anthropic messages when thinking was enabled and for OpenAI responses. Providers using OpenAI chat completions, or Anthropic without thinking, could therefore have tool calls omitted frommessageTokens.code_commentinvocations) could be significantly under-counted. This delayed context compression and could ultimately cause upstream LLM requests to fail with HTTP 400Context Length Exceeded.Changes
Universal tool call token budgeting: Added
toolCallsTokens(calls []llm.ToolCall) intininternal/llmloop/compression.goto count tokens from function names, JSON arguments, and call IDs. UpdatedmessageTokensto includetoolCallsTokens(m.ToolCalls).Eliminated double counting in
NativeTurn: UpdatedNativeTurn.EstimatedTokens()ininternal/llm/client.goto estimate only opaque thinking/reasoning blocks. Tool-use estimation was removed fromNativeTurnbecausem.ToolCallsis now handled uniformly across providers.Unit tests:
TestCountMessagesTokens_IncludesToolCallsAndArgumentsandTestComputeActiveZoneSize_AccountsForToolCallsininternal/llmloop/compression_test.go.TestNativeTurn_EstimatedTokensininternal/llm/native_turn_test.go.internal/llm: 95.7%,internal/llmloop: 94.7%).