Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

200 lignes
6.2 KiB

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