feat: sync deployed v1.0.0-rc.38-custom.42
Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
This commit is contained in:
1 parent
aa6c3f50f4
commit
ceddfd3d6b
828 files changed
+122253
-13702
No files matched your search
@@ -0,0 +1,87 @@
|
||||
package relay
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/QuantumNous/new-api/constant"
|
||||
"github.com/QuantumNous/new-api/logger"
|
||||
relaycommon "github.com/QuantumNous/new-api/relay/common"
|
||||
"github.com/QuantumNous/new-api/relay/helper"
|
||||
"github.com/QuantumNous/new-api/relaykit/dto"
|
||||
"github.com/QuantumNous/new-api/relaykit/types"
|
||||
"github.com/QuantumNous/new-api/service"
|
||||
"github.com/QuantumNous/new-api/setting"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
// PrepareRequestBilling estimates and reserves one request's charge. Transports
|
||||
// provide the current request body through BodyStorage or BillingRequestInput;
|
||||
// channel retries retain the resulting billing session and pricing snapshot.
|
||||
func PrepareRequestBilling(c *gin.Context, info *relaycommon.RelayInfo) *types.NewAPIError {
|
||||
durable := info.OriginModelName == "gpt-6-astra" && c.Request.Method == http.MethodPost && c.Request.URL.Path == "/v1/responses"
|
||||
needSensitiveCheck := setting.ShouldCheckPromptSensitive()
|
||||
meta := &types.TokenCountMeta{TokenType: types.TokenTypeTokenizer}
|
||||
if info.Request != nil && (needSensitiveCheck || constant.CountToken || durable) {
|
||||
meta = info.Request.GetTokenCountMeta()
|
||||
} else {
|
||||
// Avoid building CombineText when only the pricing quantities are needed.
|
||||
switch request := info.Request.(type) {
|
||||
case *dto.GeneralOpenAIRequest:
|
||||
meta.MaxTokens = int(max(lo.FromPtr(request.MaxTokens), lo.FromPtr(request.MaxCompletionTokens)))
|
||||
case *dto.OpenAIResponsesRequest:
|
||||
meta.MaxTokens = int(lo.FromPtr(request.MaxOutputTokens))
|
||||
case *dto.ClaudeRequest:
|
||||
meta.MaxTokens = int(lo.FromPtr(request.MaxTokens))
|
||||
case *dto.ImageRequest:
|
||||
meta = request.GetTokenCountMeta()
|
||||
}
|
||||
}
|
||||
|
||||
if needSensitiveCheck && meta != nil {
|
||||
if contains, words := service.CheckSensitiveText(meta.CombineText); contains {
|
||||
service.RequestPolicy(c).AddEvent(service.PolicyEvent{ErrorCode: string(types.ErrorCodeSensitiveWordsDetected), ErrorSource: "local", Decision: service.PolicyDecision{Action: "stop", Reason: "local_rejection", Source: "global"}, Health: "unchanged"})
|
||||
message := fmt.Sprintf("user sensitive words detected: %s", strings.Join(words, ", "))
|
||||
logger.LogWarn(c, message)
|
||||
return types.NewError(errors.New(message), types.ErrorCodeSensitiveWordsDetected)
|
||||
}
|
||||
}
|
||||
|
||||
tokens, err := service.EstimateRequestToken(c, meta, info)
|
||||
if durable { tokens,err=service.CountRequestToken(c,meta,info) }
|
||||
if err != nil {
|
||||
return types.NewError(err, types.ErrorCodeCountTokenFailed)
|
||||
}
|
||||
info.SetEstimatePromptTokens(tokens)
|
||||
|
||||
priceData, err := helper.ModelPriceHelper(c, info, tokens, meta)
|
||||
if err != nil {
|
||||
return types.NewError(err, types.ErrorCodeModelPriceError, types.ErrOptionWithStatusCode(http.StatusBadRequest))
|
||||
}
|
||||
if durable {
|
||||
info.DurableAttemptBilling = true
|
||||
return nil
|
||||
}
|
||||
if priceData.FreeModel {
|
||||
logger.LogInfo(c, fmt.Sprintf("模型 %s 免费,跳过预扣费", info.OriginModelName))
|
||||
return nil
|
||||
}
|
||||
return service.PreConsumeBilling(c, priceData.QuotaToPreConsume, info)
|
||||
}
|
||||
|
||||
// RefundFailedRequestBilling applies the common final-failure policy after all
|
||||
// eligible attempts have ended. A settled BillingSession never refunds again.
|
||||
func RefundFailedRequestBilling(c *gin.Context, info *relaycommon.RelayInfo, apiErr *types.NewAPIError) *types.NewAPIError {
|
||||
if apiErr == nil {
|
||||
return nil
|
||||
}
|
||||
apiErr = service.NormalizeViolationFeeError(apiErr)
|
||||
if info.Billing != nil {
|
||||
info.Billing.Refund(c)
|
||||
}
|
||||
service.ChargeViolationFeeIfNeeded(c, info, apiErr)
|
||||
return apiErr
|
||||
}
|
||||
Reference in new issue
Block a user