文档:冻结SFX生成优化V2实施口径

完善SFX V2权威设计、LLM参数、二进制与时长安全边界
新增可共享的T0至T6任务拆解、测试矩阵和迁移发布门禁
同步项目决策日志与文档索引
This commit is contained in:
2026-08-06 11:47:04 +00:00
parent b79f72391b
commit c72d295a84
4 changed files with 437 additions and 32 deletions
@@ -6710,3 +6710,20 @@
- 业务隔离:共享组件不等于共享规则。SFX 继续使用 Vidu `audio1.0`、2–10 秒、默认 5 秒、现有 Prompt 回退、1500 字限制、价格和提交链路;BGM 继续使用 canonical Prompt、200 字生成限制、30 个预设、AI 补全 / 简化、单层撤销、提交锁和 Suno。BGM 按 dialog ID 写回,SFX 继续走现有 `setGenerateDialog`,两条路径不得互换。
- 非目标:本次只规划视图归并,不实现 SFX V2 的 ElevenLabs、中译英、自动时长、30 秒、Loop、一键优化或预设,不修改任何后端、External v1、Schema、计费或需求原文,也不新建配置驱动的 composer 框架。
- 实施状态:已恢复共享音频 composer,独立完整 BGM composer 及其测试文件已删除,原覆盖完整迁入总 composer。Prompt / 预设 / controller / 总 composer `121/121`、surface 与 submission workflow `72/72` 通过,typecheck、变更文件 ESLint、Prettier、编码检查和差异检查通过;没有修改后端、契约或需求原文,也没有实现 SFX V2 独有功能。
## 2026-08-06 SFX 生成优化 V2.0 T0 设计与迁移口径
- 权威入口:SFX V2 的可编码规则已完整融合到 `docs/【编辑器】画板音乐生成入口设计-2026-06-18.md`。实现、审查、测试和发布只以该 tracked 权威设计、本条决策和共享实施计划为依据,不依赖团队通过 Git 无法取得的本地资料。
- 共享视图边界不变:`audio-sound-effect` 与 `audio-background-music` 继续共用 `ImageCanvasAudioGenerationComposerView`,通过 `isSoundEffect` 分流;SFX 和 BGM 的 Prompt 模型、controller、预设 wrapper、锁和提交契约分别维护,不新建独立页面或第二套音频系统。
- 后端入口边界:正式生成原地演进 `server-rs/crates/shared-contracts/src/assets.rs` 的现有音频 DTO 与 `server-rs/crates/api-server/src/vector_engine_audio_generation/generation.rs` 的现有 handler,保留既有 `/api/editor/audios/*/generations` 路由、queue / inline 分流、计费和队列边界;不得新建平行 DTO、正式生成 BFF、handler 或第二套路由。只有 SFX Prompt 优化内部路由、Worker 翻译 service 和 ElevenLabs adapter 是新增能力。
- provider 迁移:新编辑器 SFX 任务固定使用 ElevenLabs `eleven_text_to_sound_v2`,不提供模型选择、Vidu fallback 或 `audio1.0` alias。Vidu builder / 轮询仅保留给历史素材和其它未迁移调用方;历史素材可读,重绘新任务使用 ElevenLabs。
- Prompt 真相:`prompt` 表示用户可见且确认的 canonical `userPrompt`,`actual_prompt` 表示 Worker 严格验收后实际提交给 ElevenLabs 的英文 `actualPrompt`。两者均以 2048 Unicode code points 为上限,只删除首尾 Unicode `White_Space`,不做其它规范化、默认 Prompt 回退或静默截断。
- 可见交互:SFX 固定 40 个事件预设 + 12 个补充要求。空 Prompt 直接写入;非空 Prompt 末尾已是 Unicode 标点时直接追加,否则使用中文逗号 `,` 分隔。允许重复,不保留选中态,不去重或截断;点击预设清除旧快照。
- Prompt 助手:一键优化使用 `gpt-5.6-luna`、`reasoning_effort = medium`;Worker 正式英文化使用同模型、`reasoning_effort = low`。两类候选上限均为 2048 Unicode code points,因此分别固定 `max_output_tokens = 2048 × 4 = 8192`;真实 VectorEngine Chat 探测已确认该字段限制隐藏 reasoning token 与可见输出 token 共享的 completion 总预算,不包含输入 prompt token,也不是可见正文保证。预算不按实际输入长度动态缩小;两者均不发送 temperature 或 function tools,只接受完整 `response.text` 中唯一 JSON object 的严格 envelope。翻译除要求 `isEnglish = true` 外,程序侧还要求候选至少含一个 Latin alphabetic code point,且所有 alphabetic code point 都属于 Latin Script;日文假名、韩文、西里尔、希腊和阿拉伯等非 Latin 字母均失败。优化只有一个业务语义轮,`finish_reason = length` 直接失败;翻译首轮成功响应但候选不合格或 `length` 时使用同一 `userPrompt`、同一 `8192` 上限唯一重试,第二轮 `length` 最终失败,`content_filter` 和 transport 最终失败不开启第二业务语义轮。翻译最终失败时 ElevenLabs 请求数必须为 0。
- 撤销与锁:一键优化成功产生一层 canonical Prompt 交换快照;优化失败清除本次临时快照,不恢复更早快照。AI 操作和正式提交使用 dialog ID、账号 + 项目 scope、同步 operation ID 与 `AbortController`;只锁当前 SFX dialog。正式提交在第一个 `await` 前冻结 Prompt / duration / Loop;API 接受后结束 `submitting`、进入现有 `queued/generating` 占位,不把接受任务写成生成已完成。
- 时长与 Loop:首次打开默认手动时长模式、`5s`、Loop false;手动范围 `0.5-30s`,UI 步进 `0.1s`。自动模式发送 `duration_seconds = null`,禁用 slider 但保留最近手动值。Loop 是独立 API 布尔参数;系统不根据 Prompt 推断、同步或校验 Loop,Prompt 文本与 Loop 开关不建立业务一致性门禁。
- ElevenLabs 契约:`POST /v1/sound-generation`,body 固定 `text / model_id / duration_seconds / loop / prompt_influence=0.3`,query 固定 `output_format=mp3_44100_128`,`xi-api-key` 只在服务端 header 注入。provider POST 不自动重试,浏览器正式 POST 不 unsafe retry,队列 `max_attempts = 1`,一个平台 job 最多一次 ElevenLabs POST。成功响应复用现有 `MAX_GENERATED_AUDIO_BYTES = 40 MiB` 做 Content-Length 预检和 `limit + 1` 流式读取,验证 MIME 与真实 MP3,并探测有限正实际时长;实际时长仅受独立技术异常上限 `600s` 约束,不与请求最大 `30s` 比较,`30.5s-600s` 的合法结果可接受。平台使用 operation / queue job ID 作为 `taskId`,不伪造 provider task ID。
- 结果真相:服务端重建 SFX V2 `generation_inputs_json`,写入 `userPrompt / actualPrompt / model / durationMode / requestedDurationSeconds / actualDurationSeconds / loop`;实际英文 Prompt、实际时长、model 和 Loop 不信任客户端自报。信息弹窗展示用户 Prompt、实际英文 Prompt、模型、实际时长、Loop 和平台 Task ID;历史 Vidu 数据不误标英文 Prompt。
- 计费、External v1 与 schema:新模型键 `eleven_text_to_sound_v2` 保持 5 泥点 / 次,后端入队时冻结价格为真相。External v1 的 duration 演进为可选 / nullable `0.5-30 number`,Loop 缺省 false;`model` 的 omitted / null / 空串 / 纯空白 / 首尾空白包围的新模型 / 显式新模型统一 canonicalize 为 `eleven_text_to_sound_v2`,并产生相同幂等 payload。显式旧 `audio1.0` 和未知非空值返回 `400 BAD_REQUEST`,且必须为零入队、零预扣、零 LLM、零 provider;Rust、OpenAPI、幂等重放与最终响应必须在 T5 同批变更。本次不修改 SpacetimeDB schema,复用现有 `prompt`、`actual_prompt`、`generation_inputs_json` 和画布 layout。
- 共享计划:脱敏 T1–T6 任务、当前基线、测试矩阵、旧 Vidu 队列 drain、发布与回滚门禁记录在 `docs/project-memory/plans/【实施计划】SFX生成优化V2.0任务拆解-2026-08-06.md`。T0 只验收设计、决策、共享计划、差距归属和安全记录,不要求当前 Vidu V1 代码、OpenAPI 或实际 API 已与 SFX V2 设计一致;实现差距归入 T1–T5,T6 统一验收。
- 安全与状态:机器本地未跟踪资料不得进入提交,也不得被仓库文档链接、引用或作为团队证据源;ElevenLabs Key 只允许从服务端私密环境配置读取,不进入浏览器、日志、fixture、共享文档或 Git。旧凭据轮换失效的脱敏审计证据、业务 owner 和 API owner 签字尚未填写,因此 T0 暂未通过,T1–T5 不放行;不得伪造日期、责任人、工单或签字。