feat: channel affinity (#2669)

* feat: channel affinity

* feat: channel affinity -> model setting

* fix: channel affinity

* feat: channel affinity op

* feat: channel_type setting

* feat: clean

* feat: cache supports both memory and Redis.

* feat: Optimise ui/ux

* feat: Optimise ui/ux

* feat: Optimise codex usage ui/ux

* feat: Optimise ui/ux

* feat: Optimise ui/ux

* feat: Optimise ui/ux

* feat: If the affinitized channel fails and a retry succeeds on another channel, update the affinity to the successful channel
This commit is contained in:
Seefs
2026-01-26 19:57:41 +08:00
committed by GitHub
parent 9ac94f036c
commit d9321b7da3
24 changed files with 2542 additions and 125 deletions

71
model/channel_satisfy.go Normal file
View File

@@ -0,0 +1,71 @@
package model
import (
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/setting/ratio_setting"
)
func IsChannelEnabledForGroupModel(group string, modelName string, channelID int) bool {
if group == "" || modelName == "" || channelID <= 0 {
return false
}
if !common.MemoryCacheEnabled {
return isChannelEnabledForGroupModelDB(group, modelName, channelID)
}
channelSyncLock.RLock()
defer channelSyncLock.RUnlock()
if group2model2channels == nil {
return false
}
if isChannelIDInList(group2model2channels[group][modelName], channelID) {
return true
}
normalized := ratio_setting.FormatMatchingModelName(modelName)
if normalized != "" && normalized != modelName {
return isChannelIDInList(group2model2channels[group][normalized], channelID)
}
return false
}
func IsChannelEnabledForAnyGroupModel(groups []string, modelName string, channelID int) bool {
if len(groups) == 0 {
return false
}
for _, g := range groups {
if IsChannelEnabledForGroupModel(g, modelName, channelID) {
return true
}
}
return false
}
func isChannelEnabledForGroupModelDB(group string, modelName string, channelID int) bool {
var count int64
err := DB.Model(&Ability{}).
Where(commonGroupCol+" = ? and model = ? and channel_id = ? and enabled = ?", group, modelName, channelID, true).
Count(&count).Error
if err == nil && count > 0 {
return true
}
normalized := ratio_setting.FormatMatchingModelName(modelName)
if normalized == "" || normalized == modelName {
return false
}
count = 0
err = DB.Model(&Ability{}).
Where(commonGroupCol+" = ? and model = ? and channel_id = ? and enabled = ?", group, normalized, channelID, true).
Count(&count).Error
return err == nil && count > 0
}
func isChannelIDInList(list []int, channelID int) bool {
for _, id := range list {
if id == channelID {
return true
}
}
return false
}