Skip to content

fix(usage): read Gemini usageMetadata out of the antigravity response envelope - #10430

Open
rqzbeh wants to merge 13 commits into
diegosouzapw:release/v3.8.50from
rqzbeh:fix/antigravity-usage-envelope
Open

fix(usage): read Gemini usageMetadata out of the antigravity response envelope#10430
rqzbeh wants to merge 13 commits into
diegosouzapw:release/v3.8.50from
rqzbeh:fix/antigravity-usage-envelope

Conversation

@rqzbeh

@rqzbeh rqzbeh commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Non-streaming Antigravity / gemini-cli requests wrapped their payloads in
{ response: { ... } }, but extractUsageFromResponse only tested the
top-level usageMetadata — so every non-streaming antigravity request
logged IN 0 | OUT 0 and zeroed rows in the usage dashboard. This is the
port of upstream decolua/9router#59d858b ("fix(usage): read Gemini
usageMetadata out of the antigravity response envelope").

The fix reads responseBody.usageMetadata || responseBody.response?.usageMetadata
(the same envelope read the streaming path and usageTracking already use);
top-level metadata keeps priority and the OpenAI / Claude branches are
untouched.

Related Issues

Validation

  • Change type: fix (usage accounting)
  • Focused tests and category gates from the golden path
  • npm run lint — no issues in changed files (repo-wide baseline noise documented)
  • Reconciled with the current active release base (branch from release/v3.8.50 tip)
  • PR is mergeable / CI is running

Tests Added Or Updated

  • tests/unit/usage-extractor.test.ts: two new tests —
    • reads Gemini usageMetadata from the antigravity { response: {...} } envelope
    • prefers top-level usageMetadata over the envelope when both are present
  • Ran: usage-extractor, token-accounting-input-fix, xai-exact-cost-2453 suites — 49/49 pass.

Coverage Notes

  • Streaming usage (usageTracking.ts) already unwrapped the envelope; this
    closes the non-streaming gap (chatCore.ts:4367 + semantic-cache path).

Reviewer Notes

  • Same port shipped upstream in 9router v0.5.55 (2026-08-14) — verified
    against the OmniRoute codebase before implementing.

… envelope

Port decolua/9router#59d858b: antigravity/gemini-cli wrap non-streaming
payloads in { response: {...} }, so extractUsageFromResponse only saw the
top-level usageMetadata and every non-streaming antigravity request logged
zero usage (IN 0 | OUT 0) and zeroed usage-dashboard rows. Top-level
metadata keeps priority; OpenAI/Claude branches untouched.
@rqzbeh
rqzbeh requested a review from diegosouzapw as a code owner August 15, 2026 00:09
@diegosouzapw

Copy link
Copy Markdown
Owner

Thanks for the port, @rqzbeh — this is a clean, surgical fix. Verified locally against release/v3.8.50: node --import tsx/esm --test tests/unit/usage-extractor.test.ts passes 28/28 including your two new cases, and eslint on the touched files is clean. Good catch matching this up with the envelope-unwrap the streaming path already does at usageTracking.ts:675.

No changes requested — this looks merge-ready as-is. One small thought for a possible follow-up (not blocking this PR): the Gemini branch of extractUsageFromResponse still doesn't surface cachedContentTokenCount into a cached_tokens field the way the OpenAI/Claude/Responses branches do — your test fixture even includes it. Might be worth a separate PR if Gemini cache-hit accounting turns out to matter for cost tracking. Not something this fix needs to solve.

Nice work on tracing this all the way to the upstream issue and matching the existing envelope-read pattern.

@rqzbeh

rqzbeh commented Aug 15, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @diegosouzapw — good call on that gap. I've opened the follow-up as a separate PR: #10465 (fix(usage): surface Gemini cachedContentTokenCount as cached_tokens).

It adds cached_tokens: usageMetadata.cachedContentTokenCount || 0 to the Gemini branch of extractUsageFromResponse, matching the streaming path you referenced (usageTracking.ts:684), and the envelope test fixture now actually asserts the 7 it was carrying. Also added a dedicated regression test for the top-level case; usage-extractor runs 29/29 with the companion suites green and eslint clean.

One note: the branch is stacked on the #10430 branch, so the PR diff currently includes the envelope fix too — once #10430 merges, #10465 reduces to just its own delta. Happy to rebase onto release/v3.8.50 if you'd prefer it independent.

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.

Title: Antigravity: usage always shows IN 0 · OUT 0 despite successful DONE (v0.5.50)

2 participants