mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-18 20:30:51 +08:00
feat(translator): enhance OpenAI Gemini request handling for mixed content
- Replaced `contentParts` with `aggregatedParts` to support mixed content (text and inline data). - Introduced `textBuilder` for efficient text concatenation. - Added support for inline data processing, including base64-encoded image URLs. - Updated `msg["content"]` logic to handle both plain text and mixed content scenarios.
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -100,14 +101,40 @@ func ConvertGeminiRequestToOpenAI(modelName string, inputRawJSON []byte, stream
|
|||||||
"content": "",
|
"content": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
var contentParts []string
|
var textBuilder strings.Builder
|
||||||
|
var aggregatedParts []interface{}
|
||||||
|
onlyTextContent := true
|
||||||
var toolCalls []interface{}
|
var toolCalls []interface{}
|
||||||
|
|
||||||
if parts.Exists() && parts.IsArray() {
|
if parts.Exists() && parts.IsArray() {
|
||||||
parts.ForEach(func(_, part gjson.Result) bool {
|
parts.ForEach(func(_, part gjson.Result) bool {
|
||||||
// Handle text parts
|
// Handle text parts
|
||||||
if text := part.Get("text"); text.Exists() {
|
if text := part.Get("text"); text.Exists() {
|
||||||
contentParts = append(contentParts, text.String())
|
formattedText := text.String()
|
||||||
|
textBuilder.WriteString(formattedText)
|
||||||
|
aggregatedParts = append(aggregatedParts, map[string]interface{}{
|
||||||
|
"type": "text",
|
||||||
|
"text": formattedText,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle inline data (e.g., images)
|
||||||
|
if inlineData := part.Get("inlineData"); inlineData.Exists() {
|
||||||
|
onlyTextContent = false
|
||||||
|
|
||||||
|
mimeType := inlineData.Get("mimeType").String()
|
||||||
|
if mimeType == "" {
|
||||||
|
mimeType = "application/octet-stream"
|
||||||
|
}
|
||||||
|
data := inlineData.Get("data").String()
|
||||||
|
imageURL := fmt.Sprintf("data:%s;base64,%s", mimeType, data)
|
||||||
|
|
||||||
|
aggregatedParts = append(aggregatedParts, map[string]interface{}{
|
||||||
|
"type": "image_url",
|
||||||
|
"image_url": map[string]interface{}{
|
||||||
|
"url": imageURL,
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle function calls (Gemini) -> tool calls (OpenAI)
|
// Handle function calls (Gemini) -> tool calls (OpenAI)
|
||||||
@@ -175,8 +202,12 @@ func ConvertGeminiRequestToOpenAI(modelName string, inputRawJSON []byte, stream
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set content
|
// Set content
|
||||||
if len(contentParts) > 0 {
|
if len(aggregatedParts) > 0 {
|
||||||
msg["content"] = strings.Join(contentParts, "")
|
if onlyTextContent {
|
||||||
|
msg["content"] = textBuilder.String()
|
||||||
|
} else {
|
||||||
|
msg["content"] = aggregatedParts
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set tool calls if any
|
// Set tool calls if any
|
||||||
|
|||||||
Reference in New Issue
Block a user