.agents/references/realtime-session-lifecycle.md
Use this reference for RealtimeSession changes involving entry, exit, listeners, connections, background tasks, approvals, handoffs, event iteration, tracing context, or cleanup.
Treat the session as the owner of these resources once they are acquired:
| Resource | Acquisition | Required release or terminal state |
|---|---|---|
| Model listener | add_listener() during entry | remove_listener() |
| Model connection | model.connect() | model.close() |
| Event iterators | Waiting on the event queue | Wake or terminate every waiter on close |
| Guardrail tasks | Created during output processing | Complete, or cancel and account for completion |
| Tool-call tasks | Created when async_tool_calls=True | Complete, or cancel and account for completion |
| Pending approvals and outputs | Added during tool execution | Resolve, retain for retry, or clear during terminal cleanup |
| Agent and model settings | Updated on handoff or update_agent() | Keep runtime state and model configuration aligned |
Do not add a new side effect before a failure point without defining who releases it.
__aexit__ when __aenter__ raises. Any listener, connection, task, tracing scope, or other resource acquired before the exception needs explicit failure cleanup.close() and internal cleanup must be idempotent. Repeated close paths should still wake event iterators without closing the model twice.asyncio tasks inherit a snapshot of the creator's context. A background task cannot update the caller task's ContextVar state.ContextVar token must be reset in the same context that created it. Never pass a token to a different task and assume cleanup can reset it safely.close(), update_agent(), and handoff handling. Review ordering and races whenever one of those paths changes.task.cancel() requests cancellation; it does not prove the task has finished its finally blocks or released resources. Await cancelled tasks when completion matters, or document and test why dropping them is safe.update_agent() API are equivalent agent-transition surfaces. Keep their model settings, tool and handoff resolution, emitted events, and tracing metadata aligned unless a difference is intentional and documented.Runner output object. They emit guardrail_tripped instead of raising a normal Runner tripwire exception.audio_interrupted as the signal to stop local playback; text rejection alone cannot retract audio already delivered.RealtimeError event rather than disappearing.response.create work triggered by tools, handoffs, or guardrails must respect the active response lifecycle. Wait for response.done or the model layer's equivalent gate before starting a conflicting response.Add focused tests for affected phases:
close() is called repeatedly or from another task.update_agent() fails partway through model-settings application.Verify lifecycle changes with the real public path where feasible; helper-only tests are insufficient when task ownership or context propagation determines the result.
src/agents/realtime/session.pysrc/agents/realtime/model.pysrc/agents/realtime/openai_realtime.pytests/realtime/test_session.pytests/realtime/test_session_exceptions.pydocs/realtime/guide.md