实现 SFX V2 T1 契约与提示词基础

统一前后端 SFX Prompt Unicode canonicalization、字符计数和 2048 边界
固化 52 个音效预设、追加规则及跨语言测试向量
演进共享音频请求响应、duration、Loop 和 V2 metadata 契约
增加 External model 输入矩阵纯函数并保持正式接线归属 T5
补齐前端提交、读取、深拷贝与请求边界回归测试
更新共享计划并标记 T1 完成且当前不可发布
This commit is contained in:
2026-08-06 13:05:48 +00:00
parent 6fd731f56c
commit cd80c085ff
24 changed files with 1559 additions and 97 deletions
@@ -190,6 +190,34 @@ describe('ImageCanvasLayerCommandModel', () => {
expect(removeCanvasLayers(layers, ['first'])).toEqual([layers[1]]);
});
it('deep-clones authoritative SFX metadata with generation inputs', () => {
const layer = createLayer({
id: 'sound-effect',
generationInputs: {
fields: [{ title: '用户描述', value: '金币落地' }],
references: [],
soundEffect: {
schemaVersion: 2,
userPrompt: '金币落地',
actualPrompt: 'A coin landing sound',
model: 'eleven_text_to_sound_v2',
durationMode: 'auto',
requestedDurationSeconds: null,
actualDurationSeconds: 4.8,
loop: false,
},
},
});
const clipboard = createCanvasLayerClipboard([layer], [layer.id], 'copy');
const cloned = clipboard?.layers[0];
expect(cloned?.generationInputs).toEqual(layer.generationInputs);
expect(cloned?.generationInputs).not.toBe(layer.generationInputs);
expect(cloned?.generationInputs?.soundEffect).not.toBe(
layer.generationInputs?.soundEffect,
);
});
it('moves layer z-indexes with the same commands as the context menu', () => {
const layers = [
createLayer({ id: 'bottom', zIndex: 1 }),