feat: sync deployed v1.0.0-rc.38-custom.42

Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
This commit is contained in:
cneicy committed 2026-09-26 04:49:11 +08:00
1 parent aa6c3f50f4
commit ceddfd3d6b
828 files changed
+122253 -13702

No files matched your search

+65
View File
@@ -5,6 +5,7 @@ import (
"math/rand"
"testing"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/model"
"github.com/QuantumNous/new-api/pkg/billingexpr"
relaycommon "github.com/QuantumNous/new-api/relay/common"
@@ -752,6 +753,42 @@ func TestBuildTieredTokenParams_GPT_WithImage(t *testing.T) {
}
}
func TestImageCacheBilling(t *testing.T) {
const expression = `tier("standard", p * 5 + cr * 1.25 + img * 8 + img_cr * 2 + c * 30)`
for _, tc := range []struct {
name string
details *dto.CachedTokenDetails
expression string
p, cr, img, imgCR float64
quota int
}{
{"mixed cache", &dto.CachedTokenDetails{ImageTokens: common.GetPointer(200), TextTokens: common.GetPointer(100)}, expression, 300, 100, 400, 200, 4113},
{"explicit free image cache price", &dto.CachedTokenDetails{ImageTokens: common.GetPointer(200)}, `tier("standard", p * 5 + cr * 1.25 + img * 8 + img_cr * 0 + c * 30)`, 300, 100, 400, 200, 3913},
{"explicit zero", &dto.CachedTokenDetails{ImageTokens: common.GetPointer(0)}, expression, 100, 300, 600, 0, 4338},
{"missing breakdown", nil, expression, 100, 300, 600, 0, 4338},
{"missing image modality", &dto.CachedTokenDetails{TextTokens: common.GetPointer(100)}, expression, 100, 300, 600, 0, 4338},
{"negative image count", &dto.CachedTokenDetails{ImageTokens: common.GetPointer(-1)}, expression, 100, 300, 600, 0, 4338},
{"image count exceeds cache", &dto.CachedTokenDetails{ImageTokens: common.GetPointer(301)}, expression, 100, 300, 600, 0, 4338},
{"modality sum exceeds cache", &dto.CachedTokenDetails{ImageTokens: common.GetPointer(200), TextTokens: common.GetPointer(101)}, expression, 100, 300, 600, 0, 4338},
{"old expression unchanged", &dto.CachedTokenDetails{ImageTokens: common.GetPointer(200)}, `p * 5 + cr * 1.25 + img * 8 + c * 30`, 100, 300, 600, 0, 4338},
{"only image cache separately priced", &dto.CachedTokenDetails{ImageTokens: common.GetPointer(200)}, `p * 5 + img_cr * 2 + c * 30`, 800, 100, 400, 200, 3700},
} {
t.Run(tc.name, func(t *testing.T) {
usage := &dto.Usage{PromptTokens: 1000, CompletionTokens: 100,
PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 300, ImageTokens: 600, CachedTokensDetails: tc.details}}
params := BuildTieredTokenParams(usage, false, billingexpr.UsedVars(tc.expression))
assert.Equal(t, tc.p, params.P)
assert.Equal(t, tc.cr, params.CR)
assert.Equal(t, tc.img, params.Img)
assert.Equal(t, tc.imgCR, params.ImgCR)
assert.Equal(t, float64(1000), params.Len)
result, err := billingexpr.ComputeTieredQuota(makeSnapshot(tc.expression, 1, 1000, 100), params)
require.NoError(t, err)
assert.Equal(t, tc.quota, result.ActualQuotaAfterGroup)
})
}
}
func TestBuildTieredTokenParams_Claude_WithCache(t *testing.T) {
usage := &dto.Usage{
PromptTokens: 800,
@@ -1024,3 +1061,31 @@ func BenchmarkRatioBilling_Parallel(b *testing.B) {
}
})
}
func TestSamePriceCacheReadsRemainInInput(t *testing.T) {
for _, tc := range []struct {
name string
usage dto.Usage
extra string
input, cost float64
}{
{"openai", dto.Usage{PromptTokens: 1000, CompletionTokens: 100, PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 200}}, "", 1000, 72000},
{"anthropic", dto.Usage{PromptTokens: 800, CompletionTokens: 100, UsageSemantic: "anthropic", PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 200}}, "", 1000, 72000},
{"anthropic mixed cache TTLs", dto.Usage{PromptTokens: 750, CompletionTokens: 100, UsageSemantic: "anthropic", ClaudeCacheCreation5mTokens: 30, ClaudeCacheCreation1hTokens: 20, PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 200, CachedCreationTokens: 50}}, " + cc * 75 + cc1h * 120", 950, 73650},
} {
t.Run(tc.name, func(t *testing.T) {
merged := `tier("base", p * 60 + c * 120` + tc.extra + `)`
separate := `tier("base", p * 60 + c * 120 + cr * 60` + tc.extra + `)`
params := BuildTieredTokenParams(&tc.usage, tc.usage.UsageSemantic == "anthropic", billingexpr.UsedVars(merged))
assert.Equal(t, tc.input, params.P)
cost, _, err := billingexpr.RunExpr(merged, params)
require.NoError(t, err)
assert.Equal(t, tc.cost, cost)
separateParams := BuildTieredTokenParams(&tc.usage, tc.usage.UsageSemantic == "anthropic", billingexpr.UsedVars(separate))
previousCost, _, err := billingexpr.RunExpr(separate, separateParams)
require.NoError(t, err)
assert.Equal(t, previousCost, cost, "folding cache reads into input must preserve the charge")
assert.Equal(t, separateParams.Len, params.Len, "tier conditions keep the full context length")
})
}
}