@telnyx/voice-agent-tester 0.4.7 → 1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.0](https://github.com/team-telnyx/voice-agent-tester/compare/v0.4.7...v1.0.0) (2026-03-20)
4
+
5
+ ### ⚠ BREAKING CHANGES
6
+
7
+ * The tool is now focused exclusively on **Telnyx vs Vapi** comparisons. ElevenLabs, Retell, and Livetok provider support has been removed.
8
+ * The `--branch-id` CLI option has been removed (was ElevenLabs-specific).
9
+ * The `--provider` flag now only accepts `vapi`.
10
+ * Application configs for `elevenlabs.yaml` and `livetok.yaml` have been removed.
11
+
12
+ ### Features
13
+
14
+ * Focused Telnyx vs Vapi comparison tool for v1.0.0 release ([#33](https://github.com/team-telnyx/voice-agent-tester/pull/33))
15
+ * Streamlined CLI — fewer flags, simpler setup for Vapi-to-Telnyx benchmarking
16
+ * Rewritten README centered on the Vapi vs Telnyx comparison workflow
17
+
3
18
  ## [0.4.7](https://github.com/team-telnyx/voice-agent-tester/compare/v0.4.6...v0.4.7) (2026-03-19)
4
19
 
5
20
  ## [0.4.6](https://github.com/team-telnyx/voice-agent-tester/compare/v0.4.5...v0.4.6) (2026-03-18)
package/README.md CHANGED
@@ -3,33 +3,9 @@
3
3
  [![CI](https://github.com/team-telnyx/voice-agent-tester/actions/workflows/ci.yml/badge.svg)](https://github.com/team-telnyx/voice-agent-tester/actions/workflows/ci.yml)
4
4
  [![npm version](https://img.shields.io/npm/v/@telnyx/voice-agent-tester.svg)](https://www.npmjs.com/package/@telnyx/voice-agent-tester)
5
5
 
6
- Automated benchmarking CLI for voice AI agents. Import your assistant from any provider, run identical test scenarios on both platforms, and get a side-by-side latency comparison.
6
+ Automated benchmarking CLI that compares **Vapi** voice agents against **Telnyx**. Import your Vapi assistant into Telnyx, run the same test scenario on both platforms, and get a side-by-side latency report.
7
7
 
8
- Supports **Telnyx**, **ElevenLabs**, **Vapi**, and **Retell**.
9
-
10
- ## Compare Your Voice Agent Against Telnyx
11
-
12
- The tool imports your assistant from an external provider into Telnyx, then runs the **same scenario** on both platforms and produces a head-to-head latency report:
13
-
14
- ```
15
- 📈 Latency Comparison (elapsed_time):
16
- --------------------------------------------------------------------------------
17
- Metric vapi Telnyx Delta Winner
18
- --------------------------------------------------------------------------------
19
- Response #1 (wait_for_voice_elapsed_time) 2849ms 1552ms -1297ms (-45.5%) 🏆 Telnyx
20
- Response #2 (wait_for_voice_elapsed_time) 3307ms 704ms -2603ms (-78.7%) 🏆 Telnyx
21
- --------------------------------------------------------------------------------
22
-
23
- 📊 Overall Summary:
24
- Compared 2 matched response latencies
25
- vapi total latency: 6156ms
26
- Telnyx total latency: 2256ms
27
- Difference: -3900ms (-63.3%)
28
-
29
- 🏆 Result: Telnyx is faster overall
30
- ```
31
-
32
- ### Vapi vs Telnyx
8
+ ## Quick Start
33
9
 
34
10
  ```bash
35
11
  npx @telnyx/voice-agent-tester@latest \
@@ -42,49 +18,40 @@ npx @telnyx/voice-agent-tester@latest \
42
18
  --provider-import-id <VAPI_ASSISTANT_ID>
43
19
  ```
44
20
 
45
- ### ElevenLabs vs Telnyx
21
+ ## How It Works
46
22
 
47
- ```bash
48
- npx @telnyx/voice-agent-tester@latest \
49
- -a applications/telnyx.yaml \
50
- -s scenarios/appointment.yaml \
51
- --provider elevenlabs \
52
- --api-key <TELNYX_API_KEY> \
53
- --provider-api-key <ELEVENLABS_API_KEY> \
54
- --provider-import-id <ELEVENLABS_AGENT_ID>
55
- ```
56
-
57
- ### Retell vs Telnyx
23
+ 1. **Import** — Your Vapi assistant is imported into Telnyx via the Import API
24
+ 2. **Phase 1: Vapi Direct** — Runs the test scenario on Vapi's native widget
25
+ 3. **Phase 2: Telnyx Import** — Runs the same scenario on the Telnyx-imported assistant
26
+ 4. **Report** — Produces a side-by-side comparison with latency deltas and a winner per response
58
27
 
59
- ```bash
60
- npx @telnyx/voice-agent-tester@latest \
61
- -a applications/telnyx.yaml \
62
- -s scenarios/appointment.yaml \
63
- --provider retell \
64
- --api-key <TELNYX_API_KEY> \
65
- --provider-api-key <RETELL_API_KEY> \
66
- --provider-import-id <RETELL_AGENT_ID>
67
28
  ```
29
+ 📊 COMPARISON: VAPI vs TELNYX
30
+ ================================================================================
68
31
 
69
- ### How Comparison Works
32
+ Average response latency (2 matched responses):
70
33
 
71
- 1. **Import** — The assistant is imported from the external provider into Telnyx
72
- 2. **Phase 1: Provider Direct** — Runs the scenario on the provider's native widget
73
- 3. **Phase 2: Telnyx Import** — Runs the same scenario on the Telnyx-imported assistant
74
- 4. **Report** — Produces a side-by-side comparison with latency delta and winner per response
34
+ vapi 2849ms
35
+ Telnyx 1552ms
36
+ Difference -1297ms (-45.5%)
75
37
 
76
- ### Provider-Specific Keys
38
+ 🏆 Telnyx is 45.5% faster
77
39
 
78
- Some providers need an extra key to load their demo widget. If not passed via CLI, the tool prompts with instructions.
40
+ ================================================================================
41
+ ```
79
42
 
80
- | Provider | Flag | Required? | How to find it |
81
- |----------|------|-----------|----------------|
82
- | Vapi | `--share-key` | Yes | Dashboard → select assistant → click 🔗 link icon next to the assistant ID |
83
- | ElevenLabs | `--branch-id` | No | Dashboard → Agents → select agent → Publish dropdown → "Copy shareable link" |
43
+ ## Where to Find Your Keys
84
44
 
85
- ### Import Only (Skip Comparison)
45
+ | Key | Where to find it |
46
+ |-----|------------------|
47
+ | `--api-key` | [Telnyx Portal → API Keys](https://portal.telnyx.com/#/app/api-keys) |
48
+ | `--provider-api-key` | [Vapi Dashboard → Organization Settings](https://dashboard.vapi.ai/org/api-keys) |
49
+ | `--provider-import-id` | Vapi Dashboard → select your assistant → copy the assistant ID |
50
+ | `--share-key` | Vapi Dashboard → select assistant → click 🔗 link icon next to the assistant ID |
86
51
 
87
- To import without running the provider benchmark:
52
+ ## Import + Benchmark (Skip Comparison)
53
+
54
+ Import your Vapi assistant into Telnyx and benchmark the imported Telnyx assistant only (skips the Vapi direct phase):
88
55
 
89
56
  ```bash
90
57
  npx @telnyx/voice-agent-tester@latest \
@@ -97,51 +64,17 @@ npx @telnyx/voice-agent-tester@latest \
97
64
  --provider-import-id <VAPI_ASSISTANT_ID>
98
65
  ```
99
66
 
100
- ## Quick Start
67
+ > **Note:** `--no-compare` still runs the benchmark against the imported Telnyx assistant. It only skips the Vapi direct benchmark phase and the side-by-side comparison report.
101
68
 
102
- Run directly with npx (no installation required):
69
+ ## Test Telnyx Directly
103
70
 
104
- ```bash
105
- npx @telnyx/voice-agent-tester@latest \
106
- -a applications/telnyx.yaml \
107
- -s scenarios/appointment.yaml \
108
- --assistant-id <YOUR_ASSISTANT_ID>
109
- ```
110
-
111
- Or install globally:
112
-
113
- ```bash
114
- npm install -g @telnyx/voice-agent-tester
115
- voice-agent-tester -a applications/telnyx.yaml -s scenarios/appointment.yaml --assistant-id <YOUR_ASSISTANT_ID>
116
- ```
117
-
118
- ## Provider Examples
119
-
120
- ### Telnyx
71
+ Benchmark a Telnyx assistant without comparison:
121
72
 
122
73
  ```bash
123
74
  npx @telnyx/voice-agent-tester@latest \
124
75
  -a applications/telnyx.yaml \
125
76
  -s scenarios/appointment.yaml \
126
- --assistant-id <ASSISTANT_ID>
127
- ```
128
-
129
- ### ElevenLabs
130
-
131
- ```bash
132
- npx @telnyx/voice-agent-tester@latest \
133
- -a applications/elevenlabs.yaml \
134
- -s scenarios/appointment.yaml \
135
- --assistant-id <AGENT_ID>
136
- ```
137
-
138
- ### Vapi
139
-
140
- ```bash
141
- npx @telnyx/voice-agent-tester@latest \
142
- -a applications/vapi.yaml \
143
- -s scenarios/appointment.yaml \
144
- --assistant-id <ASSISTANT_ID>
77
+ --assistant-id <TELNYX_ASSISTANT_ID>
145
78
  ```
146
79
 
147
80
  ## CLI Reference
@@ -150,87 +83,28 @@ npx @telnyx/voice-agent-tester@latest \
150
83
  |--------|---------|-------------|
151
84
  | `-a, --applications` | required | Application config path(s) or folder |
152
85
  | `-s, --scenarios` | required | Scenario config path(s) or folder |
153
- | `--assistant-id` | | Telnyx or provider assistant ID |
86
+ | `--provider` | | Set to `vapi` for comparison mode |
154
87
  | `--api-key` | | Telnyx API key |
155
- | `--provider` | | Import from provider (`vapi`, `elevenlabs`, `retell`) |
156
- | `--provider-api-key` | | External provider API key |
157
- | `--provider-import-id` | | Provider assistant/agent ID to import |
88
+ | `--provider-api-key` | | Vapi API key |
89
+ | `--provider-import-id` | | Vapi assistant ID to import |
158
90
  | `--share-key` | | Vapi share key for comparison mode |
159
- | `--branch-id` | | ElevenLabs branch ID (optional) |
160
- | `--compare` | `true` | Run provider direct + Telnyx import benchmarks |
161
- | `--no-compare` | | Skip provider direct benchmark |
91
+ | `--assistant-id` | | Telnyx assistant ID (direct mode) |
92
+ | `--compare` | `true` | Run both Vapi + Telnyx benchmarks |
93
+ | `--no-compare` | | Skip Vapi direct benchmark and comparison (import + Telnyx benchmark only) |
162
94
  | `-d, --debug` | `false` | Detailed timeout diagnostics |
163
95
  | `-v, --verbose` | `false` | Show browser console logs |
164
96
  | `--headless` | `true` | Run browser in headless mode |
165
- | `--repeat` | `1` | Repetitions per app+scenario combination |
97
+ | `--repeat` | `1` | Repetitions per test combination |
166
98
  | `-c, --concurrency` | `1` | Parallel test runs |
167
99
  | `-r, --report` | | CSV report output path |
168
100
  | `-p, --params` | | URL template params (`key=value,key2=value2`) |
169
101
  | `--retries` | `0` | Retry failed runs |
170
- | `--application-tags` | | Filter applications by tags |
171
- | `--scenario-tags` | | Filter scenarios by tags |
172
102
  | `--record` | `false` | Record video+audio (webm) |
173
- | `--audio-url` | | URL to audio file played as input during run |
103
+ | `--audio-url` | | URL to audio file played as mic input |
174
104
  | `--audio-volume` | `1.0` | Audio input volume (0.0–1.0) |
175
105
  | `--assets-server` | `http://localhost:3333` | Assets server URL |
176
-
177
- ## Bundled Configs
178
-
179
- **Applications:**
180
-
181
- | Config | Provider |
182
- |--------|----------|
183
- | `applications/telnyx.yaml` | Telnyx AI Widget |
184
- | `applications/elevenlabs.yaml` | ElevenLabs |
185
- | `applications/vapi.yaml` | Vapi |
186
- | `applications/retell.yaml` | Retell |
187
-
188
- **Scenarios:**
189
-
190
- | Config | Description |
191
- |--------|-------------|
192
- | `scenarios/appointment.yaml` | Appointment booking test |
193
- | `scenarios/appointment_with_noise.yaml` | Appointment with background crowd noise |
194
-
195
- ## Background Noise Testing
196
-
197
- Test how voice agents perform with ambient noise by using pre-mixed audio files:
198
-
199
- ```bash
200
- # With background noise
201
- npx @telnyx/voice-agent-tester@latest \
202
- -a applications/telnyx.yaml \
203
- -s scenarios/appointment_with_noise.yaml \
204
- --assistant-id <ASSISTANT_ID>
205
-
206
- # Without noise (same assistant, compare results)
207
- npx @telnyx/voice-agent-tester@latest \
208
- -a applications/telnyx.yaml \
209
- -s scenarios/appointment.yaml \
210
- --assistant-id <ASSISTANT_ID>
211
- ```
212
-
213
- ### Custom Audio Input
214
-
215
- Play any audio file from a URL as microphone input throughout the benchmark:
216
-
217
- ```bash
218
- npx @telnyx/voice-agent-tester@latest \
219
- -a applications/telnyx.yaml \
220
- -s scenarios/appointment.yaml \
221
- --assistant-id <ASSISTANT_ID> \
222
- --audio-url "https://example.com/test-audio.mp3" \
223
- --audio-volume 0.8
224
- ```
225
-
226
- ### Audio Assets
227
-
228
- | File | Description |
229
- |------|-------------|
230
- | `hello_make_an_appointment.mp3` | Clean appointment request |
231
- | `hello_make_an_appointment_with_noise.mp3` | Appointment request + crowd noise |
232
- | `appointment_data.mp3` | Clean appointment details |
233
- | `appointment_data_with_noise.mp3` | Appointment details + crowd noise |
106
+ | `--application-tags` | | Filter applications by tags |
107
+ | `--scenario-tags` | | Filter scenarios by tags |
234
108
 
235
109
  ## Scenario Configuration
236
110
 
@@ -269,15 +143,56 @@ steps:
269
143
  | `screenshot` | Capture a screenshot |
270
144
  | `listen` | Record agent audio, transcribe, and evaluate |
271
145
 
272
- ## Debugging
146
+ ## Background Noise Testing
147
+
148
+ Test how voice agents perform with ambient noise:
149
+
150
+ ```bash
151
+ npx @telnyx/voice-agent-tester@latest \
152
+ -a applications/telnyx.yaml \
153
+ -s scenarios/appointment_with_noise.yaml \
154
+ --provider vapi \
155
+ --share-key <VAPI_SHARE_KEY> \
156
+ --api-key <TELNYX_API_KEY> \
157
+ --provider-api-key <VAPI_API_KEY> \
158
+ --provider-import-id <VAPI_ASSISTANT_ID>
159
+ ```
160
+
161
+ ### Custom Audio Input
273
162
 
274
- If benchmarks fail or time out, use `--debug` for detailed diagnostics including audio monitor state, WebRTC connection info, and RTP stats:
163
+ Play any audio file from a URL as microphone input throughout the benchmark:
275
164
 
276
165
  ```bash
277
166
  npx @telnyx/voice-agent-tester@latest \
278
167
  -a applications/telnyx.yaml \
279
168
  -s scenarios/appointment.yaml \
280
169
  --assistant-id <ASSISTANT_ID> \
170
+ --audio-url "https://example.com/test-audio.mp3" \
171
+ --audio-volume 0.8
172
+ ```
173
+
174
+ ### Audio Assets
175
+
176
+ | File | Description |
177
+ |------|-------------|
178
+ | `hello_make_an_appointment.mp3` | Clean appointment request |
179
+ | `hello_make_an_appointment_with_noise.mp3` | Appointment request + crowd noise |
180
+ | `appointment_data.mp3` | Clean appointment details |
181
+ | `appointment_data_with_noise.mp3` | Appointment details + crowd noise |
182
+
183
+ ## Debugging
184
+
185
+ Use `--debug` for detailed diagnostics including audio monitor state, WebRTC connections, and RTP stats:
186
+
187
+ ```bash
188
+ npx @telnyx/voice-agent-tester@latest \
189
+ -a applications/telnyx.yaml \
190
+ -s scenarios/appointment.yaml \
191
+ --provider vapi \
192
+ --share-key <VAPI_SHARE_KEY> \
193
+ --api-key <TELNYX_API_KEY> \
194
+ --provider-api-key <VAPI_API_KEY> \
195
+ --provider-import-id <VAPI_ASSISTANT_ID> \
281
196
  --debug
282
197
  ```
283
198
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telnyx/voice-agent-tester",
3
- "version": "0.4.7",
3
+ "version": "1.0.0",
4
4
  "description": "A command-line tool to test voice agents using Puppeteer",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/index.js CHANGED
@@ -89,7 +89,6 @@ function substituteUrlParams(url, params) {
89
89
 
90
90
  /**
91
91
  * Get the list of missing provider-specific parameters required for comparison mode.
92
- * Each provider has its own set of required params for the direct widget benchmark.
93
92
  *
94
93
  * @param {Object} argv - Parsed CLI arguments
95
94
  * @returns {Array<{key: string, flag: string, description: string}>} Missing params
@@ -97,21 +96,13 @@ function substituteUrlParams(url, params) {
97
96
  function getCompareRequiredParams(argv) {
98
97
  const missing = [];
99
98
 
100
- switch (argv.provider) {
101
- case 'vapi':
102
- if (!argv.shareKey) {
103
- missing.push({
104
- key: 'shareKey',
105
- flag: '--share-key',
106
- description: 'Vapi share key',
107
- hint: 'In the Vapi Dashboard, select your assistant, then click the link icon (🔗) next to the assistant ID at the top. This copies the demo link containing your share key.'
108
- });
109
- }
110
- break;
111
- case 'elevenlabs':
112
- // branchId is optional — the talk-to URL works with just agent_id
113
- break;
114
- // retell and others: no extra params needed yet
99
+ if (!argv.shareKey) {
100
+ missing.push({
101
+ key: 'shareKey',
102
+ flag: '--share-key',
103
+ description: 'Vapi share key',
104
+ hint: 'In the Vapi Dashboard, select your assistant, then click the link icon (🔗) next to the assistant ID at the top. This copies the demo link containing your share key.'
105
+ });
115
106
  }
116
107
 
117
108
  return missing;
@@ -124,28 +115,7 @@ function getCompareRequiredParams(argv) {
124
115
  * @returns {Object} Template params to merge into provider params
125
116
  */
126
117
  function getCompareTemplateParams(argv) {
127
- switch (argv.provider) {
128
- case 'vapi':
129
- return { shareKey: argv.shareKey };
130
- default:
131
- return {};
132
- }
133
- }
134
-
135
- /**
136
- * Get provider-specific extra query parameters to append to the comparison URL.
137
- * Unlike template params, these are appended as-is (not substituted into {{...}} placeholders).
138
- *
139
- * @param {Object} argv - Parsed CLI arguments
140
- * @returns {Object} Key-value pairs to append as query parameters
141
- */
142
- function getCompareExtraQueryParams(argv) {
143
- switch (argv.provider) {
144
- case 'elevenlabs':
145
- return argv.branchId ? { branch_id: argv.branchId } : {};
146
- default:
147
- return {};
148
- }
118
+ return { shareKey: argv.shareKey };
149
119
  }
150
120
 
151
121
  // Helper function to load and validate application config
@@ -298,15 +268,11 @@ const argv = yargs(hideBin(process.argv))
298
268
  })
299
269
  .option('share-key', {
300
270
  type: 'string',
301
- description: 'Vapi share key for direct widget testing (required for comparison mode with --provider vapi)'
302
- })
303
- .option('branch-id', {
304
- type: 'string',
305
- description: 'ElevenLabs branch ID for direct widget testing (optional, appended to demo URL when provided)'
271
+ description: 'Vapi share key for direct widget testing (required for comparison mode)'
306
272
  })
307
273
  .option('assistant-id', {
308
274
  type: 'string',
309
- description: 'Assistant/agent ID for direct benchmarking (works with all providers)'
275
+ description: 'Telnyx assistant ID for direct benchmarking (without comparison)'
310
276
  })
311
277
  .option('debug', {
312
278
  alias: 'd',
@@ -718,17 +684,6 @@ async function main() {
718
684
  }
719
685
 
720
686
  const providerApp = loadApplicationConfig(providerAppPath, providerParams);
721
-
722
- // Append optional extra query parameters (e.g. branch_id for ElevenLabs)
723
- const extraQueryParams = getCompareExtraQueryParams(argv);
724
- if (providerApp.url && Object.keys(extraQueryParams).length > 0) {
725
- const url = new URL(providerApp.url);
726
- for (const [key, value] of Object.entries(extraQueryParams)) {
727
- url.searchParams.set(key, value);
728
- }
729
- providerApp.url = url.toString();
730
- }
731
-
732
687
  const providerApplications = [providerApp];
733
688
 
734
689
  const providerResults = await runBenchmark({
@@ -15,7 +15,7 @@ const TELNYX_IMPORT_ENDPOINT = `${TELNYX_BASE_URL}/ai/assistants/import`;
15
15
  const TELNYX_ASSISTANTS_ENDPOINT = `${TELNYX_BASE_URL}/ai/assistants`;
16
16
 
17
17
  // Supported providers
18
- const SUPPORTED_PROVIDERS = ['vapi', 'elevenlabs', 'retell'];
18
+ const SUPPORTED_PROVIDERS = ['vapi'];
19
19
 
20
20
  // Default widget settings for benchmarking
21
21
  const DEFAULT_WIDGET_SETTINGS = {
@@ -1,18 +0,0 @@
1
- url: "https://elevenlabs.io/app/talk-to?agent_id={{assistantId}}"
2
- tags:
3
- - provider
4
- - elevenlabs
5
- steps:
6
- - action: wait_for_element
7
- selector: "text=Call AI agent"
8
- - action: sleep
9
- time: 3000
10
- - action: click
11
- selector: "text=Call AI agent"
12
- # ElevenLabs shows a terms consent dialog — click "Agree" to proceed
13
- - action: wait_for_element
14
- selector: "text=Agree"
15
- - action: click
16
- selector: "text=Agree"
17
- - action: sleep
18
- time: 2000
@@ -1,16 +0,0 @@
1
- url: "https://rti.livetok.io/demo/index.html"
2
- tags:
3
- - default
4
- - basic
5
- steps:
6
- - action: fill
7
- selector: "input[type='password']"
8
- text: "GOOGLE_API_KEY HERE"
9
- # - action: select
10
- # selector: "#model"
11
- # value: "gemini-2.5-flash-preview-native-audio-dialog"
12
- # - action: fill
13
- # selector: "#tools"
14
- # text: "[]"
15
- - action: click
16
- selector: "#start"