use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ChainLimits {
pub model: String,
pub frames_per_clip_cap: u32,
pub frames_per_clip_recommended: u32,
pub max_stages: u32,
pub max_total_frames: u32,
pub fade_frames_max: u32,
pub transition_modes: Vec<String>,
pub quantization_family: String,
pub supports_audio: bool,
}
pub fn family_cap(family: &str) -> Option<u32> {
match family {
"ltx2" => Some(97),
"ltx-video" => Some(97),
_ => None,
}
}
pub fn family_supports_audio(family: &str) -> bool {
matches!(family, "ltx2")
}
pub fn compute_limits(model: &str, family: &str, quant: &str, free_vram_bytes: u64) -> ChainLimits {
let cap = family_cap(family).unwrap_or(97);
let _ = free_vram_bytes; let recommended = cap;
const MAX_STAGES: u32 = 16;
ChainLimits {
model: model.to_string(),
frames_per_clip_cap: cap,
frames_per_clip_recommended: recommended,
max_stages: MAX_STAGES,
max_total_frames: cap * MAX_STAGES,
fade_frames_max: 32,
transition_modes: vec!["smooth".into(), "cut".into(), "fade".into()],
quantization_family: quant.to_string(),
supports_audio: family_supports_audio(family),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ltx2_cap_is_97() {
assert_eq!(family_cap("ltx2"), Some(97));
}
#[test]
fn ltx_video_cap_is_97() {
assert_eq!(family_cap("ltx-video"), Some(97));
}
#[test]
fn audio_capability_is_ltx2_only() {
assert!(family_supports_audio("ltx2"));
assert!(!family_supports_audio("ltx-video"));
assert!(!family_supports_audio("flux"));
assert!(!family_supports_audio(""));
}
#[test]
fn unknown_family_has_no_cap() {
assert_eq!(family_cap("flux"), None);
assert_eq!(family_cap("sdxl"), None);
}
#[test]
fn compute_limits_for_distilled() {
let lim = compute_limits("ltx-2-19b-distilled:fp8", "ltx2", "fp8", 8_000_000_000);
assert_eq!(lim.frames_per_clip_cap, 97);
assert_eq!(lim.frames_per_clip_recommended, 97);
assert_eq!(lim.max_stages, 16);
assert_eq!(lim.max_total_frames, 97 * 16);
assert_eq!(
lim.transition_modes,
vec!["smooth".to_string(), "cut".into(), "fade".into()]
);
assert!(
lim.supports_audio,
"ltx2 family has the AV transformer + audio VAE / vocoder path",
);
}
#[test]
fn compute_limits_for_ltx_video_has_no_audio() {
let lim = compute_limits("ltx-video-0.9.7-distilled:fp8", "ltx-video", "fp8", 0);
assert!(
!lim.supports_audio,
"ltx-video has no audio path — toggle must stay off",
);
}
}