fix(canvas): 画布图片生成 - 参考图超限时停止生成并提示清理连线
保留全部已连接参考图,在首次生成、重试和任务入口统一校验模型上限。
This commit is contained in:
@@ -3,7 +3,7 @@ import { nanoid } from "nanoid";
|
||||
import { NODE_DEFAULT_SIZE } from "@/constant/canvas";
|
||||
import { canGenerateImageInPlace, findAvailableGenerationGroupPosition, imageGenerationChildPosition, imageGenerationGroupSize } from "@/lib/canvas/canvas-generation-layout";
|
||||
import { nodeSizeFromRatio } from "@/lib/canvas/canvas-node-size";
|
||||
import { buildImageGenerationMetadata, getGenerationCount, isGenerationCanceled, limitCanvasImageReferences, runCanvasGenerationTaskToConsumer } from "@/lib/canvas/canvas-project-generation";
|
||||
import { canvasImageReferenceLimitError, buildImageGenerationMetadata, getGenerationCount, isGenerationCanceled, runCanvasGenerationTaskToConsumer } from "@/lib/canvas/canvas-project-generation";
|
||||
import { CONTENT_MODERATION_ERROR_CODE, generationFailureMetadata, type GenerationFailureMetadata } from "@/lib/generation-error";
|
||||
import { CanvasNodeType, type CanvasNodeData } from "@/types/canvas";
|
||||
|
||||
@@ -39,13 +39,18 @@ export async function executeImageGeneration({
|
||||
showError,
|
||||
registerPendingNodeIds,
|
||||
}: CanvasGenerationExecution) {
|
||||
const referenceLimitError = canvasImageReferenceLimitError(generationConfig, generationContext.referenceImages);
|
||||
if (referenceLimitError) {
|
||||
showError(referenceLimitError);
|
||||
return;
|
||||
}
|
||||
const count = getGenerationCount(generationConfig.count);
|
||||
const isConfigNode = sourceNode?.type === CanvasNodeType.Config;
|
||||
const isImageNode = sourceNode?.type === CanvasNodeType.Image;
|
||||
const reuseSourceNode = canGenerateImageInPlace(sourceNode);
|
||||
const directCopiedBatch = count > 1 && isImageNode && Boolean(sourceNode?.metadata?.content) && (Boolean(sourceNode?.metadata?.copiedFromNodeId) || sourceNode?.title.endsWith(" Copy"));
|
||||
// 已有图片生成新结果并保留旧版本;参考图只来自入边,避免把旧结果误当成自身输入。
|
||||
const referenceImages = limitCanvasImageReferences(generationConfig, generationContext.referenceImages);
|
||||
const referenceImages = generationContext.referenceImages;
|
||||
const generationType = referenceImages.length ? ("edit" as const) : ("generation" as const);
|
||||
const generationMetadata = buildImageGenerationMetadata(generationType, generationConfig, count, referenceImages);
|
||||
const parentConfig = NODE_DEFAULT_SIZE[isConfigNode ? CanvasNodeType.Config : isImageNode ? CanvasNodeType.Image : CanvasNodeType.Text];
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
findRetrySourceNode,
|
||||
generationReferenceUrls,
|
||||
isGenerationCanceled,
|
||||
limitCanvasImageReferences,
|
||||
canvasImageReferenceLimitError,
|
||||
resolveMetadataReferences,
|
||||
resolveStoredReferenceImages,
|
||||
runBackendCanvasGenerationTask,
|
||||
@@ -108,7 +108,10 @@ export function useCanvasGenerationRetry({
|
||||
try {
|
||||
const promptOnly = retryMode === "video";
|
||||
const baseContext = buildNodeGenerationContext(sourceNode.id, nodesRef.current, connectionsRef.current, retryContextPrompt, assets, promptOnly);
|
||||
rawContext = hasSavedImageMetadata && !baseContext.characterReferences.length ? null : await hydrateNodeGenerationContext(baseContext, projectId, domainProjectId, retryMode, retryMode === "video" && supportsVideoReferenceAudio(generationConfig), !promptOnly);
|
||||
rawContext =
|
||||
hasSavedImageMetadata && !baseContext.characterReferences.length
|
||||
? null
|
||||
: await hydrateNodeGenerationContext(baseContext, projectId, domainProjectId, retryMode, retryMode === "video" && supportsVideoReferenceAudio(generationConfig), !promptOnly);
|
||||
} catch (error) {
|
||||
const failure = generationFailureMetadata(error, retryPromptSource);
|
||||
message.error(failure.errorDetails);
|
||||
@@ -168,7 +171,14 @@ export function useCanvasGenerationRetry({
|
||||
message.error("参考图片已丢失,无法继续重试");
|
||||
return;
|
||||
}
|
||||
const retryImages = retryMode === "image" ? limitCanvasImageReferences(generationConfig, retryReferenceImages || []) : retryReferenceImages || [];
|
||||
const retryImages = retryReferenceImages || [];
|
||||
if (retryMode === "image") {
|
||||
const referenceLimitError = canvasImageReferenceLimitError(generationConfig, retryImages);
|
||||
if (referenceLimitError) {
|
||||
message.error(referenceLimitError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const storedVideoImages = node.type === CanvasNodeType.Video && !context?.referenceImages.length ? await resolveStoredReferenceImages(node.metadata?.references) : [];
|
||||
if (storedVideoImages === null) {
|
||||
markMissingReferences(node.id, setNodes);
|
||||
|
||||
Reference in New Issue
Block a user