Skip to content

Commit 65a2e07

Browse files
fix TTS vendor parity: MiniMax fields, Sarvam schema, add Groq and Murf
1 parent e024ed2 commit 65a2e07

2 files changed

Lines changed: 74 additions & 9 deletions

File tree

src/agora_agent/agentkit/vendors/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@
3131
ElevenLabsTTS,
3232
FishAudioTTS,
3333
GoogleTTS,
34+
GroqTTS,
3435
HumeAITTS,
3536
MicrosoftTTS,
3637
MiniMaxTTS,
38+
MurfTTS,
3739
OpenAITTS,
3840
RimeTTS,
3941
SarvamTTS,
@@ -64,7 +66,9 @@
6466
"HumeAITTS",
6567
"RimeTTS",
6668
"FishAudioTTS",
69+
"GroqTTS",
6770
"MiniMaxTTS",
71+
"MurfTTS",
6872
"SarvamTTS",
6973
"SpeechmaticsSTT",
7074
"DeepgramSTT",

src/agora_agent/agentkit/vendors/tts.py

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,35 @@ def to_config(self) -> Dict[str, Any]:
322322
return result
323323

324324

325+
class GroqTTSOptions(BaseModel):
326+
key: str = Field(..., description="Groq API key")
327+
model: Optional[str] = Field(default=None, description="Model name")
328+
skip_patterns: Optional[List[int]] = Field(default=None)
329+
330+
class Config:
331+
extra = "forbid"
332+
333+
334+
class GroqTTS(BaseTTS):
335+
def __init__(self, **kwargs: Any):
336+
self.options = GroqTTSOptions(**kwargs)
337+
338+
@property
339+
def sample_rate(self) -> Optional[int]:
340+
return None
341+
342+
def to_config(self) -> Dict[str, Any]:
343+
params: Dict[str, Any] = {"key": self.options.key}
344+
345+
if self.options.model is not None:
346+
params["model"] = self.options.model
347+
348+
result: Dict[str, Any] = {"vendor": "groq", "params": params}
349+
if self.options.skip_patterns is not None:
350+
result["skip_patterns"] = self.options.skip_patterns
351+
return result
352+
353+
325354
class MiniMaxTTSOptions(BaseModel):
326355
key: str = Field(..., description="MiniMax API key")
327356
group_id: str = Field(..., description="MiniMax group identifier")
@@ -358,9 +387,9 @@ def to_config(self) -> Dict[str, Any]:
358387

359388

360389
class SarvamTTSOptions(BaseModel):
361-
api_key: str = Field(..., description="Sarvam API key")
362-
voice_id: Optional[str] = Field(default=None, description="Voice ID")
363-
model: Optional[str] = Field(default=None, description="Model name")
390+
key: str = Field(..., description="Sarvam API subscription key")
391+
speaker: str = Field(..., description="Speaker/voice ID (e.g., 'anushka', 'abhilash', 'karun', 'hitesh', 'manisha', 'vidya', 'arya')")
392+
target_language_code: str = Field(..., description="Target language code (e.g., 'en-IN', 'hi-IN', 'ta-IN')")
364393
skip_patterns: Optional[List[int]] = Field(default=None)
365394

366395
class Config:
@@ -376,14 +405,46 @@ def sample_rate(self) -> Optional[int]:
376405
return None
377406

378407
def to_config(self) -> Dict[str, Any]:
379-
params: Dict[str, Any] = {"api_key": self.options.api_key}
380-
381-
if self.options.voice_id is not None:
382-
params["voice_id"] = self.options.voice_id
383-
if self.options.model is not None:
384-
params["model"] = self.options.model
408+
params: Dict[str, Any] = {
409+
"key": self.options.key,
410+
"speaker": self.options.speaker,
411+
"target_language_code": self.options.target_language_code,
412+
}
385413

386414
result: Dict[str, Any] = {"vendor": "sarvam", "params": params}
387415
if self.options.skip_patterns is not None:
388416
result["skip_patterns"] = self.options.skip_patterns
389417
return result
418+
419+
420+
class MurfTTSOptions(BaseModel):
421+
key: str = Field(..., description="Murf API key")
422+
voice_id: str = Field(..., description="Voice ID (e.g., 'Ariana', 'Natalie', 'Ken')")
423+
style: Optional[str] = Field(default=None, description="Voice style (e.g., 'Angry', 'Sad', 'Conversational', 'Newscast')")
424+
skip_patterns: Optional[List[int]] = Field(default=None)
425+
426+
class Config:
427+
extra = "forbid"
428+
429+
430+
class MurfTTS(BaseTTS):
431+
def __init__(self, **kwargs: Any):
432+
self.options = MurfTTSOptions(**kwargs)
433+
434+
@property
435+
def sample_rate(self) -> Optional[int]:
436+
return None
437+
438+
def to_config(self) -> Dict[str, Any]:
439+
params: Dict[str, Any] = {
440+
"key": self.options.key,
441+
"voice_id": self.options.voice_id,
442+
}
443+
444+
if self.options.style is not None:
445+
params["style"] = self.options.style
446+
447+
result: Dict[str, Any] = {"vendor": "murf", "params": params}
448+
if self.options.skip_patterns is not None:
449+
result["skip_patterns"] = self.options.skip_patterns
450+
return result

0 commit comments

Comments
 (0)