Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
4d65a13a
authored
Oct 03, 2023
by
JustSong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: support Tencent's model (close #519)
parent
dfd5b615
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
375 additions
and
26 deletions
+375
-26
README.md
+1
-0
common/constants.go
+25
-23
common/model-ratio.go
+1
-0
controller/model.go
+9
-0
controller/option.go
+1
-1
controller/relay-tencent.go
+287
-0
controller/relay-text.go
+43
-0
middleware/distributor.go
+2
-2
web/src/constants/channel.constants.js
+1
-0
web/src/pages/Channel/EditChannel.js
+5
-0
No files found.
README.md
View file @
4d65a13a
...
...
@@ -72,6 +72,7 @@ _✨ 通过标准的 OpenAI API 格式访问所有的大模型,开箱即用
+
[
x
]
[
讯飞星火认知大模型
]
(https://www.xfyun.cn/doc/spark/Web.html)
+
[
x
]
[
智谱 ChatGLM 系列模型
]
(https://bigmodel.cn)
+
[
x
]
[
360 智脑
]
(https://ai.360.cn)
+
[
x
]
[
腾讯混元大模型
]
(https://cloud.tencent.com/document/product/1729)
2.
支持配置镜像以及众多第三方代理服务:
+
[
x
]
[
OpenAI-SB
]
(https://openai-sb.com)
+
[
x
]
[
CloseAI
]
(https://console.closeai-asia.com/r/2412)
...
...
common/constants.go
View file @
4d65a13a
...
...
@@ -186,30 +186,32 @@ const (
ChannelTypeOpenRouter
=
20
ChannelTypeAIProxyLibrary
=
21
ChannelTypeFastGPT
=
22
ChannelTypeTencent
=
23
)
var
ChannelBaseURLs
=
[]
string
{
""
,
// 0
"https://api.openai.com"
,
// 1
"https://oa.api2d.net"
,
// 2
""
,
// 3
"https://api.closeai-proxy.xyz"
,
// 4
"https://api.openai-sb.com"
,
// 5
"https://api.openaimax.com"
,
// 6
"https://api.ohmygpt.com"
,
// 7
""
,
// 8
"https://api.caipacity.com"
,
// 9
"https://api.aiproxy.io"
,
// 10
""
,
// 11
"https://api.api2gpt.com"
,
// 12
"https://api.aigc2d.com"
,
// 13
"https://api.anthropic.com"
,
// 14
"https://aip.baidubce.com"
,
// 15
"https://open.bigmodel.cn"
,
// 16
"https://dashscope.aliyuncs.com"
,
// 17
""
,
// 18
"https://ai.360.cn"
,
// 19
"https://openrouter.ai/api"
,
// 20
"https://api.aiproxy.io"
,
// 21
"https://fastgpt.run/api/openapi"
,
// 22
""
,
// 0
"https://api.openai.com"
,
// 1
"https://oa.api2d.net"
,
// 2
""
,
// 3
"https://api.closeai-proxy.xyz"
,
// 4
"https://api.openai-sb.com"
,
// 5
"https://api.openaimax.com"
,
// 6
"https://api.ohmygpt.com"
,
// 7
""
,
// 8
"https://api.caipacity.com"
,
// 9
"https://api.aiproxy.io"
,
// 10
""
,
// 11
"https://api.api2gpt.com"
,
// 12
"https://api.aigc2d.com"
,
// 13
"https://api.anthropic.com"
,
// 14
"https://aip.baidubce.com"
,
// 15
"https://open.bigmodel.cn"
,
// 16
"https://dashscope.aliyuncs.com"
,
// 17
""
,
// 18
"https://ai.360.cn"
,
// 19
"https://openrouter.ai/api"
,
// 20
"https://api.aiproxy.io"
,
// 21
"https://fastgpt.run/api/openapi"
,
// 22
"https://hunyuan.cloud.tencent.com"
,
//23
}
common/model-ratio.go
View file @
4d65a13a
...
...
@@ -59,6 +59,7 @@ var ModelRatio = map[string]float64{
"embedding-bert-512-v1"
:
0.0715
,
// ¥0.001 / 1k tokens
"embedding_s1_v1"
:
0.0715
,
// ¥0.001 / 1k tokens
"semantic_similarity_s1_v1"
:
0.0715
,
// ¥0.001 / 1k tokens
"hunyuan"
:
7.143
,
// ¥0.1 / 1k tokens // https://cloud.tencent.com/document/product/1729/97731#e0e6be58-60c8-469f-bdeb-6c264ce3b4d0
}
func
ModelRatio2JSONString
()
string
{
...
...
controller/model.go
View file @
4d65a13a
...
...
@@ -423,6 +423,15 @@ func init() {
Root
:
"semantic_similarity_s1_v1"
,
Parent
:
nil
,
},
{
Id
:
"hunyuan"
,
Object
:
"model"
,
Created
:
1677649963
,
OwnedBy
:
"tencent"
,
Permission
:
permission
,
Root
:
"hunyuan"
,
Parent
:
nil
,
},
}
openAIModelsMap
=
make
(
map
[
string
]
OpenAIModels
)
for
_
,
model
:=
range
openAIModels
{
...
...
controller/option.go
View file @
4d65a13a
...
...
@@ -46,7 +46,7 @@ func UpdateOption(c *gin.Context) {
if
option
.
Value
==
"true"
&&
common
.
GitHubClientId
==
""
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"无法启用 GitHub OAuth,请先填入 GitHub Client I
D
以及 GitHub Client Secret!"
,
"message"
:
"无法启用 GitHub OAuth,请先填入 GitHub Client I
d
以及 GitHub Client Secret!"
,
})
return
}
...
...
controller/relay-tencent.go
0 → 100644
View file @
4d65a13a
This diff is collapsed.
Click to expand it.
controller/relay-text.go
View file @
4d65a13a
...
...
@@ -24,6 +24,7 @@ const (
APITypeAli
APITypeXunfei
APITypeAIProxyLibrary
APITypeTencent
)
var
httpClient
*
http
.
Client
...
...
@@ -109,6 +110,8 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode {
apiType
=
APITypeXunfei
case
common
.
ChannelTypeAIProxyLibrary
:
apiType
=
APITypeAIProxyLibrary
case
common
.
ChannelTypeTencent
:
apiType
=
APITypeTencent
}
baseURL
:=
common
.
ChannelBaseURLs
[
channelType
]
requestURL
:=
c
.
Request
.
URL
.
String
()
...
...
@@ -179,6 +182,8 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode {
if
relayMode
==
RelayModeEmbeddings
{
fullRequestURL
=
"https://dashscope.aliyuncs.com/api/v1/services/embeddings/text-embedding/text-embedding"
}
case
APITypeTencent
:
fullRequestURL
=
"https://hunyuan.cloud.tencent.com/hyllm/v1/chat/completions"
case
APITypeAIProxyLibrary
:
fullRequestURL
=
fmt
.
Sprintf
(
"%s/api/library/ask"
,
baseURL
)
}
...
...
@@ -285,6 +290,23 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode {
return
errorWrapper
(
err
,
"marshal_text_request_failed"
,
http
.
StatusInternalServerError
)
}
requestBody
=
bytes
.
NewBuffer
(
jsonStr
)
case
APITypeTencent
:
apiKey
:=
c
.
Request
.
Header
.
Get
(
"Authorization"
)
apiKey
=
strings
.
TrimPrefix
(
apiKey
,
"Bearer "
)
appId
,
secretId
,
secretKey
,
err
:=
parseTencentConfig
(
apiKey
)
if
err
!=
nil
{
return
errorWrapper
(
err
,
"invalid_tencent_config"
,
http
.
StatusInternalServerError
)
}
tencentRequest
:=
requestOpenAI2Tencent
(
textRequest
)
tencentRequest
.
AppId
=
appId
tencentRequest
.
SecretId
=
secretId
jsonStr
,
err
:=
json
.
Marshal
(
tencentRequest
)
if
err
!=
nil
{
return
errorWrapper
(
err
,
"marshal_text_request_failed"
,
http
.
StatusInternalServerError
)
}
sign
:=
getTencentSign
(
*
tencentRequest
,
secretKey
)
c
.
Request
.
Header
.
Set
(
"Authorization"
,
sign
)
requestBody
=
bytes
.
NewBuffer
(
jsonStr
)
case
APITypeAIProxyLibrary
:
aiProxyLibraryRequest
:=
requestOpenAI2AIProxyLibrary
(
textRequest
)
aiProxyLibraryRequest
.
LibraryId
=
c
.
GetString
(
"library_id"
)
...
...
@@ -332,6 +354,8 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode {
if
textRequest
.
Stream
{
req
.
Header
.
Set
(
"X-DashScope-SSE"
,
"enable"
)
}
case
APITypeTencent
:
req
.
Header
.
Set
(
"Authorization"
,
apiKey
)
default
:
req
.
Header
.
Set
(
"Authorization"
,
"Bearer "
+
apiKey
)
}
...
...
@@ -584,6 +608,25 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode {
}
return
nil
}
case
APITypeTencent
:
if
isStream
{
err
,
responseText
:=
tencentStreamHandler
(
c
,
resp
)
if
err
!=
nil
{
return
err
}
textResponse
.
Usage
.
PromptTokens
=
promptTokens
textResponse
.
Usage
.
CompletionTokens
=
countTokenText
(
responseText
,
textRequest
.
Model
)
return
nil
}
else
{
err
,
usage
:=
tencentHandler
(
c
,
resp
)
if
err
!=
nil
{
return
err
}
if
usage
!=
nil
{
textResponse
.
Usage
=
*
usage
}
return
nil
}
default
:
return
errorWrapper
(
errors
.
New
(
"unknown api type"
),
"unknown_api_type"
,
http
.
StatusInternalServerError
)
}
...
...
middleware/distributor.go
View file @
4d65a13a
...
...
@@ -25,12 +25,12 @@ func Distribute() func(c *gin.Context) {
if
ok
{
id
,
err
:=
strconv
.
Atoi
(
channelId
.
(
string
))
if
err
!=
nil
{
abortWithMessage
(
c
,
http
.
StatusBadRequest
,
"无效的渠道 I
D
"
)
abortWithMessage
(
c
,
http
.
StatusBadRequest
,
"无效的渠道 I
d
"
)
return
}
channel
,
err
=
model
.
GetChannelById
(
id
,
true
)
if
err
!=
nil
{
abortWithMessage
(
c
,
http
.
StatusBadRequest
,
"无效的渠道 I
D
"
)
abortWithMessage
(
c
,
http
.
StatusBadRequest
,
"无效的渠道 I
d
"
)
return
}
if
channel
.
Status
!=
common
.
ChannelStatusEnabled
{
...
...
web/src/constants/channel.constants.js
View file @
4d65a13a
...
...
@@ -8,6 +8,7 @@ export const CHANNEL_OPTIONS = [
{
key
:
18
,
text
:
'讯飞星火认知'
,
value
:
18
,
color
:
'blue'
},
{
key
:
16
,
text
:
'智谱 ChatGLM'
,
value
:
16
,
color
:
'violet'
},
{
key
:
19
,
text
:
'360 智脑'
,
value
:
19
,
color
:
'blue'
},
{
key
:
23
,
text
:
'腾讯混元'
,
value
:
23
,
color
:
'teal'
},
{
key
:
8
,
text
:
'自定义渠道'
,
value
:
8
,
color
:
'pink'
},
{
key
:
22
,
text
:
'知识库:FastGPT'
,
value
:
22
,
color
:
'blue'
},
{
key
:
21
,
text
:
'知识库:AI Proxy'
,
value
:
21
,
color
:
'purple'
},
...
...
web/src/pages/Channel/EditChannel.js
View file @
4d65a13a
...
...
@@ -19,6 +19,8 @@ function type2secretPrompt(type) {
return
'按照如下格式输入:APPID|APISecret|APIKey'
;
case
22
:
return
'按照如下格式输入:APIKey-AppId,例如:fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041'
;
case
23
:
return
'按照如下格式输入:AppId|SecretId|SecretKey'
;
default
:
return
'请输入渠道对应的鉴权密钥'
;
}
...
...
@@ -78,6 +80,9 @@ const EditChannel = () => {
case
19
:
localModels
=
[
'360GPT_S2_V9'
,
'embedding-bert-512-v1'
,
'embedding_s1_v1'
,
'semantic_similarity_s1_v1'
];
break
;
case
23
:
localModels
=
[
'hunyuan'
];
break
;
}
setInputs
((
inputs
)
=>
({
...
inputs
,
models
:
localModels
}));
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment