mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-30 05:22:51 -04:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8f6022b33 | ||
|
|
2d498e20a1 |
+7
-7
@@ -15,9 +15,9 @@ impl ArtcraftVeo2CostState {
|
||||
}
|
||||
|
||||
pub fn estimate_cost(&self) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client veo_2: 5s = $2.50, +$0.50/s above 5s.
|
||||
// 5s = $2.75, +$0.55/s above 5s.
|
||||
let extra = self.duration_seconds.saturating_sub(5);
|
||||
let cost_in_usd_cents = 250 + extra * 50;
|
||||
let cost_in_usd_cents = 275 + extra * 55;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
@@ -49,17 +49,17 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_is_5s_priced_at_250() { assert_eq!(cost_cents(None), 250); }
|
||||
fn default_is_5s_priced_at_275() { assert_eq!(cost_cents(None), 275); }
|
||||
|
||||
#[test]
|
||||
fn five_seconds_is_250() { assert_eq!(cost_cents(Some(5)), 250); }
|
||||
fn five_seconds_is_275() { assert_eq!(cost_cents(Some(5)), 275); }
|
||||
|
||||
#[test]
|
||||
fn six_seconds_is_300() { assert_eq!(cost_cents(Some(6)), 300); }
|
||||
fn six_seconds_is_330() { assert_eq!(cost_cents(Some(6)), 330); }
|
||||
|
||||
#[test]
|
||||
fn seven_seconds_is_350() { assert_eq!(cost_cents(Some(7)), 350); }
|
||||
fn seven_seconds_is_385() { assert_eq!(cost_cents(Some(7)), 385); }
|
||||
|
||||
#[test]
|
||||
fn eight_seconds_is_400() { assert_eq!(cost_cents(Some(8)), 400); }
|
||||
fn eight_seconds_is_440() { assert_eq!(cost_cents(Some(8)), 440); }
|
||||
}
|
||||
|
||||
+7
-7
@@ -17,8 +17,8 @@ impl ArtcraftVeo3CostState {
|
||||
}
|
||||
|
||||
pub fn estimate_cost(&self) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client veo_3: $0.20/sec audio off, $0.40/sec audio on.
|
||||
let per_second_cents: u64 = if self.generate_audio { 40 } else { 20 };
|
||||
// $0.24/sec audio off, $0.48/sec audio on.
|
||||
let per_second_cents: u64 = if self.generate_audio { 48 } else { 24 };
|
||||
let cost_in_usd_cents = per_second_cents * self.duration_seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
@@ -61,19 +61,19 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn audio_off_4s_is_80() { assert_eq!(cost_cents(Some(4), Some(false)), 80); }
|
||||
fn audio_off_4s_is_96() { assert_eq!(cost_cents(Some(4), Some(false)), 96); }
|
||||
|
||||
#[test]
|
||||
fn audio_off_6s_is_120() { assert_eq!(cost_cents(Some(6), Some(false)), 120); }
|
||||
fn audio_off_6s_is_144() { assert_eq!(cost_cents(Some(6), Some(false)), 144); }
|
||||
|
||||
#[test]
|
||||
fn audio_off_8s_is_160() { assert_eq!(cost_cents(Some(8), Some(false)), 160); }
|
||||
fn audio_off_8s_is_192() { assert_eq!(cost_cents(Some(8), Some(false)), 192); }
|
||||
|
||||
#[test]
|
||||
fn audio_on_4s_is_160() { assert_eq!(cost_cents(Some(4), Some(true)), 160); }
|
||||
fn audio_on_4s_is_192() { assert_eq!(cost_cents(Some(4), Some(true)), 192); }
|
||||
|
||||
#[test]
|
||||
fn audio_on_8s_is_320() { assert_eq!(cost_cents(Some(8), Some(true)), 320); }
|
||||
fn audio_on_8s_is_384() { assert_eq!(cost_cents(Some(8), Some(true)), 384); }
|
||||
|
||||
#[test]
|
||||
fn default_duration_is_8s() {
|
||||
|
||||
+9
-11
@@ -15,10 +15,8 @@ impl ArtcraftVeo3FastCostState {
|
||||
}
|
||||
|
||||
pub fn estimate_cost(&self) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client veo_3_fast: $0.10/sec audio off, $0.15/sec audio on.
|
||||
// Legacy handler always bills 8s.
|
||||
let per_second_cents: u64 = if self.generate_audio { 15 } else { 10 };
|
||||
let cost_in_usd_cents = per_second_cents * 8;
|
||||
// Flat per-video price: 88¢ audio off, 132¢ audio on.
|
||||
let cost_in_usd_cents: u64 = if self.generate_audio { 132 } else { 88 };
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
@@ -51,22 +49,22 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn audio_off_is_80() { assert_eq!(cost_cents(Some(8), Some(false)), 80); }
|
||||
fn audio_off_is_88() { assert_eq!(cost_cents(Some(8), Some(false)), 88); }
|
||||
|
||||
#[test]
|
||||
fn audio_on_is_120() { assert_eq!(cost_cents(Some(8), Some(true)), 120); }
|
||||
fn audio_on_is_132() { assert_eq!(cost_cents(Some(8), Some(true)), 132); }
|
||||
|
||||
#[test]
|
||||
fn audio_default_is_off() {
|
||||
assert_eq!(cost_cents(Some(8), None), 80);
|
||||
assert_eq!(cost_cents(Some(8), None), 88);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn duration_does_not_affect_cost() {
|
||||
// v1 always bills 8s regardless of duration_seconds.
|
||||
assert_eq!(cost_cents(Some(4), Some(false)), 80);
|
||||
assert_eq!(cost_cents(Some(6), Some(false)), 80);
|
||||
assert_eq!(cost_cents(Some(8), Some(false)), 80);
|
||||
assert_eq!(cost_cents(None, Some(false)), 80);
|
||||
assert_eq!(cost_cents(Some(4), Some(false)), 88);
|
||||
assert_eq!(cost_cents(Some(6), Some(false)), 88);
|
||||
assert_eq!(cost_cents(Some(8), Some(false)), 88);
|
||||
assert_eq!(cost_cents(None, Some(false)), 88);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ pub fn build_artcraft_veo_3p1(mut builder: GenerateVideoRequestBuilder) -> Resul
|
||||
let mut request = build_artcraft_omni_video_request(
|
||||
builder,
|
||||
CommonVideoModelEnum::Veo3p1,
|
||||
SupportedResolutions::Full,
|
||||
SupportedResolutions::FullWith4k,
|
||||
UltraWideSupport::Unsupported,
|
||||
)?;
|
||||
request.generate_audio = generate_audio;
|
||||
|
||||
+46
-8
@@ -1,3 +1,5 @@
|
||||
use enums::common::generation::common_resolution::CommonResolution as CommonResolutionEnum;
|
||||
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
use crate::generate::generate_video::providers::artcraft::veo_3p1::request::ArtcraftVeo3p1RequestState;
|
||||
|
||||
@@ -5,6 +7,7 @@ use crate::generate::generate_video::providers::artcraft::veo_3p1::request::Artc
|
||||
pub struct ArtcraftVeo3p1CostState {
|
||||
pub duration_seconds: u64,
|
||||
pub generate_audio: bool,
|
||||
pub is_4k: bool,
|
||||
}
|
||||
|
||||
impl ArtcraftVeo3p1CostState {
|
||||
@@ -14,12 +17,19 @@ impl ArtcraftVeo3p1CostState {
|
||||
duration_seconds: request.request.duration_seconds.map(u64::from).unwrap_or(6),
|
||||
// v1 legacy Veo 3.1 handler defaults generate_audio to true.
|
||||
generate_audio: request.request.generate_audio.unwrap_or(true),
|
||||
is_4k: request.request.resolution == Some(CommonResolutionEnum::FourK),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn estimate_cost(&self) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client veo_3p1: $0.20/sec audio off, $0.40/sec audio on.
|
||||
let per_second_cents: u64 = if self.generate_audio { 40 } else { 20 };
|
||||
// $0.24/sec audio off, $0.48/sec audio on; 4K renders bill a premium:
|
||||
// $0.48/sec audio off, $0.72/sec audio on.
|
||||
let per_second_cents: u64 = match (self.is_4k, self.generate_audio) {
|
||||
(false, false) => 24,
|
||||
(false, true) => 48,
|
||||
(true, false) => 48,
|
||||
(true, true) => 72,
|
||||
};
|
||||
let cost_in_usd_cents = per_second_cents * self.duration_seconds;
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
@@ -36,12 +46,22 @@ impl ArtcraftVeo3p1CostState {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::router_resolution::RouterResolution;
|
||||
use crate::api::router_video_model::RouterVideoModel;
|
||||
use crate::api::router_provider::RouterProvider;
|
||||
use crate::generate::generate_video::generate_video_request_builder::GenerateVideoRequestBuilder;
|
||||
|
||||
fn cost_cents(duration_seconds: Option<u16>, generate_audio: Option<bool>) -> u64 {
|
||||
cost_cents_at(duration_seconds, generate_audio, None)
|
||||
}
|
||||
|
||||
fn cost_cents_at(
|
||||
duration_seconds: Option<u16>,
|
||||
generate_audio: Option<bool>,
|
||||
resolution: Option<RouterResolution>,
|
||||
) -> u64 {
|
||||
let b = GenerateVideoRequestBuilder {
|
||||
resolution,
|
||||
model: RouterVideoModel::Veo3p1,
|
||||
provider: RouterProvider::Artcraft,
|
||||
prompt: Some("test".to_string()),
|
||||
@@ -53,24 +73,42 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn audio_on_4s_is_160() { assert_eq!(cost_cents(Some(4), Some(true)), 160); }
|
||||
fn audio_on_4s_is_192() { assert_eq!(cost_cents(Some(4), Some(true)), 192); }
|
||||
|
||||
#[test]
|
||||
fn audio_on_6s_is_240() { assert_eq!(cost_cents(Some(6), Some(true)), 240); }
|
||||
fn audio_on_6s_is_288() { assert_eq!(cost_cents(Some(6), Some(true)), 288); }
|
||||
|
||||
#[test]
|
||||
fn audio_on_8s_is_320() { assert_eq!(cost_cents(Some(8), Some(true)), 320); }
|
||||
fn audio_on_8s_is_384() { assert_eq!(cost_cents(Some(8), Some(true)), 384); }
|
||||
|
||||
#[test]
|
||||
fn audio_off_4s_is_80() { assert_eq!(cost_cents(Some(4), Some(false)), 80); }
|
||||
fn audio_off_4s_is_96() { assert_eq!(cost_cents(Some(4), Some(false)), 96); }
|
||||
|
||||
#[test]
|
||||
fn default_duration_is_6s() {
|
||||
assert_eq!(cost_cents(None, Some(true)), 240);
|
||||
assert_eq!(cost_cents(None, Some(true)), 288);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn audio_default_is_on() {
|
||||
assert_eq!(cost_cents(Some(6), None), 240);
|
||||
assert_eq!(cost_cents(Some(6), None), 288);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn four_k_audio_off_4s_is_192() {
|
||||
assert_eq!(cost_cents_at(Some(4), Some(false), Some(RouterResolution::FourK)), 192);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn four_k_audio_on_4s_is_288() {
|
||||
assert_eq!(cost_cents_at(Some(4), Some(true), Some(RouterResolution::FourK)), 288);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_four_k_resolutions_share_the_base_rate() {
|
||||
assert_eq!(
|
||||
cost_cents_at(Some(8), Some(true), Some(RouterResolution::SevenTwentyP)),
|
||||
cost_cents_at(Some(8), Some(true), Some(RouterResolution::TenEightyP)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ pub fn build_artcraft_veo_3p1_fast(mut builder: GenerateVideoRequestBuilder) ->
|
||||
let mut request = build_artcraft_omni_video_request(
|
||||
builder,
|
||||
CommonVideoModelEnum::Veo3p1Fast,
|
||||
SupportedResolutions::Full,
|
||||
SupportedResolutions::FullWith4k,
|
||||
UltraWideSupport::Unsupported,
|
||||
)?;
|
||||
request.generate_audio = generate_audio;
|
||||
|
||||
+47
-9
@@ -1,3 +1,5 @@
|
||||
use enums::common::generation::common_resolution::CommonResolution as CommonResolutionEnum;
|
||||
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
use crate::generate::generate_video::providers::artcraft::veo_3p1_fast::request::ArtcraftVeo3p1FastRequestState;
|
||||
|
||||
@@ -5,6 +7,7 @@ use crate::generate::generate_video::providers::artcraft::veo_3p1_fast::request:
|
||||
pub struct ArtcraftVeo3p1FastCostState {
|
||||
pub duration_seconds: u64,
|
||||
pub generate_audio: bool,
|
||||
pub is_4k: bool,
|
||||
}
|
||||
|
||||
impl ArtcraftVeo3p1FastCostState {
|
||||
@@ -14,13 +17,20 @@ impl ArtcraftVeo3p1FastCostState {
|
||||
duration_seconds: request.request.duration_seconds.map(u64::from).unwrap_or(6),
|
||||
// v1 legacy Veo 3.1 Fast handler defaults generate_audio to true.
|
||||
generate_audio: request.request.generate_audio.unwrap_or(true),
|
||||
is_4k: request.request.resolution == Some(CommonResolutionEnum::FourK),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn estimate_cost(&self) -> VideoGenerationCostEstimate {
|
||||
// Mirrors fal_client veo_3p1_fast: $0.10/sec audio off, $0.15/sec audio on.
|
||||
let per_second_cents: u64 = if self.generate_audio { 15 } else { 10 };
|
||||
let cost_in_usd_cents = per_second_cents * self.duration_seconds;
|
||||
// Per-second rates in hundredths of a US cent; 4K renders bill a premium.
|
||||
let rate_hundredth_cents: u64 = match (self.is_4k, self.generate_audio) {
|
||||
(false, false) => 1_100,
|
||||
(false, true) => 1_650,
|
||||
(true, false) => 3_300,
|
||||
(true, true) => 3_850,
|
||||
};
|
||||
// Round up to the next whole cent.
|
||||
let cost_in_usd_cents = (rate_hundredth_cents * self.duration_seconds).div_ceil(100);
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
@@ -36,12 +46,22 @@ impl ArtcraftVeo3p1FastCostState {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::router_resolution::RouterResolution;
|
||||
use crate::api::router_video_model::RouterVideoModel;
|
||||
use crate::api::router_provider::RouterProvider;
|
||||
use crate::generate::generate_video::generate_video_request_builder::GenerateVideoRequestBuilder;
|
||||
|
||||
fn cost_cents(duration_seconds: Option<u16>, generate_audio: Option<bool>) -> u64 {
|
||||
cost_cents_at(duration_seconds, generate_audio, None)
|
||||
}
|
||||
|
||||
fn cost_cents_at(
|
||||
duration_seconds: Option<u16>,
|
||||
generate_audio: Option<bool>,
|
||||
resolution: Option<RouterResolution>,
|
||||
) -> u64 {
|
||||
let b = GenerateVideoRequestBuilder {
|
||||
resolution,
|
||||
model: RouterVideoModel::Veo3p1Fast,
|
||||
provider: RouterProvider::Artcraft,
|
||||
prompt: Some("test".to_string()),
|
||||
@@ -53,24 +73,42 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn audio_on_4s_is_60() { assert_eq!(cost_cents(Some(4), Some(true)), 60); }
|
||||
fn audio_on_4s_is_66() { assert_eq!(cost_cents(Some(4), Some(true)), 66); }
|
||||
|
||||
#[test]
|
||||
fn audio_on_6s_is_90() { assert_eq!(cost_cents(Some(6), Some(true)), 90); }
|
||||
fn audio_on_6s_is_99() { assert_eq!(cost_cents(Some(6), Some(true)), 99); }
|
||||
|
||||
#[test]
|
||||
fn audio_on_8s_is_120() { assert_eq!(cost_cents(Some(8), Some(true)), 120); }
|
||||
fn audio_on_8s_is_132() { assert_eq!(cost_cents(Some(8), Some(true)), 132); }
|
||||
|
||||
#[test]
|
||||
fn audio_off_4s_is_40() { assert_eq!(cost_cents(Some(4), Some(false)), 40); }
|
||||
fn audio_off_4s_is_44() { assert_eq!(cost_cents(Some(4), Some(false)), 44); }
|
||||
|
||||
#[test]
|
||||
fn default_duration_is_6s() {
|
||||
assert_eq!(cost_cents(None, Some(true)), 90);
|
||||
assert_eq!(cost_cents(None, Some(true)), 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn audio_default_is_on() {
|
||||
assert_eq!(cost_cents(Some(6), None), 90);
|
||||
assert_eq!(cost_cents(Some(6), None), 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn four_k_audio_off_4s_is_132() {
|
||||
assert_eq!(cost_cents_at(Some(4), Some(false), Some(RouterResolution::FourK)), 132);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn four_k_audio_on_4s_is_154() {
|
||||
assert_eq!(cost_cents_at(Some(4), Some(true), Some(RouterResolution::FourK)), 154);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_four_k_resolutions_share_the_base_rate() {
|
||||
assert_eq!(
|
||||
cost_cents_at(Some(8), Some(true), Some(RouterResolution::SevenTwentyP)),
|
||||
cost_cents_at(Some(8), Some(true), Some(RouterResolution::TenEightyP)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -5,7 +5,7 @@ use crate::generate::generate_video::providers::artcraft::vidu_q3::request::Artc
|
||||
|
||||
/// Per-second rates in hundredths of a US cent.
|
||||
const LOW_RES_RATE_HUNDREDTH_CENTS_PER_SEC: u64 = 735;
|
||||
const HIGH_RES_RATE_HUNDREDTH_CENTS_PER_SEC: u64 = 1_617;
|
||||
const HIGH_RES_RATE_HUNDREDTH_CENTS_PER_SEC: u64 = 1_634;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ArtcraftViduQ3CostState {
|
||||
@@ -84,13 +84,13 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_resolution_5s_is_81() { assert_eq!(cost_cents(Some(5), None), 81); }
|
||||
fn default_resolution_5s_is_82() { assert_eq!(cost_cents(Some(5), None), 82); }
|
||||
|
||||
#[test]
|
||||
fn default_duration_is_5s() { assert_eq!(cost_cents(None, None), 81); }
|
||||
fn default_duration_is_5s() { assert_eq!(cost_cents(None, None), 82); }
|
||||
|
||||
#[test]
|
||||
fn high_res_10s_is_162() { assert_eq!(cost_cents(Some(10), Some(RouterResolution::TenEightyP)), 162); }
|
||||
fn high_res_10s_is_164() { assert_eq!(cost_cents(Some(10), Some(RouterResolution::TenEightyP)), 164); }
|
||||
|
||||
#[test]
|
||||
fn low_res_5s_is_37() { assert_eq!(cost_cents(Some(5), Some(RouterResolution::FourEightyP)), 37); }
|
||||
@@ -100,13 +100,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn seven_twenty_p_is_high_res_tier() {
|
||||
assert_eq!(cost_cents(Some(8), Some(RouterResolution::SevenTwentyP)), 130);
|
||||
assert_eq!(cost_cents(Some(8), Some(RouterResolution::SevenTwentyP)), 131);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn odd_duration_rounds_up_to_whole_cents() {
|
||||
// 7s high res: 1617 * 7 = 11319 hundredth-cents → 114 cents.
|
||||
assert_eq!(cost_cents(Some(7), None), 114);
|
||||
// 7s high res: 1634 * 7 = 11438 hundredth-cents → 115 cents.
|
||||
assert_eq!(cost_cents(Some(7), None), 115);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+9
-9
@@ -4,8 +4,8 @@ use crate::generate::generate_video::video_generation_cost_estimate::VideoGenera
|
||||
use crate::generate::generate_video::providers::artcraft::vidu_q3_turbo::request::ArtcraftViduQ3TurboRequestState;
|
||||
|
||||
/// Per-second rates in hundredths of a US cent.
|
||||
const LOW_RES_RATE_HUNDREDTH_CENTS_PER_SEC: u64 = 368;
|
||||
const HIGH_RES_RATE_HUNDREDTH_CENTS_PER_SEC: u64 = 809;
|
||||
const LOW_RES_RATE_HUNDREDTH_CENTS_PER_SEC: u64 = 401;
|
||||
const HIGH_RES_RATE_HUNDREDTH_CENTS_PER_SEC: u64 = 834;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ArtcraftViduQ3TurboCostState {
|
||||
@@ -82,23 +82,23 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_resolution_5s_is_41() { assert_eq!(cost_cents(Some(5), None), 41); }
|
||||
fn default_resolution_5s_is_42() { assert_eq!(cost_cents(Some(5), None), 42); }
|
||||
|
||||
#[test]
|
||||
fn default_duration_is_5s() { assert_eq!(cost_cents(None, None), 41); }
|
||||
fn default_duration_is_5s() { assert_eq!(cost_cents(None, None), 42); }
|
||||
|
||||
#[test]
|
||||
fn high_res_10s_is_81() { assert_eq!(cost_cents(Some(10), Some(RouterResolution::TenEightyP)), 81); }
|
||||
fn high_res_10s_is_84() { assert_eq!(cost_cents(Some(10), Some(RouterResolution::TenEightyP)), 84); }
|
||||
|
||||
#[test]
|
||||
fn low_res_5s_is_19() { assert_eq!(cost_cents(Some(5), Some(RouterResolution::FourEightyP)), 19); }
|
||||
fn low_res_5s_is_21() { assert_eq!(cost_cents(Some(5), Some(RouterResolution::FourEightyP)), 21); }
|
||||
|
||||
#[test]
|
||||
fn low_res_10s_is_37() { assert_eq!(cost_cents(Some(10), Some(RouterResolution::FourEightyP)), 37); }
|
||||
fn low_res_10s_is_41() { assert_eq!(cost_cents(Some(10), Some(RouterResolution::FourEightyP)), 41); }
|
||||
|
||||
#[test]
|
||||
fn odd_duration_rounds_up_to_whole_cents() {
|
||||
// 7s high res: 809 * 7 = 5663 hundredth-cents → 57 cents.
|
||||
assert_eq!(cost_cents(Some(7), None), 57);
|
||||
// 7s high res: 834 * 7 = 5838 hundredth-cents → 59 cents.
|
||||
assert_eq!(cost_cents(Some(7), None), 59);
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -94,6 +94,7 @@ pub fn veo_video_models() -> Vec<OmniGenVideoModelDetails> {
|
||||
resolution_options: Some(vec![
|
||||
CommonResolution::SevenTwentyP,
|
||||
CommonResolution::TenEightyP,
|
||||
CommonResolution::FourK,
|
||||
]),
|
||||
resolution_default: Some(CommonResolution::TenEightyP),
|
||||
duration_seconds_min: Some(4),
|
||||
@@ -123,6 +124,7 @@ pub fn veo_video_models() -> Vec<OmniGenVideoModelDetails> {
|
||||
resolution_options: Some(vec![
|
||||
CommonResolution::SevenTwentyP,
|
||||
CommonResolution::TenEightyP,
|
||||
CommonResolution::FourK,
|
||||
]),
|
||||
resolution_default: Some(CommonResolution::TenEightyP),
|
||||
duration_seconds_min: Some(4),
|
||||
|
||||
Reference in New Issue
Block a user