mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-21 09:22:41 -04:00
Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b88979859 | ||
|
|
20f16236e6 | ||
|
|
df3dac8982 | ||
|
|
ccea741443 | ||
|
|
2b9882d2d7 | ||
|
|
55cab30dec | ||
|
|
a2f204b1be | ||
|
|
12e4ff7a29 | ||
|
|
8b73569238 | ||
|
|
badabe57eb | ||
|
|
2e62eef85b | ||
|
|
fd9f002615 | ||
|
|
a0e50067bb |
Generated
-1
@@ -6089,7 +6089,6 @@ dependencies = [
|
||||
name = "jwt_signer"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"errors",
|
||||
"hmac 0.10.1",
|
||||
"jwt",
|
||||
"sha2 0.9.9",
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ pub struct GenerateKling16ProImageToVideoRequest {
|
||||
pub duration: Option<GenerateKling16ProDuration>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling16ProAspectRatio {
|
||||
/// 16:9 aspect ratio
|
||||
@@ -39,7 +39,7 @@ pub enum GenerateKling16ProAspectRatio {
|
||||
Square,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling16ProDuration {
|
||||
FiveSeconds,
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ pub struct GenerateKling21MasterImageToVideoRequest {
|
||||
pub duration: Option<GenerateKling21MasterDuration>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling21MasterAspectRatio {
|
||||
/// 16:9 aspect ratio
|
||||
@@ -35,7 +35,7 @@ pub enum GenerateKling21MasterAspectRatio {
|
||||
Square,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling21MasterDuration {
|
||||
FiveSeconds,
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ pub struct GenerateKling21ProImageToVideoRequest {
|
||||
pub duration: Option<GenerateKling21ProDuration>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling21ProAspectRatio {
|
||||
/// 16:9 aspect ratio
|
||||
@@ -39,7 +39,7 @@ pub enum GenerateKling21ProAspectRatio {
|
||||
Square,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling21ProDuration {
|
||||
FiveSeconds,
|
||||
|
||||
+3
-3
@@ -31,14 +31,14 @@ pub struct GenerateSeedance10LiteImageToVideoRequest {
|
||||
pub aspect_ratio: Option<GenerateSeedance10LiteAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateSeedance10LiteResolution {
|
||||
FourEightyP,
|
||||
SevenTwentyP,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateSeedance10LiteDuration {
|
||||
FiveSeconds,
|
||||
@@ -46,7 +46,7 @@ pub enum GenerateSeedance10LiteDuration {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateSeedance10LiteAspectRatio {
|
||||
Auto,
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ pub struct GenerateVeo2ImageToVideoRequest {
|
||||
pub duration: Option<GenerateVeo2Duration>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo2AspectRatio {
|
||||
Auto,
|
||||
@@ -33,7 +33,7 @@ pub enum GenerateVeo2AspectRatio {
|
||||
TallNineSixteen, // 9:16
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo2Duration {
|
||||
FiveSeconds,
|
||||
|
||||
+2
-2
@@ -27,14 +27,14 @@ pub struct GenerateVeo3FastImageToVideoRequest {
|
||||
pub generate_audio: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3FastResolution {
|
||||
SevenTwentyP, // 720p
|
||||
TenEightyP, // 1080p
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3FastDuration {
|
||||
EightSeconds,
|
||||
|
||||
+3
-3
@@ -37,7 +37,7 @@ pub struct GenerateVeo3ImageToVideoRequest {
|
||||
// pub auto_fix: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3AspectRatio {
|
||||
WideSixteenNine, // 16:9
|
||||
@@ -45,14 +45,14 @@ pub enum GenerateVeo3AspectRatio {
|
||||
Square, // 1:1
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3Resolution {
|
||||
SevenTwentyP, // 720p
|
||||
TenEightyP, // 1080p
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3Duration {
|
||||
EightSeconds,
|
||||
|
||||
+2
-2
@@ -41,14 +41,14 @@ pub struct Kling2p5TurboProMultiFunctionVideoGenRequest {
|
||||
pub aspect_ratio: Option<Kling2p5TurboProMultiFunctionVideoGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling2p5TurboProMultiFunctionVideoGenDuration {
|
||||
FiveSeconds,
|
||||
TenSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling2p5TurboProMultiFunctionVideoGenAspectRatio {
|
||||
Square,
|
||||
|
||||
+2
-2
@@ -45,14 +45,14 @@ pub struct Kling2p6ProMultiFunctionVideoGenRequest {
|
||||
pub aspect_ratio: Option<Kling2p6ProMultiFunctionVideoGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling2p6ProMultiFunctionVideoGenDuration {
|
||||
FiveSeconds,
|
||||
TenSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling2p6ProMultiFunctionVideoGenAspectRatio {
|
||||
Square,
|
||||
|
||||
+3
-3
@@ -35,14 +35,14 @@ pub struct Sora2MultiFunctionVideoGenRequest {
|
||||
pub aspect_ratio: Option<Sora2MultiFunctionVideoGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2MultiFunctionVideoGenResolution {
|
||||
Auto,
|
||||
SevenTwentyP,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2MultiFunctionVideoGenDuration {
|
||||
FourSeconds,
|
||||
@@ -50,7 +50,7 @@ pub enum Sora2MultiFunctionVideoGenDuration {
|
||||
TwelveSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2MultiFunctionVideoGenAspectRatio {
|
||||
Auto,
|
||||
|
||||
+3
-3
@@ -35,7 +35,7 @@ pub struct Sora2ProMultiFunctionVideoGenRequest {
|
||||
pub aspect_ratio: Option<Sora2ProMultiFunctionVideoGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2ProMultiFunctionVideoGenResolution {
|
||||
Auto,
|
||||
@@ -43,7 +43,7 @@ pub enum Sora2ProMultiFunctionVideoGenResolution {
|
||||
TenEightyP,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2ProMultiFunctionVideoGenDuration {
|
||||
FourSeconds,
|
||||
@@ -51,7 +51,7 @@ pub enum Sora2ProMultiFunctionVideoGenDuration {
|
||||
TwelveSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2ProMultiFunctionVideoGenAspectRatio {
|
||||
Auto,
|
||||
|
||||
+3
-3
@@ -60,7 +60,7 @@ pub struct Veo3p1FastMultiFunctionVideoGenRequest {
|
||||
pub auto_fix: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1FastMultiFunctionVideoGenDuration {
|
||||
FourSeconds,
|
||||
@@ -68,7 +68,7 @@ pub enum Veo3p1FastMultiFunctionVideoGenDuration {
|
||||
EightSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1FastMultiFunctionVideoGenAspectRatio {
|
||||
Auto,
|
||||
@@ -76,7 +76,7 @@ pub enum Veo3p1FastMultiFunctionVideoGenAspectRatio {
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1FastMultiFunctionVideoGenResolution {
|
||||
SevenTwentyP,
|
||||
|
||||
+3
-3
@@ -60,7 +60,7 @@ pub struct Veo3p1MultiFunctionVideoGenRequest {
|
||||
pub auto_fix: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1MultiFunctionVideoGenDuration {
|
||||
FourSeconds,
|
||||
@@ -68,7 +68,7 @@ pub enum Veo3p1MultiFunctionVideoGenDuration {
|
||||
EightSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1MultiFunctionVideoGenAspectRatio {
|
||||
Auto,
|
||||
@@ -76,7 +76,7 @@ pub enum Veo3p1MultiFunctionVideoGenAspectRatio {
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1MultiFunctionVideoGenResolution {
|
||||
SevenTwentyP,
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_pro_1p1::PlanFalFluxPro11;
|
||||
|
||||
pub(crate) fn estimate_image_cost_fal_flux_pro_1p1(
|
||||
plan: &PlanFalFluxPro11<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.04 per megapixel, billed by rounding up to nearest megapixel.
|
||||
// Default image sizes are ~1MP (1024x1024), so ~$0.04/image = 4 cents.
|
||||
let cost_per_image: u64 = 4;
|
||||
let num_images = plan.num_images.as_u64();
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_pro_1p1_ultra::PlanFalFluxPro11Ultra;
|
||||
|
||||
pub(crate) fn estimate_image_cost_fal_flux_pro_1p1_ultra(
|
||||
plan: &PlanFalFluxPro11Ultra<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.06 per image.
|
||||
let cost_per_image: u64 = 6;
|
||||
let num_images = plan.num_images.as_u64();
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_gpt_image_1p5::{
|
||||
FalGptImage1p5ImageSize, FalGptImage1p5Quality, PlanFalGptImage1p5,
|
||||
};
|
||||
|
||||
pub(crate) fn estimate_image_cost_fal_gpt_image_1p5(
|
||||
plan: &PlanFalGptImage1p5<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Per fal docs:
|
||||
// Low: $0.009 (1024x1024) / $0.013 (other)
|
||||
// Medium: $0.034 (1024x1024) / $0.050–0.051 (other)
|
||||
// High: $0.133 (1024x1024) / $0.199–0.200 (other)
|
||||
// Round up to whole cents.
|
||||
let is_square = matches!(plan.image_size, None | Some(FalGptImage1p5ImageSize::Square));
|
||||
let cost_per_image: u64 = match (plan.quality, is_square) {
|
||||
(FalGptImage1p5Quality::Low, true) => 1,
|
||||
(FalGptImage1p5Quality::Low, false) => 2,
|
||||
(FalGptImage1p5Quality::Medium, true) => 4,
|
||||
(FalGptImage1p5Quality::Medium, false) => 6,
|
||||
(FalGptImage1p5Quality::High, true) => 14,
|
||||
(FalGptImage1p5Quality::High, false) => 20,
|
||||
};
|
||||
let cost_in_usd_cents = cost_per_image * plan.num_images.as_u64();
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_4::PlanFalSeedream4;
|
||||
|
||||
pub(crate) fn estimate_image_cost_fal_seedream_4(
|
||||
plan: &PlanFalSeedream4<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.03 per image.
|
||||
let cost_per_image: u64 = 3;
|
||||
let cost_in_usd_cents = cost_per_image * plan.num_images.as_u64();
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_4p5::PlanFalSeedream4p5;
|
||||
|
||||
pub(crate) fn estimate_image_cost_fal_seedream_4p5(
|
||||
plan: &PlanFalSeedream4p5<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.04 per image.
|
||||
let cost_per_image: u64 = 4;
|
||||
let cost_in_usd_cents = cost_per_image * plan.num_images.as_u64();
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_5_lite::PlanFalSeedream5Lite;
|
||||
|
||||
pub(crate) fn estimate_image_cost_fal_seedream_5_lite(
|
||||
plan: &PlanFalSeedream5Lite<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.035 per image — round up to 4 cents.
|
||||
let cost_per_image: u64 = 4;
|
||||
let cost_in_usd_cents = cost_per_image * plan.num_images.as_u64();
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+6
@@ -1,5 +1,11 @@
|
||||
pub(crate) mod estimate_image_cost_fal_flux_1_dev;
|
||||
pub(crate) mod estimate_image_cost_fal_flux_1_schnell;
|
||||
pub(crate) mod estimate_image_cost_fal_flux_pro_1p1;
|
||||
pub(crate) mod estimate_image_cost_fal_flux_pro_1p1_ultra;
|
||||
pub(crate) mod estimate_image_cost_fal_gpt_image_1p5;
|
||||
pub(crate) mod estimate_image_cost_fal_seedream_4;
|
||||
pub(crate) mod estimate_image_cost_fal_seedream_4p5;
|
||||
pub(crate) mod estimate_image_cost_fal_seedream_5_lite;
|
||||
pub(crate) mod estimate_image_cost_fal_nano_banana;
|
||||
pub(crate) mod estimate_image_cost_fal_nano_banana_2;
|
||||
pub(crate) mod estimate_image_cost_fal_nano_banana_pro;
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_image::generate_image_response::{
|
||||
FalImageResponsePayload, GenerateImageResponse,
|
||||
};
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_pro_1p1::PlanFalFluxPro11;
|
||||
use fal_client::requests::webhook::image::text::enqueue_flux_pro_11_text_to_image_webhook::{
|
||||
enqueue_flux_pro_11_text_to_image_webhook, FluxPro11Args,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_flux_pro_1p1(
|
||||
plan: &PlanFalFluxPro11<'_>,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateImageResponse, ArtcraftRouterError> {
|
||||
let args = FluxPro11Args {
|
||||
prompt: plan.prompt.unwrap_or(""),
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
num_images: plan.num_images.to_fal(),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
let webhook_response = enqueue_flux_pro_11_text_to_image_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateImageResponse::Fal(FalImageResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_image::generate_image_response::{
|
||||
FalImageResponsePayload, GenerateImageResponse,
|
||||
};
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_pro_1p1_ultra::PlanFalFluxPro11Ultra;
|
||||
use fal_client::requests::webhook::image::text::enqueue_flux_pro_11_ultra_text_to_image_webhook::{
|
||||
enqueue_flux_pro_11_ultra_text_to_image_webhook, FluxPro11UltraArgs,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_flux_pro_1p1_ultra(
|
||||
plan: &PlanFalFluxPro11Ultra<'_>,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateImageResponse, ArtcraftRouterError> {
|
||||
let args = FluxPro11UltraArgs {
|
||||
prompt: plan.prompt.unwrap_or(""),
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
num_images: plan.num_images.to_fal(),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
let webhook_response = enqueue_flux_pro_11_ultra_text_to_image_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateImageResponse::Fal(FalImageResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_image::generate_image_response::{
|
||||
FalImageResponsePayload, GenerateImageResponse,
|
||||
};
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_gpt_image_1p5::PlanFalGptImage1p5;
|
||||
use fal_client::requests::webhook::image::edit::enqueue_gpt_image_1p5_edit_image_webhook::{
|
||||
enqueue_gpt_image_1p5_image_edit_webhook, EnqueueGptImage1p5EditImageArgs,
|
||||
};
|
||||
use fal_client::requests::webhook::image::text::enqueue_gpt_image_1p5_text_to_image_webhook::{
|
||||
enqueue_gpt_image_1p5_text_to_image_webhook, EnqueueGptImage1p5TextToImageArgs,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_gpt_image_1p5(
|
||||
plan: &PlanFalGptImage1p5<'_>,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateImageResponse, ArtcraftRouterError> {
|
||||
let webhook_response = if plan.image_urls.is_empty() {
|
||||
let args = EnqueueGptImage1p5TextToImageArgs {
|
||||
prompt: plan.prompt.unwrap_or(""),
|
||||
num_images: plan.num_images.to_t2i(),
|
||||
image_size: plan.image_size.map(|s| s.to_t2i()),
|
||||
background: None,
|
||||
quality: Some(plan.quality.to_t2i()),
|
||||
output_format: None,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_gpt_image_1p5_text_to_image_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?
|
||||
} else {
|
||||
let args = EnqueueGptImage1p5EditImageArgs {
|
||||
prompt: plan.prompt.unwrap_or(""),
|
||||
image_urls: plan.image_urls.clone(),
|
||||
num_images: plan.num_images.to_edit(),
|
||||
mask_image_url: None,
|
||||
image_size: plan.image_size.map(|s| s.to_edit()),
|
||||
background: None,
|
||||
quality: Some(plan.quality.to_edit()),
|
||||
input_fidelity: None,
|
||||
output_format: None,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_gpt_image_1p5_image_edit_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?
|
||||
};
|
||||
|
||||
Ok(GenerateImageResponse::Fal(FalImageResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_image::generate_image_response::{
|
||||
FalImageResponsePayload, GenerateImageResponse,
|
||||
};
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_4::PlanFalSeedream4;
|
||||
use fal_client::requests::webhook::image::edit::enqueue_bytedance_seedream_v4_edit_image_webhook::{
|
||||
enqueue_bytedance_seedream_v4_edit_image_webhook, EnqueueBytedanceSeedreamV4EditImageArgs,
|
||||
};
|
||||
use fal_client::requests::webhook::image::text::enqueue_bytedance_seedream_v4_text_to_image_webhook::{
|
||||
enqueue_bytedance_seedream_v4_text_to_image_webhook, EnqueueBytedanceSeedreamV4TextToImageArgs,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_seedream_4(
|
||||
plan: &PlanFalSeedream4<'_>,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateImageResponse, ArtcraftRouterError> {
|
||||
let webhook_response = if plan.image_urls.is_empty() {
|
||||
let args = EnqueueBytedanceSeedreamV4TextToImageArgs {
|
||||
prompt: plan.prompt.unwrap_or(""),
|
||||
num_images: Some(plan.num_images.to_t2i()),
|
||||
max_images: None,
|
||||
image_size: plan.image_size.map(|s| s.to_t2i()),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_bytedance_seedream_v4_text_to_image_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?
|
||||
} else {
|
||||
let args = EnqueueBytedanceSeedreamV4EditImageArgs {
|
||||
prompt: plan.prompt.unwrap_or(""),
|
||||
image_urls: plan.image_urls.clone(),
|
||||
num_images: Some(plan.num_images.to_edit()),
|
||||
max_images: None,
|
||||
image_size: plan.image_size.map(|s| s.to_edit()),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_bytedance_seedream_v4_edit_image_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?
|
||||
};
|
||||
|
||||
Ok(GenerateImageResponse::Fal(FalImageResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_image::generate_image_response::{
|
||||
FalImageResponsePayload, GenerateImageResponse,
|
||||
};
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_4p5::PlanFalSeedream4p5;
|
||||
use fal_client::requests::webhook::image::edit::enqueue_bytedance_seedream_v4p5_edit_image_webhook::{
|
||||
enqueue_bytedance_seedream_v4p5_edit_image_webhook, EnqueueBytedanceSeedreamV4p5EditImageArgs,
|
||||
};
|
||||
use fal_client::requests::webhook::image::text::enqueue_bytedance_seedream_v4p5_text_to_image_webhook::{
|
||||
enqueue_bytedance_seedream_v4p5_text_to_image_webhook, EnqueueBytedanceSeedreamV4p5TextToImageArgs,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_seedream_4p5(
|
||||
plan: &PlanFalSeedream4p5<'_>,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateImageResponse, ArtcraftRouterError> {
|
||||
let webhook_response = if plan.image_urls.is_empty() {
|
||||
let args = EnqueueBytedanceSeedreamV4p5TextToImageArgs {
|
||||
prompt: plan.prompt.unwrap_or(""),
|
||||
num_images: Some(plan.num_images.to_t2i()),
|
||||
max_images: None,
|
||||
image_size: plan.image_size.map(|s| s.to_t2i()),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_bytedance_seedream_v4p5_text_to_image_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?
|
||||
} else {
|
||||
let args = EnqueueBytedanceSeedreamV4p5EditImageArgs {
|
||||
prompt: plan.prompt.unwrap_or(""),
|
||||
image_urls: plan.image_urls.clone(),
|
||||
num_images: Some(plan.num_images.to_edit()),
|
||||
max_images: None,
|
||||
image_size: plan.image_size.map(|s| s.to_edit()),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_bytedance_seedream_v4p5_edit_image_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?
|
||||
};
|
||||
|
||||
Ok(GenerateImageResponse::Fal(FalImageResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_image::generate_image_response::{
|
||||
FalImageResponsePayload, GenerateImageResponse,
|
||||
};
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_5_lite::PlanFalSeedream5Lite;
|
||||
use fal_client::requests::webhook::image::edit::enqueue_bytedance_seedream_v5_lite_edit_image_webhook::{
|
||||
enqueue_bytedance_seedream_v5_lite_edit_image_webhook, EnqueueBytedanceSeedreamV5LiteEditImageArgs,
|
||||
};
|
||||
use fal_client::requests::webhook::image::text::enqueue_bytedance_seedream_v5_lite_text_to_image_webhook::{
|
||||
enqueue_bytedance_seedream_v5_lite_text_to_image_webhook, EnqueueBytedanceSeedreamV5LiteTextToImageArgs,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_seedream_5_lite(
|
||||
plan: &PlanFalSeedream5Lite<'_>,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateImageResponse, ArtcraftRouterError> {
|
||||
let webhook_response = if plan.image_urls.is_empty() {
|
||||
let args = EnqueueBytedanceSeedreamV5LiteTextToImageArgs {
|
||||
prompt: plan.prompt.unwrap_or(""),
|
||||
num_images: Some(plan.num_images.to_t2i()),
|
||||
max_images: None,
|
||||
image_size: plan.image_size.map(|s| s.to_t2i()),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_bytedance_seedream_v5_lite_text_to_image_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?
|
||||
} else {
|
||||
let args = EnqueueBytedanceSeedreamV5LiteEditImageArgs {
|
||||
prompt: plan.prompt.unwrap_or(""),
|
||||
image_urls: plan.image_urls.clone(),
|
||||
num_images: Some(plan.num_images.to_edit()),
|
||||
max_images: None,
|
||||
image_size: plan.image_size.map(|s| s.to_edit()),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_bytedance_seedream_v5_lite_edit_image_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?
|
||||
};
|
||||
|
||||
Ok(GenerateImageResponse::Fal(FalImageResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+6
@@ -1,5 +1,11 @@
|
||||
pub mod generate_image_fal_flux_1_dev;
|
||||
pub mod generate_image_fal_flux_1_schnell;
|
||||
pub mod generate_image_fal_flux_pro_1p1;
|
||||
pub mod generate_image_fal_flux_pro_1p1_ultra;
|
||||
pub mod generate_image_fal_gpt_image_1p5;
|
||||
pub mod generate_image_fal_seedream_4;
|
||||
pub mod generate_image_fal_seedream_4p5;
|
||||
pub mod generate_image_fal_seedream_5_lite;
|
||||
pub mod generate_image_fal_nano_banana;
|
||||
pub mod generate_image_fal_nano_banana_2;
|
||||
pub mod generate_image_fal_nano_banana_pro;
|
||||
|
||||
+12
@@ -23,6 +23,12 @@ use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraf
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_seedream_5_lite::plan_generate_image_artcraft_seedream_5_lite;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_1_dev::plan_generate_image_fal_flux_1_dev;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_1_schnell::plan_generate_image_fal_flux_1_schnell;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_pro_1p1::plan_generate_image_fal_flux_pro_1p1;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_pro_1p1_ultra::plan_generate_image_fal_flux_pro_1p1_ultra;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_gpt_image_1p5::plan_generate_image_fal_gpt_image_1p5;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_4::plan_generate_image_fal_seedream_4;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_4p5::plan_generate_image_fal_seedream_4p5;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_5_lite::plan_generate_image_fal_seedream_5_lite;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_nano_banana::plan_generate_image_fal_nano_banana;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_nano_banana_2::plan_generate_image_fal_nano_banana_2;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_nano_banana_pro::plan_generate_image_fal_nano_banana_pro;
|
||||
@@ -106,6 +112,12 @@ impl<'a> GenerateImageRequest<'a> {
|
||||
match self.model {
|
||||
CommonImageModel::Flux1Dev => plan_generate_image_fal_flux_1_dev(self),
|
||||
CommonImageModel::Flux1Schnell => plan_generate_image_fal_flux_1_schnell(self),
|
||||
CommonImageModel::FluxPro11 => plan_generate_image_fal_flux_pro_1p1(self),
|
||||
CommonImageModel::FluxPro11Ultra => plan_generate_image_fal_flux_pro_1p1_ultra(self),
|
||||
CommonImageModel::GptImage1p5 => plan_generate_image_fal_gpt_image_1p5(self),
|
||||
CommonImageModel::Seedream4 => plan_generate_image_fal_seedream_4(self),
|
||||
CommonImageModel::Seedream4p5 => plan_generate_image_fal_seedream_4p5(self),
|
||||
CommonImageModel::Seedream5Lite => plan_generate_image_fal_seedream_5_lite(self),
|
||||
CommonImageModel::NanoBanana => plan_generate_image_fal_nano_banana(self),
|
||||
CommonImageModel::NanoBanana2 => plan_generate_image_fal_nano_banana_2(self),
|
||||
CommonImageModel::NanoBananaPro => plan_generate_image_fal_nano_banana_pro(self),
|
||||
|
||||
+66
@@ -15,6 +15,12 @@ use crate::generate::generate_image::cost::artcraft::estimate_image_cost_artcraf
|
||||
use crate::generate::generate_image::cost::artcraft::estimate_image_cost_artcraft_flux_2_lora_angles::estimate_image_cost_artcraft_flux_2_lora_angles;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_flux_1_dev::estimate_image_cost_fal_flux_1_dev;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_flux_1_schnell::estimate_image_cost_fal_flux_1_schnell;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_flux_pro_1p1::estimate_image_cost_fal_flux_pro_1p1;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_flux_pro_1p1_ultra::estimate_image_cost_fal_flux_pro_1p1_ultra;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_gpt_image_1p5::estimate_image_cost_fal_gpt_image_1p5;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_seedream_4::estimate_image_cost_fal_seedream_4;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_seedream_4p5::estimate_image_cost_fal_seedream_4p5;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_seedream_5_lite::estimate_image_cost_fal_seedream_5_lite;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_nano_banana::estimate_image_cost_fal_nano_banana;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_nano_banana_2::estimate_image_cost_fal_nano_banana_2;
|
||||
use crate::generate::generate_image::cost::fal::estimate_image_cost_fal_nano_banana_pro::estimate_image_cost_fal_nano_banana_pro;
|
||||
@@ -33,6 +39,12 @@ use crate::generate::generate_image::execute::artcraft::generate_image_artcraft_
|
||||
use crate::generate::generate_image::execute::artcraft::generate_image_artcraft_flux_2_lora_angles::execute_artcraft_flux_2_lora_angles;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_flux_1_dev::execute_fal_flux_1_dev;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_flux_1_schnell::execute_fal_flux_1_schnell;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_flux_pro_1p1::execute_fal_flux_pro_1p1;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_flux_pro_1p1_ultra::execute_fal_flux_pro_1p1_ultra;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_gpt_image_1p5::execute_fal_gpt_image_1p5;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_seedream_4::execute_fal_seedream_4;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_seedream_4p5::execute_fal_seedream_4p5;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_seedream_5_lite::execute_fal_seedream_5_lite;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_nano_banana::execute_fal_nano_banana;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_nano_banana_2::execute_fal_nano_banana_2;
|
||||
use crate::generate::generate_image::execute::fal::generate_image_fal_nano_banana_pro::execute_fal_nano_banana_pro;
|
||||
@@ -53,6 +65,12 @@ use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraf
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_flux_2_lora_angles::PlanArtcraftFlux2LoraAngles;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_1_dev::PlanFalFlux1Dev;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_1_schnell::PlanFalFlux1Schnell;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_pro_1p1::PlanFalFluxPro11;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_flux_pro_1p1_ultra::PlanFalFluxPro11Ultra;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_gpt_image_1p5::PlanFalGptImage1p5;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_4::PlanFalSeedream4;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_4p5::PlanFalSeedream4p5;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_seedream_5_lite::PlanFalSeedream5Lite;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_nano_banana::PlanFalNanoBanana;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_nano_banana_2::PlanFalNanaBanana2;
|
||||
use crate::generate::generate_image::plan::fal::plan_generate_image_fal_nano_banana_pro::PlanFalNanaBananaPro;
|
||||
@@ -74,6 +92,12 @@ pub enum ImageGenerationPlan<'a> {
|
||||
ArtcraftFlux2LoraAngles(PlanArtcraftFlux2LoraAngles<'a>),
|
||||
FalFlux1Dev(PlanFalFlux1Dev<'a>),
|
||||
FalFlux1Schnell(PlanFalFlux1Schnell<'a>),
|
||||
FalFluxPro11(PlanFalFluxPro11<'a>),
|
||||
FalFluxPro11Ultra(PlanFalFluxPro11Ultra<'a>),
|
||||
FalGptImage1p5(PlanFalGptImage1p5<'a>),
|
||||
FalSeedream4(PlanFalSeedream4<'a>),
|
||||
FalSeedream4p5(PlanFalSeedream4p5<'a>),
|
||||
FalSeedream5Lite(PlanFalSeedream5Lite<'a>),
|
||||
FalNanoBanana(PlanFalNanoBanana<'a>),
|
||||
FalNanaBanana2(PlanFalNanaBanana2<'a>),
|
||||
FalNanaBananaPro(PlanFalNanaBananaPro<'a>),
|
||||
@@ -145,6 +169,30 @@ impl<'a> ImageGenerationPlan<'a> {
|
||||
let fal_client = client.get_fal_client_ref()?;
|
||||
execute_fal_flux_1_schnell(plan, fal_client).await
|
||||
}
|
||||
ImageGenerationPlan::FalFluxPro11(plan) => {
|
||||
let fal_client = client.get_fal_client_ref()?;
|
||||
execute_fal_flux_pro_1p1(plan, fal_client).await
|
||||
}
|
||||
ImageGenerationPlan::FalFluxPro11Ultra(plan) => {
|
||||
let fal_client = client.get_fal_client_ref()?;
|
||||
execute_fal_flux_pro_1p1_ultra(plan, fal_client).await
|
||||
}
|
||||
ImageGenerationPlan::FalGptImage1p5(plan) => {
|
||||
let fal_client = client.get_fal_client_ref()?;
|
||||
execute_fal_gpt_image_1p5(plan, fal_client).await
|
||||
}
|
||||
ImageGenerationPlan::FalSeedream4(plan) => {
|
||||
let fal_client = client.get_fal_client_ref()?;
|
||||
execute_fal_seedream_4(plan, fal_client).await
|
||||
}
|
||||
ImageGenerationPlan::FalSeedream4p5(plan) => {
|
||||
let fal_client = client.get_fal_client_ref()?;
|
||||
execute_fal_seedream_4p5(plan, fal_client).await
|
||||
}
|
||||
ImageGenerationPlan::FalSeedream5Lite(plan) => {
|
||||
let fal_client = client.get_fal_client_ref()?;
|
||||
execute_fal_seedream_5_lite(plan, fal_client).await
|
||||
}
|
||||
ImageGenerationPlan::FalNanoBanana(plan) => {
|
||||
let fal_client = client.get_fal_client_ref()?;
|
||||
execute_fal_nano_banana(plan, fal_client).await
|
||||
@@ -207,6 +255,24 @@ impl<'a> ImageGenerationPlan<'a> {
|
||||
ImageGenerationPlan::FalFlux1Schnell(plan) => {
|
||||
estimate_image_cost_fal_flux_1_schnell(plan)
|
||||
}
|
||||
ImageGenerationPlan::FalFluxPro11(plan) => {
|
||||
estimate_image_cost_fal_flux_pro_1p1(plan)
|
||||
}
|
||||
ImageGenerationPlan::FalFluxPro11Ultra(plan) => {
|
||||
estimate_image_cost_fal_flux_pro_1p1_ultra(plan)
|
||||
}
|
||||
ImageGenerationPlan::FalGptImage1p5(plan) => {
|
||||
estimate_image_cost_fal_gpt_image_1p5(plan)
|
||||
}
|
||||
ImageGenerationPlan::FalSeedream4(plan) => {
|
||||
estimate_image_cost_fal_seedream_4(plan)
|
||||
}
|
||||
ImageGenerationPlan::FalSeedream4p5(plan) => {
|
||||
estimate_image_cost_fal_seedream_4p5(plan)
|
||||
}
|
||||
ImageGenerationPlan::FalSeedream5Lite(plan) => {
|
||||
estimate_image_cost_fal_seedream_5_lite(plan)
|
||||
}
|
||||
ImageGenerationPlan::FalNanoBanana(plan) => {
|
||||
estimate_image_cost_fal_nano_banana(plan)
|
||||
}
|
||||
|
||||
+6
@@ -1,5 +1,11 @@
|
||||
pub mod plan_generate_image_fal_flux_1_dev;
|
||||
pub mod plan_generate_image_fal_flux_1_schnell;
|
||||
pub mod plan_generate_image_fal_flux_pro_1p1;
|
||||
pub mod plan_generate_image_fal_flux_pro_1p1_ultra;
|
||||
pub mod plan_generate_image_fal_gpt_image_1p5;
|
||||
pub mod plan_generate_image_fal_seedream_4;
|
||||
pub mod plan_generate_image_fal_seedream_4p5;
|
||||
pub mod plan_generate_image_fal_seedream_5_lite;
|
||||
pub mod plan_generate_image_fal_nano_banana;
|
||||
pub mod plan_generate_image_fal_nano_banana_2;
|
||||
pub mod plan_generate_image_fal_nano_banana_pro;
|
||||
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
use crate::api::common_aspect_ratio::CommonAspectRatio;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::client_error::ClientError;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
use crate::generate::generate_image::image_generation_plan::ImageGenerationPlan;
|
||||
use fal_client::requests::webhook::image::text::enqueue_flux_pro_11_text_to_image_webhook::{
|
||||
FluxPro11AspectRatio, FluxPro11NumImages,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalFluxPro11NumImages {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PlanFalFluxPro11<'a> {
|
||||
pub prompt: Option<&'a str>,
|
||||
pub aspect_ratio: FluxPro11AspectRatio,
|
||||
pub num_images: FalFluxPro11NumImages,
|
||||
}
|
||||
|
||||
pub fn plan_generate_image_fal_flux_pro_1p1<'a>(
|
||||
request: &'a GenerateImageRequest<'a>,
|
||||
) -> Result<ImageGenerationPlan<'a>, ArtcraftRouterError> {
|
||||
let strategy = request.request_mismatch_mitigation_strategy;
|
||||
|
||||
if request.image_inputs.is_some() {
|
||||
return Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "image_inputs",
|
||||
value: "Flux Pro 1.1 is text-to-image only".to_string(),
|
||||
}));
|
||||
}
|
||||
|
||||
let aspect_ratio = plan_aspect_ratio(request.aspect_ratio, strategy)?;
|
||||
let num_images = plan_num_images(request.image_batch_count, strategy)?;
|
||||
|
||||
Ok(ImageGenerationPlan::FalFluxPro11(PlanFalFluxPro11 {
|
||||
prompt: request.prompt,
|
||||
aspect_ratio,
|
||||
num_images,
|
||||
}))
|
||||
}
|
||||
|
||||
fn plan_aspect_ratio(
|
||||
aspect_ratio: Option<CommonAspectRatio>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<FluxPro11AspectRatio, ArtcraftRouterError> {
|
||||
use FluxPro11AspectRatio as Ar;
|
||||
match aspect_ratio {
|
||||
None => Ok(Ar::Square),
|
||||
|
||||
Some(CommonAspectRatio::Auto)
|
||||
| Some(CommonAspectRatio::Auto2k)
|
||||
| Some(CommonAspectRatio::Auto4k) => Ok(Ar::Square),
|
||||
|
||||
Some(CommonAspectRatio::Square) => Ok(Ar::Square),
|
||||
Some(CommonAspectRatio::SquareHd) => Ok(Ar::SquareHd),
|
||||
Some(CommonAspectRatio::WideFourByThree) => Ok(Ar::LandscapeFourByThree),
|
||||
Some(CommonAspectRatio::WideSixteenByNine) | Some(CommonAspectRatio::Wide) => Ok(Ar::LandscapeSixteenByNine),
|
||||
Some(CommonAspectRatio::TallThreeByFour) => Ok(Ar::PortraitThreeByFour),
|
||||
Some(CommonAspectRatio::TallNineBySixteen) | Some(CommonAspectRatio::Tall) => Ok(Ar::PortraitNineBySixteen),
|
||||
|
||||
Some(CommonAspectRatio::WideFiveByFour) => Ok(Ar::LandscapeFourByThree),
|
||||
Some(CommonAspectRatio::WideThreeByTwo) => Ok(Ar::LandscapeFourByThree),
|
||||
Some(CommonAspectRatio::WideTwentyOneByNine) => Ok(Ar::LandscapeSixteenByNine),
|
||||
Some(CommonAspectRatio::TallFourByFive) => Ok(Ar::PortraitThreeByFour),
|
||||
Some(CommonAspectRatio::TallTwoByThree) => Ok(Ar::PortraitThreeByFour),
|
||||
Some(CommonAspectRatio::TallNineByTwentyOne) => Ok(Ar::PortraitNineBySixteen),
|
||||
|
||||
Some(unsupported) => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "aspect_ratio",
|
||||
value: format!("{:?}", unsupported),
|
||||
}))
|
||||
}
|
||||
_ => Ok(Ar::Square),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_num_images(
|
||||
image_batch_count: Option<u16>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<FalFluxPro11NumImages, ArtcraftRouterError> {
|
||||
let count = image_batch_count.unwrap_or(1);
|
||||
match count {
|
||||
0 => Err(ArtcraftRouterError::Client(ClientError::UserRequestedZeroGenerations)),
|
||||
1 => Ok(FalFluxPro11NumImages::One),
|
||||
2 => Ok(FalFluxPro11NumImages::Two),
|
||||
3 => Ok(FalFluxPro11NumImages::Three),
|
||||
4 => Ok(FalFluxPro11NumImages::Four),
|
||||
_ => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "image_batch_count",
|
||||
value: format!("{}", count),
|
||||
}))
|
||||
}
|
||||
_ => Ok(FalFluxPro11NumImages::Four),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl FalFluxPro11NumImages {
|
||||
pub fn to_fal(self) -> FluxPro11NumImages {
|
||||
match self {
|
||||
Self::One => FluxPro11NumImages::One,
|
||||
Self::Two => FluxPro11NumImages::Two,
|
||||
Self::Three => FluxPro11NumImages::Three,
|
||||
Self::Four => FluxPro11NumImages::Four,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_u64(self) -> u64 {
|
||||
match self {
|
||||
Self::One => 1,
|
||||
Self::Two => 2,
|
||||
Self::Three => 3,
|
||||
Self::Four => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
use crate::api::common_aspect_ratio::CommonAspectRatio;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::client_error::ClientError;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
use crate::generate::generate_image::image_generation_plan::ImageGenerationPlan;
|
||||
use fal_client::requests::webhook::image::text::enqueue_flux_pro_11_ultra_text_to_image_webhook::{
|
||||
FluxPro11UltraAspectRatio, FluxPro11UltraNumImages,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalFluxPro11UltraNumImages {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PlanFalFluxPro11Ultra<'a> {
|
||||
pub prompt: Option<&'a str>,
|
||||
pub aspect_ratio: FluxPro11UltraAspectRatio,
|
||||
pub num_images: FalFluxPro11UltraNumImages,
|
||||
}
|
||||
|
||||
pub fn plan_generate_image_fal_flux_pro_1p1_ultra<'a>(
|
||||
request: &'a GenerateImageRequest<'a>,
|
||||
) -> Result<ImageGenerationPlan<'a>, ArtcraftRouterError> {
|
||||
let strategy = request.request_mismatch_mitigation_strategy;
|
||||
|
||||
if request.image_inputs.is_some() {
|
||||
return Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "image_inputs",
|
||||
value: "Flux Pro 1.1 Ultra is text-to-image only".to_string(),
|
||||
}));
|
||||
}
|
||||
|
||||
let aspect_ratio = plan_aspect_ratio(request.aspect_ratio, strategy)?;
|
||||
let num_images = plan_num_images(request.image_batch_count, strategy)?;
|
||||
|
||||
Ok(ImageGenerationPlan::FalFluxPro11Ultra(PlanFalFluxPro11Ultra {
|
||||
prompt: request.prompt,
|
||||
aspect_ratio,
|
||||
num_images,
|
||||
}))
|
||||
}
|
||||
|
||||
fn plan_aspect_ratio(
|
||||
aspect_ratio: Option<CommonAspectRatio>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<FluxPro11UltraAspectRatio, ArtcraftRouterError> {
|
||||
use FluxPro11UltraAspectRatio as Ar;
|
||||
match aspect_ratio {
|
||||
None => Ok(Ar::Square),
|
||||
|
||||
Some(CommonAspectRatio::Auto)
|
||||
| Some(CommonAspectRatio::Auto2k)
|
||||
| Some(CommonAspectRatio::Auto4k) => Ok(Ar::Square),
|
||||
|
||||
Some(CommonAspectRatio::Square) | Some(CommonAspectRatio::SquareHd) => Ok(Ar::Square),
|
||||
Some(CommonAspectRatio::WideFourByThree) => Ok(Ar::LandscapeFourByThree),
|
||||
Some(CommonAspectRatio::WideThreeByTwo) => Ok(Ar::LandscapeThreeByTwo),
|
||||
Some(CommonAspectRatio::WideSixteenByNine) | Some(CommonAspectRatio::Wide) => Ok(Ar::LandscapeSixteenByNine),
|
||||
Some(CommonAspectRatio::WideTwentyOneByNine) => Ok(Ar::LandscapeTwentyOneByNine),
|
||||
Some(CommonAspectRatio::TallThreeByFour) => Ok(Ar::PortraitThreeByFour),
|
||||
Some(CommonAspectRatio::TallTwoByThree) => Ok(Ar::PortraitTwoByThree),
|
||||
Some(CommonAspectRatio::TallNineBySixteen) | Some(CommonAspectRatio::Tall) => Ok(Ar::PortraitNineBySixteen),
|
||||
Some(CommonAspectRatio::TallNineByTwentyOne) => Ok(Ar::PortraitNineByTwentyOne),
|
||||
|
||||
Some(CommonAspectRatio::WideFiveByFour) => Ok(Ar::LandscapeFourByThree),
|
||||
Some(CommonAspectRatio::TallFourByFive) => Ok(Ar::PortraitThreeByFour),
|
||||
|
||||
Some(unsupported) => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "aspect_ratio",
|
||||
value: format!("{:?}", unsupported),
|
||||
}))
|
||||
}
|
||||
_ => Ok(Ar::Square),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_num_images(
|
||||
image_batch_count: Option<u16>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<FalFluxPro11UltraNumImages, ArtcraftRouterError> {
|
||||
let count = image_batch_count.unwrap_or(1);
|
||||
match count {
|
||||
0 => Err(ArtcraftRouterError::Client(ClientError::UserRequestedZeroGenerations)),
|
||||
1 => Ok(FalFluxPro11UltraNumImages::One),
|
||||
2 => Ok(FalFluxPro11UltraNumImages::Two),
|
||||
3 => Ok(FalFluxPro11UltraNumImages::Three),
|
||||
4 => Ok(FalFluxPro11UltraNumImages::Four),
|
||||
_ => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "image_batch_count",
|
||||
value: format!("{}", count),
|
||||
}))
|
||||
}
|
||||
_ => Ok(FalFluxPro11UltraNumImages::Four),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl FalFluxPro11UltraNumImages {
|
||||
pub fn to_fal(self) -> FluxPro11UltraNumImages {
|
||||
match self {
|
||||
Self::One => FluxPro11UltraNumImages::One,
|
||||
Self::Two => FluxPro11UltraNumImages::Two,
|
||||
Self::Three => FluxPro11UltraNumImages::Three,
|
||||
Self::Four => FluxPro11UltraNumImages::Four,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_u64(self) -> u64 {
|
||||
match self {
|
||||
Self::One => 1,
|
||||
Self::Two => 2,
|
||||
Self::Three => 3,
|
||||
Self::Four => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
use crate::api::common_aspect_ratio::CommonAspectRatio;
|
||||
use crate::api::image_list_ref::ImageListRef;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::client_error::ClientError;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
use crate::generate::generate_image::image_generation_plan::ImageGenerationPlan;
|
||||
use fal_client::requests::webhook::image::edit::enqueue_gpt_image_1p5_edit_image_webhook::{
|
||||
EnqueueGptImage1p5EditImageNumImages, EnqueueGptImage1p5EditImageQuality,
|
||||
EnqueueGptImage1p5EditImageSize,
|
||||
};
|
||||
use fal_client::requests::webhook::image::text::enqueue_gpt_image_1p5_text_to_image_webhook::{
|
||||
EnqueueGptImage1p5TextToImageNumImages, EnqueueGptImage1p5TextToImageQuality,
|
||||
EnqueueGptImage1p5TextToImageSize,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalGptImage1p5NumImages {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
/// Quality is shared between t2i and edit (Low / Medium / High).
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalGptImage1p5Quality {
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
}
|
||||
|
||||
/// GPT Image 1.5 supports three image sizes: 1024x1024, 1536x1024, 1024x1536.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalGptImage1p5ImageSize {
|
||||
Square,
|
||||
Wide,
|
||||
Tall,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PlanFalGptImage1p5<'a> {
|
||||
pub prompt: Option<&'a str>,
|
||||
pub image_urls: Vec<String>,
|
||||
pub image_size: Option<FalGptImage1p5ImageSize>,
|
||||
pub quality: FalGptImage1p5Quality,
|
||||
pub num_images: FalGptImage1p5NumImages,
|
||||
}
|
||||
|
||||
pub fn plan_generate_image_fal_gpt_image_1p5<'a>(
|
||||
request: &'a GenerateImageRequest<'a>,
|
||||
) -> Result<ImageGenerationPlan<'a>, ArtcraftRouterError> {
|
||||
let strategy = request.request_mismatch_mitigation_strategy;
|
||||
let image_urls = resolve_image_list_ref(request.image_inputs)?;
|
||||
let image_size = plan_image_size(request.aspect_ratio);
|
||||
let num_images = plan_num_images(request.image_batch_count, strategy)?;
|
||||
|
||||
Ok(ImageGenerationPlan::FalGptImage1p5(PlanFalGptImage1p5 {
|
||||
prompt: request.prompt,
|
||||
image_urls,
|
||||
image_size,
|
||||
quality: FalGptImage1p5Quality::Medium,
|
||||
num_images,
|
||||
}))
|
||||
}
|
||||
|
||||
fn resolve_image_list_ref(
|
||||
image_list_ref: Option<ImageListRef<'_>>,
|
||||
) -> Result<Vec<String>, ArtcraftRouterError> {
|
||||
match image_list_ref {
|
||||
None => Ok(vec![]),
|
||||
Some(ImageListRef::Urls(urls)) => Ok(urls.clone()),
|
||||
Some(ImageListRef::MediaFileTokens(_)) => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::FalOnlySupportsUrls))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_image_size(aspect_ratio: Option<CommonAspectRatio>) -> Option<FalGptImage1p5ImageSize> {
|
||||
use FalGptImage1p5ImageSize as S;
|
||||
match aspect_ratio {
|
||||
None
|
||||
| Some(CommonAspectRatio::Auto)
|
||||
| Some(CommonAspectRatio::Auto2k)
|
||||
| Some(CommonAspectRatio::Auto4k) => None,
|
||||
|
||||
Some(CommonAspectRatio::Square) | Some(CommonAspectRatio::SquareHd) => Some(S::Square),
|
||||
|
||||
Some(CommonAspectRatio::WideThreeByTwo)
|
||||
| Some(CommonAspectRatio::WideFourByThree)
|
||||
| Some(CommonAspectRatio::WideFiveByFour)
|
||||
| Some(CommonAspectRatio::WideSixteenByNine)
|
||||
| Some(CommonAspectRatio::WideTwentyOneByNine)
|
||||
| Some(CommonAspectRatio::Wide) => Some(S::Wide),
|
||||
|
||||
Some(CommonAspectRatio::TallTwoByThree)
|
||||
| Some(CommonAspectRatio::TallThreeByFour)
|
||||
| Some(CommonAspectRatio::TallFourByFive)
|
||||
| Some(CommonAspectRatio::TallNineBySixteen)
|
||||
| Some(CommonAspectRatio::TallNineByTwentyOne)
|
||||
| Some(CommonAspectRatio::Tall) => Some(S::Tall),
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_num_images(
|
||||
image_batch_count: Option<u16>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<FalGptImage1p5NumImages, ArtcraftRouterError> {
|
||||
let count = image_batch_count.unwrap_or(1);
|
||||
match count {
|
||||
0 => Err(ArtcraftRouterError::Client(ClientError::UserRequestedZeroGenerations)),
|
||||
1 => Ok(FalGptImage1p5NumImages::One),
|
||||
2 => Ok(FalGptImage1p5NumImages::Two),
|
||||
3 => Ok(FalGptImage1p5NumImages::Three),
|
||||
4 => Ok(FalGptImage1p5NumImages::Four),
|
||||
_ => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "image_batch_count",
|
||||
value: format!("{}", count),
|
||||
}))
|
||||
}
|
||||
_ => Ok(FalGptImage1p5NumImages::Four),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl FalGptImage1p5NumImages {
|
||||
pub fn to_t2i(self) -> EnqueueGptImage1p5TextToImageNumImages {
|
||||
use EnqueueGptImage1p5TextToImageNumImages as T;
|
||||
match self {
|
||||
Self::One => T::One,
|
||||
Self::Two => T::Two,
|
||||
Self::Three => T::Three,
|
||||
Self::Four => T::Four,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_edit(self) -> EnqueueGptImage1p5EditImageNumImages {
|
||||
use EnqueueGptImage1p5EditImageNumImages as E;
|
||||
match self {
|
||||
Self::One => E::One,
|
||||
Self::Two => E::Two,
|
||||
Self::Three => E::Three,
|
||||
Self::Four => E::Four,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_u64(self) -> u64 {
|
||||
match self {
|
||||
Self::One => 1,
|
||||
Self::Two => 2,
|
||||
Self::Three => 3,
|
||||
Self::Four => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FalGptImage1p5Quality {
|
||||
pub fn to_t2i(self) -> EnqueueGptImage1p5TextToImageQuality {
|
||||
use EnqueueGptImage1p5TextToImageQuality as T;
|
||||
match self {
|
||||
Self::Low => T::Low,
|
||||
Self::Medium => T::Medium,
|
||||
Self::High => T::High,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_edit(self) -> EnqueueGptImage1p5EditImageQuality {
|
||||
use EnqueueGptImage1p5EditImageQuality as E;
|
||||
match self {
|
||||
Self::Low => E::Low,
|
||||
Self::Medium => E::Medium,
|
||||
Self::High => E::High,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FalGptImage1p5ImageSize {
|
||||
pub fn to_t2i(self) -> EnqueueGptImage1p5TextToImageSize {
|
||||
use EnqueueGptImage1p5TextToImageSize as T;
|
||||
match self {
|
||||
Self::Square => T::Square,
|
||||
Self::Wide => T::Wide,
|
||||
Self::Tall => T::Tall,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_edit(self) -> EnqueueGptImage1p5EditImageSize {
|
||||
use EnqueueGptImage1p5EditImageSize as E;
|
||||
match self {
|
||||
Self::Square => E::Square,
|
||||
Self::Wide => E::Wide,
|
||||
Self::Tall => E::Tall,
|
||||
}
|
||||
}
|
||||
}
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
use crate::api::common_aspect_ratio::CommonAspectRatio;
|
||||
use crate::api::image_list_ref::ImageListRef;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::client_error::ClientError;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
use crate::generate::generate_image::image_generation_plan::ImageGenerationPlan;
|
||||
use fal_client::requests::webhook::image::edit::enqueue_bytedance_seedream_v4_edit_image_webhook::{
|
||||
EnqueueBytedanceSeedreamV4EditImageNumImages, EnqueueBytedanceSeedreamV4EditImageSize,
|
||||
};
|
||||
use fal_client::requests::webhook::image::text::enqueue_bytedance_seedream_v4_text_to_image_webhook::{
|
||||
EnqueueBytedanceSeedreamV4TextToImageNumImages, EnqueueBytedanceSeedreamV4TextToImageSize,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalSeedream4NumImages {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
/// Shared image-size shape between Seedream V4 t2i and edit (variants are identical).
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalSeedream4ImageSize {
|
||||
Square,
|
||||
SquareHd,
|
||||
PortraitFourThree,
|
||||
PortraitSixteenNine,
|
||||
LandscapeFourThree,
|
||||
LandscapeSixteenNine,
|
||||
Auto,
|
||||
Auto2k,
|
||||
Auto4k,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PlanFalSeedream4<'a> {
|
||||
pub prompt: Option<&'a str>,
|
||||
/// Image URLs for editing. Empty vec = text-to-image mode.
|
||||
pub image_urls: Vec<String>,
|
||||
pub image_size: Option<FalSeedream4ImageSize>,
|
||||
pub num_images: FalSeedream4NumImages,
|
||||
}
|
||||
|
||||
pub fn plan_generate_image_fal_seedream_4<'a>(
|
||||
request: &'a GenerateImageRequest<'a>,
|
||||
) -> Result<ImageGenerationPlan<'a>, ArtcraftRouterError> {
|
||||
let strategy = request.request_mismatch_mitigation_strategy;
|
||||
let is_edit_mode = request.image_inputs.is_some();
|
||||
let image_urls = resolve_image_list_ref(request.image_inputs)?;
|
||||
let image_size = plan_image_size(request.aspect_ratio, is_edit_mode, strategy)?;
|
||||
let num_images = plan_num_images(request.image_batch_count, strategy)?;
|
||||
|
||||
Ok(ImageGenerationPlan::FalSeedream4(PlanFalSeedream4 {
|
||||
prompt: request.prompt,
|
||||
image_urls,
|
||||
image_size,
|
||||
num_images,
|
||||
}))
|
||||
}
|
||||
|
||||
fn resolve_image_list_ref(
|
||||
image_list_ref: Option<ImageListRef<'_>>,
|
||||
) -> Result<Vec<String>, ArtcraftRouterError> {
|
||||
match image_list_ref {
|
||||
None => Ok(vec![]),
|
||||
Some(ImageListRef::Urls(urls)) => Ok(urls.clone()),
|
||||
Some(ImageListRef::MediaFileTokens(_)) => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::FalOnlySupportsUrls))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_image_size(
|
||||
aspect_ratio: Option<CommonAspectRatio>,
|
||||
is_edit_mode: bool,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<Option<FalSeedream4ImageSize>, ArtcraftRouterError> {
|
||||
use FalSeedream4ImageSize as S;
|
||||
match aspect_ratio {
|
||||
None => Ok(None),
|
||||
|
||||
Some(CommonAspectRatio::Auto) => {
|
||||
if is_edit_mode { Ok(Some(S::Auto)) } else { Ok(Some(S::Square)) }
|
||||
}
|
||||
Some(CommonAspectRatio::Auto2k) => Ok(Some(S::Auto2k)),
|
||||
Some(CommonAspectRatio::Auto4k) => Ok(Some(S::Auto4k)),
|
||||
|
||||
Some(CommonAspectRatio::Square) => Ok(Some(S::Square)),
|
||||
Some(CommonAspectRatio::SquareHd) => Ok(Some(S::SquareHd)),
|
||||
|
||||
Some(CommonAspectRatio::Wide) | Some(CommonAspectRatio::WideSixteenByNine) => Ok(Some(S::LandscapeSixteenNine)),
|
||||
Some(CommonAspectRatio::WideFourByThree) => Ok(Some(S::LandscapeFourThree)),
|
||||
|
||||
Some(unsupported @ CommonAspectRatio::WideFiveByFour)
|
||||
| Some(unsupported @ CommonAspectRatio::WideThreeByTwo)
|
||||
| Some(unsupported @ CommonAspectRatio::WideTwentyOneByNine) => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "aspect_ratio",
|
||||
value: format!("{:?}", unsupported),
|
||||
}))
|
||||
}
|
||||
_ => Ok(Some(S::LandscapeSixteenNine)),
|
||||
},
|
||||
|
||||
Some(CommonAspectRatio::Tall) | Some(CommonAspectRatio::TallNineBySixteen) => Ok(Some(S::PortraitSixteenNine)),
|
||||
Some(CommonAspectRatio::TallThreeByFour) => Ok(Some(S::PortraitFourThree)),
|
||||
|
||||
Some(unsupported @ CommonAspectRatio::TallFourByFive)
|
||||
| Some(unsupported @ CommonAspectRatio::TallTwoByThree)
|
||||
| Some(unsupported @ CommonAspectRatio::TallNineByTwentyOne) => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "aspect_ratio",
|
||||
value: format!("{:?}", unsupported),
|
||||
}))
|
||||
}
|
||||
_ => Ok(Some(S::PortraitSixteenNine)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_num_images(
|
||||
image_batch_count: Option<u16>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<FalSeedream4NumImages, ArtcraftRouterError> {
|
||||
let count = image_batch_count.unwrap_or(1);
|
||||
match count {
|
||||
0 => Err(ArtcraftRouterError::Client(ClientError::UserRequestedZeroGenerations)),
|
||||
1 => Ok(FalSeedream4NumImages::One),
|
||||
2 => Ok(FalSeedream4NumImages::Two),
|
||||
3 => Ok(FalSeedream4NumImages::Three),
|
||||
4 => Ok(FalSeedream4NumImages::Four),
|
||||
_ => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "image_batch_count",
|
||||
value: format!("{}", count),
|
||||
}))
|
||||
}
|
||||
_ => Ok(FalSeedream4NumImages::Four),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl FalSeedream4NumImages {
|
||||
pub fn to_t2i(self) -> EnqueueBytedanceSeedreamV4TextToImageNumImages {
|
||||
use EnqueueBytedanceSeedreamV4TextToImageNumImages as T;
|
||||
match self {
|
||||
Self::One => T::One,
|
||||
Self::Two => T::Two,
|
||||
Self::Three => T::Three,
|
||||
Self::Four => T::Four,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_edit(self) -> EnqueueBytedanceSeedreamV4EditImageNumImages {
|
||||
use EnqueueBytedanceSeedreamV4EditImageNumImages as E;
|
||||
match self {
|
||||
Self::One => E::One,
|
||||
Self::Two => E::Two,
|
||||
Self::Three => E::Three,
|
||||
Self::Four => E::Four,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_u64(self) -> u64 {
|
||||
match self {
|
||||
Self::One => 1,
|
||||
Self::Two => 2,
|
||||
Self::Three => 3,
|
||||
Self::Four => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FalSeedream4ImageSize {
|
||||
pub fn to_t2i(self) -> EnqueueBytedanceSeedreamV4TextToImageSize {
|
||||
use EnqueueBytedanceSeedreamV4TextToImageSize as T;
|
||||
match self {
|
||||
Self::Square => T::Square,
|
||||
Self::SquareHd => T::SquareHd,
|
||||
Self::PortraitFourThree => T::PortraitFourThree,
|
||||
Self::PortraitSixteenNine => T::PortraitSixteenNine,
|
||||
Self::LandscapeFourThree => T::LandscapeFourThree,
|
||||
Self::LandscapeSixteenNine => T::LandscapeSixteenNine,
|
||||
Self::Auto => T::Auto,
|
||||
Self::Auto2k => T::Auto2k,
|
||||
Self::Auto4k => T::Auto4k,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_edit(self) -> EnqueueBytedanceSeedreamV4EditImageSize {
|
||||
use EnqueueBytedanceSeedreamV4EditImageSize as E;
|
||||
match self {
|
||||
Self::Square => E::Square,
|
||||
Self::SquareHd => E::SquareHd,
|
||||
Self::PortraitFourThree => E::PortraitFourThree,
|
||||
Self::PortraitSixteenNine => E::PortraitSixteenNine,
|
||||
Self::LandscapeFourThree => E::LandscapeFourThree,
|
||||
Self::LandscapeSixteenNine => E::LandscapeSixteenNine,
|
||||
Self::Auto => E::Auto,
|
||||
Self::Auto2k => E::Auto2k,
|
||||
Self::Auto4k => E::Auto4k,
|
||||
}
|
||||
}
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
use crate::api::common_aspect_ratio::CommonAspectRatio;
|
||||
use crate::api::image_list_ref::ImageListRef;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::client_error::ClientError;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
use crate::generate::generate_image::image_generation_plan::ImageGenerationPlan;
|
||||
use fal_client::requests::webhook::image::edit::enqueue_bytedance_seedream_v4p5_edit_image_webhook::{
|
||||
EnqueueBytedanceSeedreamV4p5EditImageNumImages, EnqueueBytedanceSeedreamV4p5EditImageSize,
|
||||
};
|
||||
use fal_client::requests::webhook::image::text::enqueue_bytedance_seedream_v4p5_text_to_image_webhook::{
|
||||
EnqueueBytedanceSeedreamV4p5TextToImageNumImages, EnqueueBytedanceSeedreamV4p5TextToImageSize,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalSeedream4p5NumImages {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
/// Note: Seedream V4.5 lacks the bare "Auto" image_size; only Auto2k/Auto4k are supported.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalSeedream4p5ImageSize {
|
||||
Square,
|
||||
SquareHd,
|
||||
PortraitFourThree,
|
||||
PortraitSixteenNine,
|
||||
LandscapeFourThree,
|
||||
LandscapeSixteenNine,
|
||||
Auto2k,
|
||||
Auto4k,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PlanFalSeedream4p5<'a> {
|
||||
pub prompt: Option<&'a str>,
|
||||
pub image_urls: Vec<String>,
|
||||
pub image_size: Option<FalSeedream4p5ImageSize>,
|
||||
pub num_images: FalSeedream4p5NumImages,
|
||||
}
|
||||
|
||||
pub fn plan_generate_image_fal_seedream_4p5<'a>(
|
||||
request: &'a GenerateImageRequest<'a>,
|
||||
) -> Result<ImageGenerationPlan<'a>, ArtcraftRouterError> {
|
||||
let strategy = request.request_mismatch_mitigation_strategy;
|
||||
let image_urls = resolve_image_list_ref(request.image_inputs)?;
|
||||
let image_size = plan_image_size(request.aspect_ratio, strategy)?;
|
||||
let num_images = plan_num_images(request.image_batch_count, strategy)?;
|
||||
|
||||
Ok(ImageGenerationPlan::FalSeedream4p5(PlanFalSeedream4p5 {
|
||||
prompt: request.prompt,
|
||||
image_urls,
|
||||
image_size,
|
||||
num_images,
|
||||
}))
|
||||
}
|
||||
|
||||
fn resolve_image_list_ref(
|
||||
image_list_ref: Option<ImageListRef<'_>>,
|
||||
) -> Result<Vec<String>, ArtcraftRouterError> {
|
||||
match image_list_ref {
|
||||
None => Ok(vec![]),
|
||||
Some(ImageListRef::Urls(urls)) => Ok(urls.clone()),
|
||||
Some(ImageListRef::MediaFileTokens(_)) => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::FalOnlySupportsUrls))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_image_size(
|
||||
aspect_ratio: Option<CommonAspectRatio>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<Option<FalSeedream4p5ImageSize>, ArtcraftRouterError> {
|
||||
use FalSeedream4p5ImageSize as S;
|
||||
match aspect_ratio {
|
||||
None => Ok(None),
|
||||
|
||||
// No bare Auto for v4.5 — fall back to Auto2k.
|
||||
Some(CommonAspectRatio::Auto) | Some(CommonAspectRatio::Auto2k) => Ok(Some(S::Auto2k)),
|
||||
Some(CommonAspectRatio::Auto4k) => Ok(Some(S::Auto4k)),
|
||||
|
||||
Some(CommonAspectRatio::Square) => Ok(Some(S::Square)),
|
||||
Some(CommonAspectRatio::SquareHd) => Ok(Some(S::SquareHd)),
|
||||
|
||||
Some(CommonAspectRatio::Wide) | Some(CommonAspectRatio::WideSixteenByNine) => Ok(Some(S::LandscapeSixteenNine)),
|
||||
Some(CommonAspectRatio::WideFourByThree) => Ok(Some(S::LandscapeFourThree)),
|
||||
|
||||
Some(unsupported @ CommonAspectRatio::WideFiveByFour)
|
||||
| Some(unsupported @ CommonAspectRatio::WideThreeByTwo)
|
||||
| Some(unsupported @ CommonAspectRatio::WideTwentyOneByNine) => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "aspect_ratio",
|
||||
value: format!("{:?}", unsupported),
|
||||
}))
|
||||
}
|
||||
_ => Ok(Some(S::LandscapeSixteenNine)),
|
||||
},
|
||||
|
||||
Some(CommonAspectRatio::Tall) | Some(CommonAspectRatio::TallNineBySixteen) => Ok(Some(S::PortraitSixteenNine)),
|
||||
Some(CommonAspectRatio::TallThreeByFour) => Ok(Some(S::PortraitFourThree)),
|
||||
|
||||
Some(unsupported @ CommonAspectRatio::TallFourByFive)
|
||||
| Some(unsupported @ CommonAspectRatio::TallTwoByThree)
|
||||
| Some(unsupported @ CommonAspectRatio::TallNineByTwentyOne) => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "aspect_ratio",
|
||||
value: format!("{:?}", unsupported),
|
||||
}))
|
||||
}
|
||||
_ => Ok(Some(S::PortraitSixteenNine)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_num_images(
|
||||
image_batch_count: Option<u16>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<FalSeedream4p5NumImages, ArtcraftRouterError> {
|
||||
let count = image_batch_count.unwrap_or(1);
|
||||
match count {
|
||||
0 => Err(ArtcraftRouterError::Client(ClientError::UserRequestedZeroGenerations)),
|
||||
1 => Ok(FalSeedream4p5NumImages::One),
|
||||
2 => Ok(FalSeedream4p5NumImages::Two),
|
||||
3 => Ok(FalSeedream4p5NumImages::Three),
|
||||
4 => Ok(FalSeedream4p5NumImages::Four),
|
||||
_ => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "image_batch_count",
|
||||
value: format!("{}", count),
|
||||
}))
|
||||
}
|
||||
_ => Ok(FalSeedream4p5NumImages::Four),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl FalSeedream4p5NumImages {
|
||||
pub fn to_t2i(self) -> EnqueueBytedanceSeedreamV4p5TextToImageNumImages {
|
||||
use EnqueueBytedanceSeedreamV4p5TextToImageNumImages as T;
|
||||
match self {
|
||||
Self::One => T::One,
|
||||
Self::Two => T::Two,
|
||||
Self::Three => T::Three,
|
||||
Self::Four => T::Four,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_edit(self) -> EnqueueBytedanceSeedreamV4p5EditImageNumImages {
|
||||
use EnqueueBytedanceSeedreamV4p5EditImageNumImages as E;
|
||||
match self {
|
||||
Self::One => E::One,
|
||||
Self::Two => E::Two,
|
||||
Self::Three => E::Three,
|
||||
Self::Four => E::Four,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_u64(self) -> u64 {
|
||||
match self {
|
||||
Self::One => 1,
|
||||
Self::Two => 2,
|
||||
Self::Three => 3,
|
||||
Self::Four => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FalSeedream4p5ImageSize {
|
||||
pub fn to_t2i(self) -> EnqueueBytedanceSeedreamV4p5TextToImageSize {
|
||||
use EnqueueBytedanceSeedreamV4p5TextToImageSize as T;
|
||||
match self {
|
||||
Self::Square => T::Square,
|
||||
Self::SquareHd => T::SquareHd,
|
||||
Self::PortraitFourThree => T::PortraitFourThree,
|
||||
Self::PortraitSixteenNine => T::PortraitSixteenNine,
|
||||
Self::LandscapeFourThree => T::LandscapeFourThree,
|
||||
Self::LandscapeSixteenNine => T::LandscapeSixteenNine,
|
||||
Self::Auto2k => T::Auto2k,
|
||||
Self::Auto4k => T::Auto4k,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_edit(self) -> EnqueueBytedanceSeedreamV4p5EditImageSize {
|
||||
use EnqueueBytedanceSeedreamV4p5EditImageSize as E;
|
||||
match self {
|
||||
Self::Square => E::Square,
|
||||
Self::SquareHd => E::SquareHd,
|
||||
Self::PortraitFourThree => E::PortraitFourThree,
|
||||
Self::PortraitSixteenNine => E::PortraitSixteenNine,
|
||||
Self::LandscapeFourThree => E::LandscapeFourThree,
|
||||
Self::LandscapeSixteenNine => E::LandscapeSixteenNine,
|
||||
Self::Auto2k => E::Auto2k,
|
||||
Self::Auto4k => E::Auto4k,
|
||||
}
|
||||
}
|
||||
}
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
use crate::api::common_aspect_ratio::CommonAspectRatio;
|
||||
use crate::api::common_resolution::CommonResolution;
|
||||
use crate::api::image_list_ref::ImageListRef;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::client_error::ClientError;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
use crate::generate::generate_image::image_generation_plan::ImageGenerationPlan;
|
||||
use fal_client::requests::webhook::image::edit::enqueue_bytedance_seedream_v5_lite_edit_image_webhook::{
|
||||
EnqueueBytedanceSeedreamV5LiteEditImageNumImages, EnqueueBytedanceSeedreamV5LiteEditImageSize,
|
||||
};
|
||||
use fal_client::requests::webhook::image::text::enqueue_bytedance_seedream_v5_lite_text_to_image_webhook::{
|
||||
EnqueueBytedanceSeedreamV5LiteTextToImageNumImages, EnqueueBytedanceSeedreamV5LiteTextToImageSize,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalSeedream5LiteNumImages {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
/// Note: Seedream V5 Lite supports Auto2k and Auto3k (no 4K, no bare Auto).
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FalSeedream5LiteImageSize {
|
||||
Square,
|
||||
SquareHd,
|
||||
PortraitFourThree,
|
||||
PortraitSixteenNine,
|
||||
LandscapeFourThree,
|
||||
LandscapeSixteenNine,
|
||||
Auto2k,
|
||||
Auto3k,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PlanFalSeedream5Lite<'a> {
|
||||
pub prompt: Option<&'a str>,
|
||||
pub image_urls: Vec<String>,
|
||||
pub image_size: Option<FalSeedream5LiteImageSize>,
|
||||
pub num_images: FalSeedream5LiteNumImages,
|
||||
}
|
||||
|
||||
pub fn plan_generate_image_fal_seedream_5_lite<'a>(
|
||||
request: &'a GenerateImageRequest<'a>,
|
||||
) -> Result<ImageGenerationPlan<'a>, ArtcraftRouterError> {
|
||||
let strategy = request.request_mismatch_mitigation_strategy;
|
||||
let image_urls = resolve_image_list_ref(request.image_inputs)?;
|
||||
let image_size = plan_image_size(request.aspect_ratio, request.resolution, strategy)?;
|
||||
let num_images = plan_num_images(request.image_batch_count, strategy)?;
|
||||
|
||||
Ok(ImageGenerationPlan::FalSeedream5Lite(PlanFalSeedream5Lite {
|
||||
prompt: request.prompt,
|
||||
image_urls,
|
||||
image_size,
|
||||
num_images,
|
||||
}))
|
||||
}
|
||||
|
||||
fn resolve_image_list_ref(
|
||||
image_list_ref: Option<ImageListRef<'_>>,
|
||||
) -> Result<Vec<String>, ArtcraftRouterError> {
|
||||
match image_list_ref {
|
||||
None => Ok(vec![]),
|
||||
Some(ImageListRef::Urls(urls)) => Ok(urls.clone()),
|
||||
Some(ImageListRef::MediaFileTokens(_)) => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::FalOnlySupportsUrls))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_image_size(
|
||||
aspect_ratio: Option<CommonAspectRatio>,
|
||||
resolution: Option<CommonResolution>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<Option<FalSeedream5LiteImageSize>, ArtcraftRouterError> {
|
||||
use FalSeedream5LiteImageSize as S;
|
||||
|
||||
// Resolution-based auto sizes take precedence when an explicit Auto* aspect ratio
|
||||
// isn't specified but a resolution is — Seedream v5 lite has no 4K, fall back to 3K.
|
||||
match aspect_ratio {
|
||||
None => match resolution {
|
||||
Some(CommonResolution::TwoK) => Ok(Some(S::Auto2k)),
|
||||
Some(CommonResolution::ThreeK) | Some(CommonResolution::FourK) => Ok(Some(S::Auto3k)),
|
||||
_ => Ok(None),
|
||||
},
|
||||
|
||||
Some(CommonAspectRatio::Auto) | Some(CommonAspectRatio::Auto2k) => Ok(Some(S::Auto2k)),
|
||||
// No 4K — fall back to 3K.
|
||||
Some(CommonAspectRatio::Auto4k) => Ok(Some(S::Auto3k)),
|
||||
|
||||
Some(CommonAspectRatio::Square) => Ok(Some(S::Square)),
|
||||
Some(CommonAspectRatio::SquareHd) => Ok(Some(S::SquareHd)),
|
||||
|
||||
Some(CommonAspectRatio::Wide) | Some(CommonAspectRatio::WideSixteenByNine) => Ok(Some(S::LandscapeSixteenNine)),
|
||||
Some(CommonAspectRatio::WideFourByThree) => Ok(Some(S::LandscapeFourThree)),
|
||||
|
||||
Some(unsupported @ CommonAspectRatio::WideFiveByFour)
|
||||
| Some(unsupported @ CommonAspectRatio::WideThreeByTwo)
|
||||
| Some(unsupported @ CommonAspectRatio::WideTwentyOneByNine) => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "aspect_ratio",
|
||||
value: format!("{:?}", unsupported),
|
||||
}))
|
||||
}
|
||||
_ => Ok(Some(S::LandscapeSixteenNine)),
|
||||
},
|
||||
|
||||
Some(CommonAspectRatio::Tall) | Some(CommonAspectRatio::TallNineBySixteen) => Ok(Some(S::PortraitSixteenNine)),
|
||||
Some(CommonAspectRatio::TallThreeByFour) => Ok(Some(S::PortraitFourThree)),
|
||||
|
||||
Some(unsupported @ CommonAspectRatio::TallFourByFive)
|
||||
| Some(unsupported @ CommonAspectRatio::TallTwoByThree)
|
||||
| Some(unsupported @ CommonAspectRatio::TallNineByTwentyOne) => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "aspect_ratio",
|
||||
value: format!("{:?}", unsupported),
|
||||
}))
|
||||
}
|
||||
_ => Ok(Some(S::PortraitSixteenNine)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_num_images(
|
||||
image_batch_count: Option<u16>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<FalSeedream5LiteNumImages, ArtcraftRouterError> {
|
||||
let count = image_batch_count.unwrap_or(1);
|
||||
match count {
|
||||
0 => Err(ArtcraftRouterError::Client(ClientError::UserRequestedZeroGenerations)),
|
||||
1 => Ok(FalSeedream5LiteNumImages::One),
|
||||
2 => Ok(FalSeedream5LiteNumImages::Two),
|
||||
3 => Ok(FalSeedream5LiteNumImages::Three),
|
||||
4 => Ok(FalSeedream5LiteNumImages::Four),
|
||||
_ => match strategy {
|
||||
RequestMismatchMitigationStrategy::ErrorOut => {
|
||||
Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "image_batch_count",
|
||||
value: format!("{}", count),
|
||||
}))
|
||||
}
|
||||
_ => Ok(FalSeedream5LiteNumImages::Four),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl FalSeedream5LiteNumImages {
|
||||
pub fn to_t2i(self) -> EnqueueBytedanceSeedreamV5LiteTextToImageNumImages {
|
||||
use EnqueueBytedanceSeedreamV5LiteTextToImageNumImages as T;
|
||||
match self {
|
||||
Self::One => T::One,
|
||||
Self::Two => T::Two,
|
||||
Self::Three => T::Three,
|
||||
Self::Four => T::Four,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_edit(self) -> EnqueueBytedanceSeedreamV5LiteEditImageNumImages {
|
||||
use EnqueueBytedanceSeedreamV5LiteEditImageNumImages as E;
|
||||
match self {
|
||||
Self::One => E::One,
|
||||
Self::Two => E::Two,
|
||||
Self::Three => E::Three,
|
||||
Self::Four => E::Four,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_u64(self) -> u64 {
|
||||
match self {
|
||||
Self::One => 1,
|
||||
Self::Two => 2,
|
||||
Self::Three => 3,
|
||||
Self::Four => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FalSeedream5LiteImageSize {
|
||||
pub fn to_t2i(self) -> EnqueueBytedanceSeedreamV5LiteTextToImageSize {
|
||||
use EnqueueBytedanceSeedreamV5LiteTextToImageSize as T;
|
||||
match self {
|
||||
Self::Square => T::Square,
|
||||
Self::SquareHd => T::SquareHd,
|
||||
Self::PortraitFourThree => T::PortraitFourThree,
|
||||
Self::PortraitSixteenNine => T::PortraitSixteenNine,
|
||||
Self::LandscapeFourThree => T::LandscapeFourThree,
|
||||
Self::LandscapeSixteenNine => T::LandscapeSixteenNine,
|
||||
Self::Auto2k => T::Auto2k,
|
||||
Self::Auto3k => T::Auto3k,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_edit(self) -> EnqueueBytedanceSeedreamV5LiteEditImageSize {
|
||||
use EnqueueBytedanceSeedreamV5LiteEditImageSize as E;
|
||||
match self {
|
||||
Self::Square => E::Square,
|
||||
Self::SquareHd => E::SquareHd,
|
||||
Self::PortraitFourThree => E::PortraitFourThree,
|
||||
Self::PortraitSixteenNine => E::PortraitSixteenNine,
|
||||
Self::LandscapeFourThree => E::LandscapeFourThree,
|
||||
Self::LandscapeSixteenNine => E::LandscapeSixteenNine,
|
||||
Self::Auto2k => E::Auto2k,
|
||||
Self::Auto3k => E::Auto3k,
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling_1_6_pro::PlanArtcraftKling16Pro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_kling_1_6_pro(
|
||||
plan: &PlanArtcraftKling16Pro<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_v1p6_pro: 5s = $0.475 (rounded up to 48¢), 10s = $0.95 (95¢).
|
||||
let cost_in_usd_cents: u64 = if plan.is_ten_seconds() { 95 } else { 48 };
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling_2_1_master::PlanArtcraftKling21Master;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_kling_2_1_master(
|
||||
plan: &PlanArtcraftKling21Master<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_v2p1_master: 5s = $1.40, 10s = $2.80.
|
||||
let cost_in_usd_cents: u64 = if plan.is_ten_seconds() { 280 } else { 140 };
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling_2_1_pro::PlanArtcraftKling21Pro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_kling_2_1_pro(
|
||||
plan: &PlanArtcraftKling21Pro<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_v2p1_pro: 5s = $0.45, 10s = $0.90.
|
||||
let cost_in_usd_cents: u64 = if plan.is_ten_seconds() { 90 } else { 45 };
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling_2_5_turbo_pro::PlanArtcraftKling2p5TurboPro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_kling_2_5_turbo_pro(
|
||||
plan: &PlanArtcraftKling2p5TurboPro<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_v2p5_turbo_pro: 5s = $0.35, 10s = $0.70.
|
||||
let cost_in_usd_cents: u64 = if plan.is_ten_seconds() { 70 } else { 35 };
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling_2_6_pro::PlanArtcraftKling2p6Pro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_kling_2_6_pro(
|
||||
plan: &PlanArtcraftKling2p6Pro<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_v2p6_pro:
|
||||
// audio off: $0.07/sec → 5s=35¢, 10s=70¢
|
||||
// audio on: $0.14/sec → 5s=70¢, 10s=140¢
|
||||
// Default duration is 5s; default generate_audio is true.
|
||||
let cost_in_usd_cents: u64 = match (plan.generate_audio_for_cost(), plan.is_ten_seconds()) {
|
||||
(false, false) => 35,
|
||||
(false, true) => 70,
|
||||
(true, false) => 70,
|
||||
(true, true) => 140,
|
||||
};
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
use artcraft_api_defs::generate::video::generate_seedance_1_0_lite_image_to_video::GenerateSeedance10LiteResolution;
|
||||
use fal_client::creds::fal_api_key::FalApiKey;
|
||||
use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
use fal_client::requests::webhook::video::image::enqueue_seedance_1_lite_image_to_video_webhook::{
|
||||
Seedance1LiteArgs, Seedance1LiteDuration, Seedance1LiteResolution,
|
||||
};
|
||||
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_seedance_1_0_lite::PlanArtcraftSeedance10Lite;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_seedance_1_0_lite(
|
||||
plan: &PlanArtcraftSeedance10Lite<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Legacy handler defaults: 5 seconds, 720p. Delegate to the Fal client's
|
||||
// cost calculator to guarantee parity with what we actually charge.
|
||||
let api_key = FalApiKey::from_str("");
|
||||
let duration = if plan.duration_seconds_for_cost() == 10 {
|
||||
Seedance1LiteDuration::TenSeconds
|
||||
} else {
|
||||
Seedance1LiteDuration::FiveSeconds
|
||||
};
|
||||
let resolution = match plan.resolution_for_cost() {
|
||||
GenerateSeedance10LiteResolution::FourEightyP => Seedance1LiteResolution::FourEightyP,
|
||||
GenerateSeedance10LiteResolution::SevenTwentyP => Seedance1LiteResolution::SevenTwentyP,
|
||||
};
|
||||
|
||||
let end_frame: Option<&str> = None;
|
||||
let args = Seedance1LiteArgs {
|
||||
image_url: "",
|
||||
end_frame_image_url: end_frame,
|
||||
prompt: "",
|
||||
duration,
|
||||
resolution,
|
||||
aspect_ratio: None,
|
||||
camera_fixed: false,
|
||||
seed: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com",
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = args.calculate_cost_in_cents();
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_sora_2::PlanArtcraftSora2;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_sora_2(
|
||||
plan: &PlanArtcraftSora2<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Sora 2: $0.10/second. Default duration (Fal client): 4 seconds.
|
||||
let cost_in_usd_cents = plan.duration_seconds_for_cost() * 10;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_sora_2_pro::PlanArtcraftSora2Pro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_sora_2_pro(
|
||||
plan: &PlanArtcraftSora2Pro<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Sora 2 Pro: $0.30/second @ 720p, $0.50/second @ 1080p.
|
||||
// Default duration 4s. Default resolution: 1080p for text-to-video, 720p (Auto) for image-to-video.
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let per_second_cents: u64 = if plan.is_ten_eighty_p_for_cost() { 50 } else { 30 };
|
||||
let cost_in_usd_cents = per_second_cents * seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_veo_2::PlanArtcraftVeo2;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_veo_2(
|
||||
plan: &PlanArtcraftVeo2<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client veo_2 cost calculator: 5s = $2.50, +$0.50/s above 5s.
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let extra = seconds.saturating_sub(5);
|
||||
let cost_in_usd_cents = 250 + extra * 50;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_veo_3::PlanArtcraftVeo3;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_veo_3(
|
||||
plan: &PlanArtcraftVeo3<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client veo_3 cost calculator (720p/1080p):
|
||||
// $0.20/sec audio off, $0.40/sec audio on. Default 8s, audio off (legacy handler).
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let per_second_cents: u64 = if plan.generate_audio_for_cost() { 40 } else { 20 };
|
||||
let cost_in_usd_cents = per_second_cents * seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_veo_3_fast::PlanArtcraftVeo3Fast;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_veo_3_fast(
|
||||
plan: &PlanArtcraftVeo3Fast<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client veo_3_fast cost calculator (720p/1080p):
|
||||
// $0.10/sec audio off, $0.15/sec audio on. Default 8s, audio off (legacy handler).
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let per_second_cents: u64 = if plan.generate_audio_for_cost() { 15 } else { 10 };
|
||||
let cost_in_usd_cents = per_second_cents * seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_veo_3p1::PlanArtcraftVeo3p1;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_veo_3p1(
|
||||
plan: &PlanArtcraftVeo3p1<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client veo_3p1 cost calculator (720p/1080p):
|
||||
// $0.20/sec audio off, $0.40/sec audio on. Default 6s, audio on (legacy handler).
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let per_second_cents: u64 = if plan.generate_audio_for_cost() { 40 } else { 20 };
|
||||
let cost_in_usd_cents = per_second_cents * seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_veo_3p1_fast::PlanArtcraftVeo3p1Fast;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_artcraft_veo_3p1_fast(
|
||||
plan: &PlanArtcraftVeo3p1Fast<'_>,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client veo_3p1_fast cost calculator (720p/1080p):
|
||||
// $0.10/sec audio off, $0.15/sec audio on. Default 6s, audio on (legacy handler).
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let per_second_cents: u64 = if plan.generate_audio_for_cost() { 15 } else { 10 };
|
||||
let cost_in_usd_cents = per_second_cents * seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+13
@@ -1,4 +1,17 @@
|
||||
pub mod estimate_video_cost_artcraft_kling_1_6_pro;
|
||||
pub mod estimate_video_cost_artcraft_kling_2_1_master;
|
||||
pub mod estimate_video_cost_artcraft_kling_2_1_pro;
|
||||
pub mod estimate_video_cost_artcraft_kling_2_5_turbo_pro;
|
||||
pub mod estimate_video_cost_artcraft_kling_2_6_pro;
|
||||
pub mod estimate_video_cost_artcraft_kling3p0_pro;
|
||||
pub mod estimate_video_cost_artcraft_kling3p0_standard;
|
||||
pub mod estimate_video_cost_artcraft_seedance_1_0_lite;
|
||||
pub mod estimate_video_cost_artcraft_seedance1p5_pro;
|
||||
pub mod estimate_video_cost_artcraft_seedance2p0;
|
||||
pub mod estimate_video_cost_artcraft_sora_2;
|
||||
pub mod estimate_video_cost_artcraft_sora_2_pro;
|
||||
pub mod estimate_video_cost_artcraft_veo_2;
|
||||
pub mod estimate_video_cost_artcraft_veo_3;
|
||||
pub mod estimate_video_cost_artcraft_veo_3_fast;
|
||||
pub mod estimate_video_cost_artcraft_veo_3p1;
|
||||
pub mod estimate_video_cost_artcraft_veo_3p1_fast;
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_1_6_pro::PlanFalKling16Pro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_kling_1_6_pro(
|
||||
plan: &PlanFalKling16Pro,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_v1p6_pro: 5s = 48¢, 10s = 95¢ (Default → 5s).
|
||||
let cost_in_usd_cents: u64 = if plan.is_ten_seconds() { 95 } else { 48 };
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_2_1_master::PlanFalKling21Master;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_kling_2_1_master(
|
||||
plan: &PlanFalKling21Master,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_v2p1_master: 5s = $1.40, 10s = $2.80.
|
||||
let cost_in_usd_cents: u64 = if plan.is_ten_seconds() { 280 } else { 140 };
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_2_1_pro::PlanFalKling21Pro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_kling_2_1_pro(
|
||||
plan: &PlanFalKling21Pro,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_v2p1_pro: 5s = 45¢, 10s = 90¢.
|
||||
let cost_in_usd_cents: u64 = if plan.is_ten_seconds() { 90 } else { 45 };
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_2_5_turbo_pro::PlanFalKling2p5TurboPro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_kling_2_5_turbo_pro(
|
||||
plan: &PlanFalKling2p5TurboPro,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_v2p5_turbo_pro: 5s = 35¢, 10s = 70¢. None → 5s.
|
||||
let cost_in_usd_cents: u64 = if plan.is_ten_seconds() { 70 } else { 35 };
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_2_6_pro::PlanFalKling2p6Pro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_kling_2_6_pro(
|
||||
plan: &PlanFalKling2p6Pro,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_v2p6_pro:
|
||||
// audio off: $0.07/sec → 5s=35¢, 10s=70¢
|
||||
// audio on: $0.14/sec → 5s=70¢, 10s=140¢
|
||||
// Default duration is 5s; default generate_audio is true.
|
||||
let cost_in_usd_cents: u64 = match (plan.generate_audio_for_cost(), plan.is_ten_seconds()) {
|
||||
(false, false) => 35,
|
||||
(false, true) => 70,
|
||||
(true, false) => 70,
|
||||
(true, true) => 140,
|
||||
};
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_3p0_pro::PlanFalKling3p0Pro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_kling_3p0_pro(
|
||||
plan: &PlanFalKling3p0Pro,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_3p0_pro:
|
||||
// audio off: $0.224/sec (rate=224 in tenths-of-cents)
|
||||
// audio on: $0.336/sec (rate=336)
|
||||
// ceiling-divided to whole cents.
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let rate: u64 = if plan.generate_audio_for_cost() { 336 } else { 224 };
|
||||
let cost_in_usd_cents = (rate * seconds + 9) / 10;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_3p0_standard::PlanFalKling3p0Standard;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_kling_3p0_standard(
|
||||
plan: &PlanFalKling3p0Standard,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client kling_3p0_standard:
|
||||
// audio off: $0.168/sec (rate=168)
|
||||
// audio on: $0.252/sec (rate=252)
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let rate: u64 = if plan.generate_audio_for_cost() { 252 } else { 168 };
|
||||
let cost_in_usd_cents = (rate * seconds + 9) / 10;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
use fal_client::creds::fal_api_key::FalApiKey;
|
||||
use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
use fal_client::requests::webhook::video::image::enqueue_seedance_1_lite_image_to_video_webhook::Seedance1LiteArgs;
|
||||
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_seedance_1_0_lite::PlanFalSeedance10Lite;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_seedance_1_0_lite(
|
||||
plan: &PlanFalSeedance10Lite,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Delegate to the Fal client's cost calculator to guarantee parity with billing.
|
||||
let api_key = FalApiKey::from_str("");
|
||||
let end_frame: Option<&str> = plan.end_image_url.as_deref();
|
||||
let args = Seedance1LiteArgs {
|
||||
image_url: plan.image_url.as_str(),
|
||||
end_frame_image_url: end_frame,
|
||||
prompt: plan.prompt.as_str(),
|
||||
duration: plan.duration,
|
||||
resolution: plan.resolution,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
camera_fixed: false,
|
||||
seed: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com",
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = args.calculate_cost_in_cents();
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
use fal_client::creds::fal_api_key::FalApiKey;
|
||||
use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
use fal_client::requests::webhook::video::text::enqueue_seedance_1p5_pro_text_to_video_webhook::{
|
||||
EnqueueSeedance1p5ProTextToVideoArgs, EnqueueSeedance1p5ProTextToVideoDuration,
|
||||
EnqueueSeedance1p5ProTextToVideoResolution,
|
||||
};
|
||||
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_seedance_1p5_pro::{
|
||||
FalSeedance1p5ProDuration, FalSeedance1p5ProResolution, PlanFalSeedance1p5Pro,
|
||||
};
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_seedance_1p5_pro(
|
||||
plan: &PlanFalSeedance1p5Pro,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Seedance 1.5 Pro t2v and i2v have identical pricing; delegate to the t2v
|
||||
// calculator to guarantee parity with billing.
|
||||
let api_key = FalApiKey::from_str("");
|
||||
let args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
prompt: String::new(),
|
||||
resolution: plan.resolution.map(to_t2v_resolution),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: None,
|
||||
generate_audio: plan.generate_audio,
|
||||
webhook_url: "https://example.com",
|
||||
api_key: &api_key,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = args.calculate_cost_in_cents();
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_resolution(r: FalSeedance1p5ProResolution) -> EnqueueSeedance1p5ProTextToVideoResolution {
|
||||
match r {
|
||||
FalSeedance1p5ProResolution::FourEightyP => EnqueueSeedance1p5ProTextToVideoResolution::FourEightyP,
|
||||
FalSeedance1p5ProResolution::SevenTwentyP => EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP,
|
||||
FalSeedance1p5ProResolution::TenEightyP => EnqueueSeedance1p5ProTextToVideoResolution::TenEightyP,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_duration(d: FalSeedance1p5ProDuration) -> EnqueueSeedance1p5ProTextToVideoDuration {
|
||||
use EnqueueSeedance1p5ProTextToVideoDuration as T;
|
||||
match d {
|
||||
FalSeedance1p5ProDuration::Four => T::FourSeconds,
|
||||
FalSeedance1p5ProDuration::Five => T::FiveSeconds,
|
||||
FalSeedance1p5ProDuration::Six => T::SixSeconds,
|
||||
FalSeedance1p5ProDuration::Seven => T::SevenSeconds,
|
||||
FalSeedance1p5ProDuration::Eight => T::EightSeconds,
|
||||
FalSeedance1p5ProDuration::Nine => T::NineSeconds,
|
||||
FalSeedance1p5ProDuration::Ten => T::TenSeconds,
|
||||
FalSeedance1p5ProDuration::Eleven => T::ElevenSeconds,
|
||||
FalSeedance1p5ProDuration::Twelve => T::TwelveSeconds,
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_sora_2::PlanFalSora2;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_sora_2(
|
||||
plan: &PlanFalSora2,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Sora 2: $0.10/second. Default duration (Fal client): 4s.
|
||||
let cost_in_usd_cents = plan.duration_seconds_for_cost() * 10;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_sora_2_pro::PlanFalSora2Pro;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_sora_2_pro(
|
||||
plan: &PlanFalSora2Pro,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Sora 2 Pro: $0.30/second @ 720p, $0.50/second @ 1080p.
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let per_second_cents: u64 = if plan.is_ten_eighty_p_for_cost() { 50 } else { 30 };
|
||||
let cost_in_usd_cents = per_second_cents * seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_2::PlanFalVeo2;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_veo_2(
|
||||
plan: &PlanFalVeo2,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// 5s = $2.50, +$0.50 per additional second.
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let extra = seconds.saturating_sub(5);
|
||||
let cost_in_usd_cents = 250 + extra * 50;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_3::PlanFalVeo3;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_veo_3(
|
||||
plan: &PlanFalVeo3,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// $0.20/sec audio off, $0.40/sec audio on (720p/1080p).
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let per_second_cents: u64 = if plan.generate_audio { 40 } else { 20 };
|
||||
let cost_in_usd_cents = per_second_cents * seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_3_fast::PlanFalVeo3Fast;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_veo_3_fast(
|
||||
plan: &PlanFalVeo3Fast,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// $0.10/sec audio off, $0.15/sec audio on (720p/1080p).
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let per_second_cents: u64 = if plan.generate_audio { 15 } else { 10 };
|
||||
let cost_in_usd_cents = per_second_cents * seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_3p1::PlanFalVeo3p1;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_veo_3p1(
|
||||
plan: &PlanFalVeo3p1,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// $0.20/sec audio off, $0.40/sec audio on (720p/1080p).
|
||||
let seconds = plan.duration_seconds_for_cost();
|
||||
let per_second_cents: u64 = if plan.generate_audio_for_cost() { 40 } else { 20 };
|
||||
let cost_in_usd_cents = per_second_cents * seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_3p1_fast::PlanFalVeo3p1Fast;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
|
||||
pub(crate) fn estimate_video_cost_fal_veo_3p1_fast(
|
||||
plan: &PlanFalVeo3p1Fast,
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// $0.10/sec audio off, $0.15/sec audio on (720p/1080p).
|
||||
let seconds = plan.inner.duration_seconds_for_cost();
|
||||
let per_second_cents: u64 = if plan.inner.generate_audio_for_cost() { 15 } else { 10 };
|
||||
let cost_in_usd_cents = per_second_cents * seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
pub(crate) mod estimate_video_cost_fal_kling_1_6_pro;
|
||||
pub(crate) mod estimate_video_cost_fal_kling_2_1_master;
|
||||
pub(crate) mod estimate_video_cost_fal_kling_2_1_pro;
|
||||
pub(crate) mod estimate_video_cost_fal_kling_2_5_turbo_pro;
|
||||
pub(crate) mod estimate_video_cost_fal_kling_2_6_pro;
|
||||
pub(crate) mod estimate_video_cost_fal_kling_3p0_pro;
|
||||
pub(crate) mod estimate_video_cost_fal_kling_3p0_standard;
|
||||
pub(crate) mod estimate_video_cost_fal_seedance_1_0_lite;
|
||||
pub(crate) mod estimate_video_cost_fal_seedance_1p5_pro;
|
||||
pub(crate) mod estimate_video_cost_fal_sora_2;
|
||||
pub(crate) mod estimate_video_cost_fal_sora_2_pro;
|
||||
pub(crate) mod estimate_video_cost_fal_veo_2;
|
||||
pub(crate) mod estimate_video_cost_fal_veo_3;
|
||||
pub(crate) mod estimate_video_cost_fal_veo_3_fast;
|
||||
pub(crate) mod estimate_video_cost_fal_veo_3p1;
|
||||
pub(crate) mod estimate_video_cost_fal_veo_3p1_fast;
|
||||
@@ -1,3 +1,4 @@
|
||||
pub (crate) mod artcraft;
|
||||
pub (crate) mod fal;
|
||||
pub (crate) mod muapi;
|
||||
pub (crate) mod seedance2pro;
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling_1_6_pro::PlanArtcraftKling16Pro;
|
||||
use artcraft_api_defs::generate::video::generate_kling_1_6_pro_image_to_video::GenerateKling16ProImageToVideoRequest;
|
||||
use artcraft_client::endpoints::generate::video::generate_kling_16_pro_image_to_video::generate_kling_16_pro_image_to_video;
|
||||
|
||||
pub async fn execute_artcraft_kling_1_6_pro(
|
||||
plan: &PlanArtcraftKling16Pro<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = GenerateKling16ProImageToVideoRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
media_file_token: Some(plan.start_frame.to_owned()),
|
||||
end_frame_image_media_token: plan.end_frame.map(|t| t.to_owned()),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
duration: plan.duration,
|
||||
};
|
||||
|
||||
let response = generate_kling_16_pro_image_to_video(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling_2_1_master::PlanArtcraftKling21Master;
|
||||
use artcraft_api_defs::generate::video::generate_kling_2_1_master_image_to_video::GenerateKling21MasterImageToVideoRequest;
|
||||
use artcraft_client::endpoints::generate::video::generate_kling_21_master_image_to_video::generate_kling_21_master_image_to_video;
|
||||
|
||||
pub async fn execute_artcraft_kling_2_1_master(
|
||||
plan: &PlanArtcraftKling21Master<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = GenerateKling21MasterImageToVideoRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
media_file_token: Some(plan.start_frame.to_owned()),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
duration: plan.duration,
|
||||
};
|
||||
|
||||
let response = generate_kling_21_master_image_to_video(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling_2_1_pro::PlanArtcraftKling21Pro;
|
||||
use artcraft_api_defs::generate::video::generate_kling_2_1_pro_image_to_video::GenerateKling21ProImageToVideoRequest;
|
||||
use artcraft_client::endpoints::generate::video::generate_kling_21_pro_image_to_video::generate_kling_21_pro_image_to_video;
|
||||
|
||||
pub async fn execute_artcraft_kling_2_1_pro(
|
||||
plan: &PlanArtcraftKling21Pro<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = GenerateKling21ProImageToVideoRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
media_file_token: Some(plan.start_frame.to_owned()),
|
||||
end_frame_image_media_token: plan.end_frame.map(|t| t.to_owned()),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
duration: plan.duration,
|
||||
};
|
||||
|
||||
let response = generate_kling_21_pro_image_to_video(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling_2_5_turbo_pro::PlanArtcraftKling2p5TurboPro;
|
||||
use artcraft_api_defs::generate::video::multi_function::kling_2_5_turbo_multi_function_video_gen::Kling2p5TurboProMultiFunctionVideoGenRequest;
|
||||
use artcraft_client::endpoints::generate::video::multi_function::kling_2p5_turbo_pro_multi_function_video_gen::kling_2p5_turbo_pro_multi_function_video_gen;
|
||||
|
||||
pub async fn execute_artcraft_kling_2_5_turbo_pro(
|
||||
plan: &PlanArtcraftKling2p5TurboPro<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = Kling2p5TurboProMultiFunctionVideoGenRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
negative_prompt: plan.negative_prompt.map(|p| p.to_string()),
|
||||
start_frame_image_media_token: plan.start_frame.map(|t| t.to_owned()),
|
||||
end_frame_image_media_token: plan.end_frame.map(|t| t.to_owned()),
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
};
|
||||
|
||||
let response = kling_2p5_turbo_pro_multi_function_video_gen(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling_2_6_pro::PlanArtcraftKling2p6Pro;
|
||||
use artcraft_api_defs::generate::video::multi_function::kling_2_6_multi_function_video_gen::Kling2p6ProMultiFunctionVideoGenRequest;
|
||||
use artcraft_client::endpoints::generate::video::multi_function::kling_2p6_pro_multi_function_video_gen::kling_2p6_pro_multi_function_video_gen;
|
||||
|
||||
pub async fn execute_artcraft_kling_2_6_pro(
|
||||
plan: &PlanArtcraftKling2p6Pro<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = Kling2p6ProMultiFunctionVideoGenRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
negative_prompt: plan.negative_prompt.map(|p| p.to_string()),
|
||||
start_frame_image_media_token: plan.start_frame.map(|t| t.to_owned()),
|
||||
duration: plan.duration,
|
||||
generate_audio: plan.generate_audio,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
};
|
||||
|
||||
let response = kling_2p6_pro_multi_function_video_gen(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_seedance_1_0_lite::PlanArtcraftSeedance10Lite;
|
||||
use artcraft_api_defs::generate::video::generate_seedance_1_0_lite_image_to_video::GenerateSeedance10LiteImageToVideoRequest;
|
||||
use artcraft_client::endpoints::generate::video::generate_seedance_1_0_lite_image_to_video::generate_seedance_1_0_lite_image_to_video;
|
||||
|
||||
pub async fn execute_artcraft_seedance_1_0_lite(
|
||||
plan: &PlanArtcraftSeedance10Lite<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = GenerateSeedance10LiteImageToVideoRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
media_file_token: Some(plan.start_frame.to_owned()),
|
||||
end_frame_image_media_token: plan.end_frame.map(|t| t.to_owned()),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
resolution: plan.resolution,
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
};
|
||||
|
||||
let response = generate_seedance_1_0_lite_image_to_video(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_sora_2::PlanArtcraftSora2;
|
||||
use artcraft_api_defs::generate::video::multi_function::sora_2_multi_function_video_gen::Sora2MultiFunctionVideoGenRequest;
|
||||
use artcraft_client::endpoints::generate::video::multi_function::sora_2_multi_function_video_gen::sora_2_multi_function_video_gen;
|
||||
|
||||
pub async fn execute_artcraft_sora_2(
|
||||
plan: &PlanArtcraftSora2<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = Sora2MultiFunctionVideoGenRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
image_media_token: plan.start_frame.map(|t| t.to_owned()),
|
||||
resolution: plan.resolution,
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
};
|
||||
|
||||
let response = sora_2_multi_function_video_gen(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_sora_2_pro::PlanArtcraftSora2Pro;
|
||||
use artcraft_api_defs::generate::video::multi_function::sora_2_pro_multi_function_video_gen::Sora2ProMultiFunctionVideoGenRequest;
|
||||
use artcraft_client::endpoints::generate::video::multi_function::sora_2_pro_multi_function_video_gen::sora_2_pro_multi_function_video_gen;
|
||||
|
||||
pub async fn execute_artcraft_sora_2_pro(
|
||||
plan: &PlanArtcraftSora2Pro<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = Sora2ProMultiFunctionVideoGenRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
image_media_token: plan.start_frame.map(|t| t.to_owned()),
|
||||
resolution: plan.resolution,
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
};
|
||||
|
||||
let response = sora_2_pro_multi_function_video_gen(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_veo_2::PlanArtcraftVeo2;
|
||||
use artcraft_api_defs::generate::video::generate_veo_2_image_to_video::GenerateVeo2ImageToVideoRequest;
|
||||
use artcraft_client::endpoints::generate::video::generate_veo_2_image_to_video::generate_veo_2_image_to_video;
|
||||
|
||||
pub async fn execute_artcraft_veo_2(
|
||||
plan: &PlanArtcraftVeo2<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = GenerateVeo2ImageToVideoRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
media_file_token: Some(plan.start_frame.to_owned()),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
aspect_ratio: plan.aspect_ratio.clone(),
|
||||
duration: plan.duration.clone(),
|
||||
};
|
||||
|
||||
let response = generate_veo_2_image_to_video(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_veo_3::PlanArtcraftVeo3;
|
||||
use artcraft_api_defs::generate::video::generate_veo_3_image_to_video::GenerateVeo3ImageToVideoRequest;
|
||||
use artcraft_client::endpoints::generate::video::generate_veo_3_image_to_video::generate_veo_3_image_to_video;
|
||||
|
||||
pub async fn execute_artcraft_veo_3(
|
||||
plan: &PlanArtcraftVeo3<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = GenerateVeo3ImageToVideoRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
media_file_token: Some(plan.start_frame.to_owned()),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
resolution: plan.resolution,
|
||||
duration: plan.duration,
|
||||
generate_audio: plan.generate_audio,
|
||||
};
|
||||
|
||||
let response = generate_veo_3_image_to_video(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_veo_3_fast::PlanArtcraftVeo3Fast;
|
||||
use artcraft_api_defs::generate::video::generate_veo_3_fast_image_to_video::GenerateVeo3FastImageToVideoRequest;
|
||||
use artcraft_client::endpoints::generate::video::generate_veo_3_fast_image_to_video::generate_veo_3_fast_image_to_video;
|
||||
|
||||
pub async fn execute_artcraft_veo_3_fast(
|
||||
plan: &PlanArtcraftVeo3Fast<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = GenerateVeo3FastImageToVideoRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
media_file_token: Some(plan.start_frame.to_owned()),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
resolution: plan.resolution,
|
||||
duration: plan.duration,
|
||||
generate_audio: plan.generate_audio,
|
||||
};
|
||||
|
||||
let response = generate_veo_3_fast_image_to_video(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_veo_3p1::PlanArtcraftVeo3p1;
|
||||
use artcraft_api_defs::generate::video::multi_function::veo_3p1_multi_function_video_gen::Veo3p1MultiFunctionVideoGenRequest;
|
||||
use artcraft_client::endpoints::generate::video::multi_function::veo_3p1_multi_function_video_gen::veo_3p1_multi_function_video_gen;
|
||||
|
||||
pub async fn execute_artcraft_veo_3p1(
|
||||
plan: &PlanArtcraftVeo3p1<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = Veo3p1MultiFunctionVideoGenRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
negative_prompt: plan.negative_prompt.map(|p| p.to_string()),
|
||||
start_frame_image_media_token: plan.start_frame.map(|t| t.to_owned()),
|
||||
end_frame_image_media_token: plan.end_frame.map(|t| t.to_owned()),
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
resolution: plan.resolution,
|
||||
generate_audio: plan.generate_audio,
|
||||
enhance_prompt: None,
|
||||
seed: None,
|
||||
auto_fix: None,
|
||||
};
|
||||
|
||||
let response = veo_3p1_multi_function_video_gen(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
ArtcraftVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_veo_3p1_fast::PlanArtcraftVeo3p1Fast;
|
||||
use artcraft_api_defs::generate::video::multi_function::veo_3p1_fast_multi_function_video_gen::Veo3p1FastMultiFunctionVideoGenRequest;
|
||||
use artcraft_client::endpoints::generate::video::multi_function::veo_3p1_fast_multi_function_video_gen::veo_3p1_fast_multi_function_video_gen;
|
||||
|
||||
pub async fn execute_artcraft_veo_3p1_fast(
|
||||
plan: &PlanArtcraftVeo3p1Fast<'_>,
|
||||
artcraft_client: &RouterArtcraftClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let request = Veo3p1FastMultiFunctionVideoGenRequest {
|
||||
uuid_idempotency_token: plan.idempotency_token.clone(),
|
||||
prompt: plan.prompt.map(|p| p.to_string()),
|
||||
negative_prompt: plan.negative_prompt.map(|p| p.to_string()),
|
||||
start_frame_image_media_token: plan.start_frame.map(|t| t.to_owned()),
|
||||
end_frame_image_media_token: plan.end_frame.map(|t| t.to_owned()),
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
resolution: plan.resolution,
|
||||
generate_audio: plan.generate_audio,
|
||||
enhance_prompt: None,
|
||||
seed: None,
|
||||
auto_fix: None,
|
||||
};
|
||||
|
||||
let response = veo_3p1_fast_multi_function_video_gen(
|
||||
&artcraft_client.api_host,
|
||||
Some(&artcraft_client.credentials),
|
||||
request,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
let all_tokens = vec![response.inference_job_token.clone()];
|
||||
Ok(GenerateVideoResponse::Artcraft(ArtcraftVideoResponsePayload {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: all_tokens,
|
||||
}))
|
||||
}
|
||||
+13
@@ -1,4 +1,17 @@
|
||||
pub mod generate_video_artcraft_kling_1_6_pro;
|
||||
pub mod generate_video_artcraft_kling_2_1_master;
|
||||
pub mod generate_video_artcraft_kling_2_1_pro;
|
||||
pub mod generate_video_artcraft_kling_2_5_turbo_pro;
|
||||
pub mod generate_video_artcraft_kling_2_6_pro;
|
||||
pub mod generate_video_artcraft_kling3p0_pro;
|
||||
pub mod generate_video_artcraft_kling3p0_standard;
|
||||
pub mod generate_video_artcraft_seedance_1_0_lite;
|
||||
pub mod generate_video_artcraft_seedance1p5_pro;
|
||||
pub mod generate_video_artcraft_seedance2p0;
|
||||
pub mod generate_video_artcraft_sora_2;
|
||||
pub mod generate_video_artcraft_sora_2_pro;
|
||||
pub mod generate_video_artcraft_veo_2;
|
||||
pub mod generate_video_artcraft_veo_3;
|
||||
pub mod generate_video_artcraft_veo_3_fast;
|
||||
pub mod generate_video_artcraft_veo_3p1;
|
||||
pub mod generate_video_artcraft_veo_3p1_fast;
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_1_6_pro::PlanFalKling16Pro;
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_v1p6_pro_image_to_video_webhook::{
|
||||
enqueue_kling_v1p6_pro_image_to_video_webhook, Kling1p6ProArgs,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_1_6_pro(
|
||||
plan: &PlanFalKling16Pro,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
// The Fal arg type is generic over `Option<T: IntoUrl>` for the end frame URL —
|
||||
// explicitly bind T to String here.
|
||||
let end_frame_image_url: Option<String> = plan.end_image_url.clone();
|
||||
|
||||
let args = Kling1p6ProArgs {
|
||||
image_url: plan.image_url.as_str(),
|
||||
end_frame_image_url,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
prompt: plan.prompt.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
};
|
||||
|
||||
let webhook_response = enqueue_kling_v1p6_pro_image_to_video_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_2_1_master::PlanFalKling21Master;
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_v2p1_master_image_to_video_webhook::{
|
||||
enqueue_kling_v2p1_master_image_to_video_webhook, Kling2p1MasterArgs,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_2_1_master(
|
||||
plan: &PlanFalKling21Master,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let args = Kling2p1MasterArgs {
|
||||
image_url: plan.image_url.as_str(),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
prompt: plan.prompt.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
};
|
||||
|
||||
let webhook_response = enqueue_kling_v2p1_master_image_to_video_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_2_1_pro::PlanFalKling21Pro;
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_v2p1_pro_image_to_video_webhook::{
|
||||
enqueue_kling_v2p1_pro_image_to_video_webhook, Kling2p1ProArgs,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_2_1_pro(
|
||||
plan: &PlanFalKling21Pro,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let end_frame_image_url: Option<String> = plan.end_image_url.clone();
|
||||
|
||||
let args = Kling2p1ProArgs {
|
||||
image_url: plan.image_url.as_str(),
|
||||
end_frame_image_url,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
prompt: plan.prompt.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
};
|
||||
|
||||
let webhook_response = enqueue_kling_v2p1_pro_image_to_video_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_2_5_turbo_pro::{
|
||||
FalKling2p5TurboProAspectRatio, FalKling2p5TurboProDuration, FalKling2p5TurboProMode,
|
||||
PlanFalKling2p5TurboPro,
|
||||
};
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_v2p5_turbo_pro_image_to_video_webhook::{
|
||||
enqueue_kling_v2p5_turbo_pro_image_to_video_webhook, EnqueueKlingV2p5TurboProImageToVideoArgs,
|
||||
EnqueueKlingV2p5TurboProImageToVideoDurationSeconds,
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_v2p5_turbo_pro_text_to_video_webhook::{
|
||||
enqueue_kling_v2p5_turbo_pro_text_to_video_webhook, EnqueueKlingV2p5TurboProTextToVideoArgs,
|
||||
EnqueueKlingV2p5TurboProTextToVideoAspectRatio, EnqueueKlingV2p5TurboProTextToVideoDurationSeconds,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_2_5_turbo_pro(
|
||||
plan: &PlanFalKling2p5TurboPro,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let webhook_response = match &plan.mode {
|
||||
FalKling2p5TurboProMode::TextToVideo => {
|
||||
let args = EnqueueKlingV2p5TurboProTextToVideoArgs {
|
||||
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),
|
||||
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
|
||||
}
|
||||
FalKling2p5TurboProMode::ImageToVideo { image_url, end_image_url } => {
|
||||
let args = EnqueueKlingV2p5TurboProImageToVideoArgs {
|
||||
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),
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
let webhook_response = webhook_response
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
|
||||
fn to_t2v_duration(d: FalKling2p5TurboProDuration) -> EnqueueKlingV2p5TurboProTextToVideoDurationSeconds {
|
||||
match d {
|
||||
FalKling2p5TurboProDuration::Five => EnqueueKlingV2p5TurboProTextToVideoDurationSeconds::Five,
|
||||
FalKling2p5TurboProDuration::Ten => EnqueueKlingV2p5TurboProTextToVideoDurationSeconds::Ten,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_aspect_ratio(a: FalKling2p5TurboProAspectRatio) -> EnqueueKlingV2p5TurboProTextToVideoAspectRatio {
|
||||
match a {
|
||||
FalKling2p5TurboProAspectRatio::Square => EnqueueKlingV2p5TurboProTextToVideoAspectRatio::Square,
|
||||
FalKling2p5TurboProAspectRatio::SixteenByNine => EnqueueKlingV2p5TurboProTextToVideoAspectRatio::SixteenByNine,
|
||||
FalKling2p5TurboProAspectRatio::NineBySixteen => EnqueueKlingV2p5TurboProTextToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_duration(d: FalKling2p5TurboProDuration) -> EnqueueKlingV2p5TurboProImageToVideoDurationSeconds {
|
||||
match d {
|
||||
FalKling2p5TurboProDuration::Five => EnqueueKlingV2p5TurboProImageToVideoDurationSeconds::Five,
|
||||
FalKling2p5TurboProDuration::Ten => EnqueueKlingV2p5TurboProImageToVideoDurationSeconds::Ten,
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_2_6_pro::{
|
||||
FalKling2p6ProAspectRatio, FalKling2p6ProDuration, FalKling2p6ProMode, PlanFalKling2p6Pro,
|
||||
};
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_v2p6_pro_image_to_video_webhook::{
|
||||
enqueue_kling_v2p6_pro_image_to_video_webhook, EnqueueKlingV2p6ProImageToVideoArgs,
|
||||
EnqueueKlingV2p6ProImageToVideoDurationSeconds,
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_v2p6_pro_text_to_video_webhook::{
|
||||
enqueue_kling_v2p6_pro_text_to_video_webhook, EnqueueKlingV2p6ProTextToVideoArgs,
|
||||
EnqueueKlingV2p6ProTextToVideoAspectRatio, EnqueueKlingV2p6ProTextToVideoDurationSeconds,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_2_6_pro(
|
||||
plan: &PlanFalKling2p6Pro,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let webhook_response = match &plan.mode {
|
||||
FalKling2p6ProMode::TextToVideo => {
|
||||
let args = EnqueueKlingV2p6ProTextToVideoArgs {
|
||||
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),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_kling_v2p6_pro_text_to_video_webhook(args).await
|
||||
}
|
||||
FalKling2p6ProMode::ImageToVideo { image_url } => {
|
||||
let args = EnqueueKlingV2p6ProImageToVideoArgs {
|
||||
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),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_kling_v2p6_pro_image_to_video_webhook(args).await
|
||||
}
|
||||
};
|
||||
|
||||
let webhook_response = webhook_response
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
|
||||
fn to_t2v_duration(d: FalKling2p6ProDuration) -> EnqueueKlingV2p6ProTextToVideoDurationSeconds {
|
||||
match d {
|
||||
FalKling2p6ProDuration::Five => EnqueueKlingV2p6ProTextToVideoDurationSeconds::Five,
|
||||
FalKling2p6ProDuration::Ten => EnqueueKlingV2p6ProTextToVideoDurationSeconds::Ten,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_aspect_ratio(a: FalKling2p6ProAspectRatio) -> EnqueueKlingV2p6ProTextToVideoAspectRatio {
|
||||
match a {
|
||||
FalKling2p6ProAspectRatio::Square => EnqueueKlingV2p6ProTextToVideoAspectRatio::Square,
|
||||
FalKling2p6ProAspectRatio::SixteenByNine => EnqueueKlingV2p6ProTextToVideoAspectRatio::SixteenByNine,
|
||||
FalKling2p6ProAspectRatio::NineBySixteen => EnqueueKlingV2p6ProTextToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_duration(d: FalKling2p6ProDuration) -> EnqueueKlingV2p6ProImageToVideoDurationSeconds {
|
||||
match d {
|
||||
FalKling2p6ProDuration::Five => EnqueueKlingV2p6ProImageToVideoDurationSeconds::Five,
|
||||
FalKling2p6ProDuration::Ten => EnqueueKlingV2p6ProImageToVideoDurationSeconds::Ten,
|
||||
}
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_3p0_pro::{
|
||||
FalKling3p0AspectRatio, FalKling3p0Duration, FalKling3p0Mode, PlanFalKling3p0Pro,
|
||||
};
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_3p0_pro_image_to_video_webhook::{
|
||||
enqueue_kling_3p0_pro_image_to_video_webhook, EnqueueKling3p0ProImageToVideoArgs,
|
||||
EnqueueKling3p0ProImageToVideoAspectRatio, EnqueueKling3p0ProImageToVideoDuration,
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_3p0_pro_text_to_video_webhook::{
|
||||
enqueue_kling_3p0_pro_text_to_video_webhook, EnqueueKling3p0ProTextToVideoArgs,
|
||||
EnqueueKling3p0ProTextToVideoAspectRatio, EnqueueKling3p0ProTextToVideoDuration,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_3p0_pro(
|
||||
plan: &PlanFalKling3p0Pro,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let webhook_response = match &plan.mode {
|
||||
FalKling3p0Mode::TextToVideo => {
|
||||
let args = EnqueueKling3p0ProTextToVideoArgs {
|
||||
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,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_kling_3p0_pro_text_to_video_webhook(args).await
|
||||
}
|
||||
FalKling3p0Mode::ImageToVideo { image_url, end_image_url } => {
|
||||
let args = EnqueueKling3p0ProImageToVideoArgs {
|
||||
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,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_kling_3p0_pro_image_to_video_webhook(args).await
|
||||
}
|
||||
};
|
||||
|
||||
let webhook_response = webhook_response
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
|
||||
fn to_t2v_duration(d: FalKling3p0Duration) -> EnqueueKling3p0ProTextToVideoDuration {
|
||||
use EnqueueKling3p0ProTextToVideoDuration as D;
|
||||
match d.0 {
|
||||
3 => D::ThreeSeconds,
|
||||
4 => D::FourSeconds,
|
||||
5 => D::FiveSeconds,
|
||||
6 => D::SixSeconds,
|
||||
7 => D::SevenSeconds,
|
||||
8 => D::EightSeconds,
|
||||
9 => D::NineSeconds,
|
||||
10 => D::TenSeconds,
|
||||
11 => D::ElevenSeconds,
|
||||
12 => D::TwelveSeconds,
|
||||
13 => D::ThirteenSeconds,
|
||||
14 => D::FourteenSeconds,
|
||||
_ => D::FifteenSeconds,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_duration(d: FalKling3p0Duration) -> EnqueueKling3p0ProImageToVideoDuration {
|
||||
use EnqueueKling3p0ProImageToVideoDuration as D;
|
||||
match d.0 {
|
||||
3 => D::ThreeSeconds,
|
||||
4 => D::FourSeconds,
|
||||
5 => D::FiveSeconds,
|
||||
6 => D::SixSeconds,
|
||||
7 => D::SevenSeconds,
|
||||
8 => D::EightSeconds,
|
||||
9 => D::NineSeconds,
|
||||
10 => D::TenSeconds,
|
||||
11 => D::ElevenSeconds,
|
||||
12 => D::TwelveSeconds,
|
||||
13 => D::ThirteenSeconds,
|
||||
14 => D::FourteenSeconds,
|
||||
_ => D::FifteenSeconds,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_aspect_ratio(a: FalKling3p0AspectRatio) -> EnqueueKling3p0ProTextToVideoAspectRatio {
|
||||
match a {
|
||||
FalKling3p0AspectRatio::Square => EnqueueKling3p0ProTextToVideoAspectRatio::Square,
|
||||
FalKling3p0AspectRatio::SixteenByNine => EnqueueKling3p0ProTextToVideoAspectRatio::SixteenByNine,
|
||||
FalKling3p0AspectRatio::NineBySixteen => EnqueueKling3p0ProTextToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_aspect_ratio(a: FalKling3p0AspectRatio) -> EnqueueKling3p0ProImageToVideoAspectRatio {
|
||||
match a {
|
||||
FalKling3p0AspectRatio::Square => EnqueueKling3p0ProImageToVideoAspectRatio::Square,
|
||||
FalKling3p0AspectRatio::SixteenByNine => EnqueueKling3p0ProImageToVideoAspectRatio::SixteenByNine,
|
||||
FalKling3p0AspectRatio::NineBySixteen => EnqueueKling3p0ProImageToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_3p0_pro::{
|
||||
FalKling3p0AspectRatio, FalKling3p0Duration, FalKling3p0Mode,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_kling_3p0_standard::PlanFalKling3p0Standard;
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_3p0_standard_image_to_video_webhook::{
|
||||
enqueue_kling_3p0_standard_image_to_video_webhook, EnqueueKling3p0StandardImageToVideoArgs,
|
||||
EnqueueKling3p0StandardImageToVideoAspectRatio, EnqueueKling3p0StandardImageToVideoDuration,
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_3p0_standard_text_to_video_webhook::{
|
||||
enqueue_kling_3p0_standard_text_to_video_webhook, EnqueueKling3p0StandardTextToVideoArgs,
|
||||
EnqueueKling3p0StandardTextToVideoAspectRatio, EnqueueKling3p0StandardTextToVideoDuration,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_3p0_standard(
|
||||
plan: &PlanFalKling3p0Standard,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let webhook_response = match &plan.mode {
|
||||
FalKling3p0Mode::TextToVideo => {
|
||||
let args = EnqueueKling3p0StandardTextToVideoArgs {
|
||||
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,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_kling_3p0_standard_text_to_video_webhook(args).await
|
||||
}
|
||||
FalKling3p0Mode::ImageToVideo { image_url, end_image_url } => {
|
||||
let args = EnqueueKling3p0StandardImageToVideoArgs {
|
||||
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,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_kling_3p0_standard_image_to_video_webhook(args).await
|
||||
}
|
||||
};
|
||||
|
||||
let webhook_response = webhook_response
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
|
||||
fn to_t2v_duration(d: FalKling3p0Duration) -> EnqueueKling3p0StandardTextToVideoDuration {
|
||||
use EnqueueKling3p0StandardTextToVideoDuration as D;
|
||||
match d.0 {
|
||||
3 => D::ThreeSeconds,
|
||||
4 => D::FourSeconds,
|
||||
5 => D::FiveSeconds,
|
||||
6 => D::SixSeconds,
|
||||
7 => D::SevenSeconds,
|
||||
8 => D::EightSeconds,
|
||||
9 => D::NineSeconds,
|
||||
10 => D::TenSeconds,
|
||||
11 => D::ElevenSeconds,
|
||||
12 => D::TwelveSeconds,
|
||||
13 => D::ThirteenSeconds,
|
||||
14 => D::FourteenSeconds,
|
||||
_ => D::FifteenSeconds,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_duration(d: FalKling3p0Duration) -> EnqueueKling3p0StandardImageToVideoDuration {
|
||||
use EnqueueKling3p0StandardImageToVideoDuration as D;
|
||||
match d.0 {
|
||||
3 => D::ThreeSeconds,
|
||||
4 => D::FourSeconds,
|
||||
5 => D::FiveSeconds,
|
||||
6 => D::SixSeconds,
|
||||
7 => D::SevenSeconds,
|
||||
8 => D::EightSeconds,
|
||||
9 => D::NineSeconds,
|
||||
10 => D::TenSeconds,
|
||||
11 => D::ElevenSeconds,
|
||||
12 => D::TwelveSeconds,
|
||||
13 => D::ThirteenSeconds,
|
||||
14 => D::FourteenSeconds,
|
||||
_ => D::FifteenSeconds,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_aspect_ratio(a: FalKling3p0AspectRatio) -> EnqueueKling3p0StandardTextToVideoAspectRatio {
|
||||
match a {
|
||||
FalKling3p0AspectRatio::Square => EnqueueKling3p0StandardTextToVideoAspectRatio::Square,
|
||||
FalKling3p0AspectRatio::SixteenByNine => EnqueueKling3p0StandardTextToVideoAspectRatio::SixteenByNine,
|
||||
FalKling3p0AspectRatio::NineBySixteen => EnqueueKling3p0StandardTextToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_aspect_ratio(a: FalKling3p0AspectRatio) -> EnqueueKling3p0StandardImageToVideoAspectRatio {
|
||||
match a {
|
||||
FalKling3p0AspectRatio::Square => EnqueueKling3p0StandardImageToVideoAspectRatio::Square,
|
||||
FalKling3p0AspectRatio::SixteenByNine => EnqueueKling3p0StandardImageToVideoAspectRatio::SixteenByNine,
|
||||
FalKling3p0AspectRatio::NineBySixteen => EnqueueKling3p0StandardImageToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_seedance_1_0_lite::PlanFalSeedance10Lite;
|
||||
use fal_client::requests::webhook::video::image::enqueue_seedance_1_lite_image_to_video_webhook::{
|
||||
enqueue_seedance_1_lite_image_to_video_webhook, Seedance1LiteArgs,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_seedance_1_0_lite(
|
||||
plan: &PlanFalSeedance10Lite,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let end_frame: Option<&str> = plan.end_image_url.as_deref();
|
||||
|
||||
let args = Seedance1LiteArgs {
|
||||
image_url: plan.image_url.as_str(),
|
||||
end_frame_image_url: end_frame,
|
||||
prompt: plan.prompt.as_str(),
|
||||
duration: plan.duration,
|
||||
resolution: plan.resolution,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
camera_fixed: false,
|
||||
seed: None,
|
||||
api_key: &fal_client.api_key,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
};
|
||||
|
||||
let webhook_response = enqueue_seedance_1_lite_image_to_video_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_seedance_1p5_pro::{
|
||||
FalSeedance1p5ProAspectRatio, FalSeedance1p5ProDuration, FalSeedance1p5ProMode,
|
||||
FalSeedance1p5ProResolution, PlanFalSeedance1p5Pro,
|
||||
};
|
||||
use fal_client::requests::webhook::video::image::enqueue_seedance_1p5_pro_image_to_video_webhook::{
|
||||
enqueue_seedance_1p5_pro_image_to_video_webhook, EnqueueSeedance1p5ProImageToVideoArgs,
|
||||
EnqueueSeedance1p5ProImageToVideoAspectRatio, EnqueueSeedance1p5ProImageToVideoDuration,
|
||||
EnqueueSeedance1p5ProImageToVideoResolution,
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_seedance_1p5_pro_text_to_video_webhook::{
|
||||
enqueue_seedance_1p5_pro_text_to_video_webhook, EnqueueSeedance1p5ProTextToVideoArgs,
|
||||
EnqueueSeedance1p5ProTextToVideoAspectRatio, EnqueueSeedance1p5ProTextToVideoDuration,
|
||||
EnqueueSeedance1p5ProTextToVideoResolution,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_seedance_1p5_pro(
|
||||
plan: &PlanFalSeedance1p5Pro,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let webhook_response = match &plan.mode {
|
||||
FalSeedance1p5ProMode::TextToVideo => {
|
||||
let args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
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,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_seedance_1p5_pro_text_to_video_webhook(args).await
|
||||
}
|
||||
FalSeedance1p5ProMode::ImageToVideo { image_url, end_image_url } => {
|
||||
let args = EnqueueSeedance1p5ProImageToVideoArgs {
|
||||
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,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_seedance_1p5_pro_image_to_video_webhook(args).await
|
||||
}
|
||||
};
|
||||
|
||||
let webhook_response = webhook_response
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
|
||||
fn to_t2v_resolution(r: FalSeedance1p5ProResolution) -> EnqueueSeedance1p5ProTextToVideoResolution {
|
||||
match r {
|
||||
FalSeedance1p5ProResolution::FourEightyP => EnqueueSeedance1p5ProTextToVideoResolution::FourEightyP,
|
||||
FalSeedance1p5ProResolution::SevenTwentyP => EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP,
|
||||
FalSeedance1p5ProResolution::TenEightyP => EnqueueSeedance1p5ProTextToVideoResolution::TenEightyP,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_duration(d: FalSeedance1p5ProDuration) -> EnqueueSeedance1p5ProTextToVideoDuration {
|
||||
use EnqueueSeedance1p5ProTextToVideoDuration as T;
|
||||
match d {
|
||||
FalSeedance1p5ProDuration::Four => T::FourSeconds,
|
||||
FalSeedance1p5ProDuration::Five => T::FiveSeconds,
|
||||
FalSeedance1p5ProDuration::Six => T::SixSeconds,
|
||||
FalSeedance1p5ProDuration::Seven => T::SevenSeconds,
|
||||
FalSeedance1p5ProDuration::Eight => T::EightSeconds,
|
||||
FalSeedance1p5ProDuration::Nine => T::NineSeconds,
|
||||
FalSeedance1p5ProDuration::Ten => T::TenSeconds,
|
||||
FalSeedance1p5ProDuration::Eleven => T::ElevenSeconds,
|
||||
FalSeedance1p5ProDuration::Twelve => T::TwelveSeconds,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_aspect_ratio(a: FalSeedance1p5ProAspectRatio) -> EnqueueSeedance1p5ProTextToVideoAspectRatio {
|
||||
use EnqueueSeedance1p5ProTextToVideoAspectRatio as T;
|
||||
match a {
|
||||
FalSeedance1p5ProAspectRatio::Auto => T::Auto,
|
||||
FalSeedance1p5ProAspectRatio::TwentyOneByNine => T::TwentyOneByNine,
|
||||
FalSeedance1p5ProAspectRatio::SixteenByNine => T::SixteenByNine,
|
||||
FalSeedance1p5ProAspectRatio::FourByThree => T::FourByThree,
|
||||
FalSeedance1p5ProAspectRatio::Square => T::Square,
|
||||
FalSeedance1p5ProAspectRatio::ThreeByFour => T::ThreeByFour,
|
||||
FalSeedance1p5ProAspectRatio::NineBySixteen => T::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_resolution(r: FalSeedance1p5ProResolution) -> EnqueueSeedance1p5ProImageToVideoResolution {
|
||||
match r {
|
||||
FalSeedance1p5ProResolution::FourEightyP => EnqueueSeedance1p5ProImageToVideoResolution::FourEightyP,
|
||||
FalSeedance1p5ProResolution::SevenTwentyP => EnqueueSeedance1p5ProImageToVideoResolution::SevenTwentyP,
|
||||
FalSeedance1p5ProResolution::TenEightyP => EnqueueSeedance1p5ProImageToVideoResolution::TenEightyP,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_duration(d: FalSeedance1p5ProDuration) -> EnqueueSeedance1p5ProImageToVideoDuration {
|
||||
use EnqueueSeedance1p5ProImageToVideoDuration as T;
|
||||
match d {
|
||||
FalSeedance1p5ProDuration::Four => T::FourSeconds,
|
||||
FalSeedance1p5ProDuration::Five => T::FiveSeconds,
|
||||
FalSeedance1p5ProDuration::Six => T::SixSeconds,
|
||||
FalSeedance1p5ProDuration::Seven => T::SevenSeconds,
|
||||
FalSeedance1p5ProDuration::Eight => T::EightSeconds,
|
||||
FalSeedance1p5ProDuration::Nine => T::NineSeconds,
|
||||
FalSeedance1p5ProDuration::Ten => T::TenSeconds,
|
||||
FalSeedance1p5ProDuration::Eleven => T::ElevenSeconds,
|
||||
FalSeedance1p5ProDuration::Twelve => T::TwelveSeconds,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_aspect_ratio(a: FalSeedance1p5ProAspectRatio) -> EnqueueSeedance1p5ProImageToVideoAspectRatio {
|
||||
use EnqueueSeedance1p5ProImageToVideoAspectRatio as T;
|
||||
match a {
|
||||
FalSeedance1p5ProAspectRatio::Auto => T::Auto,
|
||||
FalSeedance1p5ProAspectRatio::TwentyOneByNine => T::TwentyOneByNine,
|
||||
FalSeedance1p5ProAspectRatio::SixteenByNine => T::SixteenByNine,
|
||||
FalSeedance1p5ProAspectRatio::FourByThree => T::FourByThree,
|
||||
FalSeedance1p5ProAspectRatio::Square => T::Square,
|
||||
FalSeedance1p5ProAspectRatio::ThreeByFour => T::ThreeByFour,
|
||||
FalSeedance1p5ProAspectRatio::NineBySixteen => T::NineBySixteen,
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_sora_2::{
|
||||
FalSora2AspectRatio, FalSora2Duration, FalSora2Mode, FalSora2Resolution, PlanFalSora2,
|
||||
};
|
||||
use fal_client::requests::webhook::video::image::enqueue_sora_2_image_to_video_webhook::{
|
||||
enqueue_sora_2_image_to_video_webhook, EnqueueSora2ImageToVideoArgs,
|
||||
EnqueueSora2ImageToVideoAspectRatio, EnqueueSora2ImageToVideoDurationSeconds,
|
||||
EnqueueSora2ImageToVideoResolution,
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_sora_2_text_to_video_webhook::{
|
||||
enqueue_sora_2_text_to_video_webhook, EnqueueSora2TextToVideoArgs,
|
||||
EnqueueSora2TextToVideoAspectRatio, EnqueueSora2TextToVideoDurationSeconds,
|
||||
EnqueueSora2TextToVideoResolution,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_sora_2(
|
||||
plan: &PlanFalSora2,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let webhook_response = match &plan.mode {
|
||||
FalSora2Mode::TextToVideo => {
|
||||
// Text-to-video does not support Auto aspect ratio or Auto resolution.
|
||||
let args = EnqueueSora2TextToVideoArgs {
|
||||
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),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_sora_2_text_to_video_webhook(args).await
|
||||
}
|
||||
FalSora2Mode::ImageToVideo { image_url } => {
|
||||
let args = EnqueueSora2ImageToVideoArgs {
|
||||
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),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_sora_2_image_to_video_webhook(args).await
|
||||
}
|
||||
};
|
||||
|
||||
let webhook_response = webhook_response
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
|
||||
fn to_t2v_duration(d: FalSora2Duration) -> EnqueueSora2TextToVideoDurationSeconds {
|
||||
match d {
|
||||
FalSora2Duration::Four => EnqueueSora2TextToVideoDurationSeconds::Four,
|
||||
FalSora2Duration::Eight => EnqueueSora2TextToVideoDurationSeconds::Eight,
|
||||
FalSora2Duration::Twelve => EnqueueSora2TextToVideoDurationSeconds::Twelve,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_resolution(r: FalSora2Resolution) -> Option<EnqueueSora2TextToVideoResolution> {
|
||||
match r {
|
||||
FalSora2Resolution::SevenTwentyP => Some(EnqueueSora2TextToVideoResolution::SevenTwentyP),
|
||||
FalSora2Resolution::Auto => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_aspect_ratio(a: FalSora2AspectRatio) -> Option<EnqueueSora2TextToVideoAspectRatio> {
|
||||
match a {
|
||||
FalSora2AspectRatio::SixteenByNine => Some(EnqueueSora2TextToVideoAspectRatio::SixteenByNine),
|
||||
FalSora2AspectRatio::NineBySixteen => Some(EnqueueSora2TextToVideoAspectRatio::NineBySixteen),
|
||||
FalSora2AspectRatio::Auto => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_duration(d: FalSora2Duration) -> EnqueueSora2ImageToVideoDurationSeconds {
|
||||
match d {
|
||||
FalSora2Duration::Four => EnqueueSora2ImageToVideoDurationSeconds::Four,
|
||||
FalSora2Duration::Eight => EnqueueSora2ImageToVideoDurationSeconds::Eight,
|
||||
FalSora2Duration::Twelve => EnqueueSora2ImageToVideoDurationSeconds::Twelve,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_resolution(r: FalSora2Resolution) -> EnqueueSora2ImageToVideoResolution {
|
||||
match r {
|
||||
FalSora2Resolution::SevenTwentyP => EnqueueSora2ImageToVideoResolution::SevenTwentyP,
|
||||
FalSora2Resolution::Auto => EnqueueSora2ImageToVideoResolution::Auto,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_aspect_ratio(a: FalSora2AspectRatio) -> EnqueueSora2ImageToVideoAspectRatio {
|
||||
match a {
|
||||
FalSora2AspectRatio::SixteenByNine => EnqueueSora2ImageToVideoAspectRatio::SixteenByNine,
|
||||
FalSora2AspectRatio::NineBySixteen => EnqueueSora2ImageToVideoAspectRatio::NineBySixteen,
|
||||
FalSora2AspectRatio::Auto => EnqueueSora2ImageToVideoAspectRatio::Auto,
|
||||
}
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_sora_2_pro::{
|
||||
FalSora2ProAspectRatio, FalSora2ProDuration, FalSora2ProMode, FalSora2ProResolution,
|
||||
PlanFalSora2Pro,
|
||||
};
|
||||
use fal_client::requests::webhook::video::image::enqueue_sora_2_pro_image_to_video_webhook::{
|
||||
enqueue_sora_2_pro_image_to_video_webhook, EnqueueSora2ProImageToVideoArgs,
|
||||
EnqueueSora2ProImageToVideoAspectRatio, EnqueueSora2ProImageToVideoDurationSeconds,
|
||||
EnqueueSora2ProImageToVideoResolution,
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_sora_2_pro_text_to_video_webhook::{
|
||||
enqueue_sora_2_pro_text_to_video_webhook, EnqueueSora2ProTextToVideoArgs,
|
||||
EnqueueSora2ProTextToVideoAspectRatio, EnqueueSora2ProTextToVideoDurationSeconds,
|
||||
EnqueueSora2ProTextToVideoResolution,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_sora_2_pro(
|
||||
plan: &PlanFalSora2Pro,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let webhook_response = match &plan.mode {
|
||||
FalSora2ProMode::TextToVideo => {
|
||||
// Text-to-video does not support Auto aspect ratio or Auto resolution.
|
||||
let args = EnqueueSora2ProTextToVideoArgs {
|
||||
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),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_sora_2_pro_text_to_video_webhook(args).await
|
||||
}
|
||||
FalSora2ProMode::ImageToVideo { image_url } => {
|
||||
let args = EnqueueSora2ProImageToVideoArgs {
|
||||
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),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_sora_2_pro_image_to_video_webhook(args).await
|
||||
}
|
||||
};
|
||||
|
||||
let webhook_response = webhook_response
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
|
||||
fn to_t2v_duration(d: FalSora2ProDuration) -> EnqueueSora2ProTextToVideoDurationSeconds {
|
||||
match d {
|
||||
FalSora2ProDuration::Four => EnqueueSora2ProTextToVideoDurationSeconds::Four,
|
||||
FalSora2ProDuration::Eight => EnqueueSora2ProTextToVideoDurationSeconds::Eight,
|
||||
FalSora2ProDuration::Twelve => EnqueueSora2ProTextToVideoDurationSeconds::Twelve,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_resolution(r: FalSora2ProResolution) -> Option<EnqueueSora2ProTextToVideoResolution> {
|
||||
match r {
|
||||
FalSora2ProResolution::SevenTwentyP => Some(EnqueueSora2ProTextToVideoResolution::SevenTwentyP),
|
||||
FalSora2ProResolution::TenEightyP => Some(EnqueueSora2ProTextToVideoResolution::TenEightyP),
|
||||
FalSora2ProResolution::Auto => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_aspect_ratio(a: FalSora2ProAspectRatio) -> Option<EnqueueSora2ProTextToVideoAspectRatio> {
|
||||
match a {
|
||||
FalSora2ProAspectRatio::SixteenByNine => Some(EnqueueSora2ProTextToVideoAspectRatio::SixteenByNine),
|
||||
FalSora2ProAspectRatio::NineBySixteen => Some(EnqueueSora2ProTextToVideoAspectRatio::NineBySixteen),
|
||||
FalSora2ProAspectRatio::Auto => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_duration(d: FalSora2ProDuration) -> EnqueueSora2ProImageToVideoDurationSeconds {
|
||||
match d {
|
||||
FalSora2ProDuration::Four => EnqueueSora2ProImageToVideoDurationSeconds::Four,
|
||||
FalSora2ProDuration::Eight => EnqueueSora2ProImageToVideoDurationSeconds::Eight,
|
||||
FalSora2ProDuration::Twelve => EnqueueSora2ProImageToVideoDurationSeconds::Twelve,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_resolution(r: FalSora2ProResolution) -> EnqueueSora2ProImageToVideoResolution {
|
||||
match r {
|
||||
FalSora2ProResolution::Auto => EnqueueSora2ProImageToVideoResolution::Auto,
|
||||
FalSora2ProResolution::SevenTwentyP => EnqueueSora2ProImageToVideoResolution::SevenTwentyP,
|
||||
FalSora2ProResolution::TenEightyP => EnqueueSora2ProImageToVideoResolution::TenEightyP,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_aspect_ratio(a: FalSora2ProAspectRatio) -> EnqueueSora2ProImageToVideoAspectRatio {
|
||||
match a {
|
||||
FalSora2ProAspectRatio::Auto => EnqueueSora2ProImageToVideoAspectRatio::Auto,
|
||||
FalSora2ProAspectRatio::SixteenByNine => EnqueueSora2ProImageToVideoAspectRatio::SixteenByNine,
|
||||
FalSora2ProAspectRatio::NineBySixteen => EnqueueSora2ProImageToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_2::PlanFalVeo2;
|
||||
use fal_client::requests::webhook::video::image::enqueue_veo_2_image_to_video_webhook::{
|
||||
enqueue_veo_2_image_to_video_webhook, Veo2Args,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_veo_2(
|
||||
plan: &PlanFalVeo2,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let args = Veo2Args {
|
||||
image_url: plan.start_frame_url.as_str(),
|
||||
prompt: plan.prompt.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
};
|
||||
|
||||
let webhook_response = enqueue_veo_2_image_to_video_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_3::PlanFalVeo3;
|
||||
use fal_client::requests::webhook::video::image::enqueue_veo_3_image_to_video_webhook::{
|
||||
enqueue_veo_3_image_to_video_webhook, Veo3Args,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_veo_3(
|
||||
plan: &PlanFalVeo3,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let args = Veo3Args {
|
||||
image_url: plan.start_frame_url.as_str(),
|
||||
prompt: plan.prompt.as_str(),
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio,
|
||||
resolution: plan.resolution,
|
||||
generate_audio: plan.generate_audio,
|
||||
api_key: &fal_client.api_key,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
};
|
||||
|
||||
let webhook_response = enqueue_veo_3_image_to_video_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_3_fast::PlanFalVeo3Fast;
|
||||
use fal_client::requests::webhook::video::image::enqueue_veo_3_fast_image_to_video_webhook::{
|
||||
enqueue_veo_3_fast_image_to_video_webhook, Veo3FastArgs,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_veo_3_fast(
|
||||
plan: &PlanFalVeo3Fast,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let args = Veo3FastArgs {
|
||||
prompt: plan.prompt.as_str(),
|
||||
image_url: plan.start_frame_url.as_str(),
|
||||
duration: plan.duration,
|
||||
api_key: &fal_client.api_key,
|
||||
resolution: plan.resolution,
|
||||
generate_audio: plan.generate_audio,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
};
|
||||
|
||||
let webhook_response = enqueue_veo_3_fast_image_to_video_webhook(args)
|
||||
.await
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_3p1::{
|
||||
FalVeo3p1AspectRatio, FalVeo3p1Duration, FalVeo3p1Mode, FalVeo3p1Resolution, PlanFalVeo3p1,
|
||||
};
|
||||
use fal_client::requests::webhook::video::image::enqueue_veo_3p1_first_last_frame_image_to_video_webhook::{
|
||||
enqueue_veo_3p1_first_last_frame_image_to_video_webhook,
|
||||
EnqueueVeo3p1FirstLastFrameImageToVideoArgs,
|
||||
EnqueueVeo3p1FirstLastFrameImageToVideoAspectRatio,
|
||||
EnqueueVeo3p1FirstLastFrameImageToVideoDurationSeconds,
|
||||
EnqueueVeo3p1FirstLastFrameImageToVideoResolution,
|
||||
};
|
||||
use fal_client::requests::webhook::video::image::enqueue_veo_3p1_image_to_video_webhook::{
|
||||
enqueue_veo_3p1_image_to_video_webhook, EnqueueVeo3p1ImageToVideoArgs,
|
||||
EnqueueVeo3p1ImageToVideoAspectRatio, EnqueueVeo3p1ImageToVideoDurationSeconds,
|
||||
EnqueueVeo3p1ImageToVideoResolution,
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_veo_3p1_text_to_video_webhook::{
|
||||
enqueue_veo_3p1_text_to_video_webhook, EnqueueVeo3p1TextToVideoArgs,
|
||||
EnqueueVeo3p1TextToVideoAspectRatio, EnqueueVeo3p1TextToVideoDurationSeconds,
|
||||
EnqueueVeo3p1TextToVideoResolution,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_veo_3p1(
|
||||
plan: &PlanFalVeo3p1,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let webhook_response = match &plan.mode {
|
||||
FalVeo3p1Mode::TextToVideo => {
|
||||
let args = EnqueueVeo3p1TextToVideoArgs {
|
||||
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,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_veo_3p1_text_to_video_webhook(args).await
|
||||
}
|
||||
FalVeo3p1Mode::ImageToVideo { start_frame_url } => {
|
||||
let args = EnqueueVeo3p1ImageToVideoArgs {
|
||||
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,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_veo_3p1_image_to_video_webhook(args).await
|
||||
}
|
||||
FalVeo3p1Mode::FirstLastFrame { first_frame_url, last_frame_url } => {
|
||||
let args = EnqueueVeo3p1FirstLastFrameImageToVideoArgs {
|
||||
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,
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
let webhook_response = webhook_response
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
|
||||
fn to_t2v_duration(d: FalVeo3p1Duration) -> EnqueueVeo3p1TextToVideoDurationSeconds {
|
||||
match d {
|
||||
FalVeo3p1Duration::Four => EnqueueVeo3p1TextToVideoDurationSeconds::Four,
|
||||
FalVeo3p1Duration::Six => EnqueueVeo3p1TextToVideoDurationSeconds::Six,
|
||||
FalVeo3p1Duration::Eight => EnqueueVeo3p1TextToVideoDurationSeconds::Eight,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_aspect_ratio(a: FalVeo3p1AspectRatio) -> EnqueueVeo3p1TextToVideoAspectRatio {
|
||||
match a {
|
||||
FalVeo3p1AspectRatio::Auto => EnqueueVeo3p1TextToVideoAspectRatio::Auto,
|
||||
FalVeo3p1AspectRatio::SixteenByNine => EnqueueVeo3p1TextToVideoAspectRatio::SixteenByNine,
|
||||
FalVeo3p1AspectRatio::NineBySixteen => EnqueueVeo3p1TextToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_resolution(r: FalVeo3p1Resolution) -> EnqueueVeo3p1TextToVideoResolution {
|
||||
match r {
|
||||
FalVeo3p1Resolution::SevenTwentyP => EnqueueVeo3p1TextToVideoResolution::SevenTwentyP,
|
||||
FalVeo3p1Resolution::TenEightyP => EnqueueVeo3p1TextToVideoResolution::TenEightyP,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_duration(d: FalVeo3p1Duration) -> EnqueueVeo3p1ImageToVideoDurationSeconds {
|
||||
match d {
|
||||
FalVeo3p1Duration::Four => EnqueueVeo3p1ImageToVideoDurationSeconds::Four,
|
||||
FalVeo3p1Duration::Six => EnqueueVeo3p1ImageToVideoDurationSeconds::Six,
|
||||
FalVeo3p1Duration::Eight => EnqueueVeo3p1ImageToVideoDurationSeconds::Eight,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_aspect_ratio(a: FalVeo3p1AspectRatio) -> EnqueueVeo3p1ImageToVideoAspectRatio {
|
||||
match a {
|
||||
FalVeo3p1AspectRatio::Auto => EnqueueVeo3p1ImageToVideoAspectRatio::Auto,
|
||||
FalVeo3p1AspectRatio::SixteenByNine => EnqueueVeo3p1ImageToVideoAspectRatio::SixteenByNine,
|
||||
FalVeo3p1AspectRatio::NineBySixteen => EnqueueVeo3p1ImageToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_resolution(r: FalVeo3p1Resolution) -> EnqueueVeo3p1ImageToVideoResolution {
|
||||
match r {
|
||||
FalVeo3p1Resolution::SevenTwentyP => EnqueueVeo3p1ImageToVideoResolution::SevenTwentyP,
|
||||
FalVeo3p1Resolution::TenEightyP => EnqueueVeo3p1ImageToVideoResolution::TenEightyP,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_flf_duration(d: FalVeo3p1Duration) -> EnqueueVeo3p1FirstLastFrameImageToVideoDurationSeconds {
|
||||
match d {
|
||||
FalVeo3p1Duration::Four => EnqueueVeo3p1FirstLastFrameImageToVideoDurationSeconds::Four,
|
||||
FalVeo3p1Duration::Six => EnqueueVeo3p1FirstLastFrameImageToVideoDurationSeconds::Six,
|
||||
FalVeo3p1Duration::Eight => EnqueueVeo3p1FirstLastFrameImageToVideoDurationSeconds::Eight,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_flf_aspect_ratio(a: FalVeo3p1AspectRatio) -> EnqueueVeo3p1FirstLastFrameImageToVideoAspectRatio {
|
||||
match a {
|
||||
FalVeo3p1AspectRatio::Auto => EnqueueVeo3p1FirstLastFrameImageToVideoAspectRatio::Auto,
|
||||
FalVeo3p1AspectRatio::SixteenByNine => EnqueueVeo3p1FirstLastFrameImageToVideoAspectRatio::SixteenByNine,
|
||||
FalVeo3p1AspectRatio::NineBySixteen => EnqueueVeo3p1FirstLastFrameImageToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_flf_resolution(r: FalVeo3p1Resolution) -> EnqueueVeo3p1FirstLastFrameImageToVideoResolution {
|
||||
match r {
|
||||
FalVeo3p1Resolution::SevenTwentyP => EnqueueVeo3p1FirstLastFrameImageToVideoResolution::SevenTwentyP,
|
||||
FalVeo3p1Resolution::TenEightyP => EnqueueVeo3p1FirstLastFrameImageToVideoResolution::TenEightyP,
|
||||
}
|
||||
}
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video_response::{
|
||||
FalVideoResponsePayload, GenerateVideoResponse,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_3p1::{
|
||||
FalVeo3p1AspectRatio, FalVeo3p1Duration, FalVeo3p1Mode, FalVeo3p1Resolution,
|
||||
};
|
||||
use crate::generate::generate_video::plan::fal::plan_generate_video_fal_veo_3p1_fast::PlanFalVeo3p1Fast;
|
||||
use fal_client::requests::webhook::video::image::enqueue_veo_3p1_fast_first_last_frame_image_to_video_webhook::{
|
||||
enqueue_veo_3p1_fast_first_last_frame_image_to_video_webhook,
|
||||
EnqueueVeo3p1FastFirstLastFrameImageToVideoArgs,
|
||||
EnqueueVeo3p1FastFirstLastFrameImageToVideoAspectRatio,
|
||||
EnqueueVeo3p1FastFirstLastFrameImageToVideoDurationSeconds,
|
||||
EnqueueVeo3p1FastFirstLastFrameImageToVideoResolution,
|
||||
};
|
||||
use fal_client::requests::webhook::video::image::enqueue_veo_3p1_fast_image_to_video_webhook::{
|
||||
enqueue_veo_3p1_fast_image_to_video_webhook, EnqueueVeo3p1FastImageToVideoArgs,
|
||||
EnqueueVeo3p1FastImageToVideoAspectRatio, EnqueueVeo3p1FastImageToVideoDurationSeconds,
|
||||
EnqueueVeo3p1FastImageToVideoResolution,
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_veo_3p1_fast_text_to_video_webhook::{
|
||||
enqueue_veo_3p1_fast_text_to_video_webhook, EnqueueVeo3p1FastTextToVideoArgs,
|
||||
EnqueueVeo3p1FastTextToVideoAspectRatio, EnqueueVeo3p1FastTextToVideoDurationSeconds,
|
||||
EnqueueVeo3p1FastTextToVideoResolution,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_veo_3p1_fast(
|
||||
plan: &PlanFalVeo3p1Fast,
|
||||
fal_client: &RouterFalClient,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let inner = &plan.inner;
|
||||
|
||||
let webhook_response = match &inner.mode {
|
||||
FalVeo3p1Mode::TextToVideo => {
|
||||
let args = EnqueueVeo3p1FastTextToVideoArgs {
|
||||
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,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_veo_3p1_fast_text_to_video_webhook(args).await
|
||||
}
|
||||
FalVeo3p1Mode::ImageToVideo { start_frame_url } => {
|
||||
let args = EnqueueVeo3p1FastImageToVideoArgs {
|
||||
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,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
enqueue_veo_3p1_fast_image_to_video_webhook(args).await
|
||||
}
|
||||
FalVeo3p1Mode::FirstLastFrame { first_frame_url, last_frame_url } => {
|
||||
let args = EnqueueVeo3p1FastFirstLastFrameImageToVideoArgs {
|
||||
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,
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
let webhook_response = webhook_response
|
||||
.map_err(|e| ArtcraftRouterError::Provider(ProviderError::Fal(e)))?;
|
||||
|
||||
Ok(GenerateVideoResponse::Fal(FalVideoResponsePayload {
|
||||
request_id: webhook_response.request_id,
|
||||
gateway_request_id: webhook_response.gateway_request_id,
|
||||
}))
|
||||
}
|
||||
|
||||
fn to_t2v_duration(d: FalVeo3p1Duration) -> EnqueueVeo3p1FastTextToVideoDurationSeconds {
|
||||
match d {
|
||||
FalVeo3p1Duration::Four => EnqueueVeo3p1FastTextToVideoDurationSeconds::Four,
|
||||
FalVeo3p1Duration::Six => EnqueueVeo3p1FastTextToVideoDurationSeconds::Six,
|
||||
FalVeo3p1Duration::Eight => EnqueueVeo3p1FastTextToVideoDurationSeconds::Eight,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_aspect_ratio(a: FalVeo3p1AspectRatio) -> EnqueueVeo3p1FastTextToVideoAspectRatio {
|
||||
match a {
|
||||
FalVeo3p1AspectRatio::Auto => EnqueueVeo3p1FastTextToVideoAspectRatio::Auto,
|
||||
FalVeo3p1AspectRatio::SixteenByNine => EnqueueVeo3p1FastTextToVideoAspectRatio::SixteenByNine,
|
||||
FalVeo3p1AspectRatio::NineBySixteen => EnqueueVeo3p1FastTextToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_t2v_resolution(r: FalVeo3p1Resolution) -> EnqueueVeo3p1FastTextToVideoResolution {
|
||||
match r {
|
||||
FalVeo3p1Resolution::SevenTwentyP => EnqueueVeo3p1FastTextToVideoResolution::SevenTwentyP,
|
||||
FalVeo3p1Resolution::TenEightyP => EnqueueVeo3p1FastTextToVideoResolution::TenEightyP,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_duration(d: FalVeo3p1Duration) -> EnqueueVeo3p1FastImageToVideoDurationSeconds {
|
||||
match d {
|
||||
FalVeo3p1Duration::Four => EnqueueVeo3p1FastImageToVideoDurationSeconds::Four,
|
||||
FalVeo3p1Duration::Six => EnqueueVeo3p1FastImageToVideoDurationSeconds::Six,
|
||||
FalVeo3p1Duration::Eight => EnqueueVeo3p1FastImageToVideoDurationSeconds::Eight,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_aspect_ratio(a: FalVeo3p1AspectRatio) -> EnqueueVeo3p1FastImageToVideoAspectRatio {
|
||||
match a {
|
||||
FalVeo3p1AspectRatio::Auto => EnqueueVeo3p1FastImageToVideoAspectRatio::Auto,
|
||||
FalVeo3p1AspectRatio::SixteenByNine => EnqueueVeo3p1FastImageToVideoAspectRatio::SixteenByNine,
|
||||
FalVeo3p1AspectRatio::NineBySixteen => EnqueueVeo3p1FastImageToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_i2v_resolution(r: FalVeo3p1Resolution) -> EnqueueVeo3p1FastImageToVideoResolution {
|
||||
match r {
|
||||
FalVeo3p1Resolution::SevenTwentyP => EnqueueVeo3p1FastImageToVideoResolution::SevenTwentyP,
|
||||
FalVeo3p1Resolution::TenEightyP => EnqueueVeo3p1FastImageToVideoResolution::TenEightyP,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_flf_duration(d: FalVeo3p1Duration) -> EnqueueVeo3p1FastFirstLastFrameImageToVideoDurationSeconds {
|
||||
match d {
|
||||
FalVeo3p1Duration::Four => EnqueueVeo3p1FastFirstLastFrameImageToVideoDurationSeconds::Four,
|
||||
FalVeo3p1Duration::Six => EnqueueVeo3p1FastFirstLastFrameImageToVideoDurationSeconds::Six,
|
||||
FalVeo3p1Duration::Eight => EnqueueVeo3p1FastFirstLastFrameImageToVideoDurationSeconds::Eight,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_flf_aspect_ratio(a: FalVeo3p1AspectRatio) -> EnqueueVeo3p1FastFirstLastFrameImageToVideoAspectRatio {
|
||||
match a {
|
||||
FalVeo3p1AspectRatio::Auto => EnqueueVeo3p1FastFirstLastFrameImageToVideoAspectRatio::Auto,
|
||||
FalVeo3p1AspectRatio::SixteenByNine => EnqueueVeo3p1FastFirstLastFrameImageToVideoAspectRatio::SixteenByNine,
|
||||
FalVeo3p1AspectRatio::NineBySixteen => EnqueueVeo3p1FastFirstLastFrameImageToVideoAspectRatio::NineBySixteen,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_flf_resolution(r: FalVeo3p1Resolution) -> EnqueueVeo3p1FastFirstLastFrameImageToVideoResolution {
|
||||
match r {
|
||||
FalVeo3p1Resolution::SevenTwentyP => EnqueueVeo3p1FastFirstLastFrameImageToVideoResolution::SevenTwentyP,
|
||||
FalVeo3p1Resolution::TenEightyP => EnqueueVeo3p1FastFirstLastFrameImageToVideoResolution::TenEightyP,
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
pub mod generate_video_fal_kling_1_6_pro;
|
||||
pub mod generate_video_fal_kling_2_1_master;
|
||||
pub mod generate_video_fal_kling_2_1_pro;
|
||||
pub mod generate_video_fal_kling_2_5_turbo_pro;
|
||||
pub mod generate_video_fal_kling_2_6_pro;
|
||||
pub mod generate_video_fal_kling_3p0_pro;
|
||||
pub mod generate_video_fal_kling_3p0_standard;
|
||||
pub mod generate_video_fal_seedance_1_0_lite;
|
||||
pub mod generate_video_fal_seedance_1p5_pro;
|
||||
pub mod generate_video_fal_sora_2;
|
||||
pub mod generate_video_fal_sora_2_pro;
|
||||
pub mod generate_video_fal_veo_2;
|
||||
pub mod generate_video_fal_veo_3;
|
||||
pub mod generate_video_fal_veo_3_fast;
|
||||
pub mod generate_video_fal_veo_3p1;
|
||||
pub mod generate_video_fal_veo_3p1_fast;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user