Route direct image-edit requests through the img2img pipeline

Direct `models/infer` image requests were defaulting to `image.text2image`, which dropped reference inputs and produced unrelated generations. Route image-edit payloads to `image.img2img`, accept canonical `image` URLs during reference resolution, and preserve reference-aware prompt hints.

Constraint: The test server must continue accepting both canonical `image` and legacy alias fields from callers already in circulation
Rejected: Fix only reference URL parsing | direct overrides would still be misrouted as text2image before reference resolution runs
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Any future image-model route inference must inspect input shape before defaulting to text2image
Tested: `env GOCACHE=/tmp/popiartserver-gocache go test ./internal/server -run 'TestInferRouteKeyForModelRecognizesViduAsVideo|TestInferRouteKeyForModelRecognizesImageEditInputs|TestResolveImageToImageReferenceAcceptsCanonicalImageURL|TestGenerateEditedImageRefsUsesSeedreamImagesGenerationsEndpoint'`; deployed to `101.42.99.35` and verified Seedream gateway requests include `image`
Not-tested: Full manual validation against every non-Seedream image-edit provider
This commit is contained in:
wtgoku
2026-04-13 17:08:07 +08:00
parent 214ffa1dfc
commit a73b85c45f
3 changed files with 69 additions and 4 deletions
+39
View File
@@ -130,3 +130,42 @@ func TestArtifactUploadCreatesReadableArtifactForSourceArtifactID(t *testing.T)
t.Fatal("expected resolved reference content to match uploaded bytes")
}
}
func TestResolveImageToImageReferenceAcceptsCanonicalImageURL(t *testing.T) {
cfg := Config{
SQLitePath: filepath.Join(t.TempDir(), "popiart.db"),
SkillhubDir: makeEmptySkillhub(t),
SessionSecret: "test-secret",
}
server, err := NewWithConfig(cfg)
if err != nil {
t.Fatalf("NewWithConfig: %v", err)
}
imageBytes := tinyPNG(t)
refSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "image/png")
_, _ = w.Write(imageBytes)
}))
defer refSrv.Close()
editRef, err := server.resolveImageToImageReference(context.Background(), &job{
UserID: "user_test",
UpstreamKey: "sk-upstream",
SkillID: "popiskill-image-img2img-basic-v1",
}, map[string]any{
"image": refSrv.URL + "/reference.png",
})
if err != nil {
t.Fatalf("resolveImageToImageReference: %v", err)
}
if editRef.URL != refSrv.URL+"/reference.png" {
t.Fatalf("expected resolved URL to match input image, got %q", editRef.URL)
}
if editRef.ContentType != "image/png" {
t.Fatalf("expected image/png, got %q", editRef.ContentType)
}
if !bytes.Equal(editRef.Content, imageBytes) {
t.Fatal("expected resolved canonical image content to match downloaded bytes")
}
}