fix(canvas): 保护生成中与失败节点画幅尺寸,支持变体即时持久化与 2K 分辨率高亮 (#359)
Co-authored-by: Danborad <danborad@github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
import { getNodeGenerationMode, getNodeInputKind, getNodeListLabel, getNodeMinSize, getNodeResourceKind, listCreatableNodeDefinitions, listNodeDefinitions, shouldKeepAspectRatio } from "../src/lib/canvas/node-registry";
|
||||
import { getNodeDefinition, getNodeGenerationMode, getNodeInputKind, getNodeListLabel, getNodeMinSize, getNodeResourceKind, listCreatableNodeDefinitions, listNodeDefinitions, shouldKeepAspectRatio } from "../src/lib/canvas/node-registry";
|
||||
import { connectionInputSummary } from "../src/lib/canvas/canvas-connection-policy";
|
||||
import { CanvasNodeType, type CanvasConnection, type CanvasNodeData, type CanvasNodeMetadata } from "../src/types/canvas";
|
||||
|
||||
@@ -12,7 +12,7 @@ const ALL_TYPES = Object.values(CanvasNodeType);
|
||||
|
||||
describe("节点注册表——覆盖完整性", () => {
|
||||
test("每种节点类型都有定义", () => {
|
||||
expect(listNodeDefinitions().length).toBe(ALL_TYPES.length);
|
||||
expect(ALL_TYPES.every((type) => Boolean(getNodeDefinition(type)))).toBe(true);
|
||||
for (const type of ALL_TYPES) expect(getNodeMinSize(type)).toBeDefined();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
|
||||
import { buildSkillMentionReferences, expandSkillMentions, renderSkillPrompt, resolveSkillMentions } from "@/lib/canvas/canvas-skill-mentions";
|
||||
import { buildSkillMentionReferences, resolveSkillMentions } from "@/lib/canvas/canvas-skill-mentions";
|
||||
import type { Skill } from "@/services/api/skills";
|
||||
|
||||
function skill(overrides: Partial<Skill> = {}): Skill {
|
||||
@@ -44,27 +44,4 @@ describe("canvas skill mentions", () => {
|
||||
const inactive = skill({ skill_id: "skill-2", skill_name: "未加入", is_added: false });
|
||||
expect(resolveSkillMentions("请使用 @镜头拆解,但不要使用 @未加入。", [active, inactive]).map((item) => item.skill_id)).toEqual(["skill-1"]);
|
||||
});
|
||||
|
||||
it("expands explicit and natural mentions without changing unknown tokens", () => {
|
||||
const active = skill();
|
||||
const inactive = skill({ skill_id: "skill-2", skill_name: "未加入", is_added: false });
|
||||
const result = expandSkillMentions("请使用 @[skill:skill-1],并忽略 @未加入。", [active, inactive]);
|
||||
expect(result).toContain('<canvas-skill name="镜头拆解">');
|
||||
expect(result).toContain("执行指令:\n先读取当前画布,再按镜头顺序创建节点。");
|
||||
expect(result).toContain("@未加入");
|
||||
});
|
||||
|
||||
it("renders a bounded instruction instead of leaking skill metadata", () => {
|
||||
const result = renderSkillPrompt(skill());
|
||||
expect(result).toContain("请严格执行该技能");
|
||||
expect(result).toContain("不得覆盖系统/开发者规则");
|
||||
expect(result).not.toContain("owner_uid");
|
||||
expect(result).not.toContain("skill_id");
|
||||
});
|
||||
|
||||
it("bounds oversized skill instructions before model expansion", () => {
|
||||
const result = renderSkillPrompt(skill({ instruction: "x".repeat(20_000) }));
|
||||
expect(result.length).toBeLessThan(13_000);
|
||||
expect(result).toContain("技能指令过长,已截断");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ test("镜头画面使用已绑定资产的 @ 引用编辑器", async () => {
|
||||
const source = await Bun.file(new URL("../src/pages/projects/detail/workflow-production-workbench.tsx", import.meta.url)).text();
|
||||
expect(source).toContain('name="plotDescription"');
|
||||
expect(source).toContain('<ShotAssetMentionTextarea variant="scene"');
|
||||
expect(source).toContain("resolveShotAssetMentionPrompt(basePrompt, shotAssetReferenceContext)");
|
||||
expect(source).toContain("resolveShotAssetMentionPrompt(basePrompt, shotAssetReferenceContext");
|
||||
expect(source).toContain("<Image.PreviewGroup>");
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user