fix(tts): P1 TTS emotion instruction format per voice type + missing CN aliases #1934

Merged
xiaoxia merged 1 commits from fix/p1-tts-emotion-enum into develop 2026-09-15 16:00:58 +08:00
Owner

背景

灵应 13:10 派 P1 任务指出:

  1. PR#1933 已合入的英文枚举映射里漏了 中性/伤心/吃惊 三个中文别名;
  2. CosyVoice v3 克隆音色应使用英文自然语言 instruction 格式("Speak in a {emotion} tone."),而非中文固定格式;
  3. 默认系统音色 longxiaochun_v3 等不支持 Instruct,不应传 instruction;
  4. 顺手修复 Staging E2E 过期用例(方案A:改用 from-assets 默认模板兜底)。

改动

1. emotion 映射补全(packages/application/cosyvoice_service.py)

补 中性→neutral / 伤心→sad / 吃惊→surprised 三个中文别名(灵应指定)。

2. instruction 格式按 voice 类型三路分支

新增 build_emotion_instruction(voice_id, emotion_enum)

voice 类型 判断条件 instruction 格式
克隆/设计音色 long*/loong* 前缀 "Speak in a {emotion} tone."(DashScope 克隆音色支持任意自然语言指令)
支持 emotion Instruct 的系统音色 longanyang/longanhuan/longhuhu_v3 "你说话的情感是{emotion}。"(官方固定中文格式,结尾中文句号不可省)
其他系统音色(含默认 longxiaochun_v3 默认音色/不支持 Instruct 返回空串,不传 instruction(官方列表标注 "Instruct: 不支持",传了会被 API 忽略/报错)

依据:阿里云百炼 CosyVoice 音色列表

  • longxiaochun_v3(默认音色)Instruct: 不支持
  • longanyang/longanhuan/longhuhu_v3 Instruct: 支持

3. voice_clones preview 白名单同步扩展

补 中性/吃惊/伤心 三个中文别名,错误提示文案更新。

4. 单测(210 个 emotion 相关用例全部通过)

  • test_cosyvoice_emotion.py:重构为按分支测,覆盖克隆音色英文格式 / 系统音色中文格式 / 默认音色不传 instruction / 大小写 / 别名 / 空值 / 未知值默认 neutral
  • test_ai_avatar_emotion_tts_lipsync.py:补克隆音色/longanyang/默认音色三路 payload 断言

5. E2E 修复

apps/web/e2e/core-generation.spec.ts:128 处已在 PR#1931(0e5127df)中改为 GET /templates + 默认模板兜底,方案A 已经生效,无需额外改动。

验证

  • 本地:15438 passed, 28 skipped(基线 15333 + 105 新/改)
  • black + ruff 全部通过
  • 提交后盯 CI
## 背景 灵应 13:10 派 P1 任务指出: 1. PR#1933 已合入的英文枚举映射里漏了 中性/伤心/吃惊 三个中文别名; 2. CosyVoice v3 克隆音色应使用英文自然语言 instruction 格式("Speak in a {emotion} tone."),而非中文固定格式; 3. 默认系统音色 longxiaochun_v3 等不支持 Instruct,不应传 instruction; 4. 顺手修复 Staging E2E 过期用例(方案A:改用 from-assets 默认模板兜底)。 ## 改动 ### 1. emotion 映射补全(packages/application/cosyvoice_service.py) 补 中性→neutral / 伤心→sad / 吃惊→surprised 三个中文别名(灵应指定)。 ### 2. instruction 格式按 voice 类型三路分支 新增 `build_emotion_instruction(voice_id, emotion_enum)`: | voice 类型 | 判断条件 | instruction 格式 | |---|---|---| | 克隆/设计音色 | 非 `long*/loong*` 前缀 | `"Speak in a {emotion} tone."`(DashScope 克隆音色支持任意自然语言指令) | | 支持 emotion Instruct 的系统音色 | `longanyang`/`longanhuan`/`longhuhu_v3` | `"你说话的情感是{emotion}。"`(官方固定中文格式,结尾中文句号不可省) | | 其他系统音色(含默认 `longxiaochun_v3`) | 默认音色/不支持 Instruct | **返回空串,不传 instruction**(官方列表标注 "Instruct: 不支持",传了会被 API 忽略/报错) | 依据:[阿里云百炼 CosyVoice 音色列表](https://help.aliyun.com/zh/model-studio/cosyvoice-voice-list) - longxiaochun_v3(默认音色)Instruct: 不支持 - longanyang/longanhuan/longhuhu_v3 Instruct: 支持 ### 3. voice_clones preview 白名单同步扩展 补 中性/吃惊/伤心 三个中文别名,错误提示文案更新。 ### 4. 单测(210 个 emotion 相关用例全部通过) - `test_cosyvoice_emotion.py`:重构为按分支测,覆盖克隆音色英文格式 / 系统音色中文格式 / 默认音色不传 instruction / 大小写 / 别名 / 空值 / 未知值默认 neutral - `test_ai_avatar_emotion_tts_lipsync.py`:补克隆音色/longanyang/默认音色三路 payload 断言 ### 5. E2E 修复 `apps/web/e2e/core-generation.spec.ts:128` 处已在 PR#1931(0e5127df)中改为 `GET /templates` + 默认模板兜底,方案A 已经生效,无需额外改动。 ## 验证 - 本地:15438 passed, 28 skipped(基线 15333 + 105 新/改) - black + ruff 全部通过 - 提交后盯 CI
xiaoxia added 1 commit 2026-09-15 15:36:47 +08:00
fix(tts): P1 TTS emotion instruction format per voice type + missing CN aliases
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m4s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 7m3s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m23s
AI Code Review / AI Code Review (pull_request) Successful in 6m29s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 18s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 2m28s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 24h11m34s
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Failing after 23h35m54s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 4m22s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 12m21s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 4m45s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 4m15s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 5m2s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 30s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 34s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 23h36m1s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 23h36m1s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 23h36m41s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 23h23m36s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 23h23m36s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 23h23m36s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 23h24m15s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 23h36m29s
CI/CD Pipeline / CI Gate (pull_request) Successful in 2s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 23h23m35s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 23h35m49s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 23h35m51s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Failing after 23h35m55s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 23h35m49s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 23h35m55s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 23h35m56s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 23h36m2s
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Failing after 23h36m35s
7f1d5c95f9
- Add missing CN aliases 中性→neutral, 伤心→sad, 吃惊→surprised (per 灵应 spec)
- Split instruction format by voice type:
  · Cloned/custom voices (non long*/loong* prefix): English 'Speak in a {emotion} tone.'
    (DashScope allows free-form natural language for cloned voices)
  · System voices supporting emotion Instruct (longanyang/longanhuan/longhuhu_v3):
    strict Chinese fixed format '你说话的情感是{emotion}。' per 阿里云百炼 docs
  · Other system voices (incl. default longxiaochun_v3 which doesn't support Instruct):
    skip instruction entirely to avoid being silently dropped/errored by API
- Expand preview emotion whitelist with new CN aliases
- Add/expand unit tests (210 emotion tests passing, 15438 total unit tests passing)
- E2E fix for templates CRUD was already done in PR#1931, no change needed

🚀 预览环境已部署

项目 详情
PR号 #1934
预览链接 https://pr-1934.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1934 | | 预览链接 | [https://pr-1934.preview.xiaoxiajianji.com](https://pr-1934.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia closed this pull request 2026-09-15 15:46:52 +08:00
xiaoxia reopened this pull request 2026-09-15 15:47:00 +08:00

🗑️ 预览环境已清理

PR #1934 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1934 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
xiaoxia merged commit 59fbbd8e26 into develop 2026-09-15 16:00:58 +08:00

🗑️ 预览环境已清理

PR #1934 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1934 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.