Skip to content

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:

  1. Aculab Cloud calls the /ConnectToOpenAI REST route.
  2. The route returns a greeting followed by a Connect action targeting WSS_SERVER_URL.
  3. The WSS bridge creates a CallBridge instance for the connection and opens an OpenAI Realtime session.
  4. 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 pcm16 input rate and placed on an asyncio.Queue.
  • OpenAI's 24 kHz output audio is resampled to the caller's rate and sent with send_playback_audio.
  • OpenAI audio_interrupted events call send_playback_abort so barge-in audio is not played after the caller has started speaking.
  • OpenAI audio_end events call send_playback_end.
  • User and model transcripts, tool calls, and session errors are logged.
  • Only 16bit_PCM caller 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_flights returns a stub flight result for the requested route, date, passenger, and seat class.
  • book_flight returns a stub booking result for a selected flight.
  • call_live_agent uses the Aculab REST interrupt service to end the AI leg and redirect the caller to the REST app's /CallLiveAgent route.

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.