This commit is contained in:
Brandon Thomas committed 2026-04-21 01:47:02 -04:00
1 parent 130f8243d6
commit f7329031e6
7 files changed
+92 -44

No files matched your search

@@ -114,6 +114,14 @@ pub struct GenerateVideoRequestBuilder {
}
impl GenerateVideoRequestBuilder {
pub fn use_new_builder(&self) -> bool {
match (self.provider, self.model) {
(Provider::Seedance2Pro, CommonVideoModel::Seedance2p0) => true,
_ => false,
}
}
// New builder (transitional state)
pub fn build2(self) -> Result<VideoGenerationDraftOrRequest, ArtcraftRouterError> {
match (self.provider, self.model) {
@@ -121,7 +129,7 @@ impl GenerateVideoRequestBuilder {
_ => self.unsupported_provider_and_model(),
}
}
/// Read the video generation request, construct a plan, then yield a means to execute it.
pub fn build(&self) -> Result<VideoGenerationPlan, ArtcraftRouterError> {
match self.provider {
@@ -1,5 +1,5 @@
/// The result of estimating the cost of a video generation plan.
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct VideoGenerationCostEstimate {
pub cost_in_credits: Option<u64>,
pub cost_in_usd_cents: Option<u64>,
@@ -0,0 +1,70 @@
use seedance2pro_client::requests::generate_video::generate_video::{KinoviAspectRatio, KinoviBatchCount, KinoviGenerateVideoRequest, KinoviModelType, KinoviOutputResolution};
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
use crate::generate::generate_video_v2::providers::kinovi::seedance_2p0::draft::KinoviSeedance2p0DraftState;
use crate::generate::generate_video_v2::providers::kinovi::seedance_2p0::request::KinoviSeedance2p0RequestState;
pub struct KinoviSeedance2p0CostState {
pub resolution: KinoviOutputResolution,
pub duration_seconds: u8,
pub batch_count: KinoviBatchCount,
pub has_video_reference: bool,
}
impl KinoviSeedance2p0CostState {
pub fn from_request(request: &KinoviSeedance2p0RequestState) -> Self {
Self {
resolution: request.request.output_resolution.unwrap_or(KinoviOutputResolution::SevenTwentyP),
duration_seconds: request.request.duration_seconds,
batch_count: request.request.batch_count,
has_video_reference: request.request.reference_video_urls.is_some(),
}
}
pub fn from_draft(draft: &KinoviSeedance2p0DraftState) -> Self {
Self {
resolution: draft.resolution.unwrap_or(KinoviOutputResolution::SevenTwentyP),
duration_seconds: draft.duration_seconds,
batch_count: draft.batch_count,
has_video_reference: draft.remaining_request
.as_ref()
.map(|rem| &rem.reference_videos)
.is_some(),
}
}
pub fn estimate_cost(&self) -> VideoGenerationCostEstimate {
let request = KinoviGenerateVideoRequest {
// Pricing factors
model_type: KinoviModelType::Seedance2Pro,
output_resolution: Some(self.resolution),
duration_seconds: self.duration_seconds,
batch_count: self.batch_count,
reference_video_urls: if self.has_video_reference {
Some(vec!["https://example.com".to_string()])
} else {
None
},
// No impact on price
prompt: "".to_string(),
aspect_ratio: KinoviAspectRatio::Portrait9x16,
start_frame_url: None,
end_frame_url: None,
reference_image_urls: None,
reference_audio_urls: None,
character_ids: None,
use_face_blur_hack: None,
};
let cost_in_credits = request.estimate_credits();
let cost_in_usd_cents = request.estimate_cost_in_usd_cents();
VideoGenerationCostEstimate {
cost_in_credits: Some(cost_in_credits as u64),
cost_in_usd_cents: Some(cost_in_usd_cents),
is_free: false,
is_unlimited: false,
is_rate_limited: false,
has_watermark: false,
}
}
}
@@ -1,9 +1,5 @@
use crate::errors::artcraft_router_error::ArtcraftRouterError;
use crate::generate::generate_video::generate_video_request_builder::GenerateVideoRequestBuilder;
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
use crate::generate::generate_video_v2::providers::kinovi::seedance_2p0::type_conversions::{map_common_resolution_to_kinovi, plan_aspect_ratio, plan_batch_count, plan_duration};
use crate::generate::generate_video_v2::video_generation_draft::VideoGenerationDraftRequest;
use seedance2pro_client::requests::generate_video::generate_video::{KinoviAspectRatio, KinoviBatchCount, KinoviGenerateVideoRequest, KinoviModelType, KinoviOutputResolution};
use seedance2pro_client::requests::generate_video::generate_video::{KinoviAspectRatio, KinoviBatchCount, KinoviOutputResolution};
#[derive(Debug, Clone)]
pub struct KinoviSeedance2p0DraftState {
@@ -34,36 +30,3 @@ pub struct KinoviSeedance2p0DraftState {
// pub reference_audio: Option<AudioListRef>,
// pub reference_character_tokens: Option<CharacterListRef>,
}
impl KinoviSeedance2p0DraftState {
pub fn estimate_cost(&self) -> VideoGenerationCostEstimate {
let request = KinoviGenerateVideoRequest {
model_type: KinoviModelType::Seedance2Pro,
prompt: self.prompt.clone(),
aspect_ratio: self.aspect_ratio,
output_resolution: self.resolution,
duration_seconds: self.duration_seconds,
batch_count: self.batch_count,
start_frame_url: None, // TODO
end_frame_url: None, // TODO
reference_image_urls: None, // TODO
reference_video_urls: None, // TODO
reference_audio_urls: None, // TODO
character_ids: None, // TODO
use_face_blur_hack: None,
};
let cost_in_credits = request.estimate_credits();
let cost_in_usd_cents = request.estimate_cost_in_usd_cents();
VideoGenerationCostEstimate {
cost_in_credits: Some(cost_in_credits as u64),
cost_in_usd_cents: Some(cost_in_usd_cents),
is_free: false,
is_unlimited: false,
is_rate_limited: false,
has_watermark: false,
}
}
}
@@ -1,4 +1,5 @@
pub mod build;
pub (super) mod type_conversions;
pub mod draft;
pub mod request;
pub mod request;
pub mod cost;
@@ -1,6 +1,7 @@
use crate::client::router_client::RouterClient;
use crate::errors::artcraft_router_error::ArtcraftRouterError;
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
use crate::generate::generate_video_v2::providers::kinovi::seedance_2p0::cost::KinoviSeedance2p0CostState;
use crate::generate::generate_video_v2::providers::kinovi::seedance_2p0::draft::KinoviSeedance2p0DraftState;
use crate::generate::generate_video_v2::providers::kinovi::seedance_2p0::request::KinoviSeedance2p0RequestState;
use crate::generate::generate_video_v2::video_generation_request::VideoGenerationRequest;
@@ -15,7 +16,7 @@ impl VideoGenerationDraftRequest {
/// Return a cost estimate to fulfill the request.
pub fn estimate_cost(&self) -> Result<VideoGenerationCostEstimate, ArtcraftRouterError> {
match self {
VideoGenerationDraftRequest::KinoviSeedance2p0(draft) => Ok(draft.estimate_cost()),
VideoGenerationDraftRequest::KinoviSeedance2p0(draft) => Ok(KinoviSeedance2p0CostState::from_draft(draft).estimate_cost()),
}
}
@@ -2,6 +2,7 @@ use crate::client::router_client::RouterClient;
use crate::errors::artcraft_router_error::ArtcraftRouterError;
use crate::generate::generate_video::generate_video_response::GenerateVideoResponse;
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
use crate::generate::generate_video_v2::providers::kinovi::seedance_2p0::cost::KinoviSeedance2p0CostState;
use crate::generate::generate_video_v2::providers::kinovi::seedance_2p0::request::KinoviSeedance2p0RequestState;
#[derive(Clone, Debug)]
@@ -10,10 +11,14 @@ pub enum VideoGenerationRequest {
}
impl VideoGenerationRequest {
/// Return a cost estimate to fulfill the request.
pub fn estimate_cost(&self) -> Result<VideoGenerationCostEstimate, ArtcraftRouterError> {
Ok(())
match self {
VideoGenerationRequest::KinoviSeedance2p0(request) => Ok(KinoviSeedance2p0CostState::from_request(request).estimate_cost()),
}
}
/// Send the video generation request
/// If successful, returns the job IDs.
pub async fn send_request(&self, client: &RouterClient) -> Result<GenerateVideoResponse, ArtcraftRouterError> {