diff --git a/app/api/canvas/local-edit/route.ts b/app/api/canvas/local-edit/route.ts index 7dbc354a7..552373197 100644 --- a/app/api/canvas/local-edit/route.ts +++ b/app/api/canvas/local-edit/route.ts @@ -5534,6 +5534,8 @@ export async function POST(request: NextRequest) { scaleAdjustPatchReference?.productLockMethod || null, scaleAdjustProductLockMaskEditApplied: useScaleAdjustProductLockMaskEdit, + scaleAdjustRequiresProviderMaskInput: + useScaleAdjustProductLockMaskEdit, scaleAdjustProductLockEditMaskUrl: scaleAdjustPatchReference?.productLockEditMaskUrl || null, scaleAdjustProductLockOverlayUrl: diff --git a/lib/canvas/generate-image.ts b/lib/canvas/generate-image.ts index aca38923c..79d9b70a0 100644 --- a/lib/canvas/generate-image.ts +++ b/lib/canvas/generate-image.ts @@ -3421,6 +3421,19 @@ function isCanvasScaleAdjustEmergencyFalEditModel(item: CanvasModelWithProvider) ); } +function isCanvasScaleAdjustProviderMaskEditModel(item: CanvasModelWithProvider) { + if (getCanvasScaleAdjustModelFamily(item) !== "gpt-image-2") return false; + if (item.provider.type === "openai-image") return true; + if (item.provider.type !== "fal-image") return false; + const modelId = String(item.model.modelId || "").trim().toLowerCase(); + return ( + modelId === "openai/gpt-image-2/edit" || + modelId === "fal-ai/gpt-image-2/edit" || + modelId.endsWith("/gpt-image-2/edit") || + modelId.includes("gpt-image-2/edit") + ); +} + interface CanvasImageGenConfig { maxImages?: number; supports1K?: boolean; @@ -3617,6 +3630,7 @@ function findCanvasFailoverModel(params: { failedModelRefs: string[]; failedProviderTypes?: string[]; preferLowCostSameNameProviders?: boolean; + requiresProviderMaskInput?: boolean; requiresImageInput?: boolean; requiresTextToImage?: boolean; scaleAdjustModelFamily?: string | null; @@ -3675,6 +3689,12 @@ function findCanvasFailoverModel(params: { } if (failedProviderTypes.has(item.provider.type)) return false; if (!item.model.supportsImageGen) return false; + if ( + params.requiresProviderMaskInput && + !isCanvasScaleAdjustProviderMaskEditModel(item) + ) { + return false; + } if ( params.requiresImageInput && modelLacksReferenceImageInputSupport(item.model, item.provider) @@ -3827,6 +3847,10 @@ export async function generateCanvasImage( typeof debugMeta?.scaleAdjustModelFamily === "string" ? debugMeta.scaleAdjustModelFamily.trim() : ""; + const requiresProviderMaskInput = Boolean( + debugMeta?.scaleAdjustProductLockMaskEditApplied && + debugMeta?.scaleAdjustProviderMaskImageUrl + ); const localEditComposite = normalizeLocalEditCompositeConfig( request.localEditComposite ); @@ -3886,6 +3910,7 @@ export async function generateCanvasImage( preferLowCostSameNameProviders: Boolean( debugMeta?.scaleAdjustPreferSameNameProviderFailover ), + requiresProviderMaskInput, requiresImageInput, scaleAdjustModelFamily, }); @@ -3928,6 +3953,7 @@ export async function generateCanvasImage( preferLowCostSameNameProviders: Boolean( debugMeta?.scaleAdjustPreferSameNameProviderFailover ), + requiresProviderMaskInput, requiresTextToImage, scaleAdjustModelFamily, }); @@ -4594,6 +4620,7 @@ export async function generateCanvasImage( preferLowCostSameNameProviders: Boolean( debugMeta?.scaleAdjustPreferSameNameProviderFailover ), + requiresProviderMaskInput, requiresImageInput: normalizedReferenceImages.length > 0, requiresTextToImage: normalizedReferenceImages.length === 0, scaleAdjustModelFamily,