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
Unverified
Commit
3fbad6a7
authored
Jul 07, 2026
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(price): add default token estimate for tiered expression pre-consume
parent
becc18e3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
86 additions
and
3 deletions
+86
-3
relay/helper/price.go
+8
-3
relay/helper/price_test.go
+78
-0
No files found.
relay/helper/price.go
View file @
3fbad6a7
...
@@ -35,6 +35,11 @@ func modelPriceNotConfiguredError(modelName string, userId int) error {
...
@@ -35,6 +35,11 @@ func modelPriceNotConfiguredError(modelName string, userId int) error {
// https://docs.claude.com/en/docs/build-with-claude/prompt-caching#1-hour-cache-duration
// https://docs.claude.com/en/docs/build-with-claude/prompt-caching#1-hour-cache-duration
const
claudeCacheCreation1hMultiplier
=
6
/
3.75
const
claudeCacheCreation1hMultiplier
=
6
/
3.75
// defaultTieredPreConsumeMaxTokens is the fallback completion-token estimate
// used for tiered expression pre-consume when the client omits max_tokens, so
// the pre-consumed quota still reflects a plausible output cost in paid groups.
const
defaultTieredPreConsumeMaxTokens
=
8192
// HandleGroupRatio checks for "auto_group" in the context and updates the group ratio and relayInfo.UsingGroup if present
// HandleGroupRatio checks for "auto_group" in the context and updates the group ratio and relayInfo.UsingGroup if present
func
HandleGroupRatio
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
)
types
.
GroupRatioInfo
{
func
HandleGroupRatio
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
)
types
.
GroupRatioInfo
{
groupRatioInfo
:=
types
.
GroupRatioInfo
{
groupRatioInfo
:=
types
.
GroupRatioInfo
{
...
@@ -244,9 +249,9 @@ func modelPriceHelperTiered(c *gin.Context, info *relaycommon.RelayInfo, promptT
...
@@ -244,9 +249,9 @@ func modelPriceHelperTiered(c *gin.Context, info *relaycommon.RelayInfo, promptT
return
types
.
PriceData
{},
fmt
.
Errorf
(
"model %s is configured as tiered_expr but has no billing expression"
,
info
.
OriginModelName
)
return
types
.
PriceData
{},
fmt
.
Errorf
(
"model %s is configured as tiered_expr but has no billing expression"
,
info
.
OriginModelName
)
}
}
estimatedCompletionTokens
:=
0
estimatedCompletionTokens
:=
meta
.
MaxTokens
if
meta
.
MaxTokens
!=
0
{
if
estimatedCompletionTokens
==
0
&&
groupRatioInfo
.
GroupRatio
!=
0
{
estimatedCompletionTokens
=
meta
.
MaxTokens
estimatedCompletionTokens
=
defaultTieredPreConsume
MaxTokens
}
}
requestInput
,
err
:=
ResolveIncomingBillingExprRequestInput
(
c
,
info
)
requestInput
,
err
:=
ResolveIncomingBillingExprRequestInput
(
c
,
info
)
...
...
relay/helper/price_test.go
View file @
3fbad6a7
...
@@ -60,3 +60,81 @@ func TestModelPriceHelperTieredUsesPreloadedRequestInput(t *testing.T) {
...
@@ -60,3 +60,81 @@ func TestModelPriceHelperTieredUsesPreloadedRequestInput(t *testing.T) {
require
.
Equal
(
t
,
billing_setting
.
BillingModeTieredExpr
,
info
.
TieredBillingSnapshot
.
BillingMode
)
require
.
Equal
(
t
,
billing_setting
.
BillingModeTieredExpr
,
info
.
TieredBillingSnapshot
.
BillingMode
)
require
.
Equal
(
t
,
common
.
QuotaPerUnit
,
info
.
TieredBillingSnapshot
.
QuotaPerUnit
)
require
.
Equal
(
t
,
common
.
QuotaPerUnit
,
info
.
TieredBillingSnapshot
.
QuotaPerUnit
)
}
}
func
TestModelPriceHelperTieredPreConsumeMaxTokensFallback
(
t
*
testing
.
T
)
{
gin
.
SetMode
(
gin
.
TestMode
)
saved
:=
map
[
string
]
string
{}
require
.
NoError
(
t
,
config
.
GlobalConfig
.
SaveToDB
(
func
(
key
,
value
string
)
error
{
saved
[
key
]
=
value
return
nil
}))
t
.
Cleanup
(
func
()
{
require
.
NoError
(
t
,
config
.
GlobalConfig
.
LoadFromDB
(
saved
))
})
require
.
NoError
(
t
,
config
.
GlobalConfig
.
LoadFromDB
(
map
[
string
]
string
{
"billing_setting.billing_mode"
:
`{"tiered-fallback-model":"tiered_expr"}`
,
"billing_setting.billing_expr"
:
`{"tiered-fallback-model":"tier(\"base\", p * 3 + c * 15)"}`
,
"group_ratio_setting.group_ratio"
:
`{"default":1,"free":0}`
,
}))
const
promptTokens
=
1000
cases
:=
[]
struct
{
name
string
group
string
maxTokens
int
expected
int
}{
{
// max_tokens omitted in a paid group -> fall back to 8192 completion tokens.
// p*3 + c*15 = 1000*3 + 8192*15 = 125880 -> /1e6 * 500000 = 62940
name
:
"non-free group falls back to 8192 completion tokens"
,
group
:
"default"
,
maxTokens
:
0
,
expected
:
62940
,
},
{
// explicit max_tokens is used verbatim, no fallback.
// 1000*3 + 100*15 = 4500 -> /1e6 * 500000 = 2250
name
:
"explicit max_tokens is used verbatim"
,
group
:
"default"
,
maxTokens
:
100
,
expected
:
2250
,
},
{
// free group (ratio 0) stays zero; fallback is gated on non-zero group ratio.
name
:
"free group stays zero without fallback"
,
group
:
"free"
,
maxTokens
:
0
,
expected
:
0
,
},
}
for
_
,
tc
:=
range
cases
{
t
.
Run
(
tc
.
name
,
func
(
t
*
testing
.
T
)
{
recorder
:=
httptest
.
NewRecorder
()
ctx
,
_
:=
gin
.
CreateTestContext
(
recorder
)
req
:=
httptest
.
NewRequest
(
http
.
MethodPost
,
"/v1/chat/completions"
,
nil
)
req
.
Header
.
Set
(
"Content-Type"
,
"application/json"
)
ctx
.
Request
=
req
ctx
.
Set
(
"group"
,
tc
.
group
)
info
:=
&
relaycommon
.
RelayInfo
{
OriginModelName
:
"tiered-fallback-model"
,
UserGroup
:
tc
.
group
,
UsingGroup
:
tc
.
group
,
RequestHeaders
:
map
[
string
]
string
{
"Content-Type"
:
"application/json"
},
BillingRequestInput
:
&
billingexpr
.
RequestInput
{
Headers
:
map
[
string
]
string
{
"Content-Type"
:
"application/json"
},
Body
:
[]
byte
(
`{}`
),
},
}
priceData
,
err
:=
ModelPriceHelper
(
ctx
,
info
,
promptTokens
,
&
types
.
TokenCountMeta
{
MaxTokens
:
tc
.
maxTokens
})
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
tc
.
expected
,
priceData
.
QuotaToPreConsume
)
})
}
}
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