@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.
- package/README.md +91 -0
- package/dist/cli/program.d.ts +3 -0
- package/dist/cli/program.d.ts.map +1 -0
- package/dist/cli/program.js +46 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/shared.d.ts +18 -0
- package/dist/cli/shared.d.ts.map +1 -0
- package/dist/cli/shared.js +2 -0
- package/dist/cli/shared.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/call.d.ts +7 -0
- package/dist/commands/call.d.ts.map +1 -0
- package/dist/commands/call.js +409 -0
- package/dist/commands/call.js.map +1 -0
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +120 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/find-contact.d.ts +4 -0
- package/dist/commands/find-contact.d.ts.map +1 -0
- package/dist/commands/find-contact.js +57 -0
- package/dist/commands/find-contact.js.map +1 -0
- package/dist/commands/server.d.ts +7 -0
- package/dist/commands/server.d.ts.map +1 -0
- package/dist/commands/server.js +212 -0
- package/dist/commands/server.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/call/audio/mulaw.d.ts +35 -0
- package/dist/lib/call/audio/mulaw.d.ts.map +1 -0
- package/dist/lib/call/audio/mulaw.js +109 -0
- package/dist/lib/call/audio/mulaw.js.map +1 -0
- package/dist/lib/call/audio/pcm-utils.d.ts +62 -0
- package/dist/lib/call/audio/pcm-utils.d.ts.map +1 -0
- package/dist/lib/call/audio/pcm-utils.js +149 -0
- package/dist/lib/call/audio/pcm-utils.js.map +1 -0
- package/dist/lib/call/audio/resample.d.ts +34 -0
- package/dist/lib/call/audio/resample.d.ts.map +1 -0
- package/dist/lib/call/audio/resample.js +97 -0
- package/dist/lib/call/audio/resample.js.map +1 -0
- package/dist/lib/call/audio/streaming-decoder.d.ts +45 -0
- package/dist/lib/call/audio/streaming-decoder.d.ts.map +1 -0
- package/dist/lib/call/audio/streaming-decoder.js +110 -0
- package/dist/lib/call/audio/streaming-decoder.js.map +1 -0
- package/dist/lib/call/call-server.d.ts +110 -0
- package/dist/lib/call/call-server.d.ts.map +1 -0
- package/dist/lib/call/call-server.js +681 -0
- package/dist/lib/call/call-server.js.map +1 -0
- package/dist/lib/call/call-session.d.ts +133 -0
- package/dist/lib/call/call-session.d.ts.map +1 -0
- package/dist/lib/call/call-session.js +890 -0
- package/dist/lib/call/call-session.js.map +1 -0
- package/dist/lib/call/call-types.d.ts +133 -0
- package/dist/lib/call/call-types.d.ts.map +1 -0
- package/dist/lib/call/call-types.js +16 -0
- package/dist/lib/call/call-types.js.map +1 -0
- package/dist/lib/call/conversation-ai.d.ts +56 -0
- package/dist/lib/call/conversation-ai.d.ts.map +1 -0
- package/dist/lib/call/conversation-ai.js +276 -0
- package/dist/lib/call/conversation-ai.js.map +1 -0
- package/dist/lib/call/eval/codec-test.d.ts +45 -0
- package/dist/lib/call/eval/codec-test.d.ts.map +1 -0
- package/dist/lib/call/eval/codec-test.js +169 -0
- package/dist/lib/call/eval/codec-test.js.map +1 -0
- package/dist/lib/call/eval/conversation-scripts.d.ts +55 -0
- package/dist/lib/call/eval/conversation-scripts.d.ts.map +1 -0
- package/dist/lib/call/eval/conversation-scripts.js +359 -0
- package/dist/lib/call/eval/conversation-scripts.js.map +1 -0
- package/dist/lib/call/eval/eval-runner.d.ts +64 -0
- package/dist/lib/call/eval/eval-runner.d.ts.map +1 -0
- package/dist/lib/call/eval/eval-runner.js +369 -0
- package/dist/lib/call/eval/eval-runner.js.map +1 -0
- package/dist/lib/call/eval/index.d.ts +9 -0
- package/dist/lib/call/eval/index.d.ts.map +1 -0
- package/dist/lib/call/eval/index.js +9 -0
- package/dist/lib/call/eval/index.js.map +1 -0
- package/dist/lib/call/eval/integration-test-suite.d.ts +71 -0
- package/dist/lib/call/eval/integration-test-suite.d.ts.map +1 -0
- package/dist/lib/call/eval/integration-test-suite.js +519 -0
- package/dist/lib/call/eval/integration-test-suite.js.map +1 -0
- package/dist/lib/call/eval/turn-taking-test.d.ts +84 -0
- package/dist/lib/call/eval/turn-taking-test.d.ts.map +1 -0
- package/dist/lib/call/eval/turn-taking-test.js +260 -0
- package/dist/lib/call/eval/turn-taking-test.js.map +1 -0
- package/dist/lib/call/index.d.ts +12 -0
- package/dist/lib/call/index.d.ts.map +1 -0
- package/dist/lib/call/index.js +17 -0
- package/dist/lib/call/index.js.map +1 -0
- package/dist/lib/call/providers/deepgram.d.ts +81 -0
- package/dist/lib/call/providers/deepgram.d.ts.map +1 -0
- package/dist/lib/call/providers/deepgram.js +279 -0
- package/dist/lib/call/providers/deepgram.js.map +1 -0
- package/dist/lib/call/providers/elevenlabs.d.ts +78 -0
- package/dist/lib/call/providers/elevenlabs.d.ts.map +1 -0
- package/dist/lib/call/providers/elevenlabs.js +272 -0
- package/dist/lib/call/providers/elevenlabs.js.map +1 -0
- package/dist/lib/call/providers/local-deps.d.ts +18 -0
- package/dist/lib/call/providers/local-deps.d.ts.map +1 -0
- package/dist/lib/call/providers/local-deps.js +114 -0
- package/dist/lib/call/providers/local-deps.js.map +1 -0
- package/dist/lib/call/providers/twilio.d.ts +53 -0
- package/dist/lib/call/providers/twilio.d.ts.map +1 -0
- package/dist/lib/call/providers/twilio.js +173 -0
- package/dist/lib/call/providers/twilio.js.map +1 -0
- package/dist/lib/concierge-client-types.d.ts +68 -0
- package/dist/lib/concierge-client-types.d.ts.map +1 -0
- package/dist/lib/concierge-client-types.js +2 -0
- package/dist/lib/concierge-client-types.js.map +1 -0
- package/dist/lib/concierge-client.d.ts +29 -0
- package/dist/lib/concierge-client.d.ts.map +1 -0
- package/dist/lib/concierge-client.js +534 -0
- package/dist/lib/concierge-client.js.map +1 -0
- package/dist/lib/config.d.ts +9 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +66 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/output.d.ts +7 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +114 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/utils/contact-extractor.d.ts +12 -0
- package/dist/lib/utils/contact-extractor.d.ts.map +1 -0
- package/dist/lib/utils/contact-extractor.js +159 -0
- package/dist/lib/utils/contact-extractor.js.map +1 -0
- package/dist/lib/utils/formatters.d.ts +15 -0
- package/dist/lib/utils/formatters.d.ts.map +1 -0
- package/dist/lib/utils/formatters.js +107 -0
- package/dist/lib/utils/formatters.js.map +1 -0
- package/dist/lib/utils/url-parser.d.ts +11 -0
- package/dist/lib/utils/url-parser.d.ts.map +1 -0
- package/dist/lib/utils/url-parser.js +103 -0
- package/dist/lib/utils/url-parser.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codec Integration Test
|
|
3
|
+
*
|
|
4
|
+
* Verifies that the audio pipeline produces valid µ-law audio:
|
|
5
|
+
* 1. ElevenLabs TTS → MP3 (always, regardless of output_format)
|
|
6
|
+
* 2. ffmpeg streaming decoder → µ-law 8kHz
|
|
7
|
+
* 3. Validate µ-law format and duration
|
|
8
|
+
*
|
|
9
|
+
* This catches regressions like:
|
|
10
|
+
* - Wrong codec (sending MP3 as µ-law)
|
|
11
|
+
* - Sample rate mismatches
|
|
12
|
+
* - Truncated audio
|
|
13
|
+
*/
|
|
14
|
+
import { createStreamingDecoder } from '../audio/streaming-decoder.js';
|
|
15
|
+
/**
|
|
16
|
+
* Validate that data looks like valid µ-law audio
|
|
17
|
+
* µ-law has specific characteristics:
|
|
18
|
+
* - Single byte per sample
|
|
19
|
+
* - Values distributed across 0-255 range (compressed)
|
|
20
|
+
* - 8kHz sample rate
|
|
21
|
+
*/
|
|
22
|
+
export function validateMulawFormat(data) {
|
|
23
|
+
if (data.length < 100) {
|
|
24
|
+
return { valid: false, reason: 'Audio too short (< 100 bytes)' };
|
|
25
|
+
}
|
|
26
|
+
// Check byte value distribution
|
|
27
|
+
const histogram = new Array(256).fill(0);
|
|
28
|
+
for (let i = 0; i < data.length; i++) {
|
|
29
|
+
histogram[data[i]]++;
|
|
30
|
+
}
|
|
31
|
+
// Count how many different byte values are used
|
|
32
|
+
const uniqueValues = histogram.filter((count) => count > 0).length;
|
|
33
|
+
// µ-law should have a wide distribution of values (voice uses many levels)
|
|
34
|
+
// Raw MP3 data has very different patterns (frame headers, sync words)
|
|
35
|
+
if (uniqueValues < 20) {
|
|
36
|
+
return { valid: false, reason: `Too few unique byte values (${uniqueValues}), likely wrong format` };
|
|
37
|
+
}
|
|
38
|
+
// Check for MP3 signature in first bytes (common mistake)
|
|
39
|
+
// MP3 frame sync: 0xFF followed by 0xFB, 0xFA, or 0xF3 (not 0xFF which is µ-law silence)
|
|
40
|
+
const header = data.slice(0, 4);
|
|
41
|
+
if (header[0] === 0xff && header[1] !== 0xff && (header[1] & 0xe0) === 0xe0) {
|
|
42
|
+
return { valid: false, reason: `Data starts with MP3 frame header (0xFF ${header[1].toString(16).toUpperCase()})` };
|
|
43
|
+
}
|
|
44
|
+
if (header.slice(0, 3).toString() === 'ID3') {
|
|
45
|
+
return { valid: false, reason: 'Data starts with ID3 tag (MP3 metadata)' };
|
|
46
|
+
}
|
|
47
|
+
// µ-law silence is typically 0x7F or 0xFF
|
|
48
|
+
// Check that we have some non-silence samples
|
|
49
|
+
const silenceCount = histogram[0x7f] + histogram[0xff];
|
|
50
|
+
const silenceRatio = silenceCount / data.length;
|
|
51
|
+
if (silenceRatio > 0.95) {
|
|
52
|
+
return { valid: false, reason: 'Audio is >95% silence' };
|
|
53
|
+
}
|
|
54
|
+
return { valid: true };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Test the streaming decoder with known MP3 input
|
|
58
|
+
*/
|
|
59
|
+
export async function testStreamingDecoder(mp3Data, expectedDurationMs, toleranceMs = 500) {
|
|
60
|
+
const result = {
|
|
61
|
+
success: false,
|
|
62
|
+
inputFormat: 'mp3',
|
|
63
|
+
inputSize: mp3Data.length,
|
|
64
|
+
outputFormat: 'mulaw_8000',
|
|
65
|
+
outputSize: 0,
|
|
66
|
+
expectedDurationMs,
|
|
67
|
+
actualDurationMs: 0,
|
|
68
|
+
durationMatchesExpected: false,
|
|
69
|
+
isValidMulaw: false,
|
|
70
|
+
errors: [],
|
|
71
|
+
};
|
|
72
|
+
// Check input is actually MP3
|
|
73
|
+
const header = mp3Data.slice(0, 4);
|
|
74
|
+
const isMP3 = (header[0] === 0xff && (header[1] & 0xe0) === 0xe0) || header.slice(0, 3).toString() === 'ID3';
|
|
75
|
+
if (!isMP3) {
|
|
76
|
+
result.errors.push('Input does not appear to be MP3 format');
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
// Create decoder
|
|
80
|
+
const decoder = createStreamingDecoder();
|
|
81
|
+
const mulawChunks = [];
|
|
82
|
+
decoder.on('data', (mulaw) => {
|
|
83
|
+
mulawChunks.push(mulaw);
|
|
84
|
+
});
|
|
85
|
+
const decoderDone = new Promise((resolve, reject) => {
|
|
86
|
+
decoder.on('close', resolve);
|
|
87
|
+
decoder.on('error', reject);
|
|
88
|
+
});
|
|
89
|
+
// Start decoder and feed MP3 data
|
|
90
|
+
decoder.start();
|
|
91
|
+
// Feed in chunks (simulating streaming)
|
|
92
|
+
const CHUNK_SIZE = 1024;
|
|
93
|
+
for (let i = 0; i < mp3Data.length; i += CHUNK_SIZE) {
|
|
94
|
+
const chunk = mp3Data.slice(i, i + CHUNK_SIZE);
|
|
95
|
+
decoder.write(chunk);
|
|
96
|
+
// Small delay to simulate streaming
|
|
97
|
+
await new Promise((r) => setTimeout(r, 1));
|
|
98
|
+
}
|
|
99
|
+
decoder.end();
|
|
100
|
+
await decoderDone;
|
|
101
|
+
// Analyze output
|
|
102
|
+
const mulawData = Buffer.concat(mulawChunks);
|
|
103
|
+
result.outputSize = mulawData.length;
|
|
104
|
+
result.actualDurationMs = (mulawData.length / 8000) * 1000; // 8kHz
|
|
105
|
+
// Validate µ-law format
|
|
106
|
+
const validation = validateMulawFormat(mulawData);
|
|
107
|
+
result.isValidMulaw = validation.valid;
|
|
108
|
+
if (!validation.valid) {
|
|
109
|
+
result.errors.push(`Invalid µ-law: ${validation.reason}`);
|
|
110
|
+
}
|
|
111
|
+
// Check duration matches expected
|
|
112
|
+
const durationDiff = Math.abs(result.actualDurationMs - expectedDurationMs);
|
|
113
|
+
result.durationMatchesExpected = durationDiff <= toleranceMs;
|
|
114
|
+
if (!result.durationMatchesExpected) {
|
|
115
|
+
result.errors.push(`Duration mismatch: expected ${expectedDurationMs}ms, got ${result.actualDurationMs.toFixed(0)}ms (diff: ${durationDiff.toFixed(0)}ms)`);
|
|
116
|
+
}
|
|
117
|
+
result.success = result.isValidMulaw && result.durationMatchesExpected;
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Test the full TTS pipeline
|
|
122
|
+
*/
|
|
123
|
+
export async function testTTSPipeline(text, apiKey, voiceId) {
|
|
124
|
+
// Estimate expected duration (~150ms per word)
|
|
125
|
+
const wordCount = text.split(/\s+/).length;
|
|
126
|
+
const expectedDurationMs = wordCount * 150 + 500; // +500ms buffer
|
|
127
|
+
// Get TTS audio
|
|
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: 'mp3_44100_128',
|
|
139
|
+
}),
|
|
140
|
+
});
|
|
141
|
+
if (!response.ok) {
|
|
142
|
+
const error = await response.text();
|
|
143
|
+
return {
|
|
144
|
+
success: false,
|
|
145
|
+
inputFormat: 'error',
|
|
146
|
+
inputSize: 0,
|
|
147
|
+
outputFormat: 'error',
|
|
148
|
+
outputSize: 0,
|
|
149
|
+
expectedDurationMs,
|
|
150
|
+
actualDurationMs: 0,
|
|
151
|
+
durationMatchesExpected: false,
|
|
152
|
+
isValidMulaw: false,
|
|
153
|
+
errors: [`ElevenLabs API error: ${response.status} - ${error}`],
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
// Collect MP3 data
|
|
157
|
+
const chunks = [];
|
|
158
|
+
const reader = response.body.getReader();
|
|
159
|
+
while (true) {
|
|
160
|
+
const { done, value } = await reader.read();
|
|
161
|
+
if (done)
|
|
162
|
+
break;
|
|
163
|
+
chunks.push(Buffer.from(value));
|
|
164
|
+
}
|
|
165
|
+
const mp3Data = Buffer.concat(chunks);
|
|
166
|
+
// Test the decoder
|
|
167
|
+
return testStreamingDecoder(mp3Data, expectedDurationMs, 2000); // 2s tolerance
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=codec-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec-test.js","sourceRoot":"","sources":["../../../../src/lib/call/eval/codec-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation scripts for testing the voice pipeline
|
|
3
|
+
* Each script simulates a realistic phone conversation
|
|
4
|
+
*/
|
|
5
|
+
export interface ConversationTurn {
|
|
6
|
+
/** What the human says */
|
|
7
|
+
human: string;
|
|
8
|
+
/** Expected AI behavior (for validation) */
|
|
9
|
+
expectedBehavior?: string;
|
|
10
|
+
/** How long to wait before next turn (simulates thinking) */
|
|
11
|
+
pauseMs?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface ConversationScript {
|
|
14
|
+
/** Unique ID for the script */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Human-readable name */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Goal passed to the AI */
|
|
19
|
+
goal: string;
|
|
20
|
+
/** Context passed to the AI */
|
|
21
|
+
context?: string;
|
|
22
|
+
/** The conversation turns */
|
|
23
|
+
turns: ConversationTurn[];
|
|
24
|
+
/** Expected outcome */
|
|
25
|
+
expectedOutcome: 'success' | 'partial' | 'failure';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Hotel booking scenarios
|
|
29
|
+
*/
|
|
30
|
+
export declare const HOTEL_SCRIPTS: ConversationScript[];
|
|
31
|
+
/**
|
|
32
|
+
* Restaurant reservation scenarios
|
|
33
|
+
*/
|
|
34
|
+
export declare const RESTAURANT_SCRIPTS: ConversationScript[];
|
|
35
|
+
/**
|
|
36
|
+
* Hold queue scenarios - automated systems before human answers
|
|
37
|
+
*/
|
|
38
|
+
export declare const HOLD_QUEUE_SCRIPTS: ConversationScript[];
|
|
39
|
+
/**
|
|
40
|
+
* Challenging conversation scenarios (edge cases)
|
|
41
|
+
*/
|
|
42
|
+
export declare const EDGE_CASE_SCRIPTS: ConversationScript[];
|
|
43
|
+
/**
|
|
44
|
+
* All scripts combined
|
|
45
|
+
*/
|
|
46
|
+
export declare const ALL_SCRIPTS: ConversationScript[];
|
|
47
|
+
/**
|
|
48
|
+
* Get a script by ID
|
|
49
|
+
*/
|
|
50
|
+
export declare function getScript(id: string): ConversationScript | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Get scripts by category
|
|
53
|
+
*/
|
|
54
|
+
export declare function getScriptsByCategory(category: 'hotel' | 'restaurant' | 'hold' | 'edge'): ConversationScript[];
|
|
55
|
+
//# sourceMappingURL=conversation-scripts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-scripts.d.ts","sourceRoot":"","sources":["../../../../src/lib/call/eval/conversation-scripts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,uBAAuB;IACvB,eAAe,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;CACpD;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,kBAAkB,EAwG7C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAAkB,EAwClD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAAkB,EAyGlD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,kBAAkB,EAuEjD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,kBAAkB,EAK3C,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEpE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,kBAAkB,EAAE,CAW7G"}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation scripts for testing the voice pipeline
|
|
3
|
+
* Each script simulates a realistic phone conversation
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Hotel booking scenarios
|
|
7
|
+
*/
|
|
8
|
+
export const HOTEL_SCRIPTS = [
|
|
9
|
+
{
|
|
10
|
+
id: 'hotel-direct-booking-success',
|
|
11
|
+
name: 'Hotel Direct Booking - Successful Discount',
|
|
12
|
+
goal: 'Book a room directly and negotiate a 10% discount off the Booking.com rate',
|
|
13
|
+
context: 'Hotel: Haus im Tal, Munich. Room: Downtown Cozy. Dates: March 12-14. Booking.com rate: $393 for 2 nights. Guest: John Smith.',
|
|
14
|
+
expectedOutcome: 'success',
|
|
15
|
+
turns: [
|
|
16
|
+
{ human: 'Hello, Haus im Tal, how can I help you?' },
|
|
17
|
+
{ human: 'Yes, we have availability for those dates. What rate did you see online?', pauseMs: 500 },
|
|
18
|
+
{
|
|
19
|
+
human: 'I see. Well, we do try to match or beat online rates for direct bookings. Let me check what I can offer.',
|
|
20
|
+
pauseMs: 1000,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
human: 'I can offer you three hundred and fifty dollars for the two nights. Would that work for you?',
|
|
24
|
+
pauseMs: 500,
|
|
25
|
+
},
|
|
26
|
+
{ human: 'Great. I just need a name and email to confirm the booking.', pauseMs: 300 },
|
|
27
|
+
{ human: "Perfect, I've got John Smith. And the email?", pauseMs: 300 },
|
|
28
|
+
{
|
|
29
|
+
human: "Alright, you're all set. Confirmation number is H-T-four-five-six-seven. See you on March twelfth.",
|
|
30
|
+
pauseMs: 500,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'hotel-direct-booking-no-discount',
|
|
36
|
+
name: 'Hotel Direct Booking - No Discount Available',
|
|
37
|
+
goal: 'Book a room directly and negotiate a 10% discount off the Booking.com rate',
|
|
38
|
+
context: 'Hotel: Grand Plaza. Room: Standard Queen. Dates: Dec 31 - Jan 2. Booking.com rate: $500 for 2 nights.',
|
|
39
|
+
expectedOutcome: 'partial',
|
|
40
|
+
turns: [
|
|
41
|
+
{ human: 'Grand Plaza, this is Michael speaking.' },
|
|
42
|
+
{
|
|
43
|
+
human: "I'm sorry, but those dates are during our peak season. We actually can't offer any discounts for New Year's Eve.",
|
|
44
|
+
pauseMs: 500,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
human: "No, I'm afraid the online rate is already our best rate for those dates. It's our busiest time of year.",
|
|
48
|
+
pauseMs: 800,
|
|
49
|
+
},
|
|
50
|
+
{ human: 'I understand. Would you still like to proceed with the booking at the regular rate?', pauseMs: 500 },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'hotel-direct-booking-premium-link-flow',
|
|
55
|
+
name: 'Hotel Direct Booking - Premium Link + Email Spelling',
|
|
56
|
+
goal: 'Book directly, get a better direct rate, and provide email for a payment link',
|
|
57
|
+
context: 'Hotel: Haus im Tal, Munich. Room: Downtown Cozy. Dates: March 12-14. Booking.com rate: $393 for 2 nights. Guest: Derek Rein. Email: alexanderderekrein@gmail.com.',
|
|
58
|
+
expectedOutcome: 'success',
|
|
59
|
+
turns: [
|
|
60
|
+
{ human: 'Sure.' },
|
|
61
|
+
{ human: 'Yes.' },
|
|
62
|
+
{ human: 'Yes.' },
|
|
63
|
+
{ human: 'I need to email you a premium link. Does that work?', pauseMs: 400 },
|
|
64
|
+
{ human: 'Can you spell out the email again?', pauseMs: 400 },
|
|
65
|
+
{ human: 'Okay. Perfect.', pauseMs: 300 },
|
|
66
|
+
{ human: 'Yes.', pauseMs: 300 },
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: 'hotel-no-availability',
|
|
71
|
+
name: 'Hotel Direct Booking - No Availability',
|
|
72
|
+
goal: 'Book a room directly for March 15-17',
|
|
73
|
+
context: 'Hotel: Beach Resort. Room: Ocean View Suite.',
|
|
74
|
+
expectedOutcome: 'failure',
|
|
75
|
+
turns: [
|
|
76
|
+
{ human: 'Beach Resort, good afternoon.' },
|
|
77
|
+
{ human: "I'm sorry, but we're completely booked for those dates. There's a conference in town.", pauseMs: 500 },
|
|
78
|
+
{ human: 'The earliest availability I have is March twentieth. Would that work instead?', pauseMs: 800 },
|
|
79
|
+
{ human: 'I understand. Would you like me to put you on a waitlist in case of cancellations?', pauseMs: 500 },
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: 'hotel-quick-agreement',
|
|
84
|
+
name: 'Hotel Quick Agreement - Test Role Consistency',
|
|
85
|
+
goal: 'Book a room directly and get a confirmation number',
|
|
86
|
+
context: 'Hotel: Haus im Tal, Munich. Room: Downtown Cozy. Dates: March 12-14. Customer: Derek Rein. Email: derek@example.com. Phone: 555-123-4567.',
|
|
87
|
+
expectedOutcome: 'success',
|
|
88
|
+
turns: [
|
|
89
|
+
{ human: 'Hello, Haus im Tal.' },
|
|
90
|
+
{ human: 'Mhmm.', pauseMs: 500 },
|
|
91
|
+
{ human: 'Not sure. What did you have in mind?', pauseMs: 800 },
|
|
92
|
+
{ human: 'Yeah. Sure.', pauseMs: 500 },
|
|
93
|
+
{ human: 'Yes.', pauseMs: 300 },
|
|
94
|
+
{ human: 'Yes.', pauseMs: 300 },
|
|
95
|
+
{
|
|
96
|
+
human: 'The confirmation number is H-T-seven-eight-nine-zero. I have your email as derek at example dot com.',
|
|
97
|
+
pauseMs: 500,
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
// This test specifically checks that the AI:
|
|
101
|
+
// 1. Stays in the caller/customer role throughout
|
|
102
|
+
// 2. Asks the hotel for a confirmation number
|
|
103
|
+
// 3. Provides the customer email for confirmations
|
|
104
|
+
// 4. Doesn't switch to hotel employee phrases like "Does this look correct to you?"
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
/**
|
|
108
|
+
* Restaurant reservation scenarios
|
|
109
|
+
*/
|
|
110
|
+
export const RESTAURANT_SCRIPTS = [
|
|
111
|
+
{
|
|
112
|
+
id: 'restaurant-reservation-success',
|
|
113
|
+
name: 'Restaurant Reservation - Success',
|
|
114
|
+
goal: 'Make a dinner reservation for 4 people',
|
|
115
|
+
context: 'Restaurant: Chez Marie. Date: Saturday at 7pm. Party size: 4. Name: Sarah Johnson.',
|
|
116
|
+
expectedOutcome: 'success',
|
|
117
|
+
turns: [
|
|
118
|
+
{ human: 'Chez Marie, how may I help you?' },
|
|
119
|
+
{
|
|
120
|
+
human: 'Saturday evening for four? Let me check... Yes, we have seven and eight thirty available.',
|
|
121
|
+
pauseMs: 800,
|
|
122
|
+
},
|
|
123
|
+
{ human: 'Seven oclock it is. And the name for the reservation?', pauseMs: 300 },
|
|
124
|
+
{ human: 'Sarah Johnson, party of four, Saturday at seven. Is there anything else?', pauseMs: 300 },
|
|
125
|
+
{ human: 'Perfect. We look forward to seeing you Saturday. Goodbye.', pauseMs: 300 },
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: 'restaurant-dietary-requirements',
|
|
130
|
+
name: 'Restaurant with Dietary Requirements',
|
|
131
|
+
goal: 'Make a reservation and confirm they can accommodate dietary restrictions',
|
|
132
|
+
context: 'Restaurant: Italian Bistro. Date: Friday 6:30pm. Party: 2. Requirements: One person is vegan, one has gluten allergy.',
|
|
133
|
+
expectedOutcome: 'success',
|
|
134
|
+
turns: [
|
|
135
|
+
{ human: 'Italian Bistro, good evening.' },
|
|
136
|
+
{
|
|
137
|
+
human: 'Friday at six thirty for two? Yes, that should be fine. Did you have any special requests?',
|
|
138
|
+
pauseMs: 500,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
human: "Absolutely, we have several vegan pasta options and all our dishes can be made gluten-free. I'll make a note on the reservation.",
|
|
142
|
+
pauseMs: 800,
|
|
143
|
+
},
|
|
144
|
+
{ human: 'And what name should I put this under?', pauseMs: 300 },
|
|
145
|
+
{ human: 'All set. See you Friday at six thirty.', pauseMs: 300 },
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
];
|
|
149
|
+
/**
|
|
150
|
+
* Hold queue scenarios - automated systems before human answers
|
|
151
|
+
*/
|
|
152
|
+
export const HOLD_QUEUE_SCRIPTS = [
|
|
153
|
+
{
|
|
154
|
+
id: 'hotel-ivr-queue',
|
|
155
|
+
name: 'Hotel IVR + Hold Queue',
|
|
156
|
+
goal: 'Book a hotel room for March 15-17',
|
|
157
|
+
context: 'Hotel: Marriott Downtown. Customer: John Smith.',
|
|
158
|
+
expectedOutcome: 'success',
|
|
159
|
+
turns: [
|
|
160
|
+
{
|
|
161
|
+
human: 'Thank you for calling Marriott Downtown. Your call is important to us. Please hold for the next available representative.',
|
|
162
|
+
pauseMs: 500,
|
|
163
|
+
},
|
|
164
|
+
{ human: '...', pauseMs: 2000 }, // Hold music
|
|
165
|
+
{ human: 'Thank you for holding. Your estimated wait time is two minutes.', pauseMs: 500 },
|
|
166
|
+
{ human: '...', pauseMs: 3000 }, // More hold music
|
|
167
|
+
{ human: 'Thank you for your patience. This is Sarah, how may I assist you today?', pauseMs: 500 },
|
|
168
|
+
{
|
|
169
|
+
human: 'Sure, let me check availability for March fifteenth through seventeenth. One moment please.',
|
|
170
|
+
pauseMs: 1000,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
human: 'Yes, we have a king room available for those dates at two hundred forty nine per night.',
|
|
174
|
+
pauseMs: 500,
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
human: 'Perfect, I have that booked for John Smith. You will receive a confirmation email shortly.',
|
|
178
|
+
pauseMs: 300,
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: 'restaurant-busy-hold',
|
|
184
|
+
name: 'Busy Restaurant Hold',
|
|
185
|
+
goal: 'Make a dinner reservation for 4 people on Saturday at 7pm',
|
|
186
|
+
context: 'Restaurant: The Italian Place. Party size: 4. Customer: Jane Doe.',
|
|
187
|
+
expectedOutcome: 'success',
|
|
188
|
+
turns: [
|
|
189
|
+
{ human: 'The Italian Place, please hold.', pauseMs: 200 },
|
|
190
|
+
{ human: '...', pauseMs: 4000 }, // Long hold
|
|
191
|
+
{ human: 'Sorry about that wait, we are very busy tonight. How can I help?', pauseMs: 500 },
|
|
192
|
+
{ human: 'Saturday at seven for four people? Let me check... yes we can do that. Name?', pauseMs: 500 },
|
|
193
|
+
{ human: 'Jane Doe, party of four, Saturday seven pm. Got it. See you then!', pauseMs: 300 },
|
|
194
|
+
],
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: 'hotel-full-ivr',
|
|
198
|
+
name: 'Hotel Full IVR Menu',
|
|
199
|
+
goal: 'Book a room',
|
|
200
|
+
context: 'Hotel: Hilton Garden Inn. Customer: Bob Wilson.',
|
|
201
|
+
expectedOutcome: 'success',
|
|
202
|
+
turns: [
|
|
203
|
+
{
|
|
204
|
+
human: 'Thank you for calling Hilton Garden Inn. For reservations, press 1. For an existing reservation, press 2. For the front desk, press 3. Or stay on the line to speak with an operator.',
|
|
205
|
+
pauseMs: 500,
|
|
206
|
+
},
|
|
207
|
+
{ human: '...', pauseMs: 1500 }, // Waiting
|
|
208
|
+
{ human: 'Connecting you to reservations. Please hold.', pauseMs: 500 },
|
|
209
|
+
{ human: '...', pauseMs: 2000 }, // Hold music
|
|
210
|
+
{ human: 'Reservations, this is Mike. How can I help you?', pauseMs: 500 },
|
|
211
|
+
{ human: 'What dates are you looking at?', pauseMs: 300 },
|
|
212
|
+
{ human: 'Let me see what we have... yes, we have availability. Would you like to proceed?', pauseMs: 500 },
|
|
213
|
+
{ human: 'Great, booking confirmed for Bob Wilson.', pauseMs: 300 },
|
|
214
|
+
],
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
id: 'callback-option',
|
|
218
|
+
name: 'Callback Option Offered',
|
|
219
|
+
goal: 'Book a hotel room',
|
|
220
|
+
context: 'Hotel: Best Western. Customer: Alice Brown.',
|
|
221
|
+
expectedOutcome: 'success',
|
|
222
|
+
turns: [
|
|
223
|
+
{
|
|
224
|
+
human: 'Thank you for calling Best Western. All of our agents are currently busy. Your estimated wait time is fifteen minutes. Press 1 to receive a callback, or stay on the line.',
|
|
225
|
+
pauseMs: 500,
|
|
226
|
+
},
|
|
227
|
+
{ human: '...', pauseMs: 3000 }, // Waiting on hold
|
|
228
|
+
{ human: 'Thank you for holding. You are next in queue.', pauseMs: 500 },
|
|
229
|
+
{ human: '...', pauseMs: 1500 },
|
|
230
|
+
{ human: 'Best Western reservations, this is Tom. Sorry for the wait. How can I help?', pauseMs: 500 },
|
|
231
|
+
{ human: 'Sure, what dates do you need?', pauseMs: 300 },
|
|
232
|
+
{ human: 'Got it. I can book that for you right now. Name on the reservation?', pauseMs: 500 },
|
|
233
|
+
{ human: 'Alice Brown. All set, confirmation number is BW twelve thirty four.', pauseMs: 300 },
|
|
234
|
+
],
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
id: 'transferred-call',
|
|
238
|
+
name: 'Call Gets Transferred',
|
|
239
|
+
goal: 'Ask about room rates',
|
|
240
|
+
context: 'Hotel: Holiday Inn Express.',
|
|
241
|
+
expectedOutcome: 'success',
|
|
242
|
+
turns: [
|
|
243
|
+
{ human: 'Holiday Inn Express, front desk.', pauseMs: 300 },
|
|
244
|
+
{
|
|
245
|
+
human: 'Oh, for rates you will need to speak with reservations. Let me transfer you. One moment.',
|
|
246
|
+
pauseMs: 500,
|
|
247
|
+
},
|
|
248
|
+
{ human: '...', pauseMs: 2000 }, // Transfer hold
|
|
249
|
+
{ human: 'Reservations, this is Linda.', pauseMs: 300 },
|
|
250
|
+
{ human: 'Our standard room is one twenty nine per night, and the suite is one seventy nine.', pauseMs: 500 },
|
|
251
|
+
{ human: 'Is there anything else I can help you with?', pauseMs: 300 },
|
|
252
|
+
],
|
|
253
|
+
},
|
|
254
|
+
];
|
|
255
|
+
/**
|
|
256
|
+
* Challenging conversation scenarios (edge cases)
|
|
257
|
+
*/
|
|
258
|
+
export const EDGE_CASE_SCRIPTS = [
|
|
259
|
+
{
|
|
260
|
+
id: 'hold-please',
|
|
261
|
+
name: 'Put on Hold Mid-Conversation',
|
|
262
|
+
goal: 'Book a hotel room',
|
|
263
|
+
context: 'Hotel: Test Hotel. Dates: Any available.',
|
|
264
|
+
expectedOutcome: 'success',
|
|
265
|
+
turns: [
|
|
266
|
+
{ human: 'Test Hotel, how can I help?' },
|
|
267
|
+
{ human: 'Sure, let me check on that. Can you hold for just a moment?', pauseMs: 500 },
|
|
268
|
+
{ human: '...', pauseMs: 3000 }, // Hold
|
|
269
|
+
{ human: 'Thanks for holding. Yes, we have rooms available. Would you like to book?', pauseMs: 500 },
|
|
270
|
+
{ human: "Great, you're all set.", pauseMs: 300 },
|
|
271
|
+
],
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
id: 'background-noise',
|
|
275
|
+
name: 'Noisy Background',
|
|
276
|
+
goal: 'Get business hours',
|
|
277
|
+
context: 'Business: Local Shop',
|
|
278
|
+
expectedOutcome: 'success',
|
|
279
|
+
turns: [
|
|
280
|
+
{ human: "Hello? Sorry, it's a bit loud here. Can you speak up?", pauseMs: 500 },
|
|
281
|
+
{
|
|
282
|
+
human: "Business hours? We're open nine to five Monday through Friday, and ten to three on Saturdays.",
|
|
283
|
+
pauseMs: 800,
|
|
284
|
+
},
|
|
285
|
+
{ human: 'Yes, nine to five weekdays. Anything else?', pauseMs: 300 },
|
|
286
|
+
],
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
id: 'unclear-response',
|
|
290
|
+
name: 'Unclear/Mumbled Response',
|
|
291
|
+
goal: 'Confirm a reservation',
|
|
292
|
+
context: 'Confirmation number: ABC123',
|
|
293
|
+
expectedOutcome: 'partial',
|
|
294
|
+
turns: [
|
|
295
|
+
{ human: 'Hmm... let me see... uh... what was the name again?', pauseMs: 1000 },
|
|
296
|
+
{ human: 'Ah yes... mmhmm... I think I found it... or maybe not...', pauseMs: 1500 },
|
|
297
|
+
{ human: 'Actually, could you give me the confirmation number?', pauseMs: 500 },
|
|
298
|
+
{ human: 'Got it. Yes, your reservation is confirmed.', pauseMs: 300 },
|
|
299
|
+
],
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: 'interruption',
|
|
303
|
+
name: 'Speaker Gets Interrupted',
|
|
304
|
+
goal: 'Ask about pricing',
|
|
305
|
+
context: 'Service: Car rental',
|
|
306
|
+
expectedOutcome: 'success',
|
|
307
|
+
turns: [
|
|
308
|
+
{ human: 'Car rentals, how can I—hold on one second—sorry about that, how can I help?', pauseMs: 500 },
|
|
309
|
+
{
|
|
310
|
+
human: 'Daily rates start at forty-nine ninety-nine for a compact, or—wait, let me transfer you to—actually no, I can help. What type of car?',
|
|
311
|
+
pauseMs: 800,
|
|
312
|
+
},
|
|
313
|
+
{ human: 'A midsize is seventy-nine per day. Need any other info?', pauseMs: 300 },
|
|
314
|
+
],
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
id: 'rapid-speech',
|
|
318
|
+
name: 'Fast Talker',
|
|
319
|
+
goal: 'Get store address',
|
|
320
|
+
context: 'Store: Electronics Plus',
|
|
321
|
+
expectedOutcome: 'success',
|
|
322
|
+
turns: [
|
|
323
|
+
{ human: 'ElectronicsPlushowareyoutodayhowcanIhelpyou?', pauseMs: 200 },
|
|
324
|
+
{ human: 'Addressisonetwothreemainstreetdowntownnexttothecoffeeshopcantopennintosixyougotit?', pauseMs: 200 },
|
|
325
|
+
{ human: 'Yeponetwothreemainstreetseeyousoon!', pauseMs: 200 },
|
|
326
|
+
],
|
|
327
|
+
},
|
|
328
|
+
];
|
|
329
|
+
/**
|
|
330
|
+
* All scripts combined
|
|
331
|
+
*/
|
|
332
|
+
export const ALL_SCRIPTS = [
|
|
333
|
+
...HOTEL_SCRIPTS,
|
|
334
|
+
...RESTAURANT_SCRIPTS,
|
|
335
|
+
...HOLD_QUEUE_SCRIPTS,
|
|
336
|
+
...EDGE_CASE_SCRIPTS,
|
|
337
|
+
];
|
|
338
|
+
/**
|
|
339
|
+
* Get a script by ID
|
|
340
|
+
*/
|
|
341
|
+
export function getScript(id) {
|
|
342
|
+
return ALL_SCRIPTS.find((s) => s.id === id);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Get scripts by category
|
|
346
|
+
*/
|
|
347
|
+
export function getScriptsByCategory(category) {
|
|
348
|
+
switch (category) {
|
|
349
|
+
case 'hotel':
|
|
350
|
+
return HOTEL_SCRIPTS;
|
|
351
|
+
case 'restaurant':
|
|
352
|
+
return RESTAURANT_SCRIPTS;
|
|
353
|
+
case 'hold':
|
|
354
|
+
return HOLD_QUEUE_SCRIPTS;
|
|
355
|
+
case 'edge':
|
|
356
|
+
return EDGE_CASE_SCRIPTS;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
//# sourceMappingURL=conversation-scripts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-scripts.js","sourceRoot":"","sources":["../../../../src/lib/call/eval/conversation-scripts.ts"],"names":[],"mappings":"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"}
|