diff --git a/crates/schema/database/mysql_queries/src/queries/generic_inference/gmicloud/insert_generic_inference_job_for_gmicloud.rs b/crates/schema/database/mysql_queries/src/queries/generic_inference/gmicloud/insert_generic_inference_job_for_gmicloud.rs new file mode 100644 index 0000000000..5ee714fcba --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/generic_inference/gmicloud/insert_generic_inference_job_for_gmicloud.rs @@ -0,0 +1,119 @@ +use log::info; +use sqlx::{Executor, MySql}; +use std::marker::PhantomData; + +use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory; +use enums::by_table::generic_inference_jobs::inference_job_external_third_party::InferenceJobExternalThirdParty; +use enums::by_table::generic_inference_jobs::inference_job_product_category::InferenceJobProductCategory; +use enums::by_table::generic_inference_jobs::inference_job_type::InferenceJobType; +use enums::common::job_status_plus::JobStatusPlus; +use enums::common::visibility::Visibility; +use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken; +use tokens::tokens::generic_inference_jobs::InferenceJobToken; +use tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken; +use tokens::tokens::prompts::PromptToken; +use tokens::tokens::users::UserToken; + +use crate::errors::database_query_error::DatabaseQueryError; + +pub struct InsertGmiCloudInferenceJobArgs<'e, 'c, E> +where + E: 'e + Executor<'c, Database = MySql>, +{ + pub apriori_job_token: &'e InferenceJobToken, + pub uuid_idempotency_token: &'e str, + pub external_request_id: &'e str, + pub maybe_prompt_token: Option<&'e PromptToken>, + pub maybe_creator_user_token: Option<&'e UserToken>, + pub maybe_avt_token: Option<&'e AnonymousVisitorTrackingToken>, + pub creator_ip_address: &'e str, + pub maybe_debug_log_event_token: Option<&'e DebugLogEventToken>, + pub mysql_executor: E, + pub phantom: PhantomData<&'c E>, +} + +pub async fn insert_generic_inference_job_for_gmicloud<'e, 'c: 'e, E>( + args: InsertGmiCloudInferenceJobArgs<'e, 'c, E>, +) -> Result +where + E: 'e + Executor<'c, Database = MySql>, +{ + let query = sqlx::query!( + r#" +INSERT INTO generic_inference_jobs +SET + token = ?, + uuid_idempotency_token = ?, + + job_type = ?, + + maybe_external_third_party = ?, + maybe_external_third_party_id = ?, + + product_category = ?, + inference_category = ?, + + maybe_model_type = NULL, + maybe_model_token = NULL, + + maybe_input_source_token = NULL, + maybe_input_source_token_type = NULL, + + maybe_download_url = NULL, + maybe_cover_image_media_file_token = NULL, + + maybe_prompt_token = ?, + + maybe_raw_inference_text = NULL, + + maybe_inference_args = NULL, + + maybe_creator_user_token = ?, + maybe_creator_anonymous_visitor_token = ?, + creator_ip_address = ?, + creator_set_visibility = ?, + + priority_level = 0, + is_keepalive_required = FALSE, + max_duration_seconds = 0, + + is_debug_request = FALSE, + maybe_routing_tag = NULL, + + maybe_debug_log_event_token = ?, + + frontend_failure_category = NULL, + failure_reason = NULL, + + status = ? + "#, + args.apriori_job_token.as_str(), + args.uuid_idempotency_token, + InferenceJobType::FalQueue.to_str(), + InferenceJobExternalThirdParty::GmiCloud.to_str(), + args.external_request_id, + InferenceJobProductCategory::GmiCloudVideo.to_str(), + InferenceCategory::VideoGeneration.to_str(), + args.maybe_prompt_token.map(|t| t.to_string()), + args.maybe_creator_user_token.map(|t| t.to_string()), + args.maybe_avt_token.map(|t| t.to_string()), + args.creator_ip_address, + Visibility::Public.to_str(), + args.maybe_debug_log_event_token.map(|t| t.as_str()), + JobStatusPlus::Pending.to_str(), + ); + + let query_result = query.execute(args.mysql_executor).await; + + let record_id = match query_result { + Err(err) => return Err(DatabaseQueryError::from(err)), + Ok(res) => res.last_insert_id(), + }; + + info!( + "Insert generic inference job for GmiCloud: {} with record ID {}", + args.apriori_job_token, record_id + ); + + Ok(args.apriori_job_token.clone()) +} diff --git a/crates/schema/database/mysql_queries/src/queries/generic_inference/gmicloud/mod.rs b/crates/schema/database/mysql_queries/src/queries/generic_inference/gmicloud/mod.rs new file mode 100644 index 0000000000..ac61f12ef8 --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/generic_inference/gmicloud/mod.rs @@ -0,0 +1 @@ +pub mod insert_generic_inference_job_for_gmicloud; diff --git a/crates/schema/database/mysql_queries/src/queries/generic_inference/mod.rs b/crates/schema/database/mysql_queries/src/queries/generic_inference/mod.rs index a60d53adac..422862351a 100644 --- a/crates/schema/database/mysql_queries/src/queries/generic_inference/mod.rs +++ b/crates/schema/database/mysql_queries/src/queries/generic_inference/mod.rs @@ -1,5 +1,6 @@ pub mod beeble; pub mod fal; +pub mod gmicloud; pub mod job; pub mod moderation; pub mod seedance2pro; diff --git a/crates/schema/public/enums/src/by_table/generic_inference_jobs/inference_job_external_third_party.rs b/crates/schema/public/enums/src/by_table/generic_inference_jobs/inference_job_external_third_party.rs index 6cf1a2351b..6c104da8fb 100644 --- a/crates/schema/public/enums/src/by_table/generic_inference_jobs/inference_job_external_third_party.rs +++ b/crates/schema/public/enums/src/by_table/generic_inference_jobs/inference_job_external_third_party.rs @@ -21,6 +21,10 @@ pub enum InferenceJobExternalThirdParty { #[default] Fal, + /// GmiCloud jobs + #[serde(rename = "gmicloud")] + GmiCloud, + /// Seedance 2 Pro jobs #[serde(rename = "seedance2pro")] Seedance2Pro, @@ -40,6 +44,7 @@ impl InferenceJobExternalThirdParty { match self { Self::Beeble => "beeble", Self::Fal => "fal", + Self::GmiCloud => "gmicloud", Self::Seedance2Pro => "seedance2pro", Self::Worldlabs => "worldlabs", } @@ -49,6 +54,7 @@ impl InferenceJobExternalThirdParty { match value { "beeble" => Ok(Self::Beeble), "fal" => Ok(Self::Fal), + "gmicloud" => Ok(Self::GmiCloud), "seedance2pro" => Ok(Self::Seedance2Pro), "worldlabs" => Ok(Self::Worldlabs), _ => Err(format!("invalid value: {:?}", value)), @@ -61,6 +67,7 @@ impl InferenceJobExternalThirdParty { BTreeSet::from([ Self::Beeble, Self::Fal, + Self::GmiCloud, Self::Seedance2Pro, Self::Worldlabs, ]) @@ -79,6 +86,7 @@ mod tests { fn test_serialization() { assert_serialization(InferenceJobExternalThirdParty::Beeble, "beeble"); assert_serialization(InferenceJobExternalThirdParty::Fal, "fal"); + assert_serialization(InferenceJobExternalThirdParty::GmiCloud, "gmicloud"); assert_serialization(InferenceJobExternalThirdParty::Seedance2Pro, "seedance2pro"); assert_serialization(InferenceJobExternalThirdParty::Worldlabs, "worldlabs"); } @@ -87,6 +95,7 @@ mod tests { fn to_str() { assert_eq!(InferenceJobExternalThirdParty::Beeble.to_str(), "beeble"); assert_eq!(InferenceJobExternalThirdParty::Fal.to_str(), "fal"); + assert_eq!(InferenceJobExternalThirdParty::GmiCloud.to_str(), "gmicloud"); assert_eq!(InferenceJobExternalThirdParty::Seedance2Pro.to_str(), "seedance2pro"); assert_eq!(InferenceJobExternalThirdParty::Worldlabs.to_str(), "worldlabs"); } @@ -95,6 +104,7 @@ mod tests { fn from_str() { assert_eq!(InferenceJobExternalThirdParty::from_str("beeble").unwrap(), InferenceJobExternalThirdParty::Beeble); assert_eq!(InferenceJobExternalThirdParty::from_str("fal").unwrap(), InferenceJobExternalThirdParty::Fal); + assert_eq!(InferenceJobExternalThirdParty::from_str("gmicloud").unwrap(), InferenceJobExternalThirdParty::GmiCloud); assert_eq!(InferenceJobExternalThirdParty::from_str("seedance2pro").unwrap(), InferenceJobExternalThirdParty::Seedance2Pro); assert_eq!(InferenceJobExternalThirdParty::from_str("worldlabs").unwrap(), InferenceJobExternalThirdParty::Worldlabs); } @@ -102,7 +112,7 @@ mod tests { #[test] fn all_variants() { // Static check - const EXPECTED_COUNT : usize = 4; + const EXPECTED_COUNT : usize = 5; assert_eq!(InferenceJobExternalThirdParty::all_variants().len(), EXPECTED_COUNT); assert_eq!(InferenceJobExternalThirdParty::iter().len(), EXPECTED_COUNT); diff --git a/crates/schema/public/enums/src/by_table/generic_inference_jobs/inference_job_product_category.rs b/crates/schema/public/enums/src/by_table/generic_inference_jobs/inference_job_product_category.rs index 755a888238..1e4ab1bb29 100644 --- a/crates/schema/public/enums/src/by_table/generic_inference_jobs/inference_job_product_category.rs +++ b/crates/schema/public/enums/src/by_table/generic_inference_jobs/inference_job_product_category.rs @@ -30,6 +30,11 @@ pub enum InferenceJobProductCategory { FalObject, FalBgRemoval, + // =============== GMICLOUD =============== + + #[serde(rename = "gmicloud_video")] + GmiCloudVideo, + // =============== BEEBLE =============== #[serde(rename = "beeble_video")] @@ -144,6 +149,7 @@ impl InferenceJobProductCategory { Self::FalVideo => "fal_video", Self::FalObject => "fal_object", Self::FalBgRemoval => "fal_bg_removal", + Self::GmiCloudVideo => "gmicloud_video", Self::BeebleVideo => "beeble_video", Self::Seedance2ProVideo => "seedance2pro_video", Self::Seedance2ProCharacter => "seedance2pro_character", @@ -180,6 +186,7 @@ impl InferenceJobProductCategory { "fal_video" => Ok(Self::FalVideo), "fal_object" => Ok(Self::FalObject), "fal_bg_removal" => Ok(Self::FalBgRemoval), + "gmicloud_video" => Ok(Self::GmiCloudVideo), "beeble_video" => Ok(Self::BeebleVideo), "seedance2pro_video" => Ok(Self::Seedance2ProVideo), "seedance2pro_character" => Ok(Self::Seedance2ProCharacter), @@ -219,6 +226,7 @@ impl InferenceJobProductCategory { Self::FalVideo, Self::FalObject, Self::FalBgRemoval, + Self::GmiCloudVideo, Self::BeebleVideo, Self::Seedance2ProVideo, Self::Seedance2ProCharacter, @@ -264,6 +272,7 @@ mod tests { assert_serialization(InferenceJobProductCategory::FalVideo, "fal_video"); assert_serialization(InferenceJobProductCategory::FalObject, "fal_object"); assert_serialization(InferenceJobProductCategory::FalBgRemoval, "fal_bg_removal"); + assert_serialization(InferenceJobProductCategory::GmiCloudVideo, "gmicloud_video"); assert_serialization(InferenceJobProductCategory::BeebleVideo, "beeble_video"); assert_serialization(InferenceJobProductCategory::Seedance2ProVideo, "seedance2pro_video"); assert_serialization(InferenceJobProductCategory::Seedance2ProCharacter, "seedance2pro_character"); @@ -299,6 +308,7 @@ mod tests { assert_eq!(InferenceJobProductCategory::FalVideo.to_str(), "fal_video"); assert_eq!(InferenceJobProductCategory::FalObject.to_str(), "fal_object"); assert_eq!(InferenceJobProductCategory::FalBgRemoval.to_str(), "fal_bg_removal"); + assert_eq!(InferenceJobProductCategory::GmiCloudVideo.to_str(), "gmicloud_video"); assert_eq!(InferenceJobProductCategory::BeebleVideo.to_str(), "beeble_video"); assert_eq!(InferenceJobProductCategory::Seedance2ProVideo.to_str(), "seedance2pro_video"); assert_eq!(InferenceJobProductCategory::Seedance2ProCharacter.to_str(), "seedance2pro_character"); @@ -333,6 +343,7 @@ mod tests { assert_eq!(InferenceJobProductCategory::from_str("fal_video").unwrap(), InferenceJobProductCategory::FalVideo); assert_eq!(InferenceJobProductCategory::from_str("fal_object").unwrap(), InferenceJobProductCategory::FalObject); assert_eq!(InferenceJobProductCategory::from_str("fal_bg_removal").unwrap(), InferenceJobProductCategory::FalBgRemoval); + assert_eq!(InferenceJobProductCategory::from_str("gmicloud_video").unwrap(), InferenceJobProductCategory::GmiCloudVideo); assert_eq!(InferenceJobProductCategory::from_str("beeble_video").unwrap(), InferenceJobProductCategory::BeebleVideo); assert_eq!(InferenceJobProductCategory::from_str("seedance2pro_video").unwrap(), InferenceJobProductCategory::Seedance2ProVideo); assert_eq!(InferenceJobProductCategory::from_str("seedance2pro_character").unwrap(), InferenceJobProductCategory::Seedance2ProCharacter); @@ -363,7 +374,7 @@ mod tests { #[test] fn all_variants() { // Static check - const EXPECTED_COUNT : usize = 31; + const EXPECTED_COUNT : usize = 32; assert_eq!(InferenceJobProductCategory::all_variants().len(), EXPECTED_COUNT); assert_eq!(InferenceJobProductCategory::iter().len(), EXPECTED_COUNT); diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/insert_db_job/insert_gmicloud_job.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/insert_db_job/insert_gmicloud_job.rs new file mode 100644 index 0000000000..af8dfe0d35 --- /dev/null +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/insert_db_job/insert_gmicloud_job.rs @@ -0,0 +1,45 @@ +use log::warn; + +use mysql_queries::queries::generic_inference::gmicloud::insert_generic_inference_job_for_gmicloud::{ + insert_generic_inference_job_for_gmicloud, InsertGmiCloudInferenceJobArgs, +}; +use tokens::tokens::generic_inference_jobs::InferenceJobToken; + +use crate::http_server::common_responses::advanced_common_web_error::AdvancedCommonWebError; + +use super::shared_job_args::SharedJobArgs; + +pub struct InsertGmiCloudJobArgs<'a, 'tx> { + pub external_request_id: &'a str, + pub shared: SharedJobArgs<'a, 'tx>, +} + +pub async fn insert_gmicloud_job(args: InsertGmiCloudJobArgs<'_, '_>) -> Result { + let InsertGmiCloudJobArgs { + external_request_id, + shared, + } = args; + + let db_result = insert_generic_inference_job_for_gmicloud( + InsertGmiCloudInferenceJobArgs { + apriori_job_token: shared.apriori_job_token, + uuid_idempotency_token: shared.idempotency_token, + external_request_id, + maybe_prompt_token: shared.maybe_prompt_token, + maybe_creator_user_token: Some(shared.user_token), + maybe_avt_token: shared.maybe_avt_token, + creator_ip_address: shared.ip_address, + maybe_debug_log_event_token: shared.maybe_debug_log_event_token, + mysql_executor: &mut **shared.transaction, + phantom: Default::default(), + } + ).await; + + match db_result { + Ok(token) => Ok(token), + Err(err) => { + warn!("Error inserting GmiCloud inference job: {:?}", err); + Err(AdvancedCommonWebError::from_error(err)) + } + } +} diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/insert_db_job/mod.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/insert_db_job/mod.rs index 751cbf87e7..c54f8ae75d 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/insert_db_job/mod.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/insert_db_job/mod.rs @@ -1,3 +1,4 @@ pub mod insert_fal_job; +pub mod insert_gmicloud_job; pub mod insert_seedance2pro_jobs; pub mod shared_job_args; diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/omni_gen_video_generate_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/omni_gen_video_generate_handler.rs index 931705be64..cc74308ff8 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/omni_gen_video_generate_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/omni_gen_video_generate_handler.rs @@ -33,6 +33,7 @@ use crate::http_server::common_responses::advanced_common_web_error::AdvancedCom use crate::http_server::endpoints::generate::common::payments_error_test::payments_error_test; use crate::http_server::endpoints::omni_gen::generate::video::helpers::hydrate_router_request::hydrate_to_router_request; use crate::http_server::endpoints::omni_gen::generate::video::insert_db_job::insert_fal_job::{insert_fal_job, InsertFalJobArgs}; +use crate::http_server::endpoints::omni_gen::generate::video::insert_db_job::insert_gmicloud_job::{insert_gmicloud_job, InsertGmiCloudJobArgs}; use crate::http_server::endpoints::omni_gen::generate::video::insert_db_job::insert_seedance2pro_jobs::{insert_seedance2pro_jobs, InsertSeedance2proJobsArgs}; use crate::http_server::endpoints::omni_gen::generate::video::insert_db_job::shared_job_args::SharedJobArgs; use crate::http_server::endpoints::omni_gen::generate::video::pipeline_v1::run_pipeline_v1::{run_pipeline_v1, RunPipelineV1Args}; @@ -381,8 +382,8 @@ pub async fn omni_gen_video_generate_handler( } GenerateVideoResponse::GmiCloud(payload) => { info!("Inserting GmiCloud job with token: {:?}", pipeline_result.billing.apriori_job_token); - let token = insert_fal_job(InsertFalJobArgs { - external_job_id: &payload.request_id, + let token = insert_gmicloud_job(InsertGmiCloudJobArgs { + external_request_id: &payload.request_id, shared: SharedJobArgs { apriori_job_token: &pipeline_result.billing.apriori_job_token, idempotency_token: &idempotency_token,