@skillhq/concierge 1.5.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 (138) hide show
  1. package/README.md +91 -0
  2. package/dist/cli/program.d.ts +3 -0
  3. package/dist/cli/program.d.ts.map +1 -0
  4. package/dist/cli/program.js +46 -0
  5. package/dist/cli/program.js.map +1 -0
  6. package/dist/cli/shared.d.ts +18 -0
  7. package/dist/cli/shared.d.ts.map +1 -0
  8. package/dist/cli/shared.js +2 -0
  9. package/dist/cli/shared.js.map +1 -0
  10. package/dist/cli.d.ts +3 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +5 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/commands/call.d.ts +7 -0
  15. package/dist/commands/call.d.ts.map +1 -0
  16. package/dist/commands/call.js +409 -0
  17. package/dist/commands/call.js.map +1 -0
  18. package/dist/commands/config.d.ts +4 -0
  19. package/dist/commands/config.d.ts.map +1 -0
  20. package/dist/commands/config.js +120 -0
  21. package/dist/commands/config.js.map +1 -0
  22. package/dist/commands/find-contact.d.ts +4 -0
  23. package/dist/commands/find-contact.d.ts.map +1 -0
  24. package/dist/commands/find-contact.js +57 -0
  25. package/dist/commands/find-contact.js.map +1 -0
  26. package/dist/commands/server.d.ts +7 -0
  27. package/dist/commands/server.d.ts.map +1 -0
  28. package/dist/commands/server.js +212 -0
  29. package/dist/commands/server.js.map +1 -0
  30. package/dist/index.d.ts +4 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +3 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/lib/call/audio/mulaw.d.ts +35 -0
  35. package/dist/lib/call/audio/mulaw.d.ts.map +1 -0
  36. package/dist/lib/call/audio/mulaw.js +109 -0
  37. package/dist/lib/call/audio/mulaw.js.map +1 -0
  38. package/dist/lib/call/audio/pcm-utils.d.ts +62 -0
  39. package/dist/lib/call/audio/pcm-utils.d.ts.map +1 -0
  40. package/dist/lib/call/audio/pcm-utils.js +149 -0
  41. package/dist/lib/call/audio/pcm-utils.js.map +1 -0
  42. package/dist/lib/call/audio/resample.d.ts +34 -0
  43. package/dist/lib/call/audio/resample.d.ts.map +1 -0
  44. package/dist/lib/call/audio/resample.js +97 -0
  45. package/dist/lib/call/audio/resample.js.map +1 -0
  46. package/dist/lib/call/audio/streaming-decoder.d.ts +45 -0
  47. package/dist/lib/call/audio/streaming-decoder.d.ts.map +1 -0
  48. package/dist/lib/call/audio/streaming-decoder.js +110 -0
  49. package/dist/lib/call/audio/streaming-decoder.js.map +1 -0
  50. package/dist/lib/call/call-server.d.ts +110 -0
  51. package/dist/lib/call/call-server.d.ts.map +1 -0
  52. package/dist/lib/call/call-server.js +681 -0
  53. package/dist/lib/call/call-server.js.map +1 -0
  54. package/dist/lib/call/call-session.d.ts +133 -0
  55. package/dist/lib/call/call-session.d.ts.map +1 -0
  56. package/dist/lib/call/call-session.js +890 -0
  57. package/dist/lib/call/call-session.js.map +1 -0
  58. package/dist/lib/call/call-types.d.ts +133 -0
  59. package/dist/lib/call/call-types.d.ts.map +1 -0
  60. package/dist/lib/call/call-types.js +16 -0
  61. package/dist/lib/call/call-types.js.map +1 -0
  62. package/dist/lib/call/conversation-ai.d.ts +56 -0
  63. package/dist/lib/call/conversation-ai.d.ts.map +1 -0
  64. package/dist/lib/call/conversation-ai.js +276 -0
  65. package/dist/lib/call/conversation-ai.js.map +1 -0
  66. package/dist/lib/call/eval/codec-test.d.ts +45 -0
  67. package/dist/lib/call/eval/codec-test.d.ts.map +1 -0
  68. package/dist/lib/call/eval/codec-test.js +169 -0
  69. package/dist/lib/call/eval/codec-test.js.map +1 -0
  70. package/dist/lib/call/eval/conversation-scripts.d.ts +55 -0
  71. package/dist/lib/call/eval/conversation-scripts.d.ts.map +1 -0
  72. package/dist/lib/call/eval/conversation-scripts.js +359 -0
  73. package/dist/lib/call/eval/conversation-scripts.js.map +1 -0
  74. package/dist/lib/call/eval/eval-runner.d.ts +64 -0
  75. package/dist/lib/call/eval/eval-runner.d.ts.map +1 -0
  76. package/dist/lib/call/eval/eval-runner.js +369 -0
  77. package/dist/lib/call/eval/eval-runner.js.map +1 -0
  78. package/dist/lib/call/eval/index.d.ts +9 -0
  79. package/dist/lib/call/eval/index.d.ts.map +1 -0
  80. package/dist/lib/call/eval/index.js +9 -0
  81. package/dist/lib/call/eval/index.js.map +1 -0
  82. package/dist/lib/call/eval/integration-test-suite.d.ts +71 -0
  83. package/dist/lib/call/eval/integration-test-suite.d.ts.map +1 -0
  84. package/dist/lib/call/eval/integration-test-suite.js +519 -0
  85. package/dist/lib/call/eval/integration-test-suite.js.map +1 -0
  86. package/dist/lib/call/eval/turn-taking-test.d.ts +84 -0
  87. package/dist/lib/call/eval/turn-taking-test.d.ts.map +1 -0
  88. package/dist/lib/call/eval/turn-taking-test.js +260 -0
  89. package/dist/lib/call/eval/turn-taking-test.js.map +1 -0
  90. package/dist/lib/call/index.d.ts +12 -0
  91. package/dist/lib/call/index.d.ts.map +1 -0
  92. package/dist/lib/call/index.js +17 -0
  93. package/dist/lib/call/index.js.map +1 -0
  94. package/dist/lib/call/providers/deepgram.d.ts +81 -0
  95. package/dist/lib/call/providers/deepgram.d.ts.map +1 -0
  96. package/dist/lib/call/providers/deepgram.js +279 -0
  97. package/dist/lib/call/providers/deepgram.js.map +1 -0
  98. package/dist/lib/call/providers/elevenlabs.d.ts +78 -0
  99. package/dist/lib/call/providers/elevenlabs.d.ts.map +1 -0
  100. package/dist/lib/call/providers/elevenlabs.js +272 -0
  101. package/dist/lib/call/providers/elevenlabs.js.map +1 -0
  102. package/dist/lib/call/providers/local-deps.d.ts +18 -0
  103. package/dist/lib/call/providers/local-deps.d.ts.map +1 -0
  104. package/dist/lib/call/providers/local-deps.js +114 -0
  105. package/dist/lib/call/providers/local-deps.js.map +1 -0
  106. package/dist/lib/call/providers/twilio.d.ts +53 -0
  107. package/dist/lib/call/providers/twilio.d.ts.map +1 -0
  108. package/dist/lib/call/providers/twilio.js +173 -0
  109. package/dist/lib/call/providers/twilio.js.map +1 -0
  110. package/dist/lib/concierge-client-types.d.ts +68 -0
  111. package/dist/lib/concierge-client-types.d.ts.map +1 -0
  112. package/dist/lib/concierge-client-types.js +2 -0
  113. package/dist/lib/concierge-client-types.js.map +1 -0
  114. package/dist/lib/concierge-client.d.ts +29 -0
  115. package/dist/lib/concierge-client.d.ts.map +1 -0
  116. package/dist/lib/concierge-client.js +534 -0
  117. package/dist/lib/concierge-client.js.map +1 -0
  118. package/dist/lib/config.d.ts +9 -0
  119. package/dist/lib/config.d.ts.map +1 -0
  120. package/dist/lib/config.js +66 -0
  121. package/dist/lib/config.js.map +1 -0
  122. package/dist/lib/output.d.ts +7 -0
  123. package/dist/lib/output.d.ts.map +1 -0
  124. package/dist/lib/output.js +114 -0
  125. package/dist/lib/output.js.map +1 -0
  126. package/dist/lib/utils/contact-extractor.d.ts +12 -0
  127. package/dist/lib/utils/contact-extractor.d.ts.map +1 -0
  128. package/dist/lib/utils/contact-extractor.js +159 -0
  129. package/dist/lib/utils/contact-extractor.js.map +1 -0
  130. package/dist/lib/utils/formatters.d.ts +15 -0
  131. package/dist/lib/utils/formatters.d.ts.map +1 -0
  132. package/dist/lib/utils/formatters.js +107 -0
  133. package/dist/lib/utils/formatters.js.map +1 -0
  134. package/dist/lib/utils/url-parser.d.ts +11 -0
  135. package/dist/lib/utils/url-parser.d.ts.map +1 -0
  136. package/dist/lib/utils/url-parser.js +103 -0
  137. package/dist/lib/utils/url-parser.js.map +1 -0
  138. package/package.json +67 -0
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Eval runner for testing the voice pipeline without a real phone call
3
+ *
4
+ * Pipeline being tested:
5
+ * 1. Generate human speech audio (macOS say → PCM)
6
+ * 2. Send to Deepgram STT
7
+ * 3. Send transcript to Claude AI
8
+ * 4. Send AI response to ElevenLabs TTS
9
+ * 5. Receive µ-law audio (measure quality/duration)
10
+ */
11
+ import type { ConversationScript } from './conversation-scripts.js';
12
+ export interface EvalConfig {
13
+ anthropicApiKey: string;
14
+ deepgramApiKey: string;
15
+ elevenLabsApiKey: string;
16
+ elevenLabsVoiceId: string;
17
+ /** Directory to save results */
18
+ outputDir?: string;
19
+ /** Whether to play audio during eval */
20
+ playAudio?: boolean;
21
+ /** Whether to save audio files */
22
+ saveAudio?: boolean;
23
+ }
24
+ export interface TurnMetrics {
25
+ turnIndex: number;
26
+ humanText: string;
27
+ humanAudioDurationMs: number;
28
+ sttLatencyMs: number;
29
+ sttTranscript: string;
30
+ sttConfidence: number;
31
+ aiLatencyMs: number;
32
+ aiResponse: string;
33
+ ttsLatencyMs: number;
34
+ ttsFirstByteMs: number;
35
+ ttsAudioDurationMs: number;
36
+ totalTurnLatencyMs: number;
37
+ }
38
+ export interface EvalResult {
39
+ scriptId: string;
40
+ scriptName: string;
41
+ goal: string;
42
+ timestamp: string;
43
+ success: boolean;
44
+ error?: string;
45
+ turns: TurnMetrics[];
46
+ summary: {
47
+ totalTurns: number;
48
+ completedTurns: number;
49
+ avgSttLatencyMs: number;
50
+ avgAiLatencyMs: number;
51
+ avgTtsLatencyMs: number;
52
+ avgTotalLatencyMs: number;
53
+ conversationComplete: boolean;
54
+ };
55
+ }
56
+ /**
57
+ * Run evaluation on a single script
58
+ */
59
+ export declare function runEval(script: ConversationScript, config: EvalConfig): Promise<EvalResult>;
60
+ /**
61
+ * Run evaluation on multiple scripts
62
+ */
63
+ export declare function runEvalSuite(scripts: ConversationScript[], config: EvalConfig): Promise<EvalResult[]>;
64
+ //# sourceMappingURL=eval-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-runner.d.ts","sourceRoot":"","sources":["../../../../src/lib/call/eval/eval-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kCAAkC;IAClC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,oBAAoB,EAAE,OAAO,CAAC;KAC/B,CAAC;CACH;AAyMD;;GAEG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAsLjG;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAwB3G"}
@@ -0,0 +1,369 @@
1
+ /**
2
+ * Eval runner for testing the voice pipeline without a real phone call
3
+ *
4
+ * Pipeline being tested:
5
+ * 1. Generate human speech audio (macOS say → PCM)
6
+ * 2. Send to Deepgram STT
7
+ * 3. Send transcript to Claude AI
8
+ * 4. Send AI response to ElevenLabs TTS
9
+ * 5. Receive µ-law audio (measure quality/duration)
10
+ */
11
+ import { execSync } from 'node:child_process';
12
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
13
+ import { tmpdir } from 'node:os';
14
+ import { join } from 'node:path';
15
+ import { createClient, LiveTranscriptionEvents } from '@deepgram/sdk';
16
+ import { ConversationAI } from '../conversation-ai.js';
17
+ /**
18
+ * Generate speech audio using macOS say command
19
+ * Returns PCM audio buffer at 8kHz 16-bit mono
20
+ */
21
+ async function generateSpeechAudio(text) {
22
+ const tempAiff = join(tmpdir(), `eval_speech_${Date.now()}.aiff`);
23
+ const tempPcm = join(tmpdir(), `eval_speech_${Date.now()}.pcm`);
24
+ try {
25
+ // Generate speech with macOS say
26
+ execSync(`say -o "${tempAiff}" "${text.replace(/"/g, '\\"')}"`, { stdio: 'pipe' });
27
+ // Convert to 8kHz 16-bit PCM (same as Twilio)
28
+ execSync(`ffmpeg -y -i "${tempAiff}" -f s16le -ar 8000 -ac 1 "${tempPcm}" 2>/dev/null`, { stdio: 'pipe' });
29
+ const pcm = readFileSync(tempPcm);
30
+ const durationMs = pcm.length / 2 / 8; // 16-bit = 2 bytes per sample, 8kHz
31
+ return { pcm, durationMs };
32
+ }
33
+ finally {
34
+ try {
35
+ unlinkSync(tempAiff);
36
+ }
37
+ catch { }
38
+ try {
39
+ unlinkSync(tempPcm);
40
+ }
41
+ catch { }
42
+ }
43
+ }
44
+ /**
45
+ * Send audio to Deepgram and get transcript
46
+ */
47
+ async function transcribeAudio(pcm, apiKey) {
48
+ const startTime = Date.now();
49
+ const deepgram = createClient(apiKey);
50
+ return new Promise((resolve, reject) => {
51
+ const connection = deepgram.listen.live({
52
+ model: 'nova-2-phonecall',
53
+ language: 'en-US',
54
+ punctuate: true,
55
+ interim_results: false,
56
+ endpointing: 500,
57
+ encoding: 'linear16',
58
+ sample_rate: 8000,
59
+ channels: 1,
60
+ });
61
+ let transcript = '';
62
+ let confidence = 0;
63
+ let firstTranscriptTime = null;
64
+ connection.on(LiveTranscriptionEvents.Open, () => {
65
+ // Send audio in chunks (simulating real-time)
66
+ const CHUNK_SIZE = 320; // 20ms at 8kHz 16-bit
67
+ let offset = 0;
68
+ const sendChunk = () => {
69
+ if (offset >= pcm.length) {
70
+ // Wait a bit then close
71
+ setTimeout(() => connection.requestClose(), 1000);
72
+ return;
73
+ }
74
+ const chunk = pcm.slice(offset, offset + CHUNK_SIZE);
75
+ const ab = chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.byteLength);
76
+ connection.send(ab);
77
+ offset += CHUNK_SIZE;
78
+ setTimeout(sendChunk, 20); // Real-time pace
79
+ };
80
+ sendChunk();
81
+ });
82
+ connection.on(LiveTranscriptionEvents.Transcript, (data) => {
83
+ const text = data.channel?.alternatives?.[0]?.transcript || '';
84
+ const conf = data.channel?.alternatives?.[0]?.confidence || 0;
85
+ if (text && data.is_final) {
86
+ if (!firstTranscriptTime) {
87
+ firstTranscriptTime = Date.now();
88
+ }
89
+ transcript += `${text} `;
90
+ confidence = Math.max(confidence, conf);
91
+ }
92
+ });
93
+ connection.on(LiveTranscriptionEvents.Close, () => {
94
+ const latencyMs = (firstTranscriptTime || Date.now()) - startTime;
95
+ resolve({
96
+ transcript: transcript.trim(),
97
+ confidence,
98
+ latencyMs,
99
+ });
100
+ });
101
+ connection.on(LiveTranscriptionEvents.Error, (error) => {
102
+ reject(error);
103
+ });
104
+ // Timeout
105
+ setTimeout(() => {
106
+ reject(new Error('Deepgram timeout'));
107
+ }, 30000);
108
+ });
109
+ }
110
+ /**
111
+ * Get AI response
112
+ */
113
+ async function getAIResponse(conversationAI, humanSaid) {
114
+ const startTime = Date.now();
115
+ const response = await conversationAI.respond(humanSaid);
116
+ const latencyMs = Date.now() - startTime;
117
+ return {
118
+ response: response || '[CONVERSATION COMPLETE]',
119
+ latencyMs,
120
+ };
121
+ }
122
+ /**
123
+ * Get TTS audio from ElevenLabs
124
+ */
125
+ async function synthesizeSpeech(text, apiKey, voiceId) {
126
+ const startTime = Date.now();
127
+ let firstByteTime = null;
128
+ const response = await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${voiceId}/stream`, {
129
+ method: 'POST',
130
+ headers: {
131
+ 'Content-Type': 'application/json',
132
+ 'xi-api-key': apiKey,
133
+ },
134
+ body: JSON.stringify({
135
+ text,
136
+ model_id: 'eleven_turbo_v2',
137
+ voice_settings: { stability: 0.5, similarity_boost: 0.75 },
138
+ output_format: 'ulaw_8000',
139
+ }),
140
+ });
141
+ if (!response.ok) {
142
+ throw new Error(`ElevenLabs error: ${response.status}`);
143
+ }
144
+ const chunks = [];
145
+ const reader = response.body.getReader();
146
+ while (true) {
147
+ const { done, value } = await reader.read();
148
+ if (done)
149
+ break;
150
+ if (!firstByteTime) {
151
+ firstByteTime = Date.now();
152
+ }
153
+ chunks.push(Buffer.from(value));
154
+ }
155
+ const audio = Buffer.concat(chunks);
156
+ const latencyMs = Date.now() - startTime;
157
+ const firstByteMs = (firstByteTime || startTime) - startTime;
158
+ const durationMs = (audio.length / 8000) * 1000; // 8kHz µ-law
159
+ return { audio, latencyMs, firstByteMs, durationMs };
160
+ }
161
+ /**
162
+ * Play audio using ffmpeg + afplay (macOS)
163
+ */
164
+ function playMulawAudio(audio) {
165
+ const tempUlaw = join(tmpdir(), `eval_play_${Date.now()}.ulaw`);
166
+ const tempWav = join(tmpdir(), `eval_play_${Date.now()}.wav`);
167
+ try {
168
+ writeFileSync(tempUlaw, audio);
169
+ execSync(`ffmpeg -y -f mulaw -ar 8000 -ac 1 -i "${tempUlaw}" "${tempWav}" 2>/dev/null`, { stdio: 'pipe' });
170
+ execSync(`afplay "${tempWav}"`, { stdio: 'pipe' });
171
+ }
172
+ finally {
173
+ try {
174
+ unlinkSync(tempUlaw);
175
+ }
176
+ catch { }
177
+ try {
178
+ unlinkSync(tempWav);
179
+ }
180
+ catch { }
181
+ }
182
+ }
183
+ /**
184
+ * Run evaluation on a single script
185
+ */
186
+ export async function runEval(script, config) {
187
+ const result = {
188
+ scriptId: script.id,
189
+ scriptName: script.name,
190
+ goal: script.goal,
191
+ timestamp: new Date().toISOString(),
192
+ success: false,
193
+ turns: [],
194
+ summary: {
195
+ totalTurns: script.turns.length,
196
+ completedTurns: 0,
197
+ avgSttLatencyMs: 0,
198
+ avgAiLatencyMs: 0,
199
+ avgTtsLatencyMs: 0,
200
+ avgTotalLatencyMs: 0,
201
+ conversationComplete: false,
202
+ },
203
+ };
204
+ console.log(`\n${'='.repeat(60)}`);
205
+ console.log(`EVAL: ${script.name}`);
206
+ console.log(`Goal: ${script.goal}`);
207
+ console.log(`${'='.repeat(60)}\n`);
208
+ // Initialize conversation AI
209
+ const conversationAI = new ConversationAI({
210
+ apiKey: config.anthropicApiKey,
211
+ goal: script.goal,
212
+ context: script.context,
213
+ });
214
+ try {
215
+ // Get initial greeting
216
+ console.log('[AI] Generating greeting...');
217
+ const greetingStart = Date.now();
218
+ const greeting = await conversationAI.getGreeting();
219
+ const greetingLatency = Date.now() - greetingStart;
220
+ console.log(`[AI] Greeting (${greetingLatency}ms): "${greeting}"\n`);
221
+ // Synthesize and optionally play greeting
222
+ if (config.playAudio) {
223
+ console.log('[TTS] Speaking greeting...');
224
+ const greetingAudio = await synthesizeSpeech(greeting, config.elevenLabsApiKey, config.elevenLabsVoiceId);
225
+ playMulawAudio(greetingAudio.audio);
226
+ }
227
+ // Process each turn
228
+ for (let i = 0; i < script.turns.length; i++) {
229
+ const turn = script.turns[i];
230
+ const turnStart = Date.now();
231
+ console.log(`\n--- Turn ${i + 1}/${script.turns.length} ---`);
232
+ console.log(`[Human] "${turn.human}"`);
233
+ // Generate human speech
234
+ console.log('[Audio] Generating human speech...');
235
+ const humanAudio = await generateSpeechAudio(turn.human);
236
+ console.log(`[Audio] Human speech: ${humanAudio.durationMs.toFixed(0)}ms`);
237
+ // Optionally play human audio
238
+ if (config.playAudio) {
239
+ // Convert PCM to WAV and play
240
+ const tempPcm = join(tmpdir(), `eval_human_${Date.now()}.pcm`);
241
+ const tempWav = join(tmpdir(), `eval_human_${Date.now()}.wav`);
242
+ writeFileSync(tempPcm, humanAudio.pcm);
243
+ execSync(`ffmpeg -y -f s16le -ar 8000 -ac 1 -i "${tempPcm}" "${tempWav}" 2>/dev/null`);
244
+ execSync(`afplay "${tempWav}"`);
245
+ try {
246
+ unlinkSync(tempPcm);
247
+ }
248
+ catch { }
249
+ try {
250
+ unlinkSync(tempWav);
251
+ }
252
+ catch { }
253
+ }
254
+ // Transcribe with Deepgram
255
+ console.log('[STT] Transcribing...');
256
+ const sttResult = await transcribeAudio(humanAudio.pcm, config.deepgramApiKey);
257
+ console.log(`[STT] (${sttResult.latencyMs}ms, conf: ${sttResult.confidence.toFixed(2)}): "${sttResult.transcript}"`);
258
+ // Handle empty transcripts (e.g., "..." for hold)
259
+ if (!sttResult.transcript && turn.human === '...') {
260
+ console.log('[STT] Empty transcript (simulated hold/silence)');
261
+ // Wait and continue
262
+ if (turn.pauseMs) {
263
+ await new Promise((r) => setTimeout(r, turn.pauseMs));
264
+ }
265
+ continue;
266
+ }
267
+ // Get AI response
268
+ console.log('[AI] Generating response...');
269
+ const aiResult = await getAIResponse(conversationAI, sttResult.transcript || turn.human);
270
+ console.log(`[AI] (${aiResult.latencyMs}ms): "${aiResult.response}"`);
271
+ // Check if conversation is complete
272
+ if (conversationAI.complete) {
273
+ console.log('[AI] Conversation marked complete');
274
+ result.summary.conversationComplete = true;
275
+ }
276
+ // Synthesize TTS
277
+ console.log('[TTS] Synthesizing...');
278
+ const ttsResult = await synthesizeSpeech(aiResult.response, config.elevenLabsApiKey, config.elevenLabsVoiceId);
279
+ console.log(`[TTS] (${ttsResult.latencyMs}ms, first byte: ${ttsResult.firstByteMs}ms, audio: ${ttsResult.durationMs.toFixed(0)}ms)`);
280
+ // Optionally play TTS audio
281
+ if (config.playAudio) {
282
+ console.log('[TTS] Playing...');
283
+ playMulawAudio(ttsResult.audio);
284
+ }
285
+ // Record metrics
286
+ const totalLatency = Date.now() - turnStart;
287
+ const turnMetrics = {
288
+ turnIndex: i,
289
+ humanText: turn.human,
290
+ humanAudioDurationMs: humanAudio.durationMs,
291
+ sttLatencyMs: sttResult.latencyMs,
292
+ sttTranscript: sttResult.transcript,
293
+ sttConfidence: sttResult.confidence,
294
+ aiLatencyMs: aiResult.latencyMs,
295
+ aiResponse: aiResult.response,
296
+ ttsLatencyMs: ttsResult.latencyMs,
297
+ ttsFirstByteMs: ttsResult.firstByteMs,
298
+ ttsAudioDurationMs: ttsResult.durationMs,
299
+ totalTurnLatencyMs: totalLatency,
300
+ };
301
+ result.turns.push(turnMetrics);
302
+ result.summary.completedTurns++;
303
+ // Optional pause between turns
304
+ if (turn.pauseMs && config.playAudio) {
305
+ await new Promise((r) => setTimeout(r, turn.pauseMs));
306
+ }
307
+ // Stop if conversation is complete
308
+ if (conversationAI.complete) {
309
+ break;
310
+ }
311
+ }
312
+ // Calculate summary stats
313
+ if (result.turns.length > 0) {
314
+ result.summary.avgSttLatencyMs = result.turns.reduce((sum, t) => sum + t.sttLatencyMs, 0) / result.turns.length;
315
+ result.summary.avgAiLatencyMs = result.turns.reduce((sum, t) => sum + t.aiLatencyMs, 0) / result.turns.length;
316
+ result.summary.avgTtsLatencyMs = result.turns.reduce((sum, t) => sum + t.ttsLatencyMs, 0) / result.turns.length;
317
+ result.summary.avgTotalLatencyMs =
318
+ result.turns.reduce((sum, t) => sum + t.totalTurnLatencyMs, 0) / result.turns.length;
319
+ }
320
+ result.success = true;
321
+ }
322
+ catch (error) {
323
+ result.error = error instanceof Error ? error.message : String(error);
324
+ console.error(`\n[ERROR] ${result.error}`);
325
+ }
326
+ // Print summary
327
+ console.log(`\n${'='.repeat(60)}`);
328
+ console.log(`RESULT: ${result.success ? 'SUCCESS' : 'FAILED'}`);
329
+ console.log(`Turns completed: ${result.summary.completedTurns}/${result.summary.totalTurns}`);
330
+ console.log(`Avg STT latency: ${result.summary.avgSttLatencyMs.toFixed(0)}ms`);
331
+ console.log(`Avg AI latency: ${result.summary.avgAiLatencyMs.toFixed(0)}ms`);
332
+ console.log(`Avg TTS latency: ${result.summary.avgTtsLatencyMs.toFixed(0)}ms`);
333
+ console.log(`Avg total latency: ${result.summary.avgTotalLatencyMs.toFixed(0)}ms`);
334
+ console.log(`${'='.repeat(60)}\n`);
335
+ // Save results if output dir specified
336
+ if (config.outputDir) {
337
+ if (!existsSync(config.outputDir)) {
338
+ mkdirSync(config.outputDir, { recursive: true });
339
+ }
340
+ const resultFile = join(config.outputDir, `${script.id}_${Date.now()}.json`);
341
+ writeFileSync(resultFile, JSON.stringify(result, null, 2));
342
+ console.log(`Results saved to: ${resultFile}`);
343
+ }
344
+ return result;
345
+ }
346
+ /**
347
+ * Run evaluation on multiple scripts
348
+ */
349
+ export async function runEvalSuite(scripts, config) {
350
+ const results = [];
351
+ console.log(`\n${'#'.repeat(60)}`);
352
+ console.log(`EVAL SUITE: ${scripts.length} scripts`);
353
+ console.log(`${'#'.repeat(60)}\n`);
354
+ for (const script of scripts) {
355
+ const result = await runEval(script, config);
356
+ results.push(result);
357
+ }
358
+ // Print suite summary
359
+ const successful = results.filter((r) => r.success).length;
360
+ const avgLatency = results.reduce((sum, r) => sum + r.summary.avgTotalLatencyMs, 0) / results.length;
361
+ console.log(`\n${'#'.repeat(60)}`);
362
+ console.log(`SUITE SUMMARY`);
363
+ console.log(`${'#'.repeat(60)}`);
364
+ console.log(`Scripts: ${successful}/${scripts.length} successful`);
365
+ console.log(`Avg latency across all scripts: ${avgLatency.toFixed(0)}ms`);
366
+ console.log(`${'#'.repeat(60)}\n`);
367
+ return results;
368
+ }
369
+ //# sourceMappingURL=eval-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-runner.js","sourceRoot":"","sources":["../../../../src/lib/call/eval/eval-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Voice Pipeline Evaluation Module
3
+ */
4
+ export * from './codec-test.js';
5
+ export * from './conversation-scripts.js';
6
+ export * from './eval-runner.js';
7
+ export * from './integration-test-suite.js';
8
+ export * from './turn-taking-test.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/call/eval/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Voice Pipeline Evaluation Module
3
+ */
4
+ export * from './codec-test.js';
5
+ export * from './conversation-scripts.js';
6
+ export * from './eval-runner.js';
7
+ export * from './integration-test-suite.js';
8
+ export * from './turn-taking-test.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/call/eval/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Comprehensive Integration Test Suite
3
+ *
4
+ * Combines all tests into a single suite:
5
+ * 1. Codec tests - verify audio pipeline
6
+ * 2. Turn-taking tests - verify debounce logic
7
+ * 3. Conversation flow tests - verify AI behavior
8
+ * 4. End-to-end pipeline tests - full flow without phone
9
+ */
10
+ import { type TurnTakingTestResult } from './turn-taking-test.js';
11
+ export interface IntegrationTestConfig {
12
+ anthropicApiKey: string;
13
+ deepgramApiKey: string;
14
+ elevenLabsApiKey: string;
15
+ elevenLabsVoiceId: string;
16
+ outputDir?: string;
17
+ }
18
+ export interface TestSuiteResult {
19
+ timestamp: string;
20
+ duration: number;
21
+ overallPassed: boolean;
22
+ codec: {
23
+ passed: boolean;
24
+ tests: number;
25
+ failures: string[];
26
+ };
27
+ turnTaking: {
28
+ passed: boolean;
29
+ total: number;
30
+ passedCount: number;
31
+ failures: TurnTakingTestResult[];
32
+ };
33
+ conversationFlow: {
34
+ passed: boolean;
35
+ tests: number;
36
+ failures: string[];
37
+ };
38
+ aiDisclosure: {
39
+ passed: boolean;
40
+ greeting: string;
41
+ containsDisclosure: boolean;
42
+ hasWrongRole: boolean;
43
+ issues: string[];
44
+ };
45
+ roleConsistency: {
46
+ passed: boolean;
47
+ issues: string[];
48
+ roleReversalPhrases: string[];
49
+ };
50
+ voiceFormatting: {
51
+ passed: boolean;
52
+ issues: string[];
53
+ };
54
+ noRepetition: {
55
+ passed: boolean;
56
+ issues: string[];
57
+ };
58
+ conciseness: {
59
+ passed: boolean;
60
+ issues: string[];
61
+ responses: string[];
62
+ avgWordsPerResponse: number;
63
+ maxWordsPerResponse: number;
64
+ enthusiasmCount: number;
65
+ };
66
+ }
67
+ /**
68
+ * Run the complete integration test suite
69
+ */
70
+ export declare function runIntegrationTestSuite(config: IntegrationTestConfig): Promise<TestSuiteResult>;
71
+ //# sourceMappingURL=integration-test-suite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-test-suite.d.ts","sourceRoot":"","sources":["../../../../src/lib/call/eval/integration-test-suite.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EAAyB,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAMzF,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE;QACL,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,UAAU,EAAE;QACV,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,oBAAoB,EAAE,CAAC;KAClC,CAAC;IACF,gBAAgB,EAAE;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,YAAY,EAAE;QACZ,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,YAAY,EAAE,OAAO,CAAC;QACtB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,eAAe,EAAE;QACf,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,mBAAmB,EAAE,MAAM,EAAE,CAAC;KAC/B,CAAC;IACF,eAAe,EAAE;QACf,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,YAAY,EAAE;QACZ,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,WAAW,EAAE;QACX,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AA0bD;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CA2MrG"}