Member Junction
    Preparing search index...

    Server-tier engine for the Realtime Bridge plane — coordination + execution.

    AIBridgeEngine composes AIBridgeEngineBase (the metadata-only cache of providers / identities / provider-channels) rather than extending it — exactly mirroring how the server AIEngine builds on AIEngineBase via containment. The base is itself a BaseEngine singleton keyed by class name, so inheriting from it would make the startup manager instantiate two separate engines (the base AND this subclass), each loading and event-subscribing its own copy of the same caches. Composition keeps exactly one BaseEngine cache — AIBridgeEngineBase.Instance — which this engine warms once via HandleStartup and reads through the delegating accessors below. This server engine then adds everything that actually runs a bridged session:

    • The transport seam (Phase 0, the deferred unification): wireTransportSeam connects the driver's media plane to the realtime session — inbound OnMediaSendInput, outbound OnOutputSendMedia. This is the "no client-facing pipe" gap the realtime guide flagged; the bridge IS that pipe.
    • Bot-session lifecycleStartBridgeSession / StopBridgeSession drive the AIAgentSessionBridge status state machine (Pending → Connecting → Connected → Disconnected), stamp HostInstanceID for node affinity, and resolve the driver via the ClassFactory.
    • Participant tracking — subscribes the driver's roster events (when supported) and upserts AIAgentSessionBridgeParticipant rows.
    • Turn-taking integration — holds a TurnTakingPolicy per session and feeds diarized transcript segments through it, acting on the decision (Speak / PostToChat / Silent).
    • Janitor scaffoldReconcileOrphans force-closes Connected bridges left by a dead host, following the SessionJanitor shape.

    The engine never constructs the realtime model: the IRealtimeSession is injected via StartBridgeSessionParams, keeping the only coupling the transport seam itself and making the whole engine unit-testable with a mock session + the LoopbackBridge.

    /plans/realtime/realtime-bridges-architecture.md §2 (layer cake), §7 (lifecycle), §10 (security/janitor).

    Hierarchy (View Summary)

    Implements

    Index

    Constructors

    Accessors

    • get GlobalKey(): string

      Returns string

    Methods

    • Loads (or refreshes) the composed base's bridge metadata cache. Delegates to AIBridgeEngineBase.Config so the warming path matches AIEngine's shape and there is never a second cache to load. Idempotent — a no-op when already loaded unless forceRefresh.

      Parameters

      • OptionalforceRefresh: boolean

        When true, reloads even if already loaded.

      • OptionalcontextUser: UserInfo

        Required server-side for proper data isolation.

      • Optionalprovider: IMetadataProvider

        Optional explicit metadata provider (multi-provider scenarios).

      Returns Promise<void>

    • Overrides the session timing thresholds (the idle/max-duration sweep caps, the empty-room auto-leave grace, and the floor max-hold). Any omitted value keeps its default. Call once at startup to tune for a deployment (e.g. shorter idle TTL for a high-churn telephony host).

      Parameters

      • timings: {
            EmptyGraceMs?: number;
            FloorMaxHoldMs?: number;
            IdleTtlMs?: number;
            MaxDurationMs?: number;
        }

        The thresholds to override (ms).

      Returns void

    • The Global Object Store is a place to store global objects that need to be shared across the application. Depending on the execution environment, this could be the window object in a browser, or the global object in a node environment, or something else in other contexts. The key here is that in some cases static variables are not truly shared because it is possible that a given class might have copies of its code in multiple paths in a deployed application. This approach ensures that no matter how many code copies might exist, there is only one instance of the object in question by using the Global Object Store.

      Returns GlobalObjectStore

    • Force-closes Connected/Connecting bridges left behind by a previous boot of this host (matching hostname prefix, differing instance id), stamping CloseReason = 'Janitor'. Mirrors SessionJanitor.RunStartupRecovery: a crash/redeploy vaporizes the in-memory driver sockets but leaves the durable rows reading Connected forever; this reconciles them.

      The actual scheduling (run once at boot + periodic sweep) is intentionally left to the host application (MJServer's startup + janitor timer) so this engine package carries no timer/IO of its own; call this method from that scheduler.

      Parameters

      • contextUser: UserInfo

        The system user the reconciliation writes run as.

      • provider: IMetadataProvider

        The metadata provider for the reconciliation reads/writes.

      Returns Promise<number>

      The number of orphaned bridges closed.

    • Retroactively switches an already-running session into meeting mode (auto-response off + addressed-only) — used when a room becomes multi-agent and the first (1:1) agent must stop auto-responding. Capability-gated: only sessions whose provider reports RealtimeSessionCapabilities.CanReconfigureTurnMode can change turn mode on a live socket; others (e.g. Gemini, fixed at connect) are left in their start mode — no dead-method call. Idempotent.

      Parameters

      • sessionBridgeID: string

        The bridge to re-gate.

      • matcher: IAddressedMatcher

        The addressed-matcher (the agent's names) the re-gated session should speak on.

      Returns boolean

      true if now in meeting mode (or already was); false if the session is unknown or the provider can't reconfigure mid-session.

    • Ties a bridge session into the multi-agent room coordinator when it joins a SHARED room (§4c). Call this for an agent session whose bridge connects into a room that other agent sessions may also inhabit — keyed by the shared external room id (the driver's ExternalConnectionID / the ConversationID). Once 2+ agents are registered on the same room, floor arbitration keeps exactly one agent speaking at a time across agents; combined with passive turn-taking, two agents are loop-safe.

      Additive and opt-in. A normal single-agent bridge never calls this and is wholly unaffected — the coordinator only matters once two sessions name the same room. Designating isFacilitator marks the agent (typically the one running the Meeting Controls channel) as the room's arbiter, which may override the floor to call on a specific agent.

      Parameters

      • roomId: string

        The shared external room id all co-located agents key on.

      • agentSessionId: string

        The agent session joining the room.

      • isFacilitator: boolean = false

        Whether this agent is the room's facilitator (may override the floor).

      Returns void

    • Injects the room turn TurnModerator (the LLM router). When set, a MULTI-agent room routes each turn through it (who speaks next, serialized via the floor) instead of evaluating per-agent matchers. Single-agent rooms and the no-moderator case are unaffected (they keep using the matcher path).

      Parameters

      • moderator: TurnModerator

        The moderator function, or undefined to clear it.

      Returns void

    • Starts a bridged session: resolves + connects the driver, drives the bridge row through its status state machine, and wires the transport seam between the driver and the injected realtime session.

      Flow (mirrors the §7 state machine):

      1. Create the AIAgentSessionBridge row as Pending, stamped with this host.
      2. Resolve the driver via ClassFactory.CreateInstance(BaseRealtimeBridge, provider.DriverClass).
      3. Transition to Connecting, build the RealtimeBridgeContext, call driver.Connect.
      4. On success: persist the platform handles, transition to Connected, wire the transport seam, wire participant tracking + turn-taking, register the live session.
      5. On failure: transition to Failed and rethrow.

      Parameters

      Returns Promise<ActiveBridgeSession>

      The live ActiveBridgeSession handle.

      When the driver cannot be resolved or Connect fails (the row is stamped Failed).

    • Stops a bridged session: disconnects the driver, tears down the wired listeners, and transitions the bridge row to Disconnected with the supplied CloseReason. Idempotent — stopping a session this process no longer holds still attempts to reconcile the durable row.

      Parameters

      • sessionBridgeID: string

        The AIAgentSessionBridge row id to stop.

      • reason: BridgeDisconnectReason

        Why the bridge is closing (mirrors CloseReason).

      • OptionalcontextUser: UserInfo

        Required server-side for the durable-row write when the live session is gone.

      • Optionalprovider: IMetadataProvider

        Required metadata provider when the live session is gone.

      Returns Promise<boolean>

      true when the durable row reached a Disconnected state.

    • Reaps live, same-process sessions that have gone stale — idle past SESSION_IDLE_TTL_MS (no inbound transcript) or running past SESSION_MAX_DURATION_MS. This is the same-process complement to ReconcileOrphans (prior-boot orphans): it covers a missed leave event, a rosterless transport with no occupancy signal, and "the bot joined but nobody came." Each reap routes through StopBridgeSession using the session's own user/provider, so the co-agent run finalizes.

      Tolerant: a single failed stop is logged and the sweep continues. Safe to call on any cadence.

      Parameters

      • nowMs: number = ...

        Current epoch-ms (injectable for tests; defaults to Date.now()).

      Returns Promise<number>

      The number of stale sessions reaped.

    • Removes a bridge session from the multi-agent room coordinator (its bridge stopped / it left the room). Releases the floor if the leaving agent held it and clears the facilitator slot if it was the facilitator. Safe to call unconditionally on teardown — a no-op for sessions that were never registered as room participants.

      Parameters

      • roomId: string

        The shared room the agent is leaving.

      • agentSessionId: string

        The agent session leaving.

      Returns void

    • Returns the singleton instance of the class. If the instance does not exist, it is created and stored in the Global Object Store. If className is provided it will be used as part of the key in the Global Object Store, otherwise the actual class name will be used. NOTE: the class name used by default is the lowest level of the object hierarchy, so if you have a class that extends another class, the lowest level class name will be used.

      Type Parameters

      Parameters

      • this: new () => T
      • OptionalclassName: string

      Returns T