fix(canvas): 媒体生成 - 修复已有图片引用和图片音频视频模型匹配

This commit is contained in:
ddCat
2026-08-29 14:49:59 +08:00
parent d66c7adc2c
commit d84b2b69cc
8 changed files with 159 additions and 13 deletions

View File

@@ -216,10 +216,26 @@ describe("逻辑模型选择", () => {
test("音频仅在单独参考时归类为音频生视频", () => {
expect(inferVideoOperation({ textCount: 1, imageCount: 0, videoCount: 0, audioCount: 1, characterCount: 0 })).toBe("audio_to_video");
expect(inferVideoOperation({ textCount: 1, imageCount: 1, videoCount: 0, audioCount: 1, characterCount: 0 })).toBe("reference_to_video");
expect(inferVideoOperation({ textCount: 1, imageCount: 1, videoCount: 0, audioCount: 1, characterCount: 0 })).toBe("image_to_video");
expect(inferVideoOperation({ textCount: 1, imageCount: 0, videoCount: 1, audioCount: 1, characterCount: 0 })).toBe("reference_to_video");
});
test("图片加音频可匹配支持图生视频和参考音频的模型", () => {
const config = policyConfig();
const imageModel = "relay::cinema-image";
const imageCost = config.channels[0]?.modelCosts?.find((item) => item.model === "cinema-image");
if (!imageCost?.capabilityConfig?.video) throw new Error("缺少图生视频能力配置");
imageCost.capabilityConfig.video.references.maxAudios = 1;
const requirements = {
capability: "video" as const,
input: { textCount: 0, imageCount: 1, videoCount: 0, audioCount: 1, characterCount: 0 },
videoSeconds: "6",
};
expect(modelCompatibilityError(config, imageModel, requirements)).toBe("");
expect(resolveCompatibleModel(config, "relay::cinema-text", requirements)).toBe(imageModel);
});
test("逻辑视频模型将 720 与 720p 视为同一分辨率", () => {
const model = "cinema-720p";
const channel: ModelChannel = {

View File

@@ -32,6 +32,31 @@ function connection(fromNodeId: string): CanvasConnection {
}
describe("canvas node generation position mentions", () => {
test("已有图片节点显式引用自身时作为图生图参考图提交", () => {
const source = node("image-self", CanvasNodeType.Image, "data:image/png;base64,a");
source.metadata.composerContent = "将 @图片1 图片变清晰";
const context = buildNodeGenerationContext(source.id, [source], [], source.metadata.composerContent, []);
expect(context.referenceImages.map((image) => image.id)).toEqual([source.id]);
expect(context.imageCount).toBe(1);
expect(context.prompt).toBe("将 图片1 图片变清晰");
});
test("已有图片节点未显式引用自身时不自动退化为图生图", () => {
const source = node("image-self", CanvasNodeType.Image, "data:image/png;base64,a");
const context = buildNodeGenerationContext(source.id, [source], [], "生成一个新的构图", []);
expect(context.referenceImages).toEqual([]);
expect(context.imageCount).toBe(0);
expect(context.prompt).toBe("生成一个新的构图");
});
test("无法解析的画布引用会阻止静默降级为文生图", () => {
const target = targetNode();
expect(() => buildNodeGenerationContext(target.id, [target], [], "将 @图片1 图片变清晰", [])).toThrow("@图片1 没有对应的画布资源");
});
test("同一个 @图片1 在换线后自动指向新的第一张图片", () => {
const target = targetNode();
const imageA = node("image-a", CanvasNodeType.Image, "data:image/png;base64,a");

View File

@@ -1325,7 +1325,7 @@ test("remote image video and audio references keep Backend parity without Dreami
referenceAudios: [{ id: "remote-image-audio-audio-0001", name: "reference.mp3", type: "audio/mpeg", url: "", storageKey: "resource:remote-image-audio-audio-0001" }],
},
result: { mode: "video", video: { dataUrl: "opaque://video", storageKey: "resource:remote-image-audio-output" } },
operation: "reference_to_video",
operation: "image_to_video",
},
{
mode: "audio" as const,