Skip to content

Commit 11ebc39

Browse files
committed
feat(tts): Enhance ElevenLabs TTS provider with async support and improved configuration
- Add async method `synthesize_async` to ElevenLabsTtsProvider - Implement synchronous `synthesize` method using `run_sync` - Update import handling with TYPE_CHECKING and dynamic module loading - Add support for optional API key configuration via environment variable - Improve type hints and module dependency management - Add example usage in `__main__` block for demonstration purposes
1 parent 1c49dd4 commit 11ebc39

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

agentle/tts/elevenlabs_tts_provider.py

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
1+
from __future__ import annotations
2+
13
import base64
4+
import os
25
from collections.abc import AsyncIterator
3-
from typing import override
6+
from typing import TYPE_CHECKING, override
47

58
from agentle.tts.audio_format import AudioFormat
69
from agentle.tts.output_format_type import OutputFormatType
710
from agentle.tts.speech_config import SpeechConfig
811
from agentle.tts.speech_result import SpeechResult
912
from agentle.tts.tts_provider import TtsProvider
10-
from agentle.utils.needs import needs
13+
from agentle.tts.voice_settings import VoiceSettings
14+
from agentle.utils.needs import check_modules
15+
16+
if TYPE_CHECKING:
17+
from elevenlabs import AsyncElevenLabs
1118

1219

1320
class ElevenLabsTtsProvider(TtsProvider):
21+
_client: AsyncElevenLabs
22+
23+
def __init__(self, api_key: str | None = None) -> None:
24+
super().__init__()
25+
check_modules("elevenlabs")
26+
from elevenlabs import AsyncElevenLabs
27+
28+
self._client = AsyncElevenLabs(
29+
api_key=api_key or os.getenv("ELEVENLABS_API_KEY")
30+
)
31+
1432
@override
15-
@needs("elevenlabs")
16-
async def synthesize(self, text: str, config: SpeechConfig) -> SpeechResult:
33+
async def synthesize_async(self, text: str, config: SpeechConfig) -> SpeechResult:
1734
from elevenlabs import AsyncElevenLabs
1835
from elevenlabs.types.voice_settings import (
1936
VoiceSettings as ElevenLabsVoiceSettings,
@@ -65,3 +82,27 @@ def _get_mime_type(self, output_format: OutputFormatType) -> AudioFormat:
6582
return "audio/opus"
6683
else:
6784
return "application/octet-stream" # fallback
85+
86+
87+
if __name__ == "__main__":
88+
from dotenv import load_dotenv
89+
90+
load_dotenv(override=True)
91+
tts_provider = ElevenLabsTtsProvider()
92+
audio = tts_provider.synthesize(
93+
"Oi, eu sou a Júlia. Assistente pessoal da Dany Braga do estúdio de fotografia. Em que posso ajudar você hoje?",
94+
config=SpeechConfig(
95+
voice_id="lWq4KDY8znfkV0DrK8Vb",
96+
model_id="eleven_v3",
97+
language_code="pt",
98+
voice_settings=VoiceSettings(
99+
stability=0.0,
100+
use_speaker_boost=None,
101+
similarity_boost=None,
102+
style=None,
103+
speed=None,
104+
),
105+
),
106+
)
107+
with open("audio.mp3", "wb") as file:
108+
file.write(base64.b64decode(audio.audio))

agentle/tts/tts_provider.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import abc
22

3+
from rsb.coroutines.run_sync import run_sync
4+
35
from agentle.tts.speech_config import SpeechConfig
46
from agentle.tts.speech_result import SpeechResult
57

68

79
class TtsProvider(abc.ABC):
10+
def synthesize(self, text: str, config: SpeechConfig) -> SpeechResult:
11+
return run_sync(self.synthesize_async, text=text, config=config)
12+
813
@abc.abstractmethod
9-
async def synthesize(self, text: str, config: SpeechConfig) -> SpeechResult: ...
14+
async def synthesize_async(
15+
self, text: str, config: SpeechConfig
16+
) -> SpeechResult: ...

0 commit comments

Comments
 (0)