fix: constrain scale adjust failover family

This commit is contained in:
134 2026-07-02 10:34:41 +08:00
parent d44a5d4060
commit 0ec99e8ffb
2 changed files with 69 additions and 2 deletions

View File

@ -1499,6 +1499,8 @@ export async function POST(request: NextRequest) {
: undefined, : undefined,
scaleAdjustPreferSameNameProviderFailover: scaleAdjustPreferSameNameProviderFailover:
isScaleAdjustOperation && Boolean(scaleAdjustModelFamily), isScaleAdjustOperation && Boolean(scaleAdjustModelFamily),
scaleAdjustStrictSameFamilyFailover:
isScaleAdjustOperation && Boolean(scaleAdjustModelFamily),
manualRegionReferenceImageCount: manualRegionReferenceImageUrls.length, manualRegionReferenceImageCount: manualRegionReferenceImageUrls.length,
regionReferenceImageCount: regionReferenceImageCount:
referenceImages.length, referenceImages.length,

View File

@ -1737,6 +1737,39 @@ function normalizeModelNameForSimilarity(value: unknown) {
.replace(/\s+/g, " "); .replace(/\s+/g, " ");
} }
function resolveCanvasScaleAdjustModelFamilyFromText(value: unknown) {
const normalized = normalizeModelNameForSimilarity(value);
const compact = normalized.replace(/[^a-z0-9]+/g, "");
if (!normalized && !compact) return "";
if (
normalized.includes("gemini-3-1-flash-image-preview") ||
normalized.includes("gemini-3.1-flash-image-preview") ||
normalized.includes("nano-banana-2") ||
compact.includes("nanobanana2")
) {
return "nano-banana-2";
}
if (
normalized.includes("gemini-3-pro-image-preview") ||
normalized.includes("nano-banana-pro") ||
compact.includes("nanobananapro")
) {
return "nano-banana-pro";
}
if (normalized.includes("gpt-image-2") || compact.includes("gptimage2")) {
return "gpt-image-2";
}
return "";
}
function getCanvasScaleAdjustModelFamily(item: CanvasModelWithProvider) {
return (
resolveCanvasScaleAdjustModelFamilyFromText(item.model.modelId) ||
resolveCanvasScaleAdjustModelFamilyFromText(item.model.displayName) ||
resolveCanvasScaleAdjustModelFamilyFromText(item.model.id)
);
}
function tokenizeModelNameForSimilarity(value: unknown) { function tokenizeModelNameForSimilarity(value: unknown) {
const normalized = normalizeModelNameForSimilarity(value); const normalized = normalizeModelNameForSimilarity(value);
const compact = normalized.replace(/[^a-z0-9\u4e00-\u9fa5]+/g, ""); const compact = normalized.replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "");
@ -1795,10 +1828,17 @@ function findCanvasFailoverModel(params: {
failedModelRefs: string[]; failedModelRefs: string[];
preferLowCostSameNameProviders?: boolean; preferLowCostSameNameProviders?: boolean;
requiresImageInput?: boolean; requiresImageInput?: boolean;
scaleAdjustModelFamily?: string | null;
}) { }) {
const failedRefs = new Set( const failedRefs = new Set(
params.failedModelRefs.map((item) => String(item || "").trim()).filter(Boolean) params.failedModelRefs.map((item) => String(item || "").trim()).filter(Boolean)
); );
const strictScaleAdjustModelFamily =
params.preferLowCostSameNameProviders &&
typeof params.scaleAdjustModelFamily === "string" &&
params.scaleAdjustModelFamily.trim()
? params.scaleAdjustModelFamily.trim()
: "";
const selectedFallbackRefs = [ const selectedFallbackRefs = [
params.selectedModel.model.fallbackModelId1, params.selectedModel.model.fallbackModelId1,
params.selectedModel.model.fallbackModelId2, params.selectedModel.model.fallbackModelId2,
@ -1807,10 +1847,17 @@ function findCanvasFailoverModel(params: {
.filter(Boolean); .filter(Boolean);
const isUsableFallback = (item: CanvasModelWithProvider) => { const isUsableFallback = (item: CanvasModelWithProvider) => {
const isSameFamilyScaleAdjustFallback = strictScaleAdjustModelFamily
? getCanvasScaleAdjustModelFamily(item) === strictScaleAdjustModelFamily
: false;
const isSameNameScaleAdjustFallback = const isSameNameScaleAdjustFallback =
params.preferLowCostSameNameProviders && params.preferLowCostSameNameProviders &&
scoreModelNameSimilarity(params.selectedModel, item) >= (isSameFamilyScaleAdjustFallback ||
CANVAS_FAILOVER_SAME_NAME_THRESHOLD; scoreModelNameSimilarity(params.selectedModel, item) >=
CANVAS_FAILOVER_SAME_NAME_THRESHOLD);
if (strictScaleAdjustModelFamily && !isSameFamilyScaleAdjustFallback) {
return false;
}
if ( if (
!item.model.isEnabled || !item.model.isEnabled ||
item.model.isSubModel || item.model.isSubModel ||
@ -1849,6 +1896,18 @@ function findCanvasFailoverModel(params: {
sameProviderType: item.provider.type === params.selectedModel.provider.type, sameProviderType: item.provider.type === params.selectedModel.provider.type,
})) }))
.sort((left, right) => { .sort((left, right) => {
if (strictScaleAdjustModelFamily) {
const leftPriority = getCanvasScaleAdjustFailoverPriority(left.item);
const rightPriority = getCanvasScaleAdjustFailoverPriority(right.item);
if (leftPriority !== rightPriority) return leftPriority - rightPriority;
if (right.nameSimilarity !== left.nameSimilarity) {
return right.nameSimilarity - left.nameSimilarity;
}
if (left.sameProviderType !== right.sameProviderType) {
return left.sameProviderType ? -1 : 1;
}
return left.index - right.index;
}
const leftSameName = const leftSameName =
left.nameSimilarity >= CANVAS_FAILOVER_SAME_NAME_THRESHOLD; left.nameSimilarity >= CANVAS_FAILOVER_SAME_NAME_THRESHOLD;
const rightSameName = const rightSameName =
@ -1922,6 +1981,10 @@ export async function generateCanvasImage(
request.debugMeta && typeof request.debugMeta === "object" request.debugMeta && typeof request.debugMeta === "object"
? request.debugMeta ? request.debugMeta
: undefined; : undefined;
const scaleAdjustModelFamily =
typeof debugMeta?.scaleAdjustModelFamily === "string"
? debugMeta.scaleAdjustModelFamily.trim()
: "";
const localEditComposite = normalizeLocalEditCompositeConfig( const localEditComposite = normalizeLocalEditCompositeConfig(
request.localEditComposite request.localEditComposite
); );
@ -1974,6 +2037,7 @@ export async function generateCanvasImage(
debugMeta?.scaleAdjustPreferSameNameProviderFailover debugMeta?.scaleAdjustPreferSameNameProviderFailover
), ),
requiresImageInput, requiresImageInput,
scaleAdjustModelFamily,
}); });
if (!imageInputFallback) { if (!imageInputFallback) {
@ -2578,6 +2642,7 @@ export async function generateCanvasImage(
debugMeta?.scaleAdjustPreferSameNameProviderFailover debugMeta?.scaleAdjustPreferSameNameProviderFailover
), ),
requiresImageInput: normalizedReferenceImages.length > 0, requiresImageInput: normalizedReferenceImages.length > 0,
scaleAdjustModelFamily,
}) })
: null; : null;