feat(canvas): 生成合同 - 统一节点参数并补充模型上下文能力

This commit is contained in:
ddCat committed 2026-09-19 20:32:05 +08:00
1 parent a59b77cf70
commit 3bf21d79af
18 files changed
+965 -40

No files matched your search

@@ -17,6 +17,7 @@ import type { CanvasNodeGenerationMode } from "@/components/canvas/canvas-node-p
import { CanvasNodeType, type CanvasAssistantSession, type CanvasConnection, type CanvasImageGenerationType, type CanvasNodeData, type CanvasNodeMetadata, type CanvasVideoEditOperation } from "@/types/canvas";
import type { ReferenceImage } from "@/types/image";
import type { ReferenceAudio, ReferenceVideo } from "@/types/media";
import { generationSpecMetadata, readNodeGenerationSpec, resolveGenerationSelection } from "@/lib/canvas/generation-contract";
export async function runBackendCanvasGenerationTask(
{
@@ -416,12 +417,18 @@ export function generationWorkflowMetadata(config: AiConfig): Pick<CanvasNodeMet
};
}
export function buildGenerationConfig(config: AiConfig, node: CanvasNodeData | undefined, mode: CanvasNodeGenerationMode, requirements?: ModelRequirements): AiConfig {
export function buildGenerationConfig(config: AiConfig, node: CanvasNodeData | undefined, mode: CanvasNodeGenerationMode, requirements?: ModelRequirements, displayOnly = false): AiConfig {
const generationSpec = node ? readNodeGenerationSpec(node) : undefined;
const selection = generationSpec?.mode === mode ? generationSpec.modelSelection : undefined;
const selectedModel = resolveGenerationSelection(config, selection);
if (selection && !selectedModel && !displayOnly) throw new Error("节点选择的模型或渠道已不可用,请重新选择模型后生成");
if (node && generationSpec?.mode === mode) node = { ...node, metadata: { ...node.metadata, ...generationSpecMetadata(generationSpec) } };
// 只有独立 Config 节点读取工作流元数据;普通图片/视频/音频节点始终按基础模型生成。
const workflowProvider = mode !== "text" && node?.type === CanvasNodeType.Config && resolveCanvasWorkflowProvider(node.metadata) === "runninghub" ? "runninghub" : "model";
const defaultModel = mode === "image" ? config.imageModel : mode === "video" ? config.videoModel : mode === "audio" ? config.audioModel : config.textModel;
const fallbackModel = mode === "image" ? defaultConfig.imageModel : mode === "video" ? defaultConfig.videoModel : mode === "audio" ? defaultConfig.audioModel : defaultConfig.textModel;
const storedModel = resolveCanvasGenerationModel(config, node?.metadata?.model, mode);
const storedModel = resolveCanvasGenerationModel(config, selectedModel || node?.metadata?.model, mode);
if (selection && selectedModel && !storedModel && !displayOnly) throw new Error("节点选择的模型不支持当前生成模式,请重新选择");
const preferredModel = storedModel || resolveCanvasGenerationModel(config, defaultModel, mode) || fallbackModel;
// 先合并节点上的实时选择,再做兼容性匹配。否则路由只看到全局默认值,节点改过的时长、分辨率或布尔能力无法参与分流。
const workflowParameters = node?.metadata?.workflowParameters || {};
@@ -507,10 +514,10 @@ export function buildGenerationConfig(config: AiConfig, node: CanvasNodeData | u
quality: generationDefaults.quality || requestedConfig.quality,
size: generationDefaults.size ?? requestedConfig.size,
transparentBackground: generationDefaults.transparentBackground || (requestedConfig.transparentBackground === "true" ? "true" : "false"),
videoSeconds: generationDefaults.videoSeconds || requestedConfig.videoSeconds,
videoSeconds: generationDefaults.videoSeconds ?? requestedConfig.videoSeconds,
vquality: generationDefaults.vquality ?? requestedConfig.vquality,
videoGenerateAudio: generationDefaults.videoGenerateAudio || requestedConfig.videoGenerateAudio,
videoWatermark: generationDefaults.videoWatermark || requestedConfig.videoWatermark,
videoGenerateAudio: generationDefaults.videoGenerateAudio ?? requestedConfig.videoGenerateAudio,
videoWatermark: generationDefaults.videoWatermark ?? requestedConfig.videoWatermark,
videoArkPrivateAssetUpload: requestedConfig.videoArkPrivateAssetUpload,
count: generationDefaults.count || requestedConfig.count,
};