|
|
|
|
@@ -19,7 +19,7 @@ import (
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Setting safety to the lowest possible values since Gemini is already powerless enough
|
|
|
|
|
func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatRequest, error) {
|
|
|
|
|
func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest, info *relaycommon.RelayInfo) (*GeminiChatRequest, error) {
|
|
|
|
|
|
|
|
|
|
geminiRequest := GeminiChatRequest{
|
|
|
|
|
Contents: make([]GeminiChatContent, 0, len(textRequest.Messages)),
|
|
|
|
|
@@ -32,6 +32,13 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if model_setting.IsGeminiModelSupportImagine(info.UpstreamModelName) {
|
|
|
|
|
geminiRequest.GenerationConfig.ResponseModalities = []string{
|
|
|
|
|
"TEXT",
|
|
|
|
|
"IMAGE",
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
safetySettings := make([]GeminiChatSafetySettings, 0, len(SafetySettingList))
|
|
|
|
|
for _, category := range SafetySettingList {
|
|
|
|
|
safetySettings = append(safetySettings, GeminiChatSafetySettings{
|
|
|
|
|
@@ -546,9 +553,10 @@ func responseGeminiChat2OpenAI(response *GeminiChatResponse) *dto.OpenAITextResp
|
|
|
|
|
return &fullTextResponse
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func streamResponseGeminiChat2OpenAI(geminiResponse *GeminiChatResponse) (*dto.ChatCompletionsStreamResponse, bool) {
|
|
|
|
|
func streamResponseGeminiChat2OpenAI(geminiResponse *GeminiChatResponse) (*dto.ChatCompletionsStreamResponse, bool, bool) {
|
|
|
|
|
choices := make([]dto.ChatCompletionsStreamResponseChoice, 0, len(geminiResponse.Candidates))
|
|
|
|
|
isStop := false
|
|
|
|
|
hasImage := false
|
|
|
|
|
for _, candidate := range geminiResponse.Candidates {
|
|
|
|
|
if candidate.FinishReason != nil && *candidate.FinishReason == "STOP" {
|
|
|
|
|
isStop = true
|
|
|
|
|
@@ -574,7 +582,13 @@ func streamResponseGeminiChat2OpenAI(geminiResponse *GeminiChatResponse) (*dto.C
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for _, part := range candidate.Content.Parts {
|
|
|
|
|
if part.FunctionCall != nil {
|
|
|
|
|
if part.InlineData != nil {
|
|
|
|
|
if strings.HasPrefix(part.InlineData.MimeType, "image") {
|
|
|
|
|
imgText := ""
|
|
|
|
|
texts = append(texts, imgText)
|
|
|
|
|
hasImage = true
|
|
|
|
|
}
|
|
|
|
|
} else if part.FunctionCall != nil {
|
|
|
|
|
isTools = true
|
|
|
|
|
if call := getResponseToolCall(&part); call != nil {
|
|
|
|
|
call.SetIndex(len(choice.Delta.ToolCalls))
|
|
|
|
|
@@ -602,7 +616,7 @@ func streamResponseGeminiChat2OpenAI(geminiResponse *GeminiChatResponse) (*dto.C
|
|
|
|
|
var response dto.ChatCompletionsStreamResponse
|
|
|
|
|
response.Object = "chat.completion.chunk"
|
|
|
|
|
response.Choices = choices
|
|
|
|
|
return &response, isStop
|
|
|
|
|
return &response, isStop, hasImage
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GeminiChatStreamHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (*dto.OpenAIErrorWithStatusCode, *dto.Usage) {
|
|
|
|
|
@@ -610,20 +624,23 @@ func GeminiChatStreamHandler(c *gin.Context, resp *http.Response, info *relaycom
|
|
|
|
|
id := fmt.Sprintf("chatcmpl-%s", common.GetUUID())
|
|
|
|
|
createAt := common.GetTimestamp()
|
|
|
|
|
var usage = &dto.Usage{}
|
|
|
|
|
var imageCount int
|
|
|
|
|
|
|
|
|
|
helper.StreamScannerHandler(c, resp, info, func(data string) bool {
|
|
|
|
|
var geminiResponse GeminiChatResponse
|
|
|
|
|
err := json.Unmarshal([]byte(data), &geminiResponse)
|
|
|
|
|
err := common.DecodeJsonStr(data, &geminiResponse)
|
|
|
|
|
if err != nil {
|
|
|
|
|
common.LogError(c, "error unmarshalling stream response: "+err.Error())
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response, isStop := streamResponseGeminiChat2OpenAI(&geminiResponse)
|
|
|
|
|
response, isStop, hasImage := streamResponseGeminiChat2OpenAI(&geminiResponse)
|
|
|
|
|
if hasImage {
|
|
|
|
|
imageCount++
|
|
|
|
|
}
|
|
|
|
|
response.Id = id
|
|
|
|
|
response.Created = createAt
|
|
|
|
|
response.Model = info.UpstreamModelName
|
|
|
|
|
// responseText += response.Choices[0].Delta.GetContentString()
|
|
|
|
|
if geminiResponse.UsageMetadata.TotalTokenCount != 0 {
|
|
|
|
|
usage.PromptTokens = geminiResponse.UsageMetadata.PromptTokenCount
|
|
|
|
|
usage.CompletionTokens = geminiResponse.UsageMetadata.CandidatesTokenCount
|
|
|
|
|
@@ -641,6 +658,12 @@ func GeminiChatStreamHandler(c *gin.Context, resp *http.Response, info *relaycom
|
|
|
|
|
|
|
|
|
|
var response *dto.ChatCompletionsStreamResponse
|
|
|
|
|
|
|
|
|
|
if imageCount != 0 {
|
|
|
|
|
if usage.CompletionTokens == 0 {
|
|
|
|
|
usage.CompletionTokens = imageCount * 258
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
usage.TotalTokens = usage.PromptTokens + usage.CompletionTokens
|
|
|
|
|
usage.PromptTokensDetails.TextTokens = usage.PromptTokens
|
|
|
|
|
usage.CompletionTokenDetails.TextTokens = usage.CompletionTokens
|
|
|
|
|
|