Repository navigation
Description
Describe the bug
When parsing Antigravity SQLite conversation databases (*.db), ccusage antigravity triple-counts (3x) every model turn's tokens (inputTokens, outputTokens, cacheReadTokens) and cost whenever ModelUsageStats does not populate response_id, provider_assigned_message_id, or message_id (which is the case for Gemini models such as gemini-4-argon and gemini-3.8-flash served via Antigravity ACP / localharness).
Root Cause
In rust/adapters/antigravity/src/parser.rs and rust/adapters/antigravity/src/loader.rs:
-
For a single LLM turn (even when no retry occurred), Antigravity records identical
ModelUsageStatsin 3 places:gen_metadata->CortexStepGeneratorMetadata.chat_model.usage(field4), wherechat_modelhasresponse_model = "gemini-4-argon"(field19) andmodel_display_name = "gemini-4-argon-medium"(field21).gen_metadata->CortexStepGeneratorMetadata.chat_model.retry_infos[0].usage(field17-> field4), which always records the initial attempt's usage even when only 1 attempt was made.steps->CortexStepMetadata.model_usage(field9), wheregenerator_model_info(field24) hasmodel_display_name = "gemini-4-argon-medium".
-
Here is an actual decoded
CortexStepGeneratorMetadatarow (gen_metadata[0]) and correspondingCortexStepMetadatarow (steps[1]) from Antigravity 1.4.1:# gen_metadata[0] chat_model { model: MODEL_GOOGLE_GEMINI_INTERNAL_BYOM usage { input_tokens: 15027 output_tokens: 49 response_output_tokens: 49 } retry_infos { usage { input_tokens: 15027 output_tokens: 49 response_output_tokens: 49 } } response_model: "gemini-4-argon" custom_metadata { key: "request_id" value: "5bb041ce-549c-4078-b930-a9381bcd7c96-0" } model_display_name: "gemini-4-argon-medium" } step_indices: 1 # steps[1].metadata source: CORTEX_STEP_SOURCE_MODEL model_usage { input_tokens: 15027 output_tokens: 49 response_output_tokens: 49 } -
Because
ModelUsageStatsdoes not haveresponse_id(field10),provider_assigned_message_id(field12), ormessage_id(field8) populated in these records,usage.identity_keys()returns an emptyVec<String>. -
In
loader.rs::deduplicate_events, anyAntigravityUsageEventwith emptyidentitiesnever matchesidentity_indexes, so all 3 copies are inserted as separate events instead of being merged:gen_metadatausage+retry_infos[0].usageresolve[19, 21]-> field19("gemini-4-argon"), producing 2x tokens under"gemini-4-argon".stepsmetadata.usageresolvesmodel_info->"gemini-4-argon-medium", producing 1x tokens under"gemini-4-argon-medium".
Reproduction / Observed Output
For a session whose actual cumulative usage is inputTokens: 70,786, cacheReadTokens: 500,131, outputTokens: 4,996, ccusage antigravity session --json outputs exact 2x + 1x = 3x numbers:
{
"cacheCreationTokens": 0,
"cacheReadTokens": 1500393,
"inputTokens": 212358,
"modelBreakdowns": [
{
"cacheCreationTokens": 0,
"cacheReadTokens": 1000262,
"cost": 1.0212204,
"inputTokens": 141572,
"modelName": "gemini-4-argon",
"outputTokens": 9992
},
{
"cacheCreationTokens": 0,
"cacheReadTokens": 500131,
"cost": 0.2553051,
"inputTokens": 70786,
"modelName": "gemini-4-argon-medium",
"outputTokens": 4996
}
],
"outputTokens": 14988,
"totalTokens": 1731867
}Notice that "gemini-4-argon" is literally 2 * "gemini-4-argon-medium" across every metric (141572 = 2 * 70786, 1000262 = 2 * 500131, 9992 = 2 * 4996).
Suggested Fix
- Deduplicating
usagevsretry_infoswithin a singleGeneratorMetadata/StepMetadata:- When
retry_usages.len() == 1and its token counts equalusage(or whenretry_usageshas no distinct identity keys fromusage),retry_infos[0]is simply a mirror of the primary attempt inusageand should not be emitted as a second unkeyed event.
- When
- Linking
gen_metadataandstepswhenModelUsagelacks message IDs:CortexStepGeneratorMetadatacontainsstep_indices(repeated int32, field2) which directly maps agen_metadatarow to the correspondingsteps.idxrows, andchat_model.custom_metadata(field20) includesrequest_id/last_step_index. Usingstep_idx(fromsteps.idxandgen_metadata.step_indices) as a fallback identity key (e.g.step:{session_id}:{step_idx}) allowsdeduplicate_eventsto properly merge thestepsrow and thegen_metadatarow even when provider message IDs are absent.
Activity
pullfrog commentedon Nov 5, 2026
github-actions commentedon Nov 5, 2026
Pullfrog triage: priority:high
Kind: bug
Maintenance fit: maintainable
Confidence: high
Antigravity reports 3x tokens and cost when ModelUsageStats lacks message IDs. Issue provides decoded protobuf and exact 3x reproduction numbers, and parser and loader code confirm empty identity keys bypass deduplication. This is a material usage reporting error in supported behavior.
Decision: kept open; Pullfrog will attempt a focused implementation PR.