Skip to content
Merged
Show file tree
Hide file tree
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
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ Configure a Voice Agent.

```python
from deepgram import (
SettingsOptions
SettingsOptions,
Speak
)

# Create websocket connection
Expand All @@ -249,9 +250,18 @@ options.agent.think.provider.model = "gpt-4o-mini"
options.agent.think.prompt = "You are a helpful AI assistant."
options.agent.listen.provider.type = "deepgram"
options.agent.listen.provider.model = "nova-3"
options.agent.speak.provider.type = "deepgram"
options.agent.speak.provider.model ="aura-2-thalia-en"

# Configure multiple TTS providers for automatic fallback.
primary = Speak()
primary.provider.type = "deepgram"
primary.provider.model = "aura-2-zeus-en"

fallback = Speak()
fallback.provider.type = "cartesia"
fallback.provider.model = "sonic-english"

options.agent.speak = [primary, fallback]
# Set Agent greeting
options.greeting = "Hello, I'm your AI assistant."

# Start the connection
Expand Down
41 changes: 30 additions & 11 deletions deepgram/clients/agent/v1/websocket/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,26 +273,33 @@ class Agent(BaseResponse):
or (isinstance(f, Think) and not f)
),
)
speak: Speak = field(
default_factory=Speak,
metadata=dataclass_config(
exclude=lambda f: f is None
or (isinstance(f, dict) and not f)
or (isinstance(f, Speak) and not f)
),
)
speak: Union[Speak, List[Speak]] = field(default_factory=Speak)
greeting: Optional[str] = field(
default=None, metadata=dataclass_config(exclude=lambda f: f is None)
)

def __post_init__(self):
"""Handle conversion of dict/list data to proper Speak objects"""
# Handle speak conversion (OneOf pattern)
if isinstance(self.speak, list):
self.speak = [
Speak.from_dict(item) if isinstance(item, dict) else item
for item in self.speak
]
elif isinstance(self.speak, dict):
self.speak = Speak.from_dict(self.speak)

def __getitem__(self, key):
_dict = self.to_dict()
if "listen" in _dict and isinstance(_dict["listen"], dict):
_dict["listen"] = Listen.from_dict(_dict["listen"])
if "think" in _dict and isinstance(_dict["think"], dict):
_dict["think"] = Think.from_dict(_dict["think"])
if "speak" in _dict and isinstance(_dict["speak"], dict):
_dict["speak"] = Speak.from_dict(_dict["speak"])
if "speak" in _dict:
if isinstance(_dict["speak"], list):
_dict["speak"] = [Speak.from_dict(item) for item in _dict["speak"]]
elif isinstance(_dict["speak"], dict):
_dict["speak"] = Speak.from_dict(_dict["speak"])
return _dict[key]


Expand Down Expand Up @@ -395,7 +402,19 @@ class UpdateSpeakOptions(BaseResponse):
"""

type: str = str(AgentWebSocketEvents.UpdateSpeak)
speak: Speak = field(default_factory=Speak)
speak: Union[Speak, List[Speak]] = field(default_factory=Speak)

def __post_init__(self):
"""Handle conversion of dict/list data to proper Speak objects"""
if isinstance(self.speak, list):
# Convert list of dicts to list of Speak objects
self.speak = [
Speak.from_dict(item) if isinstance(item, dict) else item
for item in self.speak
]
elif isinstance(self.speak, dict):
# Convert single dict to Speak object
self.speak = Speak.from_dict(self.speak)


# InjectAgentMessage
Expand Down
Loading