فهرست منبع

Merge branch 'Calcium-Ion:main' into main

GuoRuqiang 1 سال پیش
والد
کامیت
2422eb2820
7فایلهای تغییر یافته به همراه52 افزوده شده و 7 حذف شده
  1. 8 0
      common/email-outlook-auth.go
  2. 1 1
      common/email.go
  3. 3 3
      controller/relay.go
  4. 17 0
      relay/channel/claude/relay-claude.go
  5. 4 3
      relay/relay-image.go
  6. 17 0
      relay/relay_rerank.go
  7. 2 0
      service/channel.go

+ 8 - 0
common/email-outlook-auth.go

@@ -3,6 +3,7 @@ package common
 import (
 import (
 	"errors"
 	"errors"
 	"net/smtp"
 	"net/smtp"
+	"strings"
 )
 )
 
 
 type outlookAuth struct {
 type outlookAuth struct {
@@ -30,3 +31,10 @@ func (a *outlookAuth) Next(fromServer []byte, more bool) ([]byte, error) {
 	}
 	}
 	return nil, nil
 	return nil, nil
 }
 }
+
+func isOutlookServer(server string) bool {
+	// 兼容多地区的outlook邮箱和ofb邮箱
+	// 其实应该加一个Option来区分是否用LOGIN的方式登录
+	// 先临时兼容一下
+	return strings.Contains(server, "outlook") || strings.Contains(server, "onmicrosoft")
+}

+ 1 - 1
common/email.go

@@ -68,7 +68,7 @@ func SendEmail(subject string, receiver string, content string) error {
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-	} else if strings.HasSuffix(SMTPAccount, "outlook.com") {
+	} else if isOutlookServer(SMTPAccount) {
 		auth = LoginAuth(SMTPAccount, SMTPToken)
 		auth = LoginAuth(SMTPAccount, SMTPToken)
 		err = smtp.SendMail(addr, auth, SMTPAccount, to, mail)
 		err = smtp.SendMail(addr, auth, SMTPAccount, to, mail)
 	} else {
 	} else {

+ 3 - 3
controller/relay.go

@@ -121,6 +121,9 @@ func shouldRetry(c *gin.Context, openaiErr *dto.OpenAIErrorWithStatusCode, retry
 	if openaiErr == nil {
 	if openaiErr == nil {
 		return false
 		return false
 	}
 	}
+	if openaiErr.LocalError {
+		return false
+	}
 	if retryTimes <= 0 {
 	if retryTimes <= 0 {
 		return false
 		return false
 	}
 	}
@@ -151,9 +154,6 @@ func shouldRetry(c *gin.Context, openaiErr *dto.OpenAIErrorWithStatusCode, retry
 		// azure处理超时不重试
 		// azure处理超时不重试
 		return false
 		return false
 	}
 	}
-	if openaiErr.LocalError {
-		return false
-	}
 	if openaiErr.StatusCode/100 == 2 {
 	if openaiErr.StatusCode/100 == 2 {
 		return false
 		return false
 	}
 	}

+ 17 - 0
relay/channel/claude/relay-claude.go

@@ -139,6 +139,7 @@ func RequestOpenAI2ClaudeMessage(textRequest dto.GeneralOpenAIRequest) (*ClaudeR
 	}
 	}
 
 
 	claudeMessages := make([]ClaudeMessage, 0)
 	claudeMessages := make([]ClaudeMessage, 0)
+	isFirstMessage := true
 	for _, message := range formatMessages {
 	for _, message := range formatMessages {
 		if message.Role == "system" {
 		if message.Role == "system" {
 			if message.IsStringContent() {
 			if message.IsStringContent() {
@@ -154,6 +155,22 @@ func RequestOpenAI2ClaudeMessage(textRequest dto.GeneralOpenAIRequest) (*ClaudeR
 				claudeRequest.System = content
 				claudeRequest.System = content
 			}
 			}
 		} else {
 		} else {
+			if isFirstMessage {
+				isFirstMessage = false
+				if message.Role != "user" {
+					// fix: first message is assistant, add user message
+					claudeMessage := ClaudeMessage{
+						Role: "user",
+						Content: []ClaudeMediaMessage{
+							{
+								Type: "text",
+								Text: "...",
+							},
+						},
+					}
+					claudeMessages = append(claudeMessages, claudeMessage)
+				}
+			}
 			claudeMessage := ClaudeMessage{
 			claudeMessage := ClaudeMessage{
 				Role: message.Role,
 				Role: message.Role,
 			}
 			}

+ 4 - 3
relay/relay-image.go

@@ -38,9 +38,7 @@ func getAndValidImageRequest(c *gin.Context, info *relaycommon.RelayInfo) (*dto.
 	if imageRequest.Model == "" {
 	if imageRequest.Model == "" {
 		imageRequest.Model = "dall-e-2"
 		imageRequest.Model = "dall-e-2"
 	}
 	}
-	if imageRequest.Quality == "" {
-		imageRequest.Quality = "standard"
-	}
+
 	// Not "256x256", "512x512", or "1024x1024"
 	// Not "256x256", "512x512", or "1024x1024"
 	if imageRequest.Model == "dall-e-2" || imageRequest.Model == "dall-e" {
 	if imageRequest.Model == "dall-e-2" || imageRequest.Model == "dall-e" {
 		if imageRequest.Size != "" && imageRequest.Size != "256x256" && imageRequest.Size != "512x512" && imageRequest.Size != "1024x1024" {
 		if imageRequest.Size != "" && imageRequest.Size != "256x256" && imageRequest.Size != "512x512" && imageRequest.Size != "1024x1024" {
@@ -50,6 +48,9 @@ func getAndValidImageRequest(c *gin.Context, info *relaycommon.RelayInfo) (*dto.
 		if imageRequest.Size != "" && imageRequest.Size != "1024x1024" && imageRequest.Size != "1024x1792" && imageRequest.Size != "1792x1024" {
 		if imageRequest.Size != "" && imageRequest.Size != "1024x1024" && imageRequest.Size != "1024x1792" && imageRequest.Size != "1792x1024" {
 			return nil, errors.New("size must be one of 256x256, 512x512, or 1024x1024, dall-e-3 1024x1792 or 1792x1024")
 			return nil, errors.New("size must be one of 256x256, 512x512, or 1024x1024, dall-e-3 1024x1792 or 1792x1024")
 		}
 		}
+		if imageRequest.Quality == "" {
+			imageRequest.Quality = "standard"
+		}
 		//if imageRequest.N != 1 {
 		//if imageRequest.N != 1 {
 		//	return nil, errors.New("n must be 1")
 		//	return nil, errors.New("n must be 1")
 		//}
 		//}

+ 17 - 0
relay/relay_rerank.go

@@ -38,6 +38,23 @@ func RerankHelper(c *gin.Context, relayMode int) *dto.OpenAIErrorWithStatusCode
 	if len(rerankRequest.Documents) == 0 {
 	if len(rerankRequest.Documents) == 0 {
 		return service.OpenAIErrorWrapperLocal(fmt.Errorf("documents is empty"), "invalid_documents", http.StatusBadRequest)
 		return service.OpenAIErrorWrapperLocal(fmt.Errorf("documents is empty"), "invalid_documents", http.StatusBadRequest)
 	}
 	}
+
+	// map model name
+	modelMapping := c.GetString("model_mapping")
+	//isModelMapped := false
+	if modelMapping != "" && modelMapping != "{}" {
+		modelMap := make(map[string]string)
+		err := json.Unmarshal([]byte(modelMapping), &modelMap)
+		if err != nil {
+			return service.OpenAIErrorWrapperLocal(err, "unmarshal_model_mapping_failed", http.StatusInternalServerError)
+		}
+		if modelMap[rerankRequest.Model] != "" {
+			rerankRequest.Model = modelMap[rerankRequest.Model]
+			// set upstream model name
+			//isModelMapped = true
+		}
+	}
+
 	relayInfo.UpstreamModelName = rerankRequest.Model
 	relayInfo.UpstreamModelName = rerankRequest.Model
 	modelPrice, success := common.GetModelPrice(rerankRequest.Model, false)
 	modelPrice, success := common.GetModelPrice(rerankRequest.Model, false)
 	groupRatio := common.GetGroupRatio(relayInfo.Group)
 	groupRatio := common.GetGroupRatio(relayInfo.Group)

+ 2 - 0
service/channel.go

@@ -54,6 +54,8 @@ func ShouldDisableChannel(channelType int, err *relaymodel.OpenAIErrorWithStatus
 	switch err.Error.Type {
 	switch err.Error.Type {
 	case "insufficient_quota":
 	case "insufficient_quota":
 		return true
 		return true
+	case "insufficient_user_quota":
+		return true
 	// https://docs.anthropic.com/claude/reference/errors
 	// https://docs.anthropic.com/claude/reference/errors
 	case "authentication_error":
 	case "authentication_error":
 		return true
 		return true