fix: fallback scale adjust on provider failure
This commit is contained in:
parent
c0e16a354f
commit
0b1a3a715b
@ -514,6 +514,81 @@ async function buildScaleAdjustFallbackImage(params: {
|
||||
return workingBuffer;
|
||||
}
|
||||
|
||||
async function loadScaleAdjustSourceImage(
|
||||
verification: CanvasScaleAdjustVerificationConfig
|
||||
) {
|
||||
const sourceBuffer = await sharp(
|
||||
await fetchImageBufferFromUrl(verification.sourceImageUrl),
|
||||
{ failOn: "none" }
|
||||
)
|
||||
.rotate()
|
||||
.png({ compressionLevel: 6 })
|
||||
.toBuffer();
|
||||
const sourceMetadata = await sharp(sourceBuffer, { failOn: "none" }).metadata();
|
||||
const sourceWidth = Number(sourceMetadata.width || 0);
|
||||
const sourceHeight = Number(sourceMetadata.height || 0);
|
||||
if (sourceWidth <= 0 || sourceHeight <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
sourceBuffer,
|
||||
sourceHeight,
|
||||
sourceWidth,
|
||||
};
|
||||
}
|
||||
|
||||
async function createScaleAdjustFallbackUpload(params: {
|
||||
sourceBuffer: Buffer;
|
||||
sourceWidth: number;
|
||||
sourceHeight: number;
|
||||
verification: CanvasScaleAdjustVerificationConfig;
|
||||
debugLabel: string;
|
||||
imageIndex?: number;
|
||||
reason: string;
|
||||
diffScores?: number[];
|
||||
}) {
|
||||
const fallbackBuffer = await buildScaleAdjustFallbackImage({
|
||||
sourceBuffer: params.sourceBuffer,
|
||||
sourceHeight: params.sourceHeight,
|
||||
sourceWidth: params.sourceWidth,
|
||||
verification: params.verification,
|
||||
});
|
||||
const thumbnailBuffer = await sharp(fallbackBuffer, { failOn: "none" })
|
||||
.resize(512, 512, { fit: "inside", withoutEnlargement: true })
|
||||
.png({ compressionLevel: 6 })
|
||||
.toBuffer();
|
||||
const suffix = `${Date.now()}-${params.imageIndex || 1}-${Math.random()
|
||||
.toString(36)
|
||||
.slice(2, 8)}`;
|
||||
const [originalUpload, thumbnailUpload] = await Promise.all([
|
||||
uploadFile(
|
||||
`canvas-scale-adjust-fallback-${suffix}.png`,
|
||||
bufferToArrayBuffer(fallbackBuffer)
|
||||
),
|
||||
uploadFile(
|
||||
`canvas-scale-adjust-fallback-thumb-${suffix}.png`,
|
||||
bufferToArrayBuffer(thumbnailBuffer)
|
||||
),
|
||||
]);
|
||||
|
||||
console.warn("[Canvas Generate Image] Scale adjust fallback applied:", {
|
||||
debugLabel: params.debugLabel,
|
||||
diffScores: params.diffScores?.map((score) => Math.round(score * 10) / 10),
|
||||
imageIndex: params.imageIndex,
|
||||
reason: params.reason,
|
||||
regionCount: params.verification.regions.length,
|
||||
scalePercent: params.verification.scalePercent,
|
||||
sourceHeight: params.sourceHeight,
|
||||
sourceWidth: params.sourceWidth,
|
||||
});
|
||||
|
||||
return {
|
||||
originalUrl: originalUpload.url,
|
||||
thumbnailUrl: thumbnailUpload.url,
|
||||
};
|
||||
}
|
||||
|
||||
async function applyScaleAdjustVerificationToImages(params: {
|
||||
images: ParsedImage[];
|
||||
verification: CanvasScaleAdjustVerificationConfig | null;
|
||||
@ -523,19 +598,11 @@ async function applyScaleAdjustVerificationToImages(params: {
|
||||
if (!verification || images.length === 0) return images;
|
||||
|
||||
try {
|
||||
const sourceBuffer = await sharp(
|
||||
await fetchImageBufferFromUrl(verification.sourceImageUrl),
|
||||
{ failOn: "none" }
|
||||
)
|
||||
.rotate()
|
||||
.png({ compressionLevel: 6 })
|
||||
.toBuffer();
|
||||
const sourceMetadata = await sharp(sourceBuffer, { failOn: "none" }).metadata();
|
||||
const sourceWidth = Number(sourceMetadata.width || 0);
|
||||
const sourceHeight = Number(sourceMetadata.height || 0);
|
||||
if (sourceWidth <= 0 || sourceHeight <= 0) {
|
||||
const sourceImage = await loadScaleAdjustSourceImage(verification);
|
||||
if (!sourceImage) {
|
||||
return images;
|
||||
}
|
||||
const { sourceBuffer, sourceHeight, sourceWidth } = sourceImage;
|
||||
|
||||
const checkedImages: ParsedImage[] = [];
|
||||
for (const [index, image] of images.entries()) {
|
||||
@ -563,41 +630,17 @@ async function applyScaleAdjustVerificationToImages(params: {
|
||||
continue;
|
||||
}
|
||||
|
||||
const fallbackBuffer = await buildScaleAdjustFallbackImage({
|
||||
const fallbackImage = await createScaleAdjustFallbackUpload({
|
||||
debugLabel,
|
||||
diffScores,
|
||||
imageIndex: index + 1,
|
||||
reason: "unchanged-output",
|
||||
sourceBuffer,
|
||||
sourceHeight,
|
||||
sourceWidth,
|
||||
verification,
|
||||
});
|
||||
const thumbnailBuffer = await sharp(fallbackBuffer, { failOn: "none" })
|
||||
.resize(512, 512, { fit: "inside", withoutEnlargement: true })
|
||||
.png({ compressionLevel: 6 })
|
||||
.toBuffer();
|
||||
const suffix = `${Date.now()}-${index + 1}-${Math.random().toString(36).slice(2, 8)}`;
|
||||
const [originalUpload, thumbnailUpload] = await Promise.all([
|
||||
uploadFile(
|
||||
`canvas-scale-adjust-fallback-${suffix}.png`,
|
||||
bufferToArrayBuffer(fallbackBuffer)
|
||||
),
|
||||
uploadFile(
|
||||
`canvas-scale-adjust-fallback-thumb-${suffix}.png`,
|
||||
bufferToArrayBuffer(thumbnailBuffer)
|
||||
),
|
||||
]);
|
||||
|
||||
console.warn("[Canvas Generate Image] Scale adjust fallback applied:", {
|
||||
debugLabel,
|
||||
diffScores: diffScores.map((score) => Math.round(score * 10) / 10),
|
||||
imageIndex: index + 1,
|
||||
regionCount: verification.regions.length,
|
||||
scalePercent: verification.scalePercent,
|
||||
sourceHeight,
|
||||
sourceWidth,
|
||||
});
|
||||
checkedImages.push({
|
||||
originalUrl: originalUpload.url,
|
||||
thumbnailUrl: thumbnailUpload.url,
|
||||
});
|
||||
checkedImages.push(fallbackImage);
|
||||
}
|
||||
|
||||
return checkedImages;
|
||||
@ -1483,6 +1526,82 @@ export async function generateCanvasImage(
|
||||
await slot.release();
|
||||
}
|
||||
|
||||
if (scaleAdjustVerification) {
|
||||
try {
|
||||
const sourceImage = await loadScaleAdjustSourceImage(scaleAdjustVerification);
|
||||
if (sourceImage) {
|
||||
const fallbackImage = await createScaleAdjustFallbackUpload({
|
||||
debugLabel,
|
||||
imageIndex: 1,
|
||||
reason: "provider-error",
|
||||
sourceBuffer: sourceImage.sourceBuffer,
|
||||
sourceHeight: sourceImage.sourceHeight,
|
||||
sourceWidth: sourceImage.sourceWidth,
|
||||
verification: scaleAdjustVerification,
|
||||
});
|
||||
|
||||
await recordAiModelHealthFailure({
|
||||
model: selectedModel.model,
|
||||
provider,
|
||||
error: caughtError,
|
||||
context: debugLabel,
|
||||
elapsedMs: Date.now() - startedAt,
|
||||
metadata: {
|
||||
aspectRatio,
|
||||
imageSize,
|
||||
imageCount,
|
||||
requestedReferenceImageCount: normalizedReferenceImages.length,
|
||||
reachableReferenceImageCount: reachableReferenceImages.length,
|
||||
effectiveReferenceImageCount: effectiveReferenceImages.length,
|
||||
droppedReferenceImageCount: unreachableReferenceImages.length,
|
||||
scaleAdjustFallbackReason: "provider-error",
|
||||
...debugMeta,
|
||||
},
|
||||
}).catch((healthError) => {
|
||||
console.warn("[Canvas Generate Image] Record model health failure failed:", {
|
||||
selectedModelRef: selectedModel.model.id,
|
||||
selectedModelId: selectedModel.model.modelId,
|
||||
error: healthError instanceof Error ? healthError.message : String(healthError),
|
||||
});
|
||||
});
|
||||
|
||||
recordCanvasImageModelExecutionDuration(
|
||||
resolvedModelKey,
|
||||
Date.now() - startedAt
|
||||
);
|
||||
|
||||
console.warn("[Canvas Generate Image] Scale adjust provider failed; returned deterministic fallback:", {
|
||||
debugLabel,
|
||||
elapsedMs: Date.now() - startedAt,
|
||||
providerType: provider.type,
|
||||
selectedModelRef: selectedModel.model.id,
|
||||
selectedModelId: selectedModel.model.modelId,
|
||||
error: caughtError instanceof Error ? caughtError.message : String(caughtError),
|
||||
...debugMeta,
|
||||
});
|
||||
|
||||
return {
|
||||
images: [fallbackImage],
|
||||
model: selectedModel.model.displayName,
|
||||
modelRef: selectedModel.model.id,
|
||||
prompt: resultPrompt,
|
||||
};
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
console.warn("[Canvas Generate Image] Scale adjust provider-error fallback failed:", {
|
||||
debugLabel,
|
||||
error:
|
||||
fallbackError instanceof Error
|
||||
? fallbackError.message
|
||||
: String(fallbackError),
|
||||
originalError:
|
||||
caughtError instanceof Error ? caughtError.message : String(caughtError),
|
||||
regionCount: scaleAdjustVerification.regions.length,
|
||||
scalePercent: scaleAdjustVerification.scalePercent,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await recordAiModelHealthFailure({
|
||||
model: selectedModel.model,
|
||||
provider,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user