diff --git a/providers/ali/chat.go b/providers/ali/chat.go index 13c9cdcf..ed6dac9f 100644 --- a/providers/ali/chat.go +++ b/providers/ali/chat.go @@ -109,6 +109,7 @@ func (p *AliProvider) convertToChatOpenai(response *AliChatResponse, request *ty // 阿里云聊天请求体 func (p *AliProvider) convertFromChatOpenai(request *types.ChatCompletionRequest) *AliChatRequest { + request.ClearEmptyMessages() messages := make([]AliMessage, 0, len(request.Messages)) for i := 0; i < len(request.Messages); i++ { message := request.Messages[i] diff --git a/providers/baichuan/chat.go b/providers/baichuan/chat.go index 7e42367f..4bc19361 100644 --- a/providers/baichuan/chat.go +++ b/providers/baichuan/chat.go @@ -62,6 +62,7 @@ func (p *BaichuanProvider) CreateChatCompletionStream(request *types.ChatComplet // 获取聊天请求体 func (p *BaichuanProvider) getChatRequestBody(request *types.ChatCompletionRequest) *BaichuanChatRequest { + request.ClearEmptyMessages() messages := make([]BaichuanMessage, 0, len(request.Messages)) for i := 0; i < len(request.Messages); i++ { message := request.Messages[i] diff --git a/providers/baidu/chat.go b/providers/baidu/chat.go index 8c74b5e0..e93d1b1a 100644 --- a/providers/baidu/chat.go +++ b/providers/baidu/chat.go @@ -131,6 +131,7 @@ func (p *BaiduProvider) convertToChatOpenai(response *BaiduChatResponse, request } func convertFromChatOpenai(request *types.ChatCompletionRequest) *BaiduChatRequest { + request.ClearEmptyMessages() baiduChatRequest := &BaiduChatRequest{ Messages: make([]BaiduMessage, 0, len(request.Messages)), Temperature: request.Temperature, diff --git a/providers/claude/chat.go b/providers/claude/chat.go index 3434bfa3..471f0f4f 100644 --- a/providers/claude/chat.go +++ b/providers/claude/chat.go @@ -94,6 +94,7 @@ func (p *ClaudeProvider) getChatRequest(request *types.ChatCompletionRequest) (* } func ConvertFromChatOpenai(request *types.ChatCompletionRequest) (*ClaudeRequest, *types.OpenAIErrorWithStatusCode) { + request.ClearEmptyMessages() claudeRequest := ClaudeRequest{ Model: request.Model, Messages: []Message{}, diff --git a/providers/cloudflareAI/chat.go b/providers/cloudflareAI/chat.go index 7ae1f8ce..5ba0bb95 100644 --- a/providers/cloudflareAI/chat.go +++ b/providers/cloudflareAI/chat.go @@ -109,6 +109,7 @@ func (p *CloudflareAIProvider) convertToChatOpenai(response *ChatRespone, reques } func (p *CloudflareAIProvider) convertFromChatOpenai(request *types.ChatCompletionRequest) *ChatRequest { + request.ClearEmptyMessages() chatRequest := &ChatRequest{ Stream: request.Stream, MaxTokens: request.MaxTokens, diff --git a/providers/cohere/chat.go b/providers/cohere/chat.go index 837908af..0f4b5080 100644 --- a/providers/cohere/chat.go +++ b/providers/cohere/chat.go @@ -86,6 +86,7 @@ func (p *CohereProvider) getChatRequest(request *types.ChatCompletionRequest) (* } func ConvertFromChatOpenai(request *types.ChatCompletionRequest) (*CohereRequest, *types.OpenAIErrorWithStatusCode) { + request.ClearEmptyMessages() cohereRequest := CohereRequest{ Model: request.Model, MaxTokens: request.MaxTokens, diff --git a/providers/gemini/chat.go b/providers/gemini/chat.go index 5875d86b..e1210fd3 100644 --- a/providers/gemini/chat.go +++ b/providers/gemini/chat.go @@ -86,6 +86,7 @@ func (p *GeminiProvider) getChatRequest(request *types.ChatCompletionRequest) (* } func convertFromChatOpenai(request *types.ChatCompletionRequest) (*GeminiChatRequest, *types.OpenAIErrorWithStatusCode) { + request.ClearEmptyMessages() geminiRequest := GeminiChatRequest{ Contents: make([]GeminiChatContent, 0, len(request.Messages)), SafetySettings: []GeminiChatSafetySettings{ diff --git a/providers/minimax/chat.go b/providers/minimax/chat.go index 6aa47bf0..88d95d71 100644 --- a/providers/minimax/chat.go +++ b/providers/minimax/chat.go @@ -132,6 +132,7 @@ func (p *MiniMaxProvider) convertToChatOpenai(response *MiniMaxChatResponse, req func convertFromChatOpenai(request *types.ChatCompletionRequest) *MiniMaxChatRequest { var botSettings []MiniMaxBotSetting var messges []MiniMaxChatMessage + request.ClearEmptyMessages() for _, message := range request.Messages { if message.Role == types.ChatMessageRoleSystem { botSettings = append(botSettings, MiniMaxBotSetting{ diff --git a/providers/mistral/chat.go b/providers/mistral/chat.go index a8b532d1..d9eaa122 100644 --- a/providers/mistral/chat.go +++ b/providers/mistral/chat.go @@ -79,6 +79,7 @@ func (p *MistralProvider) getChatRequest(request *types.ChatCompletionRequest) ( } func convertFromChatOpenai(request *types.ChatCompletionRequest) *MistralChatCompletionRequest { + request.ClearEmptyMessages() mistralRequest := &MistralChatCompletionRequest{ Model: request.Model, Messages: make([]types.ChatCompletionMessage, 0, len(request.Messages)), diff --git a/providers/moonshot/chat.go b/providers/moonshot/chat.go new file mode 100644 index 00000000..e45ba2e2 --- /dev/null +++ b/providers/moonshot/chat.go @@ -0,0 +1,72 @@ +package moonshot + +import ( + "net/http" + "one-api/common" + "one-api/common/requester" + "one-api/providers/openai" + "one-api/types" +) + +func (p *MoonshotProvider) CreateChatCompletion(request *types.ChatCompletionRequest) (openaiResponse *types.ChatCompletionResponse, errWithCode *types.OpenAIErrorWithStatusCode) { + request.ClearEmptyMessages() + req, errWithCode := p.GetRequestTextBody(common.RelayModeChatCompletions, request.Model, request) + if errWithCode != nil { + return nil, errWithCode + } + defer req.Body.Close() + + response := &openai.OpenAIProviderChatResponse{} + // 发送请求 + _, errWithCode = p.Requester.SendRequest(req, response, false) + if errWithCode != nil { + return nil, errWithCode + } + + // 检测是否错误 + openaiErr := openai.ErrorHandle(&response.OpenAIErrorResponse) + if openaiErr != nil { + errWithCode = &types.OpenAIErrorWithStatusCode{ + OpenAIError: *openaiErr, + StatusCode: http.StatusBadRequest, + } + return nil, errWithCode + } + + if response.Usage == nil { + response.Usage = &types.Usage{ + PromptTokens: p.Usage.PromptTokens, + CompletionTokens: 0, + TotalTokens: 0, + } + // 那么需要计算 + response.Usage.CompletionTokens = common.CountTokenText(response.GetContent(), request.Model) + response.Usage.TotalTokens = response.Usage.PromptTokens + response.Usage.CompletionTokens + } + + *p.Usage = *response.Usage + + return &response.ChatCompletionResponse, nil +} + +func (p *MoonshotProvider) CreateChatCompletionStream(request *types.ChatCompletionRequest) (requester.StreamReaderInterface[string], *types.OpenAIErrorWithStatusCode) { + request.ClearEmptyMessages() + req, errWithCode := p.GetRequestTextBody(common.RelayModeChatCompletions, request.Model, request) + if errWithCode != nil { + return nil, errWithCode + } + defer req.Body.Close() + + // 发送请求 + resp, errWithCode := p.Requester.SendRequestRaw(req) + if errWithCode != nil { + return nil, errWithCode + } + + chatHandler := openai.OpenAIStreamHandler{ + Usage: p.Usage, + ModelName: request.Model, + } + + return requester.RequestStream(p.Requester, resp, chatHandler.HandlerChatStream) +} diff --git a/providers/tencent/chat.go b/providers/tencent/chat.go index 35d53d2a..18e009ab 100644 --- a/providers/tencent/chat.go +++ b/providers/tencent/chat.go @@ -123,6 +123,7 @@ func (p *TencentProvider) convertToChatOpenai(response *TencentChatResponse, req } func convertFromChatOpenai(request *types.ChatCompletionRequest) *TencentChatRequest { + request.ClearEmptyMessages() messages := make([]TencentMessage, 0, len(request.Messages)) for i := 0; i < len(request.Messages); i++ { message := request.Messages[i] diff --git a/providers/xunfei/chat.go b/providers/xunfei/chat.go index e22bddaa..0578d73f 100644 --- a/providers/xunfei/chat.go +++ b/providers/xunfei/chat.go @@ -74,6 +74,7 @@ func (p *XunfeiProvider) getChatRequest(request *types.ChatCompletionRequest) (* } func (p *XunfeiProvider) convertFromChatOpenai(request *types.ChatCompletionRequest) *XunfeiChatRequest { + request.ClearEmptyMessages() messages := make([]XunfeiMessage, 0, len(request.Messages)) for _, message := range request.Messages { if message.FunctionCall != nil || message.ToolCalls != nil { diff --git a/providers/zhipu/chat.go b/providers/zhipu/chat.go index 03981e21..fc2ee6a5 100644 --- a/providers/zhipu/chat.go +++ b/providers/zhipu/chat.go @@ -110,6 +110,7 @@ func (p *ZhipuProvider) convertToChatOpenai(response *ZhipuResponse, request *ty } func (p *ZhipuProvider) convertFromChatOpenai(request *types.ChatCompletionRequest) *ZhipuRequest { + request.ClearEmptyMessages() for i, _ := range request.Messages { request.Messages[i].Role = convertRole(request.Messages[i].Role) if request.Messages[i].FunctionCall != nil { diff --git a/types/chat.go b/types/chat.go index 0618b41a..8c414ffd 100644 --- a/types/chat.go +++ b/types/chat.go @@ -205,6 +205,16 @@ func (r *ChatCompletionRequest) GetFunctions() []*ChatCompletionFunction { return r.Functions } +func (r *ChatCompletionRequest) ClearEmptyMessages() { + var messages []ChatCompletionMessage + for _, message := range r.Messages { + if message.StringContent() != "" || message.ToolCalls != nil || message.FunctionCall != nil { + messages = append(messages, message) + } + } + r.Messages = messages +} + type ChatCompletionFunction struct { Name string `json:"name"` Description string `json:"description"`