fix(usage): centralize cache-inclusive app set and cover grokbuild in cost backfill

The cost backfill hardcoded codex|gemini as cache-inclusive apps, so
grokbuild TOTAL-semantics rows were priced on full input tokens with
cache reads double-counted. Converge the writer (proxy logger and
calculator) and the backfill recompute onto a single
sql_helpers::is_cache_inclusive_app predicate backed by the existing
CACHE_INCLUSIVE_APP_TYPES constant, and add a regression test for the
grokbuild backfill path.
This commit is contained in:
Jason
2026-07-23 16:59:41 +08:00
parent 15d5dbe065
commit 3cf84ca362
4 changed files with 63 additions and 5 deletions
+2 -1
View File
@@ -59,7 +59,8 @@ impl CostCalculator {
pricing: &ModelPricing,
cost_multiplier: Decimal,
) -> CostBreakdown {
let input_includes_cache_read = matches!(app_type, "codex" | "gemini" | "grokbuild");
let input_includes_cache_read =
crate::services::sql_helpers::is_cache_inclusive_app(app_type);
Self::calculate_with_cache_semantics(
usage,
pricing,
+1 -1
View File
@@ -122,7 +122,7 @@ impl<'a> UsageLogger<'a> {
let created_at = chrono::Utc::now().timestamp();
let input_token_semantics =
if matches!(log.app_type.as_str(), "codex" | "gemini" | "grokbuild") {
if crate::services::sql_helpers::is_cache_inclusive_app(log.app_type.as_str()) {
INPUT_TOKEN_SEMANTICS_TOTAL
} else {
INPUT_TOKEN_SEMANTICS_FRESH