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,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-ClP8Wx1X.mjs";
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 };
@@ -0,0 +1,34 @@
1
+ //#region src/session/InMemorySessionStore.ts
2
+ var InMemorySessionStore = class {
3
+ snapshots = /* @__PURE__ */ new Map();
4
+ maxEntries;
5
+ constructor(options = {}) {
6
+ this.maxEntries = options.maxEntries ?? 1e3;
7
+ }
8
+ async save(snapshot) {
9
+ this.snapshots.set(snapshot.callSid, structuredClone(snapshot));
10
+ while (this.snapshots.size > this.maxEntries) {
11
+ const oldest = this.snapshots.keys().next().value;
12
+ if (oldest === void 0) break;
13
+ this.snapshots.delete(oldest);
14
+ }
15
+ }
16
+ async load(callSid) {
17
+ const snapshot = this.snapshots.get(callSid);
18
+ return snapshot ? structuredClone(snapshot) : null;
19
+ }
20
+ async delete(callSid) {
21
+ this.snapshots.delete(callSid);
22
+ }
23
+ /** All stored snapshots (testing/debugging). */
24
+ list() {
25
+ return [...this.snapshots.values()].map((s) => structuredClone(s));
26
+ }
27
+ };
28
+ //#endregion
29
+ Object.defineProperty(exports, "InMemorySessionStore", {
30
+ enumerable: true,
31
+ get: function() {
32
+ return InMemorySessionStore;
33
+ }
34
+ });
@@ -0,0 +1,83 @@
1
+ //#region src/session/transcript.d.ts
2
+ interface TranscriptEntry {
3
+ role: 'user' | 'agent';
4
+ text: string;
5
+ /** Milliseconds since call start. */
6
+ timestampMs: number;
7
+ /** Which agent spoke / was active (multi-agent calls). */
8
+ agentId?: string;
9
+ /** The caller cut this utterance off mid-playback. */
10
+ interrupted?: boolean;
11
+ }
12
+ //#endregion
13
+ //#region src/session/usage.d.ts
14
+ /** Accumulated token consumption for a call, normalized across providers. */
15
+ interface UsageInfo {
16
+ inputTokens: number;
17
+ outputTokens: number;
18
+ totalTokens: number;
19
+ inputTokenDetails: {
20
+ textTokens: number;
21
+ audioTokens: number;
22
+ cachedTokens: number;
23
+ };
24
+ outputTokenDetails: {
25
+ textTokens: number;
26
+ audioTokens: number;
27
+ };
28
+ /** Number of model responses accounted. */
29
+ responses: number;
30
+ }
31
+ declare function emptyUsage(): UsageInfo;
32
+ //#endregion
33
+ //#region src/session/snapshot.d.ts
34
+ /** Serializable checkpoint of a call, written to the SessionStore. */
35
+ interface CallSnapshot {
36
+ callSid: string;
37
+ streamSid: string | null;
38
+ state: string;
39
+ activeAgentId: string;
40
+ transcript: TranscriptEntry[];
41
+ usage: UsageInfo;
42
+ context: Record<string, unknown>;
43
+ handoffHistory: Array<{
44
+ from: string;
45
+ to: string;
46
+ atMs: number;
47
+ }>;
48
+ /** Gemini session-resumption handle, when the provider supplies one. */
49
+ resumptionHandle?: string;
50
+ startedAtMs: number;
51
+ endedAtMs?: number;
52
+ endReason?: string;
53
+ }
54
+ //#endregion
55
+ //#region src/session/SessionStore.d.ts
56
+ /**
57
+ * Durable checkpoint store (LangGraph-checkpointer-inspired). Snapshots are
58
+ * written at call start, agent handoff, tool completion, and call end — never
59
+ * read on the audio hot path. Implement over Redis/Postgres for multi-instance
60
+ * observability and post-call processing; the in-memory default suffices for
61
+ * single-process deployments.
62
+ */
63
+ interface SessionStore {
64
+ save(snapshot: CallSnapshot): Promise<void>;
65
+ load(callSid: string): Promise<CallSnapshot | null>;
66
+ delete(callSid: string): Promise<void>;
67
+ }
68
+ //#endregion
69
+ //#region src/session/InMemorySessionStore.d.ts
70
+ declare class InMemorySessionStore implements SessionStore {
71
+ private readonly snapshots;
72
+ private readonly maxEntries;
73
+ constructor(options?: {
74
+ maxEntries?: number;
75
+ });
76
+ save(snapshot: CallSnapshot): Promise<void>;
77
+ load(callSid: string): Promise<CallSnapshot | null>;
78
+ delete(callSid: string): Promise<void>;
79
+ /** All stored snapshots (testing/debugging). */
80
+ list(): CallSnapshot[];
81
+ }
82
+ //#endregion
83
+ export { emptyUsage as a, UsageInfo as i, SessionStore as n, TranscriptEntry as o, CallSnapshot as r, InMemorySessionStore as t };
@@ -0,0 +1,83 @@
1
+ //#region src/session/transcript.d.ts
2
+ interface TranscriptEntry {
3
+ role: 'user' | 'agent';
4
+ text: string;
5
+ /** Milliseconds since call start. */
6
+ timestampMs: number;
7
+ /** Which agent spoke / was active (multi-agent calls). */
8
+ agentId?: string;
9
+ /** The caller cut this utterance off mid-playback. */
10
+ interrupted?: boolean;
11
+ }
12
+ //#endregion
13
+ //#region src/session/usage.d.ts
14
+ /** Accumulated token consumption for a call, normalized across providers. */
15
+ interface UsageInfo {
16
+ inputTokens: number;
17
+ outputTokens: number;
18
+ totalTokens: number;
19
+ inputTokenDetails: {
20
+ textTokens: number;
21
+ audioTokens: number;
22
+ cachedTokens: number;
23
+ };
24
+ outputTokenDetails: {
25
+ textTokens: number;
26
+ audioTokens: number;
27
+ };
28
+ /** Number of model responses accounted. */
29
+ responses: number;
30
+ }
31
+ declare function emptyUsage(): UsageInfo;
32
+ //#endregion
33
+ //#region src/session/snapshot.d.ts
34
+ /** Serializable checkpoint of a call, written to the SessionStore. */
35
+ interface CallSnapshot {
36
+ callSid: string;
37
+ streamSid: string | null;
38
+ state: string;
39
+ activeAgentId: string;
40
+ transcript: TranscriptEntry[];
41
+ usage: UsageInfo;
42
+ context: Record<string, unknown>;
43
+ handoffHistory: Array<{
44
+ from: string;
45
+ to: string;
46
+ atMs: number;
47
+ }>;
48
+ /** Gemini session-resumption handle, when the provider supplies one. */
49
+ resumptionHandle?: string;
50
+ startedAtMs: number;
51
+ endedAtMs?: number;
52
+ endReason?: string;
53
+ }
54
+ //#endregion
55
+ //#region src/session/SessionStore.d.ts
56
+ /**
57
+ * Durable checkpoint store (LangGraph-checkpointer-inspired). Snapshots are
58
+ * written at call start, agent handoff, tool completion, and call end — never
59
+ * read on the audio hot path. Implement over Redis/Postgres for multi-instance
60
+ * observability and post-call processing; the in-memory default suffices for
61
+ * single-process deployments.
62
+ */
63
+ interface SessionStore {
64
+ save(snapshot: CallSnapshot): Promise<void>;
65
+ load(callSid: string): Promise<CallSnapshot | null>;
66
+ delete(callSid: string): Promise<void>;
67
+ }
68
+ //#endregion
69
+ //#region src/session/InMemorySessionStore.d.ts
70
+ declare class InMemorySessionStore implements SessionStore {
71
+ private readonly snapshots;
72
+ private readonly maxEntries;
73
+ constructor(options?: {
74
+ maxEntries?: number;
75
+ });
76
+ save(snapshot: CallSnapshot): Promise<void>;
77
+ load(callSid: string): Promise<CallSnapshot | null>;
78
+ delete(callSid: string): Promise<void>;
79
+ /** All stored snapshots (testing/debugging). */
80
+ list(): CallSnapshot[];
81
+ }
82
+ //#endregion
83
+ export { emptyUsage as a, UsageInfo as i, SessionStore as n, TranscriptEntry as o, CallSnapshot as r, InMemorySessionStore as t };
@@ -0,0 +1,29 @@
1
+ //#region src/session/InMemorySessionStore.ts
2
+ var InMemorySessionStore = class {
3
+ snapshots = /* @__PURE__ */ new Map();
4
+ maxEntries;
5
+ constructor(options = {}) {
6
+ this.maxEntries = options.maxEntries ?? 1e3;
7
+ }
8
+ async save(snapshot) {
9
+ this.snapshots.set(snapshot.callSid, structuredClone(snapshot));
10
+ while (this.snapshots.size > this.maxEntries) {
11
+ const oldest = this.snapshots.keys().next().value;
12
+ if (oldest === void 0) break;
13
+ this.snapshots.delete(oldest);
14
+ }
15
+ }
16
+ async load(callSid) {
17
+ const snapshot = this.snapshots.get(callSid);
18
+ return snapshot ? structuredClone(snapshot) : null;
19
+ }
20
+ async delete(callSid) {
21
+ this.snapshots.delete(callSid);
22
+ }
23
+ /** All stored snapshots (testing/debugging). */
24
+ list() {
25
+ return [...this.snapshots.values()].map((s) => structuredClone(s));
26
+ }
27
+ };
28
+ //#endregion
29
+ export { InMemorySessionStore as t };