OpenAI Realtime Flight Booking Agent
The flight_booking_agent sample connects an Aculab Cloud call to an OpenAI Realtime session. It is a complete REST and WSS application built on the aculab.websocket package.
The sample demonstrates a voice flight-booking assistant. It receives caller audio from Aculab Cloud, resamples it for OpenAI Realtime, sends OpenAI audio back to the caller, and handles OpenAI function calls for flight searches, flight bookings, and transfer to a live agent.
Sample layout
The sample is located at ip-acu-aculab-websocket/samples/OpenAIRealtime/flight_booking_agent:
| File or directory | Role |
|---|---|
flight_booking_agent.py |
Main entry point. Defines the CallBridge subclass, OpenAI tools, audio resampling, and the WSS server. |
openai_api/openai_realtime.py |
OpenAI Realtime session wrapper. Sends queued caller audio to OpenAI, receives model events, and dispatches tool calls and audio callbacks. |
rest_app/connect_to_openai.py |
Flask REST application that returns a Connect action that routes an Aculab Cloud call to the WSS bridge. |
.env.example |
Configuration template for the REST app, WSS listener, OpenAI session, and live-agent transfer. |
requirements.txt |
Dependencies for the WSS bridge, OpenAI Realtime client, audio resampling, and Flask REST app. |
The two application halves work together:
- Aculab Cloud calls the
/ConnectToOpenAIREST route. - The route returns a greeting followed by a
Connectaction targetingWSS_SERVER_URL. - The WSS bridge creates a
CallBridgeinstance for the connection and opens an OpenAI Realtime session. - OpenAI audio and function-call results are sent back through the Aculab Cloud connection.
Audio bridge
CallBridge inherits AculabCloudWebsocketMixin from aculab.websocket. The package owns Aculab Cloud protocol handling, including subprotocol negotiation, JSON control frames, playback chunking, connection lifecycle, and the /echo loopback route.
The sample adds the OpenAI-specific behavior:
- Caller audio is resampled from the Aculab rate, typically 8 kHz, to OpenAI Realtime's 24 kHz
pcm16input rate and placed on anasyncio.Queue. - OpenAI's 24 kHz output audio is resampled to the caller's rate and sent with
send_playback_audio. - OpenAI
audio_interruptedevents callsend_playback_abortso barge-in audio is not played after the caller has started speaking. - OpenAI
audio_endevents callsend_playback_end. - User and model transcripts, tool calls, and session errors are logged.
- Only
16bit_PCMcaller audio is supported.
The bridge selects v2.ws.cloud.aculab.com for paths beginning with /v2/, which is the path format used by the sample's WSS_SERVER_URL. The built-in /v2/echo route can be used to test the Aculab audio path without opening an OpenAI session.
Function calling
The sample declares three OpenAI tools:
search_for_flightsreturns a stub flight result for the requested route, date, passenger, and seat class.book_flightreturns a stub booking result for a selected flight.call_live_agentuses the Aculab REST interrupt service to end the AI leg and redirect the caller to the REST app's/CallLiveAgentroute.
The flight search and booking functions are deliberately simple placeholders. Replace them with calls to the airline or booking backend before using the sample in production. The live-agent route currently plays a holding message and sleeps; replace it with the required live-agent Dial or Connect action.
Configuration
Copy .env.example to .env, or provide the variables through the process environment. Important settings include:
| Variable | Purpose |
|---|---|
OPENAI_API_KEY |
API key used to authenticate against the OpenAI Realtime endpoint. Required. |
OPENAI_MODEL |
OpenAI Realtime model, for example gpt-realtime-2.1. |
OPENAI_VOICE |
Prebuilt OpenAI voice, default ash. |
OPENAI_SYSTEM_INSTRUCTIONS |
System prompt for the flight-booking assistant. |
OPENAI_KICKOFF_TEXT |
Optional initial text sent to OpenAI when the call starts. |
CLOUD_WSS_HOST / CLOUD_WSS_PORT |
Local WSS bridge bind address and port. |
WSS_SERVER_URL |
Public WSS destination returned in the REST Connect action. It must be reachable by Aculab Cloud, use a trusted certificate, and start with /v2/. |
ACULAB_CLOUD_ID, ACULAB_CLOUD_USERNAME, ACULAB_CLOUD_API_ACCESS_KEY |
Credentials used by call_live_agent for the REST interrupt request. |
LIVE_AGENT_REDIRECT_PAGE |
REST route used after the AI leg is interrupted, default CallLiveAgent. |
RUN_FLASK |
Set to 0 when the REST app is deployed separately. |
Keep API keys out of source
Set OPENAI_API_KEY from the environment, for example a .env file, a secret manager, or your CI/CD system's secret store. Do not commit real keys to the repository.
Running the sample
From ip-acu-aculab-websocket/samples/OpenAIRealtime/flight_booking_agent:
pip install -r requirements.txt
cp .env.example .env
# Edit .env, including WSS_SERVER_URL and OPENAI_API_KEY.
python flight_booking_agent.py
By default, flight_booking_agent.py starts the Flask REST route in a background thread and starts the WSS bridge in the same process. Set RUN_FLASK=0 when the REST route is hosted separately.
Point an Aculab Cloud REST application at /ConnectToOpenAI. For an audio-path smoke test that bypasses OpenAI, point a Connect action at wss://<host>:<port>/v2/echo.
Adapting the sample
To connect a different AI backend, keep the Aculab-facing behavior supplied by AculabCloudWebsocketMixin and replace the OpenAI-specific code in CallBridge and openai_api/openai_realtime.py. The important integration points are on_caller_audio_frame, run_session, send_playback_audio, send_playback_abort, and send_playback_end. The websocket mixin guide documents the reusable package API.