Gemini Live Flight Booking Agent
The flight_booking_agent sample connects an Aculab Cloud call to a Google Gemini Live 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 Gemini Live, sends Gemini audio back to the caller, and handles Gemini 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/GeminiLive/flight_booking_agent:
| File or directory | Role |
|---|---|
flight_booking_agent.py |
Main entry point. Defines the CallBridge subclass, Gemini tools, audio resampling, credential prewarming, and the WSS server. |
gemini_api/gemini_live.py |
Google's Gemini Live session wrapper. Sends queued caller audio to Gemini, receives model events, and dispatches tool calls and audio callbacks. |
rest_app/connect_to_gemini.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, Gemini session, and live-agent transfer. |
requirements.txt |
Dependencies for the WSS bridge, Gemini Live client, audio resampling, and Flask REST app. |
The two application halves work together:
- Aculab Cloud calls the
/ConnectToGeminiREST route. - The route returns a greeting followed by a
Connectaction targetingWSS_SERVER_URL. - The WSS bridge creates a
CallBridgeinstance for the connection and opens a Gemini Live session. - Gemini 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 Gemini-specific behavior:
- Caller audio is resampled from the Aculab rate, typically 8 kHz, to Gemini's 16 kHz input rate and placed on an
asyncio.Queue. - Gemini's 24 kHz output audio is resampled to the caller's rate and sent with
send_playback_audio. - Gemini interruptions call
send_playback_abortso barge-in audio is not played after the caller has started speaking. - Gemini
turn_completeevents 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 a Gemini session.
Function calling
The sample declares three Gemini 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 |
|---|---|
GEMINI_PROJECT_ID |
Google Cloud project used for Vertex AI. Required. |
GEMINI_LOCATION / GEMINI_MODEL |
Vertex AI region and Gemini Live model. |
GEMINI_VOICE |
Prebuilt Gemini voice, default Puck. |
GEMINI_SYSTEM_INSTRUCTIONS |
System prompt for the flight-booking assistant. |
GEMINI_KICKOFF_TEXT |
Optional initial text sent to Gemini 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. |
The sample resolves and refreshes Google Application Default Credentials before accepting calls. Authenticate the host with:
gcloud auth application-default login
Running the sample
From ip-acu-aculab-websocket/samples/GeminiLive/flight_booking_agent:
pip install -r requirements.txt
gcloud auth application-default login
cp .env.example .env
# Edit .env, including WSS_SERVER_URL and GEMINI_PROJECT_ID.
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 /ConnectToGemini. For an audio-path smoke test that bypasses Gemini, 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 Gemini-specific code in CallBridge and gemini_api/gemini_live.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.