Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

473 wiersze
13 KiB

  1. package model
  2. import (
  3. "fmt"
  4. "sort"
  5. "strings"
  6. "sync"
  7. "time"
  8. "github.com/QuantumNous/new-api/common"
  9. "github.com/QuantumNous/new-api/constant"
  10. "github.com/QuantumNous/new-api/setting/ratio_setting"
  11. "github.com/QuantumNous/new-api/types"
  12. )
  13. type Pricing struct {
  14. ModelName string `json:"model_name"`
  15. Description string `json:"description,omitempty"`
  16. Icon string `json:"icon,omitempty"`
  17. Tags string `json:"tags,omitempty"`
  18. VendorID int `json:"vendor_id,omitempty"`
  19. QuotaType int `json:"quota_type"`
  20. ModelRatio float64 `json:"model_ratio"`
  21. ModelPrice float64 `json:"model_price"`
  22. OwnerBy string `json:"owner_by"`
  23. CompletionRatio float64 `json:"completion_ratio"`
  24. CacheRatio float64 `json:"cache_ratio"`
  25. CacheCreationRatio float64 `json:"cache_creation_ratio"`
  26. EnableGroup []string `json:"enable_groups"`
  27. SupportedEndpointTypes []constant.EndpointType `json:"supported_endpoint_types"`
  28. PricingVersion string `json:"pricing_version,omitempty"`
  29. Type int `json:"type"`
  30. PricingConfig *types.PricingConfig `json:"pricing_config,omitempty"`
  31. DisplayPricing []types.ModelDisplayPricingItem `json:"display_pricing,omitempty"`
  32. }
  33. type PricingVendor struct {
  34. ID int `json:"id"`
  35. Name string `json:"name"`
  36. Description string `json:"description,omitempty"`
  37. Icon string `json:"icon,omitempty"`
  38. }
  39. const (
  40. QuotaTypeByTokens = 0
  41. QuotaTypeByCall = 1
  42. )
  43. var (
  44. pricingMap []Pricing
  45. pricingByModel map[string]*Pricing
  46. vendorsList []PricingVendor
  47. supportedEndpointMap map[string]common.EndpointInfo
  48. lastGetPricingTime time.Time
  49. updatePricingLock sync.Mutex
  50. modelEnableGroups = make(map[string][]string)
  51. modelQuotaTypeMap = make(map[string]int)
  52. modelEnableGroupsLock = sync.RWMutex{}
  53. )
  54. var (
  55. modelSupportEndpointTypes = make(map[string][]constant.EndpointType)
  56. modelSupportEndpointsLock = sync.RWMutex{}
  57. )
  58. func SetTestPricing(pricing []Pricing) {
  59. updatePricingLock.Lock()
  60. defer updatePricingLock.Unlock()
  61. pricingMap = pricing
  62. idx := make(map[string]*Pricing, len(pricing))
  63. for i := range pricing {
  64. idx[pricing[i].ModelName] = &pricingMap[i]
  65. }
  66. pricingByModel = idx
  67. lastGetPricingTime = time.Now()
  68. }
  69. func GetPricing() []Pricing {
  70. if time.Since(lastGetPricingTime) > time.Minute || len(pricingMap) == 0 {
  71. updatePricingLock.Lock()
  72. defer updatePricingLock.Unlock()
  73. if time.Since(lastGetPricingTime) > time.Minute || len(pricingMap) == 0 {
  74. modelSupportEndpointsLock.Lock()
  75. defer modelSupportEndpointsLock.Unlock()
  76. updatePricing()
  77. }
  78. }
  79. return pricingMap
  80. }
  81. func GetPricingByModel(modelName string) *Pricing {
  82. GetPricing()
  83. modelEnableGroupsLock.RLock()
  84. p := pricingByModel[modelName]
  85. modelEnableGroupsLock.RUnlock()
  86. return p
  87. }
  88. func GetVendors() []PricingVendor {
  89. if time.Since(lastGetPricingTime) > time.Minute || len(pricingMap) == 0 {
  90. GetPricing()
  91. }
  92. return vendorsList
  93. }
  94. func GetModelSupportEndpointTypes(model string) []constant.EndpointType {
  95. if model == "" {
  96. return make([]constant.EndpointType, 0)
  97. }
  98. modelSupportEndpointsLock.RLock()
  99. defer modelSupportEndpointsLock.RUnlock()
  100. if endpoints, ok := modelSupportEndpointTypes[model]; ok {
  101. return endpoints
  102. }
  103. return make([]constant.EndpointType, 0)
  104. }
  105. func parseModelEndpointTypes(rawValue string) []string {
  106. trimmed := strings.TrimSpace(rawValue)
  107. if trimmed == "" {
  108. return nil
  109. }
  110. var rawObject map[string]interface{}
  111. if err := common.Unmarshal([]byte(trimmed), &rawObject); err == nil {
  112. endpoints := make([]string, 0, len(rawObject))
  113. for k, v := range rawObject {
  114. switch v.(type) {
  115. case string, map[string]interface{}:
  116. if !common.StringsContains(endpoints, k) {
  117. endpoints = append(endpoints, k)
  118. }
  119. }
  120. }
  121. if len(endpoints) == 0 {
  122. return nil
  123. }
  124. return endpoints
  125. }
  126. var rawList []string
  127. if err := common.Unmarshal([]byte(trimmed), &rawList); err == nil {
  128. endpoints := make([]string, 0, len(rawList))
  129. for _, endpoint := range rawList {
  130. endpoint = strings.TrimSpace(endpoint)
  131. if endpoint == "" || common.StringsContains(endpoints, endpoint) {
  132. continue
  133. }
  134. endpoints = append(endpoints, endpoint)
  135. }
  136. if len(endpoints) == 0 {
  137. return nil
  138. }
  139. return endpoints
  140. }
  141. return nil
  142. }
  143. func updatePricing() {
  144. enableAbilities, err := GetAllEnableAbilityWithChannels()
  145. if err != nil {
  146. common.SysLog(fmt.Sprintf("GetAllEnableAbilityWithChannels error: %v", err))
  147. return
  148. }
  149. var allMeta []Model
  150. _ = DB.Find(&allMeta).Error
  151. metaMap := make(map[string]*Model)
  152. prefixList := make([]*Model, 0)
  153. suffixList := make([]*Model, 0)
  154. containsList := make([]*Model, 0)
  155. for i := range allMeta {
  156. m := &allMeta[i]
  157. if m.NameRule == NameRuleExact {
  158. metaMap[m.ModelName] = m
  159. continue
  160. }
  161. switch m.NameRule {
  162. case NameRulePrefix:
  163. prefixList = append(prefixList, m)
  164. case NameRuleSuffix:
  165. suffixList = append(suffixList, m)
  166. case NameRuleContains:
  167. containsList = append(containsList, m)
  168. }
  169. }
  170. for _, m := range prefixList {
  171. for _, ability := range enableAbilities {
  172. if strings.HasPrefix(ability.Model, m.ModelName) {
  173. if _, exists := metaMap[ability.Model]; !exists {
  174. metaMap[ability.Model] = m
  175. }
  176. }
  177. }
  178. }
  179. for _, m := range suffixList {
  180. for _, ability := range enableAbilities {
  181. if strings.HasSuffix(ability.Model, m.ModelName) {
  182. if _, exists := metaMap[ability.Model]; !exists {
  183. metaMap[ability.Model] = m
  184. }
  185. }
  186. }
  187. }
  188. for _, m := range containsList {
  189. for _, ability := range enableAbilities {
  190. if strings.Contains(ability.Model, m.ModelName) {
  191. if _, exists := metaMap[ability.Model]; !exists {
  192. metaMap[ability.Model] = m
  193. }
  194. }
  195. }
  196. }
  197. var vendors []Vendor
  198. _ = DB.Find(&vendors).Error
  199. vendorMap := make(map[int]*Vendor, len(vendors))
  200. for i := range vendors {
  201. vendorMap[vendors[i].Id] = &vendors[i]
  202. }
  203. initDefaultVendorMapping(metaMap, vendorMap, enableAbilities)
  204. vendorOrderMap := make(map[int]int, len(vendorMap))
  205. for _, v := range vendorMap {
  206. vendorOrderMap[v.Id] = v.SortOrder
  207. }
  208. vendorsList = make([]PricingVendor, 0, len(vendorMap))
  209. for _, v := range vendorMap {
  210. vendorsList = append(vendorsList, PricingVendor{
  211. ID: v.Id,
  212. Name: v.Name,
  213. Description: v.Description,
  214. Icon: v.Icon,
  215. })
  216. }
  217. sort.Slice(vendorsList, func(i, j int) bool {
  218. oi := vendorOrderMap[vendorsList[i].ID]
  219. oj := vendorOrderMap[vendorsList[j].ID]
  220. if oi != oj {
  221. return oi < oj
  222. }
  223. return vendorsList[i].ID < vendorsList[j].ID
  224. })
  225. modelGroupsMap := make(map[string]*types.Set[string])
  226. for _, ability := range enableAbilities {
  227. groups, ok := modelGroupsMap[ability.Model]
  228. if !ok {
  229. groups = types.NewSet[string]()
  230. modelGroupsMap[ability.Model] = groups
  231. }
  232. groups.Add(ability.Group)
  233. }
  234. modelSupportEndpointsStr := make(map[string][]string)
  235. for _, ability := range enableAbilities {
  236. endpoints := modelSupportEndpointsStr[ability.Model]
  237. channelTypes := common.GetEndpointTypesByChannelType(ability.ChannelType, ability.Model)
  238. for _, channelType := range channelTypes {
  239. if !common.StringsContains(endpoints, string(channelType)) {
  240. endpoints = append(endpoints, string(channelType))
  241. }
  242. }
  243. modelSupportEndpointsStr[ability.Model] = endpoints
  244. }
  245. for modelName, meta := range metaMap {
  246. if strings.TrimSpace(meta.Endpoints) == "" {
  247. continue
  248. }
  249. if endpoints := parseModelEndpointTypes(meta.Endpoints); len(endpoints) > 0 {
  250. modelSupportEndpointsStr[modelName] = endpoints
  251. }
  252. }
  253. modelSupportEndpointTypes = make(map[string][]constant.EndpointType)
  254. for model, endpoints := range modelSupportEndpointsStr {
  255. supportedEndpoints := make([]constant.EndpointType, 0, len(endpoints))
  256. for _, endpointStr := range endpoints {
  257. supportedEndpoints = append(supportedEndpoints, constant.EndpointType(endpointStr))
  258. }
  259. modelSupportEndpointTypes[model] = supportedEndpoints
  260. }
  261. supportedEndpointMap = make(map[string]common.EndpointInfo)
  262. for _, endpoints := range modelSupportEndpointTypes {
  263. for _, et := range endpoints {
  264. if info, ok := common.GetDefaultEndpointInfo(et); ok {
  265. if _, exists := supportedEndpointMap[string(et)]; !exists {
  266. supportedEndpointMap[string(et)] = info
  267. }
  268. }
  269. }
  270. }
  271. for _, meta := range metaMap {
  272. if strings.TrimSpace(meta.Endpoints) == "" {
  273. continue
  274. }
  275. var raw map[string]interface{}
  276. if err := common.Unmarshal([]byte(meta.Endpoints), &raw); err == nil {
  277. for k, v := range raw {
  278. switch val := v.(type) {
  279. case string:
  280. supportedEndpointMap[k] = common.EndpointInfo{Path: val, Method: "POST"}
  281. case map[string]interface{}:
  282. ep := common.EndpointInfo{Method: "POST"}
  283. if p, ok := val["path"].(string); ok {
  284. ep.Path = p
  285. }
  286. if m, ok := val["method"].(string); ok {
  287. ep.Method = strings.ToUpper(m)
  288. }
  289. supportedEndpointMap[k] = ep
  290. }
  291. }
  292. }
  293. }
  294. pricingMap = make([]Pricing, 0, len(modelGroupsMap))
  295. for model, groups := range modelGroupsMap {
  296. pricing := Pricing{
  297. ModelName: model,
  298. EnableGroup: groups.Items(),
  299. SupportedEndpointTypes: modelSupportEndpointTypes[model],
  300. }
  301. if meta, ok := metaMap[model]; ok {
  302. if meta.Status == 0 {
  303. continue
  304. }
  305. pricing.Description = meta.Description
  306. pricing.Icon = meta.Icon
  307. pricing.Tags = meta.Tags
  308. pricing.VendorID = meta.VendorID
  309. pricing.Type = meta.Type
  310. }
  311. applyGlobalDefault(&pricing, model)
  312. applyDisplayPricing(&pricing, model)
  313. pricingMap = append(pricingMap, pricing)
  314. }
  315. sort.Slice(pricingMap, func(i, j int) bool {
  316. mi, okI := metaMap[pricingMap[i].ModelName]
  317. mj, okJ := metaMap[pricingMap[j].ModelName]
  318. si := 999999
  319. sj := 999999
  320. if okI {
  321. si = mi.SortOrder
  322. }
  323. if okJ {
  324. sj = mj.SortOrder
  325. }
  326. if si != sj {
  327. return si < sj
  328. }
  329. return pricingMap[i].ModelName < pricingMap[j].ModelName
  330. })
  331. if len(pricingMap) > 0 {
  332. pricingMap[0].PricingVersion = "82c4a357505fff6fee8462c3f7ec8a645bb95532669cb73b2cabee6a416ec24f"
  333. }
  334. modelEnableGroupsLock.Lock()
  335. modelEnableGroups = make(map[string][]string)
  336. modelQuotaTypeMap = make(map[string]int)
  337. byModel := make(map[string]*Pricing, len(pricingMap))
  338. for i := range pricingMap {
  339. p := &pricingMap[i]
  340. modelEnableGroups[p.ModelName] = p.EnableGroup
  341. modelQuotaTypeMap[p.ModelName] = p.QuotaType
  342. byModel[p.ModelName] = p
  343. }
  344. pricingByModel = byModel
  345. modelEnableGroupsLock.Unlock()
  346. lastGetPricingTime = time.Now()
  347. }
  348. func GetSupportedEndpointMap() map[string]common.EndpointInfo {
  349. return supportedEndpointMap
  350. }
  351. func applyGlobalDefault(pricing *Pricing, model string) {
  352. if applyMatrixPricingConfig(pricing, model) {
  353. return
  354. }
  355. modelPrice, findPrice := ratio_setting.GetModelPrice(model, false)
  356. if findPrice {
  357. pricing.ModelPrice = modelPrice
  358. pricing.ModelRatio = 0
  359. pricing.CompletionRatio = 0
  360. pricing.QuotaType = QuotaTypeByCall
  361. } else {
  362. modelRatio, _, _ := ratio_setting.GetModelRatio(model)
  363. pricing.ModelPrice = 0
  364. pricing.ModelRatio = modelRatio
  365. pricing.CompletionRatio = ratio_setting.GetCompletionRatio(model)
  366. pricing.QuotaType = QuotaTypeByTokens
  367. }
  368. pricing.CacheRatio, _ = ratio_setting.GetCacheRatio(model)
  369. pricing.CacheCreationRatio, _ = ratio_setting.GetCreateCacheRatio(model)
  370. }
  371. func applyMatrixPricingConfig(pricing *Pricing, model string) bool {
  372. cfg := ratio_setting.GetPricingConfig(model)
  373. if cfg == nil {
  374. return false
  375. }
  376. pricing.PricingConfig = cfg
  377. minPrice := minPricingConfigPrice(cfg)
  378. if cfg.BillingUnit == types.BillingUnitPer1MTokens {
  379. pricing.ModelPrice = minPrice
  380. pricing.ModelRatio = 0
  381. pricing.CompletionRatio = 0
  382. pricing.QuotaType = QuotaTypeByTokens
  383. return true
  384. }
  385. pricing.ModelPrice = minPrice
  386. pricing.ModelRatio = 0
  387. pricing.CompletionRatio = 0
  388. pricing.QuotaType = QuotaTypeByCall
  389. return true
  390. }
  391. func applyDisplayPricing(pricing *Pricing, model string) {
  392. items := ratio_setting.GetModelDisplayPricing(model)
  393. if len(items) > 0 {
  394. pricing.DisplayPricing = items
  395. }
  396. }
  397. func minPricingConfigPrice(cfg *types.PricingConfig) float64 {
  398. if cfg == nil || len(cfg.Table) == 0 {
  399. return 0
  400. }
  401. var min float64
  402. found := false
  403. for _, row := range cfg.Table {
  404. price, ok := pricingRowNumber(row["price"])
  405. if !ok {
  406. continue
  407. }
  408. if !found || price < min {
  409. min = price
  410. found = true
  411. }
  412. }
  413. return min
  414. }
  415. func pricingRowNumber(v any) (float64, bool) {
  416. switch n := v.(type) {
  417. case float64:
  418. return n, true
  419. case float32:
  420. return float64(n), true
  421. case int:
  422. return float64(n), true
  423. case int64:
  424. return float64(n), true
  425. case int32:
  426. return float64(n), true
  427. default:
  428. return 0, false
  429. }
  430. }