Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

community:langchain_community:tools:eleven_labs: Fix the tool #27130

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 35 additions & 13 deletions libs/community/langchain_community/tools/eleven_labs/text2speech.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@

def _import_elevenlabs() -> Any:
try:
import elevenlabs
from elevenlabs import play, stream
from elevenlabs.client import ElevenLabs
except ImportError as e:
raise ImportError(
"Cannot import elevenlabs, please install `pip install elevenlabs`."
) from e
return elevenlabs
return ElevenLabs, play, stream


class ElevenLabsModel(str, Enum):
Expand All @@ -41,41 +42,62 @@ class ElevenLabsText2SpeechTool(BaseTool):
"It supports multiple languages, including English, German, Polish, "
"Spanish, Italian, French, Portuguese, and Hindi. "
)
eleven_api_key: Optional[str] = None

@model_validator(mode="before")
@classmethod
def validate_environment(cls, values: Dict) -> Any:
"""Validate that api key exists in environment."""
_ = get_from_dict_or_env(values, "eleven_api_key", "ELEVEN_API_KEY")

"""Validate that API key exists in environment or is provided directly."""
if not values.get("eleven_api_key"):
values["eleven_api_key"] = get_from_dict_or_env(
{}, "eleven_api_key", "ELEVEN_API_KEY"
)
return values

def _run(
self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None
) -> str:
"""Use the tool."""
elevenlabs = _import_elevenlabs()
ElevenLabs, _, _ = _import_elevenlabs()
try:
speech = elevenlabs.generate(text=query, model=self.model)
# Use the API key provided during initialization
api_key = self.eleven_api_key or get_from_dict_or_env(
{}, "eleven_api_key", "ELEVEN_API_KEY"
)
client = ElevenLabs(api_key=api_key)
speech = client.generate(text=query, model=self.model)

# Write the generator audio output to a file
with tempfile.NamedTemporaryFile(
mode="bx", suffix=".wav", delete=False
) as f:
f.write(speech)
for chunk in speech:
f.write(chunk)
return f.name
except Exception as e:
raise RuntimeError(f"Error while running ElevenLabsText2SpeechTool: {e}")

def play(self, speech_file: str) -> None:
"""Play the text as speech."""
elevenlabs = _import_elevenlabs()
_, play, _ = _import_elevenlabs()
with open(speech_file, mode="rb") as f:
speech = f.read()

elevenlabs.play(speech)
play(speech)

def stream_speech(self, query: str) -> None:
"""Stream the text as speech as it is generated.
Play the text in your speakers."""
elevenlabs = _import_elevenlabs()
speech_stream = elevenlabs.generate(text=query, model=self.model, stream=True)
elevenlabs.stream(speech_stream)
ElevenLabs, _, stream = _import_elevenlabs()
try:
# Use the API key provided during initialization
api_key = self.eleven_api_key or get_from_dict_or_env(
{}, "eleven_api_key", "ELEVEN_API_KEY"
)
client = ElevenLabs(api_key=api_key)
# Generate the audio stream
speech_stream = client.generate(text=query, model=self.model, stream=True)
# Stream the generated audio
stream(speech_stream)
except Exception as e:
raise RuntimeError(f"Error while streaming ElevenLabsText2SpeechTool: {e}")
Loading