feat: cache token stat.
This commit is contained in:
+30
-8
@@ -245,6 +245,8 @@ type aiAnalysisResult struct {
|
||||
Content string
|
||||
InputTokens int
|
||||
OutputTokens int
|
||||
CacheHitTokens int
|
||||
CacheMissTokens int
|
||||
InputSizeBytes int
|
||||
OutputSizeBytes int
|
||||
}
|
||||
@@ -289,10 +291,16 @@ func callAIForAnalysis(prompt string) (*aiAnalysisResult, error) {
|
||||
}
|
||||
|
||||
content := resp.Choices[0].Message.Content
|
||||
cacheHitTokens := 0
|
||||
if resp.Usage.PromptTokensDetails != nil {
|
||||
cacheHitTokens = resp.Usage.PromptTokensDetails.CachedTokens
|
||||
}
|
||||
return &aiAnalysisResult{
|
||||
Content: content,
|
||||
InputTokens: resp.Usage.PromptTokens,
|
||||
OutputTokens: resp.Usage.CompletionTokens,
|
||||
CacheHitTokens: cacheHitTokens,
|
||||
CacheMissTokens: resp.Usage.PromptTokens - cacheHitTokens,
|
||||
InputSizeBytes: len(prompt),
|
||||
OutputSizeBytes: len(content),
|
||||
}, nil
|
||||
@@ -397,17 +405,29 @@ func (tc *TrainingController) AnalyzeByAI(c *gin.Context) {
|
||||
var costJSON string
|
||||
var totalCost float64
|
||||
if err := config.DB.First(&pricing).Error; err == nil {
|
||||
inputCost := float64(analysisResult.InputTokens) * pricing.InputPricePerMillion / 1_000_000
|
||||
cacheMissPrice := pricing.CacheMissPricePerMillion
|
||||
if cacheMissPrice == 0 {
|
||||
cacheMissPrice = pricing.InputPricePerMillion
|
||||
}
|
||||
cacheHitPrice := pricing.CacheHitPricePerMillion
|
||||
if cacheHitPrice == 0 {
|
||||
cacheHitPrice = pricing.InputPricePerMillion
|
||||
}
|
||||
cacheHitCost := float64(analysisResult.CacheHitTokens) * cacheHitPrice / 1_000_000
|
||||
cacheMissCost := float64(analysisResult.CacheMissTokens) * cacheMissPrice / 1_000_000
|
||||
outputCost := float64(analysisResult.OutputTokens) * pricing.OutputPricePerMillion / 1_000_000
|
||||
totalCost = inputCost + outputCost
|
||||
totalCost = cacheHitCost + cacheMissCost + outputCost
|
||||
|
||||
costInfo := map[string]interface{}{
|
||||
"pricingName": pricing.Name,
|
||||
"provider": pricing.Provider,
|
||||
"inputPricePerMillion": pricing.InputPricePerMillion,
|
||||
"outputPricePerMillion": pricing.OutputPricePerMillion,
|
||||
"inputCost": inputCost,
|
||||
"outputCost": outputCost,
|
||||
"pricingName": pricing.Name,
|
||||
"provider": pricing.Provider,
|
||||
"inputPricePerMillion": pricing.InputPricePerMillion,
|
||||
"cacheHitPricePerMillion": cacheHitPrice,
|
||||
"cacheMissPricePerMillion": cacheMissPrice,
|
||||
"outputPricePerMillion": pricing.OutputPricePerMillion,
|
||||
"cacheHitCost": cacheHitCost,
|
||||
"cacheMissCost": cacheMissCost,
|
||||
"outputCost": outputCost,
|
||||
}
|
||||
if b, err := json.Marshal(costInfo); err == nil {
|
||||
costJSON = string(b)
|
||||
@@ -423,6 +443,8 @@ func (tc *TrainingController) AnalyzeByAI(c *gin.Context) {
|
||||
TotalCost: totalCost,
|
||||
InputTokens: analysisResult.InputTokens,
|
||||
OutputTokens: analysisResult.OutputTokens,
|
||||
CacheHitTokens: analysisResult.CacheHitTokens,
|
||||
CacheMissTokens: analysisResult.CacheMissTokens,
|
||||
InputSizeBytes: analysisResult.InputSizeBytes,
|
||||
OutputSizeBytes: analysisResult.OutputSizeBytes,
|
||||
DurationMs: durationMs,
|
||||
|
||||
Reference in New Issue
Block a user