DTMF: Add support for native DTMF implementation where available
This commit is contained in:
@@ -13,6 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
Using the universal `LLMContext` and associated `LLMContextAggregatorPair` is
|
||||
a pre-requisite for using `LLMSwitcher` to switch between LLMs at runtime.
|
||||
|
||||
### Changed
|
||||
|
||||
- Restored `DailyTransport`'s native DTMF support using Daily's `send_dtmf()`
|
||||
method instead of generated audio tones.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a `AWSBedrockLLMService` crash caused by an extra `await`.
|
||||
|
||||
@@ -219,7 +219,34 @@ class BaseOutputTransport(FrameProcessor):
|
||||
pass
|
||||
|
||||
async def write_dtmf(self, frame: OutputDTMFFrame | OutputDTMFUrgentFrame):
|
||||
"""Write a DTMF tone to the transport.
|
||||
"""Write a DTMF tone using the transport's preferred method.
|
||||
|
||||
Args:
|
||||
frame: The DTMF frame to write.
|
||||
"""
|
||||
if self._supports_native_dtmf():
|
||||
await self._write_dtmf_native(frame)
|
||||
else:
|
||||
await self._write_dtmf_audio(frame)
|
||||
|
||||
def _supports_native_dtmf(self) -> bool:
|
||||
"""Override in transport implementations that support native DTMF.
|
||||
|
||||
Returns:
|
||||
True if the transport supports native DTMF, False otherwise.
|
||||
"""
|
||||
return False
|
||||
|
||||
async def _write_dtmf_native(self, frame: OutputDTMFFrame | OutputDTMFUrgentFrame):
|
||||
"""Override in transport implementations for native DTMF.
|
||||
|
||||
Args:
|
||||
frame: The DTMF frame to write.
|
||||
"""
|
||||
raise NotImplementedError("Transport claims native DTMF support but doesn't implement it")
|
||||
|
||||
async def _write_dtmf_audio(self, frame: OutputDTMFFrame | OutputDTMFUrgentFrame):
|
||||
"""Generate and send audio tones for DTMF.
|
||||
|
||||
Args:
|
||||
frame: The DTMF frame to write.
|
||||
@@ -228,7 +255,6 @@ class BaseOutputTransport(FrameProcessor):
|
||||
dtmf_audio_frame = OutputAudioRawFrame(
|
||||
audio=dtmf_audio, sample_rate=self._sample_rate, num_channels=1
|
||||
)
|
||||
dtmf_audio_frame.transport_destination = frame.transport_destination
|
||||
await self.write_audio_frame(dtmf_audio_frame)
|
||||
|
||||
async def send_audio(self, frame: OutputAudioRawFrame):
|
||||
|
||||
@@ -1809,6 +1809,27 @@ class DailyOutputTransport(BaseOutputTransport):
|
||||
"""
|
||||
await self._client.write_video_frame(frame)
|
||||
|
||||
def _supports_native_dtmf(self) -> bool:
|
||||
"""Daily supports native DTMF via telephone events.
|
||||
|
||||
Returns:
|
||||
True, as Daily supports native DTMF transmission.
|
||||
"""
|
||||
return True
|
||||
|
||||
async def _write_dtmf_native(self, frame):
|
||||
"""Use Daily's native send_dtmf method for telephone events.
|
||||
|
||||
Args:
|
||||
frame: The DTMF frame to write.
|
||||
"""
|
||||
await self._client.send_dtmf(
|
||||
{
|
||||
"sessionId": frame.transport_destination,
|
||||
"tones": frame.button.value,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class DailyTransport(BaseTransport):
|
||||
"""Transport implementation for Daily audio and video calls.
|
||||
|
||||
Reference in New Issue
Block a user