Wires the Vonage SDK factory onto the telephony base. The factory builds a VonageCallSdk
which — until a real Vonage client is bound — throws an explicit "bind the real Vonage client"
error from every operation, so Connect fails loudly. A deployment binds the real client behind
the factory; tests override it via BaseTelephonyBridge.SetSdkFactory.
ProtectedcallThe platform-native call identifier for the live call (set at Connect).
ProtectedcarrierThe carrier's PCM16 media rate (Hz) — what the SDK seam sends/receives audio at, between which and the model rate the bridge resamples. Defaults to TELEPHONY_SAMPLE_RATE (8 kHz); a wideband SIP/RTP driver overrides it per-call via CARRIER_SAMPLE_RATE_CONFIG_KEY.
ProtecteddirectionThe direction this call was established with.
ProtectedfeaturesThe capability flags for the provider this bridge instance serves. Populated from the RealtimeBridgeContext at BaseRealtimeBridge.Connect time (and may be set by the engine immediately after construction). Drives BaseRealtimeBridge.RequireFeature.
ProtectedfromThe agent's own number this call originates from / is answered on.
ProtectedmodelThe realtime model's INPUT rate (Hz) — inbound 8 kHz caller audio is resampled UP to this.
ProtectedmodelThe realtime model's OUTPUT rate (Hz) — outbound model audio is resampled DOWN to the carrier rate from this.
ProtectedproviderThe provider's display name for this bridge instance, used in capability-error messages. Populated from the RealtimeBridgeContext; falls back to the driver class name.
ProtectedremoteThe remote party's number (outbound: the dialled number; inbound: best-effort caller-id).
ProtectedsdkThe live telephony SDK seam for this call, created at Connect.
ProtectedsdkThe SDK creation seam. Defaults to a factory that throws an explicit "bind the real telephony client" error, since the base ships WITHOUT a concrete provider adapter. A concrete driver (or a deployment) binds a real factory via SetSdkFactory; tests inject a fake.
Protected Static ReadonlyAGENT_The synthetic external id used for the agent's own leg on the roster. Subclasses may override.
Protected Static ReadonlyREMOTE_The synthetic external id used for the single remote caller on the roster. Stable for the life of
the call so AIAgentSessionBridgeParticipant upserts are idempotent. Subclasses may override.
The live call's platform-native identifier (or null before Connect).
The direction this call was established with ('Outbound' until Connect reads otherwise).
The provider's supported-feature flags for this bridge instance.
Read-only accessor over the internally-held BaseRealtimeBridge.features. The engine consults this (and the underlying provider metadata) to decide which optional methods are safe to call; a driver consults it via BaseRealtimeBridge.RequireFeature.
ProtectedapplyCaptures the connection context onto the instance so BaseRealtimeBridge.Features, BaseRealtimeBridge.RequireFeature, and capability-error messages have the provider's flags and name. A concrete BaseRealtimeBridge.Connect should call this first.
The bridge context handed to Connect.
Establishes the call. Outbound (the default) places a call via ITelephonyCallSdk.dial; inbound answers a routed call via ITelephonyCallSdk.answer. Wires the inbound-audio and DTMF paths and the call-ended callback, seeds the single-party roster, and returns the bot leg + call identifiers the engine persists.
Direction comes from ctx.Configuration[DIRECTION_CONFIG_KEY] (defaults 'Outbound'); the agent's
caller-id from FromNumber; the address (RealtimeBridgeContext.Address) is the destination
number (outbound) and an inbound call id arrives via InboundCallId.
The bridge context (features, provider name, destination as Address, config).
The bot participant + call (external connection) identifiers.
Hangs up the call and releases all SDK resources. Tolerant of teardown errors.
Why the disconnect happened (telephony teardown is uniform — the bot hangs up).
Flushes the agent's queued outbound voice on barge-in by delegating to the SDK's ITelephonyCallSdk.flushOutbound (e.g. Vonage's {"action":"clear"} websocket command). The engine
calls this from OnInterruption; for carriers that buffer outbound audio (notably Vonage's ~60s
queue) this is what stops the agent talking over itself after the caller cuts in. A no-op when the
SDK doesn't implement flush (its media path has no client-side queue).
Telephony contributes no Meeting Controls / facilitator surface. A 1:1 phone call has no roster,
no hand-raise queue, and no who's-speaking timer to facilitate, so this returns null (the
BaseRealtimeBridge default — re-declared here to make the telephony intent explicit). The
engine therefore wires no Meeting Controls channel for a telephony session.
Always null — telephony has no facilitator surface.
Returns the call's "roster": the single remote caller plus the agent. Telephony has no diarization
roster — there is exactly one human on the line — so this is the trivial two-entry list. Not gated
by SpeakerDiarization (a 1:1 call needs none); always available once connected.
The caller + agent participants.
ProtectednotBuilds the standard BridgeCapabilityNotSupportedError for an un-overridden virtual method or a failed feature requirement, stamped with this bridge's provider name.
The feature / method name to report.
The error to throw or reject with.
Registers a callback the bridge invokes when the underlying call ends (remote hangup / carrier drop). The engine uses this to transition the bridge row to a terminal state. "Latest handler wins."
Invoked when the call has ended.
Registers the inbound-media handler. The driver forwards each inbound audio frame (stamped with the
single caller's label) to it; the engine routes it to IRealtimeSession.SendInput.
Invoked with each inbound media frame.
Registers a roster-change handler. On a 1:1 call the roster changes only at connect (caller joins) and at end (caller leaves), so this fires once at connect with the full roster.
Invoked with the participant list.
ProtectedRequireDefense-in-depth guard: asserts a SupportedFeatures flag is enabled before the driver
performs a capability-gated action, throwing BridgeCapabilityNotSupportedError if it
is false/omitted. An overriding driver method should call this at its top so that even a
direct (engine-bypassing) caller cannot run an action the metadata says is off.
The IBridgeProviderFeatures flag to require.
Sends DTMF tones on the call (gated by DTMF). Re-asserts the flag (defense-in-depth) so even an
engine-bypassing caller cannot send tones a disabled provider forbids.
The DTMF digit string to send (e.g. '1234#').
Sends an outbound media frame into the call. Audio is fed to the SDK's media-stream path; video and
screen tracks are n/a for telephony and silently dropped (a phone call carries audio only, and a
telephony provider's SupportedFeatures does not enable the video/screen flags).
The outbound track the frame targets.
The media frame to send.
Sets the TelephonyCallSdkFactory this driver uses to construct its SDK seam at connect — the creation seam (mirroring the meeting SDK factories). A concrete driver binds the real provider adapter here; tests inject a fake before connecting.
The factory that builds the ITelephonyCallSdk for a call.
Realtime Bridge driver for Vonage telephony (Voice API + websocket media).
Construct the driver with the default constructor (the engine's
ClassFactorypath); it binds the VonageCallSdkFactory so a real deployment only needs to wire the Vonage client behind it (or a test injects aFakeVonageCallSdkvia BaseTelephonyBridge.SetSdkFactory). Everything else is inherited from BaseTelephonyBridge.Registered via
@RegisterClass(BaseRealtimeBridge, 'VonageBridge')— the engine resolves any bridge driver against theBaseRealtimeBridgeroot, so a telephony driver registers under that same root.