fix(canvas): restore reliable text editing
This commit is contained in:
parent
f95c6b2b2b
commit
7752ec42ee
@ -29,8 +29,9 @@ export const runtime = "nodejs";
|
||||
export const maxDuration = 1200;
|
||||
|
||||
const logger = createLogger("canvas-text-edit");
|
||||
const TEXT_EDIT_SOURCE_ARCHIVE_TIMEOUT_MS = 20_000;
|
||||
const TEXT_EDIT_SOURCE_ARCHIVE_TIMEOUT_MS = 120_000;
|
||||
const TEXT_EDIT_MODEL_FALLBACK_LIMIT = 3;
|
||||
const TEXT_EDIT_GENERATION_TIMEOUT_MS = 180_000;
|
||||
|
||||
const textItemSchema = z.object({
|
||||
id: z.string().min(1),
|
||||
@ -68,6 +69,13 @@ const SUPPORTED_TEXT_EDIT_PROVIDER_TYPES = new Set([
|
||||
|
||||
type TextEditModelCandidate = Awaited<ReturnType<typeof getEnabledAiModelsWithProvider>>[number];
|
||||
|
||||
function isExplicitTextEditModel(candidate: TextEditModelCandidate) {
|
||||
const capabilities = candidate.model.capabilities as Record<string, unknown> | null;
|
||||
const kind = String(capabilities?.kind || "").toLowerCase();
|
||||
const modelId = String(candidate.model.modelId || "").toLowerCase();
|
||||
return kind === "image-edit" || /(?:^|[/_-])edit(?:$|[/_-])/.test(modelId);
|
||||
}
|
||||
|
||||
function getTextEditModelCandidates(
|
||||
models: Awaited<ReturnType<typeof getEnabledAiModelsWithProvider>>
|
||||
) {
|
||||
@ -87,11 +95,13 @@ function getTextEditModelCandidates(
|
||||
.sort((a, b) => {
|
||||
const aScore =
|
||||
(a.model.isDefaultTextEditModel ? 100 : 0) +
|
||||
(isExplicitTextEditModel(a) ? 30 : 0) +
|
||||
(a.model.isDefault ? 10 : 0) +
|
||||
(a.model.modelId?.toLowerCase().includes("seedream") ? 5 : 0) +
|
||||
(a.model.displayName?.includes("火山") ? 3 : 0);
|
||||
const bScore =
|
||||
(b.model.isDefaultTextEditModel ? 100 : 0) +
|
||||
(isExplicitTextEditModel(b) ? 30 : 0) +
|
||||
(b.model.isDefault ? 10 : 0) +
|
||||
(b.model.modelId?.toLowerCase().includes("seedream") ? 5 : 0) +
|
||||
(b.model.displayName?.includes("火山") ? 3 : 0);
|
||||
@ -220,6 +230,13 @@ async function resolveTextEditSourceImageUrl(imageUrl: string) {
|
||||
} catch (error) {
|
||||
logger.warn("source_image_archive_failed", {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
sourceHost: (() => {
|
||||
try {
|
||||
return new URL(imageUrl).host;
|
||||
} catch {
|
||||
return "invalid-url";
|
||||
}
|
||||
})(),
|
||||
});
|
||||
return imageUrl;
|
||||
}
|
||||
@ -495,6 +512,7 @@ async function generateTextEditImageWithFailover(params: {
|
||||
],
|
||||
imageParams: {
|
||||
imageCount: 1,
|
||||
timeoutMs: TEXT_EDIT_GENERATION_TIMEOUT_MS,
|
||||
},
|
||||
};
|
||||
if (selected.provider.type === "atlascloud" || selected.provider.type === "vip98k") {
|
||||
|
||||
@ -56,6 +56,7 @@ const DEFAULT_SAFETY_TOLERANCE = "4";
|
||||
const DEFAULT_TIMEOUT_MS = 600000;
|
||||
const MIN_TIMEOUT_MS = 30_000;
|
||||
const MAX_TIMEOUT_MS = 600_000;
|
||||
const FAL_INPUT_IMAGE_DOWNLOAD_TIMEOUT_MS = 120_000;
|
||||
const FAL_GENERIC_MAX_EDGE = 4096;
|
||||
const FAL_GENERIC_MAX_PIXELS = 4096 * 4096;
|
||||
const GPT_IMAGE_2_MAX_EDGE = 3840;
|
||||
@ -679,7 +680,9 @@ async function uploadImageUrlToFalStorage(params: {
|
||||
const { fal, url } = params;
|
||||
if (/fal\.(?:media|run)\//i.test(url) || /fal-ai/i.test(url)) return url;
|
||||
|
||||
const response = await fetch(url, { signal: AbortSignal.timeout(60_000) });
|
||||
const response = await fetch(url, {
|
||||
signal: AbortSignal.timeout(FAL_INPUT_IMAGE_DOWNLOAD_TIMEOUT_MS),
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`FAL input image download failed before storage upload: ${response.status}`);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user