ruff linting

This commit is contained in:
ssillerom
2026-01-28 18:02:51 +01:00
parent c5be67f293
commit 2612fae527

View File

@@ -9,7 +9,7 @@ Features:
- Input/output variables for Architect flow integration - Input/output variables for Architect flow integration
- DTMF event support - DTMF event support
- Barge-in (interruption) events - Barge-in (interruption) events
- Pause/resume support for hold scenarios - Pause/resume support for hold scenarios (optional)
Protocol Reference: Protocol Reference:
- https://developer.genesys.cloud/devapps/audiohook - https://developer.genesys.cloud/devapps/audiohook
@@ -49,6 +49,7 @@ from pipecat.serializers.base_serializer import FrameSerializer
class AudioHookMessageType(str, Enum): class AudioHookMessageType(str, Enum):
"""AudioHook protocol message types.""" """AudioHook protocol message types."""
OPEN = "open" OPEN = "open"
OPENED = "opened" OPENED = "opened"
CLOSE = "close" CLOSE = "close"
@@ -65,15 +66,17 @@ class AudioHookMessageType(str, Enum):
class AudioHookChannel(str, Enum): class AudioHookChannel(str, Enum):
"""AudioHook audio channel configuration.""" """AudioHook audio channel configuration."""
EXTERNAL = "external" # Customer audio only (mono) EXTERNAL = "external" # Customer audio only (mono)
INTERNAL = "internal" # Agent audio only (mono) INTERNAL = "internal" # Agent audio only (mono)
BOTH = "both" # Stereo: external=left, internal=right BOTH = "both" # Stereo: external=left, internal=right
class AudioHookMediaFormat(str, Enum): class AudioHookMediaFormat(str, Enum):
"""Supported audio formats.""" """Supported audio formats."""
PCMU = "PCMU" # μ-law, 8kHz PCMU = "PCMU" # μ-law, 8kHz
L16 = "L16" # 16-bit linear PCM, 8kHz L16 = "L16" # 16-bit linear PCM, 8kHz
class GenesysAudioHookSerializer(FrameSerializer): class GenesysAudioHookSerializer(FrameSerializer):
@@ -200,7 +203,6 @@ class GenesysAudioHookSerializer(FrameSerializer):
self._register_event_handler("on_error") self._register_event_handler("on_error")
self._register_event_handler("on_dtmf") self._register_event_handler("on_dtmf")
@property @property
def session_id(self) -> str: def session_id(self) -> str:
"""Get the Genesys AudioHook session ID generated by the serializer.""" """Get the Genesys AudioHook session ID generated by the serializer."""
@@ -477,11 +479,7 @@ class GenesysAudioHookSerializer(FrameSerializer):
""" """
msg = self._create_message( msg = self._create_message(
AudioHookMessageType.EVENT, AudioHookMessageType.EVENT,
parameters={ parameters={"entities": [{"type": "barge_in", "data": {}}]},
"entities": [
{"type": "barge_in", "data": {}}
]
},
) )
logger.debug("🔇 Barge-in event sent to Genesys") logger.debug("🔇 Barge-in event sent to Genesys")
@@ -572,7 +570,11 @@ class GenesysAudioHookSerializer(FrameSerializer):
the frame type is not handled or session is not open. the frame type is not handled or session is not open.
""" """
if isinstance(frame, (EndFrame, CancelFrame)): if isinstance(frame, (EndFrame, CancelFrame)):
return json.dumps(self.create_disconnect_message(output_variables=self.output_variables, reason="completed")) return json.dumps(
self.create_disconnect_message(
output_variables=self.output_variables, reason="completed"
)
)
elif isinstance(frame, AudioRawFrame): elif isinstance(frame, AudioRawFrame):
if not self._is_open or self._is_paused: if not self._is_open or self._is_paused:
@@ -670,7 +672,9 @@ class GenesysAudioHookSerializer(FrameSerializer):
# For PCMU, each sample is 1 byte # For PCMU, each sample is 1 byte
# Extract only bytes at even positions (left channel = external) # Extract only bytes at even positions (left channel = external)
audio_data = bytes(data[i] for i in range(0, len(data), 2)) audio_data = bytes(data[i] for i in range(0, len(data), 2))
logger.debug(f"🔊 Stereo audio: {original_len} bytes → {len(audio_data)} bytes (external channel)") logger.debug(
f"🔊 Stereo audio: {original_len} bytes → {len(audio_data)} bytes (external channel)"
)
if self._params.media_format == AudioHookMediaFormat.PCMU: if self._params.media_format == AudioHookMediaFormat.PCMU:
# Convert μ-law at 8kHz to PCM at pipeline rate # Convert μ-law at 8kHz to PCM at pipeline rate
@@ -699,7 +703,6 @@ class GenesysAudioHookSerializer(FrameSerializer):
return audio_frame return audio_frame
async def _handle_control_message(self, message: Dict[str, Any]) -> Frame | None: async def _handle_control_message(self, message: Dict[str, Any]) -> Frame | None:
"""Handle a JSON control message from Genesys. """Handle a JSON control message from Genesys.
@@ -783,7 +786,9 @@ class GenesysAudioHookSerializer(FrameSerializer):
if media_list and isinstance(media_list, list) and len(media_list) > 0: if media_list and isinstance(media_list, list) and len(media_list) > 0:
audio_media: Dict[str, Any] = media_list[0] # Get first media entry audio_media: Dict[str, Any] = media_list[0] # Get first media entry
channels = audio_media.get("channels", []) channels = audio_media.get("channels", [])
logger.debug(f"📡 Genesys audio config: format={audio_media.get('format')}, channels={channels}, rate={audio_media.get('rate')}") logger.debug(
f"📡 Genesys audio config: format={audio_media.get('format')}, channels={channels}, rate={audio_media.get('rate')}"
)
# channels is a list like ["external"] or ["external", "internal"] # channels is a list like ["external"] or ["external", "internal"]
if isinstance(channels, list): if isinstance(channels, list):
if "external" in channels and "internal" in channels: if "external" in channels and "internal" in channels:
@@ -805,11 +810,13 @@ class GenesysAudioHookSerializer(FrameSerializer):
await self._call_event_handler("on_open", message) await self._call_event_handler("on_open", message)
return OutputTransportMessageUrgentFrame(message=self.create_opened_response( return OutputTransportMessageUrgentFrame(
start_paused=self._params.start_paused, message=self.create_opened_response(
supported_languages=self._params.supported_languages, start_paused=self._params.start_paused,
selected_language=self._params.selected_language supported_languages=self._params.supported_languages,
)) selected_language=self._params.selected_language,
)
)
async def _handle_close(self, message: Dict[str, Any]) -> Frame | None: async def _handle_close(self, message: Dict[str, Any]) -> Frame | None:
"""Handle a 'close' message from Genesys. """Handle a 'close' message from Genesys.