feat(voice): add admin-configurable elevenlabs tts
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator, model_validator
|
||||
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
||||
|
||||
from services.shared.core import Role
|
||||
|
||||
@@ -98,6 +98,59 @@ class VoiceNameCollectionConfigOut(BaseModel):
|
||||
source: Literal["defaults", "database"] = "defaults"
|
||||
|
||||
|
||||
VoiceTTSProviderName = Literal["yandex", "elevenlabs", "openai"]
|
||||
VoiceTTSLanguage = Literal["ru", "kz"]
|
||||
|
||||
|
||||
class VoiceTTSLanguageConfig(BaseModel):
|
||||
model_config = ConfigDict(protected_namespaces=())
|
||||
|
||||
voice: str | None = None
|
||||
model_id: str | None = None
|
||||
language_code: str | None = None
|
||||
|
||||
@field_validator("voice", "model_id", "language_code", mode="before")
|
||||
@classmethod
|
||||
def _trim_optional_text(cls, value: str | None) -> str | None:
|
||||
if value is None:
|
||||
return None
|
||||
normalized = str(value).strip()
|
||||
return normalized or None
|
||||
|
||||
|
||||
class VoiceTTSProviderConfig(BaseModel):
|
||||
ru: VoiceTTSLanguageConfig = Field(default_factory=VoiceTTSLanguageConfig)
|
||||
kz: VoiceTTSLanguageConfig = Field(default_factory=VoiceTTSLanguageConfig)
|
||||
|
||||
|
||||
class VoiceTTSVoiceOption(BaseModel):
|
||||
value: str = Field(min_length=1)
|
||||
label: str = Field(min_length=1)
|
||||
|
||||
@field_validator("value", "label", mode="before")
|
||||
@classmethod
|
||||
def _trim_required_option_text(cls, value: str) -> str:
|
||||
normalized = str(value or "").strip()
|
||||
if not normalized:
|
||||
raise ValueError("Option value is required")
|
||||
return normalized
|
||||
|
||||
|
||||
class VoiceTTSConfig(BaseModel):
|
||||
provider: VoiceTTSProviderName = "yandex"
|
||||
yandex: VoiceTTSProviderConfig = Field(default_factory=VoiceTTSProviderConfig)
|
||||
elevenlabs: VoiceTTSProviderConfig = Field(default_factory=VoiceTTSProviderConfig)
|
||||
openai: VoiceTTSProviderConfig = Field(default_factory=VoiceTTSProviderConfig)
|
||||
|
||||
|
||||
class VoiceTTSConfigOut(BaseModel):
|
||||
config: VoiceTTSConfig
|
||||
updated_at: str | None = None
|
||||
source: Literal["defaults", "database"] = "defaults"
|
||||
provider_options: list[VoiceTTSProviderName] = Field(default_factory=list)
|
||||
voice_options: dict[str, dict[str, list[VoiceTTSVoiceOption]]] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class HealthResponse(BaseModel):
|
||||
status: str
|
||||
service: str
|
||||
|
||||
Reference in New Issue
Block a user