dograh/api/services/telephony/providers/cloudonix/transport.py
Abhishek 2381a803ad
feat: add openai realtime models (#298)
* feat: add openai realtime models

* chore: bump pipecat

* fix: resample telephony audio for openai realtime

* fix: sampling rate fix for openai realtime

* chore: clean up dead code
2026-05-16 18:05:23 +05:30

76 lines
2.6 KiB
Python

"""Cloudonix transport factory."""
from fastapi import WebSocket
from pipecat.transports.websocket.fastapi import (
FastAPIWebsocketParams,
FastAPIWebsocketTransport,
)
from api.services.pipecat.audio_config import AudioConfig
from api.services.pipecat.audio_mixer import build_audio_out_mixer
from api.services.pipecat.transport_params import realtime_param_overrides
from api.services.telephony.factory import load_credentials_for_transport
from .serializers import CloudonixFrameSerializer
from .strategies import CloudonixHangupStrategy
async def create_transport(
websocket: WebSocket,
workflow_run_id: int,
audio_config: AudioConfig,
organization_id: int,
*,
ambient_noise_config: dict | None = None,
telephony_configuration_id: int | None = None,
is_realtime: bool = False,
call_id: str,
stream_sid: str,
bearer_token: str | None = None,
domain_id: str | None = None,
):
"""Create a transport for Cloudonix connections.
When ``bearer_token`` and ``domain_id`` are both supplied, they are used
directly and no DB lookup is performed — this is the agent-stream path
where the caller brings credentials inline. Otherwise credentials are
resolved from the org's stored telephony configuration.
"""
if not (bearer_token and domain_id):
config = await load_credentials_for_transport(
organization_id, telephony_configuration_id, expected_provider="cloudonix"
)
bearer_token = config.get("bearer_token")
domain_id = config.get("domain_id")
if not bearer_token or not domain_id:
raise ValueError(
f"Incomplete Cloudonix configuration for organization {organization_id}. "
f"Required: bearer_token, domain_id"
)
serializer = CloudonixFrameSerializer(
call_id=call_id,
stream_sid=stream_sid,
domain_id=domain_id,
bearer_token=bearer_token,
hangup_strategy=CloudonixHangupStrategy(),
)
mixer = await build_audio_out_mixer(
audio_config.transport_out_sample_rate, ambient_noise_config
)
return FastAPIWebsocketTransport(
websocket=websocket,
params=FastAPIWebsocketParams(
audio_in_enabled=True,
audio_out_enabled=True,
audio_in_sample_rate=audio_config.transport_in_sample_rate,
audio_out_sample_rate=audio_config.transport_out_sample_rate,
audio_out_mixer=mixer,
serializer=serializer,
audio_out_10ms_chunks=2,
**realtime_param_overrides(is_realtime),
),
)