@llmrtc/llmrtc-provider-google 1.2.0 → 1.3.0
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/CHANGELOG.md +37 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/realtime-speech.d.ts +54 -0
- package/dist/realtime-speech.js +711 -0
- package/dist/realtime-speech.js.map +1 -0
- package/package.json +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @llmrtc/llmrtc-provider-google
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3f9e7be: Realtime relay milestone 4 (RFC 0001): Gemini Live adapter.
|
|
8
|
+
- New GeminiLiveSpeechProvider: speech-to-speech over the Gemini Live
|
|
9
|
+
API (gemini-3.1-flash-live-preview by default; the Live API is a
|
|
10
|
+
Google preview). 16kHz PCM in / 24kHz out, native user and assistant
|
|
11
|
+
transcripts, provider-driven barge-in, tool calls with cancellation.
|
|
12
|
+
- Gemini's ~10-minute socket lifetime is handled inside the adapter:
|
|
13
|
+
goAway (and socket loss) trigger a session-resumption reconnect with
|
|
14
|
+
bounded input-audio buffering, so user speech spanning the gap is
|
|
15
|
+
replayed rather than clipped. Stage instruction updates use a
|
|
16
|
+
system-text turn without reconnecting; tool-set changes reconnect
|
|
17
|
+
with the resumption handle.
|
|
18
|
+
- Cost controls hold on Gemini too: maxOutputTokens maps into
|
|
19
|
+
generationConfig, and usageMetadata feeds per-response usage events,
|
|
20
|
+
budget enforcement, and spend metrics.
|
|
21
|
+
- Reconnects retry with backoff, treat resumption handles as
|
|
22
|
+
single-use (falling back to a fresh session rather than dying),
|
|
23
|
+
drain trailing messages from the old socket, buffer tool results
|
|
24
|
+
across the gap, and close interrupted turns cleanly so client state
|
|
25
|
+
never dangles.
|
|
26
|
+
- Conformance-tested against the documented BidiGenerateContent wire
|
|
27
|
+
format (mock server incl. handle rotation and close-during-reconnect).
|
|
28
|
+
Live validation is pending an API key environment; wire shapes marked
|
|
29
|
+
LIVE-PROBE in the adapter (system-role instruction turns, tool-result
|
|
30
|
+
delivery across a resumption) must be confirmed before
|
|
31
|
+
playbooks-on-Gemini leave experimental status.
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- Updated dependencies [6a74624]
|
|
36
|
+
- Updated dependencies [2cc97a0]
|
|
37
|
+
- Updated dependencies [3db8818]
|
|
38
|
+
- @llmrtc/llmrtc-core@1.3.0
|
|
39
|
+
|
|
3
40
|
## 1.2.0
|
|
4
41
|
|
|
5
42
|
### Minor Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -28,3 +28,4 @@ export declare class GeminiLLMProvider implements LLMProvider {
|
|
|
28
28
|
complete(request: LLMRequest): Promise<LLMResult>;
|
|
29
29
|
stream(request: LLMRequest): AsyncIterable<LLMChunk>;
|
|
30
30
|
}
|
|
31
|
+
export { GeminiLiveSpeechProvider, type GeminiLiveSpeechOptions } from './realtime-speech.js';
|
package/dist/index.js
CHANGED
|
@@ -205,4 +205,5 @@ function parseDataUri(uri) {
|
|
|
205
205
|
// If not a data URI, assume it's already base64 and default to jpeg
|
|
206
206
|
return { mimeType: 'image/jpeg', data: uri };
|
|
207
207
|
}
|
|
208
|
+
export { GeminiLiveSpeechProvider } from './realtime-speech.js';
|
|
208
209
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini Live speech-to-speech adapter (RFC 0001, experimental).
|
|
3
|
+
*
|
|
4
|
+
* Bridges the Gemini Live API (BidiGenerateContent WebSocket) to the
|
|
5
|
+
* provider-agnostic RealtimeSpeechSession interface: 16kHz PCM up, 24kHz
|
|
6
|
+
* PCM down, native transcripts, provider-driven barge-in (interrupted),
|
|
7
|
+
* tool calls with cancellation, and adapter-internal reconnection with
|
|
8
|
+
* session resumption across Gemini's ~10-minute socket lifetime -
|
|
9
|
+
* including bounded input-audio buffering so user speech spanning a
|
|
10
|
+
* reconnect is not clipped.
|
|
11
|
+
*
|
|
12
|
+
* Gemini Live is a preview API; this adapter is experimental. Wire
|
|
13
|
+
* shapes marked LIVE-PROBE below must be confirmed against the real API
|
|
14
|
+
* before playbooks-on-Gemini are promoted from experimental.
|
|
15
|
+
*/
|
|
16
|
+
import { RealtimeSpeechConfig, RealtimeSpeechProvider, RealtimeSpeechSession } from '@llmrtc/llmrtc-core';
|
|
17
|
+
export interface GeminiLiveSpeechOptions {
|
|
18
|
+
/** Google AI API key */
|
|
19
|
+
apiKey: string;
|
|
20
|
+
/** Live-capable model (default: 'gemini-3.1-flash-live-preview') */
|
|
21
|
+
model?: string;
|
|
22
|
+
/** WebSocket URL override (tests) */
|
|
23
|
+
url?: string;
|
|
24
|
+
/** Connect timeout per attempt in ms (default: 10000) */
|
|
25
|
+
connectTimeoutMs?: number;
|
|
26
|
+
/** Max buffered input audio during a reconnect, in bytes (default: 64000 = 2s at 16kHz) */
|
|
27
|
+
reconnectBufferBytes?: number;
|
|
28
|
+
/** Reconnect attempt backoff in ms (default: [250, 1000, 2000]) */
|
|
29
|
+
reconnectBackoffMs?: number[];
|
|
30
|
+
/** Diagnostics sink (default: console) */
|
|
31
|
+
logger?: Pick<Console, 'warn' | 'error'>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Gemini Live speech-to-speech provider (experimental; the Live API is
|
|
35
|
+
* a Google preview).
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const provider = new GeminiLiveSpeechProvider({
|
|
40
|
+
* apiKey: process.env.GOOGLE_API_KEY!
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare class GeminiLiveSpeechProvider implements RealtimeSpeechProvider {
|
|
45
|
+
private readonly options;
|
|
46
|
+
readonly name = "gemini-live-speech";
|
|
47
|
+
private readonly model;
|
|
48
|
+
private readonly url;
|
|
49
|
+
private readonly connectTimeoutMs;
|
|
50
|
+
private readonly reconnectBufferBytes;
|
|
51
|
+
private readonly reconnectBackoffMs;
|
|
52
|
+
constructor(options: GeminiLiveSpeechOptions);
|
|
53
|
+
connect(config: RealtimeSpeechConfig): Promise<RealtimeSpeechSession>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,711 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini Live speech-to-speech adapter (RFC 0001, experimental).
|
|
3
|
+
*
|
|
4
|
+
* Bridges the Gemini Live API (BidiGenerateContent WebSocket) to the
|
|
5
|
+
* provider-agnostic RealtimeSpeechSession interface: 16kHz PCM up, 24kHz
|
|
6
|
+
* PCM down, native transcripts, provider-driven barge-in (interrupted),
|
|
7
|
+
* tool calls with cancellation, and adapter-internal reconnection with
|
|
8
|
+
* session resumption across Gemini's ~10-minute socket lifetime -
|
|
9
|
+
* including bounded input-audio buffering so user speech spanning a
|
|
10
|
+
* reconnect is not clipped.
|
|
11
|
+
*
|
|
12
|
+
* Gemini Live is a preview API; this adapter is experimental. Wire
|
|
13
|
+
* shapes marked LIVE-PROBE below must be confirmed against the real API
|
|
14
|
+
* before playbooks-on-Gemini are promoted from experimental.
|
|
15
|
+
*/
|
|
16
|
+
import WebSocket from 'ws';
|
|
17
|
+
import { AsyncEventQueue } from '@llmrtc/llmrtc-core';
|
|
18
|
+
const DEFAULT_URL = 'wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent';
|
|
19
|
+
function mapTools(tools) {
|
|
20
|
+
if (!tools?.length)
|
|
21
|
+
return undefined;
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
functionDeclarations: tools.map((t) => ({
|
|
25
|
+
name: t.name,
|
|
26
|
+
description: t.description,
|
|
27
|
+
parameters: t.parameters
|
|
28
|
+
}))
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
function buildSetup(model, config, handle) {
|
|
33
|
+
const tools = mapTools(config.tools);
|
|
34
|
+
const setup = {
|
|
35
|
+
model: model.startsWith('models/') ? model : `models/${model}`,
|
|
36
|
+
generationConfig: {
|
|
37
|
+
responseModalities: ['AUDIO'],
|
|
38
|
+
...(config.maxOutputTokens !== undefined && { maxOutputTokens: config.maxOutputTokens }),
|
|
39
|
+
...(config.voice && {
|
|
40
|
+
speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: config.voice } } }
|
|
41
|
+
})
|
|
42
|
+
},
|
|
43
|
+
...(config.instructions && {
|
|
44
|
+
systemInstruction: { parts: [{ text: config.instructions }] }
|
|
45
|
+
}),
|
|
46
|
+
...(tools && { tools }),
|
|
47
|
+
...(config.inputTranscription !== false && { inputAudioTranscription: {} }),
|
|
48
|
+
outputAudioTranscription: {},
|
|
49
|
+
// Compression lifts the 15-minute audio-session cap (RFC 0001 §2);
|
|
50
|
+
// always on in relay mode
|
|
51
|
+
contextWindowCompression: {
|
|
52
|
+
slidingWindow: {},
|
|
53
|
+
...(config.contextManagement?.triggerTokens && {
|
|
54
|
+
triggerTokens: config.contextManagement.triggerTokens
|
|
55
|
+
})
|
|
56
|
+
},
|
|
57
|
+
sessionResumption: handle ? { handle } : {}
|
|
58
|
+
};
|
|
59
|
+
if (config.turnDetection?.type === 'server_vad') {
|
|
60
|
+
setup.realtimeInputConfig = {
|
|
61
|
+
automaticActivityDetection: {
|
|
62
|
+
...(config.turnDetection.silenceDurationMs !== undefined && {
|
|
63
|
+
silenceDurationMs: config.turnDetection.silenceDurationMs
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return setup;
|
|
69
|
+
}
|
|
70
|
+
class GeminiLiveSpeechSession {
|
|
71
|
+
constructor(ws, options) {
|
|
72
|
+
Object.defineProperty(this, "options", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
configurable: true,
|
|
75
|
+
writable: true,
|
|
76
|
+
value: options
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(this, "inputSampleRate", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
configurable: true,
|
|
81
|
+
writable: true,
|
|
82
|
+
value: 16000
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(this, "outputSampleRate", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
configurable: true,
|
|
87
|
+
writable: true,
|
|
88
|
+
value: 24000
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(this, "queue", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
configurable: true,
|
|
93
|
+
writable: true,
|
|
94
|
+
value: new AsyncEventQueue()
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(this, "ws", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
configurable: true,
|
|
99
|
+
writable: true,
|
|
100
|
+
value: void 0
|
|
101
|
+
});
|
|
102
|
+
Object.defineProperty(this, "ready", {
|
|
103
|
+
enumerable: true,
|
|
104
|
+
configurable: true,
|
|
105
|
+
writable: true,
|
|
106
|
+
value: false
|
|
107
|
+
});
|
|
108
|
+
Object.defineProperty(this, "everReady", {
|
|
109
|
+
enumerable: true,
|
|
110
|
+
configurable: true,
|
|
111
|
+
writable: true,
|
|
112
|
+
value: false
|
|
113
|
+
});
|
|
114
|
+
Object.defineProperty(this, "closed", {
|
|
115
|
+
enumerable: true,
|
|
116
|
+
configurable: true,
|
|
117
|
+
writable: true,
|
|
118
|
+
value: false
|
|
119
|
+
});
|
|
120
|
+
Object.defineProperty(this, "reconnecting", {
|
|
121
|
+
enumerable: true,
|
|
122
|
+
configurable: true,
|
|
123
|
+
writable: true,
|
|
124
|
+
value: false
|
|
125
|
+
});
|
|
126
|
+
Object.defineProperty(this, "reconnectPromise", {
|
|
127
|
+
enumerable: true,
|
|
128
|
+
configurable: true,
|
|
129
|
+
writable: true,
|
|
130
|
+
value: Promise.resolve()
|
|
131
|
+
});
|
|
132
|
+
Object.defineProperty(this, "setupWaiter", {
|
|
133
|
+
enumerable: true,
|
|
134
|
+
configurable: true,
|
|
135
|
+
writable: true,
|
|
136
|
+
value: null
|
|
137
|
+
});
|
|
138
|
+
Object.defineProperty(this, "resumptionHandle", {
|
|
139
|
+
enumerable: true,
|
|
140
|
+
configurable: true,
|
|
141
|
+
writable: true,
|
|
142
|
+
value: null
|
|
143
|
+
});
|
|
144
|
+
Object.defineProperty(this, "handleConsumed", {
|
|
145
|
+
enumerable: true,
|
|
146
|
+
configurable: true,
|
|
147
|
+
writable: true,
|
|
148
|
+
value: false
|
|
149
|
+
});
|
|
150
|
+
Object.defineProperty(this, "lastCloseInfo", {
|
|
151
|
+
enumerable: true,
|
|
152
|
+
configurable: true,
|
|
153
|
+
writable: true,
|
|
154
|
+
value: ''
|
|
155
|
+
});
|
|
156
|
+
Object.defineProperty(this, "turnCounter", {
|
|
157
|
+
enumerable: true,
|
|
158
|
+
configurable: true,
|
|
159
|
+
writable: true,
|
|
160
|
+
value: 0
|
|
161
|
+
});
|
|
162
|
+
Object.defineProperty(this, "currentResponseId", {
|
|
163
|
+
enumerable: true,
|
|
164
|
+
configurable: true,
|
|
165
|
+
writable: true,
|
|
166
|
+
value: null
|
|
167
|
+
});
|
|
168
|
+
Object.defineProperty(this, "userRunningText", {
|
|
169
|
+
enumerable: true,
|
|
170
|
+
configurable: true,
|
|
171
|
+
writable: true,
|
|
172
|
+
value: ''
|
|
173
|
+
});
|
|
174
|
+
Object.defineProperty(this, "assistantRunningText", {
|
|
175
|
+
enumerable: true,
|
|
176
|
+
configurable: true,
|
|
177
|
+
writable: true,
|
|
178
|
+
value: ''
|
|
179
|
+
});
|
|
180
|
+
Object.defineProperty(this, "lastUsage", {
|
|
181
|
+
enumerable: true,
|
|
182
|
+
configurable: true,
|
|
183
|
+
writable: true,
|
|
184
|
+
value: void 0
|
|
185
|
+
});
|
|
186
|
+
Object.defineProperty(this, "toolNames", {
|
|
187
|
+
enumerable: true,
|
|
188
|
+
configurable: true,
|
|
189
|
+
writable: true,
|
|
190
|
+
value: new Map()
|
|
191
|
+
});
|
|
192
|
+
// Input frames + tool results buffered while a reconnect is in flight
|
|
193
|
+
Object.defineProperty(this, "reconnectBuffer", {
|
|
194
|
+
enumerable: true,
|
|
195
|
+
configurable: true,
|
|
196
|
+
writable: true,
|
|
197
|
+
value: []
|
|
198
|
+
});
|
|
199
|
+
Object.defineProperty(this, "reconnectBufferedBytes", {
|
|
200
|
+
enumerable: true,
|
|
201
|
+
configurable: true,
|
|
202
|
+
writable: true,
|
|
203
|
+
value: 0
|
|
204
|
+
});
|
|
205
|
+
Object.defineProperty(this, "pendingToolResults", {
|
|
206
|
+
enumerable: true,
|
|
207
|
+
configurable: true,
|
|
208
|
+
writable: true,
|
|
209
|
+
value: []
|
|
210
|
+
});
|
|
211
|
+
Object.defineProperty(this, "logger", {
|
|
212
|
+
enumerable: true,
|
|
213
|
+
configurable: true,
|
|
214
|
+
writable: true,
|
|
215
|
+
value: void 0
|
|
216
|
+
});
|
|
217
|
+
this.ws = ws;
|
|
218
|
+
this.logger = options.logger ?? console;
|
|
219
|
+
this.attach(ws);
|
|
220
|
+
}
|
|
221
|
+
attach(ws) {
|
|
222
|
+
ws.on('message', (data) => this.handleMessage(data));
|
|
223
|
+
ws.on('error', (err) => {
|
|
224
|
+
this.lastCloseInfo = err.message;
|
|
225
|
+
if (!this.closed && !this.reconnecting) {
|
|
226
|
+
this.startReconnect(`socket error: ${err.message}`);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
ws.on('close', (code, reason) => {
|
|
230
|
+
this.lastCloseInfo = `close ${code}${reason?.length ? `: ${reason.toString()}` : ''}`;
|
|
231
|
+
if (this.closed || this.reconnecting)
|
|
232
|
+
return;
|
|
233
|
+
if (!this.everReady) {
|
|
234
|
+
// Setup was rejected (bad model/auth/config): fail fast with the
|
|
235
|
+
// server's close reason instead of retrying a deterministic error
|
|
236
|
+
this.failSetup(new Error(`Gemini Live setup rejected (${this.lastCloseInfo})`));
|
|
237
|
+
this.queue.fail(new Error(`Gemini Live setup rejected (${this.lastCloseInfo})`));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
this.startReconnect(this.lastCloseInfo);
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
/** Resolves once the server acknowledged setup (setupComplete). */
|
|
244
|
+
waitUntilReady() {
|
|
245
|
+
if (this.ready)
|
|
246
|
+
return Promise.resolve();
|
|
247
|
+
return new Promise((resolve, reject) => {
|
|
248
|
+
const timer = setTimeout(() => {
|
|
249
|
+
this.setupWaiter = null;
|
|
250
|
+
reject(new Error(`setupComplete timed out (last close: ${this.lastCloseInfo || 'n/a'})`));
|
|
251
|
+
}, this.options.connectTimeoutMs);
|
|
252
|
+
timer.unref?.();
|
|
253
|
+
this.setupWaiter = {
|
|
254
|
+
resolve: () => {
|
|
255
|
+
clearTimeout(timer);
|
|
256
|
+
resolve();
|
|
257
|
+
},
|
|
258
|
+
reject: (e) => {
|
|
259
|
+
clearTimeout(timer);
|
|
260
|
+
reject(e);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
failSetup(err) {
|
|
266
|
+
const waiter = this.setupWaiter;
|
|
267
|
+
this.setupWaiter = null;
|
|
268
|
+
waiter?.reject(err);
|
|
269
|
+
}
|
|
270
|
+
handleMessage(data) {
|
|
271
|
+
let msg;
|
|
272
|
+
try {
|
|
273
|
+
msg = JSON.parse(data.toString());
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (msg.setupComplete) {
|
|
279
|
+
this.ready = true;
|
|
280
|
+
this.everReady = true;
|
|
281
|
+
const waiter = this.setupWaiter;
|
|
282
|
+
this.setupWaiter = null;
|
|
283
|
+
waiter?.resolve();
|
|
284
|
+
this.flushBuffers();
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (msg.sessionResumptionUpdate?.resumable && msg.sessionResumptionUpdate.newHandle) {
|
|
288
|
+
this.resumptionHandle = msg.sessionResumptionUpdate.newHandle;
|
|
289
|
+
this.handleConsumed = false;
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
if (msg.goAway) {
|
|
293
|
+
// Adapter-internal recovery (RFC 0001 §8); informational upstream
|
|
294
|
+
this.queue.push({ type: 'session-expiring', inMs: parseDuration(msg.goAway.timeLeft) });
|
|
295
|
+
this.startReconnect('goAway');
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
if (msg.usageMetadata) {
|
|
299
|
+
this.lastUsage = mapUsage(msg.usageMetadata);
|
|
300
|
+
}
|
|
301
|
+
if (msg.toolCall?.functionCalls) {
|
|
302
|
+
for (const call of msg.toolCall.functionCalls) {
|
|
303
|
+
if (call.id && call.name)
|
|
304
|
+
this.toolNames.set(call.id, call.name);
|
|
305
|
+
this.queue.push({
|
|
306
|
+
type: 'tool-call',
|
|
307
|
+
callId: call.id ?? '',
|
|
308
|
+
name: call.name ?? '',
|
|
309
|
+
arguments: call.args ?? {}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (msg.toolCallCancellation?.ids) {
|
|
315
|
+
this.queue.push({ type: 'tool-call-cancelled', callIds: msg.toolCallCancellation.ids });
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const sc = msg.serverContent;
|
|
319
|
+
if (!sc)
|
|
320
|
+
return;
|
|
321
|
+
if (sc.interrupted) {
|
|
322
|
+
// Preserve what the user actually heard in the mirrored history,
|
|
323
|
+
// then close the turn so clients never dangle in "speaking"
|
|
324
|
+
this.finishTurn(true);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
if (sc.inputTranscription?.text) {
|
|
328
|
+
this.userRunningText += sc.inputTranscription.text;
|
|
329
|
+
this.queue.push({ type: 'user-transcript', text: this.userRunningText, isFinal: false });
|
|
330
|
+
}
|
|
331
|
+
if (sc.outputTranscription?.text) {
|
|
332
|
+
this.assistantRunningText += sc.outputTranscription.text;
|
|
333
|
+
this.queue.push({ type: 'assistant-transcript', text: this.assistantRunningText, isFinal: false });
|
|
334
|
+
}
|
|
335
|
+
const parts = sc.modelTurn?.parts ?? [];
|
|
336
|
+
for (const part of parts) {
|
|
337
|
+
if (!part.inlineData?.data)
|
|
338
|
+
continue;
|
|
339
|
+
if (!this.currentResponseId) {
|
|
340
|
+
this.currentResponseId = `turn-${++this.turnCounter}`;
|
|
341
|
+
this.queue.push({ type: 'response-started', responseId: this.currentResponseId });
|
|
342
|
+
// A model turn implies the user's utterance ended
|
|
343
|
+
if (this.userRunningText) {
|
|
344
|
+
this.queue.push({ type: 'user-transcript', text: this.userRunningText, isFinal: true });
|
|
345
|
+
this.userRunningText = '';
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
this.queue.push({
|
|
349
|
+
type: 'audio',
|
|
350
|
+
pcm: Buffer.from(part.inlineData.data, 'base64'),
|
|
351
|
+
sampleRate: this.outputSampleRate,
|
|
352
|
+
responseId: this.currentResponseId
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
if (sc.turnComplete) {
|
|
356
|
+
this.finishTurn(false);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Close the current model turn: final assistant transcript, an
|
|
361
|
+
* 'interrupted' signal when applicable, and response-done - so
|
|
362
|
+
* orchestrator/client turn state never dangles, and interrupted
|
|
363
|
+
* speech still reaches the mirrored history.
|
|
364
|
+
*/
|
|
365
|
+
finishTurn(interrupted) {
|
|
366
|
+
if (this.assistantRunningText) {
|
|
367
|
+
this.queue.push({ type: 'assistant-transcript', text: this.assistantRunningText, isFinal: true });
|
|
368
|
+
this.assistantRunningText = '';
|
|
369
|
+
}
|
|
370
|
+
if (interrupted) {
|
|
371
|
+
this.queue.push({ type: 'interrupted' });
|
|
372
|
+
}
|
|
373
|
+
if (this.currentResponseId) {
|
|
374
|
+
this.queue.push({
|
|
375
|
+
type: 'response-done',
|
|
376
|
+
responseId: this.currentResponseId,
|
|
377
|
+
usage: this.lastUsage
|
|
378
|
+
});
|
|
379
|
+
this.currentResponseId = null;
|
|
380
|
+
this.lastUsage = undefined;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
startReconnect(reason) {
|
|
384
|
+
if (this.closed || this.reconnecting)
|
|
385
|
+
return;
|
|
386
|
+
this.reconnectPromise = this.reconnect(reason);
|
|
387
|
+
}
|
|
388
|
+
/** Reconnect with session resumption; buffers input audio meanwhile. */
|
|
389
|
+
async reconnect(reason) {
|
|
390
|
+
if (this.closed || this.reconnecting)
|
|
391
|
+
return;
|
|
392
|
+
this.reconnecting = true;
|
|
393
|
+
this.ready = false;
|
|
394
|
+
// A mid-drop model turn never gets turnComplete: close it now so
|
|
395
|
+
// downstream turn state doesn't dangle across the resume
|
|
396
|
+
this.finishTurn(false);
|
|
397
|
+
const oldWs = this.ws;
|
|
398
|
+
// Keep draining trailing messages (a final resumption handle, tail
|
|
399
|
+
// audio) while the replacement connects; drop lifecycle handlers so
|
|
400
|
+
// the old close can't trigger a second reconnect
|
|
401
|
+
oldWs.removeAllListeners('error');
|
|
402
|
+
oldWs.removeAllListeners('close');
|
|
403
|
+
oldWs.on('error', () => { });
|
|
404
|
+
const drainTimer = setTimeout(() => {
|
|
405
|
+
try {
|
|
406
|
+
oldWs.terminate();
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
// already dead
|
|
410
|
+
}
|
|
411
|
+
}, 1500);
|
|
412
|
+
drainTimer.unref?.();
|
|
413
|
+
const backoffs = this.options.reconnectBackoffMs;
|
|
414
|
+
let lastError = new Error('no attempts made');
|
|
415
|
+
for (let attempt = 0; attempt <= backoffs.length; attempt++) {
|
|
416
|
+
if (this.closed)
|
|
417
|
+
return;
|
|
418
|
+
try {
|
|
419
|
+
// A resumption handle is single-use: after a consumed-handle
|
|
420
|
+
// failure, fall back to a fresh session (transcript continuity)
|
|
421
|
+
const handle = this.handleConsumed ? undefined : (this.resumptionHandle ?? undefined);
|
|
422
|
+
const ws = await openGeminiSocket(this.options.url, this.options.apiKey, this.options.connectTimeoutMs);
|
|
423
|
+
if (this.closed) {
|
|
424
|
+
ws.terminate();
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
this.ws = ws;
|
|
428
|
+
this.attach(ws);
|
|
429
|
+
if (handle)
|
|
430
|
+
this.handleConsumed = true;
|
|
431
|
+
ws.send(JSON.stringify({ setup: buildSetup(this.options.model, this.options.config, handle) }));
|
|
432
|
+
await this.waitUntilReady();
|
|
433
|
+
this.reconnecting = false;
|
|
434
|
+
this.flushBuffers();
|
|
435
|
+
this.logger.warn(`[gemini-live] reconnected (${reason})${handle ? ' with resumption' : ' without resumption'}`);
|
|
436
|
+
if (!handle) {
|
|
437
|
+
this.queue.push({
|
|
438
|
+
type: 'error',
|
|
439
|
+
error: new Error(`Gemini Live reconnected without a resumption handle (${reason})`),
|
|
440
|
+
recoverable: true
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
catch (error) {
|
|
446
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
447
|
+
try {
|
|
448
|
+
this.ws.terminate();
|
|
449
|
+
}
|
|
450
|
+
catch {
|
|
451
|
+
// no socket to clean
|
|
452
|
+
}
|
|
453
|
+
if (attempt < backoffs.length && !this.closed) {
|
|
454
|
+
await new Promise((r) => {
|
|
455
|
+
const t = setTimeout(r, backoffs[attempt]);
|
|
456
|
+
t.unref?.();
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
this.reconnecting = false;
|
|
462
|
+
if (!this.closed) {
|
|
463
|
+
this.queue.fail(new Error(`Gemini Live reconnect failed (${reason}): ${lastError.message}`));
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
events() {
|
|
467
|
+
return this.queue;
|
|
468
|
+
}
|
|
469
|
+
sendAudio(frame) {
|
|
470
|
+
if (this.closed || frame.length === 0)
|
|
471
|
+
return;
|
|
472
|
+
if (this.reconnecting || !this.ready || this.ws.readyState !== WebSocket.OPEN) {
|
|
473
|
+
// Bounded buffer (default ~2s); oldest audio is dropped first
|
|
474
|
+
this.reconnectBuffer.push(frame);
|
|
475
|
+
this.reconnectBufferedBytes += frame.length;
|
|
476
|
+
let dropped = 0;
|
|
477
|
+
while (this.reconnectBufferedBytes > this.options.reconnectBufferBytes && this.reconnectBuffer.length > 1) {
|
|
478
|
+
const evicted = this.reconnectBuffer.shift();
|
|
479
|
+
this.reconnectBufferedBytes -= evicted.length;
|
|
480
|
+
dropped += evicted.length;
|
|
481
|
+
}
|
|
482
|
+
if (dropped > 0) {
|
|
483
|
+
this.logger.warn(`[gemini-live] reconnect buffer overflow: dropped ${dropped} bytes of input audio`);
|
|
484
|
+
}
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
this.sendFrame(frame);
|
|
488
|
+
}
|
|
489
|
+
flushBuffers() {
|
|
490
|
+
if (this.ws.readyState !== WebSocket.OPEN)
|
|
491
|
+
return;
|
|
492
|
+
for (const frame of this.reconnectBuffer) {
|
|
493
|
+
this.sendFrame(frame);
|
|
494
|
+
}
|
|
495
|
+
this.reconnectBuffer = [];
|
|
496
|
+
this.reconnectBufferedBytes = 0;
|
|
497
|
+
for (const payload of this.pendingToolResults) {
|
|
498
|
+
this.ws.send(payload);
|
|
499
|
+
}
|
|
500
|
+
this.pendingToolResults = [];
|
|
501
|
+
}
|
|
502
|
+
sendFrame(frame) {
|
|
503
|
+
this.ws.send(JSON.stringify({
|
|
504
|
+
realtimeInput: {
|
|
505
|
+
audio: { data: frame.toString('base64'), mimeType: `audio/pcm;rate=${this.inputSampleRate}` }
|
|
506
|
+
}
|
|
507
|
+
}));
|
|
508
|
+
}
|
|
509
|
+
cancelResponse() {
|
|
510
|
+
// Gemini barge-in is provider-driven (serverContent.interrupted);
|
|
511
|
+
// there is no client cancel primitive. Safe no-op per the interface.
|
|
512
|
+
}
|
|
513
|
+
sendToolResult(callId, output) {
|
|
514
|
+
if (this.closed)
|
|
515
|
+
return;
|
|
516
|
+
const payload = JSON.stringify({
|
|
517
|
+
toolResponse: {
|
|
518
|
+
functionResponses: [
|
|
519
|
+
{
|
|
520
|
+
id: callId,
|
|
521
|
+
// LIVE-PROBE: FunctionResponse documents a name field
|
|
522
|
+
...(this.toolNames.has(callId) && { name: this.toolNames.get(callId) }),
|
|
523
|
+
response: typeof output === 'object' && output !== null
|
|
524
|
+
? output
|
|
525
|
+
: { result: output }
|
|
526
|
+
}
|
|
527
|
+
]
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
if (this.reconnecting || !this.ready || this.ws.readyState !== WebSocket.OPEN) {
|
|
531
|
+
// The model waits on function responses - deliver after resume
|
|
532
|
+
this.pendingToolResults.push(payload);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
this.ws.send(payload);
|
|
536
|
+
}
|
|
537
|
+
async update(config) {
|
|
538
|
+
if (this.closed)
|
|
539
|
+
throw new Error('Gemini Live session is closed');
|
|
540
|
+
const toolsChanged = config.tools !== undefined &&
|
|
541
|
+
JSON.stringify(config.tools) !== JSON.stringify(this.options.config.tools);
|
|
542
|
+
// Merge into the config used for future reconnects
|
|
543
|
+
Object.assign(this.options.config, config);
|
|
544
|
+
if (this.reconnecting) {
|
|
545
|
+
// The in-flight reconnect's setup reads the merged config - the
|
|
546
|
+
// change applies with it, no extra work needed
|
|
547
|
+
await this.reconnectPromise;
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
if (toolsChanged) {
|
|
551
|
+
// Setup is connect-time only: tool-set changes require a
|
|
552
|
+
// resumption reconnect (RFC 0001 §2). Wait briefly for turn
|
|
553
|
+
// quiescence so an active answer isn't chopped mid-word.
|
|
554
|
+
const deadline = Date.now() + 10000;
|
|
555
|
+
while (this.currentResponseId && Date.now() < deadline && !this.closed) {
|
|
556
|
+
await new Promise((r) => {
|
|
557
|
+
const t = setTimeout(r, 100);
|
|
558
|
+
t.unref?.();
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
this.startReconnect('tool-set update');
|
|
562
|
+
await this.reconnectPromise;
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
if (config.instructions && this.ws.readyState === WebSocket.OPEN) {
|
|
566
|
+
// LIVE-PROBE: documented cheaper path for instruction-only changes
|
|
567
|
+
// is a system-role text turn; fall back to a prefixed user turn if
|
|
568
|
+
// the live API rejects the role
|
|
569
|
+
this.ws.send(JSON.stringify({
|
|
570
|
+
clientContent: {
|
|
571
|
+
turns: [{ role: 'system', parts: [{ text: config.instructions }] }],
|
|
572
|
+
turnComplete: false
|
|
573
|
+
}
|
|
574
|
+
}));
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
async close() {
|
|
578
|
+
this.closed = true;
|
|
579
|
+
this.failSetup(new Error('session closed'));
|
|
580
|
+
this.queue.end();
|
|
581
|
+
// An in-flight reconnect checks `closed` after connecting and
|
|
582
|
+
// terminates its own socket; await it so nothing outlives us
|
|
583
|
+
await this.reconnectPromise.catch(() => { });
|
|
584
|
+
if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {
|
|
585
|
+
this.ws.terminate();
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
function mapUsage(u) {
|
|
590
|
+
const audioOf = (details) => details?.find((d) => d.modality === 'AUDIO')?.tokenCount;
|
|
591
|
+
return {
|
|
592
|
+
inputTokens: u.promptTokenCount ?? 0,
|
|
593
|
+
outputTokens: u.responseTokenCount ?? 0,
|
|
594
|
+
audioInputTokens: audioOf(u.promptTokensDetails),
|
|
595
|
+
audioOutputTokens: audioOf(u.responseTokensDetails)
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
function parseDuration(d) {
|
|
599
|
+
if (!d)
|
|
600
|
+
return undefined;
|
|
601
|
+
const seconds = parseFloat(d);
|
|
602
|
+
return Number.isFinite(seconds) ? Math.round(seconds * 1000) : undefined;
|
|
603
|
+
}
|
|
604
|
+
function openGeminiSocket(url, apiKey, timeoutMs) {
|
|
605
|
+
const wsUrl = new URL(url);
|
|
606
|
+
if (!wsUrl.searchParams.has('key')) {
|
|
607
|
+
wsUrl.searchParams.set('key', apiKey);
|
|
608
|
+
}
|
|
609
|
+
const ws = new WebSocket(wsUrl.toString());
|
|
610
|
+
return new Promise((resolve, reject) => {
|
|
611
|
+
const timer = setTimeout(() => {
|
|
612
|
+
ws.terminate();
|
|
613
|
+
reject(new Error(`Gemini Live connect timed out after ${timeoutMs}ms`));
|
|
614
|
+
}, timeoutMs);
|
|
615
|
+
timer.unref?.();
|
|
616
|
+
ws.once('open', () => {
|
|
617
|
+
clearTimeout(timer);
|
|
618
|
+
resolve(ws);
|
|
619
|
+
});
|
|
620
|
+
ws.once('error', (err) => {
|
|
621
|
+
clearTimeout(timer);
|
|
622
|
+
reject(new Error(`Gemini Live connect failed: ${err.message}`));
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Gemini Live speech-to-speech provider (experimental; the Live API is
|
|
628
|
+
* a Google preview).
|
|
629
|
+
*
|
|
630
|
+
* @example
|
|
631
|
+
* ```typescript
|
|
632
|
+
* const provider = new GeminiLiveSpeechProvider({
|
|
633
|
+
* apiKey: process.env.GOOGLE_API_KEY!
|
|
634
|
+
* });
|
|
635
|
+
* ```
|
|
636
|
+
*/
|
|
637
|
+
export class GeminiLiveSpeechProvider {
|
|
638
|
+
constructor(options) {
|
|
639
|
+
Object.defineProperty(this, "options", {
|
|
640
|
+
enumerable: true,
|
|
641
|
+
configurable: true,
|
|
642
|
+
writable: true,
|
|
643
|
+
value: options
|
|
644
|
+
});
|
|
645
|
+
Object.defineProperty(this, "name", {
|
|
646
|
+
enumerable: true,
|
|
647
|
+
configurable: true,
|
|
648
|
+
writable: true,
|
|
649
|
+
value: 'gemini-live-speech'
|
|
650
|
+
});
|
|
651
|
+
Object.defineProperty(this, "model", {
|
|
652
|
+
enumerable: true,
|
|
653
|
+
configurable: true,
|
|
654
|
+
writable: true,
|
|
655
|
+
value: void 0
|
|
656
|
+
});
|
|
657
|
+
Object.defineProperty(this, "url", {
|
|
658
|
+
enumerable: true,
|
|
659
|
+
configurable: true,
|
|
660
|
+
writable: true,
|
|
661
|
+
value: void 0
|
|
662
|
+
});
|
|
663
|
+
Object.defineProperty(this, "connectTimeoutMs", {
|
|
664
|
+
enumerable: true,
|
|
665
|
+
configurable: true,
|
|
666
|
+
writable: true,
|
|
667
|
+
value: void 0
|
|
668
|
+
});
|
|
669
|
+
Object.defineProperty(this, "reconnectBufferBytes", {
|
|
670
|
+
enumerable: true,
|
|
671
|
+
configurable: true,
|
|
672
|
+
writable: true,
|
|
673
|
+
value: void 0
|
|
674
|
+
});
|
|
675
|
+
Object.defineProperty(this, "reconnectBackoffMs", {
|
|
676
|
+
enumerable: true,
|
|
677
|
+
configurable: true,
|
|
678
|
+
writable: true,
|
|
679
|
+
value: void 0
|
|
680
|
+
});
|
|
681
|
+
this.model = options.model ?? 'gemini-3.1-flash-live-preview';
|
|
682
|
+
this.url = options.url ?? DEFAULT_URL;
|
|
683
|
+
this.connectTimeoutMs = options.connectTimeoutMs ?? 10000;
|
|
684
|
+
this.reconnectBufferBytes = options.reconnectBufferBytes ?? 64000;
|
|
685
|
+
this.reconnectBackoffMs = options.reconnectBackoffMs ?? [250, 1000, 2000];
|
|
686
|
+
}
|
|
687
|
+
async connect(config) {
|
|
688
|
+
const ws = await openGeminiSocket(this.url, this.options.apiKey, this.connectTimeoutMs);
|
|
689
|
+
const session = new GeminiLiveSpeechSession(ws, {
|
|
690
|
+
url: this.url,
|
|
691
|
+
apiKey: this.options.apiKey,
|
|
692
|
+
model: this.model,
|
|
693
|
+
// Mutable copy: update() merges stage changes for future reconnects
|
|
694
|
+
config: { ...config },
|
|
695
|
+
connectTimeoutMs: this.connectTimeoutMs,
|
|
696
|
+
reconnectBufferBytes: this.reconnectBufferBytes,
|
|
697
|
+
reconnectBackoffMs: this.reconnectBackoffMs,
|
|
698
|
+
logger: this.options.logger
|
|
699
|
+
});
|
|
700
|
+
ws.send(JSON.stringify({ setup: buildSetup(this.model, config) }));
|
|
701
|
+
try {
|
|
702
|
+
await session.waitUntilReady();
|
|
703
|
+
}
|
|
704
|
+
catch (error) {
|
|
705
|
+
await session.close().catch(() => { });
|
|
706
|
+
throw error;
|
|
707
|
+
}
|
|
708
|
+
return session;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
//# sourceMappingURL=realtime-speech.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime-speech.js","sourceRoot":"","sources":["../src/realtime-speech.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llmrtc/llmrtc-provider-google",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Google Gemini LLM adapter for @llmrtc/LLMRTC",
|
|
5
5
|
"homepage": "https://www.llmrtc.org",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,8 +32,9 @@
|
|
|
32
32
|
"prepublishOnly": "npm run build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@llmrtc/llmrtc-core": "^1.
|
|
36
|
-
"@google/genai": "^1.30.0"
|
|
35
|
+
"@llmrtc/llmrtc-core": "^1.3.0",
|
|
36
|
+
"@google/genai": "^1.30.0",
|
|
37
|
+
"ws": "^8.16.0"
|
|
37
38
|
},
|
|
38
39
|
"exports": {
|
|
39
40
|
".": {
|
|
@@ -46,5 +47,8 @@
|
|
|
46
47
|
"sideEffects": false,
|
|
47
48
|
"engines": {
|
|
48
49
|
"node": ">=20"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/ws": "^8.5.10"
|
|
49
53
|
}
|
|
50
54
|
}
|