From d2ba22d7c1a6df272c0b7d1aa67af9870965dfff Mon Sep 17 00:00:00 2001 From: Junho Yeo Date: Sun, 31 May 2026 20:27:29 -0700 Subject: [PATCH] fix(antigravity): include cache rows in default submit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validation * Validation tier: Tier 2 — Narrow runtime change, core client registry flag changes submit default selection and targeted tests cover Antigravity parsing/submit graph behavior. * Red: `cargo test -p tokscale-core antigravity`: FAILED before implementation with `test_antigravity_submit_default_is_true` and `test_submit_default_graph_includes_antigravity_cache_rows`. * `cargo test -p tokscale-core antigravity`: PASS, 14 passed. * `cargo test -p tokscale-cli default_submit_clients`: PASS, 2 passed. * `cargo fmt --all -- --check`: PASS. * `cargo clippy -p tokscale-core --all-features -- -D warnings`: PASS. * `git diff --check`: PASS. * `git diff --cached --check`: PASS. * `bash scripts/check-version-coherence.sh`: PASS, Version coherence OK: 3.0.0. * Ledger: not applicable — scripts/ledger is absent and no ledger policy applies to this change family. * Version: PASS, `bash scripts/check-version-coherence.sh`; no version bump required because release workflow owns manifest version bumps. * Not run: frontend tests — not required because current frontend registry already accepts every core client id and no frontend files changed. * Not run: full workspace test suite — not required for selected validation tier. Rollback * git revert HEAD --- crates/tokscale-core/src/clients.rs | 6 +- crates/tokscale-core/src/lib.rs | 57 +++++++++++++++++-- crates/tokscale-core/src/pricing/aliases.rs | 2 + .../tokscale-core/src/sessions/antigravity.rs | 17 ++++++ 4 files changed, 75 insertions(+), 7 deletions(-) diff --git a/crates/tokscale-core/src/clients.rs b/crates/tokscale-core/src/clients.rs index 46706e362..f9bb1c3e6 100644 --- a/crates/tokscale-core/src/clients.rs +++ b/crates/tokscale-core/src/clients.rs @@ -368,7 +368,7 @@ define_clients!( pattern: "*.jsonl", headless: false, parse_local: true, - submit_default: false + submit_default: true }, Zed = 21 => { id: "zed", @@ -738,8 +738,8 @@ mod tests { } #[test] - fn test_antigravity_submit_default_is_false() { - assert!(!ClientId::Antigravity.submit_default()); + fn test_antigravity_submit_default_is_true() { + assert!(ClientId::Antigravity.submit_default()); } #[test] diff --git a/crates/tokscale-core/src/lib.rs b/crates/tokscale-core/src/lib.rs index cad0cc840..3c335f005 100644 --- a/crates/tokscale-core/src/lib.rs +++ b/crates/tokscale-core/src/lib.rs @@ -2590,10 +2590,11 @@ pub fn parsed_to_unified(msg: &ParsedMessage, cost: f64) -> UnifiedMessage { mod tests { use super::{ aggregate_model_usage_entries, apply_pricing_if_available, dedupe_latest_trae_messages, - message_cache, normalize_model_for_grouping, parse_all_messages_with_pricing, - parse_local_clients, parsed_to_unified, pricing, retain_for_requested_clients, scanner, - select_local_parse_pricing, unified_to_parsed, ClientId, GroupBy, LocalParseOptions, - TokenBreakdown, UnifiedMessage, UNKNOWN_WORKSPACE_LABEL, + generate_graph_with_loaded_pricing, message_cache, normalize_model_for_grouping, + parse_all_messages_with_pricing, parse_local_clients, parsed_to_unified, pricing, + retain_for_requested_clients, scanner, select_local_parse_pricing, unified_to_parsed, + ClientId, GroupBy, LocalParseOptions, ReportOptions, TokenBreakdown, UnifiedMessage, + UNKNOWN_WORKSPACE_LABEL, }; use std::collections::{HashMap, HashSet}; use std::io::Write; @@ -5926,6 +5927,54 @@ mod tests { assert_eq!(parsed_with_settings.messages[0].output, 7); } + #[test] + fn test_submit_default_graph_includes_antigravity_cache_rows() { + let temp_dir = tempfile::TempDir::new().unwrap(); + let sessions_dir = temp_dir + .path() + .join(".config/tokscale/antigravity-cache/sessions"); + std::fs::create_dir_all(&sessions_dir).unwrap(); + std::fs::write( + sessions_dir.join("ag-submit.jsonl"), + r#"{"type":"usage","sessionId":"ag-submit","modelId":"model_placeholder_m84","timestamp":1711200000000,"input":12,"output":4,"cacheRead":2,"cacheWrite":0,"reasoning":1,"responseId":"resp-ag"} +"#, + ) + .unwrap(); + + let mut clients: Vec = ClientId::iter() + .filter(|client| client.submit_default()) + .map(|client| client.as_str().to_string()) + .collect(); + clients.push("synthetic".to_string()); + + let rt = tokio::runtime::Runtime::new().unwrap(); + let graph = rt + .block_on(generate_graph_with_loaded_pricing( + ReportOptions { + home_dir: Some(temp_dir.path().to_string_lossy().to_string()), + use_env_roots: false, + clients: Some(clients), + since: None, + until: None, + year: None, + group_by: GroupBy::default(), + scanner_settings: scanner::ScannerSettings::default(), + }, + None, + )) + .unwrap(); + + assert_eq!(graph.summary.clients, vec!["antigravity"]); + assert_eq!(graph.summary.models, vec!["model_placeholder_m84"]); + assert_eq!(graph.summary.total_tokens, 19); + assert_eq!(graph.contributions.len(), 1); + assert_eq!(graph.contributions[0].clients[0].client, "antigravity"); + assert_eq!( + graph.contributions[0].clients[0].model_id, + "model_placeholder_m84" + ); + } + #[test] fn test_parse_local_clients_dedups_zed_threads_across_default_and_extra_dbs() { let temp_dir = tempfile::TempDir::new().unwrap(); diff --git a/crates/tokscale-core/src/pricing/aliases.rs b/crates/tokscale-core/src/pricing/aliases.rs index 112d12ac5..5c0b5440f 100644 --- a/crates/tokscale-core/src/pricing/aliases.rs +++ b/crates/tokscale-core/src/pricing/aliases.rs @@ -87,6 +87,8 @@ mod tests { resolve_alias("anthropic/claude-4-6-sonnet"), Some("claude-sonnet-4-6") ); + assert_eq!(resolve_alias("model_placeholder_m84"), None); + assert_eq!(resolve_alias("model_placeholder_m16"), None); } #[test] diff --git a/crates/tokscale-core/src/sessions/antigravity.rs b/crates/tokscale-core/src/sessions/antigravity.rs index 300928557..a5135de75 100644 --- a/crates/tokscale-core/src/sessions/antigravity.rs +++ b/crates/tokscale-core/src/sessions/antigravity.rs @@ -154,4 +154,21 @@ mod tests { assert_eq!(messages[0].model_id, "claude-opus-4-6"); assert_eq!(messages[0].provider_id, "anthropic"); } + + #[test] + fn parse_usage_row_preserves_unmapped_placeholder_models() { + let input = r#"{"type":"usage","sessionId":"abc","modelId":"model_placeholder_m84","timestamp":1711200000000,"input":12,"output":4,"cacheRead":2,"cacheWrite":0,"reasoning":1} +{"type":"usage","sessionId":"abc","modelId":"model_placeholder_m16","timestamp":1711200000001,"input":8,"output":3,"cacheRead":0,"cacheWrite":0,"reasoning":0} +"#; + + let path = tempfile::NamedTempFile::new().unwrap(); + std::fs::write(path.path(), input).unwrap(); + + let messages = parse_antigravity_file(path.path()); + assert_eq!(messages.len(), 2); + assert_eq!(messages[0].model_id, "model_placeholder_m84"); + assert_eq!(messages[0].provider_id, "antigravity"); + assert_eq!(messages[1].model_id, "model_placeholder_m16"); + assert_eq!(messages[1].provider_id, "antigravity"); + } }