fix(usage): parse Antigravity SSE usage and count tool calls - #70
Open
mahdiwafy wants to merge 2 commits into
Open
fix(usage): parse Antigravity SSE usage and count tool calls#70mahdiwafy wants to merge 2 commits into
mahdiwafy wants to merge 2 commits into
Conversation
…+ usageMetadata) in parseSSEToOpenAIResponse
The parseSSEToOpenAIResponse function only understood OpenAI SSE format
(choices[0].delta.content, root-level usage). Antigravity/Gemini SSE
chunks use a different schema:
data: {"response":{"candidates":[{...}],"usageMetadata":{...}}}
- Text content from response.candidates[0].content.parts[].text
- Reasoning from .parts[].thought
- Finish reason from candidate.finishReason
- Usage from response.usageMetadata (promptTokenCount, candidatesTokenCount,
thoughtsTokenCount, totalTokenCount)
Also moves the OpenAI usage extraction before the AG block so the
existing path is preserved for OpenAI-formatted chunks.
…age tracking Tool-call-only turns (agentic coding clients like Claude Code/Kiro sending 100+ tools) stream their real output entirely through delta.tool_calls (and delta.partial_json for Claude tool_use), with delta.content and delta.reasoning_content empty. totalContentLength in createSSEStream() only summed content/reasoning length, so these turns left it stuck at 0. That starved both usage fallbacks: - estimateUsage() (provider sent no/invalid usage at all) - the new hasZeroCompletionWithContent()/fixZeroCompletionUsage() path (provider sent completion_tokens: 0 despite real output) Net effect: usage logs showed "out=0" for most tool-heavy turns even though the client received a large tool_calls payload — matching the live claude-sonnet-5 report on VansRouter (a5a5b570 account/Shiteru). Changes: - stream.js: sum delta.tool_calls[].function.name/arguments length (both PASSTHROUGH and TRANSLATE modes) and delta.partial_json (Claude tool_use) into totalContentLength. - usageTracking.js: add hasZeroCompletionWithContent() and fixZeroCompletionUsage() to patch a provider-reported zero completion count without discarding its (usually accurate) prompt_tokens. - Wire the new fallback into all 4 usage-decision sites in stream.js. Verified: reproduced the exact bug shape in a new integration test (in=166912, completion_tokens: 0 finish chunk, pure tool_calls output) — now estimates a non-zero completion count instead of logging 0. Deployed the fix live to the running container and confirmed in production logs: claude-sonnet-5 tool-heavy turns now log out=44/56/322/etc instead of a long run of out=0. Separately observed (NOT fixed by this change, needs its own investigation): a distinct pattern of genuinely empty completions (response.content === "[Empty streaming response]", no tool_calls either) from the Shiteru-backed claude-sonnet-5 route once prompt size exceeds ~130k tokens — confirmed via requestDetails table, not a usage- counting artifact.
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
response.candidates/usageMetadata.Scope
Focused only on usage accounting fixes.
Verification
npm run lint:undef