Files
bifrost/plugins/compat/requestcopy.go
Beyhan Oğur 880f412e2c first commit
2026-04-26 21:52:23 +03:00

353 lines
9.2 KiB
Go

package compat
import (
"maps"
"slices"
"github.com/maximhq/bifrost/core/schemas"
)
func cloneBifrostReq(req *schemas.BifrostRequest) *schemas.BifrostRequest {
if req == nil {
return nil
}
cloned := *req
if req.TextCompletionRequest != nil && req.TextCompletionRequest.Params != nil {
cloned.TextCompletionRequest.Params = cloneTextCompletionParameters(req.TextCompletionRequest.Params)
}
if req.ChatRequest != nil && req.ChatRequest.Params != nil {
cloned.ChatRequest.Params = cloneChatParameters(req.ChatRequest.Params)
}
if req.ResponsesRequest != nil && req.ResponsesRequest.Params != nil {
cloned.ResponsesRequest.Params = cloneResponsesParameters(req.ResponsesRequest.Params)
}
return &cloned
}
func cloneTextCompletionParameters(params *schemas.TextCompletionParameters) *schemas.TextCompletionParameters {
if params == nil {
return nil
}
cloned := *params
if params.LogitBias != nil {
logitBias := cloneStringFloat64Map(*params.LogitBias)
cloned.LogitBias = &logitBias
}
if params.Stop != nil {
cloned.Stop = slices.Clone(params.Stop)
}
if params.StreamOptions != nil {
streamOptions := *params.StreamOptions
cloned.StreamOptions = &streamOptions
}
if params.ExtraParams != nil {
cloned.ExtraParams = cloneAnyMap(params.ExtraParams)
}
return &cloned
}
func cloneChatParameters(params *schemas.ChatParameters) *schemas.ChatParameters {
if params == nil {
return nil
}
cloned := *params
if params.Audio != nil {
audio := *params.Audio
cloned.Audio = &audio
}
if params.LogitBias != nil {
logitBias := cloneStringFloat64Map(*params.LogitBias)
cloned.LogitBias = &logitBias
}
if params.Metadata != nil {
metadata := cloneAnyMap(*params.Metadata)
cloned.Metadata = &metadata
}
if params.Modalities != nil {
cloned.Modalities = slices.Clone(params.Modalities)
}
if params.Prediction != nil {
prediction := *params.Prediction
prediction.Content = cloneAnyValue(params.Prediction.Content)
cloned.Prediction = &prediction
}
if params.Reasoning != nil {
reasoning := *params.Reasoning
cloned.Reasoning = &reasoning
}
if params.ResponseFormat != nil {
responseFormat := cloneAnyValue(*params.ResponseFormat)
cloned.ResponseFormat = &responseFormat
}
if params.StreamOptions != nil {
streamOptions := *params.StreamOptions
cloned.StreamOptions = &streamOptions
}
if params.Stop != nil {
cloned.Stop = slices.Clone(params.Stop)
}
if params.ToolChoice != nil {
cloned.ToolChoice = cloneChatToolChoice(params.ToolChoice)
}
if params.Tools != nil {
cloned.Tools = make([]schemas.ChatTool, len(params.Tools))
for i, tool := range params.Tools {
cloned.Tools[i] = schemas.DeepCopyChatTool(tool)
}
}
if params.WebSearchOptions != nil {
cloned.WebSearchOptions = cloneChatWebSearchOptions(params.WebSearchOptions)
}
if params.ExtraParams != nil {
cloned.ExtraParams = cloneAnyMap(params.ExtraParams)
}
return &cloned
}
func cloneChatToolChoice(choice *schemas.ChatToolChoice) *schemas.ChatToolChoice {
if choice == nil {
return nil
}
cloned := &schemas.ChatToolChoice{}
if choice.ChatToolChoiceStr != nil {
value := *choice.ChatToolChoiceStr
cloned.ChatToolChoiceStr = &value
}
if choice.ChatToolChoiceStruct != nil {
choiceStruct := *choice.ChatToolChoiceStruct
if choice.ChatToolChoiceStruct.Function != nil {
function := *choice.ChatToolChoiceStruct.Function
choiceStruct.Function = &function
}
if choice.ChatToolChoiceStruct.Custom != nil {
custom := *choice.ChatToolChoiceStruct.Custom
choiceStruct.Custom = &custom
}
if choice.ChatToolChoiceStruct.AllowedTools != nil {
allowedTools := *choice.ChatToolChoiceStruct.AllowedTools
allowedTools.Tools = slices.Clone(choice.ChatToolChoiceStruct.AllowedTools.Tools)
choiceStruct.AllowedTools = &allowedTools
}
cloned.ChatToolChoiceStruct = &choiceStruct
}
return cloned
}
func cloneChatWebSearchOptions(options *schemas.ChatWebSearchOptions) *schemas.ChatWebSearchOptions {
if options == nil {
return nil
}
cloned := *options
if options.UserLocation != nil {
userLocation := *options.UserLocation
if options.UserLocation.Approximate != nil {
approximate := *options.UserLocation.Approximate
userLocation.Approximate = &approximate
}
cloned.UserLocation = &userLocation
}
return &cloned
}
func cloneResponsesParameters(params *schemas.ResponsesParameters) *schemas.ResponsesParameters {
if params == nil {
return nil
}
cloned := *params
if params.Include != nil {
cloned.Include = slices.Clone(params.Include)
}
if params.Metadata != nil {
metadata := cloneAnyMap(*params.Metadata)
cloned.Metadata = &metadata
}
if params.Reasoning != nil {
reasoning := *params.Reasoning
cloned.Reasoning = &reasoning
}
if params.StreamOptions != nil {
streamOptions := *params.StreamOptions
cloned.StreamOptions = &streamOptions
}
if params.Text != nil {
cloned.Text = cloneResponsesTextConfig(params.Text)
}
if params.ToolChoice != nil {
cloned.ToolChoice = cloneResponsesToolChoice(params.ToolChoice)
}
if params.Tools != nil {
cloned.Tools = make([]schemas.ResponsesTool, len(params.Tools))
for i, tool := range params.Tools {
cloned.Tools[i] = cloneResponsesTool(tool)
}
}
if params.ExtraParams != nil {
cloned.ExtraParams = cloneAnyMap(params.ExtraParams)
}
return &cloned
}
func cloneResponsesTextConfig(text *schemas.ResponsesTextConfig) *schemas.ResponsesTextConfig {
if text == nil {
return nil
}
cloned := *text
if text.Format != nil {
format := *text.Format
if text.Format.JSONSchema != nil {
jsonSchema := *text.Format.JSONSchema
if text.Format.JSONSchema.Schema != nil {
schema := cloneAnyValue(*text.Format.JSONSchema.Schema)
jsonSchema.Schema = &schema
}
if text.Format.JSONSchema.Properties != nil {
properties := cloneAnyMap(*text.Format.JSONSchema.Properties)
jsonSchema.Properties = &properties
}
if text.Format.JSONSchema.Required != nil {
jsonSchema.Required = slices.Clone(text.Format.JSONSchema.Required)
}
if text.Format.JSONSchema.Defs != nil {
defs := cloneAnyMap(*text.Format.JSONSchema.Defs)
jsonSchema.Defs = &defs
}
if text.Format.JSONSchema.Definitions != nil {
definitions := cloneAnyMap(*text.Format.JSONSchema.Definitions)
jsonSchema.Definitions = &definitions
}
if text.Format.JSONSchema.Items != nil {
items := cloneAnyMap(*text.Format.JSONSchema.Items)
jsonSchema.Items = &items
}
if text.Format.JSONSchema.AnyOf != nil {
jsonSchema.AnyOf = cloneAnyMapSlice(text.Format.JSONSchema.AnyOf)
}
if text.Format.JSONSchema.OneOf != nil {
jsonSchema.OneOf = cloneAnyMapSlice(text.Format.JSONSchema.OneOf)
}
if text.Format.JSONSchema.AllOf != nil {
jsonSchema.AllOf = cloneAnyMapSlice(text.Format.JSONSchema.AllOf)
}
if text.Format.JSONSchema.Default != nil {
jsonSchema.Default = cloneAnyValue(text.Format.JSONSchema.Default)
}
if text.Format.JSONSchema.Enum != nil {
jsonSchema.Enum = slices.Clone(text.Format.JSONSchema.Enum)
}
if text.Format.JSONSchema.PropertyOrdering != nil {
jsonSchema.PropertyOrdering = slices.Clone(text.Format.JSONSchema.PropertyOrdering)
}
format.JSONSchema = &jsonSchema
}
cloned.Format = &format
}
return &cloned
}
func cloneResponsesToolChoice(choice *schemas.ResponsesToolChoice) *schemas.ResponsesToolChoice {
if choice == nil {
return nil
}
cloned := &schemas.ResponsesToolChoice{}
if choice.ResponsesToolChoiceStr != nil {
value := *choice.ResponsesToolChoiceStr
cloned.ResponsesToolChoiceStr = &value
}
if choice.ResponsesToolChoiceStruct != nil {
choiceStruct := *choice.ResponsesToolChoiceStruct
if choice.ResponsesToolChoiceStruct.Tools != nil {
choiceStruct.Tools = slices.Clone(choice.ResponsesToolChoiceStruct.Tools)
}
cloned.ResponsesToolChoiceStruct = &choiceStruct
}
return cloned
}
func cloneResponsesTool(tool schemas.ResponsesTool) schemas.ResponsesTool {
data, err := schemas.MarshalSorted(tool)
if err != nil {
return tool
}
var cloned schemas.ResponsesTool
if err := schemas.Unmarshal(data, &cloned); err != nil {
return tool
}
return cloned
}
func cloneStringFloat64Map(input map[string]float64) map[string]float64 {
if input == nil {
return nil
}
cloned := make(map[string]float64, len(input))
maps.Copy(cloned, input)
return cloned
}
func cloneAnyMap(input map[string]any) map[string]any {
if input == nil {
return nil
}
cloned := make(map[string]any, len(input))
for key, value := range input {
cloned[key] = cloneAnyValue(value)
}
return cloned
}
func cloneAnyMapSlice(input []map[string]any) []map[string]any {
if input == nil {
return nil
}
cloned := make([]map[string]any, len(input))
for i, value := range input {
cloned[i] = cloneAnyMap(value)
}
return cloned
}
func cloneAnySlice(input []any) []any {
if input == nil {
return nil
}
cloned := make([]any, len(input))
for i, value := range input {
cloned[i] = cloneAnyValue(value)
}
return cloned
}
func cloneAnyValue(value any) any {
switch typed := value.(type) {
case nil:
return nil
case map[string]any:
return cloneAnyMap(typed)
case []any:
return cloneAnySlice(typed)
case []string:
return slices.Clone(typed)
case map[string]string:
cloned := make(map[string]string, len(typed))
maps.Copy(cloned, typed)
return cloned
default:
return typed
}
}