retell-cli 1.1.0 → 1.2.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 (2) hide show
  1. package/dist/index.js +889 -290
  2. package/package.json +17 -9
package/dist/index.js CHANGED
@@ -114,11 +114,9 @@ function saveConfig(config) {
114
114
  }
115
115
  const configPath = getConfigPath();
116
116
  try {
117
- (0, import_fs.writeFileSync)(
118
- configPath,
119
- JSON.stringify(validatedConfig, null, 2),
120
- { encoding: "utf-8" }
121
- );
117
+ (0, import_fs.writeFileSync)(configPath, JSON.stringify(validatedConfig, null, 2), {
118
+ encoding: "utf-8"
119
+ });
122
120
  (0, import_fs.chmodSync)(configPath, CONFIG_FILE_PERMISSIONS);
123
121
  } catch (error) {
124
122
  throw new ConfigError(
@@ -240,16 +238,28 @@ function handleSdkError(error) {
240
238
  outputError("Rate limit exceeded. Please try again later.", "RATE_LIMIT");
241
239
  }
242
240
  if (error instanceof import_retell_sdk.default.PermissionDeniedError) {
243
- outputError("Permission denied. Check your API key permissions.", "PERMISSION_DENIED");
241
+ outputError(
242
+ "Permission denied. Check your API key permissions.",
243
+ "PERMISSION_DENIED"
244
+ );
244
245
  }
245
246
  if (error instanceof import_retell_sdk.default.InternalServerError) {
246
- outputError("Retell API server error. Please try again later.", "SERVER_ERROR");
247
+ outputError(
248
+ "Retell API server error. Please try again later.",
249
+ "SERVER_ERROR"
250
+ );
247
251
  }
248
252
  if (error instanceof import_retell_sdk.default.APIConnectionError) {
249
- outputError("Failed to connect to Retell API. Check your network connection.", "CONNECTION_ERROR");
253
+ outputError(
254
+ "Failed to connect to Retell API. Check your network connection.",
255
+ "CONNECTION_ERROR"
256
+ );
250
257
  }
251
258
  if (error instanceof import_retell_sdk.default.APIConnectionTimeoutError) {
252
- outputError("Request to Retell API timed out. Please try again.", "TIMEOUT_ERROR");
259
+ outputError(
260
+ "Request to Retell API timed out. Please try again.",
261
+ "TIMEOUT_ERROR"
262
+ );
253
263
  }
254
264
  if (error instanceof import_retell_sdk.default.APIError) {
255
265
  const message = error.message || "An API error occurred";
@@ -304,7 +314,9 @@ async function loginCommand() {
304
314
  const rl = readline.createInterface({ input: import_process.stdin, output: import_process.stdout });
305
315
  try {
306
316
  if (configFileExists()) {
307
- const overwrite = await rl.question("Config already exists. Overwrite? (y/n): ");
317
+ const overwrite = await rl.question(
318
+ "Config already exists. Overwrite? (y/n): "
319
+ );
308
320
  if (overwrite.toLowerCase() !== "y") {
309
321
  rl.close();
310
322
  outputJson({ message: "Login cancelled" });
@@ -327,10 +339,7 @@ async function loginCommand() {
327
339
  outputJson({
328
340
  message: "Successfully authenticated!",
329
341
  configPath: "./.retellrc.json",
330
- nextSteps: [
331
- "Try: retell agents list",
332
- "Try: retell transcripts list"
333
- ]
342
+ nextSteps: ["Try: retell agents list", "Try: retell transcripts list"]
334
343
  });
335
344
  } catch (error) {
336
345
  rl.close();
@@ -357,7 +366,9 @@ function getRetellClient() {
357
366
  if (error instanceof ConfigError) {
358
367
  throw error;
359
368
  }
360
- throw new Error(`Failed to initialize Retell client: ${error.message}`);
369
+ throw new Error(
370
+ `Failed to initialize Retell client: ${error.message}`
371
+ );
361
372
  }
362
373
  clientInstance = new import_retell_sdk3.default({
363
374
  apiKey,
@@ -375,7 +386,10 @@ async function listTranscriptsCommand(options) {
375
386
  const calls = await client.call.list({
376
387
  limit: options.limit || 50
377
388
  });
378
- const output = options.fields ? filterFields(calls, options.fields.split(",").map((f) => f.trim())) : calls;
389
+ const output = options.fields ? filterFields(
390
+ calls,
391
+ options.fields.split(",").map((f) => f.trim())
392
+ ) : calls;
379
393
  outputJson(output);
380
394
  } catch (error) {
381
395
  handleSdkError(error);
@@ -387,7 +401,10 @@ async function getTranscriptCommand(callId, options = {}) {
387
401
  try {
388
402
  const client = getRetellClient();
389
403
  const call = await client.call.retrieve(callId);
390
- const output = options.fields ? filterFields(call, options.fields.split(",").map((f) => f.trim())) : call;
404
+ const output = options.fields ? filterFields(
405
+ call,
406
+ options.fields.split(",").map((f) => f.trim())
407
+ ) : call;
391
408
  outputJson(output);
392
409
  } catch (error) {
393
410
  handleSdkError(error);
@@ -413,8 +430,7 @@ function extractTranscriptTurns(transcriptObject) {
413
430
  }));
414
431
  }
415
432
  function formatTimestamp(seconds) {
416
- if (!seconds || seconds < 0)
417
- return "N/A";
433
+ if (!seconds || seconds < 0) return "N/A";
418
434
  const totalSeconds = Math.floor(seconds);
419
435
  const mins = Math.floor(totalSeconds / 60);
420
436
  const secs = totalSeconds % 60;
@@ -449,12 +465,10 @@ function detectLongSilences(call, config) {
449
465
  const currTurn = transcript[i];
450
466
  const prevWords = prevTurn.words || [];
451
467
  const currWords = currTurn.words || [];
452
- if (prevWords.length === 0 || currWords.length === 0)
453
- continue;
468
+ if (prevWords.length === 0 || currWords.length === 0) continue;
454
469
  const prevEnd = prevWords[prevWords.length - 1]?.end;
455
470
  const currStart = currWords[0]?.start;
456
- if (prevEnd === void 0 || currStart === void 0)
457
- continue;
471
+ if (prevEnd === void 0 || currStart === void 0) continue;
458
472
  const gapMs = (currStart - prevEnd) * 1e3;
459
473
  if (gapMs > config.silenceThreshold) {
460
474
  hotspots.push({
@@ -492,10 +506,8 @@ function detectAllHotspots(call, config) {
492
506
  ...detectSentimentIssues(call)
493
507
  ];
494
508
  return hotspots.sort((a, b) => {
495
- if (a.turn_index === -1)
496
- return -1;
497
- if (b.turn_index === -1)
498
- return 1;
509
+ if (a.turn_index === -1) return -1;
510
+ if (b.turn_index === -1) return 1;
499
511
  return a.turn_index - b.turn_index;
500
512
  });
501
513
  }
@@ -510,7 +522,10 @@ async function analyzeTranscriptCommand(callId, options = {}) {
510
522
  const client = getRetellClient();
511
523
  const call = await client.call.retrieve(callId);
512
524
  if (options.raw) {
513
- const output2 = options.fields ? filterFields(call, options.fields.split(",").map((f) => f.trim())) : call;
525
+ const output2 = options.fields ? filterFields(
526
+ call,
527
+ options.fields.split(",").map((f) => f.trim())
528
+ ) : call;
514
529
  outputJson(output2);
515
530
  return;
516
531
  }
@@ -524,7 +539,10 @@ async function analyzeTranscriptCommand(callId, options = {}) {
524
539
  call_id: callId,
525
540
  hotspots
526
541
  };
527
- const output2 = options.fields ? filterFields(result, options.fields.split(",").map((f) => f.trim())) : result;
542
+ const output2 = options.fields ? filterFields(
543
+ result,
544
+ options.fields.split(",").map((f) => f.trim())
545
+ ) : result;
528
546
  outputJson(output2);
529
547
  return;
530
548
  }
@@ -561,7 +579,10 @@ async function analyzeTranscriptCommand(callId, options = {}) {
561
579
  breakdown: call.call_cost?.product_costs || []
562
580
  }
563
581
  };
564
- const output = options.fields ? filterFields(analysis, options.fields.split(",").map((f) => f.trim())) : analysis;
582
+ const output = options.fields ? filterFields(
583
+ analysis,
584
+ options.fields.split(",").map((f) => f.trim())
585
+ ) : analysis;
565
586
  outputJson(output);
566
587
  } catch (error) {
567
588
  handleSdkError(error);
@@ -594,11 +615,15 @@ function parseDate(dateStr) {
594
615
  const dateOnlyPattern = /^\d{4}-\d{2}-\d{2}$/;
595
616
  const iso8601Pattern = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?)?$/;
596
617
  if (!iso8601Pattern.test(dateStr)) {
597
- throw new ValidationError(`Invalid date format: "${dateStr}". Use YYYY-MM-DD or ISO 8601 format.`);
618
+ throw new ValidationError(
619
+ `Invalid date format: "${dateStr}". Use YYYY-MM-DD or ISO 8601 format.`
620
+ );
598
621
  }
599
622
  const date = new Date(dateStr);
600
623
  if (isNaN(date.getTime())) {
601
- throw new ValidationError(`Invalid date format: "${dateStr}". Use YYYY-MM-DD or ISO 8601 format.`);
624
+ throw new ValidationError(
625
+ `Invalid date format: "${dateStr}". Use YYYY-MM-DD or ISO 8601 format.`
626
+ );
602
627
  }
603
628
  return { date, isDateOnly: dateOnlyPattern.test(dateStr) };
604
629
  }
@@ -629,10 +654,14 @@ function validateSearchOptions(options) {
629
654
  }
630
655
  }
631
656
  if (options.limit !== void 0 && (options.limit < 1 || !Number.isInteger(options.limit))) {
632
- throw new ValidationError(`Limit must be a positive integer (got: "${options.limit}")`);
657
+ throw new ValidationError(
658
+ `Limit must be a positive integer (got: "${options.limit}")`
659
+ );
633
660
  }
634
661
  if (options.limit !== void 0 && options.limit > MAX_LIMIT) {
635
- throw new ValidationError(`Limit cannot exceed ${MAX_LIMIT} (got: "${options.limit}")`);
662
+ throw new ValidationError(
663
+ `Limit cannot exceed ${MAX_LIMIT} (got: "${options.limit}")`
664
+ );
636
665
  }
637
666
  return parsedDates;
638
667
  }
@@ -665,7 +694,10 @@ async function searchTranscripts(options, parsedDates) {
665
694
  const response = await client.call.list(apiParams);
666
695
  const validation = CallListSchema.safeParse(response);
667
696
  if (!validation.success) {
668
- console.warn("Warning: API response validation failed:", validation.error.message);
697
+ console.warn(
698
+ "Warning: API response validation failed:",
699
+ validation.error.message
700
+ );
669
701
  throw new Error(`Invalid API response format: ${validation.error.message}`);
670
702
  }
671
703
  const results = validation.data;
@@ -694,7 +726,10 @@ async function searchTranscriptsCommand(options = {}) {
694
726
  const searchResult = await searchTranscripts(options, parsedDates);
695
727
  const output = options.fields ? {
696
728
  results: searchResult.results.map(
697
- (r) => filterFields(r, options.fields.split(",").map((f) => f.trim()))
729
+ (r) => filterFields(
730
+ r,
731
+ options.fields.split(",").map((f) => f.trim())
732
+ )
698
733
  ),
699
734
  total_count: searchResult.total_count,
700
735
  filters_applied: searchResult.filters_applied
@@ -740,7 +775,10 @@ async function listAgentsCommand(options = {}) {
740
775
  response_engine_id
741
776
  };
742
777
  });
743
- const output = options.fields ? filterFields(formatted, options.fields.split(",").map((f) => f.trim())) : formatted;
778
+ const output = options.fields ? filterFields(
779
+ formatted,
780
+ options.fields.split(",").map((f) => f.trim())
781
+ ) : formatted;
744
782
  outputJson(output);
745
783
  } catch (error) {
746
784
  handleSdkError(error);
@@ -752,7 +790,10 @@ async function agentInfoCommand(agentId, options = {}) {
752
790
  try {
753
791
  const client = getRetellClient();
754
792
  const agent = await client.agent.retrieve(agentId);
755
- const output = options.fields ? filterFields(agent, options.fields.split(",").map((f) => f.trim())) : agent;
793
+ const output = options.fields ? filterFields(
794
+ agent,
795
+ options.fields.split(",").map((f) => f.trim())
796
+ ) : agent;
756
797
  outputJson(output);
757
798
  } catch (error) {
758
799
  handleSdkError(error);
@@ -807,7 +848,9 @@ async function resolvePromptSource(agentId) {
807
848
  // src/commands/prompts/pull.ts
808
849
  function validateAgentId(agentId) {
809
850
  if (agentId.includes("..") || agentId.includes("/") || agentId.includes("\\")) {
810
- throw new Error("Invalid agent ID: cannot contain path separators or traversal sequences");
851
+ throw new Error(
852
+ "Invalid agent ID: cannot contain path separators or traversal sequences"
853
+ );
811
854
  }
812
855
  }
813
856
  async function pullPromptsCommand(agentId, options) {
@@ -824,7 +867,10 @@ async function pullPromptsCommand(agentId, options) {
824
867
  (0, import_fs2.mkdirSync)(agentDir, { recursive: true });
825
868
  } catch (error) {
826
869
  if (error.code === "EACCES") {
827
- outputError(`Permission denied creating directory: ${agentDir}`, "PERMISSION_DENIED");
870
+ outputError(
871
+ `Permission denied creating directory: ${agentDir}`,
872
+ "PERMISSION_DENIED"
873
+ );
828
874
  } else if (error.code === "ENOSPC") {
829
875
  outputError(`No space left on device: ${agentDir}`, "NO_SPACE");
830
876
  } else {
@@ -840,11 +886,17 @@ async function pullPromptsCommand(agentId, options) {
840
886
  }
841
887
  } catch (error) {
842
888
  if (error.code === "EACCES") {
843
- outputError(`Permission denied writing files to: ${agentDir}`, "PERMISSION_DENIED");
889
+ outputError(
890
+ `Permission denied writing files to: ${agentDir}`,
891
+ "PERMISSION_DENIED"
892
+ );
844
893
  } else if (error.code === "ENOSPC") {
845
894
  outputError(`No space left on device: ${agentDir}`, "NO_SPACE");
846
895
  } else {
847
- outputError(`Failed to write prompt files: ${error.message}`, "FS_ERROR");
896
+ outputError(
897
+ `Failed to write prompt files: ${error.message}`,
898
+ "FS_ERROR"
899
+ );
848
900
  }
849
901
  return;
850
902
  }
@@ -869,8 +921,14 @@ function saveRetellLlmPrompts(agentDir, promptSource) {
869
921
  version: prompts2.version,
870
922
  pulled_at: (/* @__PURE__ */ new Date()).toISOString()
871
923
  };
872
- (0, import_fs2.writeFileSync)((0, import_path2.join)(agentDir, "metadata.json"), JSON.stringify(metadata, null, 2));
873
- (0, import_fs2.writeFileSync)((0, import_path2.join)(agentDir, "general_prompt.md"), prompts2.general_prompt || "");
924
+ (0, import_fs2.writeFileSync)(
925
+ (0, import_path2.join)(agentDir, "metadata.json"),
926
+ JSON.stringify(metadata, null, 2)
927
+ );
928
+ (0, import_fs2.writeFileSync)(
929
+ (0, import_path2.join)(agentDir, "general_prompt.md"),
930
+ prompts2.general_prompt || ""
931
+ );
874
932
  if (prompts2.begin_message) {
875
933
  (0, import_fs2.writeFileSync)((0, import_path2.join)(agentDir, "begin_message.txt"), prompts2.begin_message);
876
934
  }
@@ -895,9 +953,18 @@ function saveConversationFlowPrompts(agentDir, promptSource) {
895
953
  version: prompts2.version,
896
954
  pulled_at: (/* @__PURE__ */ new Date()).toISOString()
897
955
  };
898
- (0, import_fs2.writeFileSync)((0, import_path2.join)(agentDir, "metadata.json"), JSON.stringify(metadata, null, 2));
899
- (0, import_fs2.writeFileSync)((0, import_path2.join)(agentDir, "global_prompt.md"), prompts2.global_prompt || "");
900
- (0, import_fs2.writeFileSync)((0, import_path2.join)(agentDir, "nodes.json"), JSON.stringify(prompts2.nodes, null, 2));
956
+ (0, import_fs2.writeFileSync)(
957
+ (0, import_path2.join)(agentDir, "metadata.json"),
958
+ JSON.stringify(metadata, null, 2)
959
+ );
960
+ (0, import_fs2.writeFileSync)(
961
+ (0, import_path2.join)(agentDir, "global_prompt.md"),
962
+ prompts2.global_prompt || ""
963
+ );
964
+ (0, import_fs2.writeFileSync)(
965
+ (0, import_path2.join)(agentDir, "nodes.json"),
966
+ JSON.stringify(prompts2.nodes, null, 2)
967
+ );
901
968
  }
902
969
  function getFilesCreated(type, promptSource) {
903
970
  const files = ["metadata.json"];
@@ -925,11 +992,15 @@ var import_fs3 = require("fs");
925
992
  var import_path3 = require("path");
926
993
  function loadLocalPrompts(agentId, agentDir) {
927
994
  if (!(0, import_fs3.existsSync)(agentDir)) {
928
- throw new Error(`Prompts directory not found: ${agentDir}. Run 'retell prompts pull ${agentId}' first.`);
995
+ throw new Error(
996
+ `Prompts directory not found: ${agentDir}. Run 'retell prompts pull ${agentId}' first.`
997
+ );
929
998
  }
930
999
  const metadataPath = (0, import_path3.join)(agentDir, "metadata.json");
931
1000
  if (!(0, import_fs3.existsSync)(metadataPath)) {
932
- throw new Error(`metadata.json not found in ${agentDir}. Directory may be corrupted.`);
1001
+ throw new Error(
1002
+ `metadata.json not found in ${agentDir}. Directory may be corrupted.`
1003
+ );
933
1004
  }
934
1005
  let metadata;
935
1006
  try {
@@ -955,7 +1026,9 @@ function loadLocalPrompts(agentId, agentDir) {
955
1026
  prompts: prompts2
956
1027
  };
957
1028
  } else {
958
- throw new Error(`Unknown agent type in metadata: ${metadata.type}`);
1029
+ throw new Error(
1030
+ `Unknown agent type in metadata: ${metadata.type}`
1031
+ );
959
1032
  }
960
1033
  }
961
1034
  function loadRetellLlmPrompts(agentDir) {
@@ -983,7 +1056,9 @@ function loadRetellLlmPrompts(agentDir) {
983
1056
  const statesDir = (0, import_path3.join)(agentDir, "states");
984
1057
  if ((0, import_fs3.existsSync)(statesDir)) {
985
1058
  try {
986
- const stateFiles = (0, import_fs3.readdirSync)(statesDir).filter((f) => f.endsWith(".md"));
1059
+ const stateFiles = (0, import_fs3.readdirSync)(statesDir).filter(
1060
+ (f) => f.endsWith(".md")
1061
+ );
987
1062
  if (stateFiles.length > 0) {
988
1063
  prompts2.states = stateFiles.map((file) => {
989
1064
  const stateName = file.replace(".md", "");
@@ -991,12 +1066,16 @@ function loadRetellLlmPrompts(agentDir) {
991
1066
  try {
992
1067
  content = (0, import_fs3.readFileSync)((0, import_path3.join)(statesDir, file), "utf-8");
993
1068
  } catch (error) {
994
- throw new Error(`Failed to read state file ${file}: ${error.message}`);
1069
+ throw new Error(
1070
+ `Failed to read state file ${file}: ${error.message}`
1071
+ );
995
1072
  }
996
1073
  const STATE_HEADER_REGEX = /^#\s+State:\s+(.+)$/m;
997
1074
  const match = content.match(STATE_HEADER_REGEX);
998
1075
  if (!match) {
999
- throw new Error(`Invalid state file format in ${file}: missing "# State:" header`);
1076
+ throw new Error(
1077
+ `Invalid state file format in ${file}: missing "# State:" header`
1078
+ );
1000
1079
  }
1001
1080
  const statePrompt = content.replace(STATE_HEADER_REGEX, "").trim();
1002
1081
  return {
@@ -1046,12 +1125,9 @@ function loadConversationFlowPrompts(agentDir) {
1046
1125
 
1047
1126
  // src/services/prompt-diff.ts
1048
1127
  function deepEqual(obj1, obj2, maxDepth = 100) {
1049
- if (obj1 === obj2)
1050
- return true;
1051
- if (obj1 === null || obj2 === null)
1052
- return false;
1053
- if (typeof obj1 !== "object" || typeof obj2 !== "object")
1054
- return false;
1128
+ if (obj1 === obj2) return true;
1129
+ if (obj1 === null || obj2 === null) return false;
1130
+ if (typeof obj1 !== "object" || typeof obj2 !== "object") return false;
1055
1131
  let currentDepth = 0;
1056
1132
  const sortedStringify = (obj) => {
1057
1133
  if (++currentDepth > maxDepth) {
@@ -1059,22 +1135,26 @@ function deepEqual(obj1, obj2, maxDepth = 100) {
1059
1135
  `Maximum depth (${maxDepth}) exceeded during comparison. This may indicate a circular reference or extremely deep nesting.`
1060
1136
  );
1061
1137
  }
1062
- if (obj === null)
1063
- return "null";
1064
- if (typeof obj !== "object")
1065
- return JSON.stringify(obj);
1138
+ if (obj === null) return "null";
1139
+ if (typeof obj !== "object") return JSON.stringify(obj);
1066
1140
  if (Array.isArray(obj)) {
1067
1141
  return "[" + obj.map(sortedStringify).join(",") + "]";
1068
1142
  }
1069
1143
  const keys = Object.keys(obj).sort();
1070
- const pairs = keys.map((k) => JSON.stringify(k) + ":" + sortedStringify(obj[k]));
1144
+ const pairs = keys.map(
1145
+ (k) => JSON.stringify(k) + ":" + sortedStringify(obj[k])
1146
+ );
1071
1147
  return "{" + pairs.join(",") + "}";
1072
1148
  };
1073
1149
  try {
1074
1150
  return sortedStringify(obj1) === sortedStringify(obj2);
1075
1151
  } catch (error) {
1076
1152
  if (error instanceof Error && error.message.includes("Maximum depth")) {
1077
- console.warn("Warning:", error.message, "Falling back to reference equality.");
1153
+ console.warn(
1154
+ "Warning:",
1155
+ error.message,
1156
+ "Falling back to reference equality."
1157
+ );
1078
1158
  return obj1 === obj2;
1079
1159
  }
1080
1160
  throw error;
@@ -1130,8 +1210,12 @@ function generateRetellLlmDiff(agentId, localPrompts, remotePrompts) {
1130
1210
  }
1131
1211
  const localStates = localPrompts.prompts.states || [];
1132
1212
  const remoteStates = remotePrompts.prompts.states || [];
1133
- const localStatesMap = new Map(localStates.map((s) => [s.name, s.state_prompt]));
1134
- const remoteStatesMap = new Map(remoteStates.map((s) => [s.name, s.state_prompt]));
1213
+ const localStatesMap = new Map(
1214
+ localStates.map((s) => [s.name, s.state_prompt])
1215
+ );
1216
+ const remoteStatesMap = new Map(
1217
+ remoteStates.map((s) => [s.name, s.state_prompt])
1218
+ );
1135
1219
  for (const [stateName, localPrompt] of localStatesMap) {
1136
1220
  const remotePrompt = remoteStatesMap.get(stateName);
1137
1221
  const fieldKey = `states.${stateName}`;
@@ -1219,7 +1303,9 @@ function generateConversationFlowDiff(agentId, localPrompts, remotePrompts) {
1219
1303
  // src/commands/prompts/update.ts
1220
1304
  function validateAgentId2(agentId) {
1221
1305
  if (agentId.includes("..") || agentId.includes("/") || agentId.includes("\\")) {
1222
- throw new Error("Invalid agent ID: cannot contain path separators or traversal sequences");
1306
+ throw new Error(
1307
+ "Invalid agent ID: cannot contain path separators or traversal sequences"
1308
+ );
1223
1309
  }
1224
1310
  }
1225
1311
  async function updatePromptsCommand(agentId, options) {
@@ -1242,7 +1328,9 @@ async function updatePromptsCommand(agentId, options) {
1242
1328
  );
1243
1329
  return;
1244
1330
  }
1245
- const metadata = JSON.parse((0, import_fs4.readFileSync)(metadataPath, "utf-8"));
1331
+ const metadata = JSON.parse(
1332
+ (0, import_fs4.readFileSync)(metadataPath, "utf-8")
1333
+ );
1246
1334
  const promptSource = await resolvePromptSource(agentId);
1247
1335
  if (promptSource.type === "custom-llm") {
1248
1336
  outputError(promptSource.error, "CUSTOM_LLM_NOT_SUPPORTED");
@@ -1295,7 +1383,10 @@ async function updatePromptsCommand(agentId, options) {
1295
1383
  note: `Run 'retell agent-publish ${agentId}' to publish changes to production`
1296
1384
  });
1297
1385
  } else if (promptSource.type === "conversation-flow" && localPrompts.type === "conversation-flow") {
1298
- await client.conversationFlow.update(promptSource.flowId, localPrompts.prompts);
1386
+ await client.conversationFlow.update(
1387
+ promptSource.flowId,
1388
+ localPrompts.prompts
1389
+ );
1299
1390
  outputJson({
1300
1391
  message: "Prompts updated successfully (draft version)",
1301
1392
  agent_id: agentId,
@@ -1318,7 +1409,9 @@ async function updatePromptsCommand(agentId, options) {
1318
1409
  var import_path5 = require("path");
1319
1410
  function validateAgentId3(agentId) {
1320
1411
  if (agentId.includes("..") || agentId.includes("/") || agentId.includes("\\")) {
1321
- throw new Error("Invalid agent ID: cannot contain path separators or traversal sequences");
1412
+ throw new Error(
1413
+ "Invalid agent ID: cannot contain path separators or traversal sequences"
1414
+ );
1322
1415
  }
1323
1416
  }
1324
1417
  async function diffPromptsCommand(agentId, options) {
@@ -1391,7 +1484,10 @@ async function resolveToolsSource(agentId) {
1391
1484
  }
1392
1485
  }
1393
1486
  }
1394
- const stateToolCount = Object.values(stateTools).reduce((sum, t) => sum + t.length, 0);
1487
+ const stateToolCount = Object.values(stateTools).reduce(
1488
+ (sum, t) => sum + t.length,
1489
+ 0
1490
+ );
1395
1491
  const totalCount = generalTools.length + stateToolCount;
1396
1492
  return {
1397
1493
  type: "retell-llm",
@@ -1417,7 +1513,10 @@ async function resolveToolsSource(agentId) {
1417
1513
  }
1418
1514
  }
1419
1515
  }
1420
- const componentToolCount = Object.values(componentTools).reduce((sum, t) => sum + t.length, 0);
1516
+ const componentToolCount = Object.values(componentTools).reduce(
1517
+ (sum, t) => sum + t.length,
1518
+ 0
1519
+ );
1421
1520
  const totalCount = flowTools.length + componentToolCount;
1422
1521
  return {
1423
1522
  type: "conversation-flow",
@@ -1644,7 +1743,10 @@ async function listToolsCommand(agentId, options) {
1644
1743
  }
1645
1744
  }
1646
1745
  if (options.fields) {
1647
- const filtered = filterFields(output, options.fields.split(",").map((f) => f.trim()));
1746
+ const filtered = filterFields(
1747
+ output,
1748
+ options.fields.split(",").map((f) => f.trim())
1749
+ );
1648
1750
  outputJson(filtered);
1649
1751
  } else {
1650
1752
  outputJson(output);
@@ -1680,7 +1782,10 @@ async function getToolCommand(agentId, toolName, options) {
1680
1782
  tool: result.tool.tool
1681
1783
  };
1682
1784
  if (options.fields) {
1683
- const filtered = filterFields(output, options.fields.split(",").map((f) => f.trim()));
1785
+ const filtered = filterFields(
1786
+ output,
1787
+ options.fields.split(",").map((f) => f.trim())
1788
+ );
1684
1789
  outputJson(filtered);
1685
1790
  } else {
1686
1791
  outputJson(output);
@@ -1704,9 +1809,15 @@ async function addToolCommand(agentId, options) {
1704
1809
  tool = JSON.parse(content);
1705
1810
  } catch (error) {
1706
1811
  if (error instanceof SyntaxError) {
1707
- outputError(`Invalid JSON in tool file: ${error.message}`, "INVALID_JSON");
1812
+ outputError(
1813
+ `Invalid JSON in tool file: ${error.message}`,
1814
+ "INVALID_JSON"
1815
+ );
1708
1816
  } else {
1709
- outputError(`Error reading tool file: ${error.message}`, "FILE_READ_ERROR");
1817
+ outputError(
1818
+ `Error reading tool file: ${error.message}`,
1819
+ "FILE_READ_ERROR"
1820
+ );
1710
1821
  }
1711
1822
  return;
1712
1823
  }
@@ -1761,7 +1872,10 @@ async function addToolCommand(agentId, options) {
1761
1872
  const updatedStates = [...states];
1762
1873
  const stateTools = [...updatedStates[stateIndex].tools ?? []];
1763
1874
  stateTools.push(tool);
1764
- updatedStates[stateIndex] = { ...updatedStates[stateIndex], tools: stateTools };
1875
+ updatedStates[stateIndex] = {
1876
+ ...updatedStates[stateIndex],
1877
+ tools: stateTools
1878
+ };
1765
1879
  await client.llm.update(source.llmId, { states: updatedStates });
1766
1880
  const output = {
1767
1881
  message: "Tool added successfully (draft version)",
@@ -1776,7 +1890,9 @@ async function addToolCommand(agentId, options) {
1776
1890
  } else {
1777
1891
  const generalTools = [...llm.general_tools ?? []];
1778
1892
  generalTools.push(tool);
1779
- await client.llm.update(source.llmId, { general_tools: generalTools });
1893
+ await client.llm.update(source.llmId, {
1894
+ general_tools: generalTools
1895
+ });
1780
1896
  const output = {
1781
1897
  message: "Tool added successfully (draft version)",
1782
1898
  agent_id: agentId,
@@ -1806,7 +1922,9 @@ async function addToolCommand(agentId, options) {
1806
1922
  const flow = await client.conversationFlow.retrieve(source.flowId);
1807
1923
  if (options.component) {
1808
1924
  const components = flow.components ?? [];
1809
- const compIndex = components.findIndex((c) => c.name === options.component);
1925
+ const compIndex = components.findIndex(
1926
+ (c) => c.name === options.component
1927
+ );
1810
1928
  if (compIndex === -1) {
1811
1929
  outputError(
1812
1930
  `Component '${options.component}' not found. Available components: ${components.map((c) => c.name).join(", ") || "none"}`,
@@ -1817,8 +1935,13 @@ async function addToolCommand(agentId, options) {
1817
1935
  const updatedComponents = [...components];
1818
1936
  const compTools = [...updatedComponents[compIndex].tools ?? []];
1819
1937
  compTools.push(tool);
1820
- updatedComponents[compIndex] = { ...updatedComponents[compIndex], tools: compTools };
1821
- await client.conversationFlow.update(source.flowId, { components: updatedComponents });
1938
+ updatedComponents[compIndex] = {
1939
+ ...updatedComponents[compIndex],
1940
+ tools: compTools
1941
+ };
1942
+ await client.conversationFlow.update(source.flowId, {
1943
+ components: updatedComponents
1944
+ });
1822
1945
  const output = {
1823
1946
  message: "Tool added successfully (draft version)",
1824
1947
  agent_id: agentId,
@@ -1832,7 +1955,9 @@ async function addToolCommand(agentId, options) {
1832
1955
  } else {
1833
1956
  const flowTools = [...flow.tools ?? []];
1834
1957
  flowTools.push(tool);
1835
- await client.conversationFlow.update(source.flowId, { tools: flowTools });
1958
+ await client.conversationFlow.update(source.flowId, {
1959
+ tools: flowTools
1960
+ });
1836
1961
  const output = {
1837
1962
  message: "Tool added successfully (draft version)",
1838
1963
  agent_id: agentId,
@@ -1868,9 +1993,15 @@ async function updateToolCommand(agentId, toolName, options) {
1868
1993
  newTool = JSON.parse(content);
1869
1994
  } catch (error) {
1870
1995
  if (error instanceof SyntaxError) {
1871
- outputError(`Invalid JSON in tool file: ${error.message}`, "INVALID_JSON");
1996
+ outputError(
1997
+ `Invalid JSON in tool file: ${error.message}`,
1998
+ "INVALID_JSON"
1999
+ );
1872
2000
  } else {
1873
- outputError(`Error reading tool file: ${error.message}`, "FILE_READ_ERROR");
2001
+ outputError(
2002
+ `Error reading tool file: ${error.message}`,
2003
+ "FILE_READ_ERROR"
2004
+ );
1874
2005
  }
1875
2006
  return;
1876
2007
  }
@@ -1925,11 +2056,17 @@ async function updateToolCommand(agentId, toolName, options) {
1925
2056
  const stateTools = [...updatedStates[stateIndex].tools ?? []];
1926
2057
  const toolIndex = stateTools.findIndex((t) => t.name === toolName);
1927
2058
  if (toolIndex === -1) {
1928
- outputError(`Tool '${toolName}' not found in state '${stateName}'`, "TOOL_NOT_FOUND");
2059
+ outputError(
2060
+ `Tool '${toolName}' not found in state '${stateName}'`,
2061
+ "TOOL_NOT_FOUND"
2062
+ );
1929
2063
  return;
1930
2064
  }
1931
2065
  stateTools[toolIndex] = newTool;
1932
- updatedStates[stateIndex] = { ...updatedStates[stateIndex], tools: stateTools };
2066
+ updatedStates[stateIndex] = {
2067
+ ...updatedStates[stateIndex],
2068
+ tools: stateTools
2069
+ };
1933
2070
  await client.llm.update(source.llmId, { states: updatedStates });
1934
2071
  const output = {
1935
2072
  message: "Tool updated successfully (draft version)",
@@ -1943,13 +2080,20 @@ async function updateToolCommand(agentId, toolName, options) {
1943
2080
  outputJson(output);
1944
2081
  } else {
1945
2082
  const generalTools = [...llm.general_tools ?? []];
1946
- const toolIndex = generalTools.findIndex((t) => t.name === toolName);
2083
+ const toolIndex = generalTools.findIndex(
2084
+ (t) => t.name === toolName
2085
+ );
1947
2086
  if (toolIndex === -1) {
1948
- outputError(`Tool '${toolName}' not found in general tools`, "TOOL_NOT_FOUND");
2087
+ outputError(
2088
+ `Tool '${toolName}' not found in general tools`,
2089
+ "TOOL_NOT_FOUND"
2090
+ );
1949
2091
  return;
1950
2092
  }
1951
2093
  generalTools[toolIndex] = newTool;
1952
- await client.llm.update(source.llmId, { general_tools: generalTools });
2094
+ await client.llm.update(source.llmId, {
2095
+ general_tools: generalTools
2096
+ });
1953
2097
  const output = {
1954
2098
  message: "Tool updated successfully (draft version)",
1955
2099
  agent_id: agentId,
@@ -1981,19 +2125,30 @@ async function updateToolCommand(agentId, toolName, options) {
1981
2125
  const components = flow.components ?? [];
1982
2126
  const compIndex = components.findIndex((c) => c.name === componentId);
1983
2127
  if (compIndex === -1) {
1984
- outputError(`Component '${componentId}' not found`, "COMPONENT_NOT_FOUND");
2128
+ outputError(
2129
+ `Component '${componentId}' not found`,
2130
+ "COMPONENT_NOT_FOUND"
2131
+ );
1985
2132
  return;
1986
2133
  }
1987
2134
  const updatedComponents = [...components];
1988
2135
  const compTools = [...updatedComponents[compIndex].tools ?? []];
1989
2136
  const toolIndex = compTools.findIndex((t) => t.name === toolName);
1990
2137
  if (toolIndex === -1) {
1991
- outputError(`Tool '${toolName}' not found in component '${componentId}'`, "TOOL_NOT_FOUND");
2138
+ outputError(
2139
+ `Tool '${toolName}' not found in component '${componentId}'`,
2140
+ "TOOL_NOT_FOUND"
2141
+ );
1992
2142
  return;
1993
2143
  }
1994
2144
  compTools[toolIndex] = newTool;
1995
- updatedComponents[compIndex] = { ...updatedComponents[compIndex], tools: compTools };
1996
- await client.conversationFlow.update(source.flowId, { components: updatedComponents });
2145
+ updatedComponents[compIndex] = {
2146
+ ...updatedComponents[compIndex],
2147
+ tools: compTools
2148
+ };
2149
+ await client.conversationFlow.update(source.flowId, {
2150
+ components: updatedComponents
2151
+ });
1997
2152
  const output = {
1998
2153
  message: "Tool updated successfully (draft version)",
1999
2154
  agent_id: agentId,
@@ -2008,11 +2163,16 @@ async function updateToolCommand(agentId, toolName, options) {
2008
2163
  const flowTools = [...flow.tools ?? []];
2009
2164
  const toolIndex = flowTools.findIndex((t) => t.name === toolName);
2010
2165
  if (toolIndex === -1) {
2011
- outputError(`Tool '${toolName}' not found in flow tools`, "TOOL_NOT_FOUND");
2166
+ outputError(
2167
+ `Tool '${toolName}' not found in flow tools`,
2168
+ "TOOL_NOT_FOUND"
2169
+ );
2012
2170
  return;
2013
2171
  }
2014
2172
  flowTools[toolIndex] = newTool;
2015
- await client.conversationFlow.update(source.flowId, { tools: flowTools });
2173
+ await client.conversationFlow.update(source.flowId, {
2174
+ tools: flowTools
2175
+ });
2016
2176
  const output = {
2017
2177
  message: "Tool updated successfully (draft version)",
2018
2178
  agent_id: agentId,
@@ -2079,11 +2239,17 @@ async function removeToolCommand(agentId, toolName, options) {
2079
2239
  const stateTools = [...updatedStates[stateIndex].tools ?? []];
2080
2240
  const toolIndex = stateTools.findIndex((t) => t.name === toolName);
2081
2241
  if (toolIndex === -1) {
2082
- outputError(`Tool '${toolName}' not found in state '${stateName}'`, "TOOL_NOT_FOUND");
2242
+ outputError(
2243
+ `Tool '${toolName}' not found in state '${stateName}'`,
2244
+ "TOOL_NOT_FOUND"
2245
+ );
2083
2246
  return;
2084
2247
  }
2085
2248
  stateTools.splice(toolIndex, 1);
2086
- updatedStates[stateIndex] = { ...updatedStates[stateIndex], tools: stateTools };
2249
+ updatedStates[stateIndex] = {
2250
+ ...updatedStates[stateIndex],
2251
+ tools: stateTools
2252
+ };
2087
2253
  await client.llm.update(source.llmId, { states: updatedStates });
2088
2254
  const output = {
2089
2255
  message: "Tool removed successfully (draft version)",
@@ -2097,13 +2263,20 @@ async function removeToolCommand(agentId, toolName, options) {
2097
2263
  outputJson(output);
2098
2264
  } else {
2099
2265
  const generalTools = [...llm.general_tools ?? []];
2100
- const toolIndex = generalTools.findIndex((t) => t.name === toolName);
2266
+ const toolIndex = generalTools.findIndex(
2267
+ (t) => t.name === toolName
2268
+ );
2101
2269
  if (toolIndex === -1) {
2102
- outputError(`Tool '${toolName}' not found in general tools`, "TOOL_NOT_FOUND");
2270
+ outputError(
2271
+ `Tool '${toolName}' not found in general tools`,
2272
+ "TOOL_NOT_FOUND"
2273
+ );
2103
2274
  return;
2104
2275
  }
2105
2276
  generalTools.splice(toolIndex, 1);
2106
- await client.llm.update(source.llmId, { general_tools: generalTools });
2277
+ await client.llm.update(source.llmId, {
2278
+ general_tools: generalTools
2279
+ });
2107
2280
  const output = {
2108
2281
  message: "Tool removed successfully (draft version)",
2109
2282
  agent_id: agentId,
@@ -2134,19 +2307,30 @@ async function removeToolCommand(agentId, toolName, options) {
2134
2307
  const components = flow.components ?? [];
2135
2308
  const compIndex = components.findIndex((c) => c.name === componentId);
2136
2309
  if (compIndex === -1) {
2137
- outputError(`Component '${componentId}' not found`, "COMPONENT_NOT_FOUND");
2310
+ outputError(
2311
+ `Component '${componentId}' not found`,
2312
+ "COMPONENT_NOT_FOUND"
2313
+ );
2138
2314
  return;
2139
2315
  }
2140
2316
  const updatedComponents = [...components];
2141
2317
  const compTools = [...updatedComponents[compIndex].tools ?? []];
2142
2318
  const toolIndex = compTools.findIndex((t) => t.name === toolName);
2143
2319
  if (toolIndex === -1) {
2144
- outputError(`Tool '${toolName}' not found in component '${componentId}'`, "TOOL_NOT_FOUND");
2320
+ outputError(
2321
+ `Tool '${toolName}' not found in component '${componentId}'`,
2322
+ "TOOL_NOT_FOUND"
2323
+ );
2145
2324
  return;
2146
2325
  }
2147
2326
  compTools.splice(toolIndex, 1);
2148
- updatedComponents[compIndex] = { ...updatedComponents[compIndex], tools: compTools };
2149
- await client.conversationFlow.update(source.flowId, { components: updatedComponents });
2327
+ updatedComponents[compIndex] = {
2328
+ ...updatedComponents[compIndex],
2329
+ tools: compTools
2330
+ };
2331
+ await client.conversationFlow.update(source.flowId, {
2332
+ components: updatedComponents
2333
+ });
2150
2334
  const output = {
2151
2335
  message: "Tool removed successfully (draft version)",
2152
2336
  agent_id: agentId,
@@ -2161,11 +2345,16 @@ async function removeToolCommand(agentId, toolName, options) {
2161
2345
  const flowTools = [...flow.tools ?? []];
2162
2346
  const toolIndex = flowTools.findIndex((t) => t.name === toolName);
2163
2347
  if (toolIndex === -1) {
2164
- outputError(`Tool '${toolName}' not found in flow tools`, "TOOL_NOT_FOUND");
2348
+ outputError(
2349
+ `Tool '${toolName}' not found in flow tools`,
2350
+ "TOOL_NOT_FOUND"
2351
+ );
2165
2352
  return;
2166
2353
  }
2167
2354
  flowTools.splice(toolIndex, 1);
2168
- await client.conversationFlow.update(source.flowId, { tools: flowTools });
2355
+ await client.conversationFlow.update(source.flowId, {
2356
+ tools: flowTools
2357
+ });
2169
2358
  const output = {
2170
2359
  message: "Tool removed successfully (draft version)",
2171
2360
  agent_id: agentId,
@@ -2232,7 +2421,11 @@ async function exportToolsCommand(agentId, options) {
2232
2421
  }
2233
2422
  if (options.output) {
2234
2423
  try {
2235
- (0, import_fs7.writeFileSync)(options.output, JSON.stringify(exportData, null, 2), "utf-8");
2424
+ (0, import_fs7.writeFileSync)(
2425
+ options.output,
2426
+ JSON.stringify(exportData, null, 2),
2427
+ "utf-8"
2428
+ );
2236
2429
  outputJson({
2237
2430
  message: "Tools exported successfully",
2238
2431
  agent_id: agentId,
@@ -2243,7 +2436,10 @@ async function exportToolsCommand(agentId, options) {
2243
2436
  });
2244
2437
  } catch (error) {
2245
2438
  if (error.code === "EACCES") {
2246
- outputError(`Permission denied writing to: ${options.output}`, "PERMISSION_DENIED");
2439
+ outputError(
2440
+ `Permission denied writing to: ${options.output}`,
2441
+ "PERMISSION_DENIED"
2442
+ );
2247
2443
  } else if (error.code === "ENOSPC") {
2248
2444
  outputError("No space left on device", "NO_SPACE");
2249
2445
  } else {
@@ -2272,14 +2468,23 @@ async function importToolsCommand(agentId, options) {
2272
2468
  importData = JSON.parse(content);
2273
2469
  } catch (error) {
2274
2470
  if (error instanceof SyntaxError) {
2275
- outputError(`Invalid JSON in import file: ${error.message}`, "INVALID_JSON");
2471
+ outputError(
2472
+ `Invalid JSON in import file: ${error.message}`,
2473
+ "INVALID_JSON"
2474
+ );
2276
2475
  } else {
2277
- outputError(`Error reading import file: ${error.message}`, "FILE_READ_ERROR");
2476
+ outputError(
2477
+ `Error reading import file: ${error.message}`,
2478
+ "FILE_READ_ERROR"
2479
+ );
2278
2480
  }
2279
2481
  return;
2280
2482
  }
2281
2483
  if (!importData.tools) {
2282
- outputError('Import file must contain a "tools" object', "INVALID_IMPORT");
2484
+ outputError(
2485
+ 'Import file must contain a "tools" object',
2486
+ "INVALID_IMPORT"
2487
+ );
2283
2488
  return;
2284
2489
  }
2285
2490
  const source = await resolveToolsSource(agentId);
@@ -2307,7 +2512,9 @@ async function importToolsCommand(agentId, options) {
2307
2512
  for (const tool of importData.tools.general) {
2308
2513
  if (existingNames.has(tool.name)) {
2309
2514
  if (options.replace) {
2310
- const idx = generalTools.findIndex((t) => t.name === tool.name);
2515
+ const idx = generalTools.findIndex(
2516
+ (t) => t.name === tool.name
2517
+ );
2311
2518
  if (idx !== -1) {
2312
2519
  generalTools[idx] = tool;
2313
2520
  toolsReplaced.push(tool.name);
@@ -2323,7 +2530,9 @@ async function importToolsCommand(agentId, options) {
2323
2530
  }
2324
2531
  }
2325
2532
  if (importData.tools.states) {
2326
- for (const [stateName, tools2] of Object.entries(importData.tools.states)) {
2533
+ for (const [stateName, tools2] of Object.entries(
2534
+ importData.tools.states
2535
+ )) {
2327
2536
  const stateIndex = states.findIndex((s) => s.name === stateName);
2328
2537
  if (stateIndex === -1) {
2329
2538
  outputError(
@@ -2336,7 +2545,9 @@ async function importToolsCommand(agentId, options) {
2336
2545
  for (const tool of tools2) {
2337
2546
  if (existingNames.has(tool.name)) {
2338
2547
  if (options.replace) {
2339
- const idx = stateTools.findIndex((t) => t.name === tool.name);
2548
+ const idx = stateTools.findIndex(
2549
+ (t) => t.name === tool.name
2550
+ );
2340
2551
  if (idx !== -1) {
2341
2552
  stateTools[idx] = tool;
2342
2553
  toolsReplaced.push(`${stateName}/${tool.name}`);
@@ -2350,7 +2561,10 @@ async function importToolsCommand(agentId, options) {
2350
2561
  existingNames.add(tool.name);
2351
2562
  }
2352
2563
  }
2353
- states[stateIndex] = { ...states[stateIndex], tools: stateTools };
2564
+ states[stateIndex] = {
2565
+ ...states[stateIndex],
2566
+ tools: stateTools
2567
+ };
2354
2568
  }
2355
2569
  }
2356
2570
  if (options.dryRun) {
@@ -2410,7 +2624,9 @@ async function importToolsCommand(agentId, options) {
2410
2624
  }
2411
2625
  }
2412
2626
  if (importData.tools.components) {
2413
- for (const [compId, tools2] of Object.entries(importData.tools.components)) {
2627
+ for (const [compId, tools2] of Object.entries(
2628
+ importData.tools.components
2629
+ )) {
2414
2630
  const compIndex = components.findIndex((c) => c.name === compId);
2415
2631
  if (compIndex === -1) {
2416
2632
  outputError(
@@ -2423,7 +2639,9 @@ async function importToolsCommand(agentId, options) {
2423
2639
  for (const tool of tools2) {
2424
2640
  if (existingNames.has(tool.name)) {
2425
2641
  if (options.replace) {
2426
- const idx = compTools.findIndex((t) => t.name === tool.name);
2642
+ const idx = compTools.findIndex(
2643
+ (t) => t.name === tool.name
2644
+ );
2427
2645
  if (idx !== -1) {
2428
2646
  compTools[idx] = tool;
2429
2647
  toolsReplaced.push(`${compId}/${tool.name}`);
@@ -2437,7 +2655,10 @@ async function importToolsCommand(agentId, options) {
2437
2655
  existingNames.add(tool.name);
2438
2656
  }
2439
2657
  }
2440
- components[compIndex] = { ...components[compIndex], tools: compTools };
2658
+ components[compIndex] = {
2659
+ ...components[compIndex],
2660
+ tools: compTools
2661
+ };
2441
2662
  }
2442
2663
  }
2443
2664
  if (options.dryRun) {
@@ -2483,7 +2704,7 @@ async function apiRequest(method, path, body) {
2483
2704
  const response = await fetch(`${BASE_URL}${path}`, {
2484
2705
  method,
2485
2706
  headers: {
2486
- "Authorization": `Bearer ${config.apiKey}`,
2707
+ Authorization: `Bearer ${config.apiKey}`,
2487
2708
  "Content-Type": "application/json"
2488
2709
  },
2489
2710
  body: body ? JSON.stringify(body) : void 0
@@ -2566,42 +2787,35 @@ async function listBatchTests(responseEngine) {
2566
2787
  );
2567
2788
  }
2568
2789
  async function getBatchTest(batchJobId) {
2569
- return apiRequest(
2570
- "GET",
2571
- `/get-batch-test/${batchJobId}`
2572
- );
2790
+ return apiRequest("GET", `/get-batch-test/${batchJobId}`);
2573
2791
  }
2574
2792
  async function createBatchTest(params) {
2575
- return apiRequest(
2576
- "POST",
2577
- "/create-batch-test",
2578
- params
2579
- );
2793
+ return apiRequest("POST", "/create-batch-test", params);
2580
2794
  }
2581
2795
  async function listTestRuns(batchJobId) {
2582
- return apiRequest(
2583
- "GET",
2584
- `/list-test-runs/${batchJobId}`
2585
- );
2796
+ return apiRequest("GET", `/list-test-runs/${batchJobId}`);
2586
2797
  }
2587
2798
  async function getTestRun(testRunId) {
2588
- return apiRequest(
2589
- "GET",
2590
- `/get-test-run/${testRunId}`
2591
- );
2799
+ return apiRequest("GET", `/get-test-run/${testRunId}`);
2592
2800
  }
2593
2801
 
2594
2802
  // src/commands/tests/cases/list.ts
2595
2803
  function buildResponseEngine(options) {
2596
2804
  if (options.type === "retell-llm") {
2597
2805
  if (!options.llmId) {
2598
- outputError("--llm-id is required when type is retell-llm", "MISSING_PARAMETER");
2806
+ outputError(
2807
+ "--llm-id is required when type is retell-llm",
2808
+ "MISSING_PARAMETER"
2809
+ );
2599
2810
  return null;
2600
2811
  }
2601
2812
  return { type: "retell-llm", llm_id: options.llmId };
2602
2813
  } else {
2603
2814
  if (!options.flowId) {
2604
- outputError("--flow-id is required when type is conversation-flow", "MISSING_PARAMETER");
2815
+ outputError(
2816
+ "--flow-id is required when type is conversation-flow",
2817
+ "MISSING_PARAMETER"
2818
+ );
2605
2819
  return null;
2606
2820
  }
2607
2821
  return { type: "conversation-flow", conversation_flow_id: options.flowId };
@@ -2610,8 +2824,7 @@ function buildResponseEngine(options) {
2610
2824
  async function listTestCasesCommand(options) {
2611
2825
  try {
2612
2826
  const responseEngine = buildResponseEngine(options);
2613
- if (!responseEngine)
2614
- return;
2827
+ if (!responseEngine) return;
2615
2828
  const testCases = await listTestCaseDefinitions(responseEngine);
2616
2829
  const output = {
2617
2830
  response_engine: responseEngine,
@@ -2619,7 +2832,10 @@ async function listTestCasesCommand(options) {
2619
2832
  total_count: (testCases || []).length
2620
2833
  };
2621
2834
  if (options.fields) {
2622
- const filtered = filterFields(output, options.fields.split(",").map((f) => f.trim()));
2835
+ const filtered = filterFields(
2836
+ output,
2837
+ options.fields.split(",").map((f) => f.trim())
2838
+ );
2623
2839
  outputJson(filtered);
2624
2840
  } else {
2625
2841
  outputJson(output);
@@ -2634,7 +2850,10 @@ async function getTestCaseCommand(testCaseDefinitionId, options) {
2634
2850
  try {
2635
2851
  const testCase = await getTestCaseDefinition(testCaseDefinitionId);
2636
2852
  if (options.fields) {
2637
- const filtered = filterFields(testCase, options.fields.split(",").map((f) => f.trim()));
2853
+ const filtered = filterFields(
2854
+ testCase,
2855
+ options.fields.split(",").map((f) => f.trim())
2856
+ );
2638
2857
  outputJson(filtered);
2639
2858
  } else {
2640
2859
  outputJson(testCase);
@@ -2648,21 +2867,33 @@ async function getTestCaseCommand(testCaseDefinitionId, options) {
2648
2867
  var import_fs9 = require("fs");
2649
2868
  function buildResponseEngine2(options) {
2650
2869
  if (options.llmId && options.flowId) {
2651
- outputError("Cannot specify both --llm-id and --flow-id", "INVALID_PARAMETERS");
2870
+ outputError(
2871
+ "Cannot specify both --llm-id and --flow-id",
2872
+ "INVALID_PARAMETERS"
2873
+ );
2652
2874
  return null;
2653
2875
  }
2654
2876
  if (!options.llmId && !options.flowId) {
2655
- outputError("Either --llm-id or --flow-id is required", "MISSING_PARAMETER");
2877
+ outputError(
2878
+ "Either --llm-id or --flow-id is required",
2879
+ "MISSING_PARAMETER"
2880
+ );
2656
2881
  return null;
2657
2882
  }
2658
2883
  if (options.llmId) {
2659
- const engine = { type: "retell-llm", llm_id: options.llmId };
2884
+ const engine = {
2885
+ type: "retell-llm",
2886
+ llm_id: options.llmId
2887
+ };
2660
2888
  if (options.version !== void 0) {
2661
2889
  engine.version = options.version;
2662
2890
  }
2663
2891
  return engine;
2664
2892
  } else {
2665
- const engine = { type: "conversation-flow", conversation_flow_id: options.flowId };
2893
+ const engine = {
2894
+ type: "conversation-flow",
2895
+ conversation_flow_id: options.flowId
2896
+ };
2666
2897
  if (options.version !== void 0) {
2667
2898
  engine.version = options.version;
2668
2899
  }
@@ -2672,7 +2903,10 @@ function buildResponseEngine2(options) {
2672
2903
  async function createTestCaseCommand(options) {
2673
2904
  try {
2674
2905
  if (!(0, import_fs9.existsSync)(options.file)) {
2675
- outputError(`Test case file not found: ${options.file}`, "FILE_NOT_FOUND");
2906
+ outputError(
2907
+ `Test case file not found: ${options.file}`,
2908
+ "FILE_NOT_FOUND"
2909
+ );
2676
2910
  return;
2677
2911
  }
2678
2912
  let input;
@@ -2681,9 +2915,15 @@ async function createTestCaseCommand(options) {
2681
2915
  input = JSON.parse(content);
2682
2916
  } catch (error) {
2683
2917
  if (error instanceof SyntaxError) {
2684
- outputError(`Invalid JSON in test case file: ${error.message}`, "INVALID_JSON");
2918
+ outputError(
2919
+ `Invalid JSON in test case file: ${error.message}`,
2920
+ "INVALID_JSON"
2921
+ );
2685
2922
  } else {
2686
- outputError(`Error reading test case file: ${error.message}`, "FILE_READ_ERROR");
2923
+ outputError(
2924
+ `Error reading test case file: ${error.message}`,
2925
+ "FILE_READ_ERROR"
2926
+ );
2687
2927
  }
2688
2928
  return;
2689
2929
  }
@@ -2692,14 +2932,16 @@ async function createTestCaseCommand(options) {
2692
2932
  return;
2693
2933
  }
2694
2934
  const responseEngine = buildResponseEngine2(options);
2695
- if (!responseEngine)
2696
- return;
2935
+ if (!responseEngine) return;
2697
2936
  const testCase = await createTestCaseDefinition({
2698
2937
  name: input.name,
2699
2938
  user_prompt: input.user_prompt,
2700
2939
  scenario: input.scenario,
2701
2940
  metrics: input.metrics,
2702
- response_engine: responseEngine
2941
+ response_engine: responseEngine,
2942
+ dynamic_variables: input.dynamic_variables,
2943
+ tool_mocks: input.tool_mocks,
2944
+ llm_model: input.llm_model
2703
2945
  });
2704
2946
  const output = {
2705
2947
  message: "Test case definition created successfully",
@@ -2723,7 +2965,10 @@ var import_fs10 = require("fs");
2723
2965
  async function updateTestCaseCommand(testCaseDefinitionId, options) {
2724
2966
  try {
2725
2967
  if (!(0, import_fs10.existsSync)(options.file)) {
2726
- outputError(`Test case file not found: ${options.file}`, "FILE_NOT_FOUND");
2968
+ outputError(
2969
+ `Test case file not found: ${options.file}`,
2970
+ "FILE_NOT_FOUND"
2971
+ );
2727
2972
  return;
2728
2973
  }
2729
2974
  let input;
@@ -2732,9 +2977,15 @@ async function updateTestCaseCommand(testCaseDefinitionId, options) {
2732
2977
  input = JSON.parse(content);
2733
2978
  } catch (error) {
2734
2979
  if (error instanceof SyntaxError) {
2735
- outputError(`Invalid JSON in test case file: ${error.message}`, "INVALID_JSON");
2980
+ outputError(
2981
+ `Invalid JSON in test case file: ${error.message}`,
2982
+ "INVALID_JSON"
2983
+ );
2736
2984
  } else {
2737
- outputError(`Error reading test case file: ${error.message}`, "FILE_READ_ERROR");
2985
+ outputError(
2986
+ `Error reading test case file: ${error.message}`,
2987
+ "FILE_READ_ERROR"
2988
+ );
2738
2989
  }
2739
2990
  return;
2740
2991
  }
@@ -2742,7 +2993,10 @@ async function updateTestCaseCommand(testCaseDefinitionId, options) {
2742
2993
  name: input.name,
2743
2994
  user_prompt: input.user_prompt,
2744
2995
  scenario: input.scenario,
2745
- metrics: input.metrics
2996
+ metrics: input.metrics,
2997
+ dynamic_variables: input.dynamic_variables,
2998
+ tool_mocks: input.tool_mocks,
2999
+ llm_model: input.llm_model
2746
3000
  });
2747
3001
  const output = {
2748
3002
  message: "Test case definition updated successfully",
@@ -2779,13 +3033,19 @@ async function deleteTestCaseCommand(testCaseDefinitionId) {
2779
3033
  function buildResponseEngine3(options) {
2780
3034
  if (options.type === "retell-llm") {
2781
3035
  if (!options.llmId) {
2782
- outputError("--llm-id is required when type is retell-llm", "MISSING_PARAMETER");
3036
+ outputError(
3037
+ "--llm-id is required when type is retell-llm",
3038
+ "MISSING_PARAMETER"
3039
+ );
2783
3040
  return null;
2784
3041
  }
2785
3042
  return { type: "retell-llm", llm_id: options.llmId };
2786
3043
  } else {
2787
3044
  if (!options.flowId) {
2788
- outputError("--flow-id is required when type is conversation-flow", "MISSING_PARAMETER");
3045
+ outputError(
3046
+ "--flow-id is required when type is conversation-flow",
3047
+ "MISSING_PARAMETER"
3048
+ );
2789
3049
  return null;
2790
3050
  }
2791
3051
  return { type: "conversation-flow", conversation_flow_id: options.flowId };
@@ -2794,8 +3054,7 @@ function buildResponseEngine3(options) {
2794
3054
  async function listBatchTestsCommand(options) {
2795
3055
  try {
2796
3056
  const responseEngine = buildResponseEngine3(options);
2797
- if (!responseEngine)
2798
- return;
3057
+ if (!responseEngine) return;
2799
3058
  const batchTests = await listBatchTests(responseEngine);
2800
3059
  const output = {
2801
3060
  response_engine: responseEngine,
@@ -2803,7 +3062,10 @@ async function listBatchTestsCommand(options) {
2803
3062
  total_count: (batchTests || []).length
2804
3063
  };
2805
3064
  if (options.fields) {
2806
- const filtered = filterFields(output, options.fields.split(",").map((f) => f.trim()));
3065
+ const filtered = filterFields(
3066
+ output,
3067
+ options.fields.split(",").map((f) => f.trim())
3068
+ );
2807
3069
  outputJson(filtered);
2808
3070
  } else {
2809
3071
  outputJson(output);
@@ -2818,7 +3080,10 @@ async function getBatchTestCommand(batchJobId, options) {
2818
3080
  try {
2819
3081
  const batchTest = await getBatchTest(batchJobId);
2820
3082
  if (options.fields) {
2821
- const filtered = filterFields(batchTest, options.fields.split(",").map((f) => f.trim()));
3083
+ const filtered = filterFields(
3084
+ batchTest,
3085
+ options.fields.split(",").map((f) => f.trim())
3086
+ );
2822
3087
  outputJson(filtered);
2823
3088
  } else {
2824
3089
  outputJson(batchTest);
@@ -2831,21 +3096,33 @@ async function getBatchTestCommand(batchJobId, options) {
2831
3096
  // src/commands/tests/batch/create.ts
2832
3097
  function buildResponseEngine4(options) {
2833
3098
  if (options.llmId && options.flowId) {
2834
- outputError("Cannot specify both --llm-id and --flow-id", "INVALID_PARAMETERS");
3099
+ outputError(
3100
+ "Cannot specify both --llm-id and --flow-id",
3101
+ "INVALID_PARAMETERS"
3102
+ );
2835
3103
  return null;
2836
3104
  }
2837
3105
  if (!options.llmId && !options.flowId) {
2838
- outputError("Either --llm-id or --flow-id is required", "MISSING_PARAMETER");
3106
+ outputError(
3107
+ "Either --llm-id or --flow-id is required",
3108
+ "MISSING_PARAMETER"
3109
+ );
2839
3110
  return null;
2840
3111
  }
2841
3112
  if (options.llmId) {
2842
- const engine = { type: "retell-llm", llm_id: options.llmId };
3113
+ const engine = {
3114
+ type: "retell-llm",
3115
+ llm_id: options.llmId
3116
+ };
2843
3117
  if (options.version !== void 0) {
2844
3118
  engine.version = options.version;
2845
3119
  }
2846
3120
  return engine;
2847
3121
  } else {
2848
- const engine = { type: "conversation-flow", conversation_flow_id: options.flowId };
3122
+ const engine = {
3123
+ type: "conversation-flow",
3124
+ conversation_flow_id: options.flowId
3125
+ };
2849
3126
  if (options.version !== void 0) {
2850
3127
  engine.version = options.version;
2851
3128
  }
@@ -2855,11 +3132,13 @@ function buildResponseEngine4(options) {
2855
3132
  async function createBatchTestCommand(options) {
2856
3133
  try {
2857
3134
  const responseEngine = buildResponseEngine4(options);
2858
- if (!responseEngine)
2859
- return;
3135
+ if (!responseEngine) return;
2860
3136
  const testCaseDefinitionIds = options.cases.split(",").map((id) => id.trim()).filter(Boolean);
2861
3137
  if (testCaseDefinitionIds.length === 0) {
2862
- outputError("At least one test case definition ID is required", "MISSING_PARAMETER");
3138
+ outputError(
3139
+ "At least one test case definition ID is required",
3140
+ "MISSING_PARAMETER"
3141
+ );
2863
3142
  return;
2864
3143
  }
2865
3144
  const batchTest = await createBatchTest({
@@ -2889,7 +3168,10 @@ async function listTestRunsCommand(batchJobId, options) {
2889
3168
  total_count: (testRuns || []).length
2890
3169
  };
2891
3170
  if (options.fields) {
2892
- const filtered = filterFields(output, options.fields.split(",").map((f) => f.trim()));
3171
+ const filtered = filterFields(
3172
+ output,
3173
+ options.fields.split(",").map((f) => f.trim())
3174
+ );
2893
3175
  outputJson(filtered);
2894
3176
  } else {
2895
3177
  outputJson(output);
@@ -2904,7 +3186,10 @@ async function getTestRunCommand(testRunId, options) {
2904
3186
  try {
2905
3187
  const testRun = await getTestRun(testRunId);
2906
3188
  if (options.fields) {
2907
- const filtered = filterFields(testRun, options.fields.split(",").map((f) => f.trim()));
3189
+ const filtered = filterFields(
3190
+ testRun,
3191
+ options.fields.split(",").map((f) => f.trim())
3192
+ );
2908
3193
  outputJson(filtered);
2909
3194
  } else {
2910
3195
  outputJson(testRun);
@@ -2919,7 +3204,10 @@ async function listKnowledgeBasesCommand(options) {
2919
3204
  try {
2920
3205
  const client = getRetellClient();
2921
3206
  const knowledgeBases = await client.knowledgeBase.list();
2922
- const output = options.fields ? filterFields(knowledgeBases, options.fields.split(",").map((f) => f.trim())) : knowledgeBases;
3207
+ const output = options.fields ? filterFields(
3208
+ knowledgeBases,
3209
+ options.fields.split(",").map((f) => f.trim())
3210
+ ) : knowledgeBases;
2923
3211
  outputJson(output);
2924
3212
  } catch (error) {
2925
3213
  handleSdkError(error);
@@ -2931,7 +3219,10 @@ async function getKnowledgeBaseCommand(knowledgeBaseId, options) {
2931
3219
  try {
2932
3220
  const client = getRetellClient();
2933
3221
  const knowledgeBase = await client.knowledgeBase.retrieve(knowledgeBaseId);
2934
- const output = options.fields ? filterFields(knowledgeBase, options.fields.split(",").map((f) => f.trim())) : knowledgeBase;
3222
+ const output = options.fields ? filterFields(
3223
+ knowledgeBase,
3224
+ options.fields.split(",").map((f) => f.trim())
3225
+ ) : knowledgeBase;
2935
3226
  outputJson(output);
2936
3227
  } catch (error) {
2937
3228
  handleSdkError(error);
@@ -2943,7 +3234,10 @@ var import_fs11 = require("fs");
2943
3234
  async function createKnowledgeBaseCommand(options) {
2944
3235
  try {
2945
3236
  if (options.name.length > 40) {
2946
- outputError("Knowledge base name must be 40 characters or less", "INVALID_NAME");
3237
+ outputError(
3238
+ "Knowledge base name must be 40 characters or less",
3239
+ "INVALID_NAME"
3240
+ );
2947
3241
  return;
2948
3242
  }
2949
3243
  const createParams = {
@@ -2967,27 +3261,40 @@ async function createKnowledgeBaseCommand(options) {
2967
3261
  const content = (0, import_fs11.readFileSync)(options.texts, "utf-8");
2968
3262
  const textsData = JSON.parse(content);
2969
3263
  if (!Array.isArray(textsData)) {
2970
- outputError("Texts file must contain an array of { title, text } objects", "INVALID_TEXTS");
3264
+ outputError(
3265
+ "Texts file must contain an array of { title, text } objects",
3266
+ "INVALID_TEXTS"
3267
+ );
2971
3268
  return;
2972
3269
  }
2973
- const texts = textsData.map((entry, index) => {
2974
- if (typeof entry !== "object" || entry === null) {
2975
- throw new Error(`Entry at index ${index} must be an object`);
2976
- }
2977
- const e = entry;
2978
- if (typeof e.title !== "string" || typeof e.text !== "string") {
2979
- throw new Error(`Entry at index ${index} must have "title" and "text" string fields`);
3270
+ const texts = textsData.map(
3271
+ (entry, index) => {
3272
+ if (typeof entry !== "object" || entry === null) {
3273
+ throw new Error(`Entry at index ${index} must be an object`);
3274
+ }
3275
+ const e = entry;
3276
+ if (typeof e.title !== "string" || typeof e.text !== "string") {
3277
+ throw new Error(
3278
+ `Entry at index ${index} must have "title" and "text" string fields`
3279
+ );
3280
+ }
3281
+ return { title: e.title, text: e.text };
2980
3282
  }
2981
- return { title: e.title, text: e.text };
2982
- });
3283
+ );
2983
3284
  if (texts.length > 0) {
2984
3285
  createParams.knowledge_base_texts = texts;
2985
3286
  }
2986
3287
  } catch (error) {
2987
3288
  if (error instanceof SyntaxError) {
2988
- outputError(`Invalid JSON in texts file: ${error.message}`, "INVALID_JSON");
3289
+ outputError(
3290
+ `Invalid JSON in texts file: ${error.message}`,
3291
+ "INVALID_JSON"
3292
+ );
2989
3293
  } else if (error instanceof Error) {
2990
- outputError(`Error parsing texts file: ${error.message}`, "INVALID_TEXTS");
3294
+ outputError(
3295
+ `Error parsing texts file: ${error.message}`,
3296
+ "INVALID_TEXTS"
3297
+ );
2991
3298
  }
2992
3299
  return;
2993
3300
  }
@@ -3031,7 +3338,10 @@ var import_fs12 = require("fs");
3031
3338
  async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
3032
3339
  try {
3033
3340
  if (!options.urls && !options.texts) {
3034
- outputError("At least one of --urls or --texts must be provided", "MISSING_SOURCES");
3341
+ outputError(
3342
+ "At least one of --urls or --texts must be provided",
3343
+ "MISSING_SOURCES"
3344
+ );
3035
3345
  return;
3036
3346
  }
3037
3347
  const addParams = {};
@@ -3050,33 +3360,49 @@ async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
3050
3360
  const content = (0, import_fs12.readFileSync)(options.texts, "utf-8");
3051
3361
  const textsData = JSON.parse(content);
3052
3362
  if (!Array.isArray(textsData)) {
3053
- outputError("Texts file must contain an array of { title, text } objects", "INVALID_TEXTS");
3363
+ outputError(
3364
+ "Texts file must contain an array of { title, text } objects",
3365
+ "INVALID_TEXTS"
3366
+ );
3054
3367
  return;
3055
3368
  }
3056
- const texts = textsData.map((entry, index) => {
3057
- if (typeof entry !== "object" || entry === null) {
3058
- throw new Error(`Entry at index ${index} must be an object`);
3059
- }
3060
- const e = entry;
3061
- if (typeof e.title !== "string" || typeof e.text !== "string") {
3062
- throw new Error(`Entry at index ${index} must have "title" and "text" string fields`);
3369
+ const texts = textsData.map(
3370
+ (entry, index) => {
3371
+ if (typeof entry !== "object" || entry === null) {
3372
+ throw new Error(`Entry at index ${index} must be an object`);
3373
+ }
3374
+ const e = entry;
3375
+ if (typeof e.title !== "string" || typeof e.text !== "string") {
3376
+ throw new Error(
3377
+ `Entry at index ${index} must have "title" and "text" string fields`
3378
+ );
3379
+ }
3380
+ return { title: e.title, text: e.text };
3063
3381
  }
3064
- return { title: e.title, text: e.text };
3065
- });
3382
+ );
3066
3383
  if (texts.length > 0) {
3067
3384
  addParams.knowledge_base_texts = texts;
3068
3385
  }
3069
3386
  } catch (error) {
3070
3387
  if (error instanceof SyntaxError) {
3071
- outputError(`Invalid JSON in texts file: ${error.message}`, "INVALID_JSON");
3388
+ outputError(
3389
+ `Invalid JSON in texts file: ${error.message}`,
3390
+ "INVALID_JSON"
3391
+ );
3072
3392
  } else if (error instanceof Error) {
3073
- outputError(`Error parsing texts file: ${error.message}`, "INVALID_TEXTS");
3393
+ outputError(
3394
+ `Error parsing texts file: ${error.message}`,
3395
+ "INVALID_TEXTS"
3396
+ );
3074
3397
  }
3075
3398
  return;
3076
3399
  }
3077
3400
  }
3078
3401
  const client = getRetellClient();
3079
- const knowledgeBase = await client.knowledgeBase.addSources(knowledgeBaseId, addParams);
3402
+ const knowledgeBase = await client.knowledgeBase.addSources(
3403
+ knowledgeBaseId,
3404
+ addParams
3405
+ );
3080
3406
  const output = {
3081
3407
  message: "Sources added successfully",
3082
3408
  knowledge_base_id: knowledgeBase.knowledge_base_id,
@@ -3097,7 +3423,10 @@ async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
3097
3423
  async function deleteKnowledgeBaseSourceCommand(knowledgeBaseId, sourceId) {
3098
3424
  try {
3099
3425
  const client = getRetellClient();
3100
- const knowledgeBase = await client.knowledgeBase.deleteSource(knowledgeBaseId, sourceId);
3426
+ const knowledgeBase = await client.knowledgeBase.deleteSource(
3427
+ knowledgeBaseId,
3428
+ sourceId
3429
+ );
3101
3430
  const output = {
3102
3431
  message: "Source deleted successfully",
3103
3432
  knowledge_base_id: knowledgeBase.knowledge_base_id,
@@ -3121,7 +3450,10 @@ async function listFlowsCommand(options) {
3121
3450
  const flows2 = await client.conversationFlow.list({
3122
3451
  limit: options.limit || 100
3123
3452
  });
3124
- const output = options.fields ? filterFields(flows2, options.fields.split(",").map((f) => f.trim())) : flows2;
3453
+ const output = options.fields ? filterFields(
3454
+ flows2,
3455
+ options.fields.split(",").map((f) => f.trim())
3456
+ ) : flows2;
3125
3457
  outputJson(output);
3126
3458
  } catch (error) {
3127
3459
  handleSdkError(error);
@@ -3136,8 +3468,14 @@ async function getFlowCommand(conversationFlowId, options) {
3136
3468
  if (options.version !== void 0) {
3137
3469
  retrieveOptions.version = options.version;
3138
3470
  }
3139
- const flow = await client.conversationFlow.retrieve(conversationFlowId, retrieveOptions);
3140
- const output = options.fields ? filterFields(flow, options.fields.split(",").map((f) => f.trim())) : flow;
3471
+ const flow = await client.conversationFlow.retrieve(
3472
+ conversationFlowId,
3473
+ retrieveOptions
3474
+ );
3475
+ const output = options.fields ? filterFields(
3476
+ flow,
3477
+ options.fields.split(",").map((f) => f.trim())
3478
+ ) : flow;
3141
3479
  outputJson(output);
3142
3480
  } catch (error) {
3143
3481
  handleSdkError(error);
@@ -3158,14 +3496,23 @@ async function createFlowCommand(options) {
3158
3496
  flowConfig = JSON.parse(content);
3159
3497
  } catch (error) {
3160
3498
  if (error instanceof SyntaxError) {
3161
- outputError(`Invalid JSON in flow file: ${error.message}`, "INVALID_JSON");
3499
+ outputError(
3500
+ `Invalid JSON in flow file: ${error.message}`,
3501
+ "INVALID_JSON"
3502
+ );
3162
3503
  } else if (error instanceof Error) {
3163
- outputError(`Error reading flow file: ${error.message}`, "FILE_READ_ERROR");
3504
+ outputError(
3505
+ `Error reading flow file: ${error.message}`,
3506
+ "FILE_READ_ERROR"
3507
+ );
3164
3508
  }
3165
3509
  return;
3166
3510
  }
3167
3511
  if (!flowConfig.start_speaker) {
3168
- outputError('Flow configuration must have a "start_speaker" field (user or agent)', "INVALID_FLOW");
3512
+ outputError(
3513
+ 'Flow configuration must have a "start_speaker" field (user or agent)',
3514
+ "INVALID_FLOW"
3515
+ );
3169
3516
  return;
3170
3517
  }
3171
3518
  const client = getRetellClient();
@@ -3196,9 +3543,15 @@ async function updateFlowCommand(conversationFlowId, options) {
3196
3543
  flowUpdates = JSON.parse(content);
3197
3544
  } catch (error) {
3198
3545
  if (error instanceof SyntaxError) {
3199
- outputError(`Invalid JSON in flow file: ${error.message}`, "INVALID_JSON");
3546
+ outputError(
3547
+ `Invalid JSON in flow file: ${error.message}`,
3548
+ "INVALID_JSON"
3549
+ );
3200
3550
  } else if (error instanceof Error) {
3201
- outputError(`Error reading flow file: ${error.message}`, "FILE_READ_ERROR");
3551
+ outputError(
3552
+ `Error reading flow file: ${error.message}`,
3553
+ "FILE_READ_ERROR"
3554
+ );
3202
3555
  }
3203
3556
  return;
3204
3557
  }
@@ -3206,7 +3559,10 @@ async function updateFlowCommand(conversationFlowId, options) {
3206
3559
  flowUpdates.version = options.version;
3207
3560
  }
3208
3561
  const client = getRetellClient();
3209
- const flow = await client.conversationFlow.update(conversationFlowId, flowUpdates);
3562
+ const flow = await client.conversationFlow.update(
3563
+ conversationFlowId,
3564
+ flowUpdates
3565
+ );
3210
3566
  const output = {
3211
3567
  message: "Conversation flow updated successfully",
3212
3568
  conversation_flow_id: flow.conversation_flow_id,
@@ -3241,22 +3597,35 @@ var packageJson = JSON.parse(
3241
3597
  );
3242
3598
  var program = new import_commander.Command();
3243
3599
  program.name("retell").description("Retell AI CLI - Manage transcripts and agent prompts").version(packageJson.version, "-v, --version", "Display version number").helpOption("-h, --help", "Display help for command").option("--json", "Output as JSON (default)", true);
3244
- program.command("login").description("Authenticate with Retell AI").addHelpText("after", `
3600
+ program.command("login").description("Authenticate with Retell AI").addHelpText(
3601
+ "after",
3602
+ `
3245
3603
  Examples:
3246
3604
  $ retell login
3247
3605
  # Enter your API key when prompted
3248
3606
  # Creates .retellrc.json in current directory
3249
- `).action(async () => {
3607
+ `
3608
+ ).action(async () => {
3250
3609
  await loginCommand();
3251
3610
  });
3252
3611
  var transcripts = program.command("transcripts").description("Manage call transcripts");
3253
- transcripts.command("list").description("List all call transcripts").option("-l, --limit <number>", "Maximum number of calls to return (default: 50)", "50").option("--fields <fields>", "Comma-separated list of fields to return (e.g., call_id,call_status,metadata.duration)").addHelpText("after", `
3612
+ transcripts.command("list").description("List all call transcripts").option(
3613
+ "-l, --limit <number>",
3614
+ "Maximum number of calls to return (default: 50)",
3615
+ "50"
3616
+ ).option(
3617
+ "--fields <fields>",
3618
+ "Comma-separated list of fields to return (e.g., call_id,call_status,metadata.duration)"
3619
+ ).addHelpText(
3620
+ "after",
3621
+ `
3254
3622
  Examples:
3255
3623
  $ retell transcripts list
3256
3624
  $ retell transcripts list --limit 100
3257
3625
  $ retell transcripts list --fields call_id,call_status
3258
3626
  $ retell transcripts list | jq '.[] | select(.call_status == "error")'
3259
- `).action(async (options) => {
3627
+ `
3628
+ ).action(async (options) => {
3260
3629
  const limit = parseInt(options.limit, 10);
3261
3630
  if (isNaN(limit) || limit < 1) {
3262
3631
  console.error("Error: limit must be a positive number");
@@ -3267,17 +3636,44 @@ Examples:
3267
3636
  fields: options.fields
3268
3637
  });
3269
3638
  });
3270
- transcripts.command("get <call_id>").description("Get a specific call transcript").option("--fields <fields>", "Comma-separated list of fields to return (e.g., call_id,metadata.duration,analysis)").addHelpText("after", `
3639
+ transcripts.command("get <call_id>").description("Get a specific call transcript").option(
3640
+ "--fields <fields>",
3641
+ "Comma-separated list of fields to return (e.g., call_id,metadata.duration,analysis)"
3642
+ ).addHelpText(
3643
+ "after",
3644
+ `
3271
3645
  Examples:
3272
3646
  $ retell transcripts get call_abc123
3273
3647
  $ retell transcripts get call_abc123 --fields call_id,metadata.duration
3274
3648
  $ retell transcripts get call_abc123 | jq '.transcript_object'
3275
- `).action(async (callId, options) => {
3649
+ `
3650
+ ).action(async (callId, options) => {
3276
3651
  await getTranscriptCommand(callId, {
3277
3652
  fields: options.fields
3278
3653
  });
3279
3654
  });
3280
- transcripts.command("analyze <call_id>").description("Analyze a call transcript with performance metrics and insights").option("--fields <fields>", "Comma-separated list of fields to return (e.g., call_id,performance,analysis.summary)").option("--raw", "Return unmodified API response instead of enriched analysis").option("--hotspots-only", "Return only conversation hotspots/issues for troubleshooting").option("--latency-threshold <ms>", `Latency threshold in ms for hotspot detection (default: ${DEFAULT_LATENCY_THRESHOLD})`, String(DEFAULT_LATENCY_THRESHOLD)).option("--silence-threshold <ms>", `Silence threshold in ms for hotspot detection (default: ${DEFAULT_SILENCE_THRESHOLD})`, String(DEFAULT_SILENCE_THRESHOLD)).addHelpText("after", `
3655
+ transcripts.command("analyze <call_id>").description(
3656
+ "Analyze a call transcript with performance metrics and insights"
3657
+ ).option(
3658
+ "--fields <fields>",
3659
+ "Comma-separated list of fields to return (e.g., call_id,performance,analysis.summary)"
3660
+ ).option(
3661
+ "--raw",
3662
+ "Return unmodified API response instead of enriched analysis"
3663
+ ).option(
3664
+ "--hotspots-only",
3665
+ "Return only conversation hotspots/issues for troubleshooting"
3666
+ ).option(
3667
+ "--latency-threshold <ms>",
3668
+ `Latency threshold in ms for hotspot detection (default: ${DEFAULT_LATENCY_THRESHOLD})`,
3669
+ String(DEFAULT_LATENCY_THRESHOLD)
3670
+ ).option(
3671
+ "--silence-threshold <ms>",
3672
+ `Silence threshold in ms for hotspot detection (default: ${DEFAULT_SILENCE_THRESHOLD})`,
3673
+ String(DEFAULT_SILENCE_THRESHOLD)
3674
+ ).addHelpText(
3675
+ "after",
3676
+ `
3281
3677
  Examples:
3282
3678
  $ retell transcripts analyze call_abc123
3283
3679
  $ retell transcripts analyze call_abc123 --fields call_id,performance
@@ -3287,7 +3683,8 @@ Examples:
3287
3683
  $ retell transcripts analyze call_abc123 --hotspots-only --latency-threshold 1500
3288
3684
  $ retell transcripts analyze call_abc123 --hotspots-only --fields hotspots
3289
3685
  $ retell transcripts analyze call_abc123 | jq '.performance.latency_p50_ms'
3290
- `).action(async (callId, options) => {
3686
+ `
3687
+ ).action(async (callId, options) => {
3291
3688
  await analyzeTranscriptCommand(callId, {
3292
3689
  fields: options.fields,
3293
3690
  raw: options.raw,
@@ -3296,14 +3693,23 @@ Examples:
3296
3693
  silenceThreshold: options.silenceThreshold ? parseInt(options.silenceThreshold) : void 0
3297
3694
  });
3298
3695
  });
3299
- transcripts.command("search").description("Search transcripts with advanced filtering").option("--status <status>", "Filter by call status (error, ended, ongoing)").option("--agent-id <id>", "Filter by agent ID").option("--since <date>", "Filter calls after this date (YYYY-MM-DD or ISO format)").option("--until <date>", "Filter calls before this date (YYYY-MM-DD or ISO format)").option("--limit <number>", "Maximum number of results (default: 50)", "50").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
3696
+ transcripts.command("search").description("Search transcripts with advanced filtering").option("--status <status>", "Filter by call status (error, ended, ongoing)").option("--agent-id <id>", "Filter by agent ID").option(
3697
+ "--since <date>",
3698
+ "Filter calls after this date (YYYY-MM-DD or ISO format)"
3699
+ ).option(
3700
+ "--until <date>",
3701
+ "Filter calls before this date (YYYY-MM-DD or ISO format)"
3702
+ ).option("--limit <number>", "Maximum number of results (default: 50)", "50").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
3703
+ "after",
3704
+ `
3300
3705
  Examples:
3301
3706
  $ retell transcripts search --status error
3302
3707
  $ retell transcripts search --agent-id agent_123 --since 2025-11-01
3303
3708
  $ retell transcripts search --status error --limit 10
3304
3709
  $ retell transcripts search --status error --fields call_id,agent_id,call_status
3305
3710
  $ retell transcripts search --since 2025-11-01 --until 2025-11-15
3306
- `).action(async (options) => {
3711
+ `
3712
+ ).action(async (options) => {
3307
3713
  await searchTranscriptsCommand({
3308
3714
  status: options.status,
3309
3715
  agentId: options.agentId,
@@ -3314,13 +3720,23 @@ Examples:
3314
3720
  });
3315
3721
  });
3316
3722
  var agents = program.command("agents").description("Manage agents");
3317
- agents.command("list").description("List all agents").option("-l, --limit <number>", "Maximum number of agents to return (default: 100)", "100").option("--fields <fields>", "Comma-separated list of fields to return (e.g., agent_id,agent_name,response_engine_type)").addHelpText("after", `
3723
+ agents.command("list").description("List all agents").option(
3724
+ "-l, --limit <number>",
3725
+ "Maximum number of agents to return (default: 100)",
3726
+ "100"
3727
+ ).option(
3728
+ "--fields <fields>",
3729
+ "Comma-separated list of fields to return (e.g., agent_id,agent_name,response_engine_type)"
3730
+ ).addHelpText(
3731
+ "after",
3732
+ `
3318
3733
  Examples:
3319
3734
  $ retell agents list
3320
3735
  $ retell agents list --limit 10
3321
3736
  $ retell agents list --fields agent_id,agent_name
3322
3737
  $ retell agents list | jq '.[] | select(.response_engine.type == "retell-llm")'
3323
- `).action(async (options) => {
3738
+ `
3739
+ ).action(async (options) => {
3324
3740
  const limit = parseInt(options.limit, 10);
3325
3741
  if (isNaN(limit) || limit < 1) {
3326
3742
  console.error("Error: limit must be a positive number");
@@ -3331,78 +3747,126 @@ Examples:
3331
3747
  fields: options.fields
3332
3748
  });
3333
3749
  });
3334
- agents.command("info <agent_id>").description("Get detailed agent information").option("--fields <fields>", "Comma-separated list of fields to return (e.g., agent_name,response_engine.type,voice_config)").addHelpText("after", `
3750
+ agents.command("info <agent_id>").description("Get detailed agent information").option(
3751
+ "--fields <fields>",
3752
+ "Comma-separated list of fields to return (e.g., agent_name,response_engine.type,voice_config)"
3753
+ ).addHelpText(
3754
+ "after",
3755
+ `
3335
3756
  Examples:
3336
3757
  $ retell agents info agent_123abc
3337
3758
  $ retell agents info agent_123abc --fields agent_name,response_engine.type
3338
3759
  $ retell agents info agent_123abc | jq '.response_engine.type'
3339
- `).action(async (agentId, options) => {
3760
+ `
3761
+ ).action(async (agentId, options) => {
3340
3762
  await agentInfoCommand(agentId, {
3341
3763
  fields: options.fields
3342
3764
  });
3343
3765
  });
3344
3766
  var prompts = program.command("prompts").description("Manage agent prompts");
3345
- prompts.command("pull <agent_id>").description("Download agent prompts to a local file").option("-o, --output <path>", "Output file path (default: .retell-prompts/<agent_id>.json)", ".retell-prompts").addHelpText("after", `
3767
+ prompts.command("pull <agent_id>").description("Download agent prompts to a local file").option(
3768
+ "-o, --output <path>",
3769
+ "Output file path (default: .retell-prompts/<agent_id>.json)",
3770
+ ".retell-prompts"
3771
+ ).addHelpText(
3772
+ "after",
3773
+ `
3346
3774
  Examples:
3347
3775
  $ retell prompts pull agent_123abc
3348
3776
  $ retell prompts pull agent_123abc --output my-prompts.json
3349
- `).action(async (agentId, options) => {
3777
+ `
3778
+ ).action(async (agentId, options) => {
3350
3779
  await pullPromptsCommand(agentId, options);
3351
3780
  });
3352
- prompts.command("diff <agent_id>").description("Show differences between local and remote prompts").option("-s, --source <path>", "Source directory path (default: .retell-prompts)", ".retell-prompts").option("-f, --fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
3781
+ prompts.command("diff <agent_id>").description("Show differences between local and remote prompts").option(
3782
+ "-s, --source <path>",
3783
+ "Source directory path (default: .retell-prompts)",
3784
+ ".retell-prompts"
3785
+ ).option("-f, --fields <fields>", "Comma-separated list of fields to return").addHelpText(
3786
+ "after",
3787
+ `
3353
3788
  Examples:
3354
3789
  $ retell prompts diff agent_123abc
3355
3790
  $ retell prompts diff agent_123abc --source ./custom-prompts
3356
3791
  $ retell prompts diff agent_123abc --fields has_changes,changes.general_prompt
3357
- `).action(async (agentId, options) => {
3792
+ `
3793
+ ).action(async (agentId, options) => {
3358
3794
  await diffPromptsCommand(agentId, options);
3359
3795
  });
3360
- prompts.command("update <agent_id>").description("Update agent prompts from a local file").option("-s, --source <path>", "Source file path (default: .retell-prompts/<agent_id>.json)", ".retell-prompts").option("--dry-run", "Preview changes without applying them", false).addHelpText("after", `
3796
+ prompts.command("update <agent_id>").description("Update agent prompts from a local file").option(
3797
+ "-s, --source <path>",
3798
+ "Source file path (default: .retell-prompts/<agent_id>.json)",
3799
+ ".retell-prompts"
3800
+ ).option("--dry-run", "Preview changes without applying them", false).addHelpText(
3801
+ "after",
3802
+ `
3361
3803
  Examples:
3362
3804
  $ retell prompts update agent_123abc --source my-prompts.json --dry-run
3363
3805
  $ retell prompts update agent_123abc --source my-prompts.json
3364
3806
  # Remember to publish: retell agent-publish agent_123abc
3365
- `).action(async (agentId, options) => {
3807
+ `
3808
+ ).action(async (agentId, options) => {
3366
3809
  await updatePromptsCommand(agentId, options);
3367
3810
  });
3368
- program.command("agent-publish <agent_id>").description("Publish a draft agent to make changes live").addHelpText("after", `
3811
+ program.command("agent-publish <agent_id>").description("Publish a draft agent to make changes live").addHelpText(
3812
+ "after",
3813
+ `
3369
3814
  Examples:
3370
3815
  $ retell agent-publish agent_123abc
3371
3816
  # Run this after updating prompts to make changes live
3372
- `).action(async (agentId) => {
3817
+ `
3818
+ ).action(async (agentId) => {
3373
3819
  await publishAgentCommand(agentId);
3374
3820
  });
3375
3821
  var tools = program.command("tools").description("Manage agent tools (custom functions, webhooks, etc.)");
3376
- tools.command("list <agent_id>").description("List all tools configured for an agent").option("--state <name>", "Filter by state name (Retell LLM only)").option("--component <id>", "Filter by component ID (Conversation Flow only)").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
3822
+ tools.command("list <agent_id>").description("List all tools configured for an agent").option("--state <name>", "Filter by state name (Retell LLM only)").option("--component <id>", "Filter by component ID (Conversation Flow only)").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
3823
+ "after",
3824
+ `
3377
3825
  Examples:
3378
3826
  $ retell tools list agent_123abc
3379
3827
  $ retell tools list agent_123abc --state greeting
3380
3828
  $ retell tools list agent_123abc --fields total_count,general_tools
3381
- `).action(async (agentId, options) => {
3829
+ `
3830
+ ).action(async (agentId, options) => {
3382
3831
  await listToolsCommand(agentId, {
3383
3832
  state: options.state,
3384
3833
  component: options.component,
3385
3834
  fields: options.fields
3386
3835
  });
3387
3836
  });
3388
- tools.command("get <agent_id> <tool_name>").description("Get detailed information about a specific tool").option("--state <name>", "State name to search within (Retell LLM only)").option("--component <id>", "Component ID to search within (Conversation Flow only)").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
3837
+ tools.command("get <agent_id> <tool_name>").description("Get detailed information about a specific tool").option("--state <name>", "State name to search within (Retell LLM only)").option(
3838
+ "--component <id>",
3839
+ "Component ID to search within (Conversation Flow only)"
3840
+ ).option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
3841
+ "after",
3842
+ `
3389
3843
  Examples:
3390
3844
  $ retell tools get agent_123abc lookup_customer
3391
3845
  $ retell tools get agent_123abc book_cal --state booking
3392
3846
  $ retell tools get agent_123abc my_tool --fields tool.name,tool.type
3393
- `).action(async (agentId, toolName, options) => {
3847
+ `
3848
+ ).action(async (agentId, toolName, options) => {
3394
3849
  await getToolCommand(agentId, toolName, {
3395
3850
  state: options.state,
3396
3851
  component: options.component,
3397
3852
  fields: options.fields
3398
3853
  });
3399
3854
  });
3400
- tools.command("add <agent_id>").description("Add a new tool to an agent").requiredOption("-f, --file <path>", "Path to JSON file containing tool definition").option("--state <name>", "Add to specific state (Retell LLM only)").option("--component <id>", "Add to specific component (Conversation Flow only)").option("--dry-run", "Preview changes without applying them").addHelpText("after", `
3855
+ tools.command("add <agent_id>").description("Add a new tool to an agent").requiredOption(
3856
+ "-f, --file <path>",
3857
+ "Path to JSON file containing tool definition"
3858
+ ).option("--state <name>", "Add to specific state (Retell LLM only)").option(
3859
+ "--component <id>",
3860
+ "Add to specific component (Conversation Flow only)"
3861
+ ).option("--dry-run", "Preview changes without applying them").addHelpText(
3862
+ "after",
3863
+ `
3401
3864
  Examples:
3402
3865
  $ retell tools add agent_123abc --file tool.json
3403
3866
  $ retell tools add agent_123abc --file tool.json --state booking
3404
3867
  $ retell tools add agent_123abc --file tool.json --dry-run
3405
- `).action(async (agentId, options) => {
3868
+ `
3869
+ ).action(async (agentId, options) => {
3406
3870
  await addToolCommand(agentId, {
3407
3871
  file: options.file,
3408
3872
  state: options.state,
@@ -3410,12 +3874,21 @@ Examples:
3410
3874
  dryRun: options.dryRun
3411
3875
  });
3412
3876
  });
3413
- tools.command("update <agent_id> <tool_name>").description("Update an existing tool").requiredOption("-f, --file <path>", "Path to JSON file containing updated tool definition").option("--state <name>", "State where tool exists (Retell LLM only)").option("--component <id>", "Component where tool exists (Conversation Flow only)").option("--dry-run", "Preview changes without applying them").addHelpText("after", `
3877
+ tools.command("update <agent_id> <tool_name>").description("Update an existing tool").requiredOption(
3878
+ "-f, --file <path>",
3879
+ "Path to JSON file containing updated tool definition"
3880
+ ).option("--state <name>", "State where tool exists (Retell LLM only)").option(
3881
+ "--component <id>",
3882
+ "Component where tool exists (Conversation Flow only)"
3883
+ ).option("--dry-run", "Preview changes without applying them").addHelpText(
3884
+ "after",
3885
+ `
3414
3886
  Examples:
3415
3887
  $ retell tools update agent_123abc lookup_customer --file tool.json
3416
3888
  $ retell tools update agent_123abc book_cal --file tool.json --state booking
3417
3889
  $ retell tools update agent_123abc my_tool --file tool.json --dry-run
3418
- `).action(async (agentId, toolName, options) => {
3890
+ `
3891
+ ).action(async (agentId, toolName, options) => {
3419
3892
  await updateToolCommand(agentId, toolName, {
3420
3893
  file: options.file,
3421
3894
  state: options.state,
@@ -3423,34 +3896,55 @@ Examples:
3423
3896
  dryRun: options.dryRun
3424
3897
  });
3425
3898
  });
3426
- tools.command("remove <agent_id> <tool_name>").description("Remove a tool from an agent").option("--state <name>", "State where tool exists (Retell LLM only)").option("--component <id>", "Component where tool exists (Conversation Flow only)").option("--dry-run", "Preview changes without applying them").addHelpText("after", `
3899
+ tools.command("remove <agent_id> <tool_name>").description("Remove a tool from an agent").option("--state <name>", "State where tool exists (Retell LLM only)").option(
3900
+ "--component <id>",
3901
+ "Component where tool exists (Conversation Flow only)"
3902
+ ).option("--dry-run", "Preview changes without applying them").addHelpText(
3903
+ "after",
3904
+ `
3427
3905
  Examples:
3428
3906
  $ retell tools remove agent_123abc lookup_customer
3429
3907
  $ retell tools remove agent_123abc book_cal --state booking
3430
3908
  $ retell tools remove agent_123abc my_tool --dry-run
3431
- `).action(async (agentId, toolName, options) => {
3909
+ `
3910
+ ).action(async (agentId, toolName, options) => {
3432
3911
  await removeToolCommand(agentId, toolName, {
3433
3912
  state: options.state,
3434
3913
  component: options.component,
3435
3914
  dryRun: options.dryRun
3436
3915
  });
3437
3916
  });
3438
- tools.command("export <agent_id>").description("Export all tools from an agent to a JSON file").option("-o, --output <path>", "Output file path (prints to stdout if not specified)").addHelpText("after", `
3917
+ tools.command("export <agent_id>").description("Export all tools from an agent to a JSON file").option(
3918
+ "-o, --output <path>",
3919
+ "Output file path (prints to stdout if not specified)"
3920
+ ).addHelpText(
3921
+ "after",
3922
+ `
3439
3923
  Examples:
3440
3924
  $ retell tools export agent_123abc
3441
3925
  $ retell tools export agent_123abc --output tools.json
3442
3926
  $ retell tools export agent_123abc > tools.json
3443
- `).action(async (agentId, options) => {
3927
+ `
3928
+ ).action(async (agentId, options) => {
3444
3929
  await exportToolsCommand(agentId, {
3445
3930
  output: options.output
3446
3931
  });
3447
3932
  });
3448
- tools.command("import <agent_id>").description("Import tools from a JSON file to an agent").requiredOption("-f, --file <path>", "Path to JSON file containing tools to import").option("--dry-run", "Preview changes without applying them").option("--replace", "Replace existing tools with same name instead of skipping").addHelpText("after", `
3933
+ tools.command("import <agent_id>").description("Import tools from a JSON file to an agent").requiredOption(
3934
+ "-f, --file <path>",
3935
+ "Path to JSON file containing tools to import"
3936
+ ).option("--dry-run", "Preview changes without applying them").option(
3937
+ "--replace",
3938
+ "Replace existing tools with same name instead of skipping"
3939
+ ).addHelpText(
3940
+ "after",
3941
+ `
3449
3942
  Examples:
3450
3943
  $ retell tools import agent_123abc --file tools.json
3451
3944
  $ retell tools import agent_123abc --file tools.json --dry-run
3452
3945
  $ retell tools import agent_123abc --file tools.json --replace
3453
- `).action(async (agentId, options) => {
3946
+ `
3947
+ ).action(async (agentId, options) => {
3454
3948
  await importToolsCommand(agentId, {
3455
3949
  file: options.file,
3456
3950
  dryRun: options.dryRun,
@@ -3459,12 +3953,18 @@ Examples:
3459
3953
  });
3460
3954
  var tests = program.command("tests").description("Manage test cases, batch tests, and test runs");
3461
3955
  var testsCases = tests.command("cases").description("Manage test case definitions");
3462
- testsCases.command("list").description("List all test case definitions for an LLM or flow").requiredOption("-t, --type <type>", "Response engine type (retell-llm or conversation-flow)").option("--llm-id <id>", "LLM ID (required when type is retell-llm)").option("--flow-id <id>", "Flow ID (required when type is conversation-flow)").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
3956
+ testsCases.command("list").description("List all test case definitions for an LLM or flow").requiredOption(
3957
+ "-t, --type <type>",
3958
+ "Response engine type (retell-llm or conversation-flow)"
3959
+ ).option("--llm-id <id>", "LLM ID (required when type is retell-llm)").option("--flow-id <id>", "Flow ID (required when type is conversation-flow)").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
3960
+ "after",
3961
+ `
3463
3962
  Examples:
3464
3963
  $ retell tests cases list --type retell-llm --llm-id llm_abc123
3465
3964
  $ retell tests cases list --type conversation-flow --flow-id cf_abc123
3466
3965
  $ retell tests cases list --type retell-llm --llm-id llm_abc123 --fields test_case_definitions
3467
- `).action(async (options) => {
3966
+ `
3967
+ ).action(async (options) => {
3468
3968
  if (options.type !== "retell-llm" && options.type !== "conversation-flow") {
3469
3969
  console.error('Error: type must be "retell-llm" or "conversation-flow"');
3470
3970
  process.exit(1);
@@ -3476,16 +3976,24 @@ Examples:
3476
3976
  fields: options.fields
3477
3977
  });
3478
3978
  });
3479
- testsCases.command("get <test_case_definition_id>").description("Get a specific test case definition").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
3979
+ testsCases.command("get <test_case_definition_id>").description("Get a specific test case definition").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
3980
+ "after",
3981
+ `
3480
3982
  Examples:
3481
3983
  $ retell tests cases get tcd_abc123
3482
3984
  $ retell tests cases get tcd_abc123 --fields name,user_prompt
3483
- `).action(async (testCaseDefinitionId, options) => {
3985
+ `
3986
+ ).action(async (testCaseDefinitionId, options) => {
3484
3987
  await getTestCaseCommand(testCaseDefinitionId, {
3485
3988
  fields: options.fields
3486
3989
  });
3487
3990
  });
3488
- testsCases.command("create").description("Create a new test case definition from a JSON file").requiredOption("-f, --file <path>", "Path to JSON file containing test case definition").option("--llm-id <id>", "LLM ID (mutually exclusive with --flow-id)").option("--flow-id <id>", "Flow ID (mutually exclusive with --llm-id)").option("--version <number>", "Version of the LLM or flow (optional)").addHelpText("after", `
3991
+ testsCases.command("create").description("Create a new test case definition from a JSON file").requiredOption(
3992
+ "-f, --file <path>",
3993
+ "Path to JSON file containing test case definition"
3994
+ ).option("--llm-id <id>", "LLM ID (mutually exclusive with --flow-id)").option("--flow-id <id>", "Flow ID (mutually exclusive with --llm-id)").option("--version <number>", "Version of the LLM or flow (optional)").addHelpText(
3995
+ "after",
3996
+ `
3489
3997
  Examples:
3490
3998
  $ retell tests cases create --file test-case.json --llm-id llm_abc123
3491
3999
  $ retell tests cases create --file test-case.json --flow-id cf_abc123
@@ -3498,7 +4006,8 @@ Test case JSON format:
3498
4006
  "scenario": "User is calling about an order issue",
3499
4007
  "metrics": ["response_quality", "task_completion"]
3500
4008
  }
3501
- `).action(async (options) => {
4009
+ `
4010
+ ).action(async (options) => {
3502
4011
  await createTestCaseCommand({
3503
4012
  file: options.file,
3504
4013
  llmId: options.llmId,
@@ -3506,27 +4015,42 @@ Test case JSON format:
3506
4015
  version: options.version ? parseInt(options.version, 10) : void 0
3507
4016
  });
3508
4017
  });
3509
- testsCases.command("update <test_case_definition_id>").description("Update an existing test case definition from a JSON file").requiredOption("-f, --file <path>", "Path to JSON file containing test case updates").addHelpText("after", `
4018
+ testsCases.command("update <test_case_definition_id>").description("Update an existing test case definition from a JSON file").requiredOption(
4019
+ "-f, --file <path>",
4020
+ "Path to JSON file containing test case updates"
4021
+ ).addHelpText(
4022
+ "after",
4023
+ `
3510
4024
  Examples:
3511
4025
  $ retell tests cases update tcd_abc123 --file test-case.json
3512
- `).action(async (testCaseDefinitionId, options) => {
4026
+ `
4027
+ ).action(async (testCaseDefinitionId, options) => {
3513
4028
  await updateTestCaseCommand(testCaseDefinitionId, {
3514
4029
  file: options.file
3515
4030
  });
3516
4031
  });
3517
- testsCases.command("delete <test_case_definition_id>").description("Delete a test case definition").addHelpText("after", `
4032
+ testsCases.command("delete <test_case_definition_id>").description("Delete a test case definition").addHelpText(
4033
+ "after",
4034
+ `
3518
4035
  Examples:
3519
4036
  $ retell tests cases delete tcd_abc123
3520
- `).action(async (testCaseDefinitionId) => {
4037
+ `
4038
+ ).action(async (testCaseDefinitionId) => {
3521
4039
  await deleteTestCaseCommand(testCaseDefinitionId);
3522
4040
  });
3523
4041
  var testsBatch = tests.command("batch").description("Manage batch tests");
3524
- testsBatch.command("list").description("List all batch tests for an LLM or flow").requiredOption("-t, --type <type>", "Response engine type (retell-llm or conversation-flow)").option("--llm-id <id>", "LLM ID (required when type is retell-llm)").option("--flow-id <id>", "Flow ID (required when type is conversation-flow)").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
4042
+ testsBatch.command("list").description("List all batch tests for an LLM or flow").requiredOption(
4043
+ "-t, --type <type>",
4044
+ "Response engine type (retell-llm or conversation-flow)"
4045
+ ).option("--llm-id <id>", "LLM ID (required when type is retell-llm)").option("--flow-id <id>", "Flow ID (required when type is conversation-flow)").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
4046
+ "after",
4047
+ `
3525
4048
  Examples:
3526
4049
  $ retell tests batch list --type retell-llm --llm-id llm_abc123
3527
4050
  $ retell tests batch list --type conversation-flow --flow-id cf_abc123
3528
4051
  $ retell tests batch list --type retell-llm --llm-id llm_abc123 --fields batch_tests
3529
- `).action(async (options) => {
4052
+ `
4053
+ ).action(async (options) => {
3530
4054
  if (options.type !== "retell-llm" && options.type !== "conversation-flow") {
3531
4055
  console.error('Error: type must be "retell-llm" or "conversation-flow"');
3532
4056
  process.exit(1);
@@ -3538,21 +4062,30 @@ Examples:
3538
4062
  fields: options.fields
3539
4063
  });
3540
4064
  });
3541
- testsBatch.command("get <batch_job_id>").description("Get a specific batch test with its status and stats").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
4065
+ testsBatch.command("get <batch_job_id>").description("Get a specific batch test with its status and stats").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
4066
+ "after",
4067
+ `
3542
4068
  Examples:
3543
4069
  $ retell tests batch get bjj_abc123
3544
4070
  $ retell tests batch get bjj_abc123 --fields status,stats
3545
- `).action(async (batchJobId, options) => {
4071
+ `
4072
+ ).action(async (batchJobId, options) => {
3546
4073
  await getBatchTestCommand(batchJobId, {
3547
4074
  fields: options.fields
3548
4075
  });
3549
4076
  });
3550
- testsBatch.command("create").description("Create a new batch test with specified test case definitions").option("--llm-id <id>", "LLM ID (mutually exclusive with --flow-id)").option("--flow-id <id>", "Flow ID (mutually exclusive with --llm-id)").requiredOption("--cases <ids>", "Comma-separated list of test case definition IDs").option("--version <number>", "Version of the LLM or flow (optional)").addHelpText("after", `
4077
+ testsBatch.command("create").description("Create a new batch test with specified test case definitions").option("--llm-id <id>", "LLM ID (mutually exclusive with --flow-id)").option("--flow-id <id>", "Flow ID (mutually exclusive with --llm-id)").requiredOption(
4078
+ "--cases <ids>",
4079
+ "Comma-separated list of test case definition IDs"
4080
+ ).option("--version <number>", "Version of the LLM or flow (optional)").addHelpText(
4081
+ "after",
4082
+ `
3551
4083
  Examples:
3552
4084
  $ retell tests batch create --llm-id llm_abc123 --cases tcd_xxx,tcd_yyy,tcd_zzz
3553
4085
  $ retell tests batch create --flow-id cf_abc123 --cases tcd_xxx,tcd_yyy
3554
4086
  $ retell tests batch create --llm-id llm_abc123 --cases tcd_xxx --version 2
3555
- `).action(async (options) => {
4087
+ `
4088
+ ).action(async (options) => {
3556
4089
  await createBatchTestCommand({
3557
4090
  llmId: options.llmId,
3558
4091
  flowId: options.flowId,
@@ -3561,44 +4094,64 @@ Examples:
3561
4094
  });
3562
4095
  });
3563
4096
  var testsRuns = tests.command("runs").description("View test run results");
3564
- testsRuns.command("list <batch_job_id>").description("List all test runs for a batch test").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
4097
+ testsRuns.command("list <batch_job_id>").description("List all test runs for a batch test").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
4098
+ "after",
4099
+ `
3565
4100
  Examples:
3566
4101
  $ retell tests runs list bjj_abc123
3567
4102
  $ retell tests runs list bjj_abc123 --fields test_runs
3568
- `).action(async (batchJobId, options) => {
4103
+ `
4104
+ ).action(async (batchJobId, options) => {
3569
4105
  await listTestRunsCommand(batchJobId, {
3570
4106
  fields: options.fields
3571
4107
  });
3572
4108
  });
3573
- testsRuns.command("get <test_run_id>").description("Get a specific test run result").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
4109
+ testsRuns.command("get <test_run_id>").description("Get a specific test run result").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
4110
+ "after",
4111
+ `
3574
4112
  Examples:
3575
4113
  $ retell tests runs get tcj_abc123
3576
4114
  $ retell tests runs get tcj_abc123 --fields status,metric_results
3577
- `).action(async (testRunId, options) => {
4115
+ `
4116
+ ).action(async (testRunId, options) => {
3578
4117
  await getTestRunCommand(testRunId, {
3579
4118
  fields: options.fields
3580
4119
  });
3581
4120
  });
3582
4121
  var kb = program.command("kb").description("Manage RAG knowledge bases");
3583
- kb.command("list").description("List all knowledge bases").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
4122
+ kb.command("list").description("List all knowledge bases").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
4123
+ "after",
4124
+ `
3584
4125
  Examples:
3585
4126
  $ retell kb list
3586
4127
  $ retell kb list --fields knowledge_base_id,knowledge_base_name,status
3587
- `).action(async (options) => {
4128
+ `
4129
+ ).action(async (options) => {
3588
4130
  await listKnowledgeBasesCommand({
3589
4131
  fields: options.fields
3590
4132
  });
3591
4133
  });
3592
- kb.command("get <knowledge_base_id>").description("Get a specific knowledge base").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
4134
+ kb.command("get <knowledge_base_id>").description("Get a specific knowledge base").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
4135
+ "after",
4136
+ `
3593
4137
  Examples:
3594
4138
  $ retell kb get kb_abc123
3595
4139
  $ retell kb get kb_abc123 --fields knowledge_base_name,status,knowledge_base_sources
3596
- `).action(async (knowledgeBaseId, options) => {
4140
+ `
4141
+ ).action(async (knowledgeBaseId, options) => {
3597
4142
  await getKnowledgeBaseCommand(knowledgeBaseId, {
3598
4143
  fields: options.fields
3599
4144
  });
3600
4145
  });
3601
- kb.command("create").description("Create a new knowledge base").requiredOption("-n, --name <name>", "Knowledge base name (max 40 characters)").option("--urls <urls>", "Comma-separated list of URLs to scrape").option("--texts <file>", "Path to JSON file with text entries [{ title, text }, ...]").option("--auto-refresh", "Enable 12-hour automatic refresh for URL sources").addHelpText("after", `
4146
+ kb.command("create").description("Create a new knowledge base").requiredOption(
4147
+ "-n, --name <name>",
4148
+ "Knowledge base name (max 40 characters)"
4149
+ ).option("--urls <urls>", "Comma-separated list of URLs to scrape").option(
4150
+ "--texts <file>",
4151
+ "Path to JSON file with text entries [{ title, text }, ...]"
4152
+ ).option("--auto-refresh", "Enable 12-hour automatic refresh for URL sources").addHelpText(
4153
+ "after",
4154
+ `
3602
4155
  Examples:
3603
4156
  $ retell kb create --name "Product Docs"
3604
4157
  $ retell kb create --name "Support KB" --urls https://docs.example.com,https://help.example.com
@@ -3610,7 +4163,8 @@ Text file format (texts.json):
3610
4163
  { "title": "Getting Started", "text": "Welcome to our product..." },
3611
4164
  { "title": "FAQ", "text": "Frequently asked questions..." }
3612
4165
  ]
3613
- `).action(async (options) => {
4166
+ `
4167
+ ).action(async (options) => {
3614
4168
  await createKnowledgeBaseCommand({
3615
4169
  name: options.name,
3616
4170
  urls: options.urls,
@@ -3618,40 +4172,61 @@ Text file format (texts.json):
3618
4172
  autoRefresh: options.autoRefresh
3619
4173
  });
3620
4174
  });
3621
- kb.command("delete <knowledge_base_id>").description("Delete a knowledge base").addHelpText("after", `
4175
+ kb.command("delete <knowledge_base_id>").description("Delete a knowledge base").addHelpText(
4176
+ "after",
4177
+ `
3622
4178
  Examples:
3623
4179
  $ retell kb delete kb_abc123
3624
- `).action(async (knowledgeBaseId) => {
4180
+ `
4181
+ ).action(async (knowledgeBaseId) => {
3625
4182
  await deleteKnowledgeBaseCommand(knowledgeBaseId);
3626
4183
  });
3627
4184
  var kbSources = kb.command("sources").description("Manage knowledge base sources");
3628
- kbSources.command("add <knowledge_base_id>").description("Add sources to an existing knowledge base").option("--urls <urls>", "Comma-separated list of URLs to scrape").option("--texts <file>", "Path to JSON file with text entries [{ title, text }, ...]").addHelpText("after", `
4185
+ kbSources.command("add <knowledge_base_id>").description("Add sources to an existing knowledge base").option("--urls <urls>", "Comma-separated list of URLs to scrape").option(
4186
+ "--texts <file>",
4187
+ "Path to JSON file with text entries [{ title, text }, ...]"
4188
+ ).addHelpText(
4189
+ "after",
4190
+ `
3629
4191
  Examples:
3630
4192
  $ retell kb sources add kb_abc123 --urls https://docs.example.com/new
3631
4193
  $ retell kb sources add kb_abc123 --texts additional-texts.json
3632
4194
  $ retell kb sources add kb_abc123 --urls https://faq.example.com --texts more-texts.json
3633
- `).action(async (knowledgeBaseId, options) => {
4195
+ `
4196
+ ).action(async (knowledgeBaseId, options) => {
3634
4197
  await addKnowledgeBaseSourcesCommand(knowledgeBaseId, {
3635
4198
  urls: options.urls,
3636
4199
  texts: options.texts
3637
4200
  });
3638
4201
  });
3639
- kbSources.command("delete <knowledge_base_id> <source_id>").description("Remove a source from a knowledge base").addHelpText("after", `
4202
+ kbSources.command("delete <knowledge_base_id> <source_id>").description("Remove a source from a knowledge base").addHelpText(
4203
+ "after",
4204
+ `
3640
4205
  Examples:
3641
4206
  $ retell kb sources delete kb_abc123 source_xyz789
3642
- `).action(async (knowledgeBaseId, sourceId) => {
4207
+ `
4208
+ ).action(async (knowledgeBaseId, sourceId) => {
3643
4209
  await deleteKnowledgeBaseSourceCommand(knowledgeBaseId, sourceId);
3644
4210
  });
3645
4211
  var flows = program.command("flows").description("Manage conversation flow response engines");
3646
- flows.command("list").description("List all conversation flows").option("-l, --limit <number>", "Maximum number of flows to return (default: 100, max: 1000)", "100").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
4212
+ flows.command("list").description("List all conversation flows").option(
4213
+ "-l, --limit <number>",
4214
+ "Maximum number of flows to return (default: 100, max: 1000)",
4215
+ "100"
4216
+ ).option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
4217
+ "after",
4218
+ `
3647
4219
  Examples:
3648
4220
  $ retell flows list
3649
4221
  $ retell flows list --limit 50
3650
4222
  $ retell flows list --fields conversation_flow_id,version,start_speaker
3651
- `).action(async (options) => {
4223
+ `
4224
+ ).action(async (options) => {
3652
4225
  const limit = parseInt(options.limit, 10);
3653
4226
  if (isNaN(limit) || limit < 1 || limit > 1e3) {
3654
- console.error("Error: limit must be a positive number between 1 and 1000");
4227
+ console.error(
4228
+ "Error: limit must be a positive number between 1 and 1000"
4229
+ );
3655
4230
  process.exit(1);
3656
4231
  }
3657
4232
  await listFlowsCommand({
@@ -3659,18 +4234,29 @@ Examples:
3659
4234
  fields: options.fields
3660
4235
  });
3661
4236
  });
3662
- flows.command("get <conversation_flow_id>").description("Get a specific conversation flow").option("--version <number>", "Specific version to retrieve (defaults to latest)").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText("after", `
4237
+ flows.command("get <conversation_flow_id>").description("Get a specific conversation flow").option(
4238
+ "--version <number>",
4239
+ "Specific version to retrieve (defaults to latest)"
4240
+ ).option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
4241
+ "after",
4242
+ `
3663
4243
  Examples:
3664
4244
  $ retell flows get cf_abc123
3665
4245
  $ retell flows get cf_abc123 --version 2
3666
4246
  $ retell flows get cf_abc123 --fields conversation_flow_id,nodes,edges
3667
- `).action(async (conversationFlowId, options) => {
4247
+ `
4248
+ ).action(async (conversationFlowId, options) => {
3668
4249
  await getFlowCommand(conversationFlowId, {
3669
4250
  version: options.version ? parseInt(options.version, 10) : void 0,
3670
4251
  fields: options.fields
3671
4252
  });
3672
4253
  });
3673
- flows.command("create").description("Create a new conversation flow from a JSON file").requiredOption("-f, --file <path>", "Path to JSON file containing flow configuration").addHelpText("after", `
4254
+ flows.command("create").description("Create a new conversation flow from a JSON file").requiredOption(
4255
+ "-f, --file <path>",
4256
+ "Path to JSON file containing flow configuration"
4257
+ ).addHelpText(
4258
+ "after",
4259
+ `
3674
4260
  Examples:
3675
4261
  $ retell flows create --file flow.json
3676
4262
 
@@ -3681,25 +4267,38 @@ Flow JSON format (minimal):
3681
4267
  "nodes": [...],
3682
4268
  "edges": [...]
3683
4269
  }
3684
- `).action(async (options) => {
4270
+ `
4271
+ ).action(async (options) => {
3685
4272
  await createFlowCommand({
3686
4273
  file: options.file
3687
4274
  });
3688
4275
  });
3689
- flows.command("update <conversation_flow_id>").description("Update an existing conversation flow from a JSON file").requiredOption("-f, --file <path>", "Path to JSON file containing flow updates").option("--version <number>", "Specific version to update (defaults to latest)").addHelpText("after", `
4276
+ flows.command("update <conversation_flow_id>").description("Update an existing conversation flow from a JSON file").requiredOption(
4277
+ "-f, --file <path>",
4278
+ "Path to JSON file containing flow updates"
4279
+ ).option(
4280
+ "--version <number>",
4281
+ "Specific version to update (defaults to latest)"
4282
+ ).addHelpText(
4283
+ "after",
4284
+ `
3690
4285
  Examples:
3691
4286
  $ retell flows update cf_abc123 --file updates.json
3692
4287
  $ retell flows update cf_abc123 --file updates.json --version 2
3693
- `).action(async (conversationFlowId, options) => {
4288
+ `
4289
+ ).action(async (conversationFlowId, options) => {
3694
4290
  await updateFlowCommand(conversationFlowId, {
3695
4291
  file: options.file,
3696
4292
  version: options.version ? parseInt(options.version, 10) : void 0
3697
4293
  });
3698
4294
  });
3699
- flows.command("delete <conversation_flow_id>").description("Delete a conversation flow").addHelpText("after", `
4295
+ flows.command("delete <conversation_flow_id>").description("Delete a conversation flow").addHelpText(
4296
+ "after",
4297
+ `
3700
4298
  Examples:
3701
4299
  $ retell flows delete cf_abc123
3702
- `).action(async (conversationFlowId) => {
4300
+ `
4301
+ ).action(async (conversationFlowId) => {
3703
4302
  await deleteFlowCommand(conversationFlowId);
3704
4303
  });
3705
4304
  program.parse(process.argv);