Skip to content

feat(tts): 全面接入 Gemini TTS 语音合成节点 - #326

Merged
bahamutww merged 2 commits into
mainfrom
dev
Sep 28, 2026
Merged

bahamutww merged 2 commits into
mainfrom
dev

Conversation

@bahamutww

Copy link
Copy Markdown
Contributor
  • 新增 Gemini TTS 供应商适配层,支持多语音模式及多种输出格式
  • 创建异步合成任务模型和复刻音色持久化表,完成数据库迁移
  • 实现后端服务编排、任务异步执行与实时状态推送
  • 开发丰富的路由接口,涵盖任务管理、音色复刻、扩展库及试听功能
  • 封装生成工具与 Agent 内置技能,支持智能体调用
  • 构建前端画布节点、多语音生成历史、语气风格选择器与内联音效标签
  • 管理端新增 TTS 配置界面及相关参数设定,支持计费维度拓展
  • 多语言支持及预置官方音色,完善用户体验和权限校验
  • 详细升级说明涵盖数据库迁移、模型预置、技能启用与计费配置等步骤

- 新增 Gemini TTS 供应商适配层,支持多语音模式及多种输出格式
- 创建异步合成任务模型和复刻音色持久化表,完成数据库迁移
- 实现后端服务编排、任务异步执行与实时状态推送
- 开发丰富的路由接口,涵盖任务管理、音色复刻、扩展库及试听功能
- 封装生成工具与 Agent 内置技能,支持智能体调用
- 构建前端画布节点、多语音生成历史、语气风格选择器与内联音效标签
- 管理端新增 TTS 配置界面及相关参数设定,支持计费维度拓展
- 多语言支持及预置官方音色,完善用户体验和权限校验
- 详细升级说明涵盖数据库迁移、模型预置、技能启用与计费配置等步骤
Comment thread backend/services/tts_generation.py Fixed
Comment thread backend/services/tts_providers/gemini_tts.py Fixed


# revision identifiers, used by Alembic.
revision: str = 'k8l9m0n1o2p3'

# revision identifiers, used by Alembic.
revision: str = 'k8l9m0n1o2p3'
down_revision: Union[str, Sequence[str], None] = 'j7k8l9m0n1o2'
# revision identifiers, used by Alembic.
revision: str = 'k8l9m0n1o2p3'
down_revision: Union[str, Sequence[str], None] = 'j7k8l9m0n1o2'
branch_labels: Union[str, Sequence[str], None] = None
revision: str = 'l9m0n1o2p3q4'
down_revision: Union[str, Sequence[str], None] = 'k8l9m0n1o2p3'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
Comment thread backend/services/tool_manager/providers/tts_gen.py Fixed
Comment thread backend/services/tts_generation.py Fixed
Comment thread backend/services/tts_providers/base.py Fixed
Comment thread backend/services/tts_providers/gemini_tts.py Fixed
- 添加 _sanitize_log 函数清理日志输出中的控制字符,防止日志注入 CWE-117
- 在 GeminiTTS 及语音注册日志中应用日志清洗函数
- 组件中用 useEffect 管理音频文件的 URL 对象,避免内存泄漏
- 限制 audio 标签的 src 仅接受 blob: 协议,防止潜在安全问题
- 添加文件大小校验,超过限制时拒绝上传并显示错误提示
- 更新中英文国际化文件,新增文件过大提示文本
- 微调和清理无用变量,保持代码整洁
await db.commit()
await db.refresh(voice)

logger.info("Registered replicated voice %s (%s) for user %s", result.voice_id, _sanitize_log(display_name), user_id)
logger.warning("GeminiTTS voice replication returned no voice id — keys: %s", list(data.keys()) if isinstance(data, dict) else type(data))
return ReplicationResult(status="failed", error="No voice ID in replication response")

logger.info("GeminiTTS voice replication success: %s (%s)", voice_id, _sanitize_log(display_name))
@bahamutww
bahamutww merged commit 34cc293 into main Sep 28, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants