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
01064fb5
authored
Jun 21, 2025
by
Apple\Apple
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/alpha' into alpha
parents
2ccae2a2
4e9d8f1c
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
69 additions
and
20 deletions
+69
-20
Dockerfile
+1
-2
controller/channel-billing.go
+38
-0
relay/channel/gemini/relay-gemini.go
+1
-2
setting/operation_setting/tools.go
+9
-3
setting/ratio_setting/model_ratio.go
+18
-11
web/src/pages/Setting/Model/SettingGeminiModel.js
+2
-2
No files found.
Dockerfile
View file @
01064fb5
...
@@ -24,8 +24,7 @@ RUN go build -ldflags "-s -w -X 'one-api/common.Version=$(cat VERSION)'" -o one-
...
@@ -24,8 +24,7 @@ RUN go build -ldflags "-s -w -X 'one-api/common.Version=$(cat VERSION)'" -o one-
FROM
alpine
FROM
alpine
RUN
apk update
\
RUN
apk upgrade
--no-cache
\
&&
apk upgrade
\
&&
apk add
--no-cache
ca-certificates tzdata ffmpeg
\
&&
apk add
--no-cache
ca-certificates tzdata ffmpeg
\
&&
update-ca-certificates
&&
update-ca-certificates
...
...
controller/channel-billing.go
View file @
01064fb5
...
@@ -4,11 +4,13 @@ import (
...
@@ -4,11 +4,13 @@ import (
"encoding/json"
"encoding/json"
"errors"
"errors"
"fmt"
"fmt"
"github.com/shopspring/decimal"
"io"
"io"
"net/http"
"net/http"
"one-api/common"
"one-api/common"
"one-api/model"
"one-api/model"
"one-api/service"
"one-api/service"
"one-api/setting"
"strconv"
"strconv"
"time"
"time"
...
@@ -304,6 +306,40 @@ func updateChannelOpenRouterBalance(channel *model.Channel) (float64, error) {
...
@@ -304,6 +306,40 @@ func updateChannelOpenRouterBalance(channel *model.Channel) (float64, error) {
return
balance
,
nil
return
balance
,
nil
}
}
func
updateChannelMoonshotBalance
(
channel
*
model
.
Channel
)
(
float64
,
error
)
{
url
:=
"https://api.moonshot.cn/v1/users/me/balance"
body
,
err
:=
GetResponseBody
(
"GET"
,
url
,
channel
,
GetAuthHeader
(
channel
.
Key
))
if
err
!=
nil
{
return
0
,
err
}
type
MoonshotBalanceData
struct
{
AvailableBalance
float64
`json:"available_balance"`
VoucherBalance
float64
`json:"voucher_balance"`
CashBalance
float64
`json:"cash_balance"`
}
type
MoonshotBalanceResponse
struct
{
Code
int
`json:"code"`
Data
MoonshotBalanceData
`json:"data"`
Scode
string
`json:"scode"`
Status
bool
`json:"status"`
}
response
:=
MoonshotBalanceResponse
{}
err
=
json
.
Unmarshal
(
body
,
&
response
)
if
err
!=
nil
{
return
0
,
err
}
if
!
response
.
Status
||
response
.
Code
!=
0
{
return
0
,
fmt
.
Errorf
(
"failed to update moonshot balance, status: %v, code: %d, scode: %s"
,
response
.
Status
,
response
.
Code
,
response
.
Scode
)
}
availableBalanceCny
:=
response
.
Data
.
AvailableBalance
availableBalanceUsd
:=
decimal
.
NewFromFloat
(
availableBalanceCny
)
.
Div
(
decimal
.
NewFromFloat
(
setting
.
Price
))
.
InexactFloat64
()
channel
.
UpdateBalance
(
availableBalanceUsd
)
return
availableBalanceUsd
,
nil
}
func
updateChannelBalance
(
channel
*
model
.
Channel
)
(
float64
,
error
)
{
func
updateChannelBalance
(
channel
*
model
.
Channel
)
(
float64
,
error
)
{
baseURL
:=
common
.
ChannelBaseURLs
[
channel
.
Type
]
baseURL
:=
common
.
ChannelBaseURLs
[
channel
.
Type
]
if
channel
.
GetBaseURL
()
==
""
{
if
channel
.
GetBaseURL
()
==
""
{
...
@@ -332,6 +368,8 @@ func updateChannelBalance(channel *model.Channel) (float64, error) {
...
@@ -332,6 +368,8 @@ func updateChannelBalance(channel *model.Channel) (float64, error) {
return
updateChannelDeepSeekBalance
(
channel
)
return
updateChannelDeepSeekBalance
(
channel
)
case
common
.
ChannelTypeOpenRouter
:
case
common
.
ChannelTypeOpenRouter
:
return
updateChannelOpenRouterBalance
(
channel
)
return
updateChannelOpenRouterBalance
(
channel
)
case
common
.
ChannelTypeMoonshot
:
return
updateChannelMoonshotBalance
(
channel
)
default
:
default
:
return
0
,
errors
.
New
(
"尚未实现"
)
return
0
,
errors
.
New
(
"尚未实现"
)
}
}
...
...
relay/channel/gemini/relay-gemini.go
View file @
01064fb5
...
@@ -103,7 +103,6 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest, info *relaycommon
...
@@ -103,7 +103,6 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest, info *relaycommon
isNew25Pro
:=
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-pro"
)
&&
isNew25Pro
:=
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-pro"
)
&&
!
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-pro-preview-05-06"
)
&&
!
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-pro-preview-05-06"
)
&&
!
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-pro-preview-03-25"
)
!
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-pro-preview-03-25"
)
is25FlashLite
:=
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-flash-lite"
)
if
strings
.
Contains
(
modelName
,
"-thinking-"
)
{
if
strings
.
Contains
(
modelName
,
"-thinking-"
)
{
parts
:=
strings
.
SplitN
(
modelName
,
"-thinking-"
,
2
)
parts
:=
strings
.
SplitN
(
modelName
,
"-thinking-"
,
2
)
...
@@ -142,7 +141,7 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest, info *relaycommon
...
@@ -142,7 +141,7 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest, info *relaycommon
}
}
}
}
}
else
if
strings
.
HasSuffix
(
modelName
,
"-nothinking"
)
{
}
else
if
strings
.
HasSuffix
(
modelName
,
"-nothinking"
)
{
if
!
isNew25Pro
&&
!
is25FlashLite
{
if
!
isNew25Pro
{
geminiRequest
.
GenerationConfig
.
ThinkingConfig
=
&
GeminiThinkingConfig
{
geminiRequest
.
GenerationConfig
.
ThinkingConfig
=
&
GeminiThinkingConfig
{
ThinkingBudget
:
common
.
GetPointer
(
0
),
ThinkingBudget
:
common
.
GetPointer
(
0
),
}
}
...
...
setting/operation_setting/tools.go
View file @
01064fb5
...
@@ -17,6 +17,8 @@ const (
...
@@ -17,6 +17,8 @@ const (
const
(
const
(
// Gemini Audio Input Price
// Gemini Audio Input Price
Gemini25FlashPreviewInputAudioPrice
=
1.00
Gemini25FlashPreviewInputAudioPrice
=
1.00
Gemini25FlashProductionInputAudioPrice
=
1.00
// for `gemini-2.5-flash`
Gemini25FlashLitePreviewInputAudioPrice
=
0.50
Gemini25FlashNativeAudioInputAudioPrice
=
3.00
Gemini25FlashNativeAudioInputAudioPrice
=
3.00
Gemini20FlashInputAudioPrice
=
0.70
Gemini20FlashInputAudioPrice
=
0.70
)
)
...
@@ -64,10 +66,14 @@ func GetFileSearchPricePerThousand() float64 {
...
@@ -64,10 +66,14 @@ func GetFileSearchPricePerThousand() float64 {
}
}
func
GetGeminiInputAudioPricePerMillionTokens
(
modelName
string
)
float64
{
func
GetGeminiInputAudioPricePerMillionTokens
(
modelName
string
)
float64
{
if
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-flash-preview"
)
{
if
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-flash-preview-native-audio"
)
{
return
Gemini25FlashPreviewInputAudioPrice
}
else
if
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-flash-preview-native-audio"
)
{
return
Gemini25FlashNativeAudioInputAudioPrice
return
Gemini25FlashNativeAudioInputAudioPrice
}
else
if
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-flash-preview-lite"
)
{
return
Gemini25FlashLitePreviewInputAudioPrice
}
else
if
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-flash-preview"
)
{
return
Gemini25FlashPreviewInputAudioPrice
}
else
if
strings
.
HasPrefix
(
modelName
,
"gemini-2.5-flash"
)
{
return
Gemini25FlashProductionInputAudioPrice
}
else
if
strings
.
HasPrefix
(
modelName
,
"gemini-2.0-flash"
)
{
}
else
if
strings
.
HasPrefix
(
modelName
,
"gemini-2.0-flash"
)
{
return
Gemini20FlashInputAudioPrice
return
Gemini20FlashInputAudioPrice
}
}
...
...
setting/ratio_setting/model_ratio.go
View file @
01064fb5
...
@@ -140,6 +140,7 @@ var defaultModelRatio = map[string]float64{
...
@@ -140,6 +140,7 @@ var defaultModelRatio = map[string]float64{
"gemini-2.0-flash"
:
0.05
,
"gemini-2.0-flash"
:
0.05
,
"gemini-2.5-pro-exp-03-25"
:
0.625
,
"gemini-2.5-pro-exp-03-25"
:
0.625
,
"gemini-2.5-pro-preview-03-25"
:
0.625
,
"gemini-2.5-pro-preview-03-25"
:
0.625
,
"gemini-2.5-pro"
:
0.625
,
"gemini-2.5-flash-preview-04-17"
:
0.075
,
"gemini-2.5-flash-preview-04-17"
:
0.075
,
"gemini-2.5-flash-preview-04-17-thinking"
:
0.075
,
"gemini-2.5-flash-preview-04-17-thinking"
:
0.075
,
"gemini-2.5-flash-preview-04-17-nothinking"
:
0.075
,
"gemini-2.5-flash-preview-04-17-nothinking"
:
0.075
,
...
@@ -148,6 +149,8 @@ var defaultModelRatio = map[string]float64{
...
@@ -148,6 +149,8 @@ var defaultModelRatio = map[string]float64{
"gemini-2.5-flash-preview-05-20-nothinking"
:
0.075
,
"gemini-2.5-flash-preview-05-20-nothinking"
:
0.075
,
"gemini-2.5-flash-thinking-*"
:
0.075
,
// 用于为后续所有2.5 flash thinking budget 模型设置默认倍率
"gemini-2.5-flash-thinking-*"
:
0.075
,
// 用于为后续所有2.5 flash thinking budget 模型设置默认倍率
"gemini-2.5-pro-thinking-*"
:
0.625
,
// 用于为后续所有2.5 pro thinking budget 模型设置默认倍率
"gemini-2.5-pro-thinking-*"
:
0.625
,
// 用于为后续所有2.5 pro thinking budget 模型设置默认倍率
"gemini-2.5-flash-lite-preview-06-17"
:
0.05
,
"gemini-2.5-flash"
:
0.15
,
"text-embedding-004"
:
0.001
,
"text-embedding-004"
:
0.001
,
"chatglm_turbo"
:
0.3572
,
// ¥0.005 / 1k tokens
"chatglm_turbo"
:
0.3572
,
// ¥0.005 / 1k tokens
"chatglm_pro"
:
0.7143
,
// ¥0.01 / 1k tokens
"chatglm_pro"
:
0.7143
,
// ¥0.01 / 1k tokens
...
@@ -423,7 +426,12 @@ func UpdateCompletionRatioByJSONString(jsonStr string) error {
...
@@ -423,7 +426,12 @@ func UpdateCompletionRatioByJSONString(jsonStr string) error {
func
GetCompletionRatio
(
name
string
)
float64
{
func
GetCompletionRatio
(
name
string
)
float64
{
CompletionRatioMutex
.
RLock
()
CompletionRatioMutex
.
RLock
()
defer
CompletionRatioMutex
.
RUnlock
()
defer
CompletionRatioMutex
.
RUnlock
()
if
strings
.
HasPrefix
(
name
,
"gpt-4-gizmo"
)
{
name
=
"gpt-4-gizmo-*"
}
if
strings
.
HasPrefix
(
name
,
"gpt-4o-gizmo"
)
{
name
=
"gpt-4o-gizmo-*"
}
if
strings
.
Contains
(
name
,
"/"
)
{
if
strings
.
Contains
(
name
,
"/"
)
{
if
ratio
,
ok
:=
CompletionRatio
[
name
];
ok
{
if
ratio
,
ok
:=
CompletionRatio
[
name
];
ok
{
return
ratio
return
ratio
...
@@ -441,12 +449,6 @@ func GetCompletionRatio(name string) float64 {
...
@@ -441,12 +449,6 @@ func GetCompletionRatio(name string) float64 {
func
getHardcodedCompletionModelRatio
(
name
string
)
(
float64
,
bool
)
{
func
getHardcodedCompletionModelRatio
(
name
string
)
(
float64
,
bool
)
{
lowercaseName
:=
strings
.
ToLower
(
name
)
lowercaseName
:=
strings
.
ToLower
(
name
)
if
strings
.
HasPrefix
(
name
,
"gpt-4-gizmo"
)
{
name
=
"gpt-4-gizmo-*"
}
if
strings
.
HasPrefix
(
name
,
"gpt-4o-gizmo"
)
{
name
=
"gpt-4o-gizmo-*"
}
if
strings
.
HasPrefix
(
name
,
"gpt-4"
)
&&
!
strings
.
HasSuffix
(
name
,
"-all"
)
&&
!
strings
.
HasSuffix
(
name
,
"-gizmo-*"
)
{
if
strings
.
HasPrefix
(
name
,
"gpt-4"
)
&&
!
strings
.
HasSuffix
(
name
,
"-all"
)
&&
!
strings
.
HasSuffix
(
name
,
"-gizmo-*"
)
{
if
strings
.
HasPrefix
(
name
,
"gpt-4o"
)
{
if
strings
.
HasPrefix
(
name
,
"gpt-4o"
)
{
if
name
==
"gpt-4o-2024-05-13"
{
if
name
==
"gpt-4o-2024-05-13"
{
...
@@ -500,12 +502,17 @@ func getHardcodedCompletionModelRatio(name string) (float64, bool) {
...
@@ -500,12 +502,17 @@ func getHardcodedCompletionModelRatio(name string) (float64, bool) {
return
4
,
true
return
4
,
true
}
else
if
strings
.
HasPrefix
(
name
,
"gemini-2.5-pro"
)
{
// 移除preview来增加兼容性,这里假设正式版的倍率和preview一致
}
else
if
strings
.
HasPrefix
(
name
,
"gemini-2.5-pro"
)
{
// 移除preview来增加兼容性,这里假设正式版的倍率和preview一致
return
8
,
true
return
8
,
true
}
else
if
strings
.
HasPrefix
(
name
,
"gemini-2.5-flash"
)
{
// 同上
}
else
if
strings
.
HasPrefix
(
name
,
"gemini-2.5-flash"
)
{
// 处理不同的flash模型倍率
if
strings
.
HasPrefix
(
name
,
"gemini-2.5-flash-preview"
)
{
if
strings
.
HasSuffix
(
name
,
"-nothinking"
)
{
if
strings
.
HasSuffix
(
name
,
"-nothinking"
)
{
return
4
,
false
return
4
,
true
}
else
{
}
return
3.5
/
0.6
,
false
return
3.5
/
0.15
,
true
}
if
strings
.
HasPrefix
(
name
,
"gemini-2.5-flash-lite-preview"
)
{
return
4
,
true
}
}
return
2.5
/
0.3
,
true
}
}
return
4
,
false
return
4
,
false
}
}
...
...
web/src/pages/Setting/Model/SettingGeminiModel.js
View file @
01064fb5
...
@@ -209,8 +209,8 @@ export default function SettingGeminiModel(props) {
...
@@ -209,8 +209,8 @@ export default function SettingGeminiModel(props) {
label
=
{
t
(
'思考预算占比'
)}
label
=
{
t
(
'思考预算占比'
)}
field
=
{
'gemini.thinking_adapter_budget_tokens_percentage'
}
field
=
{
'gemini.thinking_adapter_budget_tokens_percentage'
}
initValue
=
{
''
}
initValue
=
{
''
}
extraText
=
{
t
(
'0.
1-1之间的小数'
)}
extraText
=
{
t
(
'0.
002-1之间的小数'
)}
min
=
{
0.
1
}
min
=
{
0.
002
}
max
=
{
1
}
max
=
{
1
}
onChange
=
{(
value
)
=>
onChange
=
{(
value
)
=>
setInputs
({
setInputs
({
...
...
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