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,239 @@
1
+ import { t as TypedEmitter } from "./events-BUMYdETO.cjs";
2
+ //#region src/logging/logger.d.ts
3
+ /**
4
+ * Minimal structured logger seam. Pino/winston/console all adapt in one line;
5
+ * the default is silent so the library never spams a host app's stdout.
6
+ */
7
+ interface Logger {
8
+ debug(message: string, data?: Record<string, unknown>): void;
9
+ info(message: string, data?: Record<string, unknown>): void;
10
+ warn(message: string, data?: Record<string, unknown>): void;
11
+ error(message: string, data?: Record<string, unknown>): void;
12
+ /** Derive a logger with bound context (e.g. callSid). */
13
+ child?(context: Record<string, unknown>): Logger;
14
+ }
15
+ declare const noopLogger: Logger;
16
+ /** Console-backed logger, useful in examples and debugging. */
17
+ declare function consoleLogger(context?: Record<string, unknown>): Logger;
18
+ //#endregion
19
+ //#region src/providers/base/capabilities.d.ts
20
+ /**
21
+ * Capability flags per provider. The engine branches on these — never on a
22
+ * provider's name — so new providers slot in without touching session logic.
23
+ */
24
+ interface ProviderCapabilities {
25
+ /** Supports trimming the last assistant item to what was actually heard. */
26
+ truncate: boolean;
27
+ /** Supports mid-session instruction/tool swaps (session.update). */
28
+ sessionUpdate: boolean;
29
+ /** Voice can change after audio has been emitted in the session. */
30
+ voiceChangeMidSession: boolean;
31
+ /** Provider speaks PCM — the μ-law wire format must be transcoded. */
32
+ transcodeRequired: boolean;
33
+ /** Supports server-side session resumption handles. */
34
+ resumption: boolean;
35
+ /** Streams assistant transcript deltas (enables first-sentence detection). */
36
+ agentTranscriptDeltas: boolean;
37
+ /**
38
+ * Server VAD's auto-interrupt can be disabled (`interrupt_response: false`),
39
+ * letting the bridge own barge-in: cancel/clear/truncate only when the
40
+ * interruption guard allows. Without it, the provider cancels generation on
41
+ * speech onset regardless of the guard — the guard then protects only the
42
+ * already-buffered Twilio audio (documented fallback, see parity tests).
43
+ * Optional so existing third-party providers keep compiling (absent = false).
44
+ */
45
+ vadInterruptControl?: boolean;
46
+ }
47
+ //#endregion
48
+ //#region src/providers/base/events.d.ts
49
+ /** Normalized events every provider emits, regardless of wire protocol. */
50
+ interface RawUsage {
51
+ [key: string]: unknown;
52
+ }
53
+ interface ProviderUsage {
54
+ inputTokens: number;
55
+ outputTokens: number;
56
+ totalTokens: number;
57
+ inputTokenDetails?: {
58
+ textTokens?: number;
59
+ audioTokens?: number;
60
+ cachedTokens?: number;
61
+ };
62
+ outputTokenDetails?: {
63
+ textTokens?: number;
64
+ audioTokens?: number;
65
+ };
66
+ /** Provider-native payload for advanced analytics. */
67
+ raw?: RawUsage;
68
+ }
69
+ interface ProviderAudioDelta {
70
+ /** Base64 μ-law 8 kHz — already in Twilio wire format. */
71
+ base64Mulaw: string;
72
+ responseId: string;
73
+ itemId?: string;
74
+ }
75
+ interface ProviderToolCall {
76
+ /** Provider call id used to correlate the result (function name on providers without ids). */
77
+ id: string;
78
+ name: string;
79
+ argumentsJson: string;
80
+ responseId?: string;
81
+ itemId?: string;
82
+ }
83
+ interface ProviderCloseInfo {
84
+ code?: number;
85
+ reason?: string;
86
+ /** False for auth/config failures where retrying is pointless. */
87
+ retriable: boolean;
88
+ }
89
+ interface ProviderEvents {
90
+ open: () => void;
91
+ close: (info: ProviderCloseInfo) => void;
92
+ error: (error: Error) => void;
93
+ /** Assistant audio chunk, normalized to base64 μ-law. */
94
+ audio: (delta: ProviderAudioDelta) => void;
95
+ /** A new assistant response began generating. */
96
+ responseStarted: (info: {
97
+ responseId: string;
98
+ }) => void;
99
+ /** The assistant response finished generating (audio may still be playing out). */
100
+ responseDone: (info: {
101
+ responseId: string;
102
+ usage?: ProviderUsage;
103
+ }) => void;
104
+ /** An output item was added — carries the itemId needed for truncation. */
105
+ outputItemAdded: (info: {
106
+ itemId: string;
107
+ responseId: string;
108
+ }) => void;
109
+ toolCall: (call: ProviderToolCall) => void;
110
+ userSpeechStarted: () => void;
111
+ userSpeechStopped: () => void;
112
+ userTranscript: (entry: {
113
+ text: string;
114
+ }) => void;
115
+ agentTranscriptDelta: (entry: {
116
+ responseId: string;
117
+ delta: string;
118
+ }) => void;
119
+ agentTranscript: (entry: {
120
+ responseId: string;
121
+ text: string;
122
+ }) => void;
123
+ usage: (usage: ProviderUsage) => void;
124
+ /** Session-resumption handle refresh (Gemini). */
125
+ resumptionUpdate: (handle: string) => void;
126
+ /** Provider announced imminent disconnect (Gemini GoAway). */
127
+ goAway: (info: {
128
+ timeLeftMs?: number;
129
+ }) => void;
130
+ }
131
+ //#endregion
132
+ //#region src/providers/base/BaseRealtimeProvider.d.ts
133
+ /** Normalized VAD config, mapped onto each provider's native shape. */
134
+ interface VadConfig {
135
+ /** 'server' = provider-side VAD; 'semantic' where supported; null disables turn detection. */
136
+ type?: 'server' | 'semantic';
137
+ threshold?: number;
138
+ silenceDurationMs?: number;
139
+ prefixPaddingMs?: number;
140
+ /** Semantic VAD eagerness (OpenAI). */
141
+ eagerness?: 'low' | 'medium' | 'high' | 'auto';
142
+ /** Gemini-only sensitivities. */
143
+ startSensitivity?: 'high' | 'low';
144
+ endSensitivity?: 'high' | 'low';
145
+ /**
146
+ * Server-side auto-cancel of the active response on speech onset (OpenAI
147
+ * `interrupt_response`). Leave unset: the bridge manages it via
148
+ * `bridgeOwnsInterruptions` so the interruption guard actually holds.
149
+ */
150
+ interruptResponse?: boolean;
151
+ /** Server-side auto-response on turn commit (OpenAI `create_response`). */
152
+ createResponse?: boolean;
153
+ }
154
+ interface ProviderToolSchema {
155
+ name: string;
156
+ description?: string;
157
+ /** JSON Schema for the tool parameters. */
158
+ parameters: Record<string, unknown>;
159
+ }
160
+ /** Everything a provider needs to open (or re-open) a live session. */
161
+ interface ProviderSessionInit {
162
+ instructions: string;
163
+ voice?: string;
164
+ tools?: ProviderToolSchema[];
165
+ vad?: VadConfig | null;
166
+ temperature?: number;
167
+ transcription?: {
168
+ model?: string;
169
+ language?: string;
170
+ } | false;
171
+ /** Session-resumption handle from a previous connection (capability-gated). */
172
+ resumptionHandle?: string;
173
+ /**
174
+ * Force a brand-new server session: ignore any stored resumption handle.
175
+ * Used for handoffs, where the session config itself changes.
176
+ */
177
+ freshSession?: boolean;
178
+ /**
179
+ * The bridge arbitrates barge-ins (interruption guard). Providers with
180
+ * `vadInterruptControl` disable their server-side auto-interrupt unless the
181
+ * vad config sets `interruptResponse` explicitly; others ignore this flag
182
+ * (documented fallback: guard protects buffered audio only).
183
+ */
184
+ bridgeOwnsInterruptions?: boolean;
185
+ /** Provider-native session options, deep-merged last (escape hatch). */
186
+ providerOptions?: Record<string, unknown>;
187
+ }
188
+ interface SendTextOptions {
189
+ /** `assistant` is used for history re-injection after reconnect/handoff. */
190
+ role?: 'user' | 'system' | 'assistant';
191
+ /** Ask the model to respond immediately after the text lands. Default true. */
192
+ triggerResponse?: boolean;
193
+ }
194
+ interface SendToolResultOptions {
195
+ triggerResponse?: boolean;
196
+ }
197
+ /**
198
+ * The provider contract: μ-law in, μ-law out, normalized events.
199
+ * Transcoding (when the provider speaks PCM) lives inside the provider, so
200
+ * the engine stays codec-free. `connect()` is re-invokable on the same
201
+ * instance — the session layer owns reconnect policy and context re-injection.
202
+ */
203
+ declare abstract class BaseRealtimeProvider extends TypedEmitter<ProviderEvents> {
204
+ abstract readonly name: string;
205
+ abstract readonly capabilities: ProviderCapabilities;
206
+ /** Resolves when the session is configured and ready for audio. */
207
+ abstract connect(init: ProviderSessionInit): Promise<void>;
208
+ abstract close(): Promise<void>;
209
+ abstract get isConnected(): boolean;
210
+ /** Forward caller audio (base64 μ-law 8 kHz). */
211
+ abstract sendAudio(base64Mulaw: string): void;
212
+ /** Inject a text turn into the conversation. */
213
+ abstract sendText(text: string, options?: SendTextOptions): void;
214
+ /** Return a tool result to the model. */
215
+ abstract sendToolResult(callId: string, output: unknown, options?: SendToolResultOptions): void;
216
+ /** Trigger an out-of-band assistant response (greeting, nudge, announcement). */
217
+ abstract createResponse(options?: {
218
+ instructions?: string;
219
+ }): void;
220
+ /** Mid-session config change (instructions/tools/voice) where supported. */
221
+ abstract updateSession(patch: Partial<ProviderSessionInit>): Promise<void>;
222
+ /** Interrupt in-flight generation (where the wire protocol supports it). */
223
+ cancelResponse(): void;
224
+ /** Trim the last assistant item to what the caller actually heard. */
225
+ truncatePlayback(_itemId: string, _audioEndMs: number): void;
226
+ /**
227
+ * Whether the most recent connect restored server-side context (session
228
+ * resumption). When true, the engine skips transcript re-injection.
229
+ */
230
+ get didResume(): boolean;
231
+ }
232
+ interface ProviderFactoryContext {
233
+ logger: Logger;
234
+ callSid: string;
235
+ }
236
+ /** A fresh provider per call; connection config is captured in the factory closure. */
237
+ type ProviderFactory = (context: ProviderFactoryContext) => BaseRealtimeProvider;
238
+ //#endregion
239
+ export { noopLogger as _, ProviderToolSchema as a, VadConfig as c, ProviderEvents as d, ProviderToolCall as f, consoleLogger as g, Logger as h, ProviderSessionInit as i, ProviderAudioDelta as l, ProviderCapabilities as m, ProviderFactory as n, SendTextOptions as o, ProviderUsage as p, ProviderFactoryContext as r, SendToolResultOptions as s, BaseRealtimeProvider as t, ProviderCloseInfo as u };
@@ -0,0 +1,239 @@
1
+ import { t as TypedEmitter } from "./events-BUMYdETO.mjs";
2
+ //#region src/logging/logger.d.ts
3
+ /**
4
+ * Minimal structured logger seam. Pino/winston/console all adapt in one line;
5
+ * the default is silent so the library never spams a host app's stdout.
6
+ */
7
+ interface Logger {
8
+ debug(message: string, data?: Record<string, unknown>): void;
9
+ info(message: string, data?: Record<string, unknown>): void;
10
+ warn(message: string, data?: Record<string, unknown>): void;
11
+ error(message: string, data?: Record<string, unknown>): void;
12
+ /** Derive a logger with bound context (e.g. callSid). */
13
+ child?(context: Record<string, unknown>): Logger;
14
+ }
15
+ declare const noopLogger: Logger;
16
+ /** Console-backed logger, useful in examples and debugging. */
17
+ declare function consoleLogger(context?: Record<string, unknown>): Logger;
18
+ //#endregion
19
+ //#region src/providers/base/capabilities.d.ts
20
+ /**
21
+ * Capability flags per provider. The engine branches on these — never on a
22
+ * provider's name — so new providers slot in without touching session logic.
23
+ */
24
+ interface ProviderCapabilities {
25
+ /** Supports trimming the last assistant item to what was actually heard. */
26
+ truncate: boolean;
27
+ /** Supports mid-session instruction/tool swaps (session.update). */
28
+ sessionUpdate: boolean;
29
+ /** Voice can change after audio has been emitted in the session. */
30
+ voiceChangeMidSession: boolean;
31
+ /** Provider speaks PCM — the μ-law wire format must be transcoded. */
32
+ transcodeRequired: boolean;
33
+ /** Supports server-side session resumption handles. */
34
+ resumption: boolean;
35
+ /** Streams assistant transcript deltas (enables first-sentence detection). */
36
+ agentTranscriptDeltas: boolean;
37
+ /**
38
+ * Server VAD's auto-interrupt can be disabled (`interrupt_response: false`),
39
+ * letting the bridge own barge-in: cancel/clear/truncate only when the
40
+ * interruption guard allows. Without it, the provider cancels generation on
41
+ * speech onset regardless of the guard — the guard then protects only the
42
+ * already-buffered Twilio audio (documented fallback, see parity tests).
43
+ * Optional so existing third-party providers keep compiling (absent = false).
44
+ */
45
+ vadInterruptControl?: boolean;
46
+ }
47
+ //#endregion
48
+ //#region src/providers/base/events.d.ts
49
+ /** Normalized events every provider emits, regardless of wire protocol. */
50
+ interface RawUsage {
51
+ [key: string]: unknown;
52
+ }
53
+ interface ProviderUsage {
54
+ inputTokens: number;
55
+ outputTokens: number;
56
+ totalTokens: number;
57
+ inputTokenDetails?: {
58
+ textTokens?: number;
59
+ audioTokens?: number;
60
+ cachedTokens?: number;
61
+ };
62
+ outputTokenDetails?: {
63
+ textTokens?: number;
64
+ audioTokens?: number;
65
+ };
66
+ /** Provider-native payload for advanced analytics. */
67
+ raw?: RawUsage;
68
+ }
69
+ interface ProviderAudioDelta {
70
+ /** Base64 μ-law 8 kHz — already in Twilio wire format. */
71
+ base64Mulaw: string;
72
+ responseId: string;
73
+ itemId?: string;
74
+ }
75
+ interface ProviderToolCall {
76
+ /** Provider call id used to correlate the result (function name on providers without ids). */
77
+ id: string;
78
+ name: string;
79
+ argumentsJson: string;
80
+ responseId?: string;
81
+ itemId?: string;
82
+ }
83
+ interface ProviderCloseInfo {
84
+ code?: number;
85
+ reason?: string;
86
+ /** False for auth/config failures where retrying is pointless. */
87
+ retriable: boolean;
88
+ }
89
+ interface ProviderEvents {
90
+ open: () => void;
91
+ close: (info: ProviderCloseInfo) => void;
92
+ error: (error: Error) => void;
93
+ /** Assistant audio chunk, normalized to base64 μ-law. */
94
+ audio: (delta: ProviderAudioDelta) => void;
95
+ /** A new assistant response began generating. */
96
+ responseStarted: (info: {
97
+ responseId: string;
98
+ }) => void;
99
+ /** The assistant response finished generating (audio may still be playing out). */
100
+ responseDone: (info: {
101
+ responseId: string;
102
+ usage?: ProviderUsage;
103
+ }) => void;
104
+ /** An output item was added — carries the itemId needed for truncation. */
105
+ outputItemAdded: (info: {
106
+ itemId: string;
107
+ responseId: string;
108
+ }) => void;
109
+ toolCall: (call: ProviderToolCall) => void;
110
+ userSpeechStarted: () => void;
111
+ userSpeechStopped: () => void;
112
+ userTranscript: (entry: {
113
+ text: string;
114
+ }) => void;
115
+ agentTranscriptDelta: (entry: {
116
+ responseId: string;
117
+ delta: string;
118
+ }) => void;
119
+ agentTranscript: (entry: {
120
+ responseId: string;
121
+ text: string;
122
+ }) => void;
123
+ usage: (usage: ProviderUsage) => void;
124
+ /** Session-resumption handle refresh (Gemini). */
125
+ resumptionUpdate: (handle: string) => void;
126
+ /** Provider announced imminent disconnect (Gemini GoAway). */
127
+ goAway: (info: {
128
+ timeLeftMs?: number;
129
+ }) => void;
130
+ }
131
+ //#endregion
132
+ //#region src/providers/base/BaseRealtimeProvider.d.ts
133
+ /** Normalized VAD config, mapped onto each provider's native shape. */
134
+ interface VadConfig {
135
+ /** 'server' = provider-side VAD; 'semantic' where supported; null disables turn detection. */
136
+ type?: 'server' | 'semantic';
137
+ threshold?: number;
138
+ silenceDurationMs?: number;
139
+ prefixPaddingMs?: number;
140
+ /** Semantic VAD eagerness (OpenAI). */
141
+ eagerness?: 'low' | 'medium' | 'high' | 'auto';
142
+ /** Gemini-only sensitivities. */
143
+ startSensitivity?: 'high' | 'low';
144
+ endSensitivity?: 'high' | 'low';
145
+ /**
146
+ * Server-side auto-cancel of the active response on speech onset (OpenAI
147
+ * `interrupt_response`). Leave unset: the bridge manages it via
148
+ * `bridgeOwnsInterruptions` so the interruption guard actually holds.
149
+ */
150
+ interruptResponse?: boolean;
151
+ /** Server-side auto-response on turn commit (OpenAI `create_response`). */
152
+ createResponse?: boolean;
153
+ }
154
+ interface ProviderToolSchema {
155
+ name: string;
156
+ description?: string;
157
+ /** JSON Schema for the tool parameters. */
158
+ parameters: Record<string, unknown>;
159
+ }
160
+ /** Everything a provider needs to open (or re-open) a live session. */
161
+ interface ProviderSessionInit {
162
+ instructions: string;
163
+ voice?: string;
164
+ tools?: ProviderToolSchema[];
165
+ vad?: VadConfig | null;
166
+ temperature?: number;
167
+ transcription?: {
168
+ model?: string;
169
+ language?: string;
170
+ } | false;
171
+ /** Session-resumption handle from a previous connection (capability-gated). */
172
+ resumptionHandle?: string;
173
+ /**
174
+ * Force a brand-new server session: ignore any stored resumption handle.
175
+ * Used for handoffs, where the session config itself changes.
176
+ */
177
+ freshSession?: boolean;
178
+ /**
179
+ * The bridge arbitrates barge-ins (interruption guard). Providers with
180
+ * `vadInterruptControl` disable their server-side auto-interrupt unless the
181
+ * vad config sets `interruptResponse` explicitly; others ignore this flag
182
+ * (documented fallback: guard protects buffered audio only).
183
+ */
184
+ bridgeOwnsInterruptions?: boolean;
185
+ /** Provider-native session options, deep-merged last (escape hatch). */
186
+ providerOptions?: Record<string, unknown>;
187
+ }
188
+ interface SendTextOptions {
189
+ /** `assistant` is used for history re-injection after reconnect/handoff. */
190
+ role?: 'user' | 'system' | 'assistant';
191
+ /** Ask the model to respond immediately after the text lands. Default true. */
192
+ triggerResponse?: boolean;
193
+ }
194
+ interface SendToolResultOptions {
195
+ triggerResponse?: boolean;
196
+ }
197
+ /**
198
+ * The provider contract: μ-law in, μ-law out, normalized events.
199
+ * Transcoding (when the provider speaks PCM) lives inside the provider, so
200
+ * the engine stays codec-free. `connect()` is re-invokable on the same
201
+ * instance — the session layer owns reconnect policy and context re-injection.
202
+ */
203
+ declare abstract class BaseRealtimeProvider extends TypedEmitter<ProviderEvents> {
204
+ abstract readonly name: string;
205
+ abstract readonly capabilities: ProviderCapabilities;
206
+ /** Resolves when the session is configured and ready for audio. */
207
+ abstract connect(init: ProviderSessionInit): Promise<void>;
208
+ abstract close(): Promise<void>;
209
+ abstract get isConnected(): boolean;
210
+ /** Forward caller audio (base64 μ-law 8 kHz). */
211
+ abstract sendAudio(base64Mulaw: string): void;
212
+ /** Inject a text turn into the conversation. */
213
+ abstract sendText(text: string, options?: SendTextOptions): void;
214
+ /** Return a tool result to the model. */
215
+ abstract sendToolResult(callId: string, output: unknown, options?: SendToolResultOptions): void;
216
+ /** Trigger an out-of-band assistant response (greeting, nudge, announcement). */
217
+ abstract createResponse(options?: {
218
+ instructions?: string;
219
+ }): void;
220
+ /** Mid-session config change (instructions/tools/voice) where supported. */
221
+ abstract updateSession(patch: Partial<ProviderSessionInit>): Promise<void>;
222
+ /** Interrupt in-flight generation (where the wire protocol supports it). */
223
+ cancelResponse(): void;
224
+ /** Trim the last assistant item to what the caller actually heard. */
225
+ truncatePlayback(_itemId: string, _audioEndMs: number): void;
226
+ /**
227
+ * Whether the most recent connect restored server-side context (session
228
+ * resumption). When true, the engine skips transcript re-injection.
229
+ */
230
+ get didResume(): boolean;
231
+ }
232
+ interface ProviderFactoryContext {
233
+ logger: Logger;
234
+ callSid: string;
235
+ }
236
+ /** A fresh provider per call; connection config is captured in the factory closure. */
237
+ type ProviderFactory = (context: ProviderFactoryContext) => BaseRealtimeProvider;
238
+ //#endregion
239
+ export { noopLogger as _, ProviderToolSchema as a, VadConfig as c, ProviderEvents as d, ProviderToolCall as f, consoleLogger as g, Logger as h, ProviderSessionInit as i, ProviderAudioDelta as l, ProviderCapabilities as m, ProviderFactory as n, SendTextOptions as o, ProviderUsage as p, ProviderFactoryContext as r, SendToolResultOptions as s, BaseRealtimeProvider as t, ProviderCloseInfo as u };
@@ -0,0 +1,91 @@
1
+ const require_events = require("./events-BxDTIKKq.cjs");
2
+ //#region src/logging/logger.ts
3
+ const noopLogger = {
4
+ debug: () => {},
5
+ info: () => {},
6
+ warn: () => {},
7
+ error: () => {},
8
+ child: () => noopLogger
9
+ };
10
+ /** Console-backed logger, useful in examples and debugging. */
11
+ function consoleLogger(context = {}) {
12
+ const prefix = Object.keys(context).length ? ` ${JSON.stringify(context)}` : "";
13
+ return {
14
+ debug: (msg, data) => console.debug(`[debug]${prefix} ${msg}`, data ?? ""),
15
+ info: (msg, data) => console.info(`[info]${prefix} ${msg}`, data ?? ""),
16
+ warn: (msg, data) => console.warn(`[warn]${prefix} ${msg}`, data ?? ""),
17
+ error: (msg, data) => console.error(`[error]${prefix} ${msg}`, data ?? ""),
18
+ child: (extra) => consoleLogger({
19
+ ...context,
20
+ ...extra
21
+ })
22
+ };
23
+ }
24
+ function childLogger(logger, context) {
25
+ return logger.child ? logger.child(context) : logger;
26
+ }
27
+ //#endregion
28
+ //#region src/internal/merge.ts
29
+ /** Recursive plain-object merge; arrays and non-objects replace wholesale. */
30
+ function deepMerge(base, patch) {
31
+ if (!patch) return base;
32
+ const out = { ...base };
33
+ for (const [key, value] of Object.entries(patch)) {
34
+ const existing = out[key];
35
+ if (value !== null && typeof value === "object" && !Array.isArray(value) && existing !== null && typeof existing === "object" && !Array.isArray(existing)) out[key] = deepMerge(existing, value);
36
+ else out[key] = value;
37
+ }
38
+ return out;
39
+ }
40
+ //#endregion
41
+ //#region src/providers/base/BaseRealtimeProvider.ts
42
+ /**
43
+ * The provider contract: μ-law in, μ-law out, normalized events.
44
+ * Transcoding (when the provider speaks PCM) lives inside the provider, so
45
+ * the engine stays codec-free. `connect()` is re-invokable on the same
46
+ * instance — the session layer owns reconnect policy and context re-injection.
47
+ */
48
+ var BaseRealtimeProvider = class extends require_events.TypedEmitter {
49
+ /** Interrupt in-flight generation (where the wire protocol supports it). */
50
+ cancelResponse() {}
51
+ /** Trim the last assistant item to what the caller actually heard. */
52
+ truncatePlayback(_itemId, _audioEndMs) {}
53
+ /**
54
+ * Whether the most recent connect restored server-side context (session
55
+ * resumption). When true, the engine skips transcript re-injection.
56
+ */
57
+ get didResume() {
58
+ return false;
59
+ }
60
+ };
61
+ //#endregion
62
+ Object.defineProperty(exports, "BaseRealtimeProvider", {
63
+ enumerable: true,
64
+ get: function() {
65
+ return BaseRealtimeProvider;
66
+ }
67
+ });
68
+ Object.defineProperty(exports, "childLogger", {
69
+ enumerable: true,
70
+ get: function() {
71
+ return childLogger;
72
+ }
73
+ });
74
+ Object.defineProperty(exports, "consoleLogger", {
75
+ enumerable: true,
76
+ get: function() {
77
+ return consoleLogger;
78
+ }
79
+ });
80
+ Object.defineProperty(exports, "deepMerge", {
81
+ enumerable: true,
82
+ get: function() {
83
+ return deepMerge;
84
+ }
85
+ });
86
+ Object.defineProperty(exports, "noopLogger", {
87
+ enumerable: true,
88
+ get: function() {
89
+ return noopLogger;
90
+ }
91
+ });
@@ -0,0 +1,101 @@
1
+ import { c as VadConfig, h as Logger, i as ProviderSessionInit, m as ProviderCapabilities, o as SendTextOptions, s as SendToolResultOptions, t as BaseRealtimeProvider } from "./BaseRealtimeProvider-BehPNT1r.cjs";
2
+ //#region src/providers/gemini/GeminiLiveProvider.d.ts
3
+ /** Structural slice of @google/genai's live session (also what fakes implement). */
4
+ interface GeminiLiveSessionLike {
5
+ sendRealtimeInput(input: {
6
+ audio: {
7
+ data: string;
8
+ mimeType: string;
9
+ };
10
+ }): void;
11
+ sendClientContent(content: {
12
+ turns: Array<Record<string, unknown>>;
13
+ turnComplete?: boolean;
14
+ }): void;
15
+ sendToolResponse(response: {
16
+ functionResponses: Array<Record<string, unknown>>;
17
+ }): void;
18
+ close(): void;
19
+ }
20
+ interface GeminiConnectParams {
21
+ model: string;
22
+ config: Record<string, unknown>;
23
+ callbacks: {
24
+ onopen?: () => void;
25
+ onmessage: (message: any) => void;
26
+ onerror?: (error: any) => void;
27
+ onclose?: (event: {
28
+ code?: number;
29
+ reason?: string;
30
+ }) => void;
31
+ };
32
+ }
33
+ type GeminiLiveConnector = (params: GeminiConnectParams) => Promise<GeminiLiveSessionLike>;
34
+ interface GeminiLiveProviderConfig {
35
+ /** API-key auth (Google AI Studio). Ignored when `vertex` is set. */
36
+ apiKey?: string;
37
+ /** Vertex AI auth (uses Application Default Credentials). */
38
+ vertex?: {
39
+ project: string;
40
+ location: string;
41
+ };
42
+ model: string;
43
+ voice?: string;
44
+ languageCode?: string;
45
+ defaultVad?: VadConfig | null;
46
+ /** Input/output transcription toggles. Default both on. */
47
+ transcription?: {
48
+ input?: boolean;
49
+ output?: boolean;
50
+ } | false;
51
+ /** Use session resumption handles across reconnects. Default true. */
52
+ resumption?: boolean;
53
+ /** Ask Gemini to compress old context instead of dying at the token limit. */
54
+ contextWindowCompression?: boolean;
55
+ /** Provider-native `config` fields, deep-merged last (escape hatch). */
56
+ extraConfig?: Record<string, unknown>;
57
+ connectTimeoutMs?: number;
58
+ /** Test seam: replaces `new GoogleGenAI(...).live.connect`. */
59
+ connector?: GeminiLiveConnector;
60
+ }
61
+ declare class GeminiLiveProvider extends BaseRealtimeProvider {
62
+ readonly name = "gemini";
63
+ readonly capabilities: ProviderCapabilities;
64
+ private readonly config;
65
+ private readonly logger;
66
+ private session;
67
+ private sessionInit;
68
+ private ready;
69
+ private intentionalClose;
70
+ private readonly inbound;
71
+ private readonly outbound;
72
+ private turnCounter;
73
+ private currentTurnId;
74
+ private userTranscriptBuffer;
75
+ private agentTranscriptBuffer;
76
+ private resumptionHandle;
77
+ private resumed;
78
+ constructor(config: GeminiLiveProviderConfig, logger?: Logger);
79
+ get isConnected(): boolean;
80
+ /** True when the last connect restored server-side context via a handle. */
81
+ get didResume(): boolean;
82
+ connect(init: ProviderSessionInit): Promise<void>;
83
+ private defaultConnector;
84
+ private buildConfig;
85
+ close(): Promise<void>;
86
+ sendAudio(base64Mulaw: string): void;
87
+ sendText(text: string, options?: SendTextOptions): void;
88
+ sendToolResult(callId: string, output: unknown, options?: SendToolResultOptions): void;
89
+ createResponse(options?: {
90
+ instructions?: string;
91
+ }): void;
92
+ updateSession(_patch: Partial<ProviderSessionInit>): Promise<void>;
93
+ private handleMessage;
94
+ private readonly callNames;
95
+ private toolNameForCall;
96
+ private ensureTurn;
97
+ private flushUserTranscript;
98
+ private flushAgentTranscript;
99
+ }
100
+ //#endregion
101
+ export { GeminiLiveSessionLike as a, GeminiLiveProviderConfig as i, GeminiLiveConnector as n, GeminiLiveProvider as r, GeminiConnectParams as t };