From a6d0b10c670671fd1bc7986f08012f80426978e2 Mon Sep 17 00:00:00 2001 From: Alex Hancock Date: Fri, 28 Aug 2026 16:29:13 +0000 Subject: [PATCH] feat(gdk): expose cached input-token usage metrics (#11628) --- crates/goose-sdk/src/bindings.rs | 38 +++++++++++++++++++++++++++++ documentation/src/data/gdk-api.json | 12 +++++++++ 2 files changed, 50 insertions(+) diff --git a/crates/goose-sdk/src/bindings.rs b/crates/goose-sdk/src/bindings.rs index 889ea7dc7..ffb020653 100644 --- a/crates/goose-sdk/src/bindings.rs +++ b/crates/goose-sdk/src/bindings.rs @@ -802,6 +802,8 @@ impl Provider { input_tokens: summary.usage.usage.input_tokens, output_tokens: summary.usage.usage.output_tokens, total_tokens: summary.usage.usage.total_tokens, + cache_read_input_tokens: summary.usage.usage.cache_read_input_tokens, + cache_creation_input_tokens: summary.usage.usage.cache_write_input_tokens, }) } } @@ -852,6 +854,8 @@ pub struct CompactionSummary { pub input_tokens: Option, pub output_tokens: Option, pub total_tokens: Option, + pub cache_read_input_tokens: Option, + pub cache_creation_input_tokens: Option, } #[uniffi::export] @@ -1237,4 +1241,38 @@ mod tests { assert_eq!(result.is_error, Some(false)); assert_eq!(result.content[0].as_text().unwrap().text, "done"); } + + fn provider_usage_with_cache( + cache_read: Option, + cache_write: Option, + ) -> ProviderUsage { + use goose_providers::conversation::token_usage::Usage as GooseUsage; + + ProviderUsage::new( + "test-model".to_string(), + GooseUsage::new(Some(100), Some(20), Some(120)) + .with_cache_tokens(cache_read, cache_write), + ) + } + + #[test] + fn usage_exposes_reported_cache_tokens() { + let usage = Usage::from_provider_usage(&provider_usage_with_cache(Some(80), Some(5))) + .expect("conversion"); + + assert_eq!(usage.cache_read_input_tokens, Some(80)); + assert_eq!(usage.cache_creation_input_tokens, Some(5)); + } + + #[test] + fn usage_distinguishes_reported_zero_cache_tokens_from_absence() { + let zero = + Usage::from_provider_usage(&provider_usage_with_cache(Some(0), Some(0))).unwrap(); + assert_eq!(zero.cache_read_input_tokens, Some(0)); + assert_eq!(zero.cache_creation_input_tokens, Some(0)); + + let absent = Usage::from_provider_usage(&provider_usage_with_cache(None, None)).unwrap(); + assert_eq!(absent.cache_read_input_tokens, None); + assert_eq!(absent.cache_creation_input_tokens, None); + } } diff --git a/documentation/src/data/gdk-api.json b/documentation/src/data/gdk-api.json index 48d24b79e..0bb913fc8 100644 --- a/documentation/src/data/gdk-api.json +++ b/documentation/src/data/gdk-api.json @@ -1042,6 +1042,18 @@ "type": "Option", "default": null, "docs": "" + }, + { + "name": "cache_read_input_tokens", + "type": "Option", + "default": null, + "docs": "" + }, + { + "name": "cache_creation_input_tokens", + "type": "Option", + "default": null, + "docs": "" } ], "variants": [],