fix: normalize video duration steps

This commit is contained in:
2026-05-13 12:29:00 +08:00
parent 2685450f3e
commit 0d0d0b9115
2 changed files with 137 additions and 15 deletions
@@ -180,6 +180,100 @@ func TestParamProcessorVideoCapabilitiesNormalizeAndFilter(t *testing.T) {
}
}
func TestParamProcessorDurationRangeRoundsFractionalSecondsUp(t *testing.T) {
body := map[string]any{
"model": "Seedance",
"prompt": "animate it",
"duration": 5.5,
}
candidate := store.RuntimeModelCandidate{
ModelType: "video_generate",
Capabilities: map[string]any{
"video_generate": map[string]any{
"duration_range": []any{3, 12},
},
},
}
result := preprocessRequestWithLog("videos.generations", body, candidate)
if result.Body["duration"] != float64(6) && result.Body["duration"] != 6 {
t.Fatalf("fractional duration should be rounded up to default 1s step, got %+v", result.Body["duration"])
}
}
func TestParamProcessorDurationWithoutRangeStillRoundsUp(t *testing.T) {
body := map[string]any{
"model": "Seedance",
"prompt": "animate it",
"duration": 5.2,
}
candidate := store.RuntimeModelCandidate{
ModelType: "video_generate",
Capabilities: map[string]any{
"video_generate": map[string]any{},
},
}
result := preprocessRequestWithLog("videos.generations", body, candidate)
if result.Body["duration"] != float64(6) && result.Body["duration"] != 6 {
t.Fatalf("duration should default to a 1s upward step without range, got %+v", result.Body["duration"])
}
}
func TestParamProcessorDurationRangeUsesStepCeilingAndRange(t *testing.T) {
body := map[string]any{
"model": "Seedance",
"prompt": "animate it",
"duration": 6.1,
"duration_seconds": 6.1,
}
candidate := store.RuntimeModelCandidate{
ModelType: "image_to_video",
Capabilities: map[string]any{
"image_to_video": map[string]any{
"duration_range": []any{5, 10},
"duration_step": 2,
},
},
}
result := preprocessRequestWithLog("videos.generations", body, candidate)
if result.Body["duration"] != float64(7) && result.Body["duration"] != 7 {
t.Fatalf("duration should be rounded up by configured step, got %+v", result.Body["duration"])
}
if result.Body["duration_seconds"] != result.Body["duration"] {
t.Fatalf("duration_seconds should sync with normalized duration, got %+v", result.Body)
}
body["duration"] = 10.1
body["duration_seconds"] = 10.1
result = preprocessRequestWithLog("videos.generations", body, candidate)
if result.Body["duration"] != float64(10) && result.Body["duration"] != 10 {
t.Fatalf("duration should be capped by range max, got %+v", result.Body["duration"])
}
}
func TestParamProcessorDurationOptionsChooseNextAllowedValue(t *testing.T) {
body := map[string]any{
"model": "Seedance",
"prompt": "animate it",
"duration": 8.1,
}
candidate := store.RuntimeModelCandidate{
ModelType: "image_to_video",
Capabilities: map[string]any{
"image_to_video": map[string]any{
"duration_options": []any{4, 8, 12},
},
},
}
result := preprocessRequestWithLog("videos.generations", body, candidate)
if result.Body["duration"] != float64(12) && result.Body["duration"] != 12 {
t.Fatalf("duration should use next allowed option, got %+v", result.Body["duration"])
}
}
func TestParamProcessorVideoGenerateLogsFirstFrameRemoval(t *testing.T) {
body := map[string]any{
"model": "Seedance T2V",