From b8bb3f40ac9d38d309f30a69183cd4813b182678 Mon Sep 17 00:00:00 2001 From: CaIon Date: Mon, 27 Jul 2026 16:45:02 +0800 Subject: [PATCH] refactor: update import paths to use new types package --- controller/channel-test.go | 5 +- controller/channel_test_internal_test.go | 2 +- controller/task.go | 2 +- model/log.go | 2 +- model/pricing.go | 2 +- relay/chat_completions_via_responses_test.go | 2 +- relay/common/relay_info.go | 3 +- relay/helper/price.go | 37 +++++------ relaykit/go.mod | 1 - relaykit/go.sum | 2 - service/log_info_generate.go | 3 +- service/quota.go | 2 +- service/task_billing.go | 2 +- service/task_billing_test.go | 2 +- service/text_quota_test.go | 65 ++++++++++---------- setting/ratio_setting/cache_ratio.go | 2 +- setting/ratio_setting/group_ratio.go | 2 +- setting/ratio_setting/model_ratio.go | 2 +- {relaykit/types => types}/price_data.go | 2 - {relaykit/types => types}/rw_map.go | 13 ++-- {relaykit/types => types}/set.go | 6 -- 21 files changed, 75 insertions(+), 84 deletions(-) rename {relaykit/types => types}/price_data.go (96%) rename {relaykit/types => types}/rw_map.go (78%) rename {relaykit/types => types}/set.go (65%) diff --git a/controller/channel-test.go b/controller/channel-test.go index c705db0f..f6e6bd7f 100644 --- a/controller/channel-test.go +++ b/controller/channel-test.go @@ -28,6 +28,7 @@ import ( "github.com/QuantumNous/new-api/service" "github.com/QuantumNous/new-api/setting/operation_setting" "github.com/QuantumNous/new-api/setting/ratio_setting" + hosttypes "github.com/QuantumNous/new-api/types" "github.com/samber/lo" "github.com/tidwall/gjson" @@ -530,7 +531,7 @@ func attachTestBillingRequestInput(info *relaycommon.RelayInfo, request dto.Requ return nil } -func settleTestQuota(info *relaycommon.RelayInfo, priceData types.PriceData, usage *dto.Usage) (int, *billingexpr.TieredResult) { +func settleTestQuota(info *relaycommon.RelayInfo, priceData hosttypes.PriceData, usage *dto.Usage) (int, *billingexpr.TieredResult) { if usage != nil && info != nil && info.TieredBillingSnapshot != nil { isClaudeUsageSemantic := usage.UsageSemantic == "anthropic" || info.GetFinalRequestRelayFormat() == types.RelayFormatClaude usedVars := billingexpr.UsedVars(info.TieredBillingSnapshot.ExprString) @@ -552,7 +553,7 @@ func settleTestQuota(info *relaycommon.RelayInfo, priceData types.PriceData, usa return int(priceData.ModelPrice * common.QuotaPerUnit), nil } -func buildTestLogOther(c *gin.Context, info *relaycommon.RelayInfo, priceData types.PriceData, usage *dto.Usage, tieredResult *billingexpr.TieredResult) map[string]interface{} { +func buildTestLogOther(c *gin.Context, info *relaycommon.RelayInfo, priceData hosttypes.PriceData, usage *dto.Usage, tieredResult *billingexpr.TieredResult) map[string]interface{} { other := service.GenerateTextOtherInfo(c, info, priceData.ModelRatio, priceData.GroupRatioInfo.GroupRatio, priceData.CompletionRatio, usage.PromptTokensDetails.CachedTokens, priceData.CacheRatio, priceData.ModelPrice, priceData.GroupRatioInfo.GroupSpecialRatio) if tieredResult != nil { diff --git a/controller/channel_test_internal_test.go b/controller/channel_test_internal_test.go index 3af30186..abbd2d23 100644 --- a/controller/channel_test_internal_test.go +++ b/controller/channel_test_internal_test.go @@ -13,9 +13,9 @@ import ( "github.com/QuantumNous/new-api/pkg/billingexpr" relaycommon "github.com/QuantumNous/new-api/relay/common" "github.com/QuantumNous/new-api/relaykit/dto" - "github.com/QuantumNous/new-api/relaykit/types" "github.com/QuantumNous/new-api/service" "github.com/QuantumNous/new-api/setting/operation_setting" + "github.com/QuantumNous/new-api/types" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/controller/task.go b/controller/task.go index cb466a85..a80f1a68 100644 --- a/controller/task.go +++ b/controller/task.go @@ -8,7 +8,7 @@ import ( "github.com/QuantumNous/new-api/dto" "github.com/QuantumNous/new-api/model" "github.com/QuantumNous/new-api/relay" - "github.com/QuantumNous/new-api/relaykit/types" + "github.com/QuantumNous/new-api/types" "github.com/gin-gonic/gin" ) diff --git a/model/log.go b/model/log.go index a6773fcb..401d53c4 100644 --- a/model/log.go +++ b/model/log.go @@ -9,7 +9,7 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/logger" - "github.com/QuantumNous/new-api/relaykit/types" + "github.com/QuantumNous/new-api/types" "github.com/gin-gonic/gin" diff --git a/model/pricing.go b/model/pricing.go index 0bfb1a3b..6dfbfe7a 100644 --- a/model/pricing.go +++ b/model/pricing.go @@ -10,9 +10,9 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/constant" "github.com/QuantumNous/new-api/relaykit/dto" - "github.com/QuantumNous/new-api/relaykit/types" "github.com/QuantumNous/new-api/setting/billing_setting" "github.com/QuantumNous/new-api/setting/ratio_setting" + "github.com/QuantumNous/new-api/types" ) type Pricing struct { diff --git a/relay/chat_completions_via_responses_test.go b/relay/chat_completions_via_responses_test.go index 9f4645a7..18587874 100644 --- a/relay/chat_completions_via_responses_test.go +++ b/relay/chat_completions_via_responses_test.go @@ -5,7 +5,7 @@ import ( "testing" relaycommon "github.com/QuantumNous/new-api/relay/common" - "github.com/QuantumNous/new-api/relaykit/types" + "github.com/QuantumNous/new-api/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/relay/common/relay_info.go b/relay/common/relay_info.go index b26fd799..d8d45f99 100644 --- a/relay/common/relay_info.go +++ b/relay/common/relay_info.go @@ -16,6 +16,7 @@ import ( "github.com/QuantumNous/new-api/relaykit/relayconvert/convmeta" "github.com/QuantumNous/new-api/relaykit/types" "github.com/QuantumNous/new-api/setting/model_setting" + hosttypes "github.com/QuantumNous/new-api/types" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" @@ -155,7 +156,7 @@ type RelayInfo struct { // *bytes.Reader/Buffer/strings.Reader). 0 means "let net/http decide". UpstreamRequestBodySize int64 - PriceData types.PriceData + PriceData hosttypes.PriceData // QuotaClamp is set (non-nil) when a quota conversion saturated at the // int32 bound (or NaN fallback) while computing this request's charge. diff --git a/relay/helper/price.go b/relay/helper/price.go index b85e29b6..b9ae819b 100644 --- a/relay/helper/price.go +++ b/relay/helper/price.go @@ -13,6 +13,7 @@ import ( "github.com/QuantumNous/new-api/setting/billing_setting" "github.com/QuantumNous/new-api/setting/operation_setting" "github.com/QuantumNous/new-api/setting/ratio_setting" + hosttypes "github.com/QuantumNous/new-api/types" "github.com/gin-gonic/gin" ) @@ -41,8 +42,8 @@ const claudeCacheCreation1hMultiplier = 6 / 3.75 const defaultTieredPreConsumeMaxTokens = 8192 // HandleGroupRatio checks for "auto_group" in the context and updates the group ratio and relayInfo.UsingGroup if present -func HandleGroupRatio(ctx *gin.Context, relayInfo *relaycommon.RelayInfo) types.GroupRatioInfo { - groupRatioInfo := types.GroupRatioInfo{ +func HandleGroupRatio(ctx *gin.Context, relayInfo *relaycommon.RelayInfo) hosttypes.GroupRatioInfo { + groupRatioInfo := hosttypes.GroupRatioInfo{ GroupRatio: 1.0, // default ratio GroupSpecialRatio: -1, } @@ -69,7 +70,7 @@ func HandleGroupRatio(ctx *gin.Context, relayInfo *relaycommon.RelayInfo) types. return groupRatioInfo } -func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens int, meta *types.TokenCountMeta) (types.PriceData, error) { +func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens int, meta *types.TokenCountMeta) (hosttypes.PriceData, error) { modelPrice, usePrice := ratio_setting.GetModelPrice(info.OriginModelName, false) groupRatioInfo := HandleGroupRatio(c, info) @@ -104,7 +105,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens acceptUnsetRatio = true } if !acceptUnsetRatio { - return types.PriceData{}, modelPriceNotConfiguredError(matchName, info.UserId) + return hosttypes.PriceData{}, modelPriceNotConfiguredError(matchName, info.UserId) } } completionRatio = ratio_setting.GetCompletionRatio(info.OriginModelName) @@ -119,7 +120,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens ratio := modelRatio * groupRatioInfo.GroupRatio quota, err := common.QuotaFromFloatStrict(float64(preConsumedTokens) * ratio) if err != nil { - return types.PriceData{}, err + return hosttypes.PriceData{}, err } preConsumedQuota = quota } else { @@ -147,7 +148,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens } } - priceData := types.PriceData{ + priceData := hosttypes.PriceData{ FreeModel: freeModel, ModelPrice: modelPrice, ModelRatio: modelRatio, @@ -170,7 +171,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens quotaToPreConsume := priceData.ApplyOtherRatiosToFloat(modelPrice * common.QuotaPerUnit * groupRatioInfo.GroupRatio) quota, err := common.QuotaFromFloatStrict(quotaToPreConsume) if err != nil { - return types.PriceData{}, err + return hosttypes.PriceData{}, err } priceData.QuotaToPreConsume = quota } @@ -183,7 +184,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens } // ModelPriceHelperPerCall 按次/按量计费的 PriceHelper (MJ、Task) -func ModelPriceHelperPerCall(c *gin.Context, info *relaycommon.RelayInfo) (types.PriceData, error) { +func ModelPriceHelperPerCall(c *gin.Context, info *relaycommon.RelayInfo) (hosttypes.PriceData, error) { groupRatioInfo := HandleGroupRatio(c, info) modelPrice, success := ratio_setting.GetModelPrice(info.OriginModelName, true) @@ -204,7 +205,7 @@ func ModelPriceHelperPerCall(c *gin.Context, info *relaycommon.RelayInfo) (types acceptUnsetRatio = true } if !ratioSuccess && !acceptUnsetRatio { - return types.PriceData{}, modelPriceNotConfiguredError(matchName, info.UserId) + return hosttypes.PriceData{}, modelPriceNotConfiguredError(matchName, info.UserId) } } } @@ -216,7 +217,7 @@ func ModelPriceHelperPerCall(c *gin.Context, info *relaycommon.RelayInfo) (types var err error quota, err = common.QuotaFromFloatStrict(modelPrice * common.QuotaPerUnit * groupRatioInfo.GroupRatio) if err != nil { - return types.PriceData{}, err + return hosttypes.PriceData{}, err } if !operation_setting.GetQuotaSetting().EnableFreeModelPreConsume { if groupRatioInfo.GroupRatio == 0 || modelPrice == 0 { @@ -229,7 +230,7 @@ func ModelPriceHelperPerCall(c *gin.Context, info *relaycommon.RelayInfo) (types var err error quota, err = common.QuotaFromFloatStrict(modelRatio / 2 * common.QuotaPerUnit * groupRatioInfo.GroupRatio) if err != nil { - return types.PriceData{}, err + return hosttypes.PriceData{}, err } modelPrice = -1 if !operation_setting.GetQuotaSetting().EnableFreeModelPreConsume { @@ -240,7 +241,7 @@ func ModelPriceHelperPerCall(c *gin.Context, info *relaycommon.RelayInfo) (types } } - priceData := types.PriceData{ + priceData := hosttypes.PriceData{ FreeModel: freeModel, ModelPrice: modelPrice, ModelRatio: modelRatio, @@ -265,10 +266,10 @@ func HasModelBillingConfig(modelName string) bool { return ok && strings.TrimSpace(expr) != "" } -func modelPriceHelperTiered(c *gin.Context, info *relaycommon.RelayInfo, promptTokens int, meta *types.TokenCountMeta, groupRatioInfo types.GroupRatioInfo) (types.PriceData, error) { +func modelPriceHelperTiered(c *gin.Context, info *relaycommon.RelayInfo, promptTokens int, meta *types.TokenCountMeta, groupRatioInfo hosttypes.GroupRatioInfo) (hosttypes.PriceData, error) { exprStr, ok := billing_setting.GetBillingExpr(info.OriginModelName) if !ok { - return types.PriceData{}, fmt.Errorf("model %s is configured as tiered_expr but has no billing expression", info.OriginModelName) + return hosttypes.PriceData{}, fmt.Errorf("model %s is configured as tiered_expr but has no billing expression", info.OriginModelName) } estimatedCompletionTokens := meta.MaxTokens @@ -278,7 +279,7 @@ func modelPriceHelperTiered(c *gin.Context, info *relaycommon.RelayInfo, promptT requestInput, err := ResolveIncomingBillingExprRequestInput(c, info) if err != nil { - return types.PriceData{}, err + return hosttypes.PriceData{}, err } rawCost, trace, err := billingexpr.RunExprWithRequest(exprStr, billingexpr.TokenParams{ @@ -287,14 +288,14 @@ func modelPriceHelperTiered(c *gin.Context, info *relaycommon.RelayInfo, promptT Len: float64(promptTokens), }, requestInput) if err != nil { - return types.PriceData{}, fmt.Errorf("model %s tiered expr run failed: %w", info.OriginModelName, err) + return hosttypes.PriceData{}, fmt.Errorf("model %s tiered expr run failed: %w", info.OriginModelName, err) } // Expression coefficients are $/1M tokens prices; convert to quota the same way per-call billing does. quotaBeforeGroup := rawCost / 1_000_000 * common.QuotaPerUnit preConsumedQuota, err := billingexpr.QuotaRoundStrict(quotaBeforeGroup * groupRatioInfo.GroupRatio) if err != nil { - return types.PriceData{}, err + return hosttypes.PriceData{}, err } freeModel := false @@ -323,7 +324,7 @@ func modelPriceHelperTiered(c *gin.Context, info *relaycommon.RelayInfo, promptT info.TieredBillingSnapshot = snapshot info.BillingRequestInput = &requestInput - priceData := types.PriceData{ + priceData := hosttypes.PriceData{ FreeModel: freeModel, GroupRatioInfo: groupRatioInfo, QuotaToPreConsume: preConsumedQuota, diff --git a/relaykit/go.mod b/relaykit/go.mod index daed09ef..430a7458 100644 --- a/relaykit/go.mod +++ b/relaykit/go.mod @@ -5,7 +5,6 @@ go 1.25.1 require ( github.com/google/uuid v1.6.0 github.com/samber/lo v1.53.0 - github.com/shopspring/decimal v1.4.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.19.0 github.com/tidwall/sjson v1.2.5 diff --git a/relaykit/go.sum b/relaykit/go.sum index d4d8b57f..1abb3990 100644 --- a/relaykit/go.sum +++ b/relaykit/go.sum @@ -18,8 +18,6 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM= github.com/samber/lo v1.53.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= -github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= -github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= diff --git a/service/log_info_generate.go b/service/log_info_generate.go index 220c511c..e510ec02 100644 --- a/service/log_info_generate.go +++ b/service/log_info_generate.go @@ -12,6 +12,7 @@ import ( relaycommon "github.com/QuantumNous/new-api/relay/common" "github.com/QuantumNous/new-api/relaykit/dto" "github.com/QuantumNous/new-api/relaykit/types" + hosttypes "github.com/QuantumNous/new-api/types" "github.com/gin-gonic/gin" ) @@ -289,7 +290,7 @@ func GenerateClaudeOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, return info } -func GenerateMjOtherInfo(relayInfo *relaycommon.RelayInfo, priceData types.PriceData) map[string]interface{} { +func GenerateMjOtherInfo(relayInfo *relaycommon.RelayInfo, priceData hosttypes.PriceData) map[string]interface{} { other := make(map[string]interface{}) other["model_price"] = priceData.ModelPrice other["group_ratio"] = priceData.GroupRatioInfo.GroupRatio diff --git a/service/quota.go b/service/quota.go index 92841667..1f3a9ef2 100644 --- a/service/quota.go +++ b/service/quota.go @@ -15,8 +15,8 @@ import ( perfmetrics "github.com/QuantumNous/new-api/pkg/perf_metrics" relaycommon "github.com/QuantumNous/new-api/relay/common" "github.com/QuantumNous/new-api/relaykit/dto" - "github.com/QuantumNous/new-api/relaykit/types" "github.com/QuantumNous/new-api/setting/ratio_setting" + "github.com/QuantumNous/new-api/types" "github.com/bytedance/gopkg/util/gopool" diff --git a/service/task_billing.go b/service/task_billing.go index 62ba1231..b677cb62 100644 --- a/service/task_billing.go +++ b/service/task_billing.go @@ -10,8 +10,8 @@ import ( "github.com/QuantumNous/new-api/logger" "github.com/QuantumNous/new-api/model" relaycommon "github.com/QuantumNous/new-api/relay/common" - "github.com/QuantumNous/new-api/relaykit/types" "github.com/QuantumNous/new-api/setting/ratio_setting" + "github.com/QuantumNous/new-api/types" "github.com/gin-gonic/gin" ) diff --git a/service/task_billing_test.go b/service/task_billing_test.go index 6a0ae123..53e3f680 100644 --- a/service/task_billing_test.go +++ b/service/task_billing_test.go @@ -12,7 +12,7 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/model" relaycommon "github.com/QuantumNous/new-api/relay/common" - "github.com/QuantumNous/new-api/relaykit/types" + "github.com/QuantumNous/new-api/types" "github.com/glebarez/sqlite" "github.com/shopspring/decimal" "github.com/stretchr/testify/assert" diff --git a/service/text_quota_test.go b/service/text_quota_test.go index a27df970..5a908af2 100644 --- a/service/text_quota_test.go +++ b/service/text_quota_test.go @@ -14,6 +14,7 @@ import ( "github.com/QuantumNous/new-api/relaykit/dto" "github.com/QuantumNous/new-api/relaykit/types" "github.com/QuantumNous/new-api/setting/operation_setting" + hosttypes "github.com/QuantumNous/new-api/types" "github.com/gin-gonic/gin" "github.com/shopspring/decimal" @@ -37,14 +38,14 @@ func TestCalculateTextQuotaSummaryUnifiedForClaudeSemantic(t *testing.T) { ClaudeCacheCreation1hTokens: 20, } - priceData := types.PriceData{ + priceData := hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 2, CacheRatio: 0.1, CacheCreationRatio: 1.25, CacheCreation5mRatio: 1.25, CacheCreation1hRatio: 2, - GroupRatioInfo: types.GroupRatioInfo{ + GroupRatioInfo: hosttypes.GroupRatioInfo{ GroupRatio: 1, }, } @@ -83,14 +84,14 @@ func TestCalculateTextQuotaSummaryUsesSplitClaudeCacheCreationRatios(t *testing. RelayFormat: types.RelayFormatOpenAI, FinalRequestRelayFormat: types.RelayFormatClaude, OriginModelName: "claude-3-7-sonnet", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 1, CacheRatio: 0, CacheCreationRatio: 1, CacheCreation5mRatio: 2, CacheCreation1hRatio: 3, - GroupRatioInfo: types.GroupRatioInfo{ + GroupRatioInfo: hosttypes.GroupRatioInfo{ GroupRatio: 1, }, }, @@ -121,14 +122,14 @@ func TestCalculateTextQuotaSummaryUsesAnthropicUsageSemanticFromUpstreamUsage(t relayInfo := &relaycommon.RelayInfo{ RelayFormat: types.RelayFormatOpenAI, OriginModelName: "claude-3-7-sonnet", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 2, CacheRatio: 0.1, CacheCreationRatio: 1.25, CacheCreation5mRatio: 1.25, CacheCreation1hRatio: 2, - GroupRatioInfo: types.GroupRatioInfo{ + GroupRatioInfo: hosttypes.GroupRatioInfo{ GroupRatio: 1, }, }, @@ -162,14 +163,14 @@ func TestCalculateTextQuotaSummaryUsesClaudeBillingUsageBeforeTopLevelUsage(t *t relayInfo := &relaycommon.RelayInfo{ RelayFormat: types.RelayFormatOpenAI, OriginModelName: "claude-3-7-sonnet", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 2, CacheRatio: 0.1, CacheCreationRatio: 1.25, CacheCreation5mRatio: 1.25, CacheCreation1hRatio: 2, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1}, }, StartTime: time.Now(), } @@ -211,11 +212,11 @@ func TestCalculateTextQuotaSummaryUsesGeminiBillingUsageBeforeTopLevelUsage(t *t relayInfo := &relaycommon.RelayInfo{ RelayFormat: types.RelayFormatOpenAI, OriginModelName: "gemini-2.5-flash", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 2, CacheRatio: 0.1, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1}, }, StartTime: time.Now(), } @@ -253,10 +254,10 @@ func TestCalculateTextQuotaSummaryUsesOpenAIBillingUsageBeforeTopLevelUsage(t *t relayInfo := &relaycommon.RelayInfo{ RelayFormat: types.RelayFormatClaude, OriginModelName: "gpt-4o", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 2, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1}, }, StartTime: time.Now(), } @@ -352,14 +353,14 @@ func TestCalculateTextQuotaSummaryHandlesLegacyClaudeDerivedOpenAIUsage(t *testi relayInfo := &relaycommon.RelayInfo{ RelayFormat: types.RelayFormatOpenAI, OriginModelName: "claude-3-7-sonnet", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 5, CacheRatio: 0.1, CacheCreationRatio: 1.25, CacheCreation5mRatio: 1.25, CacheCreation1hRatio: 2, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1}, }, StartTime: time.Now(), } @@ -387,12 +388,12 @@ func TestCalculateTextQuotaSummaryBillsOpenAICacheWriteTokens(t *testing.T) { relayInfo := &relaycommon.RelayInfo{ RelayFormat: types.RelayFormatOpenAI, OriginModelName: "gpt-5.1", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 2, CacheRatio: 0.1, CacheCreationRatio: 1.25, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1}, }, StartTime: time.Now(), } @@ -445,12 +446,12 @@ func TestCalculateTextQuotaSummarySeparatesOpenRouterCacheReadFromPromptBilling( ChannelMeta: &relaycommon.ChannelMeta{ ChannelType: constant.ChannelTypeOpenRouter, }, - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 1, CacheRatio: 0.1, CacheCreationRatio: 1.25, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1}, }, StartTime: time.Now(), } @@ -482,11 +483,11 @@ func TestCalculateTextQuotaSummarySeparatesOpenRouterCacheCreationFromPromptBill ChannelMeta: &relaycommon.ChannelMeta{ ChannelType: constant.ChannelTypeOpenRouter, }, - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 1, CacheCreationRatio: 1.25, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1}, }, StartTime: time.Now(), } @@ -518,12 +519,12 @@ func TestCalculateTextQuotaSummaryKeepsPrePRClaudeOpenRouterBilling(t *testing.T ChannelMeta: &relaycommon.ChannelMeta{ ChannelType: constant.ChannelTypeOpenRouter, }, - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 1, CacheRatio: 0.1, CacheCreationRatio: 1.25, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1}, }, StartTime: time.Now(), } @@ -559,10 +560,10 @@ func TestComposeTieredTextQuotaKeepsToolCallSurcharges(t *testing.T) { relayInfo := &relaycommon.RelayInfo{ OriginModelName: "o1", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 1, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1}, }, ResponsesUsageInfo: &relaycommon.ResponsesUsageInfo{ BuiltInTools: map[string]*relaycommon.BuildInToolInfo{ @@ -609,10 +610,10 @@ func TestComposeTieredTextQuotaFallbackKeepsToolCallSurcharges(t *testing.T) { relayInfo := &relaycommon.RelayInfo{ OriginModelName: "claude-3-7-sonnet", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 1, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1.25}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1.25}, }, TieredBillingSnapshot: &billingexpr.BillingSnapshot{ BillingMode: "tiered_expr", @@ -643,10 +644,10 @@ func TestComposeTieredTextQuotaErrorFallbackUsesPreConsumedQuota(t *testing.T) { relayInfo := &relaycommon.RelayInfo{ OriginModelName: "claude-3-7-sonnet", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 1, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1.25}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1.25}, }, TieredBillingSnapshot: &billingexpr.BillingSnapshot{ BillingMode: "tiered_expr", @@ -726,10 +727,10 @@ func TestTryTieredSettleNoClampInRange(t *testing.T) { func TestCalculateTextQuotaSummaryFixedPriceAppliesImageCountOnceAndAllowsOverride(t *testing.T) { gin.SetMode(gin.TestMode) ctx, _ := gin.CreateTestContext(httptest.NewRecorder()) - priceData := types.PriceData{ + priceData := hosttypes.PriceData{ ModelPrice: 0.12, UsePrice: true, - GroupRatioInfo: types.GroupRatioInfo{ + GroupRatioInfo: hosttypes.GroupRatioInfo{ GroupRatio: 1, }, } @@ -911,10 +912,10 @@ func TestCalculateTextQuotaSummaryDoesNotApplyRequestMultipliersToToolSurcharge( relayInfo := &relaycommon.RelayInfo{ OriginModelName: "o1", - PriceData: types.PriceData{ + PriceData: hosttypes.PriceData{ ModelRatio: 1, CompletionRatio: 1, - GroupRatioInfo: types.GroupRatioInfo{GroupRatio: 1}, + GroupRatioInfo: hosttypes.GroupRatioInfo{GroupRatio: 1}, }, ResponsesUsageInfo: &relaycommon.ResponsesUsageInfo{ BuiltInTools: map[string]*relaycommon.BuildInToolInfo{ diff --git a/setting/ratio_setting/cache_ratio.go b/setting/ratio_setting/cache_ratio.go index 42147607..6e874b5b 100644 --- a/setting/ratio_setting/cache_ratio.go +++ b/setting/ratio_setting/cache_ratio.go @@ -1,7 +1,7 @@ package ratio_setting import ( - "github.com/QuantumNous/new-api/relaykit/types" + "github.com/QuantumNous/new-api/types" ) var defaultCacheRatio = map[string]float64{ diff --git a/setting/ratio_setting/group_ratio.go b/setting/ratio_setting/group_ratio.go index c52f5e5e..7d16d928 100644 --- a/setting/ratio_setting/group_ratio.go +++ b/setting/ratio_setting/group_ratio.go @@ -5,8 +5,8 @@ import ( "errors" "github.com/QuantumNous/new-api/common" - "github.com/QuantumNous/new-api/relaykit/types" "github.com/QuantumNous/new-api/setting/config" + "github.com/QuantumNous/new-api/types" ) var defaultGroupRatio = map[string]float64{ diff --git a/setting/ratio_setting/model_ratio.go b/setting/ratio_setting/model_ratio.go index e3ecc344..829e0794 100644 --- a/setting/ratio_setting/model_ratio.go +++ b/setting/ratio_setting/model_ratio.go @@ -4,8 +4,8 @@ import ( "strings" "github.com/QuantumNous/new-api/common" - "github.com/QuantumNous/new-api/relaykit/types" "github.com/QuantumNous/new-api/setting/operation_setting" + "github.com/QuantumNous/new-api/types" ) // from songquanpeng/one-api diff --git a/relaykit/types/price_data.go b/types/price_data.go similarity index 96% rename from relaykit/types/price_data.go rename to types/price_data.go index 8ab1c57c..b9215f7b 100644 --- a/relaykit/types/price_data.go +++ b/types/price_data.go @@ -104,8 +104,6 @@ func (p *PriceData) RemoveOtherRatiosFromFloat(value float64) float64 { } func isValidOtherRatio(ratio float64) bool { - // NaN/Inf would poison every downstream quota multiplication - // (int(NaN * quota) wraps to a negative charge). return ratio > 0 && !math.IsInf(ratio, 1) } diff --git a/relaykit/types/rw_map.go b/types/rw_map.go similarity index 78% rename from relaykit/types/rw_map.go rename to types/rw_map.go index 46dd5d8e..5c5e0640 100644 --- a/relaykit/types/rw_map.go +++ b/types/rw_map.go @@ -3,7 +3,7 @@ package types import ( "sync" - kitutil "github.com/QuantumNous/new-api/relaykit/relayconvert/kitutil" + "github.com/QuantumNous/new-api/common" ) type RWMap[K comparable, V any] struct { @@ -15,13 +15,13 @@ func (m *RWMap[K, V]) UnmarshalJSON(b []byte) error { m.mutex.Lock() defer m.mutex.Unlock() m.data = make(map[K]V) - return kitutil.Unmarshal(b, &m.data) + return common.Unmarshal(b, &m.data) } func (m *RWMap[K, V]) MarshalJSON() ([]byte, error) { m.mutex.RLock() defer m.mutex.RUnlock() - return kitutil.Marshal(m.data) + return common.Marshal(m.data) } func NewRWMap[K comparable, V any]() *RWMap[K, V] { @@ -57,7 +57,6 @@ func (m *RWMap[K, V]) Clear() { m.data = make(map[K]V) } -// ReadAll returns a copy of the entire map. func (m *RWMap[K, V]) ReadAll() map[K]V { m.mutex.RLock() defer m.mutex.RUnlock() @@ -78,22 +77,20 @@ func LoadFromJsonString[K comparable, V any](m *RWMap[K, V], jsonStr string) err m.mutex.Lock() defer m.mutex.Unlock() m.data = make(map[K]V) - return kitutil.Unmarshal([]byte(jsonStr), &m.data) + return common.Unmarshal([]byte(jsonStr), &m.data) } -// LoadFromJsonStringWithCallback loads a JSON string into the RWMap and calls the callback on success. func LoadFromJsonStringWithCallback[K comparable, V any](m *RWMap[K, V], jsonStr string, onSuccess func()) error { m.mutex.Lock() defer m.mutex.Unlock() m.data = make(map[K]V) - err := kitutil.Unmarshal([]byte(jsonStr), &m.data) + err := common.Unmarshal([]byte(jsonStr), &m.data) if err == nil && onSuccess != nil { onSuccess() } return err } -// MarshalJSONString returns the JSON string representation of the RWMap. func (m *RWMap[K, V]) MarshalJSONString() string { bytes, err := m.MarshalJSON() if err != nil { diff --git a/relaykit/types/set.go b/types/set.go similarity index 65% rename from relaykit/types/set.go rename to types/set.go index db6b0272..c0b09e86 100644 --- a/relaykit/types/set.go +++ b/types/set.go @@ -4,7 +4,6 @@ type Set[T comparable] struct { items map[T]struct{} } -// NewSet 创建并返回一个新的 Set func NewSet[T comparable]() *Set[T] { return &Set[T]{ items: make(map[T]struct{}), @@ -15,24 +14,19 @@ func (s *Set[T]) Add(item T) { s.items[item] = struct{}{} } -// Remove 从 Set 中移除一个元素 func (s *Set[T]) Remove(item T) { delete(s.items, item) } -// Contains 检查 Set 是否包含某个元素 func (s *Set[T]) Contains(item T) bool { _, exists := s.items[item] return exists } -// Len 返回 Set 中元素的数量 func (s *Set[T]) Len() int { return len(s.items) } -// Items 返回 Set 中所有元素组成的切片 -// 注意:由于 map 的无序性,返回的切片元素顺序是随机的 func (s *Set[T]) Items() []T { items := make([]T, 0, s.Len()) for item := range s.items {