refactor: Improve message content handling and quota error responses

This commit is contained in:
1808837298@qq.com
2025-02-21 18:18:21 +08:00
parent 1f4f9123aa
commit b9b69b01e5
3 changed files with 27 additions and 26 deletions

View File

@@ -88,15 +88,15 @@ func (r GeneralOpenAIRequest) ParseInput() []string {
} }
type Message struct { type Message struct {
Role string `json:"role"` Role string `json:"role"`
Content json.RawMessage `json:"content"` Content json.RawMessage `json:"content"`
// parsedContent not json field Name *string `json:"name,omitempty"`
parsedContent []MediaContent Prefix *bool `json:"prefix,omitempty"`
Name *string `json:"name,omitempty"` ReasoningContent string `json:"reasoning_content,omitempty"`
Prefix *bool `json:"prefix,omitempty"` ToolCalls json.RawMessage `json:"tool_calls,omitempty"`
ReasoningContent string `json:"reasoning_content,omitempty"` ToolCallId string `json:"tool_call_id,omitempty"`
ToolCalls json.RawMessage `json:"tool_calls,omitempty"` parsedContent []MediaContent
ToolCallId string `json:"tool_call_id,omitempty"` parsedStringContent *string
} }
type MediaContent struct { type MediaContent struct {
@@ -150,6 +150,9 @@ func (m *Message) SetToolCalls(toolCalls any) {
} }
func (m *Message) StringContent() string { func (m *Message) StringContent() string {
if m.parsedStringContent != nil {
return *m.parsedStringContent
}
var stringContent string var stringContent string
if err := json.Unmarshal(m.Content, &stringContent); err == nil { if err := json.Unmarshal(m.Content, &stringContent); err == nil {
return stringContent return stringContent
@@ -160,16 +163,24 @@ func (m *Message) StringContent() string {
func (m *Message) SetStringContent(content string) { func (m *Message) SetStringContent(content string) {
jsonContent, _ := json.Marshal(content) jsonContent, _ := json.Marshal(content)
m.Content = jsonContent m.Content = jsonContent
m.parsedStringContent = &content
m.parsedContent = nil
} }
func (m *Message) SetMediaContent(content []MediaContent) { func (m *Message) SetMediaContent(content []MediaContent) {
jsonContent, _ := json.Marshal(content) jsonContent, _ := json.Marshal(content)
m.Content = jsonContent m.Content = jsonContent
m.parsedContent = nil
m.parsedStringContent = nil
} }
func (m *Message) IsStringContent() bool { func (m *Message) IsStringContent() bool {
if m.parsedStringContent != nil {
return true
}
var stringContent string var stringContent string
if err := json.Unmarshal(m.Content, &stringContent); err == nil { if err := json.Unmarshal(m.Content, &stringContent); err == nil {
m.parsedStringContent = &stringContent
return true return true
} }
return false return false

View File

@@ -86,15 +86,13 @@ func ImageHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
imageRequest.Model = relayInfo.UpstreamModelName imageRequest.Model = relayInfo.UpstreamModelName
modelPrice, success := common.GetModelPrice(imageRequest.Model, true) priceData := helper.ModelPriceHelper(c, relayInfo, 0, 0)
if !success { if !priceData.UsePrice {
modelRatio := common.GetModelRatio(imageRequest.Model)
// modelRatio 16 = modelPrice $0.04 // modelRatio 16 = modelPrice $0.04
// per 1 modelRatio = $0.04 / 16 // per 1 modelRatio = $0.04 / 16
modelPrice = 0.0025 * modelRatio priceData.ModelPrice = 0.0025 * priceData.ModelRatio
} }
groupRatio := setting.GetGroupRatio(relayInfo.Group)
userQuota, err := model.GetUserQuota(relayInfo.UserId, false) userQuota, err := model.GetUserQuota(relayInfo.UserId, false)
sizeRatio := 1.0 sizeRatio := 1.0
@@ -117,11 +115,11 @@ func ImageHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
} }
} }
imageRatio := modelPrice * sizeRatio * qualityRatio * float64(imageRequest.N) imageRatio := priceData.ModelPrice * sizeRatio * qualityRatio * float64(imageRequest.N)
quota := int(imageRatio * groupRatio * common.QuotaPerUnit) quota := int(imageRatio * priceData.GroupRatio * common.QuotaPerUnit)
if userQuota-quota < 0 { if userQuota-quota < 0 {
return service.OpenAIErrorWrapperLocal(errors.New(fmt.Sprintf("image pre-consumed quota failed, user quota: %d, need quota: %d", userQuota, quota)), "insufficient_user_quota", http.StatusBadRequest) return service.OpenAIErrorWrapperLocal(fmt.Errorf("image pre-consumed quota failed, user quota: %s, need quota: %s", common.FormatQuota(userQuota), common.FormatQuota(quota)), "insufficient_user_quota", http.StatusForbidden)
} }
adaptor := GetAdaptor(relayInfo.ApiType) adaptor := GetAdaptor(relayInfo.ApiType)
@@ -178,14 +176,6 @@ func ImageHelper(c *gin.Context) *dto.OpenAIErrorWithStatusCode {
quality = "hd" quality = "hd"
} }
priceData := helper.PriceData{
UsePrice: true,
GroupRatio: groupRatio,
ModelPrice: modelPrice,
ModelRatio: 0,
ShouldPreConsumedQuota: 0,
}
logContent := fmt.Sprintf("大小 %s, 品质 %s", imageRequest.Size, quality) logContent := fmt.Sprintf("大小 %s, 品质 %s", imageRequest.Size, quality)
postConsumeQuota(c, relayInfo, usage, 0, userQuota, priceData, logContent) postConsumeQuota(c, relayInfo, usage, 0, userQuota, priceData, logContent)
return nil return nil

View File

@@ -246,7 +246,7 @@ func preConsumeQuota(c *gin.Context, preConsumedQuota int, relayInfo *relaycommo
return 0, 0, service.OpenAIErrorWrapperLocal(errors.New("user quota is not enough"), "insufficient_user_quota", http.StatusForbidden) return 0, 0, service.OpenAIErrorWrapperLocal(errors.New("user quota is not enough"), "insufficient_user_quota", http.StatusForbidden)
} }
if userQuota-preConsumedQuota < 0 { if userQuota-preConsumedQuota < 0 {
return 0, 0, service.OpenAIErrorWrapperLocal(fmt.Errorf("chat pre-consumed quota failed, user quota: %s, need quota: %s", common.FormatQuota(userQuota), common.FormatQuota(preConsumedQuota)), "insufficient_user_quota", http.StatusBadRequest) return 0, 0, service.OpenAIErrorWrapperLocal(fmt.Errorf("chat pre-consumed quota failed, user quota: %s, need quota: %s", common.FormatQuota(userQuota), common.FormatQuota(preConsumedQuota)), "insufficient_user_quota", http.StatusForbidden)
} }
if userQuota > 100*preConsumedQuota { if userQuota > 100*preConsumedQuota {
// 用户额度充足,判断令牌额度是否充足 // 用户额度充足,判断令牌额度是否充足