feat: bill OpenAI cache_write_tokens at cache-creation price with zero clamp
Parse OpenAI's native cache_write_tokens (chat prompt_tokens_details / responses input_tokens_details), bill it at the cache-creation ratio, and clamp the uncached prompt remainder at zero since cached + cache-write can exceed prompt_tokens. Propagate the field through chat/responses/claude format conversions and tiered expression billing (cc variable).
This commit is contained in:
@@ -51,6 +51,7 @@ func OaiResponsesHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http
|
||||
usage.TotalTokens = responsesResponse.Usage.TotalTokens
|
||||
if responsesResponse.Usage.InputTokensDetails != nil {
|
||||
usage.PromptTokensDetails.CachedTokens = responsesResponse.Usage.InputTokensDetails.CachedTokens
|
||||
usage.PromptTokensDetails.CacheWriteTokens = responsesResponse.Usage.InputTokensDetails.CacheWriteTokens
|
||||
}
|
||||
}
|
||||
if info == nil || info.ResponsesUsageInfo == nil || info.ResponsesUsageInfo.BuiltInTools == nil {
|
||||
@@ -104,6 +105,7 @@ func OaiResponsesStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp
|
||||
}
|
||||
if streamResponse.Response.Usage.InputTokensDetails != nil {
|
||||
usage.PromptTokensDetails.CachedTokens = streamResponse.Response.Usage.InputTokensDetails.CachedTokens
|
||||
usage.PromptTokensDetails.CacheWriteTokens = streamResponse.Response.Usage.InputTokensDetails.CacheWriteTokens
|
||||
}
|
||||
}
|
||||
if streamResponse.Response.HasImageGenerationCall() {
|
||||
|
||||
@@ -37,6 +37,7 @@ func OaiResponsesCompactionHandler(c *gin.Context, resp *http.Response) (*dto.Us
|
||||
usage.TotalTokens = compactResp.Usage.TotalTokens
|
||||
if compactResp.Usage.InputTokensDetails != nil {
|
||||
usage.PromptTokensDetails.CachedTokens = compactResp.Usage.InputTokensDetails.CachedTokens
|
||||
usage.PromptTokensDetails.CacheWriteTokens = compactResp.Usage.InputTokensDetails.CacheWriteTokens
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,12 +41,14 @@ func ResponsesHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *
|
||||
responsesReq = req
|
||||
case *dto.OpenAIResponsesCompactionRequest:
|
||||
responsesReq = &dto.OpenAIResponsesRequest{
|
||||
Model: req.Model,
|
||||
Input: req.Input,
|
||||
Instructions: req.Instructions,
|
||||
PreviousResponseID: req.PreviousResponseID,
|
||||
ParallelToolCalls: req.ParallelToolCalls,
|
||||
ServiceTier: req.ServiceTier,
|
||||
Model: req.Model,
|
||||
Input: req.Input,
|
||||
Instructions: req.Instructions,
|
||||
PreviousResponseID: req.PreviousResponseID,
|
||||
ParallelToolCalls: req.ParallelToolCalls,
|
||||
ServiceTier: req.ServiceTier,
|
||||
PromptCacheOptions: req.PromptCacheOptions,
|
||||
PromptCacheRetention: req.PromptCacheRetention,
|
||||
}
|
||||
default:
|
||||
return types.NewErrorWithStatusCode(
|
||||
|
||||
Reference in New Issue
Block a user