@memberjunction/ai-realtime-client 6.2.0-edge.2 → 6.2.0-edge.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +156 -29
- package/dist/audio/audioMeter.d.ts +71 -0
- package/dist/audio/audioMeter.d.ts.map +1 -1
- package/dist/audio/audioMeter.js +83 -0
- package/dist/audio/audioMeter.js.map +1 -1
- package/dist/audio/mediaElementAudioRouter.d.ts +41 -0
- package/dist/audio/mediaElementAudioRouter.d.ts.map +1 -0
- package/dist/audio/mediaElementAudioRouter.js +82 -0
- package/dist/audio/mediaElementAudioRouter.js.map +1 -0
- package/dist/audio/micCapture.d.ts +12 -3
- package/dist/audio/micCapture.d.ts.map +1 -1
- package/dist/audio/micCapture.js +15 -1
- package/dist/audio/micCapture.js.map +1 -1
- package/dist/audio/pcmPlayback.d.ts +72 -4
- package/dist/audio/pcmPlayback.d.ts.map +1 -1
- package/dist/audio/pcmPlayback.js +101 -1
- package/dist/audio/pcmPlayback.js.map +1 -1
- package/dist/drivers/assemblyAIRealtimeClient.d.ts +2 -0
- package/dist/drivers/assemblyAIRealtimeClient.d.ts.map +1 -1
- package/dist/drivers/assemblyAIRealtimeClient.js +14 -0
- package/dist/drivers/assemblyAIRealtimeClient.js.map +1 -1
- package/dist/drivers/elevenLabsRealtimeClient.d.ts +2 -0
- package/dist/drivers/elevenLabsRealtimeClient.d.ts.map +1 -1
- package/dist/drivers/elevenLabsRealtimeClient.js +14 -0
- package/dist/drivers/elevenLabsRealtimeClient.js.map +1 -1
- package/dist/drivers/geminiAvatarOutput.d.ts +132 -0
- package/dist/drivers/geminiAvatarOutput.d.ts.map +1 -0
- package/dist/drivers/geminiAvatarOutput.js +310 -0
- package/dist/drivers/geminiAvatarOutput.js.map +1 -0
- package/dist/drivers/geminiEnterpriseRealtimeClient.d.ts +38 -0
- package/dist/drivers/geminiEnterpriseRealtimeClient.d.ts.map +1 -0
- package/dist/drivers/geminiEnterpriseRealtimeClient.js +107 -0
- package/dist/drivers/geminiEnterpriseRealtimeClient.js.map +1 -0
- package/dist/drivers/geminiRealtimeClient.d.ts +314 -48
- package/dist/drivers/geminiRealtimeClient.d.ts.map +1 -1
- package/dist/drivers/geminiRealtimeClient.js +759 -176
- package/dist/drivers/geminiRealtimeClient.js.map +1 -1
- package/dist/drivers/openAILiveClient.d.ts +5 -8
- package/dist/drivers/openAILiveClient.d.ts.map +1 -1
- package/dist/drivers/openAILiveClient.js +19 -32
- package/dist/drivers/openAILiveClient.js.map +1 -1
- package/dist/drivers/openAIRealtimeClient.d.ts +23 -26
- package/dist/drivers/openAIRealtimeClient.d.ts.map +1 -1
- package/dist/drivers/openAIRealtimeClient.js +42 -57
- package/dist/drivers/openAIRealtimeClient.js.map +1 -1
- package/dist/generic/baseRealtimeClient.d.ts +188 -30
- package/dist/generic/baseRealtimeClient.d.ts.map +1 -1
- package/dist/generic/baseRealtimeClient.js +250 -14
- package/dist/generic/baseRealtimeClient.js.map +1 -1
- package/dist/generic/openAIProtocolClient.d.ts +57 -1
- package/dist/generic/openAIProtocolClient.d.ts.map +1 -1
- package/dist/generic/openAIProtocolClient.js +89 -4
- package/dist/generic/openAIProtocolClient.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/media/attachVideoSource.d.ts +23 -0
- package/dist/media/attachVideoSource.d.ts.map +1 -0
- package/dist/media/attachVideoSource.js +49 -0
- package/dist/media/attachVideoSource.js.map +1 -0
- package/dist/media/channelVideoSource.d.ts +110 -14
- package/dist/media/channelVideoSource.d.ts.map +1 -1
- package/dist/media/channelVideoSource.js +183 -18
- package/dist/media/channelVideoSource.js.map +1 -1
- package/dist/media/decoders/frameScheduler.d.ts +119 -0
- package/dist/media/decoders/frameScheduler.d.ts.map +1 -0
- package/dist/media/decoders/frameScheduler.js +238 -0
- package/dist/media/decoders/frameScheduler.js.map +1 -0
- package/dist/media/decoders/imageFrameDecoder.d.ts +58 -0
- package/dist/media/decoders/imageFrameDecoder.d.ts.map +1 -0
- package/dist/media/decoders/imageFrameDecoder.js +110 -0
- package/dist/media/decoders/imageFrameDecoder.js.map +1 -0
- package/dist/media/decoders/mseFmp4Decoder.d.ts +130 -0
- package/dist/media/decoders/mseFmp4Decoder.d.ts.map +1 -0
- package/dist/media/decoders/mseFmp4Decoder.js +402 -0
- package/dist/media/decoders/mseFmp4Decoder.js.map +1 -0
- package/dist/media/decoders/streamCanvas.d.ts +46 -0
- package/dist/media/decoders/streamCanvas.d.ts.map +1 -0
- package/dist/media/decoders/streamCanvas.js +163 -0
- package/dist/media/decoders/streamCanvas.js.map +1 -0
- package/dist/media/decoders/videoMimeTypes.d.ts +29 -0
- package/dist/media/decoders/videoMimeTypes.d.ts.map +1 -0
- package/dist/media/decoders/videoMimeTypes.js +50 -0
- package/dist/media/decoders/videoMimeTypes.js.map +1 -0
- package/dist/media/decoders/webCodecsChunkDecoder.d.ts +99 -0
- package/dist/media/decoders/webCodecsChunkDecoder.d.ts.map +1 -0
- package/dist/media/decoders/webCodecsChunkDecoder.js +265 -0
- package/dist/media/decoders/webCodecsChunkDecoder.js.map +1 -0
- package/dist/media/displayCapture.d.ts +128 -0
- package/dist/media/displayCapture.d.ts.map +1 -0
- package/dist/media/displayCapture.js +245 -0
- package/dist/media/displayCapture.js.map +1 -0
- package/dist/media/frameCapture.d.ts +25 -8
- package/dist/media/frameCapture.d.ts.map +1 -1
- package/dist/media/frameCapture.js +42 -72
- package/dist/media/frameCapture.js.map +1 -1
- package/dist/media/frameSampler.d.ts +94 -0
- package/dist/media/frameSampler.d.ts.map +1 -0
- package/dist/media/frameSampler.js +134 -0
- package/dist/media/frameSampler.js.map +1 -0
- package/dist/media/index.d.ts +32 -0
- package/dist/media/index.d.ts.map +1 -0
- package/dist/media/index.js +32 -0
- package/dist/media/index.js.map +1 -0
- package/dist/media/localMediaController.d.ts +116 -0
- package/dist/media/localMediaController.d.ts.map +1 -0
- package/dist/media/localMediaController.js +281 -0
- package/dist/media/localMediaController.js.map +1 -0
- package/dist/media/mediaLayout.d.ts +93 -0
- package/dist/media/mediaLayout.d.ts.map +1 -0
- package/dist/media/mediaLayout.js +187 -0
- package/dist/media/mediaLayout.js.map +1 -0
- package/dist/media/mediaPreview.d.ts +94 -0
- package/dist/media/mediaPreview.d.ts.map +1 -0
- package/dist/media/mediaPreview.js +154 -0
- package/dist/media/mediaPreview.js.map +1 -0
- package/dist/media/mediaStage.d.ts +99 -0
- package/dist/media/mediaStage.d.ts.map +1 -0
- package/dist/media/mediaStage.js +171 -0
- package/dist/media/mediaStage.js.map +1 -0
- package/dist/media/model.d.ts +154 -0
- package/dist/media/model.d.ts.map +1 -0
- package/dist/media/model.js +9 -0
- package/dist/media/model.js.map +1 -0
- package/dist/media/playbackClock.d.ts +20 -0
- package/dist/media/playbackClock.d.ts.map +1 -0
- package/dist/media/playbackClock.js +13 -0
- package/dist/media/playbackClock.js.map +1 -0
- package/dist/media/videoFrameDecoder.d.ts +86 -0
- package/dist/media/videoFrameDecoder.d.ts.map +1 -0
- package/dist/media/videoFrameDecoder.js +2 -0
- package/dist/media/videoFrameDecoder.js.map +1 -0
- package/dist/media/videoFrameDecoderRegistry.d.ts +40 -0
- package/dist/media/videoFrameDecoderRegistry.d.ts.map +1 -0
- package/dist/media/videoFrameDecoderRegistry.js +69 -0
- package/dist/media/videoFrameDecoderRegistry.js.map +1 -0
- package/dist/media/videoPacing.d.ts +32 -0
- package/dist/media/videoPacing.d.ts.map +1 -0
- package/dist/media/videoPacing.js +37 -0
- package/dist/media/videoPacing.js.map +1 -0
- package/dist/media/videoPlayout.d.ts +168 -0
- package/dist/media/videoPlayout.d.ts.map +1 -0
- package/dist/media/videoPlayout.js +217 -0
- package/dist/media/videoPlayout.js.map +1 -0
- package/dist/media/videoSourceArbiter.d.ts +250 -0
- package/dist/media/videoSourceArbiter.d.ts.map +1 -0
- package/dist/media/videoSourceArbiter.js +423 -0
- package/dist/media/videoSourceArbiter.js.map +1 -0
- package/dist/testing/conformanceAssertions.d.ts +25 -0
- package/dist/testing/conformanceAssertions.d.ts.map +1 -0
- package/dist/testing/conformanceAssertions.js +64 -0
- package/dist/testing/conformanceAssertions.js.map +1 -0
- package/dist/testing/conformanceFixtures.d.ts +76 -0
- package/dist/testing/conformanceFixtures.d.ts.map +1 -0
- package/dist/testing/conformanceFixtures.js +169 -0
- package/dist/testing/conformanceFixtures.js.map +1 -0
- package/dist/testing/conformanceGates.d.ts +32 -0
- package/dist/testing/conformanceGates.d.ts.map +1 -0
- package/dist/testing/conformanceGates.js +35 -0
- package/dist/testing/conformanceGates.js.map +1 -0
- package/dist/testing/conformanceMicrophone.d.ts +10 -0
- package/dist/testing/conformanceMicrophone.d.ts.map +1 -0
- package/dist/testing/conformanceMicrophone.js +71 -0
- package/dist/testing/conformanceMicrophone.js.map +1 -0
- package/dist/testing/conformanceTimeline.d.ts +128 -0
- package/dist/testing/conformanceTimeline.d.ts.map +1 -0
- package/dist/testing/conformanceTimeline.js +32 -0
- package/dist/testing/conformanceTimeline.js.map +1 -0
- package/dist/testing/conformanceVideoStream.d.ts +29 -0
- package/dist/testing/conformanceVideoStream.d.ts.map +1 -0
- package/dist/testing/conformanceVideoStream.js +39 -0
- package/dist/testing/conformanceVideoStream.js.map +1 -0
- package/dist/testing/index.d.ts +29 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +28 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/realtimeVideoConformance.d.ts +23 -0
- package/dist/testing/realtimeVideoConformance.d.ts.map +1 -0
- package/dist/testing/realtimeVideoConformance.js +139 -0
- package/dist/testing/realtimeVideoConformance.js.map +1 -0
- package/dist/testing/realtimeVideoConformanceChecks.d.ts +4 -0
- package/dist/testing/realtimeVideoConformanceChecks.d.ts.map +1 -0
- package/dist/testing/realtimeVideoConformanceChecks.js +164 -0
- package/dist/testing/realtimeVideoConformanceChecks.js.map +1 -0
- package/dist/testing/realtimeVideoConformanceFrameChecks.d.ts +4 -0
- package/dist/testing/realtimeVideoConformanceFrameChecks.d.ts.map +1 -0
- package/dist/testing/realtimeVideoConformanceFrameChecks.js +63 -0
- package/dist/testing/realtimeVideoConformanceFrameChecks.js.map +1 -0
- package/dist/testing/realtimeVideoConformanceSession.d.ts +108 -0
- package/dist/testing/realtimeVideoConformanceSession.d.ts.map +1 -0
- package/dist/testing/realtimeVideoConformanceSession.js +270 -0
- package/dist/testing/realtimeVideoConformanceSession.js.map +1 -0
- package/dist/testing/realtimeVideoConformanceTurnChecks.d.ts +4 -0
- package/dist/testing/realtimeVideoConformanceTurnChecks.d.ts.map +1 -0
- package/dist/testing/realtimeVideoConformanceTurnChecks.js +248 -0
- package/dist/testing/realtimeVideoConformanceTurnChecks.js.map +1 -0
- package/dist/testing/realtimeVideoConformanceTypes.d.ts +155 -0
- package/dist/testing/realtimeVideoConformanceTypes.d.ts.map +1 -0
- package/dist/testing/realtimeVideoConformanceTypes.js +2 -0
- package/dist/testing/realtimeVideoConformanceTypes.js.map +1 -0
- package/dist/testing/recordingPlayout.d.ts +84 -0
- package/dist/testing/recordingPlayout.d.ts.map +1 -0
- package/dist/testing/recordingPlayout.js +120 -0
- package/dist/testing/recordingPlayout.js.map +1 -0
- package/package.json +29 -4
|
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { RegisterClass } from '@memberjunction/global';
|
|
8
8
|
import { RealtimeAudioMeter } from '../audio/audioMeter.js';
|
|
9
|
-
import { BaseRealtimeClient } from '../generic/baseRealtimeClient.js';
|
|
9
|
+
import { BaseRealtimeClient, ToProviderSessionConfig } from '../generic/baseRealtimeClient.js';
|
|
10
10
|
import { OpenAIProtocolRealtimeClient, } from '../generic/openAIProtocolClient.js';
|
|
11
11
|
/**
|
|
12
12
|
* OpenAI implementation of {@link BaseRealtimeClient}: a **browser-direct** WebRTC
|
|
@@ -32,17 +32,11 @@ let OpenAIRealtimeClient = class OpenAIRealtimeClient extends OpenAIProtocolReal
|
|
|
32
32
|
super(...arguments);
|
|
33
33
|
// ── Transport ──────────────────────────────────────────────────────────────
|
|
34
34
|
this.peerConnection = null;
|
|
35
|
+
/** The senders carrying the mic tracks, kept so {@link ReplaceMicrophone} can move them to a new track. */
|
|
36
|
+
this.micSenders = [];
|
|
35
37
|
/** Protected so test subclasses can inspect/inject; production code treats it as private. */
|
|
36
38
|
this.dataChannel = null;
|
|
37
39
|
this.remoteAudioEl = null;
|
|
38
|
-
/**
|
|
39
|
-
* The AGENT's remote-audio stream, captured from the peer connection's `ontrack` event
|
|
40
|
-
* (see {@link attachRemoteAudio}). Exposed via {@link GetRemoteMediaStream} so a host can
|
|
41
|
-
* mix the agent's voice into a browser-side recording. `null` until the remote track lands.
|
|
42
|
-
*/
|
|
43
|
-
this.remoteStream = null;
|
|
44
|
-
/** Host handlers notified when the agent's remote-audio stream lands (or immediately, if already present). */
|
|
45
|
-
this.remoteStreamHandlers = [];
|
|
46
40
|
/**
|
|
47
41
|
* The server-built session config applied verbatim via `session.update` when the data
|
|
48
42
|
* channel opens. Protected so test subclasses can seed it without a full Connect.
|
|
@@ -63,6 +57,7 @@ let OpenAIRealtimeClient = class OpenAIRealtimeClient extends OpenAIProtocolReal
|
|
|
63
57
|
* data channel opens; the client reports `'listening'` at that point.
|
|
64
58
|
*/
|
|
65
59
|
async Connect(config, micStream) {
|
|
60
|
+
this.AssertTransportSupported(config);
|
|
66
61
|
this.sessionConfig = config.SessionConfig;
|
|
67
62
|
this.micStream = micStream;
|
|
68
63
|
this.setState('connecting');
|
|
@@ -78,6 +73,22 @@ let OpenAIRealtimeClient = class OpenAIRealtimeClient extends OpenAIProtocolReal
|
|
|
78
73
|
await this.performSdpHandshake(pc, config.EphemeralToken);
|
|
79
74
|
this.setState('connected');
|
|
80
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Moves the mic senders and the input meter to the stream's current tracks (obligation #10).
|
|
78
|
+
* `replaceTrack` needs no renegotiation, so the call carries on.
|
|
79
|
+
*/
|
|
80
|
+
async ReplaceMicrophone(micStream) {
|
|
81
|
+
if (this.micSenders.length === 0) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const tracks = micStream.getAudioTracks();
|
|
85
|
+
if (tracks.length === 0) {
|
|
86
|
+
throw new Error('The microphone stream has no audio track.');
|
|
87
|
+
}
|
|
88
|
+
await Promise.all(this.micSenders.map((sender, index) => sender.replaceTrack(tracks[index] ?? null)));
|
|
89
|
+
this.micStream = micStream;
|
|
90
|
+
this.attachInputAudioMeter(RealtimeAudioMeter.ForMicStream(micStream));
|
|
91
|
+
}
|
|
81
92
|
/**
|
|
82
93
|
* Tears down the channel, peer connection, mic tracks, and audio sink, resets the
|
|
83
94
|
* response state machine, and emits a final `'closed'` (unless already `'error'`).
|
|
@@ -86,6 +97,7 @@ let OpenAIRealtimeClient = class OpenAIRealtimeClient extends OpenAIProtocolReal
|
|
|
86
97
|
this.closeAudioMeters();
|
|
87
98
|
this.micStream?.getTracks().forEach((t) => t.stop());
|
|
88
99
|
this.micStream = null;
|
|
100
|
+
this.micSenders = [];
|
|
89
101
|
if (this.dataChannel) {
|
|
90
102
|
try {
|
|
91
103
|
this.dataChannel.close();
|
|
@@ -105,9 +117,8 @@ let OpenAIRealtimeClient = class OpenAIRealtimeClient extends OpenAIProtocolReal
|
|
|
105
117
|
this.remoteAudioEl.remove();
|
|
106
118
|
this.remoteAudioEl = null;
|
|
107
119
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
this.remoteStreamHandlers = [];
|
|
120
|
+
// Drops the stream and the session-scoped host handlers (must not survive a reused instance).
|
|
121
|
+
this.clearRemoteMediaStream();
|
|
111
122
|
this.sessionConfig = null;
|
|
112
123
|
this.resetResponseState();
|
|
113
124
|
this.audioPlaying = false;
|
|
@@ -194,11 +205,9 @@ let OpenAIRealtimeClient = class OpenAIRealtimeClient extends OpenAIProtocolReal
|
|
|
194
205
|
return response.text();
|
|
195
206
|
}
|
|
196
207
|
// ── Connection internals ───────────────────────────────────────────────────
|
|
197
|
-
/** Streams the mic tracks to the provider. */
|
|
208
|
+
/** Streams the mic tracks to the provider, keeping their senders. */
|
|
198
209
|
attachMicrophone(pc, micStream) {
|
|
199
|
-
|
|
200
|
-
pc.addTrack(track, micStream);
|
|
201
|
-
}
|
|
210
|
+
this.micSenders = micStream.getAudioTracks().map((track) => pc.addTrack(track, micStream));
|
|
202
211
|
}
|
|
203
212
|
/** Routes the provider's audio track into the hidden `<audio>` sink. */
|
|
204
213
|
attachRemoteAudio(pc) {
|
|
@@ -206,52 +215,16 @@ let OpenAIRealtimeClient = class OpenAIRealtimeClient extends OpenAIProtocolReal
|
|
|
206
215
|
pc.ontrack = (e) => {
|
|
207
216
|
if (this.remoteAudioEl && e.streams[0]) {
|
|
208
217
|
this.remoteAudioEl.srcObject = e.streams[0];
|
|
209
|
-
//
|
|
210
|
-
// (see GetRemoteMediaStream)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
// so they can mix it in — the track typically lands AFTER recording already began.
|
|
214
|
-
this.notifyRemoteStream(e.streams[0]);
|
|
218
|
+
// Publish the agent's remote stream so a host can mix it into a recording
|
|
219
|
+
// (see GetRemoteMediaStream) — the track typically lands AFTER recording already
|
|
220
|
+
// began. Playback still flows through the <audio> element.
|
|
221
|
+
this.publishRemoteMediaStream(e.streams[0]);
|
|
215
222
|
// Agent-side audio meter taps the remote stream (obligation #9). The
|
|
216
223
|
// analyser sinks nowhere — playback still flows through the <audio> element.
|
|
217
224
|
this.attachOutputAudioMeter(RealtimeAudioMeter.ForStream(e.streams[0]));
|
|
218
225
|
}
|
|
219
226
|
};
|
|
220
227
|
}
|
|
221
|
-
/**
|
|
222
|
-
* Returns the AGENT's remote-audio stream once the WebRTC `ontrack` event has delivered it,
|
|
223
|
-
* or `null` before the track lands. Lets a host mix the agent's voice into a browser-side
|
|
224
|
-
* recording alongside the mic.
|
|
225
|
-
*/
|
|
226
|
-
GetRemoteMediaStream() {
|
|
227
|
-
return this.remoteStream;
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Registers a handler invoked when the agent's remote-audio stream becomes available — either
|
|
231
|
-
* later via the WebRTC `ontrack`, or IMMEDIATELY if the track has already landed. Lets a host
|
|
232
|
-
* attach the agent voice to a recording that started (mic-only) before the track arrived.
|
|
233
|
-
*/
|
|
234
|
-
OnRemoteMediaStream(handler) {
|
|
235
|
-
this.remoteStreamHandlers.push(handler);
|
|
236
|
-
if (this.remoteStream) {
|
|
237
|
-
this.invokeRemoteStreamHandler(handler, this.remoteStream);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
/** Fans a freshly-landed remote stream out to all registered host handlers. */
|
|
241
|
-
notifyRemoteStream(stream) {
|
|
242
|
-
for (const handler of this.remoteStreamHandlers) {
|
|
243
|
-
this.invokeRemoteStreamHandler(handler, stream);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
/** Invokes one remote-stream handler, isolating host errors so they never disturb the call. */
|
|
247
|
-
invokeRemoteStreamHandler(handler, stream) {
|
|
248
|
-
try {
|
|
249
|
-
handler(stream);
|
|
250
|
-
}
|
|
251
|
-
catch (error) {
|
|
252
|
-
console.warn('[OpenAIRealtimeClient] remote-stream handler threw:', error);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
228
|
/**
|
|
256
229
|
* Adopts + wires the events data channel: applies the session config and reports
|
|
257
230
|
* `'listening'` on open; translates inbound frames through the shared protocol brain;
|
|
@@ -284,6 +257,18 @@ let OpenAIRealtimeClient = class OpenAIRealtimeClient extends OpenAIProtocolReal
|
|
|
284
257
|
const answerSdp = await this.postSdpOffer(offer.sdp ?? '', ephemeralToken);
|
|
285
258
|
await pc.setRemoteDescription({ type: 'answer', sdp: answerSdp });
|
|
286
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* @inheritdoc
|
|
262
|
+
*
|
|
263
|
+
* This transport keeps the pact in {@link sessionConfig} rather than in the protocol
|
|
264
|
+
* client's `sessionObject` — WebRTC applies it over the data channel, so the base field is
|
|
265
|
+
* never populated here. Without this override a spoken update would find no identity to
|
|
266
|
+
* carry and would send the caller's direction alone, which is the defect the base method
|
|
267
|
+
* documents (#397).
|
|
268
|
+
*/
|
|
269
|
+
currentSessionInstructions() {
|
|
270
|
+
return OpenAIProtocolRealtimeClient.readInstructions(this.sessionConfig);
|
|
271
|
+
}
|
|
287
272
|
/**
|
|
288
273
|
* Sends the server-controlled session config (instructions + tools) as a
|
|
289
274
|
* `session.update` so the co-agent's identity and tool set apply. Skipped when the
|
|
@@ -295,7 +280,7 @@ let OpenAIRealtimeClient = class OpenAIRealtimeClient extends OpenAIProtocolReal
|
|
|
295
280
|
return;
|
|
296
281
|
}
|
|
297
282
|
if (channel.readyState === 'open') {
|
|
298
|
-
channel.send(JSON.stringify({ type: 'session.update', session: this.sessionConfig }));
|
|
283
|
+
channel.send(JSON.stringify({ type: 'session.update', session: ToProviderSessionConfig(this.sessionConfig) }));
|
|
299
284
|
}
|
|
300
285
|
}
|
|
301
286
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openAIRealtimeClient.js","sourceRoot":"","sources":["../../src/drivers/openAIRealtimeClient.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"openAIRealtimeClient.js","sourceRoot":"","sources":["../../src/drivers/openAIRealtimeClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,20 @@
|
|
|
1
|
-
import { ClientRealtimeSessionConfig, RealtimeTrack, RealtimeTrackDescriptor, RealtimeTrackDirection, RealtimeUsageModalityDetail } from '@memberjunction/ai';
|
|
1
|
+
import { ClientRealtimeSessionConfig, JSONObject, RealtimeTrack, RealtimeTrackDescriptor, RealtimeTrackDirection, RealtimeUsageModalityDetail } from '@memberjunction/ai';
|
|
2
2
|
import { IRealtimeAudioMeter } from '../audio/audioMeter.js';
|
|
3
|
+
import type { MediaVideoSource } from '../media/model.js';
|
|
4
|
+
/**
|
|
5
|
+
* Session-config key under which the realtime runtime hands a driver the tracks to negotiate
|
|
6
|
+
* (`RealtimeSessionRuntime.BuildClientConfig` aggregates them from the active channels). It is a
|
|
7
|
+
* CLIENT-side negotiation hint, never a provider field: a driver reads it (Gemini) or ignores it.
|
|
8
|
+
*/
|
|
9
|
+
export declare const REQUESTED_TRACKS_SESSION_KEY = "requestedTracks";
|
|
10
|
+
/**
|
|
11
|
+
* The session config as the PROVIDER must receive it: the server-built config minus the
|
|
12
|
+
* client-only hints the runtime adds. Drivers that send the config on the wire go through this —
|
|
13
|
+
* OpenAI's Realtime API rejects the WHOLE `session.update` on an unknown key
|
|
14
|
+
* (`unknown_parameter: 'session.requestedTracks'`), so one stray hint costs the session its
|
|
15
|
+
* instructions and every tool.
|
|
16
|
+
*/
|
|
17
|
+
export declare function ToProviderSessionConfig(sessionConfig: JSONObject): JSONObject;
|
|
3
18
|
/**
|
|
4
19
|
* A point-in-time snapshot of the session's audible activity, sampled by the host
|
|
5
20
|
* (typically per animation frame) via {@link BaseRealtimeClient.GetAudioActivity} to drive
|
|
@@ -84,7 +99,9 @@ export interface RealtimeClientToolCall {
|
|
|
84
99
|
* simply never emit):
|
|
85
100
|
* - **OpenAI** — emits per-response deltas from the GA `response.done` frame's `usage` payload.
|
|
86
101
|
* - **Gemini** — emits per-turn deltas from `LiveServerMessage.usageMetadata`
|
|
87
|
-
* (`promptTokenCount` / `responseTokenCount` are per-response counts, not cumulative)
|
|
102
|
+
* (`promptTokenCount` / `responseTokenCount` are per-response counts, not cumulative), and,
|
|
103
|
+
* in an avatar session, the seconds of avatar video each turn generated, in updates of their
|
|
104
|
+
* own that carry only `OutputTokenDetails.VideoSeconds`.
|
|
88
105
|
* - **ElevenLabs** — the Conversational AI socket exposes no usage events; never emits.
|
|
89
106
|
* - **AssemblyAI** — the streaming STT socket exposes no token-usage events; never emits.
|
|
90
107
|
*/
|
|
@@ -100,7 +117,10 @@ export interface RealtimeClientUsage {
|
|
|
100
117
|
DurationSeconds?: number;
|
|
101
118
|
/** Per-modality breakdown of input tokens (text, audio, image/video). */
|
|
102
119
|
InputTokenDetails?: RealtimeUsageModalityDetail;
|
|
103
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* Per-modality breakdown of output tokens (text, audio, video), and the seconds of avatar video
|
|
122
|
+
* generated since the last update (`VideoSeconds`, an amount like the tokens).
|
|
123
|
+
*/
|
|
104
124
|
OutputTokenDetails?: RealtimeUsageModalityDetail;
|
|
105
125
|
/** Cumulative video frames processed or sent across inbound video tracks. */
|
|
106
126
|
VideoFrames?: number;
|
|
@@ -123,6 +143,11 @@ export interface RealtimeClientUsage {
|
|
|
123
143
|
* receiving a tool call and calling {@link BaseRealtimeClient.SendToolResult}.
|
|
124
144
|
*/
|
|
125
145
|
export type RealtimeClientState = 'connecting' | 'connected' | 'listening' | 'speaking' | 'closed' | 'error';
|
|
146
|
+
/**
|
|
147
|
+
* The {@link RealtimeClientError.Code} of a call that ended because its session reached its time limit (MJAPI's relay
|
|
148
|
+
* closed it with `REALTIME_RELAY_TIME_LIMIT_CLOSE_CODE`), so a host can say so instead of showing a connection error.
|
|
149
|
+
*/
|
|
150
|
+
export declare const REALTIME_CLIENT_TIME_LIMIT_ERROR_CODE = "time-limit";
|
|
126
151
|
/**
|
|
127
152
|
* An error surfaced by a realtime client. `Fatal: true` means the session is unusable
|
|
128
153
|
* (transport failure); `Fatal: false` is a provider-reported, recoverable error frame.
|
|
@@ -212,6 +237,32 @@ export interface RealtimeClientError {
|
|
|
212
237
|
* client-owned-audio drivers, the remote WebRTC stream on peer-connection drivers.
|
|
213
238
|
* Meters must be released on disconnect ({@link closeAudioMeters}). A driver with no
|
|
214
239
|
* tappable plane simply attaches nothing — hosts fall back to turn-state animation.
|
|
240
|
+
* 10. **Follow a replaced microphone track, when the transport can.** A device switch or a
|
|
241
|
+
* lost device swaps the track inside the mic stream, and anything bound to the old track (a
|
|
242
|
+
* WebRTC sender, a Web Audio source node, the input meter's clone) goes silent. A driver
|
|
243
|
+
* implements {@link BaseRealtimeClient.ReplaceMicrophone} to rebind them: `replaceTrack` on
|
|
244
|
+
* its senders, or `IPcmMicCapture.Rebind` on its PCM capture, and a new input meter.
|
|
245
|
+
* 11. **Refuse a transport you don't speak.** A session minted to run through MJAPI's realtime
|
|
246
|
+
* relay (`ClientRealtimeSessionConfig.Transport` `'relay'`) has no provider token, only a relay
|
|
247
|
+
* URL. Every driver calls {@link BaseRealtimeClient.AssertTransportSupported} first in
|
|
248
|
+
* {@link BaseRealtimeClient.Connect}, so a driver that connects only to its provider refuses
|
|
249
|
+
* such a session with a clear error instead of failing at the provider. A driver that speaks
|
|
250
|
+
* its provider's protocol through the relay opts in by overriding
|
|
251
|
+
* {@link BaseRealtimeClient.SupportsRelayTransport}.
|
|
252
|
+
* 12. **The agent's video keeps the voice's rules.** A driver whose model sends the agent's video
|
|
253
|
+
* hands it over through {@link emitRemoteVideo} once per session, and only while its outbound
|
|
254
|
+
* video track is live; an audio-only session hands over nothing and never plays a video part as
|
|
255
|
+
* audio. Its player gets each frame as the model sent it (a `RealtimeVideoFrame`, in order).
|
|
256
|
+
* Barge-in flushes the video with the voice (obligation #3) and the cut turn's late media never
|
|
257
|
+
* plays; a turn's end lets its video play out; a video that carries the voice never plays it
|
|
258
|
+
* twice; each second of generated video is reported once (`OutputTokenDetails.VideoSeconds`); the
|
|
259
|
+
* video a model streams between answers (Vertex AI's avatar does) plays, but is not the agent
|
|
260
|
+
* speaking: it reports no `'speaking'`, leaves {@link IsBusy} as it was, and does not keep
|
|
261
|
+
* {@link IsAudioPlaying} true once the answer's media has played; a resumed session keeps its
|
|
262
|
+
* video; `Disconnect` releases it. A driver whose voice and video share a media timeline queues
|
|
263
|
+
* its PCM at its media times and gives the player its voice playback as the clock
|
|
264
|
+
* (`VideoPlayoutOptions.Clock`). The video conformance kit
|
|
265
|
+
* (`@memberjunction/ai-realtime-client/testing`) checks each rule.
|
|
215
266
|
*/
|
|
216
267
|
export declare abstract class BaseRealtimeClient {
|
|
217
268
|
private transcriptHandler?;
|
|
@@ -232,6 +283,32 @@ export declare abstract class BaseRealtimeClient {
|
|
|
232
283
|
* All tracks evaluated for this session (including `'unsupported'` or `'denied'`).
|
|
233
284
|
*/
|
|
234
285
|
get AllTracks(): readonly RealtimeTrack[];
|
|
286
|
+
/** The model's declared inbound video stream ceiling, recorded by {@link negotiateTracks}; `undefined` until a driver declares one. */
|
|
287
|
+
private inboundVideoStreamLimit;
|
|
288
|
+
/** What the driver supports, recorded by {@link negotiateTracks} so {@link AddTrack} can resolve against it later. */
|
|
289
|
+
private supportedTracks;
|
|
290
|
+
/** The index the next added track's id takes, so an added track never reuses an id. */
|
|
291
|
+
private nextTrackIndex;
|
|
292
|
+
/**
|
|
293
|
+
* How many concurrent inbound video streams the model accepts: the ceiling the driver declared when it
|
|
294
|
+
* negotiated tracks, else `1` when an inbound video track is live and `0` when it is not.
|
|
295
|
+
*
|
|
296
|
+
* A source arbiter reads this to decide whether several live video sources must be narrowed to one
|
|
297
|
+
* (with a note to the model on each switch) or passed through untouched.
|
|
298
|
+
*/
|
|
299
|
+
get MaxInboundVideoStreams(): number;
|
|
300
|
+
/**
|
|
301
|
+
* The frame rate (frames per second) the live inbound video track was negotiated at — the model's
|
|
302
|
+
* ceiling or the session's request, whichever is lower — or `undefined` when no inbound video track
|
|
303
|
+
* is live or none declared a rate. Anything pacing a video feed reads THIS, never a constant of its own.
|
|
304
|
+
*/
|
|
305
|
+
get InboundVideoRate(): number | undefined;
|
|
306
|
+
/**
|
|
307
|
+
* Whether the model takes inbound video on this session: the driver declared an inbound video track it supports when it
|
|
308
|
+
* negotiated tracks, and a stream limit above zero. No video track need be live; one is added when a capture starts
|
|
309
|
+
* ({@link AddTrack}). `false` before tracks are negotiated, and for a driver that does not negotiate them.
|
|
310
|
+
*/
|
|
311
|
+
get SupportsInboundVideo(): boolean;
|
|
235
312
|
/**
|
|
236
313
|
* Returns whether a track of the requested modality and direction is established and `'live'`.
|
|
237
314
|
*/
|
|
@@ -241,7 +318,28 @@ export declare abstract class BaseRealtimeClient {
|
|
|
241
318
|
* Audio (inbound + outbound) is the baseline floor of every realtime session;
|
|
242
319
|
* any additional requested tracks (such as channel video) are unioned onto this baseline floor.
|
|
243
320
|
*/
|
|
244
|
-
protected negotiateTracks(requested: readonly RealtimeTrackDescriptor[] | undefined, supported: readonly RealtimeTrackDescriptor[] | undefined): RealtimeTrack[];
|
|
321
|
+
protected negotiateTracks(requested: readonly RealtimeTrackDescriptor[] | undefined, supported: readonly RealtimeTrackDescriptor[] | undefined, maxInboundVideoStreams?: number): RealtimeTrack[];
|
|
322
|
+
/**
|
|
323
|
+
* Adds a track to a running session, such as inbound video when the user starts their camera, resolved against
|
|
324
|
+
* what the driver supported when it negotiated at connect. The new track is `'live'`, or `'unsupported'` with the
|
|
325
|
+
* reason (the model takes no such track, or no more inbound video streams). A live track with the same
|
|
326
|
+
* direction, modality and source is returned as it is. Other tracks keep their ids.
|
|
327
|
+
*
|
|
328
|
+
* The base re-negotiates locally, which is all a driver needs when its provider accepts the media without a
|
|
329
|
+
* setup change (Gemini Live takes video frames at any time). A driver whose wire must change overrides this and
|
|
330
|
+
* calls it.
|
|
331
|
+
*
|
|
332
|
+
* @returns The track, or `null` when the session has not negotiated tracks: before it connects, or with a driver
|
|
333
|
+
* that does not negotiate them (only the Gemini driver does today).
|
|
334
|
+
*/
|
|
335
|
+
AddTrack(descriptor: RealtimeTrackDescriptor): RealtimeTrack | null;
|
|
336
|
+
/**
|
|
337
|
+
* Ends a track on a running session, such as inbound video when the user stops their camera: the track is
|
|
338
|
+
* reported `'ended'` and leaves {@link AllTracks}. Audio, the session's floor, cannot be removed.
|
|
339
|
+
*
|
|
340
|
+
* @returns Whether a track was ended.
|
|
341
|
+
*/
|
|
342
|
+
RemoveTrack(descriptor: Pick<RealtimeTrackDescriptor, 'Modality' | 'Direction' | 'SourceID'>): boolean;
|
|
245
343
|
/** Meter over the USER's microphone, when the driver attached one. */
|
|
246
344
|
protected inputAudioMeter: IRealtimeAudioMeter | null;
|
|
247
345
|
/** Meter over the AGENT's audio output, when the driver attached one. */
|
|
@@ -266,7 +364,8 @@ export declare abstract class BaseRealtimeClient {
|
|
|
266
364
|
* private pact between this driver and the same-keyed server driver that minted it (see
|
|
267
365
|
* driver obligation #8); how it is applied is entirely driver-specific.
|
|
268
366
|
*
|
|
269
|
-
* @param config The server-minted client session config (provider, model, ephemeral token
|
|
367
|
+
* @param config The server-minted client session config (provider, model, ephemeral token or relay transport,
|
|
368
|
+
* session config). A driver refuses a transport it does not speak first (see {@link AssertTransportSupported}).
|
|
270
369
|
* @param micStream The user's microphone capture stream. The caller acquires it (so IT owns
|
|
271
370
|
* the permission prompt UX); the client attaches it to the transport and stops its tracks
|
|
272
371
|
* on {@link Disconnect}.
|
|
@@ -277,25 +376,56 @@ export declare abstract class BaseRealtimeClient {
|
|
|
277
376
|
*/
|
|
278
377
|
abstract Connect(config: ClientRealtimeSessionConfig, micStream: MediaStream, cameraStream?: MediaStream): Promise<void>;
|
|
279
378
|
/**
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
|
|
284
|
-
|
|
379
|
+
* Whether this driver can open a relay session (`ClientRealtimeSessionConfig.Transport` `'relay'`): connect to
|
|
380
|
+
* MJAPI's realtime relay at the session's `RelayUrl` rather than to its provider. `false` here; a driver that speaks
|
|
381
|
+
* its provider's protocol through the relay opts in by overriding it (the Gemini Enterprise client does).
|
|
382
|
+
*/
|
|
383
|
+
protected get SupportsRelayTransport(): boolean;
|
|
384
|
+
/**
|
|
385
|
+
* Refuses a session this driver cannot open: a relay session, unless the driver opts in through
|
|
386
|
+
* {@link SupportsRelayTransport}. Every driver calls this first in {@link Connect}, before it touches the session's
|
|
387
|
+
* media or opens a connection (driver obligation #11). The message names the provider key and never quotes the
|
|
388
|
+
* relay URL, which carries the relay's ticket.
|
|
285
389
|
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
|
|
390
|
+
* @param config The session the host asked this driver to open.
|
|
391
|
+
* @throws When the session runs through the relay and this driver does not support it.
|
|
392
|
+
*/
|
|
393
|
+
protected AssertTransportSupported(config: ClientRealtimeSessionConfig): void;
|
|
394
|
+
/** The agent's current remote-audio stream, or `null` until a driver publishes one. */
|
|
395
|
+
private remoteMediaStream;
|
|
396
|
+
/** Host handlers notified when the agent's stream lands (or immediately, if already present). */
|
|
397
|
+
private remoteMediaStreamHandlers;
|
|
398
|
+
/**
|
|
399
|
+
* Returns the AGENT's remote-audio {@link MediaStream} when this driver owns a tappable
|
|
400
|
+
* agent-audio plane (a WebRTC driver's remote track, or a PCM driver's playout output),
|
|
401
|
+
* or `null` otherwise. Hosts use it to MIX the agent's voice into a browser-side recording
|
|
402
|
+
* alongside the mic; `null` (drivers with no tappable plane, or before the stream lands)
|
|
403
|
+
* degrades gracefully to mic-only capture. Hosts may still call it as `client.GetRemoteMediaStream?.()`.
|
|
404
|
+
* Pure read — never mutates.
|
|
405
|
+
*/
|
|
406
|
+
GetRemoteMediaStream(): MediaStream | null;
|
|
407
|
+
/**
|
|
408
|
+
* Registers a handler invoked when the agent's remote-audio stream becomes available —
|
|
409
|
+
* IMMEDIATELY (synchronously) if it has already landed, otherwise when the driver publishes
|
|
410
|
+
* it (a WebRTC track typically lands AFTER {@link Connect} resolves). Lets a host attach the
|
|
411
|
+
* agent voice to a recording that began before the stream landed. Handler errors are
|
|
412
|
+
* isolated (logged) so a host bug never disturbs the call. Handlers are session-scoped:
|
|
413
|
+
* {@link clearRemoteMediaStream} (called from `Disconnect`) drops them.
|
|
289
414
|
*/
|
|
290
|
-
|
|
415
|
+
OnRemoteMediaStream(handler: (stream: MediaStream) => void): void;
|
|
291
416
|
/**
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
* recording that began before the track landed. Call as `client.OnRemoteMediaStream?.(cb)`;
|
|
296
|
-
* drivers without a remote stream simply don't implement it.
|
|
417
|
+
* Driver hook: records the agent's remote-audio stream and fans it out to every registered
|
|
418
|
+
* handler. Passing `null` (a driver with no tappable plane) just records `null` and
|
|
419
|
+
* notifies nobody.
|
|
297
420
|
*/
|
|
298
|
-
|
|
421
|
+
protected publishRemoteMediaStream(stream: MediaStream | null): void;
|
|
422
|
+
/**
|
|
423
|
+
* Driver hook for `Disconnect`: drops the stream AND the handlers. Handlers must not survive
|
|
424
|
+
* into a later `Connect` on a reused instance, or a stale host callback would receive the
|
|
425
|
+
* next session's stream.
|
|
426
|
+
*/
|
|
427
|
+
protected clearRemoteMediaStream(): void;
|
|
428
|
+
private invokeRemoteMediaStreamHandler;
|
|
299
429
|
/**
|
|
300
430
|
* Injects typed text into the live session as a USER turn and asks the model to respond.
|
|
301
431
|
* Implementations must route the reply through the same collision-safe path as tool
|
|
@@ -364,6 +494,24 @@ export declare abstract class BaseRealtimeClient {
|
|
|
364
494
|
* @param muted `true` to mute the mic, `false` to unmute.
|
|
365
495
|
*/
|
|
366
496
|
abstract SetMuted(muted: boolean): void;
|
|
497
|
+
/**
|
|
498
|
+
* Moves a connected session onto the microphone stream's current audio track: call it after the
|
|
499
|
+
* track changes (a device switch, or a lost device replaced by the default) or to use another
|
|
500
|
+
* stream. The connection stays up and the provider hears the new track. The driver now owns this
|
|
501
|
+
* stream as it owned the one given to {@link Connect}; the previous stream's tracks are the
|
|
502
|
+
* caller's to stop.
|
|
503
|
+
*
|
|
504
|
+
* Mute follows the track: the new track's `enabled` flag decides it, so a caller replacing a
|
|
505
|
+
* muted track carries `enabled` over (the `LocalMediaController` does).
|
|
506
|
+
*
|
|
507
|
+
* **Optional capability** (driver obligation #10): a driver that can't rebind its transport
|
|
508
|
+
* leaves it undefined. Does nothing when the session isn't connected.
|
|
509
|
+
*
|
|
510
|
+
* @param micStream The stream to follow, usually the one given to {@link Connect} after the
|
|
511
|
+
* controller swapped its track.
|
|
512
|
+
* @throws (rejects) When the stream has no audio track; the session keeps its current microphone.
|
|
513
|
+
*/
|
|
514
|
+
ReplaceMicrophone?(micStream: MediaStream): Promise<void>;
|
|
367
515
|
/**
|
|
368
516
|
* Tears down the provider connection and all client-held resources (control channel,
|
|
369
517
|
* transport, mic tracks, audio sink) and emits a final `'closed'` state (unless the
|
|
@@ -433,17 +581,21 @@ export declare abstract class BaseRealtimeClient {
|
|
|
433
581
|
*/
|
|
434
582
|
OnUsage(handler: (usage: RealtimeClientUsage) => void): void;
|
|
435
583
|
/**
|
|
436
|
-
* Registers the (single) remote-VIDEO handler — the model/avatar's video
|
|
437
|
-
*
|
|
438
|
-
*
|
|
584
|
+
* Registers the (single) remote-VIDEO handler — the model/avatar's video for a VIDEO session (a talking-head
|
|
585
|
+
* the host renders, e.g. as the agent's tile). Invoked once the provider's video is available.
|
|
586
|
+
*
|
|
587
|
+
* The video is a {@link MediaVideoSource}: a live stream (a WebRTC track), or a player that must own the
|
|
588
|
+
* `<video>` element (MSE or WebCodecs playout of encoded avatar video). Hosts show either with
|
|
589
|
+
* `AttachVideoSource`.
|
|
439
590
|
*
|
|
440
591
|
* **Optional capability:** audio-only drivers (the default) never emit — registering is always safe,
|
|
441
|
-
* but hosts must not assume
|
|
442
|
-
*
|
|
592
|
+
* but hosts must not assume video arrives. A driver whose model sends video (the server driver declares an
|
|
593
|
+
* outbound video track in its session's `Capabilities.SupportedOutboundTracks`, or renders an avatar,
|
|
594
|
+
* `BaseRealtimeModel.SupportsAvatarOutput`) calls {@link emitRemoteVideo} when it is live.
|
|
443
595
|
*
|
|
444
|
-
* @param handler Invoked with the remote video
|
|
596
|
+
* @param handler Invoked with the remote video when it becomes available.
|
|
445
597
|
*/
|
|
446
|
-
OnRemoteVideo(handler: (
|
|
598
|
+
OnRemoteVideo(handler: (video: MediaVideoSource) => void): void;
|
|
447
599
|
/**
|
|
448
600
|
* Registers the track-state-change handler — invoked when tracks transition in lifecycle
|
|
449
601
|
* (e.g. established to `'live'`, `'denied'`, or `'unsupported'`).
|
|
@@ -455,9 +607,12 @@ export declare abstract class BaseRealtimeClient {
|
|
|
455
607
|
*
|
|
456
608
|
* @param base64Image Base64-encoded image data.
|
|
457
609
|
* @param mimeType Image MIME type (defaults to 'image/jpeg').
|
|
610
|
+
* @param sourceId Which source this frame came from. A driver whose model takes ONE inbound video
|
|
611
|
+
* stream ignores it (the source arbiter already chose what to send); a driver whose model takes
|
|
612
|
+
* several routes the frame to the track bound to that `SourceID`.
|
|
458
613
|
* @returns `true` if accepted and sent; `false` if dropped (throttled, unestablished, etc.).
|
|
459
614
|
*/
|
|
460
|
-
SendVideoFrame?(base64Image: string, mimeType?: string): boolean;
|
|
615
|
+
SendVideoFrame?(base64Image: string, mimeType?: string, sourceId?: string): boolean;
|
|
461
616
|
/** Emits a track state change to the registered handler (if any). */
|
|
462
617
|
protected emitTrackStateChange(track: RealtimeTrack): void;
|
|
463
618
|
/** Emits a transcript event to the registered handler (if any). */
|
|
@@ -472,7 +627,10 @@ export declare abstract class BaseRealtimeClient {
|
|
|
472
627
|
protected emitInterruption(): void;
|
|
473
628
|
/** Emits a usage update (token deltas for a completed response/turn) to the registered handler (if any). */
|
|
474
629
|
protected emitUsage(usage: RealtimeClientUsage): void;
|
|
475
|
-
/**
|
|
476
|
-
|
|
630
|
+
/**
|
|
631
|
+
* Emits the model/avatar's remote video to the registered handler (video drivers only). A driver with a plain
|
|
632
|
+
* `MediaStream` passes it as it is; it is handed on as a `'stream'` source.
|
|
633
|
+
*/
|
|
634
|
+
protected emitRemoteVideo(video: MediaVideoSource | MediaStream): void;
|
|
477
635
|
}
|
|
478
636
|
//# sourceMappingURL=baseRealtimeClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseRealtimeClient.d.ts","sourceRoot":"","sources":["../../src/generic/baseRealtimeClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAE3B,aAAa,EACb,uBAAuB,EACvB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"baseRealtimeClient.d.ts","sourceRoot":"","sources":["../../src/generic/baseRealtimeClient.ts"],"names":[],"mappings":"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"}
|