From 2ff6da67f8362f16da5db3a2c569a3b0f8b71e84 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Mon, 22 Dec 2025 02:54:42 -0500 Subject: [PATCH] veo3.1 --- .../artcraft/handle_artcraft_veo3p1.rs | 79 +++++++++++++++++++ .../artcraft/handle_artcraft_veo3p1_fast.rs | 78 ++++++++++++++++++ .../artcraft/handle_artcraft_video.rs | 10 ++- .../enqueue/image_to_video/artcraft/mod.rs | 4 +- .../enqueue_image_to_video_command.rs | 6 ++ .../core/events/generation_events/common.rs | 4 + 6 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_veo3p1.rs create mode 100644 crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_veo3p1_fast.rs diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_veo3p1.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_veo3p1.rs new file mode 100644 index 0000000000..0dcfc9a313 --- /dev/null +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_veo3p1.rs @@ -0,0 +1,79 @@ +use crate::core::commands::enqueue::generate_error::GenerateError; +use crate::core::commands::enqueue::image_to_video::artcraft::get_storyteller_creds_or_error::get_storyteller_creds_or_error; +use crate::core::commands::enqueue::image_to_video::enqueue_image_to_video_command::{EnqueueImageToVideoRequest, SoraOrientation}; +use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess; +use crate::core::events::basic_sendable_event_trait::BasicSendableEvent; +use crate::core::events::functional_events::show_provider_login_modal_event::ShowProviderLoginModalEvent; +use crate::core::events::generation_events::common::{GenerationAction, GenerationModel}; +use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent; +use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs; +use crate::core::state::data_dir::app_data_root::AppDataRoot; +use crate::services::sora::state::sora_credential_manager::SoraCredentialManager; +use crate::services::sora::state::sora_task_queue::SoraTaskQueue; +use crate::services::sora::utils::upload_images_to_sora::{upload_images_to_sora, UploadImagesToSoraArgs, UploadImagesToSoraResult}; +use crate::services::storyteller::state::storyteller_credential_manager::StorytellerCredentialManager; +use artcraft_api_defs::generate::video::generate_kling_1_6_pro_image_to_video::{GenerateKling16ProAspectRatio, GenerateKling16ProImageToVideoRequest}; +use artcraft_api_defs::generate::video::multi_function::sora_2_multi_function_video_gen::{Veo3p1MultiFunctionVideoGenAspectRatio, Veo3p1MultiFunctionVideoGenDuration, Veo3p1MultiFunctionVideoGenRequest, Veo3p1MultiFunctionVideoGenResolution}; +use artcraft_api_defs::generate::video::multi_function::veo_3p1_multi_function_video_gen::{Veo3p1MultiFunctionVideoGenAspectRatio, Veo3p1MultiFunctionVideoGenDuration, Veo3p1MultiFunctionVideoGenRequest, Veo3p1MultiFunctionVideoGenResolution}; +use enums::common::generation_provider::GenerationProvider; +use enums::tauri::tasks::task_type::TaskType; +use idempotency::uuid::generate_random_uuid; +use log::{error, info}; +use storyteller_client::credentials::storyteller_credential_set::StorytellerCredentialSet; +use storyteller_client::endpoints::generate::video::multi_function::veo_3p1_multi_function_video_gen::veo_3p1_multi_function_video_gen; +use tauri::AppHandle; +use tokens::tokens::media_files::MediaFileToken; + +pub (super) async fn handle_artcraft_veo3p1( + request: &EnqueueImageToVideoRequest, + app_env_configs: &AppEnvConfigs, + creds: &StorytellerCredentialSet, +) -> Result { + + let uuid_idempotency_token = generate_random_uuid(); + + let aspect_ratio = match request.sora_orientation { + Some(SoraOrientation::Portrait) => Veo3p1MultiFunctionVideoGenAspectRatio::NineBySixteen, + Some(SoraOrientation::Landscape) => Veo3p1MultiFunctionVideoGenAspectRatio::SixteenByNine, + None => Veo3p1MultiFunctionVideoGenAspectRatio::SixteenByNine, + }; + + let request = Veo3p1MultiFunctionVideoGenRequest { + uuid_idempotency_token, + prompt: request.prompt.clone(), + start_frame_image_media_token: request.image_media_token.clone(), + end_frame_image_media_token: request.end_frame_image_media_token.clone(), + aspect_ratio: Some(aspect_ratio), + generate_audio: request.generate_audio, + resolution: Some(Veo3p1MultiFunctionVideoGenResolution::TenEightyP), // TODO: Parameterize + duration: Some(Veo3p1MultiFunctionVideoGenDuration::EightSeconds), // TODO: Parameterize + negative_prompt: None, // TODO: Parameterize + enhance_prompt: None, // NB: Handled downstream. + auto_fix: None, // NB: Handled downstream. + seed: None, // NB: Handled downstream. + }; + + let result = veo_3p1_multi_function_video_gen( + &app_env_configs.storyteller_host, + Some(&creds), + request, + ).await; + + let job_token = match result { + Ok(enqueued) => { + info!("Successfully enqueued."); + enqueued.inference_job_token + } + Err(err) => { + error!("Failed to enqueue: {:?}", err); + return Err(GenerateError::from(err)); + } + }; + + Ok(TaskEnqueueSuccess { + task_type: TaskType::VideoGeneration, + model: Some(GenerationModel::Veo3p1), + provider: GenerationProvider::Artcraft, + provider_job_id: Some(job_token.to_string()), + }) +} diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_veo3p1_fast.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_veo3p1_fast.rs new file mode 100644 index 0000000000..79fb321b00 --- /dev/null +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_veo3p1_fast.rs @@ -0,0 +1,78 @@ +use crate::core::commands::enqueue::generate_error::GenerateError; +use crate::core::commands::enqueue::image_to_video::artcraft::get_storyteller_creds_or_error::get_storyteller_creds_or_error; +use crate::core::commands::enqueue::image_to_video::enqueue_image_to_video_command::{EnqueueImageToVideoRequest, SoraOrientation}; +use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess; +use crate::core::events::basic_sendable_event_trait::BasicSendableEvent; +use crate::core::events::functional_events::show_provider_login_modal_event::ShowProviderLoginModalEvent; +use crate::core::events::generation_events::common::{GenerationAction, GenerationModel}; +use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent; +use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs; +use crate::core::state::data_dir::app_data_root::AppDataRoot; +use crate::services::sora::state::sora_credential_manager::SoraCredentialManager; +use crate::services::sora::state::sora_task_queue::SoraTaskQueue; +use crate::services::sora::utils::upload_images_to_sora::{upload_images_to_sora, UploadImagesToSoraArgs, UploadImagesToSoraResult}; +use crate::services::storyteller::state::storyteller_credential_manager::StorytellerCredentialManager; +use artcraft_api_defs::generate::video::multi_function::veo_3p1_fast_multi_function_video_gen::{Veo3p1FastMultiFunctionVideoGenAspectRatio, Veo3p1FastMultiFunctionVideoGenDuration, Veo3p1FastMultiFunctionVideoGenRequest, Veo3p1FastMultiFunctionVideoGenResolution}; +use enums::common::generation_provider::GenerationProvider; +use enums::tauri::tasks::task_type::TaskType; +use idempotency::uuid::generate_random_uuid; +use log::{error, info}; +use storyteller_client::credentials::storyteller_credential_set::StorytellerCredentialSet; +use storyteller_client::endpoints::generate::video::multi_function::veo_3p1_fast_multi_function_video_gen::veo_3p1_fast_multi_function_video_gen; +use storyteller_client::endpoints::generate::video::multi_function::veo_3p1_multi_function_video_gen::veo_3p1_multi_function_video_gen; +use tauri::AppHandle; +use tokens::tokens::media_files::MediaFileToken; + +pub (super) async fn handle_artcraft_veo3p1_fast( + request: &EnqueueImageToVideoRequest, + app_env_configs: &AppEnvConfigs, + creds: &StorytellerCredentialSet, +) -> Result { + + let uuid_idempotency_token = generate_random_uuid(); + + let aspect_ratio = match request.sora_orientation { + Some(SoraOrientation::Portrait) => Veo3p1FastMultiFunctionVideoGenAspectRatio::NineBySixteen, + Some(SoraOrientation::Landscape) => Veo3p1FastMultiFunctionVideoGenAspectRatio::SixteenByNine, + None => Veo3p1FastMultiFunctionVideoGenAspectRatio::SixteenByNine, + }; + + let request = Veo3p1FastMultiFunctionVideoGenRequest { + uuid_idempotency_token, + prompt: request.prompt.clone(), + start_frame_image_media_token: request.image_media_token.clone(), + end_frame_image_media_token: request.end_frame_image_media_token.clone(), + aspect_ratio: Some(aspect_ratio), + generate_audio: request.generate_audio, + resolution: Some(Veo3p1FastMultiFunctionVideoGenResolution::TenEightyP), // TODO: Parameterize + duration: Some(Veo3p1FastMultiFunctionVideoGenDuration::EightSeconds), // TODO: Parameterize + negative_prompt: None, // TODO: Parameterize + enhance_prompt: None, // NB: Handled downstream. + auto_fix: None, // NB: Handled downstream. + seed: None, // NB: Handled downstream. + }; + + let result = veo_3p1_fast_multi_function_video_gen( + &app_env_configs.storyteller_host, + Some(&creds), + request, + ).await; + + let job_token = match result { + Ok(enqueued) => { + info!("Successfully enqueued."); + enqueued.inference_job_token + } + Err(err) => { + error!("Failed to enqueue: {:?}", err); + return Err(GenerateError::from(err)); + } + }; + + Ok(TaskEnqueueSuccess { + task_type: TaskType::VideoGeneration, + model: Some(GenerationModel::Veo3p1Fast), + provider: GenerationProvider::Artcraft, + provider_job_id: Some(job_token.to_string()), + }) +} diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_video.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_video.rs index 24279620b4..4cb39290a8 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_video.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/handle_artcraft_video.rs @@ -1,7 +1,11 @@ use crate::core::commands::enqueue::generate_error::GenerateError; use crate::core::commands::enqueue::image_to_video::artcraft::get_storyteller_creds_or_error::get_storyteller_creds_or_error; +use crate::core::commands::enqueue::image_to_video::artcraft::handle_artcraft_kling_2p5_turbo_pro::handle_artcraft_kling_2p5_turbo_pro; +use crate::core::commands::enqueue::image_to_video::artcraft::handle_artcraft_kling_2p6_pro::handle_artcraft_kling_2p6_pro; use crate::core::commands::enqueue::image_to_video::artcraft::handle_artcraft_sora2::handle_artcraft_sora2; use crate::core::commands::enqueue::image_to_video::artcraft::handle_artcraft_sora2_pro::handle_artcraft_sora2_pro; +use crate::core::commands::enqueue::image_to_video::artcraft::handle_artcraft_veo3p1::handle_artcraft_veo3p1; +use crate::core::commands::enqueue::image_to_video::artcraft::handle_artcraft_veo3p1_fast::handle_artcraft_veo3p1_fast; use crate::core::commands::enqueue::image_to_video::enqueue_image_to_video_command::{EnqueueImageToVideoRequest, VideoModel}; use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess; use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs; @@ -17,13 +21,17 @@ pub async fn handle_video_artcraft( ) -> Result { let creds = get_storyteller_creds_or_error(app, storyteller_creds_manager)?; - + match request.model { None => { Err(GenerateError::no_model_specified()) }, + Some(VideoModel::Kling2p5TurboPro) => handle_artcraft_kling_2p5_turbo_pro(request, app_env_configs, &creds).await, + Some(VideoModel::Kling2p6Pro) => handle_artcraft_kling_2p6_pro(request, app_env_configs, &creds).await, Some(VideoModel::Sora2) => handle_artcraft_sora2(request, app_env_configs, &creds).await, Some(VideoModel::Sora2Pro) => handle_artcraft_sora2_pro(request, app_env_configs, &creds).await, + Some(VideoModel::Veo3p1) => handle_artcraft_veo3p1(request, app_env_configs, &creds).await, + Some(VideoModel::Veo3p1Fast) => handle_artcraft_veo3p1_fast(request, app_env_configs, &creds).await, Some(_) => { Err(GenerateError::AnyhowError( anyhow!("wrong logic: another branch should handle this: {:?}", request.model))) diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/mod.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/mod.rs index 505b32a963..eb7ed02cc6 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/mod.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/artcraft/mod.rs @@ -3,4 +3,6 @@ mod handle_artcraft_kling_2p5_turbo_pro; mod handle_artcraft_kling_2p6_pro; mod handle_artcraft_sora2; mod handle_artcraft_sora2_pro; -mod handle_artcraft_video; \ No newline at end of file +mod handle_artcraft_video; +mod handle_artcraft_veo3p1; +mod handle_artcraft_veo3p1_fast; \ No newline at end of file diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/enqueue_image_to_video_command.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/enqueue_image_to_video_command.rs index faa1c3a708..2d867ceee9 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/enqueue_image_to_video_command.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image_to_video/enqueue_image_to_video_command.rs @@ -66,6 +66,12 @@ pub enum VideoModel { #[serde(rename = "veo_3_fast")] Veo3Fast, + + #[serde(rename = "veo_3p1")] + Veo3p1, + + #[serde(rename = "veo_3p1_fast")] + Veo3p1Fast, } #[derive(Deserialize, Debug)] diff --git a/crates/desktop/artcraft/src/core/events/generation_events/common.rs b/crates/desktop/artcraft/src/core/events/generation_events/common.rs index b8095b259e..4d5ce55528 100644 --- a/crates/desktop/artcraft/src/core/events/generation_events/common.rs +++ b/crates/desktop/artcraft/src/core/events/generation_events/common.rs @@ -90,6 +90,10 @@ pub enum GenerationModel { Veo3, #[serde(rename = "veo_3_fast")] Veo3Fast, + #[serde(rename = "veo_3p1")] + Veo3p1, + #[serde(rename = "veo_3p1_fast")] + Veo3p1Fast, } #[derive(Debug, Copy, Clone, Serialize)]