A voice model can finish producing its answer while a speaker is still playing it. Closing the session at that first milestone can discard buffered audio. Pydantic AI's September 18 addition of RealtimeSession.wait_for_playback() gives application builders a place to wait before teardown—or before opening the microphone for the next turn.
The public Python API belongs to Pydantic AI, not to one model provider. Its implementation requires exactly one active stream_audio() iterator. A chunk counts as consumed when that iterator asks for the next chunk. Your playback loop must therefore wait for the device to consume a chunk before advancing. Rapidly copying chunks into another queue does not prove that the loudspeaker has finished.
Try it: a gallery guide that waits its turn
Imagine a museum station that greets a visitor, then opens its microphone. Use the updated speaking-first example: subscribe to audio, run the device-paced playback consumer concurrently, send the greeting request, observe the assistant speech boundary, then await session.wait_for_playback() before listening. For a one-response demo, put the wait before leaving the session context instead.
Agent instruction
Build a disposable Pydantic AI voice greeting demo.
First verify that the installed RealtimeSession has wait_for_playback.
Use exactly one stream_audio iterator and start its consumer before sending.
Make the consumer await actual device consumption before taking the next chunk.
After the reply-generation boundary, await session.wait_for_playback()
before closing the session or opening the microphone.
Test slow playback, interruption, and early stream closure separately.
Use synthetic speech only; report the package version and results.
Do not substitute a fixed sleep for playback accounting.
What to check before trusting the wait
The method waits for audio to be accounted for. That includes audio dropped during interruption or buffer overflow, and audio emitted before the view subscribed. It can also return when the view or session closes. It is therefore a coordination primitive, not a receipt that the visitor heard every word. Keep the early-closure and interruption cases distinct from successful playback in your own UI.
We inspected the source, documentation and added device-paced tests; we did not run a paid provider call or a hardware playback test. Confirm that your installed version contains the method, configure the provider credentials it requires, and expect provider charges for a live test. The next useful result is a slow-speaker test that finishes the last chunk before normal teardown, while still letting an intentional interruption end the wait.