From fc3423d05ecda22b790b63bcc2d8c819409d607c Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Thu, 16 Apr 2026 18:02:00 -0400 Subject: [PATCH] model creator + name metadata for omni endpoints (#1386) --- .../omni_gen/models/omni_gen_image_models.rs | 5 + .../omni_gen/models/omni_gen_video_models.rs | 5 + .../public/enums/src/common/generation/mod.rs | 1 + .../src/common/generation/model_creator.rs | 280 ++++++++++++++++++ .../src/configs/omni_gen/image_models.rs | 23 +- .../src/configs/omni_gen/video_models.rs | 35 ++- 6 files changed, 336 insertions(+), 13 deletions(-) create mode 100644 crates/schema/public/enums/src/common/generation/model_creator.rs diff --git a/crates/api_clients/artcraft/artcraft_api_defs/src/omni_gen/models/omni_gen_image_models.rs b/crates/api_clients/artcraft/artcraft_api_defs/src/omni_gen/models/omni_gen_image_models.rs index ce82d61c5c..119d2fb38b 100644 --- a/crates/api_clients/artcraft/artcraft_api_defs/src/omni_gen/models/omni_gen_image_models.rs +++ b/crates/api_clients/artcraft/artcraft_api_defs/src/omni_gen/models/omni_gen_image_models.rs @@ -2,6 +2,7 @@ use enums::common::generation::common_aspect_ratio::CommonAspectRatio; use enums::common::generation::common_image_model::CommonImageModel; use enums::common::generation::common_quality::CommonQuality; use enums::common::generation::common_resolution::CommonResolution; +use enums::common::generation::model_creator::ModelCreator; use enums::common::generation_provider::GenerationProvider; use serde_derive::{Deserialize, Serialize}; use utoipa::{IntoParams, ToSchema}; @@ -56,6 +57,9 @@ pub struct OmniGenImageProviderModelDetails { pub struct OmniGenImageModelDetails { pub model: CommonImageModel, + #[serde(skip_serializing_if = "Option::is_none")] + pub model_creator: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub full_name: Option, @@ -129,6 +133,7 @@ impl Default for OmniGenImageModelDetails { fn default() -> Self { Self { model: CommonImageModel::NanoBananaPro, + model_creator: None, full_name: None, text_prompt_supported: None, text_prompt_max_length: None, diff --git a/crates/api_clients/artcraft/artcraft_api_defs/src/omni_gen/models/omni_gen_video_models.rs b/crates/api_clients/artcraft/artcraft_api_defs/src/omni_gen/models/omni_gen_video_models.rs index 316ff1c604..1cf37ad897 100644 --- a/crates/api_clients/artcraft/artcraft_api_defs/src/omni_gen/models/omni_gen_video_models.rs +++ b/crates/api_clients/artcraft/artcraft_api_defs/src/omni_gen/models/omni_gen_video_models.rs @@ -2,6 +2,7 @@ use enums::common::generation::common_aspect_ratio::CommonAspectRatio; use enums::common::generation::common_quality::CommonQuality; use enums::common::generation::common_resolution::CommonResolution; use enums::common::generation::common_video_model::CommonVideoModel; +use enums::common::generation::model_creator::ModelCreator; use enums::common::generation_provider::GenerationProvider; use serde_derive::{Deserialize, Serialize}; use utoipa::{IntoParams, ToSchema}; @@ -65,6 +66,9 @@ pub struct OmniGenVideoModelDetails { pub model: CommonVideoModel, + #[serde(skip_serializing_if = "Option::is_none")] + pub model_creator: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub full_name: Option, @@ -172,6 +176,7 @@ impl Default for OmniGenVideoModelDetails { fn default() -> Self { Self { model: DEFAULT_VIDEO_MODEL, + model_creator: None, full_name: None, text_prompt_supported: None, text_prompt_max_length: None, diff --git a/crates/schema/public/enums/src/common/generation/mod.rs b/crates/schema/public/enums/src/common/generation/mod.rs index 0c2a1f839d..11128e7ac3 100644 --- a/crates/schema/public/enums/src/common/generation/mod.rs +++ b/crates/schema/public/enums/src/common/generation/mod.rs @@ -4,6 +4,7 @@ pub mod common_image_model; pub mod common_quality; pub mod common_model_class; pub mod common_model_type; +pub mod model_creator; pub mod common_resolution; pub mod common_splat_model; pub mod common_video_model; diff --git a/crates/schema/public/enums/src/common/generation/model_creator.rs b/crates/schema/public/enums/src/common/generation/model_creator.rs new file mode 100644 index 0000000000..5462375d02 --- /dev/null +++ b/crates/schema/public/enums/src/common/generation/model_creator.rs @@ -0,0 +1,280 @@ +use std::collections::BTreeSet; +use utoipa::ToSchema; + +#[cfg(test)] +use strum::EnumCount; +#[cfg(test)] +use strum::EnumIter; + +/// The company or organization that created a model. +#[cfg_attr(test, derive(EnumIter, EnumCount))] +#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, ToSchema)] +pub enum ModelCreator { + #[serde(rename = "alibaba")] + Alibaba, + #[serde(rename = "artcraft")] + ArtCraft, + #[serde(rename = "black_forest_labs")] + BlackForestLabs, + #[serde(rename = "bytedance")] + Bytedance, + #[serde(rename = "fal")] + Fal, + #[serde(rename = "google")] + Google, + #[serde(rename = "grok")] + Grok, + #[serde(rename = "hailuo")] + Hailuo, + #[serde(rename = "higgsfield")] + Higgsfield, + #[serde(rename = "kling")] + Kling, + #[serde(rename = "krea")] + Krea, + #[serde(rename = "midjourney")] + Midjourney, + #[serde(rename = "open_ai")] + OpenAi, + #[serde(rename = "open_art")] + OpenArt, + #[serde(rename = "recraft")] + Recraft, + #[serde(rename = "replicate")] + Replicate, + #[serde(rename = "runway")] + Runway, + #[serde(rename = "stability")] + Stability, + #[serde(rename = "tencent")] + Tencent, + #[serde(rename = "tensor_art")] + TensorArt, + #[serde(rename = "vidu")] + Vidu, + #[serde(rename = "world_labs")] + WorldLabs, +} + +impl ModelCreator { + /// Returns the properly formatted human-readable name. + pub fn get_name(&self) -> &'static str { + match self { + Self::Alibaba => "Alibaba", + Self::ArtCraft => "ArtCraft", + Self::BlackForestLabs => "Black Forest Labs", + Self::Bytedance => "ByteDance", + Self::Fal => "fal", + Self::Google => "Google", + Self::Grok => "Grok", + Self::Hailuo => "Hailuo", + Self::Higgsfield => "Higgsfield", + Self::Kling => "Kling", + Self::Krea => "Krea", + Self::Midjourney => "Midjourney", + Self::OpenAi => "OpenAI", + Self::OpenArt => "OpenArt", + Self::Recraft => "Recraft", + Self::Replicate => "Replicate", + Self::Runway => "Runway", + Self::Stability => "Stability AI", + Self::Tencent => "Tencent", + Self::TensorArt => "TensorArt", + Self::Vidu => "Vidu", + Self::WorldLabs => "World Labs", + } + } + + pub fn to_str(&self) -> &'static str { + match self { + Self::Alibaba => "alibaba", + Self::ArtCraft => "artcraft", + Self::BlackForestLabs => "black_forest_labs", + Self::Bytedance => "bytedance", + Self::Fal => "fal", + Self::Google => "google", + Self::Grok => "grok", + Self::Hailuo => "hailuo", + Self::Higgsfield => "higgsfield", + Self::Kling => "kling", + Self::Krea => "krea", + Self::Midjourney => "midjourney", + Self::OpenAi => "open_ai", + Self::OpenArt => "open_art", + Self::Recraft => "recraft", + Self::Replicate => "replicate", + Self::Runway => "runway", + Self::Stability => "stability", + Self::Tencent => "tencent", + Self::TensorArt => "tensor_art", + Self::Vidu => "vidu", + Self::WorldLabs => "world_labs", + } + } + + pub fn from_str(value: &str) -> Result { + match value { + "alibaba" => Ok(Self::Alibaba), + "artcraft" => Ok(Self::ArtCraft), + "black_forest_labs" => Ok(Self::BlackForestLabs), + "bytedance" => Ok(Self::Bytedance), + "fal" => Ok(Self::Fal), + "google" => Ok(Self::Google), + "grok" => Ok(Self::Grok), + "hailuo" => Ok(Self::Hailuo), + "higgsfield" => Ok(Self::Higgsfield), + "kling" => Ok(Self::Kling), + "krea" => Ok(Self::Krea), + "midjourney" => Ok(Self::Midjourney), + "open_ai" => Ok(Self::OpenAi), + "open_art" => Ok(Self::OpenArt), + "recraft" => Ok(Self::Recraft), + "replicate" => Ok(Self::Replicate), + "runway" => Ok(Self::Runway), + "stability" => Ok(Self::Stability), + "tencent" => Ok(Self::Tencent), + "tensor_art" => Ok(Self::TensorArt), + "vidu" => Ok(Self::Vidu), + "world_labs" => Ok(Self::WorldLabs), + _ => Err(format!("invalid ModelCreator value: {:?}", value)), + } + } + + pub fn all_variants() -> BTreeSet { + BTreeSet::from([ + Self::Alibaba, + Self::ArtCraft, + Self::BlackForestLabs, + Self::Bytedance, + Self::Fal, + Self::Google, + Self::Grok, + Self::Hailuo, + Self::Higgsfield, + Self::Kling, + Self::Krea, + Self::Midjourney, + Self::OpenAi, + Self::OpenArt, + Self::Recraft, + Self::Replicate, + Self::Runway, + Self::Stability, + Self::Tencent, + Self::TensorArt, + Self::Vidu, + Self::WorldLabs, + ]) + } +} + +impl_enum_display_and_debug_using_to_str!(ModelCreator); + +#[cfg(test)] +mod tests { + use crate::common::generation::model_creator::ModelCreator; + use crate::test_helpers::assert_serialization; + + mod explicit_checks { + use super::*; + + #[test] + fn test_serialization() { + assert_serialization(ModelCreator::Alibaba, "alibaba"); + assert_serialization(ModelCreator::ArtCraft, "artcraft"); + assert_serialization(ModelCreator::BlackForestLabs, "black_forest_labs"); + assert_serialization(ModelCreator::Bytedance, "bytedance"); + assert_serialization(ModelCreator::Fal, "fal"); + assert_serialization(ModelCreator::Google, "google"); + assert_serialization(ModelCreator::Grok, "grok"); + assert_serialization(ModelCreator::Hailuo, "hailuo"); + assert_serialization(ModelCreator::Higgsfield, "higgsfield"); + assert_serialization(ModelCreator::Kling, "kling"); + assert_serialization(ModelCreator::Krea, "krea"); + assert_serialization(ModelCreator::Midjourney, "midjourney"); + assert_serialization(ModelCreator::OpenAi, "open_ai"); + assert_serialization(ModelCreator::OpenArt, "open_art"); + assert_serialization(ModelCreator::Recraft, "recraft"); + assert_serialization(ModelCreator::Replicate, "replicate"); + assert_serialization(ModelCreator::Runway, "runway"); + assert_serialization(ModelCreator::Stability, "stability"); + assert_serialization(ModelCreator::Tencent, "tencent"); + assert_serialization(ModelCreator::TensorArt, "tensor_art"); + assert_serialization(ModelCreator::Vidu, "vidu"); + assert_serialization(ModelCreator::WorldLabs, "world_labs"); + } + + #[test] + fn to_str() { + assert_eq!(ModelCreator::Alibaba.to_str(), "alibaba"); + assert_eq!(ModelCreator::ArtCraft.to_str(), "artcraft"); + assert_eq!(ModelCreator::BlackForestLabs.to_str(), "black_forest_labs"); + assert_eq!(ModelCreator::OpenAi.to_str(), "open_ai"); + assert_eq!(ModelCreator::WorldLabs.to_str(), "world_labs"); + } + + #[test] + fn from_str() { + assert_eq!(ModelCreator::from_str("alibaba").unwrap(), ModelCreator::Alibaba); + assert_eq!(ModelCreator::from_str("artcraft").unwrap(), ModelCreator::ArtCraft); + assert_eq!(ModelCreator::from_str("black_forest_labs").unwrap(), ModelCreator::BlackForestLabs); + assert_eq!(ModelCreator::from_str("open_ai").unwrap(), ModelCreator::OpenAi); + assert_eq!(ModelCreator::from_str("world_labs").unwrap(), ModelCreator::WorldLabs); + assert!(ModelCreator::from_str("invalid").is_err()); + } + + #[test] + fn get_name() { + assert_eq!(ModelCreator::Alibaba.get_name(), "Alibaba"); + assert_eq!(ModelCreator::ArtCraft.get_name(), "ArtCraft"); + assert_eq!(ModelCreator::BlackForestLabs.get_name(), "Black Forest Labs"); + assert_eq!(ModelCreator::Bytedance.get_name(), "ByteDance"); + assert_eq!(ModelCreator::Fal.get_name(), "fal"); + assert_eq!(ModelCreator::Google.get_name(), "Google"); + assert_eq!(ModelCreator::OpenAi.get_name(), "OpenAI"); + assert_eq!(ModelCreator::Stability.get_name(), "Stability AI"); + assert_eq!(ModelCreator::WorldLabs.get_name(), "World Labs"); + } + + #[test] + fn all_variants() { + const EXPECTED_COUNT: usize = 22; + assert_eq!(ModelCreator::all_variants().len(), EXPECTED_COUNT); + } + } + + mod mechanical_checks { + use super::*; + + #[test] + fn variant_length() { + use strum::IntoEnumIterator; + assert_eq!(ModelCreator::all_variants().len(), ModelCreator::iter().len()); + } + + #[test] + fn round_trip() { + for variant in ModelCreator::all_variants() { + assert_eq!(variant, ModelCreator::from_str(variant.to_str()).unwrap()); + } + } + + #[test] + fn serialized_length_ok_for_database() { + const MAX_LENGTH: usize = 32; + for variant in ModelCreator::all_variants() { + let serialized = variant.to_str(); + assert!(!serialized.is_empty()); + assert!(serialized.len() <= MAX_LENGTH, "variant {:?} is too long for VARCHAR({})", variant, MAX_LENGTH); + } + } + + #[test] + fn every_variant_has_a_human_name() { + for variant in ModelCreator::all_variants() { + let name = variant.get_name(); + assert!(!name.is_empty(), "variant {:?} has empty name", variant); + } + } + } +} diff --git a/crates/service/web/storyteller_web/src/configs/omni_gen/image_models.rs b/crates/service/web/storyteller_web/src/configs/omni_gen/image_models.rs index e46c4f123b..d9d1589ff6 100644 --- a/crates/service/web/storyteller_web/src/configs/omni_gen/image_models.rs +++ b/crates/service/web/storyteller_web/src/configs/omni_gen/image_models.rs @@ -2,6 +2,7 @@ use artcraft_api_defs::omni_gen::models::omni_gen_image_models::{OmniGenImageMod use enums::common::generation::common_aspect_ratio::CommonAspectRatio; use enums::common::generation::common_image_model::CommonImageModel; use enums::common::generation::common_resolution::CommonResolution; +use enums::common::generation::model_creator::ModelCreator; use enums::common::generation_provider::GenerationProvider; use once_cell::sync::Lazy; use enums::common::generation::common_quality::CommonQuality; @@ -21,7 +22,8 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::Flux1Dev, - full_name: None, + model_creator: Some(ModelCreator::BlackForestLabs), + full_name: Some("FLUX.1 [dev]".to_string()), text_prompt_supported: Some(true), aspect_ratio_options: Some(vec![ CommonAspectRatio::SquareHd, @@ -40,7 +42,8 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::Flux1Schnell, - full_name: None, + model_creator: Some(ModelCreator::BlackForestLabs), + full_name: Some("FLUX.1 [schnell]".to_string()), text_prompt_supported: Some(true), aspect_ratio_options: Some(vec![ CommonAspectRatio::SquareHd, @@ -59,6 +62,7 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::FluxPro11, + model_creator: Some(ModelCreator::BlackForestLabs), full_name: Some("FLUX 1.1 [pro]".to_string()), text_prompt_supported: Some(true), aspect_ratio_options: Some(vec![ @@ -78,6 +82,7 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::FluxPro11Ultra, + model_creator: Some(ModelCreator::BlackForestLabs), full_name: Some("FLUX 1.1 [pro] ultra".to_string()), text_prompt_supported: Some(true), aspect_ratio_options: Some(vec![ @@ -100,7 +105,8 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::NanoBanana, // NB: currently Gemini25Flash in our system - full_name: None, + model_creator: Some(ModelCreator::ArtCraft), + full_name: Some("Nano Banana".to_string()), text_prompt_supported: Some(true), image_refs_supported: Some(true), aspect_ratio_options: Some(vec![ @@ -126,7 +132,8 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::NanoBanana2, - full_name: None, + model_creator: Some(ModelCreator::ArtCraft), + full_name: Some("Nano Banana 2".to_string()), text_prompt_supported: Some(true), image_refs_supported: Some(true), aspect_ratio_options: Some(vec![ @@ -159,7 +166,8 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::NanoBananaPro, - full_name: None, + model_creator: Some(ModelCreator::ArtCraft), + full_name: Some("Nano Banana Pro".to_string()), text_prompt_supported: Some(true), image_refs_supported: Some(true), aspect_ratio_options: Some(vec![ @@ -191,6 +199,7 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::GptImage1, + model_creator: Some(ModelCreator::OpenAi), full_name: Some("GPT Image 1".to_string()), text_prompt_supported: Some(true), image_refs_supported: Some(true), @@ -214,6 +223,7 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::GptImage1p5, + model_creator: Some(ModelCreator::OpenAi), full_name: Some("GPT Image 1.5".to_string()), text_prompt_supported: Some(true), image_refs_supported: Some(true), @@ -237,6 +247,7 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::Seedream4, + model_creator: Some(ModelCreator::Bytedance), full_name: Some("Seedream 4".to_string()), text_prompt_supported: Some(true), image_refs_supported: Some(true), @@ -261,6 +272,7 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::Seedream4p5, + model_creator: Some(ModelCreator::Bytedance), full_name: Some("Seedream 4.5".to_string()), text_prompt_supported: Some(true), image_refs_supported: Some(true), @@ -284,6 +296,7 @@ fn build_omni_gen_image_models() -> Vec { models.push(OmniGenImageModelDetails { model: CommonImageModel::Seedream5Lite, + model_creator: Some(ModelCreator::Bytedance), full_name: Some("Seedream 5 Lite".to_string()), text_prompt_supported: Some(true), image_refs_supported: Some(true), diff --git a/crates/service/web/storyteller_web/src/configs/omni_gen/video_models.rs b/crates/service/web/storyteller_web/src/configs/omni_gen/video_models.rs index 7041dbbae2..25435c36b6 100644 --- a/crates/service/web/storyteller_web/src/configs/omni_gen/video_models.rs +++ b/crates/service/web/storyteller_web/src/configs/omni_gen/video_models.rs @@ -2,6 +2,7 @@ use artcraft_api_defs::omni_gen::models::omni_gen_video_models::{OmniGenVideoMod use enums::common::generation::common_aspect_ratio::CommonAspectRatio; use enums::common::generation::common_resolution::CommonResolution; use enums::common::generation::common_video_model::CommonVideoModel; +use enums::common::generation::model_creator::ModelCreator; use enums::common::generation_provider::GenerationProvider; use once_cell::sync::Lazy; @@ -20,7 +21,8 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { model: CommonVideoModel::Seedance1p5Pro, - full_name: None, + model_creator: Some(ModelCreator::Bytedance), + full_name: Some("Seedance 1.5 Pro".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), ending_keyframe_supported: Some(true), @@ -49,7 +51,8 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { model: CommonVideoModel::Seedance2p0, - full_name: None, + model_creator: Some(ModelCreator::Bytedance), + full_name: Some("Seedance 2.0".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), ending_keyframe_supported: Some(true), @@ -81,7 +84,8 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { model: CommonVideoModel::Seedance2p0Fast, - full_name: None, + model_creator: Some(ModelCreator::Bytedance), + full_name: Some("Seedance 2.0 Fast".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), ending_keyframe_supported: Some(true), @@ -115,7 +119,8 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Veo2, - full_name: Some("Google Veo 2".to_string()), + model_creator: Some(ModelCreator::Google), + full_name: Some("Veo 2".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), // TODO(bt,2026-04-10): Veo 2 image-to-video doesn't support aspect ratio @@ -134,7 +139,8 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Veo3, - full_name: Some("Google Veo 3".to_string()), + model_creator: Some(ModelCreator::Google), + full_name: Some("Veo 3".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), show_generate_with_sound_toggle: Some(true), @@ -158,7 +164,8 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { model: CommonVideoModel::Veo3Fast, - full_name: Some("Google Veo 3 Fast".to_string()), + model_creator: Some(ModelCreator::Google), + full_name: Some("Veo 3 Fast".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), show_generate_with_sound_toggle: Some(true), @@ -176,7 +183,8 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Veo3p1, - full_name: Some("Google Veo 3.1".to_string()), + model_creator: Some(ModelCreator::Google), + full_name: Some("Veo 3.1".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), ending_keyframe_supported: Some(true), @@ -201,7 +209,8 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Veo3p1Fast, - full_name: Some("Google Veo 3.1 Fast".to_string()), + model_creator: Some(ModelCreator::Google), + full_name: Some("Veo 3.1 Fast".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), ending_keyframe_supported: Some(true), @@ -226,6 +235,7 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Kling16Pro, + model_creator: Some(ModelCreator::Kling), full_name: Some("Kling 1.6 Pro".to_string()), starting_keyframe_supported: Some(true), ending_keyframe_supported: Some(true), @@ -243,6 +253,7 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Kling21Pro, + model_creator: Some(ModelCreator::Kling), full_name: Some("Kling 2.1 Pro".to_string()), starting_keyframe_supported: Some(true), ending_keyframe_supported: Some(true), @@ -260,6 +271,7 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Kling21Master, + model_creator: Some(ModelCreator::Kling), full_name: Some("Kling 2.1 Master".to_string()), starting_keyframe_supported: Some(true), aspect_ratio_options: Some(vec![ @@ -276,6 +288,7 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Kling2p5TurboPro, + model_creator: Some(ModelCreator::Kling), full_name: Some("Kling 2.5 Turbo Pro".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), @@ -294,6 +307,7 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Kling2p6Pro, + model_creator: Some(ModelCreator::Kling), full_name: Some("Kling 2.6 Pro".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), @@ -312,6 +326,7 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Kling3p0Pro, + model_creator: Some(ModelCreator::Kling), full_name: Some("Kling 3.0 Pro".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), @@ -332,6 +347,7 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Kling3p0Standard, + model_creator: Some(ModelCreator::Kling), full_name: Some("Kling 3.0 Standard".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), @@ -352,6 +368,7 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Seedance10Lite, + model_creator: Some(ModelCreator::Bytedance), full_name: Some("Seedance 1.0 Lite".to_string()), starting_keyframe_supported: Some(true), ending_keyframe_supported: Some(true), @@ -379,6 +396,7 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Sora2, + model_creator: Some(ModelCreator::OpenAi), full_name: Some("Sora 2".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true), @@ -397,6 +415,7 @@ fn build_omni_gen_video_models() -> Vec { models.push(OmniGenVideoModelDetails { is_disabled: Some(true), // TODO: Temporarily disable model: CommonVideoModel::Sora2Pro, + model_creator: Some(ModelCreator::OpenAi), full_name: Some("Sora 2 Pro".to_string()), text_prompt_supported: Some(true), starting_keyframe_supported: Some(true),