Files
CaIon f362c7c51b feat(billingexpr): support image cache and quantity variables
Add img_cr and bounded image_count inputs, expose settled billing inputs, and reuse expression digests. Extend the shared frontend contract fixtures and billing documentation.
2026-09-11 21:44:53 +08:00

57 lines
2.0 KiB
Go

package billingexpr
import (
"fmt"
"github.com/QuantumNous/new-api/common"
)
// quotaConversion converts raw expression output to quota based on the
// expression version. This is the central dispatch point for future versions
// that may use a different conversion formula.
func quotaConversion(exprOutput float64, snap *BillingSnapshot) float64 {
if snap.TaskUsageBilling {
return exprOutput * snap.QuotaPerUnit
}
switch snap.ExprVersion {
default: // v1: coefficients are $/1M tokens prices
return exprOutput / 1_000_000 * snap.QuotaPerUnit
}
}
// ComputeTieredQuota runs the Expr from a frozen BillingSnapshot against
// actual token counts and returns the settlement result.
func ComputeTieredQuota(snap *BillingSnapshot, params TokenParams) (TieredResult, error) {
return ComputeTieredQuotaWithRequest(snap, params, RequestInput{})
}
func ComputeTieredQuotaWithRequest(snap *BillingSnapshot, params TokenParams, request RequestInput) (TieredResult, error) {
if snap.TaskUsageBilling && UsesFixedPricingByHash(snap.ExprString, snap.ExprHash) {
return TieredResult{}, fmt.Errorf("fixed pricing is not supported for task usage expressions")
}
cost, trace, err := RunExprByHashWithRequest(snap.ExprString, snap.ExprHash, params, request)
if err != nil {
return TieredResult{}, err
}
quotaBeforeGroup := quotaConversion(cost, snap)
afterGroup, clamp := common.QuotaRoundChecked(quotaBeforeGroup * snap.GroupRatio)
crossed := trace.MatchedTier != snap.EstimatedTier
result := TieredResult{
ImageCount: trace.ImageCount,
BillingUnit: trace.BillingUnit,
FixedPrice: trace.FixedPrice,
ActualQuotaBeforeGroup: quotaBeforeGroup,
ActualQuotaAfterGroup: afterGroup,
MatchedTier: trace.MatchedTier,
RequestRules: trace.RequestRules,
CrossedTier: crossed,
Clamp: clamp,
}
if trace.BillingUnit == BillingUnitToken && UsedVarsByHash(snap.ExprString, snap.ExprHash)["img_cr"] {
result.BillingTokens = &params
}
return result, nil
}