Skip to main content

llmsdk_provider/language_model/
usage.rs

1//! Token usage reported by a language model call.
2//!
3//! Mirrors `language-model-v4-usage.ts`. All counters are optional because
4//! many providers omit subsets.
5// Rust guideline compliant 2026-02-21
6
7use serde::{Deserialize, Serialize};
8
9use crate::json::JsonObject;
10
11/// Aggregated token usage for a call.
12#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
13pub struct Usage {
14    /// Input-side counters.
15    #[serde(rename = "inputTokens")]
16    pub input_tokens: InputTokenUsage,
17    /// Output-side counters.
18    #[serde(rename = "outputTokens")]
19    pub output_tokens: OutputTokenUsage,
20    /// Provider-native usage object preserved verbatim.
21    #[serde(default, skip_serializing_if = "Option::is_none")]
22    pub raw: Option<JsonObject>,
23}
24
25/// Input-side token counters.
26#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
27pub struct InputTokenUsage {
28    /// Total input tokens.
29    #[serde(default, skip_serializing_if = "Option::is_none")]
30    pub total: Option<u64>,
31    /// Non-cached input tokens.
32    #[serde(default, rename = "noCache", skip_serializing_if = "Option::is_none")]
33    pub no_cache: Option<u64>,
34    /// Cached input tokens read.
35    #[serde(default, rename = "cacheRead", skip_serializing_if = "Option::is_none")]
36    pub cache_read: Option<u64>,
37    /// Cached input tokens written.
38    #[serde(
39        default,
40        rename = "cacheWrite",
41        skip_serializing_if = "Option::is_none"
42    )]
43    pub cache_write: Option<u64>,
44}
45
46/// Output-side token counters.
47#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
48pub struct OutputTokenUsage {
49    /// Total output tokens.
50    #[serde(default, skip_serializing_if = "Option::is_none")]
51    pub total: Option<u64>,
52    /// Output text tokens.
53    #[serde(default, skip_serializing_if = "Option::is_none")]
54    pub text: Option<u64>,
55    /// Output reasoning tokens.
56    #[serde(default, skip_serializing_if = "Option::is_none")]
57    pub reasoning: Option<u64>,
58}