diff --git a/common/utils/array.go b/common/utils/array.go
new file mode 100644
index 00000000..72437d4f
--- /dev/null
+++ b/common/utils/array.go
@@ -0,0 +1,13 @@
+package utils
+
+func DeDuplication(slice []string) []string {
+ m := make(map[string]bool)
+ for _, v := range slice {
+ m[v] = true
+ }
+ result := make([]string, 0, len(m))
+ for v := range m {
+ result = append(result, v)
+ }
+ return result
+}
diff --git a/model/ability.go b/model/ability.go
index 2db72518..5cfb9949 100644
--- a/model/ability.go
+++ b/model/ability.go
@@ -2,10 +2,13 @@ package model
import (
"context"
- "github.com/songquanpeng/one-api/common"
- "gorm.io/gorm"
"sort"
"strings"
+
+ "gorm.io/gorm"
+
+ "github.com/songquanpeng/one-api/common"
+ "github.com/songquanpeng/one-api/common/utils"
)
type Ability struct {
@@ -49,6 +52,7 @@ func GetRandomSatisfiedChannel(group string, model string, ignoreFirstPriority b
func (channel *Channel) AddAbilities() error {
models_ := strings.Split(channel.Models, ",")
+ models_ = utils.DeDuplication(models_)
groups_ := strings.Split(channel.Group, ",")
abilities := make([]Ability, 0, len(models_))
for _, model := range models_ {
diff --git a/relay/adaptor/baiduv2/constants.go b/relay/adaptor/baiduv2/constants.go
new file mode 100644
index 00000000..aad9e584
--- /dev/null
+++ b/relay/adaptor/baiduv2/constants.go
@@ -0,0 +1,30 @@
+package baiduv2
+
+// https://console.bce.baidu.com/support/?_=1692863460488×tamp=1739074632076#/api?product=QIANFAN&project=%E5%8D%83%E5%B8%86ModelBuilder&parent=%E5%AF%B9%E8%AF%9DChat%20V2&api=v2%2Fchat%2Fcompletions&method=post
+// https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Fm2vrveyu#%E6%94%AF%E6%8C%81%E6%A8%A1%E5%9E%8B%E5%88%97%E8%A1%A8
+
+var ModelList = []string{
+ "ernie-4.0-8k-latest",
+ "ernie-4.0-8k-preview",
+ "ernie-4.0-8k",
+ "ernie-4.0-turbo-8k-latest",
+ "ernie-4.0-turbo-8k-preview",
+ "ernie-4.0-turbo-8k",
+ "ernie-4.0-turbo-128k",
+ "ernie-3.5-8k-preview",
+ "ernie-3.5-8k",
+ "ernie-3.5-128k",
+ "ernie-speed-8k",
+ "ernie-speed-128k",
+ "ernie-speed-pro-128k",
+ "ernie-lite-8k",
+ "ernie-lite-pro-128k",
+ "ernie-tiny-8k",
+ "ernie-char-8k",
+ "ernie-char-fiction-8k",
+ "ernie-novel-8k",
+ "deepseek-v3",
+ "deepseek-r1",
+ "deepseek-r1-distill-qwen-32b",
+ "deepseek-r1-distill-qwen-14b",
+}
diff --git a/relay/adaptor/baiduv2/main.go b/relay/adaptor/baiduv2/main.go
new file mode 100644
index 00000000..d305e1d9
--- /dev/null
+++ b/relay/adaptor/baiduv2/main.go
@@ -0,0 +1,17 @@
+package baiduv2
+
+import (
+ "fmt"
+
+ "github.com/songquanpeng/one-api/relay/meta"
+ "github.com/songquanpeng/one-api/relay/relaymode"
+)
+
+func GetRequestURL(meta *meta.Meta) (string, error) {
+ switch meta.Mode {
+ case relaymode.ChatCompletions:
+ return fmt.Sprintf("%s/v2/chat/completions", meta.BaseURL), nil
+ default:
+ }
+ return "", fmt.Errorf("unsupported relay mode %d for baidu v2", meta.Mode)
+}
diff --git a/relay/adaptor/openai/adaptor.go b/relay/adaptor/openai/adaptor.go
index 6946e402..3907a0db 100644
--- a/relay/adaptor/openai/adaptor.go
+++ b/relay/adaptor/openai/adaptor.go
@@ -8,7 +8,9 @@ import (
"strings"
"github.com/gin-gonic/gin"
+
"github.com/songquanpeng/one-api/relay/adaptor"
+ "github.com/songquanpeng/one-api/relay/adaptor/baiduv2"
"github.com/songquanpeng/one-api/relay/adaptor/doubao"
"github.com/songquanpeng/one-api/relay/adaptor/minimax"
"github.com/songquanpeng/one-api/relay/adaptor/novita"
@@ -52,6 +54,8 @@ func (a *Adaptor) GetRequestURL(meta *meta.Meta) (string, error) {
return doubao.GetRequestURL(meta)
case channeltype.Novita:
return novita.GetRequestURL(meta)
+ case channeltype.BaiduV2:
+ return baiduv2.GetRequestURL(meta)
default:
return GetFullRequestURL(meta.BaseURL, meta.RequestURLPath, meta.ChannelType), nil
}
diff --git a/relay/adaptor/openai/compatible.go b/relay/adaptor/openai/compatible.go
index 15b4dcc0..99424e49 100644
--- a/relay/adaptor/openai/compatible.go
+++ b/relay/adaptor/openai/compatible.go
@@ -3,6 +3,7 @@ package openai
import (
"github.com/songquanpeng/one-api/relay/adaptor/ai360"
"github.com/songquanpeng/one-api/relay/adaptor/baichuan"
+ "github.com/songquanpeng/one-api/relay/adaptor/baiduv2"
"github.com/songquanpeng/one-api/relay/adaptor/deepseek"
"github.com/songquanpeng/one-api/relay/adaptor/doubao"
"github.com/songquanpeng/one-api/relay/adaptor/groq"
@@ -34,6 +35,7 @@ var CompatibleChannels = []int{
channeltype.Novita,
channeltype.SiliconFlow,
channeltype.XAI,
+ channeltype.BaiduV2,
}
func GetCompatibleChannelMeta(channelType int) (string, []string) {
@@ -68,6 +70,8 @@ func GetCompatibleChannelMeta(channelType int) (string, []string) {
return "siliconflow", siliconflow.ModelList
case channeltype.XAI:
return "xai", xai.ModelList
+ case channeltype.BaiduV2:
+ return "baiduv2", baiduv2.ModelList
default:
return "openai", ModelList
}
diff --git a/relay/channeltype/define.go b/relay/channeltype/define.go
index f54d0e30..a74c6269 100644
--- a/relay/channeltype/define.go
+++ b/relay/channeltype/define.go
@@ -48,5 +48,6 @@ const (
SiliconFlow
XAI
Replicate
+ BaiduV2
Dummy
)
diff --git a/relay/channeltype/url.go b/relay/channeltype/url.go
index 8e271f4e..6279fee2 100644
--- a/relay/channeltype/url.go
+++ b/relay/channeltype/url.go
@@ -48,6 +48,7 @@ var ChannelBaseURLs = []string{
"https://api.siliconflow.cn", // 44
"https://api.x.ai", // 45
"https://api.replicate.com/v1/models/", // 46
+ "https://qianfan.baidubce.com", // 47
}
func init() {
diff --git a/web/default/src/constants/channel.constants.js b/web/default/src/constants/channel.constants.js
index b030805b..a2a048b6 100644
--- a/web/default/src/constants/channel.constants.js
+++ b/web/default/src/constants/channel.constants.js
@@ -21,6 +21,13 @@ export const CHANNEL_OPTIONS = [
color: 'blue',
tip: '请前往此处获取 AK(API Key)以及 SK(Secret Key)',
},
+ {
+ key: 47,
+ text: '百度文心千帆 V2',
+ value: 47,
+ color: 'blue',
+ tip: '请前往此处获取 API Key',
+ },
{key: 17, text: '阿里通义千问', value: 17, color: 'orange'},
{key: 18, text: '讯飞星火认知', value: 18, color: 'blue'},
{key: 16, text: '智谱 ChatGLM', value: 16, color: 'violet'},