Member Junction
    Preparing search index...

    Real-time, full-duplex driver for the AssemblyAI Voice Agent API (launched April 2026), implementing the Core BaseRealtimeModel primitive. Registers as AssemblyAIRealtime and is resolved for MJ: AI Models typed Realtime (API-key env alias: AI_VENDOR_API_KEY__AssemblyAIRealtime).

    What the provider is: a single-websocket speech-to-speech stack — Universal-3 Pro streaming ASR, server-side turn detection / barge-in, LLM reasoning, JSON-Schema tool calling, and conversational TTS — billed flat per session-hour. Unlike ElevenLabs there is no server-side agent object to manage: the ENTIRE session config (prompt, tools, voice, turn detection) is supplied per-session via the first session.update frame, so MJ's prompt/tool authority is native here, with no managed-agent ensure flow.

    Model resolution: the Voice Agent API exposes ONE endpoint and no model selection; params.Model is carried through to ClientRealtimeSessionConfig.Model for bookkeeping but plays no wire role.

    Topologies:

    • Server-bridged (StartSession): the driver opens the websocket itself (?token=<api key>), sends the session config, and resolves only after session.ready.
    • Client-direct (CreateClientSession): the driver mints a ONE-TIME, short-lived client token (GET /v1/token) — the browser opens its own socket with it (no API key ever leaves the server) and applies the server-built session object from the SessionConfig pact.

    No usage events: billing is a flat hourly session rate; the websocket reports no token usage, so sessions never emit IRealtimeSession.OnUsage. (The terminal session.ended frame carries duration seconds, but by then the consumer has typically closed — duration accounting lives in the provider dashboard.)

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    SupportsDynamicToolSet?: boolean

    Whether this driver subclass supports dynamic, multi-tool sets projected into the realtime session (e.g. direct action invocation on realtime co-agents).

    Static capability descriptor read before a session instance exists. Default: absent / false. Subclasses that support dynamic toolsets declare public static readonly SupportsDynamicToolSet = true;.

    Accessors

    • get apiKey(): string

      Only sub-classes can access the API key

      Returns string

    • get SupportsClientDirect(): boolean

      AssemblyAI supports the client-direct topology natively: a one-time temp token minted server-side authenticates the browser's own websocket.

      Returns boolean

    • get SupportsVideo(): boolean

      Whether this driver's sessions carry a video track in addition to audio — i.e. the model accepts video input (it can "see" the user's camera) and/or emits video output (a talking-head avatar / generated video), in sync with audio.

      Defaults to false (audio-only — today's realtime models). Video-capable drivers (a native multimodal realtime model, or an avatar provider) override this to true. The session's media plane is media-tagged (IRealtimeSession.SendInput takes a RealtimeMediaKind; IRealtimeSession.OnVideoOutput delivers video-out), so a video session reuses the entire realtime contract — only the media frames gain a video kind. Resolution prefers a video-capable model when an agent requests video, and degrades to audio-only otherwise.

      Returns boolean

      true if sessions can carry video; false (audio-only) otherwise.

    Methods

    • Optional WebRTC SDP exchange seam for drivers that support server-brokered WebRTC topologies.

      Parameters

      • _offerSdp: string

        The local SDP offer generated by the browser.

      • Optional_sessionConfig: Record<string, unknown>

        The session configuration to initialize the session with.

      Returns Promise<{ answerSdp: string; prebillSeconds: number; sessionId: string }>

      The answer SDP, provider session ID, and any prebill accounting.

    • REST seam: mints a ONE-TIME client token for a browser-direct session (GET /v1/token?expires_in_seconds=… with Authorization: Bearer <api key>).

      Parameters

      • expiresInSeconds: number

      Returns Promise<string>

    • Builds the session object for the session.update frame from the Core params:

      • system_prompt: the session system prompt, with InitialContext folded in under a "Prior context" heading — the protocol has no history-seeding channel, so prior conversation context rides the prompt.
      • tools: the Core tool set mapped to the provider's { type: 'function', … } schema.
      • Recognized params.Config keys pass through to their wire slots: voiceoutput.voice, firstMessage (or the legacy greeting) → greeting (spoken on connect; omitted = no auto-greeting), turn_detectioninput.turn_detection, keytermsinput.keyterms.

      Parameters

      Returns JSONObject

    • Folds optional prior context into the system prompt (no history channel exists).

      Parameters

      • systemPrompt: string
      • OptionalinitialContext: string

      Returns string

    • Reads the session's opening utterance out of the config bag — this driver's greeting wire slot, fed from the driver-NEUTRAL firstMessage key (issue #3557) that a persona authors without knowing which vendor will run. greeting predates the neutral name and is still accepted so existing configs keep working.

      Both keys go through the SAME trim-and-drop-blank rule the ElevenLabs driver applies, so one authored value means the same thing on either provider. That rule is also why the neutral key only wins when it carries something: a blank firstMessage must not suppress a valid legacy greeting — it is an absent opening utterance, not an empty one.

      Parameters

      Returns string

      The trimmed opening utterance, or undefined when neither key carries one.