Skip to content

fix(pricing): resolve gemini-default routing label for submission - #1026

Merged
junhoyeo merged 5 commits into
junhoyeo:mainfrom
Yuxin-Qiao:fix/gemini-default-submission-pricing
Aug 3, 2026
Merged

junhoyeo merged 5 commits into
junhoyeo:mainfrom
Yuxin-Qiao:fix/gemini-default-submission-pricing

Conversation

@Yuxin-Qiao

@Yuxin-Qiao Yuxin-Qiao commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

antigravity-cli records sessions with gemini-default (Google AI Studio's generic routing label) when no specific model is selected. Local reports priced this label through fuzzy matching, but tokscale submit validation requires every token bucket to have a rate, so any session with cached-prefix tokens failed with pricing is unavailable for submitted token usage: google/gemini-default (issue #1019).

This PR makes the label resolve deterministically and prices it with full bucket coverage:

  • Add a pricing alias gemini-default -> gemini-2.0-flash-lite (same target the local display already fuzzy-matched to, matching the issue's suggested mapping).
  • Block the bare brand token gemini in fuzzy matching, so generic ids that erode to gemini can no longer land on an unrelated gemini key (e.g. a native-audio preview with no cache rates).
  • Add a usage-aware fallback in submission validation and cost calculation: when the provider-hinted resolution (e.g. vercel_ai_gateway/google/gemini-2.0-flash-lite, which has no cache-read rates) cannot cover the usage, retry the canonical unhinted resolution (the bare official key, which has cache rates). This also protects other models whose hinted reseller row lacks rates.

Root cause

google/gemini-default has no exact pricing key. The lookup strips the -default suffix, and fuzzy matching then selected the longest unrelated gemini key (dataset-dependent; e.g. gemini/gemini-2.5-flash-native-audio-preview-12-2025). Those rows have input/output rates but no cache-read rates, while Antigravity CLI sessions routinely include cacheRead tokens. covers_usage requires every populated bucket to have a rate, so validation failed for the whole submission. Local display still worked because cost display only needs input/output rates.

Reproduced against the real LiteLLM dataset in both the current shape and an older-cache shape (without the later-added live-audio key): pure input/output usage passed validation while input/output + cacheRead + reasoning failed. After the fix both pass.

Validation

  • cargo test -p tokscale-core: 1357 lib tests + all integration suites pass (new regression tests cover the alias, the fuzzy blocklist, the Antigravity CLI parser, and submission validation with cache-read usage).
  • cargo test -p tokscale-cli: 993 unit + 132 integration pass.
  • Real-dataset probe: covers_usage_with_provider("gemini-default", Some("google"), cache-read usage) is now true on the current LiteLLM dataset and on the older-cache simulation, with cost computed at full flash-lite rates.
  • cargo fmt --check and git diff --check clean.

Boundary

The gemini-default -> gemini-2.0-flash-lite mapping is taken from the issue reporter's local display behavior and the issue's suggested mapping; it is not confirmed against official Google/Antigravity documentation. If the maintainers know the actual default-routing billable model, only the single alias line needs updating - the fallback fix is independent of that choice.

Known CI note

test_pricing_command_with_provider in the CLI integration suite depends on live LiteLLM data and fails on main too because upstream removed the bare claude-sonnet-4-20250514 key. Verified by running that test with this change stashed: it fails identically on the base commit. This PR does not change that behavior.

Fixes #1019


Summary by cubic

Fix submission pricing for Google’s gemini-default by resolving it to gemini-2.0-flash-lite when it fully covers the used buckets and excluding unpriceable generic routing usage from submission. Submissions now price covered tokens (including cache-read) and no longer fail validation; the CLI warns about excluded generic usage without promising a submission when none remains. Fixes #1019.

  • Bug Fixes
    • Added alias: gemini-default -> gemini-2.0-flash-lite only when it covers all used buckets; otherwise keep provider pricing.
    • Blocked bare brand token gemini in fuzzy matching to avoid wrong hits.
    • Preserved the generic routing label in session parsing and excluded unpriced google/gemini-default messages from submission.
    • CLI: print per-model exclusion warnings with counts/tokens; show “Remaining priced usage will be submitted.” only if priced usage exists, otherwise “No usage data found to submit.”

Written for commit 72d8207. Summary will update on new commits.

Review in cubic

@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
tokscale Ignored Ignored Preview Aug 3, 2026 7:35pm

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread crates/tokscale-core/src/pricing/aliases.rs Outdated
Comment thread crates/tokscale-core/src/pricing/lookup.rs Outdated
@junhoyeo
junhoyeo force-pushed the fix/gemini-default-submission-pricing branch 2 times, most recently from d4491a6 to 72d8207 Compare August 3, 2026 19:34
@junhoyeo
junhoyeo force-pushed the fix/gemini-default-submission-pricing branch from 72d8207 to e82fe55 Compare August 3, 2026 19:34
@junhoyeo
junhoyeo merged commit 56b2008 into junhoyeo:main Aug 3, 2026
4 of 8 checks passed
junhoyeo pushed a commit that referenced this pull request Aug 4, 2026
* fix(test): pass the bucket timezone to build_graph_from_messages in submission tests

`build_graph_from_messages` gained a `bucket_timezone` parameter in #1016, and #1026 added two submission tests written against the previous four-argument signature. Neither branch touched the other's lines, so the merge produced no textual conflict and the mismatch only surfaced at compile time: `cargo test -p tokscale-core --lib` fails with two E0061 errors, which blocks the whole core unit test suite.

Both call sites now pass `&crate::bucket_tz::BucketTimezone::Local`, matching the neighbouring `graph_pricing_policy_is_strict_only_for_submission` test.

* fix(pricing): compose routing-prefix and tier-suffix stripping

An id carrying both a routing prefix and a tier suffix resolved to nothing, so `cx/gpt-5.5-xhigh` priced at $0 even though `cx/gpt-5.5` and `gpt-5.5-xhigh` each resolve on their own. The two transformations were never applied together: prefix stripping retried only the terminal segment exactly as it stood, and the suffix stage saw the still-prefixed id and splits on `-`, so peeling `-xhigh` off `cx/gpt-5.5-xhigh` left `cx/gpt-5.5`, which is not a dataset key either.

The terminal segment produced by prefix stripping is now also offered to suffix stripping, which resolves the pair through the existing guards rather than adding a new matching rule. This covers the whole tier family reported on the issue, `cx/gpt-5.5-high`, `-medium` and `-low` included, and the same shape on other versions such as `cx/gpt-5.4-xhigh`.

---------

Co-authored-by: MoerAI <26067127+MoerAI@users.noreply.github.com>
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.

Tokscale Issue: google/gemini-default model pricing unavailable on server submission

2 participants