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
c6a9df67
authored
Jun 16, 2025
by
creamlike1024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: auto分组
parent
c4e65246
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
244 additions
and
57 deletions
+244
-57
controller/group.go
+8
-1
controller/misc.go
+40
-39
controller/model.go
+16
-2
controller/playground.go
+4
-3
controller/relay.go
+2
-2
controller/user.go
+3
-0
middleware/distributor.go
+11
-4
model/cache.go
+37
-1
model/option.go
+6
-0
relay/helper/price.go
+11
-1
service/quota.go
+27
-3
setting/auto_group.go
+31
-0
setting/user_usable_group.go
+7
-0
web/src/components/settings/OperationSetting.js
+5
-1
web/src/pages/Setting/Operation/GroupRatioSettings.js
+36
-0
web/src/pages/Token/EditToken.js
+0
-0
No files found.
controller/group.go
View file @
c6a9df67
package
controller
package
controller
import
(
import
(
"github.com/gin-gonic/gin"
"net/http"
"net/http"
"one-api/model"
"one-api/model"
"one-api/setting"
"one-api/setting"
"github.com/gin-gonic/gin"
)
)
func
GetGroups
(
c
*
gin
.
Context
)
{
func
GetGroups
(
c
*
gin
.
Context
)
{
...
@@ -34,6 +35,12 @@ func GetUserGroups(c *gin.Context) {
...
@@ -34,6 +35,12 @@ func GetUserGroups(c *gin.Context) {
}
}
}
}
}
}
if
setting
.
GroupInUserUsableGroups
(
"auto"
)
{
usableGroups
[
"auto"
]
=
map
[
string
]
interface
{}{
"ratio"
:
"自动"
,
"desc"
:
setting
.
GetUsableGroupDescription
(
"auto"
),
}
}
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
true
,
"success"
:
true
,
"message"
:
""
,
"message"
:
""
,
...
...
controller/misc.go
View file @
c6a9df67
...
@@ -9,9 +9,9 @@ import (
...
@@ -9,9 +9,9 @@ import (
"one-api/middleware"
"one-api/middleware"
"one-api/model"
"one-api/model"
"one-api/setting"
"one-api/setting"
"one-api/setting/console_setting"
"one-api/setting/operation_setting"
"one-api/setting/operation_setting"
"one-api/setting/system_setting"
"one-api/setting/system_setting"
"one-api/setting/console_setting"
"strings"
"strings"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin"
...
@@ -41,46 +41,47 @@ func GetStatus(c *gin.Context) {
...
@@ -41,46 +41,47 @@ func GetStatus(c *gin.Context) {
cs
:=
console_setting
.
GetConsoleSetting
()
cs
:=
console_setting
.
GetConsoleSetting
()
data
:=
gin
.
H
{
data
:=
gin
.
H
{
"version"
:
common
.
Version
,
"version"
:
common
.
Version
,
"start_time"
:
common
.
StartTime
,
"start_time"
:
common
.
StartTime
,
"email_verification"
:
common
.
EmailVerificationEnabled
,
"email_verification"
:
common
.
EmailVerificationEnabled
,
"github_oauth"
:
common
.
GitHubOAuthEnabled
,
"github_oauth"
:
common
.
GitHubOAuthEnabled
,
"github_client_id"
:
common
.
GitHubClientId
,
"github_client_id"
:
common
.
GitHubClientId
,
"linuxdo_oauth"
:
common
.
LinuxDOOAuthEnabled
,
"linuxdo_oauth"
:
common
.
LinuxDOOAuthEnabled
,
"linuxdo_client_id"
:
common
.
LinuxDOClientId
,
"linuxdo_client_id"
:
common
.
LinuxDOClientId
,
"telegram_oauth"
:
common
.
TelegramOAuthEnabled
,
"telegram_oauth"
:
common
.
TelegramOAuthEnabled
,
"telegram_bot_name"
:
common
.
TelegramBotName
,
"telegram_bot_name"
:
common
.
TelegramBotName
,
"system_name"
:
common
.
SystemName
,
"system_name"
:
common
.
SystemName
,
"logo"
:
common
.
Logo
,
"logo"
:
common
.
Logo
,
"footer_html"
:
common
.
Footer
,
"footer_html"
:
common
.
Footer
,
"wechat_qrcode"
:
common
.
WeChatAccountQRCodeImageURL
,
"wechat_qrcode"
:
common
.
WeChatAccountQRCodeImageURL
,
"wechat_login"
:
common
.
WeChatAuthEnabled
,
"wechat_login"
:
common
.
WeChatAuthEnabled
,
"server_address"
:
setting
.
ServerAddress
,
"server_address"
:
setting
.
ServerAddress
,
"price"
:
setting
.
Price
,
"price"
:
setting
.
Price
,
"min_topup"
:
setting
.
MinTopUp
,
"min_topup"
:
setting
.
MinTopUp
,
"turnstile_check"
:
common
.
TurnstileCheckEnabled
,
"turnstile_check"
:
common
.
TurnstileCheckEnabled
,
"turnstile_site_key"
:
common
.
TurnstileSiteKey
,
"turnstile_site_key"
:
common
.
TurnstileSiteKey
,
"top_up_link"
:
common
.
TopUpLink
,
"top_up_link"
:
common
.
TopUpLink
,
"docs_link"
:
operation_setting
.
GetGeneralSetting
()
.
DocsLink
,
"docs_link"
:
operation_setting
.
GetGeneralSetting
()
.
DocsLink
,
"quota_per_unit"
:
common
.
QuotaPerUnit
,
"quota_per_unit"
:
common
.
QuotaPerUnit
,
"display_in_currency"
:
common
.
DisplayInCurrencyEnabled
,
"display_in_currency"
:
common
.
DisplayInCurrencyEnabled
,
"enable_batch_update"
:
common
.
BatchUpdateEnabled
,
"enable_batch_update"
:
common
.
BatchUpdateEnabled
,
"enable_drawing"
:
common
.
DrawingEnabled
,
"enable_drawing"
:
common
.
DrawingEnabled
,
"enable_task"
:
common
.
TaskEnabled
,
"enable_task"
:
common
.
TaskEnabled
,
"enable_data_export"
:
common
.
DataExportEnabled
,
"enable_data_export"
:
common
.
DataExportEnabled
,
"data_export_default_time"
:
common
.
DataExportDefaultTime
,
"data_export_default_time"
:
common
.
DataExportDefaultTime
,
"default_collapse_sidebar"
:
common
.
DefaultCollapseSidebar
,
"default_collapse_sidebar"
:
common
.
DefaultCollapseSidebar
,
"enable_online_topup"
:
setting
.
PayAddress
!=
""
&&
setting
.
EpayId
!=
""
&&
setting
.
EpayKey
!=
""
,
"enable_online_topup"
:
setting
.
PayAddress
!=
""
&&
setting
.
EpayId
!=
""
&&
setting
.
EpayKey
!=
""
,
"mj_notify_enabled"
:
setting
.
MjNotifyEnabled
,
"mj_notify_enabled"
:
setting
.
MjNotifyEnabled
,
"chats"
:
setting
.
Chats
,
"chats"
:
setting
.
Chats
,
"demo_site_enabled"
:
operation_setting
.
DemoSiteEnabled
,
"demo_site_enabled"
:
operation_setting
.
DemoSiteEnabled
,
"self_use_mode_enabled"
:
operation_setting
.
SelfUseModeEnabled
,
"self_use_mode_enabled"
:
operation_setting
.
SelfUseModeEnabled
,
"default_use_auto_group"
:
setting
.
DefaultUseAutoGroup
,
// 面板启用开关
// 面板启用开关
"api_info_enabled"
:
cs
.
ApiInfoEnabled
,
"api_info_enabled"
:
cs
.
ApiInfoEnabled
,
"uptime_kuma_enabled"
:
cs
.
UptimeKumaEnabled
,
"uptime_kuma_enabled"
:
cs
.
UptimeKumaEnabled
,
"announcements_enabled"
:
cs
.
AnnouncementsEnabled
,
"announcements_enabled"
:
cs
.
AnnouncementsEnabled
,
"faq_enabled"
:
cs
.
FAQEnabled
,
"faq_enabled"
:
cs
.
FAQEnabled
,
"oidc_enabled"
:
system_setting
.
GetOIDCSettings
()
.
Enabled
,
"oidc_enabled"
:
system_setting
.
GetOIDCSettings
()
.
Enabled
,
"oidc_client_id"
:
system_setting
.
GetOIDCSettings
()
.
ClientId
,
"oidc_client_id"
:
system_setting
.
GetOIDCSettings
()
.
ClientId
,
...
...
controller/model.go
View file @
c6a9df67
...
@@ -2,7 +2,6 @@ package controller
...
@@ -2,7 +2,6 @@ package controller
import
(
import
(
"fmt"
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"net/http"
"one-api/common"
"one-api/common"
"one-api/constant"
"one-api/constant"
...
@@ -15,6 +14,9 @@ import (
...
@@ -15,6 +14,9 @@ import (
"one-api/relay/channel/moonshot"
"one-api/relay/channel/moonshot"
relaycommon
"one-api/relay/common"
relaycommon
"one-api/relay/common"
relayconstant
"one-api/relay/constant"
relayconstant
"one-api/relay/constant"
"one-api/setting"
"github.com/gin-gonic/gin"
)
)
// https://platform.openai.com/docs/api-reference/models/list
// https://platform.openai.com/docs/api-reference/models/list
...
@@ -179,7 +181,19 @@ func ListModels(c *gin.Context) {
...
@@ -179,7 +181,19 @@ func ListModels(c *gin.Context) {
if
tokenGroup
!=
""
{
if
tokenGroup
!=
""
{
group
=
tokenGroup
group
=
tokenGroup
}
}
models
:=
model
.
GetGroupModels
(
group
)
var
models
[]
string
if
tokenGroup
==
"auto"
{
for
_
,
autoGroup
:=
range
setting
.
AutoGroups
{
groupModels
:=
model
.
GetGroupModels
(
autoGroup
)
for
_
,
g
:=
range
groupModels
{
if
!
common
.
StringsContains
(
models
,
g
)
{
models
=
append
(
models
,
g
)
}
}
}
}
else
{
models
=
model
.
GetGroupModels
(
group
)
}
for
_
,
s
:=
range
models
{
for
_
,
s
:=
range
models
{
if
_
,
ok
:=
openAIModelsMap
[
s
];
ok
{
if
_
,
ok
:=
openAIModelsMap
[
s
];
ok
{
userOpenAiModels
=
append
(
userOpenAiModels
,
openAIModelsMap
[
s
])
userOpenAiModels
=
append
(
userOpenAiModels
,
openAIModelsMap
[
s
])
...
...
controller/playground.go
View file @
c6a9df67
...
@@ -3,7 +3,6 @@ package controller
...
@@ -3,7 +3,6 @@ package controller
import
(
import
(
"errors"
"errors"
"fmt"
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"net/http"
"one-api/common"
"one-api/common"
"one-api/constant"
"one-api/constant"
...
@@ -13,6 +12,8 @@ import (
...
@@ -13,6 +12,8 @@ import (
"one-api/service"
"one-api/service"
"one-api/setting"
"one-api/setting"
"time"
"time"
"github.com/gin-gonic/gin"
)
)
func
Playground
(
c
*
gin
.
Context
)
{
func
Playground
(
c
*
gin
.
Context
)
{
...
@@ -57,9 +58,9 @@ func Playground(c *gin.Context) {
...
@@ -57,9 +58,9 @@ func Playground(c *gin.Context) {
c
.
Set
(
"group"
,
group
)
c
.
Set
(
"group"
,
group
)
}
}
c
.
Set
(
"token_name"
,
"playground-"
+
group
)
c
.
Set
(
"token_name"
,
"playground-"
+
group
)
channel
,
err
:=
model
.
CacheGetRandomSatisfiedChannel
(
group
,
playgroundRequest
.
Model
,
0
)
channel
,
finalGroup
,
err
:=
model
.
CacheGetRandomSatisfiedChannel
(
c
,
group
,
playgroundRequest
.
Model
,
0
)
if
err
!=
nil
{
if
err
!=
nil
{
message
:=
fmt
.
Sprintf
(
"当前分组 %s 下对于模型 %s 无可用渠道"
,
g
roup
,
playgroundRequest
.
Model
)
message
:=
fmt
.
Sprintf
(
"当前分组 %s 下对于模型 %s 无可用渠道"
,
finalG
roup
,
playgroundRequest
.
Model
)
openaiErr
=
service
.
OpenAIErrorWrapperLocal
(
errors
.
New
(
message
),
"get_playground_channel_failed"
,
http
.
StatusInternalServerError
)
openaiErr
=
service
.
OpenAIErrorWrapperLocal
(
errors
.
New
(
message
),
"get_playground_channel_failed"
,
http
.
StatusInternalServerError
)
return
return
}
}
...
...
controller/relay.go
View file @
c6a9df67
...
@@ -259,7 +259,7 @@ func getChannel(c *gin.Context, group, originalModel string, retryCount int) (*m
...
@@ -259,7 +259,7 @@ func getChannel(c *gin.Context, group, originalModel string, retryCount int) (*m
AutoBan
:
&
autoBanInt
,
AutoBan
:
&
autoBanInt
,
},
nil
},
nil
}
}
channel
,
err
:=
model
.
CacheGetRandomSatisfiedChannel
(
group
,
originalModel
,
retryCount
)
channel
,
_
,
err
:=
model
.
CacheGetRandomSatisfiedChannel
(
c
,
group
,
originalModel
,
retryCount
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
errors
.
New
(
fmt
.
Sprintf
(
"获取重试渠道失败: %s"
,
err
.
Error
()))
return
nil
,
errors
.
New
(
fmt
.
Sprintf
(
"获取重试渠道失败: %s"
,
err
.
Error
()))
}
}
...
@@ -388,7 +388,7 @@ func RelayTask(c *gin.Context) {
...
@@ -388,7 +388,7 @@ func RelayTask(c *gin.Context) {
retryTimes
=
0
retryTimes
=
0
}
}
for
i
:=
0
;
shouldRetryTaskRelay
(
c
,
channelId
,
taskErr
,
retryTimes
)
&&
i
<
retryTimes
;
i
++
{
for
i
:=
0
;
shouldRetryTaskRelay
(
c
,
channelId
,
taskErr
,
retryTimes
)
&&
i
<
retryTimes
;
i
++
{
channel
,
err
:=
model
.
CacheGetRandomSatisfiedChannel
(
group
,
originalModel
,
i
)
channel
,
_
,
err
:=
model
.
CacheGetRandomSatisfiedChannel
(
c
,
group
,
originalModel
,
i
)
if
err
!=
nil
{
if
err
!=
nil
{
common
.
LogError
(
c
,
fmt
.
Sprintf
(
"CacheGetRandomSatisfiedChannel failed: %s"
,
err
.
Error
()))
common
.
LogError
(
c
,
fmt
.
Sprintf
(
"CacheGetRandomSatisfiedChannel failed: %s"
,
err
.
Error
()))
break
break
...
...
controller/user.go
View file @
c6a9df67
...
@@ -226,6 +226,9 @@ func Register(c *gin.Context) {
...
@@ -226,6 +226,9 @@ func Register(c *gin.Context) {
UnlimitedQuota
:
true
,
UnlimitedQuota
:
true
,
ModelLimitsEnabled
:
false
,
ModelLimitsEnabled
:
false
,
}
}
if
setting
.
DefaultUseAutoGroup
{
token
.
Group
=
"auto"
}
if
err
:=
token
.
Insert
();
err
!=
nil
{
if
err
:=
token
.
Insert
();
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"success"
:
false
,
...
...
middleware/distributor.go
View file @
c6a9df67
...
@@ -49,8 +49,10 @@ func Distribute() func(c *gin.Context) {
...
@@ -49,8 +49,10 @@ func Distribute() func(c *gin.Context) {
}
}
// check group in common.GroupRatio
// check group in common.GroupRatio
if
!
setting
.
ContainsGroupRatio
(
tokenGroup
)
{
if
!
setting
.
ContainsGroupRatio
(
tokenGroup
)
{
abortWithOpenAiMessage
(
c
,
http
.
StatusForbidden
,
fmt
.
Sprintf
(
"分组 %s 已被弃用"
,
tokenGroup
))
if
tokenGroup
!=
"auto"
{
return
abortWithOpenAiMessage
(
c
,
http
.
StatusForbidden
,
fmt
.
Sprintf
(
"分组 %s 已被弃用"
,
tokenGroup
))
return
}
}
}
userGroup
=
tokenGroup
userGroup
=
tokenGroup
}
}
...
@@ -95,9 +97,14 @@ func Distribute() func(c *gin.Context) {
...
@@ -95,9 +97,14 @@ func Distribute() func(c *gin.Context) {
}
}
if
shouldSelectChannel
{
if
shouldSelectChannel
{
channel
,
err
=
model
.
CacheGetRandomSatisfiedChannel
(
userGroup
,
modelRequest
.
Model
,
0
)
var
selectGroup
string
channel
,
selectGroup
,
err
=
model
.
CacheGetRandomSatisfiedChannel
(
c
,
userGroup
,
modelRequest
.
Model
,
0
)
if
err
!=
nil
{
if
err
!=
nil
{
message
:=
fmt
.
Sprintf
(
"当前分组 %s 下对于模型 %s 无可用渠道"
,
userGroup
,
modelRequest
.
Model
)
showGroup
:=
userGroup
if
userGroup
==
"auto"
{
showGroup
=
fmt
.
Sprintf
(
"auto(%s)"
,
selectGroup
)
}
message
:=
fmt
.
Sprintf
(
"当前分组 %s 下对于模型 %s 无可用渠道"
,
showGroup
,
modelRequest
.
Model
)
// 如果错误,但是渠道不为空,说明是数据库一致性问题
// 如果错误,但是渠道不为空,说明是数据库一致性问题
if
channel
!=
nil
{
if
channel
!=
nil
{
common
.
SysError
(
fmt
.
Sprintf
(
"渠道不存在:%d"
,
channel
.
Id
))
common
.
SysError
(
fmt
.
Sprintf
(
"渠道不存在:%d"
,
channel
.
Id
))
...
...
model/cache.go
View file @
c6a9df67
...
@@ -3,12 +3,16 @@ package model
...
@@ -3,12 +3,16 @@ package model
import
(
import
(
"errors"
"errors"
"fmt"
"fmt"
"log"
"math/rand"
"math/rand"
"one-api/common"
"one-api/common"
"one-api/setting"
"sort"
"sort"
"strings"
"strings"
"sync"
"sync"
"time"
"time"
"github.com/gin-gonic/gin"
)
)
var
group2model2channels
map
[
string
]
map
[
string
][]
*
Channel
var
group2model2channels
map
[
string
]
map
[
string
][]
*
Channel
...
@@ -75,7 +79,39 @@ func SyncChannelCache(frequency int) {
...
@@ -75,7 +79,39 @@ func SyncChannelCache(frequency int) {
}
}
}
}
func
CacheGetRandomSatisfiedChannel
(
group
string
,
model
string
,
retry
int
)
(
*
Channel
,
error
)
{
func
CacheGetRandomSatisfiedChannel
(
c
*
gin
.
Context
,
group
string
,
model
string
,
retry
int
)
(
*
Channel
,
string
,
error
)
{
var
channel
*
Channel
var
err
error
selectGroup
:=
group
if
group
==
"auto"
{
if
len
(
setting
.
AutoGroups
)
==
0
{
return
nil
,
selectGroup
,
errors
.
New
(
"auto groups is not enabled"
)
}
for
_
,
autoGroup
:=
range
setting
.
AutoGroups
{
log
.
Printf
(
"autoGroup: %s"
,
autoGroup
)
channel
,
_
=
getRandomSatisfiedChannel
(
autoGroup
,
model
,
retry
)
if
channel
==
nil
{
continue
}
else
{
c
.
Set
(
"auto_group"
,
autoGroup
)
selectGroup
=
autoGroup
log
.
Printf
(
"selectGroup: %s"
,
selectGroup
)
break
}
}
}
else
{
channel
,
err
=
getRandomSatisfiedChannel
(
group
,
model
,
retry
)
if
err
!=
nil
{
return
nil
,
group
,
err
}
}
if
channel
==
nil
{
return
nil
,
group
,
errors
.
New
(
"channel not found"
)
}
return
channel
,
selectGroup
,
nil
}
func
getRandomSatisfiedChannel
(
group
string
,
model
string
,
retry
int
)
(
*
Channel
,
error
)
{
if
strings
.
HasPrefix
(
model
,
"gpt-4-gizmo"
)
{
if
strings
.
HasPrefix
(
model
,
"gpt-4-gizmo"
)
{
model
=
"gpt-4-gizmo-*"
model
=
"gpt-4-gizmo-*"
}
}
...
...
model/option.go
View file @
c6a9df67
...
@@ -76,6 +76,8 @@ func InitOptionMap() {
...
@@ -76,6 +76,8 @@ func InitOptionMap() {
common
.
OptionMap
[
"MinTopUp"
]
=
strconv
.
Itoa
(
setting
.
MinTopUp
)
common
.
OptionMap
[
"MinTopUp"
]
=
strconv
.
Itoa
(
setting
.
MinTopUp
)
common
.
OptionMap
[
"TopupGroupRatio"
]
=
common
.
TopupGroupRatio2JSONString
()
common
.
OptionMap
[
"TopupGroupRatio"
]
=
common
.
TopupGroupRatio2JSONString
()
common
.
OptionMap
[
"Chats"
]
=
setting
.
Chats2JsonString
()
common
.
OptionMap
[
"Chats"
]
=
setting
.
Chats2JsonString
()
common
.
OptionMap
[
"AutoGroups"
]
=
setting
.
AutoGroups2JsonString
()
common
.
OptionMap
[
"DefaultUseAutoGroup"
]
=
strconv
.
FormatBool
(
setting
.
DefaultUseAutoGroup
)
common
.
OptionMap
[
"GitHubClientId"
]
=
""
common
.
OptionMap
[
"GitHubClientId"
]
=
""
common
.
OptionMap
[
"GitHubClientSecret"
]
=
""
common
.
OptionMap
[
"GitHubClientSecret"
]
=
""
common
.
OptionMap
[
"TelegramBotToken"
]
=
""
common
.
OptionMap
[
"TelegramBotToken"
]
=
""
...
@@ -287,6 +289,10 @@ func updateOptionMap(key string, value string) (err error) {
...
@@ -287,6 +289,10 @@ func updateOptionMap(key string, value string) (err error) {
setting
.
PayAddress
=
value
setting
.
PayAddress
=
value
case
"Chats"
:
case
"Chats"
:
err
=
setting
.
UpdateChatsByJsonString
(
value
)
err
=
setting
.
UpdateChatsByJsonString
(
value
)
case
"AutoGroups"
:
err
=
setting
.
UpdateAutoGroupsByJsonString
(
value
)
case
"DefaultUseAutoGroup"
:
setting
.
DefaultUseAutoGroup
=
value
==
"true"
case
"CustomCallbackAddress"
:
case
"CustomCallbackAddress"
:
setting
.
CustomCallbackAddress
=
value
setting
.
CustomCallbackAddress
=
value
case
"EpayId"
:
case
"EpayId"
:
...
...
relay/helper/price.go
View file @
c6a9df67
...
@@ -2,6 +2,7 @@ package helper
...
@@ -2,6 +2,7 @@ package helper
import
(
import
(
"fmt"
"fmt"
"log"
"one-api/common"
"one-api/common"
constant2
"one-api/constant"
constant2
"one-api/constant"
relaycommon
"one-api/relay/common"
relaycommon
"one-api/relay/common"
...
@@ -31,10 +32,19 @@ func (p PriceData) ToSetting() string {
...
@@ -31,10 +32,19 @@ func (p PriceData) ToSetting() string {
func
ModelPriceHelper
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
promptTokens
int
,
maxTokens
int
)
(
PriceData
,
error
)
{
func
ModelPriceHelper
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
promptTokens
int
,
maxTokens
int
)
(
PriceData
,
error
)
{
modelPrice
,
usePrice
:=
operation_setting
.
GetModelPrice
(
info
.
OriginModelName
,
false
)
modelPrice
,
usePrice
:=
operation_setting
.
GetModelPrice
(
info
.
OriginModelName
,
false
)
groupRatio
:=
setting
.
GetGroupRatio
(
info
.
Group
)
groupRatio
:=
setting
.
GetGroupRatio
(
info
.
Group
)
var
userGroupRatio
float64
autoGroup
,
exists
:=
c
.
Get
(
"auto_group"
)
if
exists
{
groupRatio
=
setting
.
GetGroupRatio
(
autoGroup
.
(
string
))
log
.
Printf
(
"final group ratio: %f"
,
groupRatio
)
info
.
Group
=
autoGroup
.
(
string
)
}
actualGroupRatio
:=
groupRatio
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
info
.
UserGroup
,
info
.
Group
)
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
info
.
UserGroup
,
info
.
Group
)
if
ok
{
if
ok
{
g
roupRatio
=
userGroupRatio
actualG
roupRatio
=
userGroupRatio
}
}
groupRatio
=
actualGroupRatio
var
preConsumedQuota
int
var
preConsumedQuota
int
var
modelRatio
float64
var
modelRatio
float64
var
completionRatio
float64
var
completionRatio
float64
...
...
service/quota.go
View file @
c6a9df67
...
@@ -3,6 +3,7 @@ package service
...
@@ -3,6 +3,7 @@ package service
import
(
import
(
"errors"
"errors"
"fmt"
"fmt"
"log"
"one-api/common"
"one-api/common"
constant2
"one-api/constant"
constant2
"one-api/constant"
"one-api/dto"
"one-api/dto"
...
@@ -94,11 +95,20 @@ func PreWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usag
...
@@ -94,11 +95,20 @@ func PreWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usag
audioInputTokens
:=
usage
.
InputTokenDetails
.
AudioTokens
audioInputTokens
:=
usage
.
InputTokenDetails
.
AudioTokens
audioOutTokens
:=
usage
.
OutputTokenDetails
.
AudioTokens
audioOutTokens
:=
usage
.
OutputTokenDetails
.
AudioTokens
groupRatio
:=
setting
.
GetGroupRatio
(
relayInfo
.
Group
)
groupRatio
:=
setting
.
GetGroupRatio
(
relayInfo
.
Group
)
modelRatio
,
_
:=
operation_setting
.
GetModelRatio
(
modelName
)
autoGroup
,
exists
:=
ctx
.
Get
(
"auto_group"
)
if
exists
{
groupRatio
=
setting
.
GetGroupRatio
(
autoGroup
.
(
string
))
log
.
Printf
(
"final group ratio: %f"
,
groupRatio
)
relayInfo
.
Group
=
autoGroup
.
(
string
)
}
actualGroupRatio
:=
groupRatio
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
if
ok
{
if
ok
{
g
roupRatio
=
userGroupRatio
actualG
roupRatio
=
userGroupRatio
}
}
modelRatio
,
_
:=
operation_setting
.
GetModelRatio
(
modelName
)
quotaInfo
:=
QuotaInfo
{
quotaInfo
:=
QuotaInfo
{
InputDetails
:
TokenDetails
{
InputDetails
:
TokenDetails
{
...
@@ -112,7 +122,7 @@ func PreWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usag
...
@@ -112,7 +122,7 @@ func PreWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usag
ModelName
:
modelName
,
ModelName
:
modelName
,
UsePrice
:
relayInfo
.
UsePrice
,
UsePrice
:
relayInfo
.
UsePrice
,
ModelRatio
:
modelRatio
,
ModelRatio
:
modelRatio
,
GroupRatio
:
g
roupRatio
,
GroupRatio
:
actualG
roupRatio
,
}
}
quota
:=
calculateAudioQuota
(
quotaInfo
)
quota
:=
calculateAudioQuota
(
quotaInfo
)
...
@@ -149,6 +159,13 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
...
@@ -149,6 +159,13 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
audioRatio
:=
decimal
.
NewFromFloat
(
operation_setting
.
GetAudioRatio
(
relayInfo
.
OriginModelName
))
audioRatio
:=
decimal
.
NewFromFloat
(
operation_setting
.
GetAudioRatio
(
relayInfo
.
OriginModelName
))
audioCompletionRatio
:=
decimal
.
NewFromFloat
(
operation_setting
.
GetAudioCompletionRatio
(
modelName
))
audioCompletionRatio
:=
decimal
.
NewFromFloat
(
operation_setting
.
GetAudioCompletionRatio
(
modelName
))
autoGroup
,
exists
:=
ctx
.
Get
(
"auto_group"
)
if
exists
{
groupRatio
=
setting
.
GetGroupRatio
(
autoGroup
.
(
string
))
log
.
Printf
(
"final group ratio: %f"
,
groupRatio
)
relayInfo
.
Group
=
autoGroup
.
(
string
)
}
actualGroupRatio
:=
groupRatio
actualGroupRatio
:=
groupRatio
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
if
ok
{
if
ok
{
...
@@ -290,6 +307,13 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
...
@@ -290,6 +307,13 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
modelPrice
:=
priceData
.
ModelPrice
modelPrice
:=
priceData
.
ModelPrice
usePrice
:=
priceData
.
UsePrice
usePrice
:=
priceData
.
UsePrice
autoGroup
,
exists
:=
ctx
.
Get
(
"auto_group"
)
if
exists
{
groupRatio
=
setting
.
GetGroupRatio
(
autoGroup
.
(
string
))
log
.
Printf
(
"final group ratio: %f"
,
groupRatio
)
relayInfo
.
Group
=
autoGroup
.
(
string
)
}
actualGroupRatio
:=
groupRatio
actualGroupRatio
:=
groupRatio
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
if
ok
{
if
ok
{
...
...
setting/auto_group.go
0 → 100644
View file @
c6a9df67
package
setting
import
"encoding/json"
var
AutoGroups
=
[]
string
{
"default"
,
}
var
DefaultUseAutoGroup
=
false
func
ContainsAutoGroup
(
group
string
)
bool
{
for
_
,
autoGroup
:=
range
AutoGroups
{
if
autoGroup
==
group
{
return
true
}
}
return
false
}
func
UpdateAutoGroupsByJsonString
(
jsonString
string
)
error
{
AutoGroups
=
make
([]
string
,
0
)
return
json
.
Unmarshal
([]
byte
(
jsonString
),
&
AutoGroups
)
}
func
AutoGroups2JsonString
()
string
{
jsonBytes
,
err
:=
json
.
Marshal
(
AutoGroups
)
if
err
!=
nil
{
return
"[]"
}
return
string
(
jsonBytes
)
}
setting/user_usable_group.go
View file @
c6a9df67
...
@@ -50,3 +50,10 @@ func GroupInUserUsableGroups(groupName string) bool {
...
@@ -50,3 +50,10 @@ func GroupInUserUsableGroups(groupName string) bool {
_
,
ok
:=
userUsableGroups
[
groupName
]
_
,
ok
:=
userUsableGroups
[
groupName
]
return
ok
return
ok
}
}
func
GetUsableGroupDescription
(
groupName
string
)
string
{
if
desc
,
ok
:=
userUsableGroups
[
groupName
];
ok
{
return
desc
}
return
groupName
}
web/src/components/settings/OperationSetting.js
View file @
c6a9df67
...
@@ -31,6 +31,8 @@ const OperationSetting = () => {
...
@@ -31,6 +31,8 @@ const OperationSetting = () => {
ModelPrice
:
''
,
ModelPrice
:
''
,
GroupRatio
:
''
,
GroupRatio
:
''
,
GroupGroupRatio
:
''
,
GroupGroupRatio
:
''
,
AutoGroups
:
''
,
DefaultUseAutoGroup
:
false
,
UserUsableGroups
:
''
,
UserUsableGroups
:
''
,
TopUpLink
:
''
,
TopUpLink
:
''
,
'general_setting.docs_link'
:
''
,
'general_setting.docs_link'
:
''
,
...
@@ -76,6 +78,7 @@ const OperationSetting = () => {
...
@@ -76,6 +78,7 @@ const OperationSetting = () => {
item
.
key
===
'ModelRatio'
||
item
.
key
===
'ModelRatio'
||
item
.
key
===
'GroupRatio'
||
item
.
key
===
'GroupRatio'
||
item
.
key
===
'GroupGroupRatio'
||
item
.
key
===
'GroupGroupRatio'
||
item
.
key
===
'AutoGroups'
||
item
.
key
===
'UserUsableGroups'
||
item
.
key
===
'UserUsableGroups'
||
item
.
key
===
'CompletionRatio'
||
item
.
key
===
'CompletionRatio'
||
item
.
key
===
'ModelPrice'
||
item
.
key
===
'ModelPrice'
||
...
@@ -85,7 +88,8 @@ const OperationSetting = () => {
...
@@ -85,7 +88,8 @@ const OperationSetting = () => {
}
}
if
(
if
(
item
.
key
.
endsWith
(
'Enabled'
)
||
item
.
key
.
endsWith
(
'Enabled'
)
||
[
'DefaultCollapseSidebar'
].
includes
(
item
.
key
)
[
'DefaultCollapseSidebar'
].
includes
(
item
.
key
)
||
[
'DefaultUseAutoGroup'
].
includes
(
item
.
key
)
)
{
)
{
newInputs
[
item
.
key
]
=
item
.
value
===
'true'
?
true
:
false
;
newInputs
[
item
.
key
]
=
item
.
value
===
'true'
?
true
:
false
;
}
else
{
}
else
{
...
...
web/src/pages/Setting/Operation/GroupRatioSettings.js
View file @
c6a9df67
...
@@ -17,6 +17,8 @@ export default function GroupRatioSettings(props) {
...
@@ -17,6 +17,8 @@ export default function GroupRatioSettings(props) {
GroupRatio
:
''
,
GroupRatio
:
''
,
UserUsableGroups
:
''
,
UserUsableGroups
:
''
,
GroupGroupRatio
:
''
,
GroupGroupRatio
:
''
,
AutoGroups
:
''
,
DefaultUseAutoGroup
:
false
,
});
});
const
refForm
=
useRef
();
const
refForm
=
useRef
();
const
[
inputsRow
,
setInputsRow
]
=
useState
(
inputs
);
const
[
inputsRow
,
setInputsRow
]
=
useState
(
inputs
);
...
@@ -167,6 +169,40 @@ export default function GroupRatioSettings(props) {
...
@@ -167,6 +169,40 @@ export default function GroupRatioSettings(props) {
/
>
/
>
<
/Col
>
<
/Col
>
<
/Row
>
<
/Row
>
<
Row
gutter
=
{
16
}
>
<
Col
xs
=
{
24
}
sm
=
{
16
}
>
<
Form
.
TextArea
label
=
{
t
(
'自动分组auto,从第一个开始选择'
)}
placeholder
=
{
t
(
'为一个 JSON 文本'
)}
field
=
{
'AutoGroups'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
stopValidateWithError
rules
=
{[
{
validator
:
(
rule
,
value
)
=>
verifyJSON
(
value
),
message
:
t
(
'不是合法的 JSON 字符串'
),
},
]}
onChange
=
{(
value
)
=>
setInputs
({
...
inputs
,
AutoGroups
:
value
})
}
/
>
<
/Col
>
<
/Row
>
<
Row
gutter
=
{
16
}
>
<
Col
span
=
{
16
}
>
<
Form
.
Switch
label
=
{
t
(
'创建令牌默认选择auto分组,初始令牌也将设为auto(否则留空,为用户默认分组)'
,
)}
field
=
{
'DefaultUseAutoGroup'
}
onChange
=
{(
value
)
=>
setInputs
({
...
inputs
,
DefaultUseAutoGroup
:
value
})
}
/
>
<
/Col
>
<
/Row
>
<
/Form.Section
>
<
/Form.Section
>
<
/Form
>
<
/Form
>
<
Button
onClick
=
{
onSubmit
}
>
{
t
(
'保存分组倍率设置'
)}
<
/Button
>
<
Button
onClick
=
{
onSubmit
}
>
{
t
(
'保存分组倍率设置'
)}
<
/Button
>
...
...
web/src/pages/Token/EditToken.js
View file @
c6a9df67
This diff is collapsed.
Click to expand it.
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