feat: Add FunctionResponse type and enhance GeminiPart structure
- Introduced a new `FunctionResponse` type to encapsulate function call responses, improving the clarity of data handling. - Updated the `GeminiPart` struct to include the new `FunctionResponse` field, allowing for better representation of function call results in Gemini requests. - Modified the `CovertGemini2OpenAI` function to handle tool calls more effectively by setting the message role and appending function responses to the Gemini parts, enhancing the integration with OpenAI and Gemini systems.
This commit is contained in:
@@ -18,10 +18,16 @@ type FunctionCall struct {
|
|||||||
Arguments any `json:"args"`
|
Arguments any `json:"args"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FunctionResponse struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Response any `json:"response"`
|
||||||
|
}
|
||||||
|
|
||||||
type GeminiPart struct {
|
type GeminiPart struct {
|
||||||
Text string `json:"text,omitempty"`
|
Text string `json:"text,omitempty"`
|
||||||
InlineData *GeminiInlineData `json:"inlineData,omitempty"`
|
InlineData *GeminiInlineData `json:"inlineData,omitempty"`
|
||||||
FunctionCall *FunctionCall `json:"functionCall,omitempty"`
|
FunctionCall *FunctionCall `json:"functionCall,omitempty"`
|
||||||
|
FunctionResponse *FunctionResponse `json:"functionResponse,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GeminiChatContent struct {
|
type GeminiChatContent struct {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package gemini
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -108,16 +109,14 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
} else if message.Role == "tool" {
|
|
||||||
message.Role = "model"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var parts []GeminiPart
|
var parts []GeminiPart
|
||||||
content := GeminiChatContent{
|
content := GeminiChatContent{
|
||||||
Role: message.Role,
|
Role: message.Role,
|
||||||
}
|
}
|
||||||
isToolCall := false
|
isToolCall := false
|
||||||
if message.ToolCalls != nil {
|
if message.ToolCalls != nil {
|
||||||
|
message.Role = "model"
|
||||||
isToolCall = true
|
isToolCall = true
|
||||||
for _, call := range message.ParseToolCalls() {
|
for _, call := range message.ParseToolCalls() {
|
||||||
toolCall := GeminiPart{
|
toolCall := GeminiPart{
|
||||||
@@ -130,40 +129,55 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isToolCall {
|
if !isToolCall {
|
||||||
openaiContent := message.ParseContent()
|
if message.Role == "tool" {
|
||||||
imageNum := 0
|
content.Role = "user"
|
||||||
for _, part := range openaiContent {
|
name := ""
|
||||||
if part.Type == dto.ContentTypeText {
|
if message.Name != nil {
|
||||||
parts = append(parts, GeminiPart{
|
name = *message.Name
|
||||||
Text: part.Text,
|
}
|
||||||
})
|
functionResp := &FunctionResponse{
|
||||||
} else if part.Type == dto.ContentTypeImageURL {
|
Name: name,
|
||||||
imageNum += 1
|
Response: common.StrToMap(message.StringContent()),
|
||||||
|
}
|
||||||
|
parts = append(parts, GeminiPart{
|
||||||
|
FunctionResponse: functionResp,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
openaiContent := message.ParseContent()
|
||||||
|
imageNum := 0
|
||||||
|
for _, part := range openaiContent {
|
||||||
|
if part.Type == dto.ContentTypeText {
|
||||||
|
parts = append(parts, GeminiPart{
|
||||||
|
Text: part.Text,
|
||||||
|
})
|
||||||
|
} else if part.Type == dto.ContentTypeImageURL {
|
||||||
|
imageNum += 1
|
||||||
|
|
||||||
if constant.GeminiVisionMaxImageNum != -1 && imageNum > constant.GeminiVisionMaxImageNum {
|
if constant.GeminiVisionMaxImageNum != -1 && imageNum > constant.GeminiVisionMaxImageNum {
|
||||||
return nil, fmt.Errorf("too many images in the message, max allowed is %d", constant.GeminiVisionMaxImageNum)
|
return nil, fmt.Errorf("too many images in the message, max allowed is %d", constant.GeminiVisionMaxImageNum)
|
||||||
}
|
}
|
||||||
// 判断是否是url
|
// 判断是否是url
|
||||||
if strings.HasPrefix(part.ImageUrl.(dto.MessageImageUrl).Url, "http") {
|
if strings.HasPrefix(part.ImageUrl.(dto.MessageImageUrl).Url, "http") {
|
||||||
// 是url,获取图片的类型和base64编码的数据
|
// 是url,获取图片的类型和base64编码的数据
|
||||||
mimeType, data, _ := service.GetImageFromUrl(part.ImageUrl.(dto.MessageImageUrl).Url)
|
mimeType, data, _ := service.GetImageFromUrl(part.ImageUrl.(dto.MessageImageUrl).Url)
|
||||||
parts = append(parts, GeminiPart{
|
parts = append(parts, GeminiPart{
|
||||||
InlineData: &GeminiInlineData{
|
InlineData: &GeminiInlineData{
|
||||||
MimeType: mimeType,
|
MimeType: mimeType,
|
||||||
Data: data,
|
Data: data,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
_, format, base64String, err := service.DecodeBase64ImageData(part.ImageUrl.(dto.MessageImageUrl).Url)
|
_, format, base64String, err := service.DecodeBase64ImageData(part.ImageUrl.(dto.MessageImageUrl).Url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("decode base64 image data failed: %s", err.Error())
|
return nil, fmt.Errorf("decode base64 image data failed: %s", err.Error())
|
||||||
|
}
|
||||||
|
parts = append(parts, GeminiPart{
|
||||||
|
InlineData: &GeminiInlineData{
|
||||||
|
MimeType: "image/" + format,
|
||||||
|
Data: base64String,
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
parts = append(parts, GeminiPart{
|
|
||||||
InlineData: &GeminiInlineData{
|
|
||||||
MimeType: "image/" + format,
|
|
||||||
Data: base64String,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,6 +190,7 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
|
|||||||
}
|
}
|
||||||
geminiRequest.Contents = append(geminiRequest.Contents, content)
|
geminiRequest.Contents = append(geminiRequest.Contents, content)
|
||||||
}
|
}
|
||||||
|
common.LogJson(context.Background(), "gemini_request", geminiRequest)
|
||||||
return &geminiRequest, nil
|
return &geminiRequest, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user