first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

View File

@@ -0,0 +1,212 @@
package openai
import (
"encoding/base64"
"fmt"
"mime/multipart"
"net/http"
"github.com/maximhq/bifrost/core/providers/utils"
providerUtils "github.com/maximhq/bifrost/core/providers/utils"
"github.com/maximhq/bifrost/core/schemas"
)
// ToOpenAIVideoGenerationRequest converts a Bifrost Video Request to OpenAI format
func ToOpenAIVideoGenerationRequest(bifrostReq *schemas.BifrostVideoGenerationRequest) (*OpenAIVideoGenerationRequest, error) {
if bifrostReq == nil || bifrostReq.Input == nil || bifrostReq.Input.Prompt == "" {
return nil, fmt.Errorf("bifrost request, input, or prompt is nil/empty")
}
req := &OpenAIVideoGenerationRequest{
Model: bifrostReq.Model,
Prompt: bifrostReq.Input.Prompt,
}
if bifrostReq.Input.InputReference != nil {
// convert base64 to bytes
sanitizedURL, err := schemas.SanitizeImageURL(*bifrostReq.Input.InputReference)
if err != nil {
return nil, fmt.Errorf("invalid input reference: %w", err)
}
urlInfo := schemas.ExtractURLTypeInfo(sanitizedURL)
if urlInfo.DataURLWithoutPrefix != nil {
bytes, err := base64.StdEncoding.DecodeString(*urlInfo.DataURLWithoutPrefix)
if err != nil {
return nil, fmt.Errorf("failed to decode base64 input reference: %w", err)
}
req.InputReference = bytes
} else {
return nil, fmt.Errorf("input_reference must be a base64 data URL (e.g. data:image/png;base64,...)")
}
}
if bifrostReq.Params != nil {
if bifrostReq.Params.Seconds != nil {
req.Seconds = bifrostReq.Params.Seconds
}
// Validate and set size
if bifrostReq.Params.Size != "" {
// Check if the provided size is valid
if ValidOpenAIVideoSizes[bifrostReq.Params.Size] {
req.Size = bifrostReq.Params.Size
} else {
// Invalid size provided, use default
req.Size = string(DefaultOpenAIVideoSize)
}
} else {
// No size provided, use default
req.Size = string(DefaultOpenAIVideoSize)
}
req.ExtraParams = bifrostReq.Params.ExtraParams
}
return req, nil
}
func ToOpenAIVideoRemixRequest(bifrostReq *schemas.BifrostVideoRemixRequest) (*OpenAIVideoRemixRequest, error) {
if bifrostReq == nil || bifrostReq.Input == nil || bifrostReq.Input.Prompt == "" {
return nil, fmt.Errorf("bifrost request, input, or prompt is nil/empty")
}
req := &OpenAIVideoRemixRequest{
Prompt: bifrostReq.Input.Prompt,
}
return req, nil
}
func ToBifrostVideoRemixRequest(openaiReq *OpenAIVideoRemixRequest) *schemas.BifrostVideoRemixRequest {
if openaiReq == nil || openaiReq.Prompt == "" {
return nil
}
provider := openaiReq.Provider
if provider == "" {
provider = schemas.OpenAI
}
return &schemas.BifrostVideoRemixRequest{
ID: openaiReq.ID,
Provider: provider,
Input: &schemas.VideoGenerationInput{
Prompt: openaiReq.Prompt,
},
}
}
func (req *OpenAIVideoGenerationRequest) ToBifrostVideoGenerationRequest(ctx *schemas.BifrostContext) *schemas.BifrostVideoGenerationRequest {
if req == nil {
return nil
}
defaultProvider := schemas.OpenAI
// for requests coming from azure sdk without provider prefix, we need to set the default provider to azure
if ctx != nil {
if isAzureUser, ok := ctx.Value(schemas.BifrostContextKeyIsAzureUserAgent).(bool); ok && isAzureUser {
defaultProvider = schemas.Azure
}
}
provider, model := schemas.ParseModelString(req.Model, utils.CheckAndSetDefaultProvider(ctx, defaultProvider))
input := &schemas.VideoGenerationInput{
Prompt: req.Prompt,
}
if req.InputReference != nil {
input.InputReference = schemas.Ptr(providerUtils.FileBytesToBase64DataURL(req.InputReference))
}
return &schemas.BifrostVideoGenerationRequest{
Provider: provider,
Model: model,
Input: input,
Params: &req.VideoGenerationParameters,
Fallbacks: schemas.ParseFallbacks(req.Fallbacks),
}
}
// parseVideoGenerationFormDataBodyFromRequest parses the video generation request and writes it to the multipart form.
func parseVideoGenerationFormDataBodyFromRequest(writer *multipart.Writer, openaiReq *OpenAIVideoGenerationRequest, providerName schemas.ModelProvider) *schemas.BifrostError {
// Add prompt field (required)
if openaiReq.Prompt == "" {
return providerUtils.NewBifrostOperationError("prompt is required", nil)
}
if err := writer.WriteField("prompt", openaiReq.Prompt); err != nil {
return providerUtils.NewBifrostOperationError("failed to write prompt field", err)
}
// Add optional model field
if openaiReq.Model != "" {
if err := writer.WriteField("model", openaiReq.Model); err != nil {
return providerUtils.NewBifrostOperationError("failed to write model field", err)
}
}
// Add optional seconds field
if openaiReq.Seconds != nil {
if err := writer.WriteField("seconds", *openaiReq.Seconds); err != nil {
return providerUtils.NewBifrostOperationError("failed to write seconds field", err)
}
}
// Add optional size field
if openaiReq.Size != "" {
if err := writer.WriteField("size", openaiReq.Size); err != nil {
return providerUtils.NewBifrostOperationError("failed to write size field", err)
}
}
// Add optional input_reference field (image or video file)
if len(openaiReq.InputReference) > 0 {
// Detect MIME type
mimeType := http.DetectContentType(openaiReq.InputReference)
// Validate and set proper MIME type
validMimeTypes := map[string]bool{
"image/jpeg": true,
"image/png": true,
"image/webp": true,
"video/mp4": true,
}
if !validMimeTypes[mimeType] {
// Default to image/png if not detected properly
mimeType = "image/png"
}
// Determine filename based on MIME type
var filename string
switch mimeType {
case "image/jpeg":
filename = "input_reference.jpg"
case "image/webp":
filename = "input_reference.webp"
case "video/mp4":
filename = "input_reference.mp4"
default:
filename = "input_reference.png"
}
// Create form part with proper Content-Type header
part, err := writer.CreatePart(map[string][]string{
"Content-Disposition": {fmt.Sprintf(`form-data; name="input_reference"; filename="%s"`, filename)},
"Content-Type": {mimeType},
})
if err != nil {
return providerUtils.NewBifrostOperationError("failed to create form part for input_reference", err)
}
if _, err := part.Write(openaiReq.InputReference); err != nil {
return providerUtils.NewBifrostOperationError("failed to write input_reference file data", err)
}
}
// Close the multipart writer
if err := writer.Close(); err != nil {
return providerUtils.NewBifrostOperationError("failed to close multipart writer", err)
}
return nil
}