mirror of
https://mirror.skon.top/github.com/router-for-me/CLIProxyAPI
synced 2026-04-30 16:20:23 +08:00
fix(usage_helpers): skip zero-token usage in additional model records
- Added `buildAdditionalModelRecord` to filter out zero-token usage details. - Introduced `hasNonZeroTokenUsage` helper function for token usage validation. - Updated tests to cover scenarios for zero and non-zero token usage.
This commit is contained in:
@@ -49,15 +49,26 @@ func (r *UsageReporter) Publish(ctx context.Context, detail usage.Detail) {
|
||||
}
|
||||
|
||||
func (r *UsageReporter) PublishAdditionalModel(ctx context.Context, model string, detail usage.Detail) {
|
||||
if r == nil {
|
||||
record, ok := r.buildAdditionalModelRecord(model, detail)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
usage.PublishRecord(ctx, record)
|
||||
}
|
||||
|
||||
func (r *UsageReporter) buildAdditionalModelRecord(model string, detail usage.Detail) (usage.Record, bool) {
|
||||
if r == nil {
|
||||
return usage.Record{}, false
|
||||
}
|
||||
model = strings.TrimSpace(model)
|
||||
if model == "" {
|
||||
return
|
||||
return usage.Record{}, false
|
||||
}
|
||||
detail = normalizeUsageDetailTotal(detail)
|
||||
usage.PublishRecord(ctx, r.buildRecordForModel(model, detail, false))
|
||||
if !hasNonZeroTokenUsage(detail) {
|
||||
return usage.Record{}, false
|
||||
}
|
||||
return r.buildRecordForModel(model, detail, false), true
|
||||
}
|
||||
|
||||
func (r *UsageReporter) PublishFailure(ctx context.Context) {
|
||||
@@ -93,6 +104,14 @@ func normalizeUsageDetailTotal(detail usage.Detail) usage.Detail {
|
||||
return detail
|
||||
}
|
||||
|
||||
func hasNonZeroTokenUsage(detail usage.Detail) bool {
|
||||
return detail.InputTokens != 0 ||
|
||||
detail.OutputTokens != 0 ||
|
||||
detail.ReasoningTokens != 0 ||
|
||||
detail.CachedTokens != 0 ||
|
||||
detail.TotalTokens != 0
|
||||
}
|
||||
|
||||
// ensurePublished guarantees that a usage record is emitted exactly once.
|
||||
// It is safe to call multiple times; only the first call wins due to once.Do.
|
||||
// This is used to ensure request counting even when upstream responses do not
|
||||
|
||||
@@ -62,3 +62,21 @@ func TestUsageReporterBuildRecordIncludesLatency(t *testing.T) {
|
||||
t.Fatalf("latency = %v, want <= 3s", record.Latency)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsageReporterBuildAdditionalModelRecordSkipsZeroTokens(t *testing.T) {
|
||||
reporter := &UsageReporter{
|
||||
provider: "codex",
|
||||
model: "gpt-5.4",
|
||||
requestedAt: time.Now(),
|
||||
}
|
||||
|
||||
if _, ok := reporter.buildAdditionalModelRecord("gpt-image-2", usage.Detail{}); ok {
|
||||
t.Fatalf("expected all-zero token usage to be skipped")
|
||||
}
|
||||
if _, ok := reporter.buildAdditionalModelRecord("gpt-image-2", usage.Detail{InputTokens: 2}); !ok {
|
||||
t.Fatalf("expected non-zero input token usage to be recorded")
|
||||
}
|
||||
if _, ok := reporter.buildAdditionalModelRecord("gpt-image-2", usage.Detail{CachedTokens: 2}); !ok {
|
||||
t.Fatalf("expected non-zero cached token usage to be recorded")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user