86 lines
2.3 KiB
Go
86 lines
2.3 KiB
Go
package helps
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/router-for-me/CLIProxyAPI/v7/internal/util"
|
|
"github.com/tidwall/gjson"
|
|
"github.com/tidwall/sjson"
|
|
)
|
|
|
|
// StripVertexOpenAIResponsesToolCallIDs removes OpenAI Responses call IDs that
|
|
// Vertex rejects in Gemini functionCall/functionResponse payloads.
|
|
func StripVertexOpenAIResponsesToolCallIDs(payload []byte, sourceFormat string) []byte {
|
|
if !strings.EqualFold(strings.TrimSpace(sourceFormat), "openai-response") {
|
|
return payload
|
|
}
|
|
|
|
contents := util.GetGJSONBytesNoCopy(payload, "contents")
|
|
if !contents.IsArray() || !vertexContentsHaveToolCallIDs(contents) {
|
|
return payload
|
|
}
|
|
|
|
contentsChanged := false
|
|
contentItems := make([][]byte, 0, int(contents.Get("#").Int()))
|
|
contents.ForEach(func(_, content gjson.Result) bool {
|
|
parts := content.Get("parts")
|
|
if !parts.IsArray() {
|
|
contentItems = append(contentItems, []byte(content.Raw))
|
|
return true
|
|
}
|
|
|
|
partsChanged := false
|
|
partItems := make([][]byte, 0, int(parts.Get("#").Int()))
|
|
parts.ForEach(func(_, part gjson.Result) bool {
|
|
partJSON := []byte(part.Raw)
|
|
for _, path := range []string{"functionCall.id", "functionResponse.id"} {
|
|
if !part.Get(path).Exists() {
|
|
continue
|
|
}
|
|
updated, errDelete := sjson.DeleteBytes(partJSON, path)
|
|
if errDelete == nil {
|
|
partJSON = updated
|
|
partsChanged = true
|
|
}
|
|
}
|
|
partItems = append(partItems, partJSON)
|
|
return true
|
|
})
|
|
|
|
contentJSON := []byte(content.Raw)
|
|
if partsChanged {
|
|
updated, errSet := sjson.SetRawBytes(contentJSON, "parts", JoinRawJSONArray(partItems))
|
|
if errSet == nil {
|
|
contentJSON = updated
|
|
contentsChanged = true
|
|
}
|
|
}
|
|
contentItems = append(contentItems, contentJSON)
|
|
return true
|
|
})
|
|
if !contentsChanged {
|
|
return payload
|
|
}
|
|
|
|
updated, errSet := sjson.SetRawBytes(payload, "contents", JoinRawJSONArray(contentItems))
|
|
if errSet != nil {
|
|
return payload
|
|
}
|
|
return updated
|
|
}
|
|
|
|
func vertexContentsHaveToolCallIDs(contents gjson.Result) bool {
|
|
hasIDs := false
|
|
contents.ForEach(func(_, content gjson.Result) bool {
|
|
parts := content.Get("parts")
|
|
if !parts.IsArray() {
|
|
return true
|
|
}
|
|
parts.ForEach(func(_, part gjson.Result) bool {
|
|
hasIDs = part.Get("functionCall.id").Exists() || part.Get("functionResponse.id").Exists()
|
|
return !hasIDs
|
|
})
|
|
return !hasIDs
|
|
})
|
|
return hasIDs
|
|
}
|