ai_sdk_provider/language_model/
usage.rs

1use serde::{Deserialize, Serialize};
2
3/// Usage information for a language model call.
4#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5#[serde(rename_all = "camelCase")]
6pub struct Usage {
7    /// The number of input (prompt) tokens used.
8    #[serde(skip_serializing_if = "Option::is_none")]
9    pub input_tokens: Option<u32>,
10
11    /// The number of output (completion) tokens used.
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub output_tokens: Option<u32>,
14
15    /// The total number of tokens as reported by the provider.
16    /// This might differ from input + output and include reasoning tokens.
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub total_tokens: Option<u32>,
19
20    /// The number of reasoning tokens used.
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub reasoning_tokens: Option<u32>,
23
24    /// The number of cached input tokens.
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub cached_input_tokens: Option<u32>,
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32
33    #[test]
34    fn test_usage_serialization() {
35        let usage = Usage {
36            input_tokens: Some(100),
37            output_tokens: Some(50),
38            total_tokens: Some(150),
39            reasoning_tokens: None,
40            cached_input_tokens: None,
41        };
42        let json = serde_json::to_value(&usage).unwrap();
43        assert_eq!(json["inputTokens"], 100);
44        assert_eq!(json["outputTokens"], 50);
45        assert_eq!(json["totalTokens"], 150);
46
47        // Ensure None fields are not serialized
48        assert!(json.get("reasoningTokens").is_none());
49        assert!(json.get("cachedInputTokens").is_none());
50    }
51
52    #[test]
53    fn test_usage_default() {
54        let usage = Usage::default();
55        assert_eq!(usage.input_tokens, None);
56        assert_eq!(usage.output_tokens, None);
57    }
58}