realtime-voice-agents 2.0.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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +298 -0
  3. package/assets/elevator-jazz.ulaw +1 -0
  4. package/assets/keyboard-typing.ulaw +1 -0
  5. package/assets/lofi.ulaw +1 -0
  6. package/assets/ringing.ulaw +1 -0
  7. package/assets/thinking-hum.ulaw +1 -0
  8. package/dist/BackgroundAudioPlayer-iMcivjis.mjs +282 -0
  9. package/dist/BackgroundAudioPlayer-jfRULWKC.cjs +313 -0
  10. package/dist/BaseRealtimeProvider-BQigr5mB.mjs +62 -0
  11. package/dist/BaseRealtimeProvider-BehPNT1r.d.cts +239 -0
  12. package/dist/BaseRealtimeProvider-ClP8Wx1X.d.mts +239 -0
  13. package/dist/BaseRealtimeProvider-DI4pKtOb.cjs +91 -0
  14. package/dist/GeminiLiveProvider-DvkTgzjG.d.cts +101 -0
  15. package/dist/GeminiLiveProvider-x2nyx5aO.d.mts +101 -0
  16. package/dist/InMemorySessionStore-B0_i-DOU.cjs +34 -0
  17. package/dist/InMemorySessionStore-B5_rq61L.d.cts +83 -0
  18. package/dist/InMemorySessionStore-B5_rq61L.d.mts +83 -0
  19. package/dist/InMemorySessionStore-DYParOJO.mjs +29 -0
  20. package/dist/OpenAICompatibleProvider-Bdtl-UXH.mjs +402 -0
  21. package/dist/OpenAICompatibleProvider-NS4cKVQj.cjs +409 -0
  22. package/dist/audio.cjs +21 -0
  23. package/dist/audio.d.cts +165 -0
  24. package/dist/audio.d.mts +165 -0
  25. package/dist/audio.mjs +4 -0
  26. package/dist/env-DSnGaERV.cjs +19 -0
  27. package/dist/env-DUwUWTsg.mjs +14 -0
  28. package/dist/events-BUMYdETO.d.cts +24 -0
  29. package/dist/events-BUMYdETO.d.mts +24 -0
  30. package/dist/events-BxDTIKKq.cjs +48 -0
  31. package/dist/events-BylBSBW-.mjs +43 -0
  32. package/dist/gemini.cjs +401 -0
  33. package/dist/gemini.d.cts +41 -0
  34. package/dist/gemini.d.mts +41 -0
  35. package/dist/gemini.mjs +395 -0
  36. package/dist/index.cjs +2142 -0
  37. package/dist/index.d.cts +920 -0
  38. package/dist/index.d.mts +920 -0
  39. package/dist/index.mjs +2113 -0
  40. package/dist/mulaw--cwU2c9L.mjs +64 -0
  41. package/dist/mulaw-DLUObjdP.cjs +117 -0
  42. package/dist/openai.cjs +61 -0
  43. package/dist/openai.d.cts +121 -0
  44. package/dist/openai.d.mts +121 -0
  45. package/dist/openai.mjs +53 -0
  46. package/dist/presets-Bf75YXs5.d.cts +24 -0
  47. package/dist/presets-Bf75YXs5.d.mts +24 -0
  48. package/dist/rest-BYqiVOhe.mjs +265 -0
  49. package/dist/rest-BvUKut_k.cjs +300 -0
  50. package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
  51. package/dist/session-config-BVLl7-ha.mjs +74 -0
  52. package/dist/session-config-c8sOw1XL.cjs +85 -0
  53. package/dist/store.cjs +3 -0
  54. package/dist/store.d.cts +2 -0
  55. package/dist/store.d.mts +2 -0
  56. package/dist/store.mjs +2 -0
  57. package/dist/testing.cjs +544 -0
  58. package/dist/testing.d.cts +191 -0
  59. package/dist/testing.d.mts +191 -0
  60. package/dist/testing.mjs +538 -0
  61. package/dist/transcode-C9aJG7_W.cjs +215 -0
  62. package/dist/transcode-CsAp97G9.mjs +198 -0
  63. package/dist/transport-B_PJFIVd.d.cts +155 -0
  64. package/dist/transport-CEaLFV4E.d.mts +155 -0
  65. package/dist/twilio.cjs +8 -0
  66. package/dist/twilio.d.cts +3 -0
  67. package/dist/twilio.d.mts +3 -0
  68. package/dist/twilio.mjs +2 -0
  69. package/dist/twiml-z9LjoF4_.d.cts +67 -0
  70. package/dist/twiml-z9LjoF4_.d.mts +67 -0
  71. package/dist/xai.cjs +92 -0
  72. package/dist/xai.d.cts +35 -0
  73. package/dist/xai.d.mts +35 -0
  74. package/dist/xai.mjs +86 -0
  75. package/package.json +183 -0
@@ -0,0 +1,401 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_BaseRealtimeProvider = require("./BaseRealtimeProvider-DI4pKtOb.cjs");
3
+ const require_env = require("./env-DSnGaERV.cjs");
4
+ const require_transcode = require("./transcode-C9aJG7_W.cjs");
5
+ //#region src/providers/gemini/GeminiLiveProvider.ts
6
+ /**
7
+ * Gemini Live provider via the official `@google/genai` SDK (optional peer).
8
+ *
9
+ * Unlike the OpenAI-compatible path, Gemini speaks PCM (16 kHz in, 24 kHz
10
+ * out), so this provider owns a stateful transcoding pair: μ-law↔PCM with
11
+ * inter-chunk resampler state — the engine stays μ-law-only.
12
+ *
13
+ * Gemini specifics handled here:
14
+ * - turn ids are synthesized (`gturn_N`) — the wire has no response ids
15
+ * - `serverContent.interrupted` is the barge-in signal (maps to
16
+ * userSpeechStarted + responseDone; the server already cancelled itself)
17
+ * - session resumption handles are captured continuously and replayed on the
18
+ * next connect, so reconnects restore context server-side
19
+ * - `goAway` (imminent disconnect, e.g. the session time limit) is surfaced
20
+ * so the session can reconnect proactively
21
+ * - tool results go through the proper `toolResponse` message
22
+ */
23
+ const GEMINI_INPUT_MIME = "audio/pcm;rate=16000";
24
+ var GeminiLiveProvider = class extends require_BaseRealtimeProvider.BaseRealtimeProvider {
25
+ name = "gemini";
26
+ capabilities = {
27
+ truncate: false,
28
+ sessionUpdate: false,
29
+ voiceChangeMidSession: false,
30
+ transcodeRequired: true,
31
+ resumption: true,
32
+ agentTranscriptDeltas: true,
33
+ vadInterruptControl: false
34
+ };
35
+ config;
36
+ logger;
37
+ session = null;
38
+ sessionInit = null;
39
+ ready = false;
40
+ intentionalClose = false;
41
+ inbound = new require_transcode.InboundTranscoder(16e3);
42
+ outbound = new require_transcode.OutboundTranscoder(24e3);
43
+ turnCounter = 0;
44
+ currentTurnId = null;
45
+ userTranscriptBuffer = "";
46
+ agentTranscriptBuffer = "";
47
+ resumptionHandle = null;
48
+ resumed = false;
49
+ constructor(config, logger = require_BaseRealtimeProvider.noopLogger) {
50
+ super();
51
+ this.config = config;
52
+ this.logger = logger;
53
+ }
54
+ get isConnected() {
55
+ return this.ready && this.session !== null;
56
+ }
57
+ /** True when the last connect restored server-side context via a handle. */
58
+ get didResume() {
59
+ return this.resumed;
60
+ }
61
+ async connect(init) {
62
+ if (this.session) await this.close();
63
+ this.sessionInit = init;
64
+ this.intentionalClose = false;
65
+ this.ready = false;
66
+ this.resumed = false;
67
+ this.inbound.reset();
68
+ this.outbound.reset();
69
+ const connector = this.config.connector ?? await this.defaultConnector();
70
+ const handle = init.freshSession ? void 0 : init.resumptionHandle ?? this.resumptionHandle ?? void 0;
71
+ if (init.freshSession) this.resumptionHandle = null;
72
+ let setupResolve;
73
+ let rejectSetup;
74
+ const setupDone = new Promise((resolve, reject) => {
75
+ setupResolve = resolve;
76
+ rejectSetup = reject;
77
+ });
78
+ let setupError = null;
79
+ setupDone.catch(() => {});
80
+ const setupReject = (error) => {
81
+ setupError ??= error;
82
+ rejectSetup(error);
83
+ };
84
+ const timeoutMs = this.config.connectTimeoutMs ?? 1e4;
85
+ const timer = setTimeout(() => setupReject(/* @__PURE__ */ new Error(`gemini setup not complete within ${timeoutMs}ms`)), timeoutMs);
86
+ timer.unref?.();
87
+ try {
88
+ try {
89
+ this.session = await connector({
90
+ model: this.config.model,
91
+ config: this.buildConfig(init, handle),
92
+ callbacks: {
93
+ onopen: () => this.emit("open"),
94
+ onmessage: (message) => {
95
+ if (message?.setupComplete !== void 0) {
96
+ this.ready = true;
97
+ if (handle) this.resumed = true;
98
+ setupResolve();
99
+ return;
100
+ }
101
+ this.handleMessage(message);
102
+ },
103
+ onerror: (error) => {
104
+ const err = error instanceof Error ? error : new Error(String(error?.message ?? error));
105
+ if (!this.ready) setupReject(err);
106
+ else this.emit("error", err);
107
+ },
108
+ onclose: (event) => {
109
+ const wasReady = this.ready;
110
+ this.ready = false;
111
+ this.session = null;
112
+ if (!wasReady) {
113
+ setupReject(/* @__PURE__ */ new Error(`gemini closed during setup (${event?.code} ${event?.reason ?? ""})`));
114
+ return;
115
+ }
116
+ this.emit("close", {
117
+ code: event?.code,
118
+ reason: event?.reason,
119
+ retriable: !this.intentionalClose && !isNonRetriableClose(event?.code)
120
+ });
121
+ }
122
+ }
123
+ });
124
+ } catch (error) {
125
+ throw setupError ?? (error instanceof Error ? error : new Error(String(error)));
126
+ }
127
+ await setupDone;
128
+ } finally {
129
+ clearTimeout(timer);
130
+ }
131
+ }
132
+ async defaultConnector() {
133
+ let genai;
134
+ try {
135
+ genai = await import("@google/genai");
136
+ } catch (error) {
137
+ throw new Error("the '@google/genai' package is required for the Gemini provider — npm install @google/genai", { cause: error });
138
+ }
139
+ const { GoogleGenAI } = genai;
140
+ const ai = this.config.vertex ? new GoogleGenAI({
141
+ vertexai: true,
142
+ project: this.config.vertex.project,
143
+ location: this.config.vertex.location
144
+ }) : new GoogleGenAI({ apiKey: this.config.apiKey });
145
+ return (params) => ai.live.connect({
146
+ model: params.model,
147
+ config: params.config,
148
+ callbacks: params.callbacks
149
+ });
150
+ }
151
+ buildConfig(init, resumptionHandle) {
152
+ const transcription = this.config.transcription;
153
+ const vad = init.vad !== void 0 ? init.vad : this.config.defaultVad;
154
+ const config = {
155
+ responseModalities: ["AUDIO"],
156
+ systemInstruction: init.instructions,
157
+ speechConfig: {
158
+ voiceConfig: { prebuiltVoiceConfig: { voiceName: init.voice ?? this.config.voice ?? "Aoede" } },
159
+ ...this.config.languageCode ? { languageCode: this.config.languageCode } : {}
160
+ },
161
+ ...init.tools?.length ? { tools: [{ functionDeclarations: init.tools.map((tool) => ({
162
+ name: tool.name,
163
+ description: tool.description ?? "",
164
+ parameters: tool.parameters
165
+ })) }] } : {},
166
+ realtimeInputConfig: { automaticActivityDetection: buildGeminiVad(vad) },
167
+ ...transcription === false ? {} : {
168
+ ...transcription?.input !== false ? { inputAudioTranscription: {} } : {},
169
+ ...transcription?.output !== false ? { outputAudioTranscription: {} } : {}
170
+ },
171
+ ...this.config.resumption !== false ? { sessionResumption: { ...resumptionHandle ? { handle: resumptionHandle } : {} } } : {},
172
+ ...this.config.contextWindowCompression ? { contextWindowCompression: { slidingWindow: {} } } : {}
173
+ };
174
+ return require_BaseRealtimeProvider.deepMerge(require_BaseRealtimeProvider.deepMerge(config, init.providerOptions), this.config.extraConfig);
175
+ }
176
+ async close() {
177
+ this.intentionalClose = true;
178
+ this.ready = false;
179
+ const session = this.session;
180
+ this.session = null;
181
+ if (!session) return;
182
+ try {
183
+ session.close();
184
+ } catch {}
185
+ }
186
+ sendAudio(base64Mulaw) {
187
+ if (!this.isConnected || !this.session) return;
188
+ const pcm = this.inbound.process(base64Mulaw);
189
+ if (pcm.length === 0) return;
190
+ this.session.sendRealtimeInput({ audio: {
191
+ data: pcm,
192
+ mimeType: GEMINI_INPUT_MIME
193
+ } });
194
+ }
195
+ sendText(text, options = {}) {
196
+ if (!this.session) return;
197
+ const role = options.role === "assistant" ? "model" : "user";
198
+ const content = options.role === "system" ? `(system note) ${text}` : text;
199
+ this.session.sendClientContent({
200
+ turns: [{
201
+ role,
202
+ parts: [{ text: content }]
203
+ }],
204
+ turnComplete: options.triggerResponse !== false
205
+ });
206
+ }
207
+ sendToolResult(callId, output, options = {}) {
208
+ if (!this.session) return;
209
+ const response = output !== null && typeof output === "object" && !Array.isArray(output) ? output : { result: output };
210
+ this.session.sendToolResponse({ functionResponses: [{
211
+ id: callId,
212
+ name: this.toolNameForCall(callId),
213
+ response
214
+ }] });
215
+ }
216
+ createResponse(options = {}) {
217
+ if (!this.session) return;
218
+ const text = options.instructions ? `(instruction) ${options.instructions}` : "(instruction) Continue the conversation now — speak to the caller.";
219
+ this.session.sendClientContent({
220
+ turns: [{
221
+ role: "user",
222
+ parts: [{ text }]
223
+ }],
224
+ turnComplete: true
225
+ });
226
+ }
227
+ async updateSession(_patch) {
228
+ this.logger.warn("gemini: updateSession ignored (no mid-session config on Live API)");
229
+ }
230
+ handleMessage(message) {
231
+ const serverContent = message?.serverContent;
232
+ if (message?.toolCall?.functionCalls) {
233
+ for (const call of message.toolCall.functionCalls) {
234
+ const id = call.id ?? `gcall_${++this.turnCounter}`;
235
+ this.callNames.set(id, call.name);
236
+ this.emit("toolCall", {
237
+ id,
238
+ name: call.name,
239
+ argumentsJson: JSON.stringify(call.args ?? {}),
240
+ responseId: this.currentTurnId ?? void 0
241
+ });
242
+ }
243
+ return;
244
+ }
245
+ if (message?.sessionResumptionUpdate) {
246
+ const update = message.sessionResumptionUpdate;
247
+ if (update.resumable && update.newHandle) {
248
+ this.resumptionHandle = update.newHandle;
249
+ this.emit("resumptionUpdate", update.newHandle);
250
+ }
251
+ return;
252
+ }
253
+ if (message?.goAway) {
254
+ const timeLeftMs = parseGoAwayTime(message.goAway.timeLeft);
255
+ this.logger.info("gemini goAway received", { timeLeftMs });
256
+ this.emit("goAway", { timeLeftMs });
257
+ return;
258
+ }
259
+ if (message?.usageMetadata) {
260
+ const usage = message.usageMetadata;
261
+ this.emit("usage", {
262
+ inputTokens: usage.promptTokenCount ?? 0,
263
+ outputTokens: usage.responseTokenCount ?? usage.candidatesTokenCount ?? 0,
264
+ totalTokens: usage.totalTokenCount ?? 0,
265
+ raw: usage
266
+ });
267
+ }
268
+ if (!serverContent) return;
269
+ if (serverContent.interrupted) {
270
+ const turnId = this.currentTurnId;
271
+ this.emit("userSpeechStarted");
272
+ if (turnId) {
273
+ this.flushAgentTranscript(turnId);
274
+ this.currentTurnId = null;
275
+ this.emit("responseDone", { responseId: turnId });
276
+ }
277
+ return;
278
+ }
279
+ if (serverContent.inputTranscription?.text) this.userTranscriptBuffer += serverContent.inputTranscription.text;
280
+ if (serverContent.outputTranscription?.text) {
281
+ const turnId = this.ensureTurn();
282
+ this.agentTranscriptBuffer += serverContent.outputTranscription.text;
283
+ this.emit("agentTranscriptDelta", {
284
+ responseId: turnId,
285
+ delta: serverContent.outputTranscription.text
286
+ });
287
+ }
288
+ const parts = serverContent.modelTurn?.parts ?? [];
289
+ for (const part of parts) if (part.inlineData?.data) {
290
+ const turnId = this.ensureTurn();
291
+ const mulaw = this.outbound.process(part.inlineData.data);
292
+ if (mulaw.length > 0) this.emit("audio", {
293
+ base64Mulaw: mulaw,
294
+ responseId: turnId
295
+ });
296
+ }
297
+ if (serverContent.turnComplete) {
298
+ this.flushUserTranscript();
299
+ const turnId = this.currentTurnId;
300
+ if (turnId) {
301
+ this.flushAgentTranscript(turnId);
302
+ this.currentTurnId = null;
303
+ this.emit("responseDone", { responseId: turnId });
304
+ }
305
+ }
306
+ }
307
+ callNames = /* @__PURE__ */ new Map();
308
+ toolNameForCall(callId) {
309
+ const name = this.callNames.get(callId) ?? callId;
310
+ this.callNames.delete(callId);
311
+ return name;
312
+ }
313
+ ensureTurn() {
314
+ if (!this.currentTurnId) {
315
+ this.currentTurnId = `gturn_${++this.turnCounter}`;
316
+ this.flushUserTranscript();
317
+ this.emit("responseStarted", { responseId: this.currentTurnId });
318
+ }
319
+ return this.currentTurnId;
320
+ }
321
+ flushUserTranscript() {
322
+ const text = this.userTranscriptBuffer.trim();
323
+ this.userTranscriptBuffer = "";
324
+ if (text) this.emit("userTranscript", { text });
325
+ }
326
+ flushAgentTranscript(turnId) {
327
+ const text = this.agentTranscriptBuffer.trim();
328
+ this.agentTranscriptBuffer = "";
329
+ if (text) this.emit("agentTranscript", {
330
+ responseId: turnId,
331
+ text
332
+ });
333
+ }
334
+ };
335
+ /** Protocol/auth/policy closes where retrying cannot help. */
336
+ function isNonRetriableClose(code) {
337
+ if (code === void 0) return false;
338
+ return code === 1002 || code === 1003 || code === 1007 || code === 1008 || code >= 4400 && code < 4500;
339
+ }
340
+ function buildGeminiVad(vad) {
341
+ if (vad === null) return { disabled: true };
342
+ return {
343
+ disabled: false,
344
+ ...vad?.startSensitivity ? { startOfSpeechSensitivity: `START_SENSITIVITY_${vad.startSensitivity.toUpperCase()}` } : {},
345
+ ...vad?.endSensitivity ? { endOfSpeechSensitivity: `END_SENSITIVITY_${vad.endSensitivity.toUpperCase()}` } : {},
346
+ ...vad?.prefixPaddingMs !== void 0 ? { prefixPaddingMs: vad.prefixPaddingMs } : {},
347
+ ...vad?.silenceDurationMs !== void 0 ? { silenceDurationMs: vad.silenceDurationMs } : {}
348
+ };
349
+ }
350
+ function parseGoAwayTime(timeLeft) {
351
+ if (typeof timeLeft === "number") return timeLeft;
352
+ if (typeof timeLeft === "string") {
353
+ const seconds = Number.parseFloat(timeLeft.replace(/s$/, ""));
354
+ if (!Number.isNaN(seconds)) return Math.round(seconds * 1e3);
355
+ }
356
+ }
357
+ //#endregion
358
+ //#region src/gemini.ts
359
+ /** Google Gemini Live provider — `realtime-voice-agents/gemini`. */
360
+ /** Env vars checked (in order) when no explicit apiKey is passed. */
361
+ const GEMINI_KEY_ENV_VARS = [
362
+ "GOOGLE_API_KEY",
363
+ "GEMINI_API_KEY",
364
+ "GOOGLE_GENAI_API_KEY"
365
+ ];
366
+ const GEMINI_DEFAULT_MODEL = "gemini-2.5-flash-native-audio-preview-12-2025";
367
+ const GEMINI_DEFAULT_VOICE = "Aoede";
368
+ const GEMINI_VOICES = [
369
+ "Aoede",
370
+ "Charon",
371
+ "Fenrir",
372
+ "Kore",
373
+ "Puck"
374
+ ];
375
+ /** Create a Gemini Live provider factory for the bridge. */
376
+ function geminiLive(options = {}) {
377
+ const apiKey = require_env.resolveApiKey(options.apiKey, GEMINI_KEY_ENV_VARS);
378
+ if (!apiKey && !options.vertex && !options.connector) throw new Error(`geminiLive: credentials missing (pass apiKey, set one of ${GEMINI_KEY_ENV_VARS.join("/")}, or configure vertex)`);
379
+ const config = {
380
+ apiKey,
381
+ vertex: options.vertex,
382
+ model: options.model ?? "gemini-2.5-flash-native-audio-preview-12-2025",
383
+ voice: options.voice ?? "Aoede",
384
+ languageCode: options.languageCode,
385
+ defaultVad: options.vad,
386
+ transcription: options.transcription,
387
+ resumption: options.resumption,
388
+ contextWindowCompression: options.contextWindowCompression,
389
+ extraConfig: options.config,
390
+ connectTimeoutMs: options.connectTimeoutMs,
391
+ connector: options.connector
392
+ };
393
+ return ({ logger }) => new GeminiLiveProvider(config, logger);
394
+ }
395
+ //#endregion
396
+ exports.GEMINI_DEFAULT_MODEL = GEMINI_DEFAULT_MODEL;
397
+ exports.GEMINI_DEFAULT_VOICE = GEMINI_DEFAULT_VOICE;
398
+ exports.GEMINI_KEY_ENV_VARS = GEMINI_KEY_ENV_VARS;
399
+ exports.GEMINI_VOICES = GEMINI_VOICES;
400
+ exports.GeminiLiveProvider = GeminiLiveProvider;
401
+ exports.geminiLive = geminiLive;
@@ -0,0 +1,41 @@
1
+ import { c as VadConfig, n as ProviderFactory } from "./BaseRealtimeProvider-BehPNT1r.cjs";
2
+ import { a as GeminiLiveSessionLike, i as GeminiLiveProviderConfig, n as GeminiLiveConnector, r as GeminiLiveProvider, t as GeminiConnectParams } from "./GeminiLiveProvider-DvkTgzjG.cjs";
3
+ //#region src/gemini.d.ts
4
+ /** Env vars checked (in order) when no explicit apiKey is passed. */
5
+ declare const GEMINI_KEY_ENV_VARS: readonly ["GOOGLE_API_KEY", "GEMINI_API_KEY", "GOOGLE_GENAI_API_KEY"];
6
+ declare const GEMINI_DEFAULT_MODEL = "gemini-2.5-flash-native-audio-preview-12-2025";
7
+ declare const GEMINI_DEFAULT_VOICE = "Aoede";
8
+ declare const GEMINI_VOICES: readonly ["Aoede", "Charon", "Fenrir", "Kore", "Puck"];
9
+ interface GeminiLiveOptions {
10
+ /** Google AI Studio key. Defaults to the first of GOOGLE_API_KEY / GEMINI_API_KEY / GOOGLE_GENAI_API_KEY set in the env. */
11
+ apiKey?: string;
12
+ /** Vertex AI instead of API-key auth (Application Default Credentials). */
13
+ vertex?: {
14
+ project: string;
15
+ location: string;
16
+ };
17
+ model?: string;
18
+ voice?: string;
19
+ /** BCP-47 speech language (e.g. 'en-US'). */
20
+ languageCode?: string;
21
+ /** Normalized VAD (start/end sensitivity, padding, silence). `null` disables. */
22
+ vad?: VadConfig | null;
23
+ /** Caller/agent transcription toggles. Default both on. */
24
+ transcription?: {
25
+ input?: boolean;
26
+ output?: boolean;
27
+ } | false;
28
+ /** Session resumption across reconnects. Default true. */
29
+ resumption?: boolean;
30
+ /** Sliding-window context compression for long calls. Default false. */
31
+ contextWindowCompression?: boolean;
32
+ /** Provider-native live config, deep-merged last (escape hatch). */
33
+ config?: Record<string, unknown>;
34
+ connectTimeoutMs?: number;
35
+ /** Test seam: replaces the @google/genai live connection. */
36
+ connector?: GeminiLiveConnector;
37
+ }
38
+ /** Create a Gemini Live provider factory for the bridge. */
39
+ declare function geminiLive(options?: GeminiLiveOptions): ProviderFactory;
40
+ //#endregion
41
+ export { GEMINI_DEFAULT_MODEL, GEMINI_DEFAULT_VOICE, GEMINI_KEY_ENV_VARS, GEMINI_VOICES, type GeminiConnectParams, type GeminiLiveConnector, GeminiLiveOptions, GeminiLiveProvider, type GeminiLiveProviderConfig, type GeminiLiveSessionLike, geminiLive };
@@ -0,0 +1,41 @@
1
+ import { c as VadConfig, n as ProviderFactory } from "./BaseRealtimeProvider-ClP8Wx1X.mjs";
2
+ import { a as GeminiLiveSessionLike, i as GeminiLiveProviderConfig, n as GeminiLiveConnector, r as GeminiLiveProvider, t as GeminiConnectParams } from "./GeminiLiveProvider-x2nyx5aO.mjs";
3
+ //#region src/gemini.d.ts
4
+ /** Env vars checked (in order) when no explicit apiKey is passed. */
5
+ declare const GEMINI_KEY_ENV_VARS: readonly ["GOOGLE_API_KEY", "GEMINI_API_KEY", "GOOGLE_GENAI_API_KEY"];
6
+ declare const GEMINI_DEFAULT_MODEL = "gemini-2.5-flash-native-audio-preview-12-2025";
7
+ declare const GEMINI_DEFAULT_VOICE = "Aoede";
8
+ declare const GEMINI_VOICES: readonly ["Aoede", "Charon", "Fenrir", "Kore", "Puck"];
9
+ interface GeminiLiveOptions {
10
+ /** Google AI Studio key. Defaults to the first of GOOGLE_API_KEY / GEMINI_API_KEY / GOOGLE_GENAI_API_KEY set in the env. */
11
+ apiKey?: string;
12
+ /** Vertex AI instead of API-key auth (Application Default Credentials). */
13
+ vertex?: {
14
+ project: string;
15
+ location: string;
16
+ };
17
+ model?: string;
18
+ voice?: string;
19
+ /** BCP-47 speech language (e.g. 'en-US'). */
20
+ languageCode?: string;
21
+ /** Normalized VAD (start/end sensitivity, padding, silence). `null` disables. */
22
+ vad?: VadConfig | null;
23
+ /** Caller/agent transcription toggles. Default both on. */
24
+ transcription?: {
25
+ input?: boolean;
26
+ output?: boolean;
27
+ } | false;
28
+ /** Session resumption across reconnects. Default true. */
29
+ resumption?: boolean;
30
+ /** Sliding-window context compression for long calls. Default false. */
31
+ contextWindowCompression?: boolean;
32
+ /** Provider-native live config, deep-merged last (escape hatch). */
33
+ config?: Record<string, unknown>;
34
+ connectTimeoutMs?: number;
35
+ /** Test seam: replaces the @google/genai live connection. */
36
+ connector?: GeminiLiveConnector;
37
+ }
38
+ /** Create a Gemini Live provider factory for the bridge. */
39
+ declare function geminiLive(options?: GeminiLiveOptions): ProviderFactory;
40
+ //#endregion
41
+ export { GEMINI_DEFAULT_MODEL, GEMINI_DEFAULT_VOICE, GEMINI_KEY_ENV_VARS, GEMINI_VOICES, type GeminiConnectParams, type GeminiLiveConnector, GeminiLiveOptions, GeminiLiveProvider, type GeminiLiveProviderConfig, type GeminiLiveSessionLike, geminiLive };