Capabilities and hooks
A capability attached to the agent or passed to
realtime(capabilities=...) participates in a realtime session where its lifecycle maps onto a
persistent connection. Third-party capabilities
load exactly the same way as in a regular run; nothing realtime-specific is required of them.
| Capability stage | Session behavior |
|---|---|
for_agent, for_run, get_instructions | Runs during setup; dynamic instructions are evaluated once at connect. |
get_toolset, get_wrapper_toolset, prepare_tools | Contributes, wraps, and prepares local tools before connecting. |
get_native_tools | Contributes native tools before connecting; a dynamic native-tool function is resolved once against the connect-time context, like dynamic instructions. |
| Tool validation/execution hooks | Runs around each local function-tool call. |
handle_deferred_tool_calls | Resolves deferred requests inline; see deferred and approval-required tools. |
| Graph node, model-request, and output-processing hooks | Do not run; no agent graph or output-processing stage exists. |
All regular tool validation and
tool execution hooks — before, after, wrap, and on_error
for both stages — run around every local function-tool call exactly as in a standard run, retries
and all. What does not run is anything tied to the request-response graph:
node hooks, model request hooks such as
before_model_request, and output validation and
output processing hooks — a session has no graph nodes, no
per-request boundary, and no output stage.
before_run, after_run, wrap_run, and on_run_error run hooks run
once around the session — a realtime session is a run — with the same close-boundary recovery and
result-transformation semantics as iter().
wrap_run_event_stream wraps the consumer-facing session iterator. It can observe or transform
shared AgentStreamEvent members and realtime-only
RealtimeEvent members (see the
event reference) without changing history or tool execution. There is no
event_stream_handler parameter on realtime(); a handler-style consumer is attached with the
ProcessEventStream capability, which works through
this same stream.
get_model_settings() may run during capability setup, but regular model settings do not configure
a realtime model. Pass RealtimeModelSettings through
realtime(model_settings=...) instead. Inside session hooks and tools, the
RunContext reflects the session:
RunContext field | Value in a realtime session |
|---|---|
ctx.model_settings | The merged RealtimeModelSettings the session was connected with. |
ctx.realtime | True from before_run onward. |
ctx.realtime_session | The live RealtimeSession once it is connected. |
History-processing capabilities do not transform message_history before it is
seeded into a session; preprocess the history before opening the
session when filtering or redaction is required.
Deferred capabilities load in a session the same way they do in a regular run: the capability
catalog is part of the session’s instructions, and calling the load_capability tool returns the
loaded capability’s instructions as its result — which works on every provider. What a session
cannot do is advertise new tools mid-conversation (the connection’s tools are fixed when it
opens; see #7288), so opening a session with
a defer_loading=True capability that contributes tools or native tools raises
UserError before connecting — accepting it would silently
provide less than requested. Realtime per-turn/exchange hooks are expected to widen this boundary
in the future; see #7190 and
#7191.