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 2867dd0198..91fe69e0bb 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 @@ -28,9 +28,9 @@ 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::insert_fal_job::insert_fal_job; use crate::http_server::endpoints::omni_gen::generate::video::helpers::insert_seedance2pro_jobs::insert_seedance2pro_jobs; +use crate::http_server::endpoints::omni_gen::generate::video::pipeline_v1::run_pipeline_v1::{run_pipeline_v1, RunPipelineV1Args}; +use crate::http_server::endpoints::omni_gen::generate::video::pipeline_v2::run_pipeline_v2::{run_pipeline_v2, RunPipelineV2Args}; use crate::http_server::endpoints::omni_gen::generate::video::request_helper::resolve_kinovi_character_ids::resolve_kinovi_character_ids; -use crate::http_server::endpoints::omni_gen::generate::video::pipeline_v1::run_pipeline_v1::run_pipeline_v1; -use crate::http_server::endpoints::omni_gen::generate::video::pipeline_v2::run_pipeline_v2::run_pipeline_v2; use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format; use crate::state::server_state::ServerState; use crate::util::lookup::lookup_image_urls_as_map::lookup_image_urls_as_map; @@ -167,12 +167,23 @@ pub async fn omni_gen_video_generate_handler( ); let pipeline_result = if use_v2 { - run_pipeline_v2( - &request, &server_state, &mut mysql_connection, user_token, - &media_file_hydration_map, &media_file_to_url_map, &kinovi_character_id_map, - ).await? + run_pipeline_v2(RunPipelineV2Args { + request: &request, + server_state: &server_state, + mysql_connection: &mut mysql_connection, + user_token, + media_file_to_url_map: &media_file_to_url_map, + kinovi_character_id_map: &kinovi_character_id_map, + }).await? } else { - run_pipeline_v1(&request, &server_state, &mut mysql_connection, user_token, &media_file_hydration_map).await? + run_pipeline_v1(RunPipelineV1Args { + request: &request, + server_state: &server_state, + mysql_connection: &mut mysql_connection, + user_token, + media_file_hydration_map: &media_file_hydration_map, + kinovi_character_id_map: &kinovi_character_id_map, + }).await? }; // ==================== WRITE RESULT ==================== // diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/pipeline_v1/run_pipeline_v1.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/pipeline_v1/run_pipeline_v1.rs index 355c08a7b4..c9c90830c0 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/pipeline_v1/run_pipeline_v1.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/pipeline_v1/run_pipeline_v1.rs @@ -7,32 +7,40 @@ use artcraft_api_defs::omni_gen::cost_and_generate_requests::omni_gen_video_cost use artcraft_router::api::provider::Provider; use artcraft_router::generate::generate_video::generate_video_response::GenerateVideoResponse; use enums::common::generation::common_video_model::CommonVideoModel; +use tokens::tokens::characters::CharacterToken; use tokens::tokens::media_files::MediaFileToken; +use tokens::tokens::users::UserToken; use crate::http_server::common_responses::advanced_common_web_error::AdvancedCommonWebError; use crate::http_server::endpoints::omni_gen::generate::video::helpers::bill_wallet::bill_wallet; use crate::http_server::endpoints::omni_gen::generate::video::pipeline_result::PipelineResult; -use crate::http_server::endpoints::omni_gen::generate::video::hydrate_router_request::hydrate_to_router_request; use crate::http_server::endpoints::omni_gen::generate::video::pipeline_v1::distill_video_request::distill_video_request; use crate::http_server::endpoints::omni_gen::generate::video::pipeline_v1::execute::execute_generation::execute_generation; -use crate::http_server::endpoints::omni_gen::generate::video::request_helper::resolve_kinovi_character_ids::resolve_kinovi_character_ids; use crate::state::server_state::ServerState; -pub async fn run_pipeline_v1( - request: &OmniGenVideoCostAndGenerateRequest, - server_state: &ServerState, - mysql_connection: &mut sqlx::pool::PoolConnection, - user_token: &tokens::tokens::users::UserToken, - media_file_hydration_map: &Option>, -) -> Result { - let kinovi_character_id_map = resolve_kinovi_character_ids( - request.reference_character_tokens.as_deref(), +pub struct RunPipelineV1Args<'a> { + pub request: &'a OmniGenVideoCostAndGenerateRequest, + pub server_state: &'a ServerState, + pub mysql_connection: &'a mut sqlx::pool::PoolConnection, + pub user_token: &'a UserToken, + pub media_file_hydration_map: &'a Option>, + pub kinovi_character_id_map: &'a Option>, +} + +pub async fn run_pipeline_v1(args: RunPipelineV1Args<'_>) -> Result { + let RunPipelineV1Args { + request, + server_state, mysql_connection, - ).await?; + user_token, + media_file_hydration_map, + kinovi_character_id_map, + } = args; // v1 execute_generation expects a flat Vec of kinovi IDs let kinovi_character_ids: Option> = kinovi_character_id_map - .map(|map| map.into_values().collect()); + .as_ref() + .map(|map| map.values().cloned().collect()); let execution_provider = match request.model { Some(CommonVideoModel::Seedance2p0) => Provider::Seedance2Pro, @@ -51,7 +59,7 @@ pub async fn run_pipeline_v1( kinovi_character_ids, billing.maybe_wallet_ledger_entry_token.as_ref(), mysql_connection, ).await?; - // Map v1 GenerationResult -> GenerateVideoResponse for the shared suffix + // Map v1 GenerationResult → GenerateVideoResponse for the shared suffix let response = if gen_result.is_seedance2pro { GenerateVideoResponse::Seedance2Pro( artcraft_router::generate::generate_video::generate_video_response::Seedance2proVideoResponsePayload { diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/pipeline_v2/run_pipeline_v2.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/pipeline_v2/run_pipeline_v2.rs index 5cf9532453..3d38c49685 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/pipeline_v2/run_pipeline_v2.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/omni_gen/generate/video/pipeline_v2/run_pipeline_v2.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use log::{error, info, warn}; +use sqlx::pool::PoolConnection; use url::Url; use artcraft_api_defs::omni_gen::cost_and_generate_requests::omni_gen_video_cost_and_generate_request::OmniGenVideoCostAndGenerateRequest; @@ -20,23 +21,34 @@ use crate::http_server::endpoints::omni_gen::generate::video::hydrate_router_req use crate::http_server::endpoints::omni_gen::generate::video::pipeline_result::PipelineResult; use crate::state::server_state::ServerState; -pub async fn run_pipeline_v2( - request: &OmniGenVideoCostAndGenerateRequest, - server_state: &ServerState, - mysql_connection: &mut sqlx::pool::PoolConnection, - user_token: &UserToken, - media_file_hydration_map: &Option>, - media_file_to_url_map: &Option>, - kinovi_character_id_map: &Option>, -) -> Result { +pub struct RunPipelineV2Args<'a> { + pub request: &'a OmniGenVideoCostAndGenerateRequest, + pub server_state: &'a ServerState, + pub mysql_connection: &'a mut PoolConnection, + pub user_token: &'a UserToken, + pub media_file_to_url_map: &'a Option>, + pub kinovi_character_id_map: &'a Option>, +} + +pub async fn run_pipeline_v2(args: RunPipelineV2Args<'_>) -> Result { + let RunPipelineV2Args { + request, + server_state, + mysql_connection, + user_token, + media_file_to_url_map, + kinovi_character_id_map, + } = args; + // 1. Build execution request (provider = Seedance2Pro for Kinovi) let mut exec_builder = hydrate_to_router_request(request)?; exec_builder.provider = Provider::Seedance2Pro; - let draft_or_request = exec_builder.build2().map_err(|e| { - warn!("Failed to build2 for v2 pipeline: {}", e); - AdvancedCommonWebError::from_error(e) - })?; + let draft_or_request = exec_builder.build2() + .map_err(|e| { + warn!("Failed to build2 for v2 pipeline: {}", e); + AdvancedCommonWebError::from_error(e) + })?; let provider = draft_or_request.get_provider(); @@ -76,7 +88,10 @@ pub async fn run_pipeline_v2( if matches!(provider, Provider::Seedance2Pro) { if let Some(ledger_entry_token) = billing.maybe_wallet_ledger_entry_token.as_ref() { warn!("Kinovi v2 generation failed, issuing refund for {}: {:?}", ledger_entry_token.as_str(), err); - if let Err(refund_err) = refund_wallet_after_api_failure(ledger_entry_token, mysql_connection).await { + + let result = refund_wallet_after_api_failure(ledger_entry_token, mysql_connection).await; + + if let Err(refund_err) = result { error!("Failed to refund wallet after Kinovi v2 failure: {:?}", refund_err); } } @@ -84,6 +99,7 @@ pub async fn run_pipeline_v2( } let response = result?; + info!("v2 generation response: {:?}", response); Ok(PipelineResult { billing, response }) @@ -98,6 +114,7 @@ async fn upload_and_generate( media_file_urls_by_token: Option<&HashMap>, kinovi_character_ids: Option<&HashMap>, ) -> Result { + let provider = draft_or_request.get_provider(); let client = build_router_client(provider, server_state)?; @@ -110,15 +127,19 @@ async fn upload_and_generate( character_token_to_kinovi_id_map: kinovi_character_ids, }; - draft.finalize(draft_context).await.map_err(|err| { - warn!("Failed to finalize v2 draft: {:?}", err); - AdvancedCommonWebError::from_error(err) - })? + draft.finalize(draft_context) + .await + .map_err(|err| { + warn!("Failed to finalize v2 draft: {:?}", err); + AdvancedCommonWebError::from_error(err) + })? } }; - video_request.send_request(&client).await.map_err(|err| { - warn!("v2 video generation failed: {:?}", err); - AdvancedCommonWebError::from_error(err) - }) + video_request.send_request(&client) + .await + .map_err(|err| { + warn!("v2 video generation failed: {:?}", err); + AdvancedCommonWebError::from_error(err) + }) }