-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat(azure): Add Azure Voice Live Realtime API support #4693
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/realtime/realtime_model.py
Outdated
Show resolved
Hide resolved
livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/realtime/realtime_model.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/realtime/realtime_model.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| await self._handle_response_done(event) | ||
|
|
||
| elif event_type == ServerEventType.ERROR: | ||
| error_msg = getattr(event, "error", {}).get("message", "Unknown error") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 Error event handling assumes event.error is a dict when it's likely an object
The error handling code will crash with AttributeError if event.error is an object rather than a dictionary.
Click to expand
Issue
At line 502, the code does:
error_msg = getattr(event, "error", {}).get("message", "Unknown error")This assumes event.error is a dictionary with a get() method. However, looking at how other Azure SDK event attributes are accessed throughout the codebase, they are objects with attributes (e.g., event.response.id at line 514, event.session.id at line 440). If event.error is similarly an object (not a dict), calling .get() on it will raise an AttributeError.
Impact
When Azure returns an error event, the code will crash with AttributeError: 'SomeErrorClass' object has no attribute 'get', causing the event loop to fail and potentially disconnecting the session.
Expected Behavior
The error message should be extracted using getattr(event.error, "message", "Unknown error") to be consistent with how other event attributes are accessed.
Recommendation: Change to: error_msg = getattr(getattr(event, "error", None), "message", None) or "Unknown error" or use a consistent pattern like other event handlers: error_obj = getattr(event, "error", None); error_msg = getattr(error_obj, "message", "Unknown error") if error_obj else "Unknown error"
Was this helpful? React with 👍 or 👎 to provide feedback.
| from . import realtime | ||
| from .stt import STT, SpeechStream | ||
| from .tts import TTS | ||
| from .version import __version__ | ||
|
|
||
| __all__ = ["STT", "SpeechStream", "TTS", "responses", "__version__"] | ||
| __all__ = ["STT", "SpeechStream", "TTS", "realtime", "__version__"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Breaking change: responses module removed from package exports without deprecation
The responses module was replaced with realtime in the package exports, but the responses directory still exists with functional code.
Click to expand
Issue
In __init__.py, the import changed from:
from . import responses
__all__ = ["STT", "SpeechStream", "TTS", "responses", "__version__"]to:
from . import realtime
__all__ = ["STT", "SpeechStream", "TTS", "realtime", "__version__"]The responses directory (livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/responses/) still exists with __init__.py and llm.py, but is no longer exported.
Impact
Existing users who import from livekit.plugins import azure; azure.responses or from livekit.plugins.azure import responses will get an AttributeError or ImportError after upgrading. This is a breaking API change that should either be documented or the responses module should continue to be exported alongside realtime.
Recommendation: Either: (1) Export both modules: from . import realtime, responses and update __all__ to include both, or (2) Remove the responses directory if it's deprecated, or (3) Document this as a breaking change in the PR description.
Was this helpful? React with 👍 or 👎 to provide feedback.
Description
This PR adds support for Azure Voice Live, enabling real-time speech-to-speech conversations through the Azure plugin.
What's New
Azure Voice Live Integration
RealtimeModelclass providing end-to-end speech-to-speech capabilitiesFeatures
en-US-AvaMultilingualNeural)save_audio_per_turn=True)Usage
Environment Variables
New Dependencies
azure-ai-voicelive[aiohttp]>=1.0.0azure-identity>=1.15.0