"""统一配音响应 Schema — Phase 3 CosyVoice 集成. 支持预置音色和克隆音色的统一响应格式。 """ from __future__ import annotations from datetime import datetime from typing import List, Literal, Optional from pydantic import BaseModel, Field class UnifiedVoiceItemResponse(BaseModel): """统一配音项响应。 同时支持预置音色(type=preset)和克隆音色(type=clone)。 """ id: str """音色 ID(预置音色为 voice_id,克隆音色为数据库 ID)""" type: Literal["preset", "clone"] """音色类型:preset=预置音色,clone=用户克隆音色""" name: str """音色展示名称""" description: str = "" """音色描述""" gender: str = "unknown" """性别:male/female/unknown""" language: str = "zh-CN" """语言代码""" voice_id: str = "" """CosyVoice 模型音色名""" voice_provider: str = "cosyvoice" """语音服务商""" audio_url: str = "" """音频 URL(克隆音色为上传的音频,预置音色为空)""" preview_url: str = "" """预览音频 URL(预置音色可能有)""" duration: float = 0 """音频时长(秒)""" file_size: int = 0 """文件大小(字节)""" status: str = "completed" """状态""" tags: List[str] = Field(default_factory=list) """标签列表""" # 克隆音色特有字段 user_id: Optional[str] = None """所属用户 ID(仅克隆音色)""" project_id: Optional[str] = None """所属项目 ID(仅克隆音色)""" voice_clone_profile_id: Optional[str] = None """关联的音色克隆档案 ID(仅克隆音色)""" created_at: Optional[datetime] = None """创建时间(仅克隆音色)""" updated_at: Optional[datetime] = None """更新时间(仅克隆音色)""" class UnifiedVoiceListResponse(BaseModel): """统一配音列表响应。""" items: list[UnifiedVoiceItemResponse] """音色列表(预置音色在前)""" total: int = 0 """总数""" preset_count: int = 0 """预置音色数量""" clone_count: int = 0 """克隆音色数量""" class PresetVoiceItemResponse(BaseModel): """预置音色项响应。""" voice_id: str """CosyVoice 模型音色名""" name: str """中文展示名""" description: str """音色描述""" gender: str """性别""" language: str = "zh-CN" """语言代码""" preview_url: str = "" """预览音频 URL""" tags: List[str] = Field(default_factory=list) """标签列表""" class PresetVoiceListResponse(BaseModel): """预置音色列表响应。""" items: list[PresetVoiceItemResponse] """预置音色列表""" total: int = 0 """总数"""