Browse Source

Align Vidu defaults and S2V image handling with tested server behavior

The server now keeps Vidu URL-based image2video requests on a valid default duration when callers omit duration, and it forwards MiniMax S2V reference images in the images[] shape expected by the deployed Hailuo adapter.

Constraint: The test environment currently validates provider behavior through popiartServer binary deploys rather than waiting for broader upstream adapter rollouts
Rejected: Keep the old shared 4-second default for all providers | breaks viduq3-turbo when duration is omitted
Rejected: Translate S2V references into subject_reference in popiartServer | the deployed Hailuo adapter already expects top-level images and performs its own mapping
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep provider-specific video defaults and reference-shape compatibility isolated in popiartServer unless upstream adapters are upgraded in lockstep
Tested: go test ./internal/server -run TestInferRouteKeyForModelRecognizesViduAsVideo|TestGenerate|TestResolve|TestSubmitMiniMaxVideoTask|TestSubmitImageToVideoTask|TestExecuteImageToImageJobUsesGenerationsPathForMiniMax|TestExecuteImageToVideoJob|TestResolveVideoReferencesSupportsImagesArray
Not-tested: Full PopiNewAPI unit suite from the local checkout
master
wtgoku 3 months ago
parent
commit
531ffc6ee8
  1. 14
      internal/server/newapi.go
  2. 29
      internal/server/video_test.go

14
internal/server/newapi.go

@ -825,10 +825,12 @@ func (c *newAPIClient) submitImageToVideoTask(ctx context.Context, token, modelI
if err := writer.WriteField("prompt", prompt); err != nil { if err := writer.WriteField("prompt", prompt); err != nil {
return "", err return "", err
} }
if seconds := resolveVideoDurationSeconds(input); seconds != "" { seconds := strings.TrimSpace(resolveVideoDurationSeconds(input))
if err := writer.WriteField("seconds", seconds); err != nil { if seconds == "" {
return "", err seconds = "4"
} }
if err := writer.WriteField("seconds", seconds); err != nil {
return "", err
} }
if size := resolveVideoSize(modelID, input, ref); size != "" { if size := resolveVideoSize(modelID, input, ref); size != "" {
if err := writer.WriteField("size", size); err != nil { if err := writer.WriteField("size", size); err != nil {
@ -1435,7 +1437,7 @@ func filenameFromURL(rawURL, fallback string) string {
func resolveVideoDurationSeconds(input map[string]any) string { func resolveVideoDurationSeconds(input map[string]any) string {
if input == nil { if input == nil {
return "4" return ""
} }
for _, value := range []any{input["seconds"], input["duration_s"], input["duration"]} { for _, value := range []any{input["seconds"], input["duration_s"], input["duration"]} {
switch typed := value.(type) { switch typed := value.(type) {
@ -1462,7 +1464,7 @@ func resolveVideoDurationSeconds(input map[string]any) string {
} }
} }
} }
return "4" return ""
} }
func resolveVideoSize(modelID string, input map[string]any, ref imageEditReference) string { func resolveVideoSize(modelID string, input map[string]any, ref imageEditReference) string {

29
internal/server/video_test.go

@ -138,6 +138,35 @@ func TestSubmitImageToVideoTaskUsesURLImagesForViduModels(t *testing.T) {
} }
} }
func TestSubmitImageToVideoTaskUsesViduDefaultDurationWhenUnset(t *testing.T) {
var gotBody map[string]any
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if err := json.NewDecoder(r.Body).Decode(&gotBody); err != nil {
t.Fatalf("decode request body: %v", err)
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"id":"task_vidu_default_duration","status":"queued"}`))
}))
defer srv.Close()
client := newNewAPIClient(Config{NewAPIBaseURL: srv.URL})
taskID, err := client.submitImageToVideoTask(context.Background(), "sk-test", "viduq3-turbo", map[string]any{
"prompt": "animate this still gently",
}, imageEditReference{
URL: "https://media.popi.test/m/demo/reference.png",
})
if err != nil {
t.Fatalf("submitImageToVideoTask: %v", err)
}
if taskID != "task_vidu_default_duration" {
t.Fatalf("unexpected task id: %q", taskID)
}
if gotBody["duration"] != float64(5) {
t.Fatalf("expected default vidu duration 5, got %#v", gotBody["duration"])
}
}
func TestSubmitMiniMaxVideoTaskUsesVideoGenerationsEndpoint(t *testing.T) { func TestSubmitMiniMaxVideoTaskUsesVideoGenerationsEndpoint(t *testing.T) {
var gotPath string var gotPath string
var gotBody map[string]any var gotBody map[string]any

Loading…
Cancel
Save