fix: prefer detail model for scale adjustments

This commit is contained in:
134 2026-06-22 01:22:25 +08:00
parent dd65ef46a7
commit eb2153818d
2 changed files with 100 additions and 6 deletions

View File

@ -9,7 +9,11 @@ import {
getCanvasImageTaskForUser,
} from "@/lib/canvas/image-task-queue";
import type { CanvasGenerateImageRequest } from "@/lib/canvas/generate-image";
import { getPointsSystemConfig, getSiteSettings } from "@/lib/db/queries";
import {
getEnabledAiModelsWithProvider,
getPointsSystemConfig,
getSiteSettings,
} from "@/lib/db/queries";
import { getImageToolCreditCost } from "@/lib/points/config";
import { prepareFeaturePointsCharge } from "@/lib/points/feature-charge";
import { uploadFile } from "@/lib/storage/service";
@ -89,6 +93,9 @@ type ScaleAdjustCropReference = {
regionIndex: number;
url: string;
};
type AiModelWithProviderForSelection = Awaited<
ReturnType<typeof getEnabledAiModelsWithProvider>
>[number];
const DEFAULT_REGION_COLORS = [
"#ff3b30",
"#1677ff",
@ -179,6 +186,61 @@ function normalizeHexColor(input: unknown, fallback: string) {
return /^#[0-9a-f]{6}$/i.test(expanded) ? expanded.toLowerCase() : fallback;
}
function findModelSelectionEntry(
models: AiModelWithProviderForSelection[],
modelRef: string
) {
const normalizedRef = String(modelRef || "").trim();
if (!normalizedRef) return null;
return (
models.find(
(entry) =>
entry.model.id === normalizedRef || entry.model.modelId === normalizedRef
) || null
);
}
function isScaleAdjustDedicatedDetailModel(
entry: AiModelWithProviderForSelection | null | undefined
) {
if (!entry?.model?.supportsImageGen || entry.model.supportsVision === false) {
return false;
}
const label = `${entry.model.displayName || ""} ${entry.model.modelId || ""}`
.toLowerCase()
.replace(/\s+/g, "");
return label.includes("详情专线");
}
function resolveScaleAdjustPreferredModelId(params: {
configuredModelId: string;
requestedModelId: string;
models: AiModelWithProviderForSelection[];
}) {
const requestedModel = findModelSelectionEntry(
params.models,
params.requestedModelId
);
if (isScaleAdjustDedicatedDetailModel(requestedModel)) {
return requestedModel?.model.id || params.requestedModelId;
}
const configuredModel = findModelSelectionEntry(
params.models,
params.configuredModelId
);
if (isScaleAdjustDedicatedDetailModel(configuredModel)) {
return configuredModel?.model.id || params.configuredModelId;
}
const autoDetailModel = params.models.find(isScaleAdjustDedicatedDetailModel);
if (autoDetailModel) {
return autoDetailModel.model.id;
}
return params.configuredModelId || params.requestedModelId;
}
function normalizeHttpImageUrl(input: unknown) {
const raw = String(input || "").trim();
if (!/^https?:\/\//i.test(raw)) return "";
@ -805,9 +867,21 @@ export async function POST(request: NextRequest) {
);
}
const [pointsConfig, siteSettingsForModel] = await Promise.all([
const shouldUseScaleAdjustDetailModel =
operation === SCALE_ADJUST_OPERATION && scalePercent !== null;
const [pointsConfig, siteSettingsForModel, scaleAdjustModelCandidates] =
await Promise.all([
getPointsSystemConfig(),
getSiteSettings().catch(() => null),
shouldUseScaleAdjustDetailModel
? getEnabledAiModelsWithProvider(false, true).catch((error) => {
console.warn(
"[Canvas Local Edit] Failed to load scale adjust model candidates:",
error
);
return [] as AiModelWithProviderForSelection[];
})
: Promise.resolve([] as AiModelWithProviderForSelection[]),
]);
const pointsCharge = await prepareFeaturePointsCharge({
userId: session.user.id,
@ -887,10 +961,28 @@ export async function POST(request: NextRequest) {
typeof body.model === "string" && body.model.trim()
? body.model.trim()
: undefined;
const detailFixedModel =
isScaleAdjustOperation && typeof siteSettingsForModel?.canvasDetailDefaultModelId === "string"
const configuredDetailModel =
typeof siteSettingsForModel?.canvasDetailDefaultModelId === "string"
? siteSettingsForModel.canvasDetailDefaultModelId.trim()
: "";
const detailFixedModel = isScaleAdjustOperation
? resolveScaleAdjustPreferredModelId({
configuredModelId: configuredDetailModel,
requestedModelId: requestedModel || "",
models: scaleAdjustModelCandidates,
})
: "";
if (
isScaleAdjustOperation &&
detailFixedModel &&
detailFixedModel !== configuredDetailModel
) {
console.info("[Canvas Local Edit] Override scale adjust model to detail line:", {
configuredDetailModel: configuredDetailModel || null,
requestedModel: requestedModel || null,
resolvedModel: detailFixedModel,
});
}
const resolvedModel = detailFixedModel || requestedModel;
const scaleAdjustCompositeRegions = isScaleAdjustOperation
? buildScaleAdjustCompositeRegions(
@ -908,6 +1000,7 @@ export async function POST(request: NextRequest) {
annotatedReferenceUrl: annotatedUpload.url,
annotatedReferenceSentToModel: isScaleAdjustOperation,
cleanSourceReferenceIndex: 1,
configuredDetailModelId: configuredDetailModel || null,
detailFixedModelApplied: Boolean(detailFixedModel),
detailFixedModelId: detailFixedModel || null,
displayPrompt,

View File

@ -6142,8 +6142,9 @@ export function AgentGenerationWorkspaceDarkV2({
return;
}
if (detailLocalEditSubmittingId) return;
const resolvedLocalEditModelId =
selectedModelId !== "auto"
const resolvedLocalEditModelId = isScaleAdjust
? undefined
: selectedModelId !== "auto"
? selectedModelId
: effectiveDefaultModelId || undefined;