Compare commits

...

8 Commits

Author SHA1 Message Date
JustSong
6b1a24d650 fix: check if token is nil before using it 2023-06-25 10:40:54 +08:00
JustSong
94ba3dd024 chore: billing api now will return a large number if unlimited quota is set 2023-06-25 10:39:22 +08:00
JustSong
f6eb4e5628 perf: validate the request first before send to OpenAI's server 2023-06-25 10:25:33 +08:00
JustSong
57bd907f83 fix: do not record if used quota is zero 2023-06-25 09:59:58 +08:00
JustSong
dd8e8d5ee8 fix: do not charge the user if the amount of tokens used was zero 2023-06-25 09:56:03 +08:00
JustSong
1ca1aa0cdc fix: fix usage is not correct 2023-06-25 09:36:39 +08:00
quzard
f2ba0c0300 fix: fix log sorting (#195) 2023-06-24 21:34:20 +08:00
JustSong
f5c1fcd3c3 fix: do not reuse state variable directly 2023-06-24 19:45:18 +08:00
3 changed files with 50 additions and 11 deletions

View File

@@ -32,6 +32,9 @@ func GetSubscription(c *gin.Context) {
if common.DisplayInCurrencyEnabled {
amount /= common.QuotaPerUnit
}
if token != nil && token.UnlimitedQuota {
amount = 99999999.9999
}
subscription := OpenAISubscriptionResponse{
Object: "billing_subscription",
HasPaymentMethod: true,
@@ -71,7 +74,7 @@ func GetUsage(c *gin.Context) {
}
usage := OpenAIUsageResponse{
Object: "list",
TotalUsage: amount,
TotalUsage: amount * 100,
}
c.JSON(200, usage)
return

View File

@@ -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") != "" {
@@ -139,17 +159,25 @@ 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 {
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)
}
}
}()

View File

@@ -107,7 +107,7 @@ const LogsTable = () => {
if (startIdx === 0) {
setLogs(data);
} else {
let newLogs = logs;
let newLogs = [...logs];
newLogs.push(...data);
setLogs(newLogs);
}
@@ -169,9 +169,17 @@ const LogsTable = () => {
if (logs.length === 0) return;
setLoading(true);
let sortedLogs = [...logs];
sortedLogs.sort((a, b) => {
return ('' + a[key]).localeCompare(b[key]);
});
if (typeof sortedLogs[0][key] === 'string'){
sortedLogs.sort((a, b) => {
return ('' + a[key]).localeCompare(b[key]);
});
} else {
sortedLogs.sort((a, b) => {
if (a[key] === b[key]) return 0;
if (a[key] > b[key]) return -1;
if (a[key] < b[key]) return 1;
});
}
if (sortedLogs[0].id === logs[0].id) {
sortedLogs.reverse();
}