From 1ca1aa0cdc1d43bec7dc56b78bdd19d2ab455f16 Mon Sep 17 00:00:00 2001 From: JustSong Date: Sun, 25 Jun 2023 09:36:26 +0800 Subject: [PATCH 1/4] fix: fix usage is not correct --- controller/billing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/billing.go b/controller/billing.go index ec8e3ce3..7bc63425 100644 --- a/controller/billing.go +++ b/controller/billing.go @@ -71,7 +71,7 @@ func GetUsage(c *gin.Context) { } usage := OpenAIUsageResponse{ Object: "list", - TotalUsage: amount, + TotalUsage: amount * 100, } c.JSON(200, usage) return From dd8e8d5ee807d3f07c4b18e878ca82159ab3079b Mon Sep 17 00:00:00 2001 From: JustSong Date: Sun, 25 Jun 2023 09:56:03 +0800 Subject: [PATCH 2/4] fix: do not charge the user if the amount of tokens used was zero --- controller/relay-text.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/controller/relay-text.go b/controller/relay-text.go index 26970dc8..485bdfdf 100644 --- a/controller/relay-text.go +++ b/controller/relay-text.go @@ -139,6 +139,12 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { if ratio != 0 && quota <= 0 { quota = 1 } + totalTokens := promptTokens + completionTokens + if totalTokens == 0 { + // in this case, must be some error happened + // we cannot just return, because we may have to return the pre-consumed quota + quota = 0 + } quotaDelta := quota - preConsumedQuota err := model.PostConsumeTokenQuota(tokenId, quotaDelta) if err != nil { From 57bd907f83d669358bde3b18b895837f2b830a52 Mon Sep 17 00:00:00 2001 From: JustSong Date: Sun, 25 Jun 2023 09:59:58 +0800 Subject: [PATCH 3/4] fix: do not record if used quota is zero --- controller/relay-text.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/controller/relay-text.go b/controller/relay-text.go index 485bdfdf..778991bd 100644 --- a/controller/relay-text.go +++ b/controller/relay-text.go @@ -150,12 +150,14 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { if err != nil { common.SysError("error consuming token remain quota: " + err.Error()) } - tokenName := c.GetString("token_name") - logContent := fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f", modelRatio, groupRatio) - model.RecordConsumeLog(userId, promptTokens, completionTokens, textRequest.Model, tokenName, quota, logContent) - model.UpdateUserUsedQuotaAndRequestCount(userId, quota) - channelId := c.GetInt("channel_id") - model.UpdateChannelUsedQuota(channelId, quota) + if quota != 0 { + tokenName := c.GetString("token_name") + logContent := fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f", modelRatio, groupRatio) + model.RecordConsumeLog(userId, promptTokens, completionTokens, textRequest.Model, tokenName, quota, logContent) + model.UpdateUserUsedQuotaAndRequestCount(userId, quota) + channelId := c.GetInt("channel_id") + model.UpdateChannelUsedQuota(channelId, quota) + } } }() From f6eb4e56287a1cdb1e00bae299ea4f12e9b6477c Mon Sep 17 00:00:00 2001 From: JustSong Date: Sun, 25 Jun 2023 10:25:33 +0800 Subject: [PATCH 4/4] perf: validate the request first before send to OpenAI's server --- controller/relay-text.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/controller/relay-text.go b/controller/relay-text.go index 778991bd..e14e0632 100644 --- a/controller/relay-text.go +++ b/controller/relay-text.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "encoding/json" + "errors" "fmt" "github.com/gin-gonic/gin" "io" @@ -29,6 +30,25 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { if relayMode == RelayModeModeration && textRequest.Model == "" { textRequest.Model = "text-moderation-latest" } + // request validation + if textRequest.Model == "" { + return errorWrapper(errors.New("model is required"), "required_field_missing", http.StatusBadRequest) + } + switch relayMode { + case RelayModeCompletions: + if textRequest.Prompt == "" { + return errorWrapper(errors.New("prompt is required"), "required_field_missing", http.StatusBadRequest) + } + case RelayModeChatCompletions: + if len(textRequest.Messages) == 0 { + return errorWrapper(errors.New("messages is required"), "required_field_missing", http.StatusBadRequest) + } + case RelayModeEmbeddings: + case RelayModeModeration: + if textRequest.Input == "" { + return errorWrapper(errors.New("input is required"), "required_field_missing", http.StatusBadRequest) + } + } baseURL := common.ChannelBaseURLs[channelType] requestURL := c.Request.URL.String() if c.GetString("base_url") != "" {