openai_usage.go RawHistoryFolder
1package provider
2
3// openAIInputTokensDetails is shared by the Chat Completions and Responses
4// streams. The details object is optional; its presence is the availability
5// signal for cache accounting, including a known cache miss.
6type openAIInputTokensDetails struct {
7 CachedTokens int `json:"cached_tokens"`
8 CacheWriteTokens int `json:"cache_write_tokens"`
9}
10
11// normalizeDeepSeekUsage converts DeepSeek's explicit hit/miss counts into
12// disjoint usage buckets. Cache accounting is accepted only when both fields
13// are present and add up to the reported prompt total.
14func normalizeDeepSeekUsage(inputTokens, outputTokens int, cacheHits, cacheMisses *int) Usage {
15 usage := Usage{InputTokens: inputTokens, OutputTokens: outputTokens}
16 if inputTokens < 0 || outputTokens < 0 || cacheHits == nil || cacheMisses == nil || *cacheHits < 0 || *cacheMisses < 0 || *cacheHits+*cacheMisses != inputTokens {
17 if usage.InputTokens < 0 {
18 usage.InputTokens = 0
19 }
20 if usage.OutputTokens < 0 {
21 usage.OutputTokens = 0
22 }
23 return usage
24 }
25
26 usage.InputTokens = *cacheMisses
27 usage.CacheReadTokens = *cacheHits
28 usage.CacheMeasuredPromptTokens = inputTokens
29 usage.CacheMeasuredReadTokens = *cacheHits
30 return usage
31}
32
33// normalizeOpenAIUsage converts OpenAI's total input count and optional cache
34// detail into disjoint usage buckets. Malformed detail must not create a
35// negative ordinary-input count or an unsupported cache metric, so it falls
36// back to treating the total as ordinary input.
37func normalizeOpenAIUsage(inputTokens, outputTokens int, details *openAIInputTokensDetails) Usage {
38 if inputTokens < 0 {
39 inputTokens = 0
40 }
41 if outputTokens < 0 {
42 outputTokens = 0
43 }
44
45 usage := Usage{InputTokens: inputTokens, OutputTokens: outputTokens}
46 if details == nil || details.CachedTokens < 0 || details.CacheWriteTokens < 0 {
47 return usage
48 }
49 if details.CachedTokens+details.CacheWriteTokens > inputTokens {
50 return usage
51 }
52
53 usage.InputTokens -= details.CachedTokens + details.CacheWriteTokens
54 usage.CacheReadTokens = details.CachedTokens
55 usage.CacheWriteTokens = details.CacheWriteTokens
56 usage.CacheMeasuredPromptTokens = inputTokens
57 usage.CacheMeasuredReadTokens = details.CachedTokens
58 return usage
59}