fix(canvas): 保护生成中与失败节点画幅尺寸,支持变体即时持久化与 2K 分辨率高亮 (#359)

Co-authored-by: Danborad <danborad@github.com>
This commit is contained in:
Danborad
2026-08-31 12:28:12 +08:00
committed by GitHub
parent 76e5a166dc
commit 8d9ab03a66
10 changed files with 127 additions and 77 deletions

View File

@@ -79,15 +79,16 @@ export function buildNodeGenerationContext(nodeId: string, nodes: CanvasNodeData
assertResolvableGenerationMentions(prompt, mentionInputs);
const hasExplicitResourceMention = hasResolvableGenerationMention(prompt, mentionInputs);
const isWorkflowSource = sourceNode?.type === CanvasNodeType.Config && isCanvasWorkflowProvider(sourceNode.metadata);
if ((Boolean(sourceNode?.metadata?.composerContent?.trim()) && (sourceNode?.type === CanvasNodeType.Config || isWorkflowSource)) || hasExplicitResourceMention) {
const hasConnectedMedia = connectedInputs.some((input) => input.type === "image" || input.type === "video" || input.type === "audio" || input.type === "character");
if ((promptOnly && hasConnectedMedia) || (Boolean(sourceNode?.metadata?.composerContent?.trim()) && (sourceNode?.type === CanvasNodeType.Config || isWorkflowSource)) || hasExplicitResourceMention) {
const autoIncludeWorkflowMedia = isWorkflowSource;
return buildComposerGenerationContext(
mentionInputs,
prompt,
// 工作流节点由字段映射接收全部连线媒体;视频节点的历史首尾帧字段不能再额外追加参考图。
autoIncludeWorkflowMedia ? [] : [sourceNode?.metadata?.videoStartFrameNodeId, sourceNode?.metadata?.videoEndFrameNodeId].filter((id): id is string => Boolean(id)),
autoIncludeWorkflowMedia || (promptOnly && hasConnectedMedia) ? [] : [sourceNode?.metadata?.videoStartFrameNodeId, sourceNode?.metadata?.videoEndFrameNodeId].filter((id): id is string => Boolean(id)),
promptOnly,
autoIncludeWorkflowMedia,
autoIncludeWorkflowMedia || (promptOnly && hasConnectedMedia),
connectedInputs,
);
}

View File

@@ -4,7 +4,7 @@ import { Switch } from "antd";
import { ImageSettingsTheme } from "@/components/image-settings-panel";
import { boolConfig, isSeedanceFastModel, isSeedanceVideoConfig, normalizeSeedanceDuration, normalizeSeedanceRatio, normalizeSeedanceResolution, seedanceRatioOptions } from "@/lib/seedance-video";
import { type CanvasTheme } from "@/lib/canvas-theme";
import { formatVideoResolutionLabel, normalizeVideoDuration, videoDimensionsForRatioAndResolution, videoResolutionComparisonKey, VIDEO_DURATION_MIN } from "@/lib/video-generation-options";
import { formatVideoResolutionLabel, isVideoResolutionMatch, normalizeVideoDuration, videoDimensionsForRatioAndResolution, videoResolutionComparisonKey, VIDEO_DURATION_MIN } from "@/lib/video-generation-options";
import { modelCapabilityConfigFor, resolveVideoRatioValue, resolveVideoResolutionValue, videoDurationOptions, type VideoCapabilityConfig } from "@/lib/model-capabilities";
import { modelOptionName, resolveModelChannel, resolveModelRequestConfig, type AiConfig } from "@/stores/use-config-store";
@@ -51,7 +51,7 @@ export function VideoSettingsPanel({ config, onConfigChange, theme, showTitle =
{configuredResolutions.length ? <SettingGroup title="分辨率" color={theme.node.muted}>
<div className="grid grid-cols-3 gap-1.5">
{configuredResolutions.map((item) => (
<OptionPill key={item.value} selected={resolution === item.value} disabled={!hasPriceTierForVideoSelection(priceTiers, item.value, Number(seconds))} theme={theme} onClick={() => onConfigChange("vquality", item.value)}>
<OptionPill key={item.value} selected={isVideoResolutionMatch(resolution, item.value)} disabled={!hasPriceTierForVideoSelection(priceTiers, item.value, Number(seconds))} theme={theme} onClick={() => onConfigChange("vquality", item.value)}>
{item.label}
</OptionPill>
))}