|
|
@@ -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
|