Merge remote-tracking branch 'origin/main' into ui/refactor
This commit is contained in:
@@ -14,6 +14,7 @@ type ImageRequest struct {
|
|||||||
ExtraFields json.RawMessage `json:"extra_fields,omitempty"`
|
ExtraFields json.RawMessage `json:"extra_fields,omitempty"`
|
||||||
Background string `json:"background,omitempty"`
|
Background string `json:"background,omitempty"`
|
||||||
Moderation string `json:"moderation,omitempty"`
|
Moderation string `json:"moderation,omitempty"`
|
||||||
|
OutputFormat string `json:"output_format,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImageResponse struct {
|
type ImageResponse struct {
|
||||||
|
|||||||
19
main.go
19
main.go
@@ -89,9 +89,22 @@ func main() {
|
|||||||
if common.MemoryCacheEnabled {
|
if common.MemoryCacheEnabled {
|
||||||
common.SysLog("memory cache enabled")
|
common.SysLog("memory cache enabled")
|
||||||
common.SysError(fmt.Sprintf("sync frequency: %d seconds", common.SyncFrequency))
|
common.SysError(fmt.Sprintf("sync frequency: %d seconds", common.SyncFrequency))
|
||||||
model.InitChannelCache()
|
|
||||||
}
|
// Add panic recovery and retry for InitChannelCache
|
||||||
if common.MemoryCacheEnabled {
|
func() {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
common.SysError(fmt.Sprintf("InitChannelCache panic: %v, retrying once", r))
|
||||||
|
// Retry once
|
||||||
|
_, fixErr := model.FixAbility()
|
||||||
|
if fixErr != nil {
|
||||||
|
common.SysError(fmt.Sprintf("InitChannelCache failed: %s", fixErr.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
model.InitChannelCache()
|
||||||
|
}()
|
||||||
|
|
||||||
go model.SyncOptions(common.SyncFrequency)
|
go model.SyncOptions(common.SyncFrequency)
|
||||||
go model.SyncChannelCache(common.SyncFrequency)
|
go model.SyncChannelCache(common.SyncFrequency)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func getPriority(group string, model string, retry int) (int, error) {
|
|||||||
err := DB.Model(&Ability{}).
|
err := DB.Model(&Ability{}).
|
||||||
Select("DISTINCT(priority)").
|
Select("DISTINCT(priority)").
|
||||||
Where(groupCol+" = ? and model = ? and enabled = "+trueVal, group, model).
|
Where(groupCol+" = ? and model = ? and enabled = "+trueVal, group, model).
|
||||||
Order("priority DESC"). // 按优先级降序排序
|
Order("priority DESC"). // 按优先级降序排序
|
||||||
Pluck("priority", &priorities).Error // Pluck用于将查询的结果直接扫描到一个切片中
|
Pluck("priority", &priorities).Error // Pluck用于将查询的结果直接扫描到一个切片中
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -261,12 +261,28 @@ func FixAbility() (int, error) {
|
|||||||
common.SysError(fmt.Sprintf("Get channel ids from channel table failed: %s", err.Error()))
|
common.SysError(fmt.Sprintf("Get channel ids from channel table failed: %s", err.Error()))
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
// Delete abilities of channels that are not in channel table
|
|
||||||
err = DB.Where("channel_id NOT IN (?)", channelIds).Delete(&Ability{}).Error
|
// Delete abilities of channels that are not in channel table - in batches to avoid too many placeholders
|
||||||
if err != nil {
|
if len(channelIds) > 0 {
|
||||||
common.SysError(fmt.Sprintf("Delete abilities of channels that are not in channel table failed: %s", err.Error()))
|
// Process deletion in chunks to avoid "too many placeholders" error
|
||||||
return 0, err
|
for _, chunk := range lo.Chunk(channelIds, 100) {
|
||||||
|
err = DB.Where("channel_id NOT IN (?)", chunk).Delete(&Ability{}).Error
|
||||||
|
if err != nil {
|
||||||
|
common.SysError(fmt.Sprintf("Delete abilities of channels (batch) that are not in channel table failed: %s", err.Error()))
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If no channels exist, delete all abilities
|
||||||
|
err = DB.Delete(&Ability{}).Error
|
||||||
|
if err != nil {
|
||||||
|
common.SysError(fmt.Sprintf("Delete all abilities failed: %s", err.Error()))
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
common.SysLog("Delete all abilities successfully")
|
||||||
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
common.SysLog(fmt.Sprintf("Delete abilities of channels that are not in channel table successfully, ids: %v", channelIds))
|
common.SysLog(fmt.Sprintf("Delete abilities of channels that are not in channel table successfully, ids: %v", channelIds))
|
||||||
count += len(channelIds)
|
count += len(channelIds)
|
||||||
|
|
||||||
@@ -275,17 +291,26 @@ func FixAbility() (int, error) {
|
|||||||
err = DB.Table("abilities").Distinct("channel_id").Pluck("channel_id", &abilityChannelIds).Error
|
err = DB.Table("abilities").Distinct("channel_id").Pluck("channel_id", &abilityChannelIds).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.SysError(fmt.Sprintf("Get channel ids from abilities table failed: %s", err.Error()))
|
common.SysError(fmt.Sprintf("Get channel ids from abilities table failed: %s", err.Error()))
|
||||||
return 0, err
|
return count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var channels []Channel
|
var channels []Channel
|
||||||
if len(abilityChannelIds) == 0 {
|
if len(abilityChannelIds) == 0 {
|
||||||
err = DB.Find(&channels).Error
|
err = DB.Find(&channels).Error
|
||||||
} else {
|
} else {
|
||||||
err = DB.Where("id NOT IN (?)", abilityChannelIds).Find(&channels).Error
|
// Process query in chunks to avoid "too many placeholders" error
|
||||||
}
|
err = nil
|
||||||
if err != nil {
|
for _, chunk := range lo.Chunk(abilityChannelIds, 100) {
|
||||||
return 0, err
|
var channelsChunk []Channel
|
||||||
|
err = DB.Where("id NOT IN (?)", chunk).Find(&channelsChunk).Error
|
||||||
|
if err != nil {
|
||||||
|
common.SysError(fmt.Sprintf("Find channels not in abilities table failed: %s", err.Error()))
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
channels = append(channels, channelsChunk...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, channel := range channels {
|
for _, channel := range channels {
|
||||||
err := channel.UpdateAbilities(nil)
|
err := channel.UpdateAbilities(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ var channelsIDM map[int]*Channel
|
|||||||
var channelSyncLock sync.RWMutex
|
var channelSyncLock sync.RWMutex
|
||||||
|
|
||||||
func InitChannelCache() {
|
func InitChannelCache() {
|
||||||
|
if !common.MemoryCacheEnabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
newChannelId2channel := make(map[int]*Channel)
|
newChannelId2channel := make(map[int]*Channel)
|
||||||
var channels []*Channel
|
var channels []*Channel
|
||||||
DB.Where("status = ?", common.ChannelStatusEnabled).Find(&channels)
|
DB.Where("status = ?", common.ChannelStatusEnabled).Find(&channels)
|
||||||
|
|||||||
@@ -46,6 +46,17 @@ func (channel *Channel) GetModels() []string {
|
|||||||
return strings.Split(strings.Trim(channel.Models, ","), ",")
|
return strings.Split(strings.Trim(channel.Models, ","), ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) GetGroups() []string {
|
||||||
|
if channel.Group == "" {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
groups := strings.Split(strings.Trim(channel.Group, ","), ",")
|
||||||
|
for i, group := range groups {
|
||||||
|
groups[i] = strings.TrimSpace(group)
|
||||||
|
}
|
||||||
|
return groups
|
||||||
|
}
|
||||||
|
|
||||||
func (channel *Channel) GetOtherInfo() map[string]interface{} {
|
func (channel *Channel) GetOtherInfo() map[string]interface{} {
|
||||||
otherInfo := make(map[string]interface{})
|
otherInfo := make(map[string]interface{})
|
||||||
if channel.OtherInfo != "" {
|
if channel.OtherInfo != "" {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ var awsModelIDMap = map[string]string{
|
|||||||
"claude-3-5-sonnet-20241022": "anthropic.claude-3-5-sonnet-20241022-v2:0",
|
"claude-3-5-sonnet-20241022": "anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||||||
"claude-3-5-haiku-20241022": "anthropic.claude-3-5-haiku-20241022-v1:0",
|
"claude-3-5-haiku-20241022": "anthropic.claude-3-5-haiku-20241022-v1:0",
|
||||||
"claude-3-7-sonnet-20250219": "anthropic.claude-3-7-sonnet-20250219-v1:0",
|
"claude-3-7-sonnet-20250219": "anthropic.claude-3-7-sonnet-20250219-v1:0",
|
||||||
|
"claude-sonnet-4-20250514": "anthropic.claude-sonnet-4-20250514-v1:0",
|
||||||
|
"claude-opus-4-20250514": "anthropic.claude-opus-4-20250514-v1:0",
|
||||||
}
|
}
|
||||||
|
|
||||||
var awsModelCanCrossRegionMap = map[string]map[string]bool{
|
var awsModelCanCrossRegionMap = map[string]map[string]bool{
|
||||||
@@ -41,6 +43,16 @@ var awsModelCanCrossRegionMap = map[string]map[string]bool{
|
|||||||
},
|
},
|
||||||
"anthropic.claude-3-7-sonnet-20250219-v1:0": {
|
"anthropic.claude-3-7-sonnet-20250219-v1:0": {
|
||||||
"us": true,
|
"us": true,
|
||||||
|
"ap": true,
|
||||||
|
"eu": true,
|
||||||
|
},
|
||||||
|
"apac.anthropic.claude-sonnet-4-20250514-v1:0": {
|
||||||
|
"us": true,
|
||||||
|
"ap": true,
|
||||||
|
"eu": true,
|
||||||
|
},
|
||||||
|
"anthropic.claude-opus-4-20250514-v1:0": {
|
||||||
|
"us": true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ func (a *Adaptor) ConvertImageRequest(c *gin.Context, info *relaycommon.RelayInf
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Adaptor) Init(info *relaycommon.RelayInfo) {
|
func (a *Adaptor) Init(info *relaycommon.RelayInfo) {
|
||||||
if strings.HasPrefix(info.UpstreamModelName, "claude-3") {
|
if strings.HasPrefix(info.UpstreamModelName, "claude-2") || strings.HasPrefix(info.UpstreamModelName, "claude-instant") {
|
||||||
a.RequestMode = RequestModeMessage
|
|
||||||
} else {
|
|
||||||
a.RequestMode = RequestModeCompletion
|
a.RequestMode = RequestModeCompletion
|
||||||
|
} else {
|
||||||
|
a.RequestMode = RequestModeMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ var ModelList = []string{
|
|||||||
"claude-3-5-sonnet-20241022",
|
"claude-3-5-sonnet-20241022",
|
||||||
"claude-3-7-sonnet-20250219",
|
"claude-3-7-sonnet-20250219",
|
||||||
"claude-3-7-sonnet-20250219-thinking",
|
"claude-3-7-sonnet-20250219-thinking",
|
||||||
|
"claude-sonnet-4-20250514",
|
||||||
|
"claude-sonnet-4-20250514-thinking",
|
||||||
|
"claude-opus-4-20250514",
|
||||||
|
"claude-opus-4-20250514-thinking",
|
||||||
}
|
}
|
||||||
|
|
||||||
var ChannelName = "claude"
|
var ChannelName = "claude"
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package gemini
|
|||||||
|
|
||||||
type GeminiChatRequest struct {
|
type GeminiChatRequest struct {
|
||||||
Contents []GeminiChatContent `json:"contents"`
|
Contents []GeminiChatContent `json:"contents"`
|
||||||
SafetySettings []GeminiChatSafetySettings `json:"safety_settings,omitempty"`
|
SafetySettings []GeminiChatSafetySettings `json:"safetySettings,omitempty"`
|
||||||
GenerationConfig GeminiChatGenerationConfig `json:"generation_config,omitempty"`
|
GenerationConfig GeminiChatGenerationConfig `json:"generationConfig,omitempty"`
|
||||||
Tools []GeminiChatTool `json:"tools,omitempty"`
|
Tools []GeminiChatTool `json:"tools,omitempty"`
|
||||||
SystemInstructions *GeminiChatContent `json:"system_instruction,omitempty"`
|
SystemInstructions *GeminiChatContent `json:"systemInstruction,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GeminiThinkingConfig struct {
|
type GeminiThinkingConfig struct {
|
||||||
@@ -54,6 +54,7 @@ type GeminiFileData struct {
|
|||||||
|
|
||||||
type GeminiPart struct {
|
type GeminiPart struct {
|
||||||
Text string `json:"text,omitempty"`
|
Text string `json:"text,omitempty"`
|
||||||
|
Thought bool `json:"thought,omitempty"`
|
||||||
InlineData *GeminiInlineData `json:"inlineData,omitempty"`
|
InlineData *GeminiInlineData `json:"inlineData,omitempty"`
|
||||||
FunctionCall *FunctionCall `json:"functionCall,omitempty"`
|
FunctionCall *FunctionCall `json:"functionCall,omitempty"`
|
||||||
FunctionResponse *FunctionResponse `json:"functionResponse,omitempty"`
|
FunctionResponse *FunctionResponse `json:"functionResponse,omitempty"`
|
||||||
|
|||||||
@@ -539,6 +539,8 @@ func responseGeminiChat2OpenAI(response *GeminiChatResponse) *dto.OpenAITextResp
|
|||||||
if call := getResponseToolCall(&part); call != nil {
|
if call := getResponseToolCall(&part); call != nil {
|
||||||
toolCalls = append(toolCalls, *call)
|
toolCalls = append(toolCalls, *call)
|
||||||
}
|
}
|
||||||
|
} else if part.Thought {
|
||||||
|
choice.Message.ReasoningContent = part.Text
|
||||||
} else {
|
} else {
|
||||||
if part.ExecutableCode != nil {
|
if part.ExecutableCode != nil {
|
||||||
texts = append(texts, "```"+part.ExecutableCode.Language+"\n"+part.ExecutableCode.Code+"\n```")
|
texts = append(texts, "```"+part.ExecutableCode.Language+"\n"+part.ExecutableCode.Code+"\n```")
|
||||||
@@ -556,7 +558,6 @@ func responseGeminiChat2OpenAI(response *GeminiChatResponse) *dto.OpenAITextResp
|
|||||||
choice.Message.SetToolCalls(toolCalls)
|
choice.Message.SetToolCalls(toolCalls)
|
||||||
isToolCall = true
|
isToolCall = true
|
||||||
}
|
}
|
||||||
|
|
||||||
choice.Message.SetStringContent(strings.Join(texts, "\n"))
|
choice.Message.SetStringContent(strings.Join(texts, "\n"))
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -596,6 +597,7 @@ func streamResponseGeminiChat2OpenAI(geminiResponse *GeminiChatResponse) (*dto.C
|
|||||||
}
|
}
|
||||||
var texts []string
|
var texts []string
|
||||||
isTools := false
|
isTools := false
|
||||||
|
isThought := false
|
||||||
if candidate.FinishReason != nil {
|
if candidate.FinishReason != nil {
|
||||||
// p := GeminiConvertFinishReason(*candidate.FinishReason)
|
// p := GeminiConvertFinishReason(*candidate.FinishReason)
|
||||||
switch *candidate.FinishReason {
|
switch *candidate.FinishReason {
|
||||||
@@ -620,6 +622,9 @@ func streamResponseGeminiChat2OpenAI(geminiResponse *GeminiChatResponse) (*dto.C
|
|||||||
call.SetIndex(len(choice.Delta.ToolCalls))
|
call.SetIndex(len(choice.Delta.ToolCalls))
|
||||||
choice.Delta.ToolCalls = append(choice.Delta.ToolCalls, *call)
|
choice.Delta.ToolCalls = append(choice.Delta.ToolCalls, *call)
|
||||||
}
|
}
|
||||||
|
} else if part.Thought {
|
||||||
|
isThought = true
|
||||||
|
texts = append(texts, part.Text)
|
||||||
} else {
|
} else {
|
||||||
if part.ExecutableCode != nil {
|
if part.ExecutableCode != nil {
|
||||||
texts = append(texts, "```"+part.ExecutableCode.Language+"\n"+part.ExecutableCode.Code+"\n```\n")
|
texts = append(texts, "```"+part.ExecutableCode.Language+"\n"+part.ExecutableCode.Code+"\n```\n")
|
||||||
@@ -632,7 +637,11 @@ func streamResponseGeminiChat2OpenAI(geminiResponse *GeminiChatResponse) (*dto.C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
choice.Delta.SetContentString(strings.Join(texts, "\n"))
|
if isThought {
|
||||||
|
choice.Delta.SetReasoningContent(strings.Join(texts, "\n"))
|
||||||
|
} else {
|
||||||
|
choice.Delta.SetContentString(strings.Join(texts, "\n"))
|
||||||
|
}
|
||||||
if isTools {
|
if isTools {
|
||||||
choice.FinishReason = &constant.FinishReasonToolCalls
|
choice.FinishReason = &constant.FinishReasonToolCalls
|
||||||
}
|
}
|
||||||
@@ -716,8 +725,11 @@ func GeminiChatHandler(c *gin.Context, resp *http.Response, info *relaycommon.Re
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return service.OpenAIErrorWrapper(err, "close_response_body_failed", http.StatusInternalServerError), nil
|
return service.OpenAIErrorWrapper(err, "close_response_body_failed", http.StatusInternalServerError), nil
|
||||||
}
|
}
|
||||||
|
if common.DebugEnabled {
|
||||||
|
println(string(responseBody))
|
||||||
|
}
|
||||||
var geminiResponse GeminiChatResponse
|
var geminiResponse GeminiChatResponse
|
||||||
err = json.Unmarshal(responseBody, &geminiResponse)
|
err = common.DecodeJson(responseBody, &geminiResponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return service.OpenAIErrorWrapper(err, "unmarshal_response_body_failed", http.StatusInternalServerError), nil
|
return service.OpenAIErrorWrapper(err, "unmarshal_response_body_failed", http.StatusInternalServerError), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ var claudeModelMap = map[string]string{
|
|||||||
"claude-3-5-sonnet-20240620": "claude-3-5-sonnet@20240620",
|
"claude-3-5-sonnet-20240620": "claude-3-5-sonnet@20240620",
|
||||||
"claude-3-5-sonnet-20241022": "claude-3-5-sonnet-v2@20241022",
|
"claude-3-5-sonnet-20241022": "claude-3-5-sonnet-v2@20241022",
|
||||||
"claude-3-7-sonnet-20250219": "claude-3-7-sonnet@20250219",
|
"claude-3-7-sonnet-20250219": "claude-3-7-sonnet@20250219",
|
||||||
|
"claude-sonnet-4-20250514": "claude-sonnet-4@20250514",
|
||||||
|
"claude-opus-4-20250514": "claude-opus-4@20250514",
|
||||||
}
|
}
|
||||||
|
|
||||||
const anthropicVersion = "vertex-2023-10-16"
|
const anthropicVersion = "vertex-2023-10-16"
|
||||||
|
|||||||
@@ -32,7 +32,23 @@ func RelayMidjourneyImage(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, err := http.Get(midjourneyTask.ImageUrl)
|
var httpClient *http.Client
|
||||||
|
if channel, err := model.CacheGetChannel(midjourneyTask.ChannelId); err == nil {
|
||||||
|
if proxy, ok := channel.GetSetting()["proxy"]; ok {
|
||||||
|
if proxyURL, ok := proxy.(string); ok && proxyURL != "" {
|
||||||
|
if httpClient, err = service.NewProxyHttpClient(proxyURL); err != nil {
|
||||||
|
c.JSON(400, gin.H{
|
||||||
|
"error": "proxy_url_invalid",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if httpClient == nil {
|
||||||
|
httpClient = service.GetHttpClient()
|
||||||
|
}
|
||||||
|
resp, err := httpClient.Get(midjourneyTask.ImageUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
"error": "http_get_image_failed",
|
"error": "http_get_image_failed",
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ var defaultCacheRatio = map[string]float64{
|
|||||||
"claude-3-5-sonnet-20241022": 0.1,
|
"claude-3-5-sonnet-20241022": 0.1,
|
||||||
"claude-3-7-sonnet-20250219": 0.1,
|
"claude-3-7-sonnet-20250219": 0.1,
|
||||||
"claude-3-7-sonnet-20250219-thinking": 0.1,
|
"claude-3-7-sonnet-20250219-thinking": 0.1,
|
||||||
|
"claude-sonnet-4-20250514": 0.1,
|
||||||
|
"claude-sonnet-4-20250514-thinking": 0.1,
|
||||||
|
"claude-opus-4-20250514": 0.1,
|
||||||
|
"claude-opus-4-20250514-thinking": 0.1,
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultCreateCacheRatio = map[string]float64{
|
var defaultCreateCacheRatio = map[string]float64{
|
||||||
@@ -47,6 +51,10 @@ var defaultCreateCacheRatio = map[string]float64{
|
|||||||
"claude-3-5-sonnet-20241022": 1.25,
|
"claude-3-5-sonnet-20241022": 1.25,
|
||||||
"claude-3-7-sonnet-20250219": 1.25,
|
"claude-3-7-sonnet-20250219": 1.25,
|
||||||
"claude-3-7-sonnet-20250219-thinking": 1.25,
|
"claude-3-7-sonnet-20250219-thinking": 1.25,
|
||||||
|
"claude-sonnet-4-20250514": 1.25,
|
||||||
|
"claude-sonnet-4-20250514-thinking": 1.25,
|
||||||
|
"claude-opus-4-20250514": 1.25,
|
||||||
|
"claude-opus-4-20250514-thinking": 1.25,
|
||||||
}
|
}
|
||||||
|
|
||||||
//var defaultCreateCacheRatio = map[string]float64{}
|
//var defaultCreateCacheRatio = map[string]float64{}
|
||||||
|
|||||||
@@ -114,7 +114,9 @@ var defaultModelRatio = map[string]float64{
|
|||||||
"claude-3-5-sonnet-20241022": 1.5,
|
"claude-3-5-sonnet-20241022": 1.5,
|
||||||
"claude-3-7-sonnet-20250219": 1.5,
|
"claude-3-7-sonnet-20250219": 1.5,
|
||||||
"claude-3-7-sonnet-20250219-thinking": 1.5,
|
"claude-3-7-sonnet-20250219-thinking": 1.5,
|
||||||
|
"claude-sonnet-4-20250514": 1.5,
|
||||||
"claude-3-opus-20240229": 7.5, // $15 / 1M tokens
|
"claude-3-opus-20240229": 7.5, // $15 / 1M tokens
|
||||||
|
"claude-opus-4-20250514": 7.5,
|
||||||
"ERNIE-4.0-8K": 0.120 * RMB,
|
"ERNIE-4.0-8K": 0.120 * RMB,
|
||||||
"ERNIE-3.5-8K": 0.012 * RMB,
|
"ERNIE-3.5-8K": 0.012 * RMB,
|
||||||
"ERNIE-3.5-8K-0205": 0.024 * RMB,
|
"ERNIE-3.5-8K-0205": 0.024 * RMB,
|
||||||
@@ -440,13 +442,15 @@ func getHardcodedCompletionModelRatio(name string) (float64, bool) {
|
|||||||
if name == "chatgpt-4o-latest" {
|
if name == "chatgpt-4o-latest" {
|
||||||
return 3, true
|
return 3, true
|
||||||
}
|
}
|
||||||
if strings.Contains(name, "claude-instant-1") {
|
|
||||||
return 3, true
|
if strings.Contains(name, "claude-3") {
|
||||||
} else if strings.Contains(name, "claude-2") {
|
|
||||||
return 3, true
|
|
||||||
} else if strings.Contains(name, "claude-3") {
|
|
||||||
return 5, true
|
return 5, true
|
||||||
|
} else if strings.Contains(name, "claude-sonnet-4") || strings.Contains(name, "claude-opus-4") {
|
||||||
|
return 5, true
|
||||||
|
} else if strings.Contains(name, "claude-instant-1") || strings.Contains(name, "claude-2") {
|
||||||
|
return 3, true
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(name, "gpt-3.5") {
|
if strings.HasPrefix(name, "gpt-3.5") {
|
||||||
if name == "gpt-3.5-turbo" || strings.HasSuffix(name, "0125") {
|
if name == "gpt-3.5-turbo" || strings.HasSuffix(name, "0125") {
|
||||||
// https://openai.com/blog/new-embedding-models-and-api-updates
|
// https://openai.com/blog/new-embedding-models-and-api-updates
|
||||||
|
|||||||
@@ -871,7 +871,16 @@ const ChannelsTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
await loadChannels(activePage - 1, pageSize, idSort, enableTagMode);
|
if (searchKeyword === '' && searchGroup === '' && searchModel === '') {
|
||||||
|
await loadChannels(activePage - 1, pageSize, idSort, enableTagMode);
|
||||||
|
} else {
|
||||||
|
await searchChannels(
|
||||||
|
searchKeyword,
|
||||||
|
searchGroup,
|
||||||
|
searchModel,
|
||||||
|
enableTagMode,
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -979,8 +988,8 @@ const ChannelsTable = () => {
|
|||||||
enableTagMode,
|
enableTagMode,
|
||||||
) => {
|
) => {
|
||||||
if (searchKeyword === '' && searchGroup === '' && searchModel === '') {
|
if (searchKeyword === '' && searchGroup === '' && searchModel === '') {
|
||||||
await loadChannels(0, pageSize, idSort, enableTagMode);
|
await loadChannels(activePage - 1, pageSize, idSort, enableTagMode);
|
||||||
setActivePage(1);
|
// setActivePage(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setSearching(true);
|
setSearching(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user