client.realtime.sessions.create, then client.realtime.connect(session). Audio is PCM16 mono 24 kHz. Model kupe-realtime. Web-only — no telephony minutes.
Identify the agent with name or agent_id. A new name creates the agent with prompt, greeting, voice, and tools/mcp. Pass voice (sanitized name) or voice_id — either one (copy the id from the voice library).
Terminal
realtime_turn.py and run python realtime_turn.py.
Existing agent from the console:
Events you will see
send_text sends conversation.item.create then response.create. Mic path: rt.append_audio(pcm16_bytes) at 24 kHz.
Echo: speakers vs headset
If you play the agent’s audio through open speakers next to the mic, the mic records the agent andappend_audio sends its own voice back as user
speech. The agent then answers itself, and its greeting shows up in the
transcript as a user turn.
Pass echo_suppression="half_duplex" to mute the mic while the agent is
still speaking:
append_audio returns True when the frame was sent and False when it was
muted; rt.suppressed_frames counts the muted frames, and
rt.agent_is_speaking exposes the gate. Pass force=True to bypass it for one
frame. Tune the hold after playback ends with echo_tail_ms (default 250).
A muted frame is still sent, as silence. The server runs streaming VAD and STT
over a continuous audio stream, so sending nothing at all would stall turn
detection and the agent would stop hearing you even after it stopped talking.
The gate advances only while something is iterating the connection, since it
is driven by
response.output_audio.delta sizes. Keep your reader loop
running — a common mistake is reading events only after the mic loop ends.
