| 197 | } |
| 198 | |
| 199 | pub(super) fn parse_usage_object(value: Option<&Value>) -> AssistantUsage { |
| 200 | let mut usage = AssistantUsage::default(); |
| 201 | let Some(record) = value.and_then(Value::as_object) else { |
| 202 | return usage; |
| 203 | }; |
| 204 | usage.input_tokens = pick_u64( |
| 205 | record, |
| 206 | &[ |
| 207 | "inputTokens", |
| 208 | "input_tokens", |
| 209 | "promptTokens", |
| 210 | "prompt_tokens", |
| 211 | ], |
| 212 | ); |
| 213 | usage.output_tokens = pick_u64( |
| 214 | record, |
| 215 | &[ |
| 216 | "outputTokens", |
| 217 | "output_tokens", |
| 218 | "completionTokens", |
| 219 | "completion_tokens", |
| 220 | ], |
| 221 | ); |
| 222 | usage.cache_read_input_tokens = |
| 223 | pick_u64(record, &["cacheReadInputTokens", "cache_read_input_tokens"]) |
| 224 | .max(pick_nested_u64( |
| 225 | record, |
| 226 | "promptTokensDetails", |
| 227 | &["cachedTokens"], |
| 228 | )) |
| 229 | .max(pick_nested_u64( |
| 230 | record, |
| 231 | "prompt_tokens_details", |
| 232 | &["cached_tokens"], |
| 233 | )); |
| 234 | usage.cache_creation_input_tokens = pick_u64( |
| 235 | record, |
| 236 | &[ |
| 237 | "cacheCreationInputTokens", |
| 238 | "cache_creation_input_tokens", |
| 239 | "cacheCreationTokens", |
| 240 | "cache_creation_tokens", |
| 241 | "cachedTokensCreated", |
| 242 | "cached_tokens_created", |
| 243 | ], |
| 244 | ); |
| 245 | let total_tokens = pick_u64(record, &["totalTokens", "total_tokens", "total"]); |
| 246 | let raw_usage = TokenUsageRaw { |
| 247 | input_tokens: usage.input_tokens, |
| 248 | output_tokens: usage.output_tokens, |
| 249 | cache_creation_input_tokens: usage.cache_creation_input_tokens, |
| 250 | cache_read_input_tokens: usage.cache_read_input_tokens, |
| 251 | speed: None, |
| 252 | cache_creation: None, |
| 253 | }; |
| 254 | let (raw_usage, extra_total_tokens) = |
| 255 | apply_total_token_fallback(raw_usage, usage.extra_total_tokens, total_tokens); |
| 256 | usage.input_tokens = raw_usage.input_tokens; |