From d124ec5b1a1794d1fafe6813910b5186d8467482 Mon Sep 17 00:00:00 2001 From: RedwindA Date: Sun, 8 Jun 2025 00:06:56 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(mistral):=20validate=20and?= =?UTF-8?q?=20generate=20new=20IDs=20for=20tool=20calls=20and=20tool=20cal?= =?UTF-8?q?l=20IDs;=20Correctly=20handle=20null=20content=20for=20assistan?= =?UTF-8?q?t=20messages=20with=20tool=5Fcalls.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- relay/channel/mistral/text.go | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/relay/channel/mistral/text.go b/relay/channel/mistral/text.go index 75272e34..a25c1492 100644 --- a/relay/channel/mistral/text.go +++ b/relay/channel/mistral/text.go @@ -1,13 +1,55 @@ package mistral import ( + "one-api/common" "one-api/dto" + "regexp" ) +var mistralToolCallIdRegexp = regexp.MustCompile("^[a-zA-Z0-9]{9}$") + func requestOpenAI2Mistral(request *dto.GeneralOpenAIRequest) *dto.GeneralOpenAIRequest { messages := make([]dto.Message, 0, len(request.Messages)) + idMap := make(map[string]string) for _, message := range request.Messages { + // 1. tool_calls.id + toolCalls := message.ParseToolCalls() + if toolCalls != nil { + for i := range toolCalls { + if !mistralToolCallIdRegexp.MatchString(toolCalls[i].ID) { + if newId, ok := idMap[toolCalls[i].ID]; ok { + toolCalls[i].ID = newId + } else { + newId, err := common.GenerateRandomCharsKey(9) + if err == nil { + idMap[toolCalls[i].ID] = newId + toolCalls[i].ID = newId + } + } + } + } + message.SetToolCalls(toolCalls) + } + + // 2. tool_call_id + if message.ToolCallId != "" { + if newId, ok := idMap[message.ToolCallId]; ok { + message.ToolCallId = newId + } else { + if !mistralToolCallIdRegexp.MatchString(message.ToolCallId) { + newId, err := common.GenerateRandomCharsKey(9) + if err == nil { + idMap[message.ToolCallId] = newId + message.ToolCallId = newId + } + } + } + } + mediaMessages := message.ParseContent() + if message.Role == "assistant" && message.ToolCalls != nil && string(message.Content) == "null" { + mediaMessages = []dto.MediaContent{} + } for j, mediaMessage := range mediaMessages { if mediaMessage.Type == dto.ContentTypeImageURL { imageUrl := mediaMessage.GetImageMedia()