feat: support cached input token billing

This commit is contained in:
2026-06-23 17:17:57 +08:00
parent 6089aa6085
commit 7f32446466
16 changed files with 570 additions and 45 deletions
+43 -2
View File
@@ -185,11 +185,17 @@ func buildOpenAIStreamResult(last map[string]any, parts []string, reasoningParts
}},
}
if usage.TotalTokens > 0 {
out["usage"] = map[string]any{
usageMap := map[string]any{
"prompt_tokens": usage.InputTokens,
"completion_tokens": usage.OutputTokens,
"total_tokens": usage.TotalTokens,
}
if usage.CachedInputTokens > 0 {
usageMap["prompt_tokens_details"] = map[string]any{
"cached_tokens": usage.CachedInputTokens,
}
}
out["usage"] = usageMap
}
return out
}
@@ -877,7 +883,42 @@ func usageFromOpenAI(result map[string]any) Usage {
if total == 0 {
total = input + output
}
return Usage{InputTokens: input, OutputTokens: output, TotalTokens: total}
cachedInput := cachedInputTokensFromOpenAIUsage(usage)
if cachedInput > input && input > 0 {
cachedInput = input
}
return Usage{InputTokens: input, OutputTokens: output, CachedInputTokens: cachedInput, TotalTokens: total}
}
func cachedInputTokensFromOpenAIUsage(usage map[string]any) int {
if len(usage) == 0 {
return 0
}
promptDetails, _ := firstPresent(usage["prompt_tokens_details"], usage["promptTokensDetails"]).(map[string]any)
inputDetails, _ := firstPresent(usage["input_tokens_details"], usage["inputTokensDetails"]).(map[string]any)
usageMetadata, _ := usage["usageMetadata"].(map[string]any)
return intFromAny(firstPresent(
promptDetails["cached_tokens"],
promptDetails["cachedTokens"],
promptDetails["cache_read_input_tokens"],
promptDetails["cacheReadInputTokens"],
inputDetails["cached_tokens"],
inputDetails["cachedTokens"],
inputDetails["cache_read_input_tokens"],
inputDetails["cacheReadInputTokens"],
usage["prompt_cache_hit_tokens"],
usage["promptCacheHitTokens"],
usage["cached_tokens"],
usage["cachedTokens"],
usage["cached_input_tokens"],
usage["cachedInputTokens"],
usage["cache_read_input_tokens"],
usage["cacheReadInputTokens"],
usage["cached_content_token_count"],
usage["cachedContentTokenCount"],
usageMetadata["cached_content_token_count"],
usageMetadata["cachedContentTokenCount"],
))
}
func requestIDFromHTTPResponse(resp *http.Response) string {