Commit 08f88d25 by feitianbubu Committed by GitHub

feat: support Tencent TokenHub API key via OpenAI-compatible protocol (#6232)

* feat: support tencent tokenhub api key via openai-compatible protocol

* fix: use tokenhub base url for tencent api key channels

* test: cover tencent key-format dispatch and add TokenHub key prompt locales
parent 8b41defb
package tencent
import (
"strings"
"github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/relay/channel"
"github.com/QuantumNous/new-api/relay/channel/openai"
relaycommon "github.com/QuantumNous/new-api/relay/common"
)
const tokenHubBaseURL = "https://tokenhub.tencentmaas.com"
// DispatchAdaptor 按密钥格式分流:三段式 ak/sk 走原生 TC3,单段 TokenHub key 走 OpenAI 兼容。
type DispatchAdaptor struct {
channel.Adaptor
}
func (a *DispatchAdaptor) Init(info *relaycommon.RelayInfo) {
if strings.Contains(info.ApiKey, "|") {
a.Adaptor = &Adaptor{}
} else {
a.Adaptor = &openai.Adaptor{}
if info.ChannelBaseUrl == "" || info.ChannelBaseUrl == constant.ChannelBaseURLs[constant.ChannelTypeTencent] {
info.ChannelBaseUrl = tokenHubBaseURL
}
}
a.Adaptor.Init(info)
}
func (a *DispatchAdaptor) GetModelList() []string {
return ModelList
}
func (a *DispatchAdaptor) GetChannelName() string {
return ChannelName
}
package tencent
import (
"testing"
"github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/relay/channel/openai"
relaycommon "github.com/QuantumNous/new-api/relay/common"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDispatchAdaptorInit(t *testing.T) {
tests := []struct {
name string
apiKey string
baseURL string
wantTC3 bool
wantBaseURL string
}{
{
name: "legacy three-segment key selects TC3 adaptor and keeps base url",
apiKey: "1300000000|AKIDxxxxxxxx|secretxxxxxxxx",
baseURL: constant.ChannelBaseURLs[constant.ChannelTypeTencent],
wantTC3: true,
wantBaseURL: constant.ChannelBaseURLs[constant.ChannelTypeTencent],
},
{
name: "tokenhub key with default base url rewrites to tokenhub",
apiKey: "sk-xxxxxxxxxxxxxxxx",
baseURL: constant.ChannelBaseURLs[constant.ChannelTypeTencent],
wantTC3: false,
wantBaseURL: tokenHubBaseURL,
},
{
name: "tokenhub key with empty base url rewrites to tokenhub",
apiKey: "sk-xxxxxxxxxxxxxxxx",
baseURL: "",
wantTC3: false,
wantBaseURL: tokenHubBaseURL,
},
{
name: "tokenhub key with custom base url is preserved",
apiKey: "sk-xxxxxxxxxxxxxxxx",
baseURL: "https://proxy.example.com",
wantTC3: false,
wantBaseURL: "https://proxy.example.com",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
info := &relaycommon.RelayInfo{ChannelMeta: &relaycommon.ChannelMeta{
ChannelType: constant.ChannelTypeTencent,
ApiKey: tt.apiKey,
ChannelBaseUrl: tt.baseURL,
}}
dispatch := &DispatchAdaptor{}
dispatch.Init(info)
require.NotNil(t, dispatch.Adaptor)
if tt.wantTC3 {
assert.IsType(t, &Adaptor{}, dispatch.Adaptor)
} else {
assert.IsType(t, &openai.Adaptor{}, dispatch.Adaptor)
}
assert.Equal(t, tt.wantBaseURL, info.ChannelBaseUrl)
})
}
}
...@@ -342,6 +342,7 @@ var streamSupportedChannels = map[int]bool{ ...@@ -342,6 +342,7 @@ var streamSupportedChannels = map[int]bool{
constant.ChannelTypeMiniMax: true, constant.ChannelTypeMiniMax: true,
constant.ChannelTypeSiliconFlow: true, constant.ChannelTypeSiliconFlow: true,
constant.ChannelTypeAdvancedCustom: true, constant.ChannelTypeAdvancedCustom: true,
constant.ChannelTypeTencent: true,
} }
func GenRelayInfoWs(c *gin.Context, ws *websocket.Conn) *RelayInfo { func GenRelayInfoWs(c *gin.Context, ws *websocket.Conn) *RelayInfo {
......
...@@ -66,7 +66,7 @@ func GetAdaptor(apiType int) channel.Adaptor { ...@@ -66,7 +66,7 @@ func GetAdaptor(apiType int) channel.Adaptor {
case constant.APITypePaLM: case constant.APITypePaLM:
return &palm.Adaptor{} return &palm.Adaptor{}
case constant.APITypeTencent: case constant.APITypeTencent:
return &tencent.Adaptor{} return &tencent.DispatchAdaptor{}
case constant.APITypeXunfei: case constant.APITypeXunfei:
return &xunfei.Adaptor{} return &xunfei.Adaptor{}
case constant.APITypeZhipu: case constant.APITypeZhipu:
......
...@@ -386,7 +386,7 @@ export const TYPE_TO_KEY_PROMPT: Record<number, string> = { ...@@ -386,7 +386,7 @@ export const TYPE_TO_KEY_PROMPT: Record<number, string> = {
15: 'Format: APIKey|SecretKey', 15: 'Format: APIKey|SecretKey',
18: 'Format: APPID|APISecret|APIKey', 18: 'Format: APPID|APISecret|APIKey',
22: 'Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041', 22: 'Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041',
23: 'Format: AppId|SecretId|SecretKey', 23: 'Format: TokenHub API Key, or legacy AppId|SecretId|SecretKey',
33: 'Format: Ak|Sk|Region', 33: 'Format: Ak|Sk|Region',
50: 'Format: AccessKey|SecretKey (or just ApiKey if upstream is New API)', 50: 'Format: AccessKey|SecretKey (or just ApiKey if upstream is New API)',
51: 'Format: Access Key ID|Secret Access Key', 51: 'Format: Access Key ID|Secret Access Key',
......
...@@ -2052,7 +2052,7 @@ ...@@ -2052,7 +2052,7 @@
"Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041", "Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041",
"Format: APIKey|SecretKey": "Format: APIKey|SecretKey", "Format: APIKey|SecretKey": "Format: APIKey|SecretKey",
"Format: APPID|APISecret|APIKey": "Format: APPID|APISecret|APIKey", "Format: APPID|APISecret|APIKey": "Format: APPID|APISecret|APIKey",
"Format: AppId|SecretId|SecretKey": "Format: AppId|SecretId|SecretKey", "Format: TokenHub API Key, or legacy AppId|SecretId|SecretKey": "Format: TokenHub API Key, or legacy AppId|SecretId|SecretKey",
"Forward requests directly to upstream providers without any post-processing.": "Forward requests directly to upstream providers without any post-processing.", "Forward requests directly to upstream providers without any post-processing.": "Forward requests directly to upstream providers without any post-processing.",
"Frames per second": "Frames per second", "Frames per second": "Frames per second",
"Free": "Free", "Free": "Free",
......
...@@ -2052,7 +2052,7 @@ ...@@ -2052,7 +2052,7 @@
"Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "Format : APIKey-AppId, par ex. fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041", "Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "Format : APIKey-AppId, par ex. fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041",
"Format: APIKey|SecretKey": "Format : APIKey|SecretKey", "Format: APIKey|SecretKey": "Format : APIKey|SecretKey",
"Format: APPID|APISecret|APIKey": "Format : APPID|APISecret|APIKey", "Format: APPID|APISecret|APIKey": "Format : APPID|APISecret|APIKey",
"Format: AppId|SecretId|SecretKey": "Format : AppId|SecretId|SecretKey", "Format: TokenHub API Key, or legacy AppId|SecretId|SecretKey": "Format : TokenHub API Key, ou l'ancien format AppId|SecretId|SecretKey",
"Forward requests directly to upstream providers without any post-processing.": "Transférer les requêtes directement aux fournisseurs amont sans aucun post-traitement.", "Forward requests directly to upstream providers without any post-processing.": "Transférer les requêtes directement aux fournisseurs amont sans aucun post-traitement.",
"Frames per second": "Images par seconde", "Frames per second": "Images par seconde",
"Free": "Libre", "Free": "Libre",
......
...@@ -2052,7 +2052,7 @@ ...@@ -2052,7 +2052,7 @@
"Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "形式: APIKey-AppId、例: fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041", "Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "形式: APIKey-AppId、例: fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041",
"Format: APIKey|SecretKey": "形式: APIKey|SecretKey", "Format: APIKey|SecretKey": "形式: APIKey|SecretKey",
"Format: APPID|APISecret|APIKey": "形式: APPID|APISecret|APIKey", "Format: APPID|APISecret|APIKey": "形式: APPID|APISecret|APIKey",
"Format: AppId|SecretId|SecretKey": "形式: AppId|SecretId|SecretKey", "Format: TokenHub API Key, or legacy AppId|SecretId|SecretKey": "形式: TokenHub API Key、または旧形式の AppId|SecretId|SecretKey",
"Forward requests directly to upstream providers without any post-processing.": "ポストプロセスなしで、リクエストをアップストリームプロバイダーに直接転送します。", "Forward requests directly to upstream providers without any post-processing.": "ポストプロセスなしで、リクエストをアップストリームプロバイダーに直接転送します。",
"Frames per second": "フレームレート", "Frames per second": "フレームレート",
"Free": "空き", "Free": "空き",
......
...@@ -2052,7 +2052,7 @@ ...@@ -2052,7 +2052,7 @@
"Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "Формат: APIKey-AppId, напр., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041", "Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "Формат: APIKey-AppId, напр., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041",
"Format: APIKey|SecretKey": "Формат: APIKey|SecretKey", "Format: APIKey|SecretKey": "Формат: APIKey|SecretKey",
"Format: APPID|APISecret|APIKey": "Формат: APPID|APISecret|APIKey", "Format: APPID|APISecret|APIKey": "Формат: APPID|APISecret|APIKey",
"Format: AppId|SecretId|SecretKey": "Формат: AppId|SecretId|SecretKey", "Format: TokenHub API Key, or legacy AppId|SecretId|SecretKey": "Формат: TokenHub API Key или устаревший AppId|SecretId|SecretKey",
"Forward requests directly to upstream providers without any post-processing.": "Перенаправлять запросы напрямую upstream-провайдерам без какой-либо постобработки.", "Forward requests directly to upstream providers without any post-processing.": "Перенаправлять запросы напрямую upstream-провайдерам без какой-либо постобработки.",
"Frames per second": "Кадров в секунду", "Frames per second": "Кадров в секунду",
"Free": "Свободно", "Free": "Свободно",
......
...@@ -2052,7 +2052,7 @@ ...@@ -2052,7 +2052,7 @@
"Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "Định dạng: APIKey-AppId, ví dụ: fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041", "Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "Định dạng: APIKey-AppId, ví dụ: fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041",
"Format: APIKey|SecretKey": "Định dạng: APIKey|SecretKey", "Format: APIKey|SecretKey": "Định dạng: APIKey|SecretKey",
"Format: APPID|APISecret|APIKey": "Định dạng: APPID|APISecret|APIKey", "Format: APPID|APISecret|APIKey": "Định dạng: APPID|APISecret|APIKey",
"Format: AppId|SecretId|SecretKey": "Định dạng: AppId|SecretId|SecretKey", "Format: TokenHub API Key, or legacy AppId|SecretId|SecretKey": "Định dạng: TokenHub API Key, hoặc định dạng cũ AppId|SecretId|SecretKey",
"Forward requests directly to upstream providers without any post-processing.": "Chuyển tiếp các yêu cầu trực tiếp đến các nhà cung cấp ngược dòng mà không cần xử lý hậu kỳ nào.", "Forward requests directly to upstream providers without any post-processing.": "Chuyển tiếp các yêu cầu trực tiếp đến các nhà cung cấp ngược dòng mà không cần xử lý hậu kỳ nào.",
"Frames per second": "Khung hình / giây", "Frames per second": "Khung hình / giây",
"Free": "Trống", "Free": "Trống",
......
...@@ -2052,7 +2052,7 @@ ...@@ -2052,7 +2052,7 @@
"Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "格式:APIKey-AppId,例如:fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041", "Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "格式:APIKey-AppId,例如:fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041",
"Format: APIKey|SecretKey": "格式:APIKey|SecretKey", "Format: APIKey|SecretKey": "格式:APIKey|SecretKey",
"Format: APPID|APISecret|APIKey": "格式:APPID|APISecret|APIKey", "Format: APPID|APISecret|APIKey": "格式:APPID|APISecret|APIKey",
"Format: AppId|SecretId|SecretKey": "格式:AppId|SecretId|SecretKey", "Format: TokenHub API Key, or legacy AppId|SecretId|SecretKey": "格式:TokenHub API Key,或舊版 AppId|SecretId|SecretKey",
"Forward requests directly to upstream providers without any post-processing.": "將請求直接轉發給上游供應商,不進行任何後處理。", "Forward requests directly to upstream providers without any post-processing.": "將請求直接轉發給上游供應商,不進行任何後處理。",
"Frames per second": "幀率", "Frames per second": "幀率",
"Free": "可用", "Free": "可用",
......
...@@ -2052,7 +2052,7 @@ ...@@ -2052,7 +2052,7 @@
"Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "格式:APIKey-AppId,例如:fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041", "Format: APIKey-AppId, e.g., fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041": "格式:APIKey-AppId,例如:fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041",
"Format: APIKey|SecretKey": "格式:APIKey|SecretKey", "Format: APIKey|SecretKey": "格式:APIKey|SecretKey",
"Format: APPID|APISecret|APIKey": "格式:APPID|APISecret|APIKey", "Format: APPID|APISecret|APIKey": "格式:APPID|APISecret|APIKey",
"Format: AppId|SecretId|SecretKey": "格式:AppId|SecretId|SecretKey", "Format: TokenHub API Key, or legacy AppId|SecretId|SecretKey": "格式:TokenHub API Key,或旧版 AppId|SecretId|SecretKey",
"Forward requests directly to upstream providers without any post-processing.": "将请求直接转发给上游提供商,不进行任何后处理。", "Forward requests directly to upstream providers without any post-processing.": "将请求直接转发给上游提供商,不进行任何后处理。",
"Frames per second": "帧率", "Frames per second": "帧率",
"Free": "可用", "Free": "可用",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment