Binds the underlying socket. Called by the driver once the websocket is open.
Closes the session and releases the underlying provider connection.
A promise that resolves once the session is fully closed.
Entry point for an inbound websocket frame. Multiplexes on type to focused
per-concern handlers so each translation unit stays small and testable.
Surfaces an UNEXPECTED socket close as a fatal error (expected closes — the consumer called Close — are silent). ElevenLabs hard-closes at signed-URL expiry and when the agent itself ends the conversation, so this is also how credential / conversation death reaches the consumer.
Optionalcode: numberOptionalreason: stringSurfaces a websocket-level failure as a FATAL session error — the transport is gone, so the consumer should finalize cleanly instead of idling (driver obligation #6).
Registers a handler for session errors.
Fatality semantics mirror the client-side BaseRealtimeClient contract:
Fatal: true — the session is unusable (transport/socket failure, credential/token
expiry, unexpected connection loss). The consumer should finalize the session (e.g.
RealtimeSessionRunner calls Stop()) instead of idling forever on a dead socket.Fatal: false — a provider-reported, recoverable error frame; the session stays open
and the consumer should log and continue.Invoked with each RealtimeSessionError.
Registers a handler for provider-detected interruptions (barge-in).
True barge-in only: the handler fires ONLY when user speech interrupts ACTIVE model output — NOT on every user utterance. A user simply taking their normal turn while the model is idle is not an interruption, and drivers must not report it as one (e.g. a raw "speech started" frame must be gated on whether a model response is actually in flight).
Turn detection / VAD is owned by the provider. The agent layer uses this hook to cancel
the model's current turn and to fire the cancellationToken of any in-flight
delegated agent run — a stale delegated result must never be narrated into a conversation
that has moved on.
Invoked when the provider reports a true barge-in interruption.
Registers a handler for model audio output frames (the audio media plane).
Invoked with each output audio frame as an ArrayBuffer.
Registers a handler for model tool-call requests.
Consumers execute the requested tool (under the session's context user) and feed the result back to the model.
Invoked with each RealtimeToolCall.
Registers a handler for transcript events (the text stream).
Consumers typically forward these to the control plane and persist them as
ConversationDetail records.
Invoked with each RealtimeTranscript (partial or final).
binds the tool set on the server-side AGENT configuration (the driver's managed-agent ensure flow), not on the open conversation. Per the contract's idempotency rule: an identical post-start set is a silent no-op; a different set is unsupported on an open conversation — it logs a clear warning and does nothing (the NEXT session picks the new set up via the ensure flow's fingerprint check).
Sends the conversation_initiation_client_data frame carrying the per-session system
prompt as the agent.prompt.prompt override (which the managed agent's platform
settings enable). initialContext, when provided, is held back and injected as a
native contextual_update once the metadata confirms the session — ElevenLabs has no
pre-turn history-seeding channel, so prior context rides the contextual-update lane.
OptionalinitialContext: stringclient_tool_result correlated by tool_call_id. Sent IMMEDIATELY (never queued):
the platform requested the result (expects_response: true blocks the conversation on
it) and handles its own continuation, so deferring it could only delay the spoken reply.
The result string is parsed to ride as structured JSON when possible; free-text results
pass through as-is.
Records the tool set bound at connect time. Called by ElevenLabsRealtime.StartSession.
Resolves once the server's conversation_initiation_metadata arrives (the provider's
confirmation that the session — including the prompt override — is applied); rejects if
the transport dies first. Awaited by ElevenLabsRealtime.StartSession so the
session is never handed to a consumer before it is actually configured.
StaticParseParses a JSON-stringified tool result into a structured value for the result slot,
falling back to the raw string so a free-text result still round-trips.
Concrete IRealtimeSession backed by a raw ElevenLabs Agents conversation websocket.
Owns the inbound translation (snake_case wire events → Core events) and the outbound translation (Core calls → wire frames). Created by ElevenLabsRealtime.StartSession; never instantiated directly by consumers.
Provider-behavior notes (the contract deltas a consumer should know):
user_transcript/agent_responseevents — there are no interim deltas, so every RealtimeTranscript this session emits hasIsFinal: true.agent_response_correctionre-finalizes a truncated turn. After a barge-in the platform sends the corrected (actually-spoken) agent text; the session emits it as a fresh FINAL assistant transcript — consumers persisting transcripts should treat a final assistant transcript arriving immediately after an interruption as the authoritative replacement for the previous one.user_messageturn (ElevenLabs has no per-response-instructions channel), queued behind any in-flight response. Fidelity caveat: the instruction enters the conversation as a user turn, so the agent may occasionally reference it ("you asked me to give an update") — hosts should phrase instructions accordingly. SendContextNote is NATIVE (contextual_update) and never interrupts.