Files
bifrost/core/providers/openai/transcription.go
Beyhan Oğur 880f412e2c first commit
2026-04-26 21:52:23 +03:00

118 lines
4.0 KiB
Go

package openai
import (
"fmt"
"mime/multipart"
"github.com/maximhq/bifrost/core/providers/utils"
"github.com/maximhq/bifrost/core/schemas"
)
// ToBifrostTranscriptionRequest converts an OpenAI transcription request to Bifrost format
func (request *OpenAITranscriptionRequest) ToBifrostTranscriptionRequest(ctx *schemas.BifrostContext) *schemas.BifrostTranscriptionRequest {
provider, model := schemas.ParseModelString(request.Model, utils.CheckAndSetDefaultProvider(ctx, schemas.OpenAI))
return &schemas.BifrostTranscriptionRequest{
Provider: provider,
Model: model,
Input: &schemas.TranscriptionInput{
File: request.File,
},
Params: &request.TranscriptionParameters,
Fallbacks: schemas.ParseFallbacks(request.Fallbacks),
}
}
// ToOpenAITranscriptionRequest converts a Bifrost transcription request to OpenAI format
func ToOpenAITranscriptionRequest(bifrostReq *schemas.BifrostTranscriptionRequest) *OpenAITranscriptionRequest {
if bifrostReq == nil || bifrostReq.Input.File == nil {
return nil
}
transcriptionInput := bifrostReq.Input
params := bifrostReq.Params
openaiReq := &OpenAITranscriptionRequest{
Model: bifrostReq.Model,
File: transcriptionInput.File,
Filename: transcriptionInput.Filename,
}
if params != nil {
openaiReq.TranscriptionParameters = *params
}
return openaiReq
}
// ParseTranscriptionFormDataBodyFromRequest parses the transcription request and writes it to the multipart form.
func ParseTranscriptionFormDataBodyFromRequest(writer *multipart.Writer, openaiReq *OpenAITranscriptionRequest, providerName schemas.ModelProvider) *schemas.BifrostError {
// Add model field before the file so upstreams can route without buffering the audio payload.
if err := writer.WriteField("model", openaiReq.Model); err != nil {
return utils.NewBifrostOperationError("failed to write model field", err)
}
// Add optional fields
if openaiReq.Language != nil {
if err := writer.WriteField("language", *openaiReq.Language); err != nil {
return utils.NewBifrostOperationError("failed to write language field", err)
}
}
if openaiReq.Prompt != nil {
if err := writer.WriteField("prompt", *openaiReq.Prompt); err != nil {
return utils.NewBifrostOperationError("failed to write prompt field", err)
}
}
if openaiReq.ResponseFormat != nil {
if err := writer.WriteField("response_format", *openaiReq.ResponseFormat); err != nil {
return utils.NewBifrostOperationError("failed to write response_format field", err)
}
}
if openaiReq.Temperature != nil {
if err := writer.WriteField("temperature", fmt.Sprintf("%g", *openaiReq.Temperature)); err != nil {
return utils.NewBifrostOperationError("failed to write temperature field", err)
}
}
for _, granularity := range openaiReq.TimestampGranularities {
if err := writer.WriteField("timestamp_granularities[]", granularity); err != nil {
return utils.NewBifrostOperationError("failed to write timestamp_granularities field", err)
}
}
for _, include := range openaiReq.Include {
if err := writer.WriteField("include[]", include); err != nil {
return utils.NewBifrostOperationError("failed to write include field", err)
}
}
if openaiReq.Stream != nil && *openaiReq.Stream {
if err := writer.WriteField("stream", "true"); err != nil {
return utils.NewBifrostOperationError("failed to write stream field", err)
}
}
// Add file field last so large multipart uploads don't block model discovery upstream.
filename := openaiReq.Filename
if filename == "" {
filename = utils.AudioFilenameFromBytes(openaiReq.File)
}
fileWriter, err := writer.CreateFormFile("file", filename)
if err != nil {
return utils.NewBifrostOperationError("failed to create form file", err)
}
if _, err := fileWriter.Write(openaiReq.File); err != nil {
return utils.NewBifrostOperationError("failed to write file data", err)
}
// Close the multipart writer
if err := writer.Close(); err != nil {
return utils.NewBifrostOperationError("failed to close multipart writer", err)
}
return nil
}