From ebfd12fec2f2739ad8cc22acda0fbe1ef1c250b4 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Thu, 7 May 2026 21:37:49 -0400 Subject: [PATCH] wip --- .../fal/generate_video_fal_kling_1_6_pro.rs | 22 ++++-- .../generate_video_fal_kling_2_1_master.rs | 20 +++-- .../fal/generate_video_fal_kling_2_1_pro.rs | 22 ++++-- .../generate_video_fal_kling_2_5_turbo_pro.rs | 40 ++++++---- .../fal/generate_video_fal_kling_2_6_pro.rs | 42 ++++++----- .../fal/generate_video_fal_kling_3p0_pro.rs | 50 +++++++------ .../generate_video_fal_kling_3p0_standard.rs | 50 +++++++------ .../generate_video_fal_seedance_1_0_lite.rs | 28 ++++--- .../generate_video_fal_seedance_1p5_pro.rs | 46 +++++++----- .../execute/fal/generate_video_fal_sora_2.rs | 40 ++++++---- .../fal/generate_video_fal_sora_2_pro.rs | 40 ++++++---- .../execute/fal/generate_video_fal_veo_2.rs | 42 +++++++---- .../execute/fal/generate_video_fal_veo_3.rs | 52 +++++++------ .../fal/generate_video_fal_veo_3_fast.rs | 24 ++++-- .../execute/fal/generate_video_fal_veo_3p1.rs | 74 +++++++++++-------- .../fal/generate_video_fal_veo_3p1_fast.rs | 74 +++++++++++-------- .../generate_video/generate_video_response.rs | 8 ++ 17 files changed, 409 insertions(+), 265 deletions(-) diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_1_6_pro.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_1_6_pro.rs index ad0b5cf552..d8baeddcb2 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_1_6_pro.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_1_6_pro.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -13,14 +16,18 @@ pub async fn execute_fal_kling_1_6_pro( plan: &PlanFalKling16Pro, fal_client: &RouterFalClient, ) -> Result { + let request = Kling1p6ProRequest { + image_url: plan.image_url.clone(), + end_frame_image_url: plan.end_image_url.clone(), + prompt: plan.prompt.clone(), + duration: plan.duration, + aspect_ratio: plan.aspect_ratio, + }; + + let outbound_request: Arc = Arc::new(request.clone()); + let args = Kling1p6ProArgs { - request: Kling1p6ProRequest { - image_url: plan.image_url.clone(), - end_frame_image_url: plan.end_image_url.clone(), - prompt: plan.prompt.clone(), - duration: plan.duration, - aspect_ratio: plan.aspect_ratio, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; @@ -32,5 +39,6 @@ pub async fn execute_fal_kling_1_6_pro( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_1_master.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_1_master.rs index bd2d812de2..471bc77d6d 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_1_master.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_1_master.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -13,13 +16,17 @@ pub async fn execute_fal_kling_2_1_master( plan: &PlanFalKling21Master, fal_client: &RouterFalClient, ) -> Result { + let request = Kling2p1MasterRequest { + image_url: plan.image_url.clone(), + prompt: plan.prompt.clone(), + duration: plan.duration, + aspect_ratio: plan.aspect_ratio, + }; + + let outbound_request: Arc = Arc::new(request.clone()); + let args = Kling2p1MasterArgs { - request: Kling2p1MasterRequest { - image_url: plan.image_url.clone(), - prompt: plan.prompt.clone(), - duration: plan.duration, - aspect_ratio: plan.aspect_ratio, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; @@ -31,5 +38,6 @@ pub async fn execute_fal_kling_2_1_master( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_1_pro.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_1_pro.rs index ebbfe65f74..42a54d470b 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_1_pro.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_1_pro.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -13,14 +16,18 @@ pub async fn execute_fal_kling_2_1_pro( plan: &PlanFalKling21Pro, fal_client: &RouterFalClient, ) -> Result { + let request = Kling2p1ProRequest { + image_url: plan.image_url.clone(), + end_frame_image_url: plan.end_image_url.clone(), + prompt: plan.prompt.clone(), + duration: plan.duration, + aspect_ratio: plan.aspect_ratio, + }; + + let outbound_request: Arc = Arc::new(request.clone()); + let args = Kling2p1ProArgs { - request: Kling2p1ProRequest { - image_url: plan.image_url.clone(), - end_frame_image_url: plan.end_image_url.clone(), - prompt: plan.prompt.clone(), - duration: plan.duration, - aspect_ratio: plan.aspect_ratio, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; @@ -32,5 +39,6 @@ pub async fn execute_fal_kling_2_1_pro( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_5_turbo_pro.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_5_turbo_pro.rs index c6c80912f1..2eb0033c21 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_5_turbo_pro.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_5_turbo_pro.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -22,33 +25,37 @@ pub async fn execute_fal_kling_2_5_turbo_pro( plan: &PlanFalKling2p5TurboPro, fal_client: &RouterFalClient, ) -> Result { - let webhook_response = match &plan.mode { + let (webhook_response, outbound_request) = match &plan.mode { FalKling2p5TurboProMode::TextToVideo => { + let request = EnqueueKlingV2p5TurboProTextToVideoRequest { + prompt: plan.prompt.clone(), + negative_prompt: plan.negative_prompt.clone(), + duration: plan.duration.map(to_t2v_duration), + aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueKlingV2p5TurboProTextToVideoArgs { - request: EnqueueKlingV2p5TurboProTextToVideoRequest { - prompt: plan.prompt.clone(), - negative_prompt: plan.negative_prompt.clone(), - duration: plan.duration.map(to_t2v_duration), - aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_kling_v2p5_turbo_pro_text_to_video_webhook(args).await + (enqueue_kling_v2p5_turbo_pro_text_to_video_webhook(args).await, outbound) } FalKling2p5TurboProMode::ImageToVideo { image_url, end_image_url } => { + let request = EnqueueKlingV2p5TurboProImageToVideoRequest { + prompt: plan.prompt.clone(), + image_url: image_url.clone(), + tail_image_url: end_image_url.clone(), + negative_prompt: plan.negative_prompt.clone(), + duration: plan.duration.map(to_i2v_duration), + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueKlingV2p5TurboProImageToVideoArgs { - request: EnqueueKlingV2p5TurboProImageToVideoRequest { - prompt: plan.prompt.clone(), - image_url: image_url.clone(), - tail_image_url: end_image_url.clone(), - negative_prompt: plan.negative_prompt.clone(), - duration: plan.duration.map(to_i2v_duration), - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_kling_v2p5_turbo_pro_image_to_video_webhook(args).await + (enqueue_kling_v2p5_turbo_pro_image_to_video_webhook(args).await, outbound) } }; @@ -58,6 +65,7 @@ pub async fn execute_fal_kling_2_5_turbo_pro( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_6_pro.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_6_pro.rs index 5f0e316764..46046ed76c 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_6_pro.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_2_6_pro.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -21,34 +24,38 @@ pub async fn execute_fal_kling_2_6_pro( plan: &PlanFalKling2p6Pro, fal_client: &RouterFalClient, ) -> Result { - let webhook_response = match &plan.mode { + let (webhook_response, outbound_request) = match &plan.mode { FalKling2p6ProMode::TextToVideo => { + let request = EnqueueKlingV2p6ProTextToVideoRequest { + prompt: plan.prompt.clone(), + generate_audio: plan.generate_audio, + negative_prompt: plan.negative_prompt.clone(), + duration: plan.duration.map(to_t2v_duration), + aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueKlingV2p6ProTextToVideoArgs { - request: EnqueueKlingV2p6ProTextToVideoRequest { - prompt: plan.prompt.clone(), - generate_audio: plan.generate_audio, - negative_prompt: plan.negative_prompt.clone(), - duration: plan.duration.map(to_t2v_duration), - aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_kling_v2p6_pro_text_to_video_webhook(args).await + (enqueue_kling_v2p6_pro_text_to_video_webhook(args).await, outbound) } FalKling2p6ProMode::ImageToVideo { image_url } => { + let request = EnqueueKlingV2p6ProImageToVideoRequest { + prompt: plan.prompt.clone(), + image_url: image_url.clone(), + generate_audio: plan.generate_audio, + negative_prompt: plan.negative_prompt.clone(), + duration: plan.duration.map(to_i2v_duration), + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueKlingV2p6ProImageToVideoArgs { - request: EnqueueKlingV2p6ProImageToVideoRequest { - prompt: plan.prompt.clone(), - image_url: image_url.clone(), - generate_audio: plan.generate_audio, - negative_prompt: plan.negative_prompt.clone(), - duration: plan.duration.map(to_i2v_duration), - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_kling_v2p6_pro_image_to_video_webhook(args).await + (enqueue_kling_v2p6_pro_image_to_video_webhook(args).await, outbound) } }; @@ -58,6 +65,7 @@ pub async fn execute_fal_kling_2_6_pro( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_3p0_pro.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_3p0_pro.rs index 292ce7179b..56c417c9ff 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_3p0_pro.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_3p0_pro.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -22,38 +25,42 @@ pub async fn execute_fal_kling_3p0_pro( plan: &PlanFalKling3p0Pro, fal_client: &RouterFalClient, ) -> Result { - let webhook_response = match &plan.mode { + let (webhook_response, outbound_request) = match &plan.mode { FalKling3p0Mode::TextToVideo => { + let request = EnqueueKling3p0ProTextToVideoRequest { + prompt: plan.prompt.clone(), + generate_audio: plan.generate_audio, + negative_prompt: plan.negative_prompt.clone(), + duration: plan.duration.map(to_t2v_duration), + aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), + shot_type: None, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueKling3p0ProTextToVideoArgs { - request: EnqueueKling3p0ProTextToVideoRequest { - prompt: plan.prompt.clone(), - generate_audio: plan.generate_audio, - negative_prompt: plan.negative_prompt.clone(), - duration: plan.duration.map(to_t2v_duration), - aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), - shot_type: None, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_kling_3p0_pro_text_to_video_webhook(args).await + (enqueue_kling_3p0_pro_text_to_video_webhook(args).await, outbound) } FalKling3p0Mode::ImageToVideo { image_url, end_image_url } => { + let request = EnqueueKling3p0ProImageToVideoRequest { + prompt: plan.prompt.clone(), + image_url: image_url.clone(), + end_image_url: end_image_url.clone(), + generate_audio: plan.generate_audio, + negative_prompt: plan.negative_prompt.clone(), + duration: plan.duration.map(to_i2v_duration), + aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), + shot_type: None, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueKling3p0ProImageToVideoArgs { - request: EnqueueKling3p0ProImageToVideoRequest { - prompt: plan.prompt.clone(), - image_url: image_url.clone(), - end_image_url: end_image_url.clone(), - generate_audio: plan.generate_audio, - negative_prompt: plan.negative_prompt.clone(), - duration: plan.duration.map(to_i2v_duration), - aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), - shot_type: None, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_kling_3p0_pro_image_to_video_webhook(args).await + (enqueue_kling_3p0_pro_image_to_video_webhook(args).await, outbound) } }; @@ -63,6 +70,7 @@ pub async fn execute_fal_kling_3p0_pro( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_3p0_standard.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_3p0_standard.rs index 7d83a81ead..14c47a0cec 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_3p0_standard.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_kling_3p0_standard.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -23,38 +26,42 @@ pub async fn execute_fal_kling_3p0_standard( plan: &PlanFalKling3p0Standard, fal_client: &RouterFalClient, ) -> Result { - let webhook_response = match &plan.mode { + let (webhook_response, outbound_request) = match &plan.mode { FalKling3p0Mode::TextToVideo => { + let request = EnqueueKling3p0StandardTextToVideoRequest { + prompt: plan.prompt.clone(), + generate_audio: plan.generate_audio, + negative_prompt: plan.negative_prompt.clone(), + duration: plan.duration.map(to_t2v_duration), + aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), + shot_type: None, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueKling3p0StandardTextToVideoArgs { - request: EnqueueKling3p0StandardTextToVideoRequest { - prompt: plan.prompt.clone(), - generate_audio: plan.generate_audio, - negative_prompt: plan.negative_prompt.clone(), - duration: plan.duration.map(to_t2v_duration), - aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), - shot_type: None, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_kling_3p0_standard_text_to_video_webhook(args).await + (enqueue_kling_3p0_standard_text_to_video_webhook(args).await, outbound) } FalKling3p0Mode::ImageToVideo { image_url, end_image_url } => { + let request = EnqueueKling3p0StandardImageToVideoRequest { + prompt: plan.prompt.clone(), + image_url: image_url.clone(), + end_image_url: end_image_url.clone(), + generate_audio: plan.generate_audio, + negative_prompt: plan.negative_prompt.clone(), + duration: plan.duration.map(to_i2v_duration), + aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), + shot_type: None, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueKling3p0StandardImageToVideoArgs { - request: EnqueueKling3p0StandardImageToVideoRequest { - prompt: plan.prompt.clone(), - image_url: image_url.clone(), - end_image_url: end_image_url.clone(), - generate_audio: plan.generate_audio, - negative_prompt: plan.negative_prompt.clone(), - duration: plan.duration.map(to_i2v_duration), - aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), - shot_type: None, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_kling_3p0_standard_image_to_video_webhook(args).await + (enqueue_kling_3p0_standard_image_to_video_webhook(args).await, outbound) } }; @@ -64,6 +71,7 @@ pub async fn execute_fal_kling_3p0_standard( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_seedance_1_0_lite.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_seedance_1_0_lite.rs index 6675c88db7..c8c9c5119b 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_seedance_1_0_lite.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_seedance_1_0_lite.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -13,17 +16,21 @@ pub async fn execute_fal_seedance_1_0_lite( plan: &PlanFalSeedance10Lite, fal_client: &RouterFalClient, ) -> Result { + let request = Seedance1LiteRequest { + image_url: plan.image_url.clone(), + end_frame_image_url: plan.end_image_url.clone(), + prompt: plan.prompt.clone(), + duration: plan.duration, + resolution: plan.resolution, + aspect_ratio: plan.aspect_ratio, + camera_fixed: false, + seed: None, + }; + + let outbound_request: Arc = Arc::new(request.clone()); + let args = Seedance1LiteArgs { - request: Seedance1LiteRequest { - image_url: plan.image_url.clone(), - end_frame_image_url: plan.end_image_url.clone(), - prompt: plan.prompt.clone(), - duration: plan.duration, - resolution: plan.resolution, - aspect_ratio: plan.aspect_ratio, - camera_fixed: false, - seed: None, - }, + request, api_key: &fal_client.api_key, webhook_url: fal_client.webhook_url.as_str(), }; @@ -35,5 +42,6 @@ pub async fn execute_fal_seedance_1_0_lite( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_seedance_1p5_pro.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_seedance_1p5_pro.rs index ce048e3932..4031db8be9 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_seedance_1p5_pro.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_seedance_1p5_pro.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -23,36 +26,40 @@ pub async fn execute_fal_seedance_1p5_pro( plan: &PlanFalSeedance1p5Pro, fal_client: &RouterFalClient, ) -> Result { - let webhook_response = match &plan.mode { + let (webhook_response, outbound_request) = match &plan.mode { FalSeedance1p5ProMode::TextToVideo => { + let request = EnqueueSeedance1p5ProTextToVideoRequest { + prompt: plan.prompt.clone(), + resolution: plan.resolution.map(to_t2v_resolution), + duration: plan.duration.map(to_t2v_duration), + aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), + generate_audio: plan.generate_audio, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueSeedance1p5ProTextToVideoArgs { - request: EnqueueSeedance1p5ProTextToVideoRequest { - prompt: plan.prompt.clone(), - resolution: plan.resolution.map(to_t2v_resolution), - duration: plan.duration.map(to_t2v_duration), - aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), - generate_audio: plan.generate_audio, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_seedance_1p5_pro_text_to_video_webhook(args).await + (enqueue_seedance_1p5_pro_text_to_video_webhook(args).await, outbound) } FalSeedance1p5ProMode::ImageToVideo { image_url, end_image_url } => { + let request = EnqueueSeedance1p5ProImageToVideoRequest { + prompt: plan.prompt.clone(), + image_url: image_url.clone(), + end_image_url: end_image_url.clone(), + resolution: plan.resolution.map(to_i2v_resolution), + duration: plan.duration.map(to_i2v_duration), + aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), + generate_audio: plan.generate_audio, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueSeedance1p5ProImageToVideoArgs { - request: EnqueueSeedance1p5ProImageToVideoRequest { - prompt: plan.prompt.clone(), - image_url: image_url.clone(), - end_image_url: end_image_url.clone(), - resolution: plan.resolution.map(to_i2v_resolution), - duration: plan.duration.map(to_i2v_duration), - aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), - generate_audio: plan.generate_audio, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_seedance_1p5_pro_image_to_video_webhook(args).await + (enqueue_seedance_1p5_pro_image_to_video_webhook(args).await, outbound) } }; @@ -62,6 +69,7 @@ pub async fn execute_fal_seedance_1p5_pro( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_sora_2.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_sora_2.rs index db159544c6..68b93a372c 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_sora_2.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_sora_2.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -22,34 +25,38 @@ pub async fn execute_fal_sora_2( plan: &PlanFalSora2, fal_client: &RouterFalClient, ) -> Result { - let webhook_response = match &plan.mode { + let (webhook_response, outbound_request) = match &plan.mode { FalSora2Mode::TextToVideo => { // Text-to-video does not support Auto aspect ratio or Auto resolution. + let request = EnqueueSora2TextToVideoRequest { + prompt: plan.prompt.clone(), + resolution: plan.resolution.and_then(to_t2v_resolution), + duration: plan.duration.map(to_t2v_duration), + aspect_ratio: plan.aspect_ratio.and_then(to_t2v_aspect_ratio), + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueSora2TextToVideoArgs { - request: EnqueueSora2TextToVideoRequest { - prompt: plan.prompt.clone(), - resolution: plan.resolution.and_then(to_t2v_resolution), - duration: plan.duration.map(to_t2v_duration), - aspect_ratio: plan.aspect_ratio.and_then(to_t2v_aspect_ratio), - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_sora_2_text_to_video_webhook(args).await + (enqueue_sora_2_text_to_video_webhook(args).await, outbound) } FalSora2Mode::ImageToVideo { image_url } => { + let request = EnqueueSora2ImageToVideoRequest { + prompt: plan.prompt.clone(), + image_url: image_url.clone(), + duration: plan.duration.map(to_i2v_duration), + resolution: plan.resolution.map(to_i2v_resolution), + aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueSora2ImageToVideoArgs { - request: EnqueueSora2ImageToVideoRequest { - prompt: plan.prompt.clone(), - image_url: image_url.clone(), - duration: plan.duration.map(to_i2v_duration), - resolution: plan.resolution.map(to_i2v_resolution), - aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_sora_2_image_to_video_webhook(args).await + (enqueue_sora_2_image_to_video_webhook(args).await, outbound) } }; @@ -59,6 +66,7 @@ pub async fn execute_fal_sora_2( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_sora_2_pro.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_sora_2_pro.rs index 870fa44a57..5818cbe626 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_sora_2_pro.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_sora_2_pro.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -23,34 +26,38 @@ pub async fn execute_fal_sora_2_pro( plan: &PlanFalSora2Pro, fal_client: &RouterFalClient, ) -> Result { - let webhook_response = match &plan.mode { + let (webhook_response, outbound_request) = match &plan.mode { FalSora2ProMode::TextToVideo => { // Text-to-video does not support Auto aspect ratio or Auto resolution. + let request = EnqueueSora2ProTextToVideoRequest { + prompt: plan.prompt.clone(), + resolution: plan.resolution.and_then(to_t2v_resolution), + duration: plan.duration.map(to_t2v_duration), + aspect_ratio: plan.aspect_ratio.and_then(to_t2v_aspect_ratio), + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueSora2ProTextToVideoArgs { - request: EnqueueSora2ProTextToVideoRequest { - prompt: plan.prompt.clone(), - resolution: plan.resolution.and_then(to_t2v_resolution), - duration: plan.duration.map(to_t2v_duration), - aspect_ratio: plan.aspect_ratio.and_then(to_t2v_aspect_ratio), - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_sora_2_pro_text_to_video_webhook(args).await + (enqueue_sora_2_pro_text_to_video_webhook(args).await, outbound) } FalSora2ProMode::ImageToVideo { image_url } => { + let request = EnqueueSora2ProImageToVideoRequest { + prompt: plan.prompt.clone(), + image_url: image_url.clone(), + duration: plan.duration.map(to_i2v_duration), + resolution: plan.resolution.map(to_i2v_resolution), + aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueSora2ProImageToVideoArgs { - request: EnqueueSora2ProImageToVideoRequest { - prompt: plan.prompt.clone(), - image_url: image_url.clone(), - duration: plan.duration.map(to_i2v_duration), - resolution: plan.resolution.map(to_i2v_resolution), - aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_sora_2_pro_image_to_video_webhook(args).await + (enqueue_sora_2_pro_image_to_video_webhook(args).await, outbound) } }; @@ -60,6 +67,7 @@ pub async fn execute_fal_sora_2_pro( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_2.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_2.rs index 3d3f54547d..20e4983ffc 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_2.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_2.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -18,42 +21,49 @@ pub async fn execute_fal_veo_2( plan: &PlanFalVeo2, fal_client: &RouterFalClient, ) -> Result { - let webhook_response = match &plan.mode { + let (webhook_response, outbound_request) = match &plan.mode { FalVeo2Mode::TextToVideo => { + let request = Veo2TextToVideoRequest { + prompt: plan.prompt.clone(), + negative_prompt: plan.negative_prompt.clone(), + duration: plan.duration, + aspect_ratio: plan.aspect_ratio.unwrap_or(Veo2AspectRatio::Auto), + }; + let outbound: Arc = Arc::new(request.clone()); let args = Veo2TextToVideoArgs { - request: Veo2TextToVideoRequest { - prompt: plan.prompt.clone(), - negative_prompt: plan.negative_prompt.clone(), - duration: plan.duration, - aspect_ratio: plan.aspect_ratio.unwrap_or(Veo2AspectRatio::Auto), - }, + request, api_key: &fal_client.api_key, webhook_url: fal_client.webhook_url.as_str(), }; - enqueue_veo_2_text_to_video_webhook(args) + let resp = enqueue_veo_2_text_to_video_webhook(args) .await - .map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))? + .map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?; + (resp, outbound) } FalVeo2Mode::ImageToVideo { image_url } => { // Image-to-video does not support aspect_ratio — the output // inherits the source image's aspect ratio. + let request = Veo2Request { + image_url: image_url.to_string(), + prompt: plan.prompt.clone(), + duration: plan.duration, + }; + let outbound: Arc = Arc::new(request.clone()); let args = Veo2Args { - request: Veo2Request { - image_url: image_url.to_string(), - prompt: plan.prompt.clone(), - duration: plan.duration, - }, + request, api_key: &fal_client.api_key, webhook_url: fal_client.webhook_url.as_str(), }; - enqueue_veo_2_image_to_video_webhook(args) + let resp = enqueue_veo_2_image_to_video_webhook(args) .await - .map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))? + .map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?; + (resp, outbound) } }; Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3.rs index 43dcc9a013..892654a00a 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -71,45 +74,52 @@ pub async fn execute_fal_veo_3( plan: &PlanFalVeo3, fal_client: &RouterFalClient, ) -> Result { - let webhook_response = match &plan.mode { + let (webhook_response, outbound_request) = match &plan.mode { FalVeo3Mode::TextToVideo => { + let request = Veo3TextToVideoRequest { + prompt: plan.prompt.clone(), + negative_prompt: plan.negative_prompt.clone(), + duration: to_t2v_duration(plan.duration), + aspect_ratio: plan.t2v_aspect_ratio.map(to_t2v_aspect_ratio).unwrap_or(Veo3T2vAspectRatio::Default), + resolution: to_t2v_resolution(plan.resolution), + generate_audio: plan.generate_audio, + }; + let outbound: Arc = Arc::new(request.clone()); let args = Veo3TextToVideoArgs { - request: Veo3TextToVideoRequest { - prompt: plan.prompt.clone(), - negative_prompt: plan.negative_prompt.clone(), - duration: to_t2v_duration(plan.duration), - aspect_ratio: plan.t2v_aspect_ratio.map(to_t2v_aspect_ratio).unwrap_or(Veo3T2vAspectRatio::Default), - resolution: to_t2v_resolution(plan.resolution), - generate_audio: plan.generate_audio, - }, + request, api_key: &fal_client.api_key, webhook_url: fal_client.webhook_url.as_str(), }; - enqueue_veo_3_text_to_video_webhook(args) + let resp = enqueue_veo_3_text_to_video_webhook(args) .await - .map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))? + .map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?; + (resp, outbound) } FalVeo3Mode::ImageToVideo { image_url } => { + let request = Veo3Request { + image_url: image_url.to_string(), + prompt: plan.prompt.clone(), + duration: to_i2v_duration(plan.duration), + aspect_ratio: plan.i2v_aspect_ratio.map(to_i2v_aspect_ratio).unwrap_or(Veo3I2vAspectRatio::Auto), + resolution: to_i2v_resolution(plan.resolution), + generate_audio: plan.generate_audio, + }; + let outbound: Arc = Arc::new(request.clone()); let args = Veo3Args { - request: Veo3Request { - image_url: image_url.to_string(), - prompt: plan.prompt.clone(), - duration: to_i2v_duration(plan.duration), - aspect_ratio: plan.i2v_aspect_ratio.map(to_i2v_aspect_ratio).unwrap_or(Veo3I2vAspectRatio::Auto), - resolution: to_i2v_resolution(plan.resolution), - generate_audio: plan.generate_audio, - }, + request, api_key: &fal_client.api_key, webhook_url: fal_client.webhook_url.as_str(), }; - enqueue_veo_3_image_to_video_webhook(args) + let resp = enqueue_veo_3_image_to_video_webhook(args) .await - .map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))? + .map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?; + (resp, outbound) } }; Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3_fast.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3_fast.rs index 358017d2ba..35b6b65ffd 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3_fast.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3_fast.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -13,15 +16,19 @@ pub async fn execute_fal_veo_3_fast( plan: &PlanFalVeo3Fast, fal_client: &RouterFalClient, ) -> Result { + let request = Veo3FastRequest { + prompt: plan.prompt.clone(), + image_url: plan.start_frame_url.clone(), + aspect_ratio: plan.aspect_ratio, + duration: plan.duration, + resolution: plan.resolution, + generate_audio: plan.generate_audio, + }; + + let outbound_request: Arc = Arc::new(request.clone()); + let args = Veo3FastArgs { - request: Veo3FastRequest { - prompt: plan.prompt.clone(), - image_url: plan.start_frame_url.clone(), - aspect_ratio: plan.aspect_ratio, - duration: plan.duration, - resolution: plan.resolution, - generate_audio: plan.generate_audio, - }, + request, api_key: &fal_client.api_key, webhook_url: fal_client.webhook_url.as_str(), }; @@ -33,5 +40,6 @@ pub async fn execute_fal_veo_3_fast( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3p1.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3p1.rs index c28aa09a21..00f1cfb6ff 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3p1.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3p1.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -30,55 +33,61 @@ pub async fn execute_fal_veo_3p1( plan: &PlanFalVeo3p1, fal_client: &RouterFalClient, ) -> Result { - let webhook_response = match &plan.mode { + let (webhook_response, outbound_request) = match &plan.mode { FalVeo3p1Mode::TextToVideo => { + let request = EnqueueVeo3p1TextToVideoRequest { + prompt: plan.prompt.clone(), + duration: plan.duration.map(to_t2v_duration), + aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), + resolution: plan.resolution.map(to_t2v_resolution), + generate_audio: plan.generate_audio, + enhance_prompt: None, + negative_prompt: plan.negative_prompt.clone(), + seed: None, + auto_fix: None, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueVeo3p1TextToVideoArgs { - request: EnqueueVeo3p1TextToVideoRequest { - prompt: plan.prompt.clone(), - duration: plan.duration.map(to_t2v_duration), - aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio), - resolution: plan.resolution.map(to_t2v_resolution), - generate_audio: plan.generate_audio, - enhance_prompt: None, - negative_prompt: plan.negative_prompt.clone(), - seed: None, - auto_fix: None, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_veo_3p1_text_to_video_webhook(args).await + (enqueue_veo_3p1_text_to_video_webhook(args).await, outbound) } FalVeo3p1Mode::ImageToVideo { start_frame_url } => { + let request = EnqueueVeo3p1ImageToVideoRequest { + prompt: plan.prompt.clone(), + image_url: start_frame_url.clone(), + duration: plan.duration.map(to_i2v_duration), + aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), + resolution: plan.resolution.map(to_i2v_resolution), + generate_audio: plan.generate_audio, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueVeo3p1ImageToVideoArgs { - request: EnqueueVeo3p1ImageToVideoRequest { - prompt: plan.prompt.clone(), - image_url: start_frame_url.clone(), - duration: plan.duration.map(to_i2v_duration), - aspect_ratio: plan.aspect_ratio.map(to_i2v_aspect_ratio), - resolution: plan.resolution.map(to_i2v_resolution), - generate_audio: plan.generate_audio, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_veo_3p1_image_to_video_webhook(args).await + (enqueue_veo_3p1_image_to_video_webhook(args).await, outbound) } FalVeo3p1Mode::FirstLastFrame { first_frame_url, last_frame_url } => { + let request = EnqueueVeo3p1FirstLastFrameImageToVideoRequest { + prompt: plan.prompt.clone(), + first_frame_url: first_frame_url.clone(), + last_frame_url: last_frame_url.clone(), + duration: plan.duration.map(to_flf_duration), + aspect_ratio: plan.aspect_ratio.map(to_flf_aspect_ratio), + resolution: plan.resolution.map(to_flf_resolution), + generate_audio: plan.generate_audio, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueVeo3p1FirstLastFrameImageToVideoArgs { - request: EnqueueVeo3p1FirstLastFrameImageToVideoRequest { - prompt: plan.prompt.clone(), - first_frame_url: first_frame_url.clone(), - last_frame_url: last_frame_url.clone(), - duration: plan.duration.map(to_flf_duration), - aspect_ratio: plan.aspect_ratio.map(to_flf_aspect_ratio), - resolution: plan.resolution.map(to_flf_resolution), - generate_audio: plan.generate_audio, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_veo_3p1_first_last_frame_image_to_video_webhook(args).await + (enqueue_veo_3p1_first_last_frame_image_to_video_webhook(args).await, outbound) } }; @@ -88,6 +97,7 @@ pub async fn execute_fal_veo_3p1( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3p1_fast.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3p1_fast.rs index ad07079bcb..0a0ee21520 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3p1_fast.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/execute/fal/generate_video_fal_veo_3p1_fast.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use crate::client::router_fal_client::RouterFalClient; use crate::errors::artcraft_router_error::ArtcraftRouterError; use crate::errors::provider_error::ProviderError; @@ -33,55 +36,61 @@ pub async fn execute_fal_veo_3p1_fast( ) -> Result { let inner = &plan.inner; - let webhook_response = match &inner.mode { + let (webhook_response, outbound_request) = match &inner.mode { FalVeo3p1Mode::TextToVideo => { + let request = EnqueueVeo3p1FastTextToVideoRequest { + prompt: inner.prompt.clone(), + duration: inner.duration.map(to_t2v_duration), + aspect_ratio: inner.aspect_ratio.map(to_t2v_aspect_ratio), + resolution: inner.resolution.map(to_t2v_resolution), + generate_audio: inner.generate_audio, + enhance_prompt: None, + negative_prompt: inner.negative_prompt.clone(), + seed: None, + auto_fix: None, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueVeo3p1FastTextToVideoArgs { - request: EnqueueVeo3p1FastTextToVideoRequest { - prompt: inner.prompt.clone(), - duration: inner.duration.map(to_t2v_duration), - aspect_ratio: inner.aspect_ratio.map(to_t2v_aspect_ratio), - resolution: inner.resolution.map(to_t2v_resolution), - generate_audio: inner.generate_audio, - enhance_prompt: None, - negative_prompt: inner.negative_prompt.clone(), - seed: None, - auto_fix: None, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_veo_3p1_fast_text_to_video_webhook(args).await + (enqueue_veo_3p1_fast_text_to_video_webhook(args).await, outbound) } FalVeo3p1Mode::ImageToVideo { start_frame_url } => { + let request = EnqueueVeo3p1FastImageToVideoRequest { + prompt: inner.prompt.clone(), + image_url: start_frame_url.clone(), + duration: inner.duration.map(to_i2v_duration), + aspect_ratio: inner.aspect_ratio.map(to_i2v_aspect_ratio), + resolution: inner.resolution.map(to_i2v_resolution), + generate_audio: inner.generate_audio, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueVeo3p1FastImageToVideoArgs { - request: EnqueueVeo3p1FastImageToVideoRequest { - prompt: inner.prompt.clone(), - image_url: start_frame_url.clone(), - duration: inner.duration.map(to_i2v_duration), - aspect_ratio: inner.aspect_ratio.map(to_i2v_aspect_ratio), - resolution: inner.resolution.map(to_i2v_resolution), - generate_audio: inner.generate_audio, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_veo_3p1_fast_image_to_video_webhook(args).await + (enqueue_veo_3p1_fast_image_to_video_webhook(args).await, outbound) } FalVeo3p1Mode::FirstLastFrame { first_frame_url, last_frame_url } => { + let request = EnqueueVeo3p1FastFirstLastFrameImageToVideoRequest { + prompt: inner.prompt.clone(), + first_frame_url: first_frame_url.clone(), + last_frame_url: last_frame_url.clone(), + duration: inner.duration.map(to_flf_duration), + aspect_ratio: inner.aspect_ratio.map(to_flf_aspect_ratio), + resolution: inner.resolution.map(to_flf_resolution), + generate_audio: inner.generate_audio, + }; + let outbound: Arc = Arc::new(request.clone()); let args = EnqueueVeo3p1FastFirstLastFrameImageToVideoArgs { - request: EnqueueVeo3p1FastFirstLastFrameImageToVideoRequest { - prompt: inner.prompt.clone(), - first_frame_url: first_frame_url.clone(), - last_frame_url: last_frame_url.clone(), - duration: inner.duration.map(to_flf_duration), - aspect_ratio: inner.aspect_ratio.map(to_flf_aspect_ratio), - resolution: inner.resolution.map(to_flf_resolution), - generate_audio: inner.generate_audio, - }, + request, webhook_url: fal_client.webhook_url.as_str(), api_key: &fal_client.api_key, }; - enqueue_veo_3p1_fast_first_last_frame_image_to_video_webhook(args).await + (enqueue_veo_3p1_fast_first_last_frame_image_to_video_webhook(args).await, outbound) } }; @@ -91,6 +100,7 @@ pub async fn execute_fal_veo_3p1_fast( Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload { request_id: webhook_response.request_id, gateway_request_id: webhook_response.gateway_request_id, + maybe_outbound_request: Some(outbound_request), })) } diff --git a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/generate_video_response.rs b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/generate_video_response.rs index d9e8ba911b..f8c9839841 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/generate_video_response.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/generate/generate_video/generate_video_response.rs @@ -1,3 +1,6 @@ +use std::fmt::Debug; +use std::sync::Arc; + use muapi_client::api_types::request_id::RequestId as MuapiRequestId; use tokens::tokens::generic_inference_jobs::InferenceJobToken; @@ -24,6 +27,11 @@ pub struct Seedance2proVideoResponsePayload { pub struct FalVideoResponsePayload { pub request_id: Option, pub gateway_request_id: Option, + + /// The outbound request that was sent to Fal. + /// Stored as a trait object so any Request type can be captured. + /// Use `format!("{:?}", ...)` or `format!("{:#?}", ...)` to print. + pub maybe_outbound_request: Option>, } #[derive(Clone, Debug)]