Convert `StreamUsage` from the provider into session-level `MessageUsage`.
(
usage: &StreamUsage,
provider_metadata: Option<&serde_json::Value>,
provider_id: &str,
)
| 1174 | |
| 1175 | /// Convert `StreamUsage` from the provider into session-level `MessageUsage`. |
| 1176 | fn usage_from_stream( |
| 1177 | usage: &StreamUsage, |
| 1178 | provider_metadata: Option<&serde_json::Value>, |
| 1179 | provider_id: &str, |
| 1180 | ) -> MessageUsage { |
| 1181 | let (meta_cache_read, meta_cache_write) = |
| 1182 | extract_cache_tokens_from_metadata(provider_metadata, provider_id); |
| 1183 | let cache_read_tokens = usage.cache_read_tokens.max(meta_cache_read); |
| 1184 | let cache_write_tokens = usage.cache_write_tokens.max(meta_cache_write); |
| 1185 | |
| 1186 | MessageUsage { |
| 1187 | input_tokens: usage.prompt_tokens, |
| 1188 | output_tokens: usage.completion_tokens, |
| 1189 | reasoning_tokens: usage.reasoning_tokens, |
| 1190 | // Anthropic/Bedrock `input_tokens` do not include cached usage; keep cache |
| 1191 | // tokens explicit so total usage and compaction logic can account for them. |
| 1192 | cache_write_tokens, |
| 1193 | cache_read_tokens, |
| 1194 | total_cost: 0.0, // Cost is computed separately |
| 1195 | } |
| 1196 | } |
| 1197 | |
| 1198 | /// Compute cost from stream usage using model-specific pricing rates. |
| 1199 | /// Falls back to Claude-like pricing ($3/$15 per million) if no rates provided. |