* fix(antigravity): count cache reads and price the standalone app's model The standalone Antigravity app (2.19) stores usage as ModelUsageStats in gen_metadata. Field 5 (cache_read_tokens) was never read, on the SQLite path or the RPC path, so every cached prompt token was dropped. Fields 9 and 10 are thinking and response output, the reverse of what the SQLite path assumed. The rows carry only MODEL_PLACEHOLDER_M16 and "gemini-pro-default", so the model priced at $0. Read cache read (and cache write) in both paths, read 9/10 in the right order, drop the input fallback to field 1 (the model enum), and map the placeholders seen in the app's own model catalog, flagged as estimated. Bump the antigravity results cache, its parse version and the daily cache. * fix(antigravity): keep .pb history across the cache bump, step times, 200k tier With the results cache at v8 and Antigravity closed, .pb cascades had no entry and no server, so they vanished until the app was next opened. Serve the v7 entry meanwhile, stored with mtimeMs -1, and preload the results cache so the session cache reparses such sources and the next run with the server up re-fetches them with cache reads. Standalone .db rows without created_at take their first step's time (steps.metadata #1), which equals created_at wherever both exist, instead of the file mtime. Price antigravity at the Gemini long-context tier: add it to TIERED_PRICING_PROVIDERS and pass the provider at both calculateCost sites.
9.8 KiB
Antigravity
Google Antigravity (CLI and IDE). CodeBurn discovers session files on disk and queries the local language-server RPC endpoint to parse them.
- Source:
src/providers/antigravity.ts - Loading: lazy via
src/providers/index.ts. Lazy because the protobuf dependency is heavy. - Test: focused helper coverage in
tests/providers/antigravity.test.ts.
Where it reads from
CodeBurn discovers Antigravity sessions from local directories on disk, then queries the live language-server process (if running) to fetch detailed trajectory generator metadata:
- Session Discovery: It scans the following folders for
.pbor.dbfiles:- Antigravity CLI:
%USERPROFILE%\.gemini\antigravity-cli\conversations(andimplicit) - Antigravity App/older path:
%USERPROFILE%\.gemini\antigravity\conversations. The standalone app (2.19+,language_server --standalone --subclient_type hub --app_data_dir antigravity) writes here too: new conversations as.db, older ones stay.pb. - Antigravity IDE:
%USERPROFILE%\.gemini\antigravity-ide\conversations(andimplicit). The IDE also maintains VSCode-style global state at%APPDATA%\Antigravity IDE\User\globalStorage\state.vscdb, but that DB stores trajectory metadata (titles, timestamps, workspace paths) — not token usage. Token usage data still comes from the.dbconversation files.
- Antigravity CLI:
- Language Server RPC Query: It locates the active language-server process via
pson POSIX orGet-CimInstance Win32_Processon Windows. It extracts the port and CSRF token from the process arguments, and queries the local HTTPS RPC endpointGetCascadeTrajectoryGeneratorMetadatato parse the session. - Cache Fallback: If the language server is not running, it falls back to the local results cache.
Antigravity exposes slightly different process flags across platforms:
POSIX builds have used --https_server_port and --csrf_token; Windows
builds can expose --extension_server_port and
--extension_server_csrf_token. Both space-separated and --flag=value
forms are supported. The parser identifies the target app type using the --app-data-dir flag (e.g., antigravity, antigravity-cli, or antigravity-ide).
For Antigravity CLI (agy), CodeBurn can also install an opt-in status line
hook with codeburn antigravity-hook install. The hook records the CLI's
sanitized context_window.current_usage payload while agy is still alive,
without prompts or local working-directory paths. It also attempts a best-effort
RPC snapshot for full response metadata. The installed command points at a
persistent codeburn binary from PATH rather than a local build artifact, and
running codeburn antigravity-hook install again repairs older CodeBurn-owned
statusLine commands that used stale absolute paths. Remove it with codeburn antigravity-hook uninstall; if --force replaced an existing statusLine
command, uninstall restores that previous command.
Storage format
Protobuf and SQLite.
SQLite .db Files
Native Antigravity Desktop, IDE, and CLI sessions store structured state in SQLite databases under ~/.gemini/<app>/conversations/<id>.db:
gen_metadata(Model Generations):- Each row represents a completed LLM completion turn.
dataBLOB Protobuf:- Field 1 (
ChatModel): Token usage (Field 4, see Accuracy), model config id (Field 19, e.g.gemini-pro-default), key/value metadata includingmodel_enum(Field 20), display name (Field 21, absent in the standalone app), and generation timestamp (Field 9 -> Field 4). - Field 2 (
stepIndices): Packed varints listing the exactsteps.idxrows produced during that generation turn. - Field 4: Generation UUID used for deduplication (
<cascadeId>:<responseId>).
- Field 1 (
steps(Execution Steps & Tools):- Monotonic step records (
idx,step_type,status,metadata). metadataBLOB Protobuf:- Field 4 (
ToolCallMetadata): Containscall_id(Field 1), canonicaltool_name(Field 2), andargumentsJson(Field 3). - Standard tool calls are mapped directly:
run_command: populatesbashCommands.call_mcp_tool: extractsServerNameandToolNameasmcp__<server>__<tool>.view_file: scansAbsolutePathforSKILL.mdto identify activated skills.invoke_subagent: parsesSubagentsarray for subagent archetype roles.- Assistant-to-assistant replies (
send_message) are explicitly excluded from developer tools.
- Field 4 (
- Monotonic step records (
- Concurrency & Lifecycle:
- Operates in SQLite WAL mode.
- Transient database write locks during progressing sessions propagate
SQLITE_BUSYto allow automatic retry on the next refresh pass. - In-flight steps (
status = 2) settle into subsequent generation records once completed. - User-cancelled turns (
status = 7) commit partial token spend togen_metadata.
For older .pb files, cascade and response objects map to ParsedProviderCall directly via the language-server RPC.
Accuracy
The usage message is exa.codeium_common_pb.ModelUsageStats; field numbers
come from the descriptor embedded in the language_server binary and match the
RPC JSON names:
| Field | Name | CodeBurn |
|---|---|---|
| 1 | model (enum, e.g. 1016 = MODEL_PLACEHOLDER_M16) |
not read; the same id comes from the model_enum key |
| 2 | input_tokens (uncached) |
inputTokens |
| 3 | output_tokens (= 9 + 10) |
fills outputTokens when 9 and 10 are missing or disagree |
| 4 | cache_write_tokens |
cacheCreationInputTokens |
| 5 | cache_read_tokens |
cacheReadInputTokens |
| 6 | api_provider (24 = API_PROVIDER_GOOGLE_GEMINI) |
ignored |
| 9 | thinking_output_tokens |
reasoningTokens, billed at the output rate |
| 10 | response_output_tokens |
outputTokens |
| 11 | response_id |
dedup key |
- Exact: call count, input, output, thinking and cache-read tokens, from
both
.dbfiles and the RPC. Cache read is separate from input (it is often larger), so it is priced at the cache-read rate on top of input. - Estimated: the model of
.dbcalls that carry only a placeholder. The standalone app writesmodel_enum=MODEL_PLACEHOLDER_M16andgemini-pro-default, with no display name. CodeBurn maps the placeholder through a small table taken from the app's ownGetAvailableModelscatalog (6 Oct 2026, app 2.19.1):M16andM37are Gemini 3.1 Pro (High),M36Gemini 3.1 Pro (Low),M84Gemini 3.5 Flash (High),M18Gemini 3 Flash,M35Claude Sonnet 4.6,M26Claude Opus 4.6 (Thinking). These calls carrycostIsEstimated, because a later app build can repoint a placeholder..pbcalls resolve the placeholder through the live catalog at parse time and are not flagged. Gemini 3.1 Pro prices asgemini-3.1-pro-preview: $2/M input, $12/M output, $0.20/M cache read, and $4/$18/$0.40 per request whose prompt (input + cache read) reaches 200,000 tokens. Google's rule is "over 200k", so a prompt of exactly 200,000 gets the higher rate one token early; the shared threshold check uses>=for every tiered provider. - Timestamps:
ChatStartMetadata.created_atwhen present. Standalone-app rows leave it out; they take the time of the generation's first step (steps.metadata#1), which equalscreated_atto the second wherever both exist. The file mtime is the last resort. - A placeholder that is in neither the table nor the live catalog stays
unpriced and shows as
$0undercodeburn models --unpriced.
Caching
Custom file cache at $CODEBURN_CACHE_DIR/antigravity-results.v<n>.json (version 8, defaults to ~/.cache/codeburn/). The unsuffixed antigravity-results.json is left for older binaries; a matching-version copy is adopted once and never overwritten. The cache is also used as the data source when the RPC endpoint is unavailable, not just as an optimization. Bumping the cache version forces a recompute.
Deduplication
Per <cascadeId>:<responseId> for RPC data. The status line fallback collapses
repeated identical usage snapshots, ignores singleton intermediate snapshots
when a later stabilized usage total is observed for the same conversation, and
uses positive deltas for monotonic snapshots so cumulative counters are not
double-counted.
Quirks
.pbconversations need the live process..dbconversations are read straight from SQLite;.pbones only through the RPC, so with Antigravity closed they come from the results cache. After a cache-version bump, a.pbcascade missing from the new file is served from the previous version's file (stored withmtimeMs: -1) until a run with Antigravity open re-fetches it.~/.gemini/antigravity-backupis not scanned. On the machine checked it held only a copy of a conversation also underantigravityandantigravity-ide, which the cascade-id dedup would drop anyway.- Antigravity CLI has a shorter capture window than the desktop app.
agyexposes its language server only while the CLI session is active. The status line hook closes that gap for future sessions; older CLI.pbfiles still cannot be priced exactly unless an RPC snapshot was captured. - The 16 MB cap on RPC responses is necessary because individual cascades can balloon. Raising it risks OOM on the user's machine.
When fixing a bug here
- Reproducing the full provider path requires Antigravity running locally. The unit tests cover process flag parsing and wrapped/unwrapped RPC response extraction, but they do not stand up a live Antigravity RPC endpoint.
- Before any change, capture a sample protobuf response (anonymized) so future regressions can be tested against a recording.
- If the bug is "no data after Antigravity update", the protobuf schema may have shifted. The parser's response handling is the place to look.
- If the bug is "stale data", check whether the RPC is reachable; the cache fallback can mask connectivity issues.