package schemas // VideoStatus is the lifecycle status of a video job. type VideoStatus string const ( VideoStatusQueued VideoStatus = "queued" VideoStatusInProgress VideoStatus = "in_progress" VideoStatusCompleted VideoStatus = "completed" VideoStatusFailed VideoStatus = "failed" ) type VideoOutputType string const ( VideoOutputTypeBase64 VideoOutputType = "base64" VideoOutputTypeURL VideoOutputType = "url" ) // VideoCreateError is the error payload when video generation fails. type VideoCreateError struct { Code string `json:"code,omitempty"` Message string `json:"message,omitempty"` } // ContentFilterInfo contains information about content that was filtered due to safety policies. // This is a provider-agnostic structure for representing content filtering results. type ContentFilterInfo struct { FilteredCount int `json:"filtered_count,omitempty"` // Number of items filtered Reasons []string `json:"reasons,omitempty"` // Human-readable reasons for filtering } type VideoOutput struct { Type VideoOutputType `json:"type"` // "url" | "base64" URL *string `json:"url,omitempty"` Base64Data *string `json:"base64,omitempty"` ContentType string `json:"content_type"` } // VideoReferenceInput represents a reference image for video generation type VideoReferenceInput struct { Image []byte `json:"image"` // Image bytes ReferenceType string `json:"reference_type,omitempty"` // "style" or "asset" (Gemini: "REFERENCE_TYPE_STYLE" or "REFERENCE_TYPE_ASSET") } type VideoObject struct { ID string `json:"id"` Object string `json:"object"` // always "video" Model string `json:"model"` Status VideoStatus `json:"status"` CreatedAt int64 `json:"created_at"` CompletedAt *int64 `json:"completed_at,omitempty"` ExpiresAt *int64 `json:"expires_at,omitempty"` Progress *float64 `json:"progress,omitempty"` Prompt string `json:"prompt"` RemixedFromVideoID *string `json:"remixed_from_video_id,omitempty"` Seconds *string `json:"seconds"` Size string `json:"size"` Error *VideoCreateError `json:"error,omitempty"` } // --- Video Generation --- type BifrostVideoGenerationRequest struct { Provider ModelProvider `json:"provider"` Model string `json:"model"` Input *VideoGenerationInput `json:"input"` Params *VideoGenerationParameters `json:"params,omitempty"` Fallbacks []Fallback `json:"fallbacks,omitempty"` RawRequestBody []byte `json:"-"` } func (b *BifrostVideoGenerationRequest) GetRawRequestBody() []byte { return b.RawRequestBody } func (b *BifrostVideoGenerationRequest) GetExtraParams() map[string]interface{} { if b == nil || b.Params == nil { return nil } return b.Params.ExtraParams } type VideoGenerationInput struct { Prompt string `json:"prompt"` InputReference *string `json:"input_reference,omitempty"` // Primary image for image-to-video (OpenAI-compatible) } type VideoGenerationParameters struct { Seconds *string `json:"seconds,omitempty"` Size string `json:"size,omitempty"` NegativePrompt *string `json:"negative_prompt,omitempty"` Seed *int `json:"seed,omitempty"` VideoURI *string `json:"video_uri,omitempty"` // for video to video generation Audio *bool `json:"audio,omitempty"` ExtraParams map[string]any `json:"-"` } // DefaultVideoDuration is the default video duration in seconds for Gemini/Vertex when not specified. const DefaultVideoDuration = "8" // BifrostVideoGenerationResponse represents the video generation job response in bifrost format. type BifrostVideoGenerationResponse struct { ID string `json:"id,omitempty"` CompletedAt *int64 `json:"completed_at,omitempty"` // Unix timestamp (seconds) when the job completed CreatedAt int64 `json:"created_at,omitempty"` // Unix timestamp (seconds) when the job was created Error *VideoCreateError `json:"error,omitempty"` // Error payload if generation failed ExpiresAt *int64 `json:"expires_at,omitempty"` // Unix timestamp (seconds) when downloadable assets expire Model string `json:"model,omitempty"` // Video generation model that produced the job Object string `json:"object,omitempty"` // Object type, always "video" Progress *float64 `json:"progress,omitempty"` // Approximate completion percentage (0-100) Prompt string `json:"prompt,omitempty"` // Prompt used to generate the video RemixedFromVideoID *string `json:"remixed_from_video_id,omitempty"` // Source video ID if this is a remix Seconds *string `json:"seconds,omitempty"` // Duration of the generated clip in seconds Size string `json:"size,omitempty"` // Resolution of the generated video Status VideoStatus `json:"status,omitempty"` // Current lifecycle status of the video job Videos []VideoOutput `json:"videos,omitempty"` // Generated videos (supports multiple videos) ContentFilter *ContentFilterInfo `json:"content_filter,omitempty"` // Information about content filtering (if applicable) ExtraFields BifrostResponseExtraFields `json:"extra_fields,omitempty"` } // getSecondsFromVideoRequest extracts Seconds from video-related requests. func getSecondsFromVideoRequest(req *BifrostRequest) *string { if req == nil { return nil } useDefaultForSeconds := func(p ModelProvider) bool { return p == Gemini || p == Vertex } if req.VideoGenerationRequest != nil { var seconds *string if req.VideoGenerationRequest.Params != nil { seconds = req.VideoGenerationRequest.Params.Seconds } if seconds == nil && useDefaultForSeconds(req.VideoGenerationRequest.Provider) { seconds = Ptr(DefaultVideoDuration) } return seconds } if req.VideoRemixRequest != nil && useDefaultForSeconds(req.VideoRemixRequest.Provider) { return Ptr(DefaultVideoDuration) } return nil } // BackfillParams populates response fields from the original request that are needed // for cost calculation but may not be returned by the provider. // - Seconds (duration from request params or default) func (r *BifrostVideoGenerationResponse) BackfillParams(req *BifrostRequest) { if r == nil || req == nil { return } seconds := getSecondsFromVideoRequest(req) if seconds != nil { r.Seconds = seconds } if r.Model == "" && req.VideoGenerationRequest != nil { r.Model = req.VideoGenerationRequest.Model } } // --- Video Remix --- type BifrostVideoRemixRequest struct { ID string `json:"id"` Provider ModelProvider `json:"provider"` Input *VideoGenerationInput `json:"input"` ExtraParams map[string]any `json:"-"` RawRequestBody []byte `json:"-"` } func (b *BifrostVideoRemixRequest) GetRawRequestBody() []byte { return b.RawRequestBody } func (b *BifrostVideoRemixRequest) GetExtraParams() map[string]interface{} { if b == nil { return nil } return b.ExtraParams } // --- Video List --- type BifrostVideoListRequest struct { Provider ModelProvider `json:"provider"` After *string `json:"after,omitempty"` Limit *int `json:"limit,omitempty"` Order *string `json:"order,omitempty"` } type BifrostVideoListResponse struct { Object string `json:"object"` // "list" Data []VideoObject `json:"data"` FirstID *string `json:"first_id,omitempty"` HasMore *bool `json:"has_more,omitempty"` LastID *string `json:"last_id,omitempty"` ExtraFields BifrostResponseExtraFields `json:"extra_fields"` } // --- Video Retrieve / Delete --- type BifrostVideoReferenceRequest struct { Provider ModelProvider `json:"provider"` ID string `json:"id"` } type BifrostVideoDeleteRequest = BifrostVideoReferenceRequest type BifrostVideoRetrieveRequest = BifrostVideoReferenceRequest type BifrostVideoDeleteResponse struct { ID string `json:"id"` Deleted bool `json:"deleted"` Object string `json:"object,omitempty"` // "video.deleted" ExtraFields BifrostResponseExtraFields `json:"extra_fields"` } // --- Video Download --- type BifrostVideoDownloadRequest struct { Provider ModelProvider `json:"provider"` ID string `json:"id"` Variant *VideoDownloadVariant `json:"variant,omitempty"` ExtraParams map[string]any `json:"-"` } type VideoDownloadVariant string const ( VideoDownloadVariantVideo VideoDownloadVariant = "video" VideoDownloadVariantThumbnail VideoDownloadVariant = "thumbnail" VideoDownloadVariantSpriteSheet VideoDownloadVariant = "sprite_sheet" ) type BifrostVideoDownloadResponse struct { VideoID string `json:"video_id"` Content []byte `json:"-"` // Raw video content (not serialized) ContentType string `json:"content_type,omitempty"` // MIME type (e.g., "video/mp4", "image/png" for thumbnails) ExtraFields BifrostResponseExtraFields `json:"extra_fields"` } type VideoLogParams struct { VideoID string `json:"video_id"` }