price.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package helper
  2. import (
  3. "fmt"
  4. "github.com/QuantumNous/new-api/common"
  5. "github.com/QuantumNous/new-api/logger"
  6. relaycommon "github.com/QuantumNous/new-api/relay/common"
  7. "github.com/QuantumNous/new-api/setting/operation_setting"
  8. "github.com/QuantumNous/new-api/setting/ratio_setting"
  9. "github.com/QuantumNous/new-api/types"
  10. "github.com/gin-gonic/gin"
  11. )
  12. // HandleGroupRatio checks for "auto_group" in the context and updates the group ratio and relayInfo.UsingGroup if present
  13. func HandleGroupRatio(ctx *gin.Context, relayInfo *relaycommon.RelayInfo) types.GroupRatioInfo {
  14. groupRatioInfo := types.GroupRatioInfo{
  15. GroupRatio: 1.0, // default ratio
  16. GroupSpecialRatio: -1,
  17. }
  18. // check auto group
  19. autoGroup, exists := ctx.Get("auto_group")
  20. if exists {
  21. logger.LogDebug(ctx, fmt.Sprintf("final group: %s", autoGroup))
  22. relayInfo.UsingGroup = autoGroup.(string)
  23. }
  24. // check user group special ratio
  25. userGroupRatio, ok := ratio_setting.GetGroupGroupRatio(relayInfo.UserGroup, relayInfo.UsingGroup)
  26. if ok {
  27. // user group special ratio
  28. groupRatioInfo.GroupSpecialRatio = userGroupRatio
  29. groupRatioInfo.GroupRatio = userGroupRatio
  30. groupRatioInfo.HasSpecialRatio = true
  31. } else {
  32. // normal group ratio
  33. groupRatioInfo.GroupRatio = ratio_setting.GetGroupRatio(relayInfo.UsingGroup)
  34. }
  35. return groupRatioInfo
  36. }
  37. func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens int, meta *types.TokenCountMeta) (types.PriceData, error) {
  38. modelPrice, usePrice := ratio_setting.GetModelPrice(info.OriginModelName, false)
  39. groupRatioInfo := HandleGroupRatio(c, info)
  40. var preConsumedQuota int
  41. var modelRatio float64
  42. var completionRatio float64
  43. var cacheRatio float64
  44. var imageRatio float64
  45. var cacheCreationRatio float64
  46. var audioRatio float64
  47. var audioCompletionRatio float64
  48. var freeModel bool
  49. if !usePrice {
  50. preConsumedTokens := common.Max(promptTokens, common.PreConsumedQuota)
  51. if meta.MaxTokens != 0 {
  52. preConsumedTokens += meta.MaxTokens
  53. }
  54. var success bool
  55. var matchName string
  56. modelRatio, success, matchName = ratio_setting.GetModelRatio(info.OriginModelName)
  57. if !success {
  58. acceptUnsetRatio := false
  59. if info.UserSetting.AcceptUnsetRatioModel {
  60. acceptUnsetRatio = true
  61. }
  62. if !acceptUnsetRatio {
  63. return types.PriceData{}, fmt.Errorf("模型 %s 倍率或价格未配置,请联系管理员设置或开始自用模式;Model %s ratio or price not set, please set or start self-use mode", matchName, matchName)
  64. }
  65. }
  66. completionRatio = ratio_setting.GetCompletionRatio(info.OriginModelName)
  67. cacheRatio, _ = ratio_setting.GetCacheRatio(info.OriginModelName)
  68. cacheCreationRatio, _ = ratio_setting.GetCreateCacheRatio(info.OriginModelName)
  69. imageRatio, _ = ratio_setting.GetImageRatio(info.OriginModelName)
  70. audioRatio = ratio_setting.GetAudioRatio(info.OriginModelName)
  71. audioCompletionRatio = ratio_setting.GetAudioCompletionRatio(info.OriginModelName)
  72. ratio := modelRatio * groupRatioInfo.GroupRatio
  73. preConsumedQuota = int(float64(preConsumedTokens) * ratio)
  74. } else {
  75. if meta.ImagePriceRatio != 0 {
  76. modelPrice = modelPrice * meta.ImagePriceRatio
  77. }
  78. preConsumedQuota = int(modelPrice * common.QuotaPerUnit * groupRatioInfo.GroupRatio)
  79. }
  80. // check if free model pre-consume is disabled
  81. if !operation_setting.GetQuotaSetting().EnableFreeModelPreConsume {
  82. // if model price or ratio is 0, do not pre-consume quota
  83. if usePrice {
  84. if modelPrice == 0 {
  85. preConsumedQuota = 0
  86. freeModel = true
  87. }
  88. } else {
  89. if modelRatio == 0 {
  90. preConsumedQuota = 0
  91. freeModel = true
  92. }
  93. }
  94. }
  95. priceData := types.PriceData{
  96. FreeModel: freeModel,
  97. ModelPrice: modelPrice,
  98. ModelRatio: modelRatio,
  99. CompletionRatio: completionRatio,
  100. GroupRatioInfo: groupRatioInfo,
  101. UsePrice: usePrice,
  102. CacheRatio: cacheRatio,
  103. ImageRatio: imageRatio,
  104. AudioRatio: audioRatio,
  105. AudioCompletionRatio: audioCompletionRatio,
  106. CacheCreationRatio: cacheCreationRatio,
  107. QuotaToPreConsume: preConsumedQuota,
  108. }
  109. if common.DebugEnabled {
  110. println(fmt.Sprintf("model_price_helper result: %s", priceData.ToSetting()))
  111. }
  112. info.PriceData = priceData
  113. return priceData, nil
  114. }
  115. // ModelPriceHelperPerCall 按次计费的 PriceHelper (MJ、Task)
  116. func ModelPriceHelperPerCall(c *gin.Context, info *relaycommon.RelayInfo) types.PerCallPriceData {
  117. groupRatioInfo := HandleGroupRatio(c, info)
  118. modelPrice, success := ratio_setting.GetModelPrice(info.OriginModelName, true)
  119. // 如果没有配置价格,则使用默认价格
  120. if !success {
  121. defaultPrice, ok := ratio_setting.GetDefaultModelPriceMap()[info.OriginModelName]
  122. if !ok {
  123. modelPrice = 0.1
  124. } else {
  125. modelPrice = defaultPrice
  126. }
  127. }
  128. quota := int(modelPrice * common.QuotaPerUnit * groupRatioInfo.GroupRatio)
  129. priceData := types.PerCallPriceData{
  130. ModelPrice: modelPrice,
  131. Quota: quota,
  132. GroupRatioInfo: groupRatioInfo,
  133. }
  134. return priceData
  135. }
  136. func ContainPriceOrRatio(modelName string) bool {
  137. _, ok := ratio_setting.GetModelPrice(modelName, false)
  138. if ok {
  139. return true
  140. }
  141. _, ok, _ = ratio_setting.GetModelRatio(modelName)
  142. if ok {
  143. return true
  144. }
  145. return false
  146. }