Track prompt cache write token usage (#33454)

## What changed

- Parse `cache_write_tokens` from response input token details and carry it through token usage aggregation.
- Expose `cache_write_input_tokens` in protocol, app-server, exec, and TypeScript SDK usage events, defaulting it to zero for compatibility with older payloads.
- Report cache-write usage in analytics, metrics, traces, and rollout data alongside existing cache-read usage.

## Testing

- Add coverage for response parsing, usage event output, aggregation, analytics, metrics, and telemetry fields.

GitOrigin-RevId: 634e4fbe3086a8923c0ee13b622573e7d9d221bd
This commit is contained in:
Eric Traut
2026-07-16 00:22:53 +00:00
committed by copyberry
parent 78d4a563f9
commit 2edad72de3
46 changed files with 207 additions and 31 deletions
+6
View File
@@ -60,6 +60,10 @@ fn emit_guardian_token_usage_histograms(
("total", token_usage.total_tokens.max(0)),
("input", token_usage.input_tokens.max(0)),
("cached_input", token_usage.cached_input()),
(
"cache_write_input",
token_usage.cache_write_input_tokens.max(0),
),
("non_cached_input", token_usage.non_cached_input()),
("output", token_usage.output_tokens.max(0)),
(
@@ -348,6 +352,7 @@ mod tests {
token_usage: Some(TokenUsage {
input_tokens: 10,
cached_input_tokens: 4,
cache_write_input_tokens: 2,
output_tokens: 3,
reasoning_output_tokens: 2,
total_tokens: 15,
@@ -399,6 +404,7 @@ mod tests {
histogram_sums(&snapshot, GUARDIAN_REVIEW_TOKEN_USAGE_METRIC),
BTreeMap::from([
("cached_input".to_string(), 4),
("cache_write_input".to_string(), 2),
("input".to_string(), 10),
("non_cached_input".to_string(), 6),
("output".to_string(), 3),
@@ -128,6 +128,8 @@ fn token_usage_delta(start: &TokenUsage, end: &TokenUsage) -> TokenUsage {
TokenUsage {
input_tokens: (end.input_tokens - start.input_tokens).max(0),
cached_input_tokens: (end.cached_input_tokens - start.cached_input_tokens).max(0),
cache_write_input_tokens: (end.cache_write_input_tokens - start.cache_write_input_tokens)
.max(0),
output_tokens: (end.output_tokens - start.output_tokens).max(0),
reasoning_output_tokens: (end.reasoning_output_tokens - start.reasoning_output_tokens)
.max(0),
@@ -1636,6 +1638,7 @@ mod tests {
let start = TokenUsage {
input_tokens: 10,
cached_input_tokens: 8,
cache_write_input_tokens: 8,
output_tokens: 6,
reasoning_output_tokens: 4,
total_tokens: 28,
@@ -1643,6 +1646,7 @@ mod tests {
let end = TokenUsage {
input_tokens: 15,
cached_input_tokens: 7,
cache_write_input_tokens: 7,
output_tokens: 10,
reasoning_output_tokens: 2,
total_tokens: 34,
@@ -1653,6 +1657,7 @@ mod tests {
TokenUsage {
input_tokens: 5,
cached_input_tokens: 0,
cache_write_input_tokens: 0,
output_tokens: 4,
reasoning_output_tokens: 0,
total_tokens: 6,