refactor(canvas): 节点注册表 - 收敛素材类型、生成模式与输入计数判据
把三条按类型分支的语义判据收进注册表: - resourceKind 原 canvas-resource-references.ts,作为 @ 引用素材时的类型 - generationMode 原 canvas-connection-policy.ts,作为生成节点时的模式 - inputKind 原 canvas-connection-policy.ts,被容量校验计数时的类别 resourceKind 与 inputKind 刻意分成两个字段:它们语义不同——空图片节点不是素材 (不进 @ 引用),但照样计入 imageCount。合成一个会静默改掉连线容量校验。 两处必须保住的语义,均已由测试钉住: 1. 角色卡(workflowKind === character)是跨类型覆盖,对任何节点类型生效, 属于查注册表之前的前置判定,因此留在调用点而不进 per-type 定义。 2. 排除必须早于覆盖。原实现先 return 掉生成配置与背板,之后才判角色卡; 若把角色卡判定提前,带角色元数据的配置/背板节点会被多算成 characterCount。 新增 test/canvas-node-registry.test.ts(19 用例 / 77 断言)并加入 package.json 的 test 列表——该列表是显式枚举,不加进去文件不会跑。补测的原因是 canvas-resource-references.test.ts 只覆盖 collectUpstreamVideoNodes, 本次改动的 resourceKind 此前零覆盖,而这类判据出错不报错、只会让 @ 引用少收素材。 顺带内联 nodeGenerationMode(迁移后退化为单行转发)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,18 +26,27 @@ const BUILTIN_NODE_TRAITS = {
|
||||
minSize: MEDIA_NODE_MIN_SIZE,
|
||||
keepAspectRatio: (node: CanvasNodeData) => !node.metadata?.freeResize,
|
||||
showInCreateMenu: true,
|
||||
resourceKind: (node: CanvasNodeData) => (node.metadata?.content ? "image" : null),
|
||||
generationMode: () => "image",
|
||||
inputKind: "image",
|
||||
},
|
||||
[CanvasNodeType.Text]: {
|
||||
label: "文本",
|
||||
icon: <Type />,
|
||||
minSize: DEFAULT_MIN_SIZE,
|
||||
showInCreateMenu: true,
|
||||
resourceKind: (node: CanvasNodeData) => (node.metadata?.content || node.metadata?.prompt ? "text" : null),
|
||||
generationMode: () => "text",
|
||||
inputKind: "text",
|
||||
},
|
||||
[CanvasNodeType.Drawing]: {
|
||||
label: "绘图",
|
||||
icon: <Pencil />,
|
||||
minSize: DEFAULT_MIN_SIZE,
|
||||
showInCreateMenu: true,
|
||||
// 绘图产出的是图像,所以作为素材与输入都按图片计。
|
||||
resourceKind: (node: CanvasNodeData) => (node.metadata?.drawingId ? "image" : null),
|
||||
inputKind: "image",
|
||||
},
|
||||
[CanvasNodeType.Script]: {
|
||||
label: "分镜脚本",
|
||||
@@ -45,6 +54,8 @@ const BUILTIN_NODE_TRAITS = {
|
||||
// 分镜脚本的表格布局需要更宽的下限;高度仍由内容动态撑开(见 canvas-node.tsx)。
|
||||
minSize: { width: 800, height: DEFAULT_MIN_SIZE.height },
|
||||
showInCreateMenu: true,
|
||||
generationMode: () => "text",
|
||||
inputKind: "text",
|
||||
},
|
||||
[CanvasNodeType.Skill]: {
|
||||
label: "技能",
|
||||
@@ -52,6 +63,9 @@ const BUILTIN_NODE_TRAITS = {
|
||||
minSize: DEFAULT_MIN_SIZE,
|
||||
// 技能节点由技能库插入,不占创建菜单格位。
|
||||
showInCreateMenu: false,
|
||||
// 技能注入的是提示词文本,故按文本素材计。
|
||||
resourceKind: (node: CanvasNodeData) => (node.metadata?.skillSnapshot || node.metadata?.content ? "text" : null),
|
||||
inputKind: "text",
|
||||
},
|
||||
[CanvasNodeType.Config]: {
|
||||
label: "生成配置",
|
||||
@@ -59,6 +73,9 @@ const BUILTIN_NODE_TRAITS = {
|
||||
minSize: DEFAULT_MIN_SIZE,
|
||||
// 生成配置由连线时自动创建。
|
||||
showInCreateMenu: false,
|
||||
// 生成模式由用户在配置节点上选择,缺省按图片。
|
||||
generationMode: (node: CanvasNodeData) => node.metadata?.generationMode || "image",
|
||||
// 不设 inputKind:配置节点本身不是参考素材,不参与容量计数。
|
||||
},
|
||||
[CanvasNodeType.Video]: {
|
||||
label: "视频",
|
||||
@@ -66,12 +83,18 @@ const BUILTIN_NODE_TRAITS = {
|
||||
minSize: MEDIA_NODE_MIN_SIZE,
|
||||
keepAspectRatio: () => true,
|
||||
showInCreateMenu: true,
|
||||
resourceKind: (node: CanvasNodeData) => (node.metadata?.content ? "video" : null),
|
||||
generationMode: () => "video",
|
||||
inputKind: "video",
|
||||
},
|
||||
[CanvasNodeType.Audio]: {
|
||||
label: "音频",
|
||||
icon: <Music2 />,
|
||||
minSize: DEFAULT_MIN_SIZE,
|
||||
showInCreateMenu: true,
|
||||
resourceKind: (node: CanvasNodeData) => (node.metadata?.content ? "audio" : null),
|
||||
generationMode: () => "audio",
|
||||
inputKind: "audio",
|
||||
},
|
||||
[CanvasNodeType.Frame]: {
|
||||
label: "背板",
|
||||
@@ -80,6 +103,7 @@ const BUILTIN_NODE_TRAITS = {
|
||||
icon: <PanelTop />,
|
||||
minSize: DEFAULT_MIN_SIZE,
|
||||
showInCreateMenu: true,
|
||||
// 背板只是视觉容器,既不是素材也不参与计数。
|
||||
},
|
||||
} satisfies Record<CanvasNodeType, Omit<CanvasNodeDefinition, "type" | "defaultTitle" | "defaultSize" | "defaultMetadata">>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user