retell-cli 1.2.0 → 1.3.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 (3) hide show
  1. package/README.md +75 -0
  2. package/dist/index.js +222 -63
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -305,6 +305,81 @@ Publish a draft agent to make changes live.
305
305
  retell agent-publish agent_123abc
306
306
  ```
307
307
 
308
+ ### Agent Configuration
309
+
310
+ Manage agent-level settings that aren't part of prompts (voice, webhooks, post-call analysis, etc.).
311
+
312
+ #### `retell agent get <agent_id> [options]`
313
+
314
+ Get agent configuration including all agent-level settings.
315
+
316
+ **Options:**
317
+ - `--version <number>` - Specific version to retrieve (defaults to latest)
318
+ - `--fields <fields>` - Comma-separated list of fields to return
319
+
320
+ **Examples:**
321
+ ```bash
322
+ # Get full agent config
323
+ retell agent get agent_123abc
324
+
325
+ # Get specific version
326
+ retell agent get agent_123abc --version 2
327
+
328
+ # Get specific fields only
329
+ retell agent get agent_123abc --fields agent_name,post_call_analysis_data
330
+
331
+ # Save config to file for editing
332
+ retell agent get agent_123abc > config.json
333
+ ```
334
+
335
+ #### `retell agent update <agent_id> [options]`
336
+
337
+ Update agent configuration from a JSON file. This is useful for updating agent-level fields that aren't accessible through `prompts update`, such as:
338
+ - `post_call_analysis_data` - Custom data extraction from calls
339
+ - `post_call_analysis_model` - Model for analysis
340
+ - `analysis_successful_prompt` - Success criteria prompt
341
+ - `analysis_summary_prompt` - Summary generation prompt
342
+ - Voice settings, language, webhooks, and more
343
+
344
+ **Options:**
345
+ - `-f, --file <path>` - Path to JSON file containing agent configuration updates (required)
346
+ - `--dry-run` - Preview changes without applying them
347
+ - `--version <number>` - Specific version to update (defaults to latest draft)
348
+
349
+ **Example JSON for post-call analysis:**
350
+ ```json
351
+ {
352
+ "post_call_analysis_model": "claude-4.5-sonnet",
353
+ "post_call_analysis_data": [
354
+ {
355
+ "name": "call_outcome",
356
+ "type": "enum",
357
+ "description": "Result of the call",
358
+ "choices": ["successful", "unsuccessful", "callback_needed"]
359
+ },
360
+ {
361
+ "name": "customer_sentiment",
362
+ "type": "string",
363
+ "description": "Overall customer sentiment"
364
+ }
365
+ ],
366
+ "analysis_successful_prompt": "Determine if the issue was resolved.",
367
+ "analysis_summary_prompt": "Summarize the call in 2 sentences."
368
+ }
369
+ ```
370
+
371
+ **Examples:**
372
+ ```bash
373
+ # Preview changes first (recommended)
374
+ retell agent update agent_123abc --file config.json --dry-run
375
+
376
+ # Apply changes
377
+ retell agent update agent_123abc --file config.json
378
+
379
+ # Remember to publish after updating
380
+ retell agent-publish agent_123abc
381
+ ```
382
+
308
383
  ### Tools
309
384
 
310
385
  Manage agent tools (custom functions, webhooks, etc.). Tools are embedded within Retell LLM and Conversation Flow configurations.
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
 
26
26
  // src/index.ts
27
27
  var import_commander = require("commander");
28
- var import_fs15 = require("fs");
28
+ var import_fs16 = require("fs");
29
29
  var import_path6 = require("path");
30
30
 
31
31
  // src/commands/login.ts
@@ -751,27 +751,27 @@ async function listAgentsCommand(options = {}) {
751
751
  const agents2 = await client.agent.list({
752
752
  limit: options.limit || 100
753
753
  });
754
- const formatted = agents2.map((agent) => {
754
+ const formatted = agents2.map((agent2) => {
755
755
  let response_engine_id;
756
- switch (agent.response_engine.type) {
756
+ switch (agent2.response_engine.type) {
757
757
  case "retell-llm":
758
- response_engine_id = agent.response_engine.llm_id || "unknown";
758
+ response_engine_id = agent2.response_engine.llm_id || "unknown";
759
759
  break;
760
760
  case "conversation-flow":
761
- response_engine_id = agent.response_engine.conversation_flow_id || "unknown";
761
+ response_engine_id = agent2.response_engine.conversation_flow_id || "unknown";
762
762
  break;
763
763
  case "custom-llm":
764
- response_engine_id = agent.response_engine.llm_websocket_url || "unknown";
764
+ response_engine_id = agent2.response_engine.llm_websocket_url || "unknown";
765
765
  break;
766
766
  default:
767
767
  response_engine_id = "unknown";
768
768
  }
769
769
  return {
770
- agent_id: agent.agent_id,
771
- agent_name: agent.agent_name,
772
- version: agent.version,
773
- is_published: agent.is_published,
774
- response_engine_type: agent.response_engine.type,
770
+ agent_id: agent2.agent_id,
771
+ agent_name: agent2.agent_name,
772
+ version: agent2.version,
773
+ is_published: agent2.is_published,
774
+ response_engine_type: agent2.response_engine.type,
775
775
  response_engine_id
776
776
  };
777
777
  });
@@ -789,11 +789,11 @@ async function listAgentsCommand(options = {}) {
789
789
  async function agentInfoCommand(agentId, options = {}) {
790
790
  try {
791
791
  const client = getRetellClient();
792
- const agent = await client.agent.retrieve(agentId);
792
+ const agent2 = await client.agent.retrieve(agentId);
793
793
  const output = options.fields ? filterFields(
794
- agent,
794
+ agent2,
795
795
  options.fields.split(",").map((f) => f.trim())
796
- ) : agent;
796
+ ) : agent2;
797
797
  outputJson(output);
798
798
  } catch (error) {
799
799
  handleSdkError(error);
@@ -807,13 +807,13 @@ var import_path2 = require("path");
807
807
  // src/services/prompt-resolver.ts
808
808
  async function resolvePromptSource(agentId) {
809
809
  const client = getRetellClient();
810
- const agent = await client.agent.retrieve(agentId);
811
- if (agent.response_engine.type === "retell-llm") {
812
- const llm = await client.llm.retrieve(agent.response_engine.llm_id);
810
+ const agent2 = await client.agent.retrieve(agentId);
811
+ if (agent2.response_engine.type === "retell-llm") {
812
+ const llm = await client.llm.retrieve(agent2.response_engine.llm_id);
813
813
  return {
814
814
  type: "retell-llm",
815
815
  llmId: llm.llm_id,
816
- agentName: agent.agent_name,
816
+ agentName: agent2.agent_name,
817
817
  prompts: {
818
818
  llm_id: llm.llm_id,
819
819
  version: llm.version,
@@ -823,14 +823,14 @@ async function resolvePromptSource(agentId) {
823
823
  }
824
824
  };
825
825
  }
826
- if (agent.response_engine.type === "conversation-flow") {
826
+ if (agent2.response_engine.type === "conversation-flow") {
827
827
  const flow = await client.conversationFlow.retrieve(
828
- agent.response_engine.conversation_flow_id
828
+ agent2.response_engine.conversation_flow_id
829
829
  );
830
830
  return {
831
831
  type: "conversation-flow",
832
832
  flowId: flow.conversation_flow_id,
833
- agentName: agent.agent_name,
833
+ agentName: agent2.agent_name,
834
834
  prompts: {
835
835
  conversation_flow_id: flow.conversation_flow_id,
836
836
  version: flow.version,
@@ -1454,13 +1454,13 @@ async function publishAgentCommand(agentId) {
1454
1454
  }
1455
1455
  }
1456
1456
  try {
1457
- const agent = await client.agent.retrieve(agentId);
1457
+ const agent2 = await client.agent.retrieve(agentId);
1458
1458
  outputJson({
1459
1459
  message: "Agent published successfully",
1460
- agent_id: agent.agent_id,
1461
- agent_name: agent.agent_name || "Unknown",
1462
- version: agent.version || "Unknown",
1463
- is_published: agent.is_published ?? true,
1460
+ agent_id: agent2.agent_id,
1461
+ agent_name: agent2.agent_name || "Unknown",
1462
+ version: agent2.version || "Unknown",
1463
+ is_published: agent2.is_published ?? true,
1464
1464
  note: "Draft version incremented and ready for new changes"
1465
1465
  });
1466
1466
  } catch (error) {
@@ -1468,12 +1468,109 @@ async function publishAgentCommand(agentId) {
1468
1468
  }
1469
1469
  }
1470
1470
 
1471
+ // src/commands/agent/get.ts
1472
+ async function getAgentCommand(agentId, options) {
1473
+ const client = getRetellClient();
1474
+ try {
1475
+ const agent2 = await client.agent.retrieve(agentId, {
1476
+ version: options.version
1477
+ });
1478
+ if (options.fields) {
1479
+ const fields = options.fields.split(",").map((f) => f.trim());
1480
+ const filtered = filterFields(agent2, fields);
1481
+ outputJson(filtered);
1482
+ } else {
1483
+ outputJson(agent2);
1484
+ }
1485
+ } catch (error) {
1486
+ handleSdkError(error);
1487
+ }
1488
+ }
1489
+
1490
+ // src/commands/agent/update.ts
1491
+ var import_fs5 = require("fs");
1492
+ function validateFilePath(filePath) {
1493
+ if (filePath.includes("\0")) {
1494
+ throw new Error("Invalid file path: contains null bytes");
1495
+ }
1496
+ }
1497
+ async function updateAgentCommand(agentId, options) {
1498
+ const client = getRetellClient();
1499
+ try {
1500
+ validateFilePath(options.file);
1501
+ if (!(0, import_fs5.existsSync)(options.file)) {
1502
+ outputError(`File not found: ${options.file}`, "FILE_NOT_FOUND");
1503
+ return;
1504
+ }
1505
+ let updateParams;
1506
+ try {
1507
+ const fileContent = (0, import_fs5.readFileSync)(options.file, "utf-8");
1508
+ updateParams = JSON.parse(fileContent);
1509
+ } catch (error) {
1510
+ if (error instanceof SyntaxError) {
1511
+ outputError(`Invalid JSON in file: ${error.message}`, "INVALID_JSON");
1512
+ return;
1513
+ }
1514
+ throw error;
1515
+ }
1516
+ if (typeof updateParams !== "object" || updateParams === null || Array.isArray(updateParams)) {
1517
+ outputError(
1518
+ "File must contain a JSON object with agent configuration fields",
1519
+ "INVALID_FORMAT"
1520
+ );
1521
+ return;
1522
+ }
1523
+ if (options.dryRun) {
1524
+ const currentAgent = await client.agent.retrieve(agentId, {
1525
+ version: options.version
1526
+ });
1527
+ const changes = {};
1528
+ for (const [key, newValue] of Object.entries(updateParams)) {
1529
+ const currentValue = currentAgent[key];
1530
+ if (JSON.stringify(currentValue) !== JSON.stringify(newValue)) {
1531
+ changes[key] = {
1532
+ current: currentValue,
1533
+ new: newValue
1534
+ };
1535
+ }
1536
+ }
1537
+ outputJson({
1538
+ message: "Dry run - no changes applied",
1539
+ agent_id: agentId,
1540
+ agent_name: currentAgent.agent_name || "Unknown",
1541
+ fields_to_update: Object.keys(updateParams),
1542
+ changes: Object.keys(changes).length > 0 ? changes : "No changes detected (values are identical)",
1543
+ note: `Run without --dry-run to apply changes`
1544
+ });
1545
+ return;
1546
+ }
1547
+ const updatedAgent = await client.agent.update(
1548
+ agentId,
1549
+ updateParams
1550
+ );
1551
+ outputJson({
1552
+ message: "Agent updated successfully (draft version)",
1553
+ agent_id: updatedAgent.agent_id,
1554
+ agent_name: updatedAgent.agent_name || "Unknown",
1555
+ version: updatedAgent.version,
1556
+ fields_updated: Object.keys(updateParams),
1557
+ note: `Run 'retell agent-publish ${agentId}' to publish changes to production`
1558
+ });
1559
+ } catch (error) {
1560
+ if (error instanceof SyntaxError) {
1561
+ outputError(`Invalid JSON in file: ${error.message}`, "INVALID_JSON");
1562
+ return;
1563
+ }
1564
+ handleSdkError(error);
1565
+ }
1566
+ }
1567
+
1471
1568
  // src/services/tool-resolver.ts
1472
1569
  async function resolveToolsSource(agentId) {
1473
1570
  const client = getRetellClient();
1474
- const agent = await client.agent.retrieve(agentId);
1475
- if (agent.response_engine.type === "retell-llm") {
1476
- const llm = await client.llm.retrieve(agent.response_engine.llm_id);
1571
+ const agent2 = await client.agent.retrieve(agentId);
1572
+ if (agent2.response_engine.type === "retell-llm") {
1573
+ const llm = await client.llm.retrieve(agent2.response_engine.llm_id);
1477
1574
  const generalTools = llm.general_tools ?? [];
1478
1575
  const stateTools = {};
1479
1576
  if (llm.states) {
@@ -1492,16 +1589,16 @@ async function resolveToolsSource(agentId) {
1492
1589
  return {
1493
1590
  type: "retell-llm",
1494
1591
  agentId,
1495
- agentName: agent.agent_name ?? "Unknown",
1592
+ agentName: agent2.agent_name ?? "Unknown",
1496
1593
  llmId: llm.llm_id,
1497
1594
  generalTools,
1498
1595
  stateTools,
1499
1596
  totalCount
1500
1597
  };
1501
1598
  }
1502
- if (agent.response_engine.type === "conversation-flow") {
1599
+ if (agent2.response_engine.type === "conversation-flow") {
1503
1600
  const flow = await client.conversationFlow.retrieve(
1504
- agent.response_engine.conversation_flow_id
1601
+ agent2.response_engine.conversation_flow_id
1505
1602
  );
1506
1603
  const flowTools = flow.tools ?? [];
1507
1604
  const componentTools = {};
@@ -1521,7 +1618,7 @@ async function resolveToolsSource(agentId) {
1521
1618
  return {
1522
1619
  type: "conversation-flow",
1523
1620
  agentId,
1524
- agentName: agent.agent_name ?? "Unknown",
1621
+ agentName: agent2.agent_name ?? "Unknown",
1525
1622
  flowId: flow.conversation_flow_id,
1526
1623
  flowTools,
1527
1624
  componentTools,
@@ -1796,16 +1893,16 @@ async function getToolCommand(agentId, toolName, options) {
1796
1893
  }
1797
1894
 
1798
1895
  // src/commands/tools/add.ts
1799
- var import_fs5 = require("fs");
1896
+ var import_fs6 = require("fs");
1800
1897
  async function addToolCommand(agentId, options) {
1801
1898
  try {
1802
- if (!(0, import_fs5.existsSync)(options.file)) {
1899
+ if (!(0, import_fs6.existsSync)(options.file)) {
1803
1900
  outputError(`Tool file not found: ${options.file}`, "FILE_NOT_FOUND");
1804
1901
  return;
1805
1902
  }
1806
1903
  let tool;
1807
1904
  try {
1808
- const content = (0, import_fs5.readFileSync)(options.file, "utf-8");
1905
+ const content = (0, import_fs6.readFileSync)(options.file, "utf-8");
1809
1906
  tool = JSON.parse(content);
1810
1907
  } catch (error) {
1811
1908
  if (error instanceof SyntaxError) {
@@ -1980,16 +2077,16 @@ async function addToolCommand(agentId, options) {
1980
2077
  }
1981
2078
 
1982
2079
  // src/commands/tools/update.ts
1983
- var import_fs6 = require("fs");
2080
+ var import_fs7 = require("fs");
1984
2081
  async function updateToolCommand(agentId, toolName, options) {
1985
2082
  try {
1986
- if (!(0, import_fs6.existsSync)(options.file)) {
2083
+ if (!(0, import_fs7.existsSync)(options.file)) {
1987
2084
  outputError(`Tool file not found: ${options.file}`, "FILE_NOT_FOUND");
1988
2085
  return;
1989
2086
  }
1990
2087
  let newTool;
1991
2088
  try {
1992
- const content = (0, import_fs6.readFileSync)(options.file, "utf-8");
2089
+ const content = (0, import_fs7.readFileSync)(options.file, "utf-8");
1993
2090
  newTool = JSON.parse(content);
1994
2091
  } catch (error) {
1995
2092
  if (error instanceof SyntaxError) {
@@ -2373,7 +2470,7 @@ async function removeToolCommand(agentId, toolName, options) {
2373
2470
  }
2374
2471
 
2375
2472
  // src/commands/tools/export.ts
2376
- var import_fs7 = require("fs");
2473
+ var import_fs8 = require("fs");
2377
2474
  async function exportToolsCommand(agentId, options) {
2378
2475
  try {
2379
2476
  const source = await resolveToolsSource(agentId);
@@ -2421,7 +2518,7 @@ async function exportToolsCommand(agentId, options) {
2421
2518
  }
2422
2519
  if (options.output) {
2423
2520
  try {
2424
- (0, import_fs7.writeFileSync)(
2521
+ (0, import_fs8.writeFileSync)(
2425
2522
  options.output,
2426
2523
  JSON.stringify(exportData, null, 2),
2427
2524
  "utf-8"
@@ -2455,16 +2552,16 @@ async function exportToolsCommand(agentId, options) {
2455
2552
  }
2456
2553
 
2457
2554
  // src/commands/tools/import.ts
2458
- var import_fs8 = require("fs");
2555
+ var import_fs9 = require("fs");
2459
2556
  async function importToolsCommand(agentId, options) {
2460
2557
  try {
2461
- if (!(0, import_fs8.existsSync)(options.file)) {
2558
+ if (!(0, import_fs9.existsSync)(options.file)) {
2462
2559
  outputError(`Import file not found: ${options.file}`, "FILE_NOT_FOUND");
2463
2560
  return;
2464
2561
  }
2465
2562
  let importData;
2466
2563
  try {
2467
- const content = (0, import_fs8.readFileSync)(options.file, "utf-8");
2564
+ const content = (0, import_fs9.readFileSync)(options.file, "utf-8");
2468
2565
  importData = JSON.parse(content);
2469
2566
  } catch (error) {
2470
2567
  if (error instanceof SyntaxError) {
@@ -2864,7 +2961,7 @@ async function getTestCaseCommand(testCaseDefinitionId, options) {
2864
2961
  }
2865
2962
 
2866
2963
  // src/commands/tests/cases/create.ts
2867
- var import_fs9 = require("fs");
2964
+ var import_fs10 = require("fs");
2868
2965
  function buildResponseEngine2(options) {
2869
2966
  if (options.llmId && options.flowId) {
2870
2967
  outputError(
@@ -2902,7 +2999,7 @@ function buildResponseEngine2(options) {
2902
2999
  }
2903
3000
  async function createTestCaseCommand(options) {
2904
3001
  try {
2905
- if (!(0, import_fs9.existsSync)(options.file)) {
3002
+ if (!(0, import_fs10.existsSync)(options.file)) {
2906
3003
  outputError(
2907
3004
  `Test case file not found: ${options.file}`,
2908
3005
  "FILE_NOT_FOUND"
@@ -2911,7 +3008,7 @@ async function createTestCaseCommand(options) {
2911
3008
  }
2912
3009
  let input;
2913
3010
  try {
2914
- const content = (0, import_fs9.readFileSync)(options.file, "utf-8");
3011
+ const content = (0, import_fs10.readFileSync)(options.file, "utf-8");
2915
3012
  input = JSON.parse(content);
2916
3013
  } catch (error) {
2917
3014
  if (error instanceof SyntaxError) {
@@ -2961,10 +3058,10 @@ async function createTestCaseCommand(options) {
2961
3058
  }
2962
3059
 
2963
3060
  // src/commands/tests/cases/update.ts
2964
- var import_fs10 = require("fs");
3061
+ var import_fs11 = require("fs");
2965
3062
  async function updateTestCaseCommand(testCaseDefinitionId, options) {
2966
3063
  try {
2967
- if (!(0, import_fs10.existsSync)(options.file)) {
3064
+ if (!(0, import_fs11.existsSync)(options.file)) {
2968
3065
  outputError(
2969
3066
  `Test case file not found: ${options.file}`,
2970
3067
  "FILE_NOT_FOUND"
@@ -2973,7 +3070,7 @@ async function updateTestCaseCommand(testCaseDefinitionId, options) {
2973
3070
  }
2974
3071
  let input;
2975
3072
  try {
2976
- const content = (0, import_fs10.readFileSync)(options.file, "utf-8");
3073
+ const content = (0, import_fs11.readFileSync)(options.file, "utf-8");
2977
3074
  input = JSON.parse(content);
2978
3075
  } catch (error) {
2979
3076
  if (error instanceof SyntaxError) {
@@ -3230,7 +3327,7 @@ async function getKnowledgeBaseCommand(knowledgeBaseId, options) {
3230
3327
  }
3231
3328
 
3232
3329
  // src/commands/kb/create.ts
3233
- var import_fs11 = require("fs");
3330
+ var import_fs12 = require("fs");
3234
3331
  async function createKnowledgeBaseCommand(options) {
3235
3332
  try {
3236
3333
  if (options.name.length > 40) {
@@ -3253,12 +3350,12 @@ async function createKnowledgeBaseCommand(options) {
3253
3350
  }
3254
3351
  }
3255
3352
  if (options.texts) {
3256
- if (!(0, import_fs11.existsSync)(options.texts)) {
3353
+ if (!(0, import_fs12.existsSync)(options.texts)) {
3257
3354
  outputError(`Texts file not found: ${options.texts}`, "FILE_NOT_FOUND");
3258
3355
  return;
3259
3356
  }
3260
3357
  try {
3261
- const content = (0, import_fs11.readFileSync)(options.texts, "utf-8");
3358
+ const content = (0, import_fs12.readFileSync)(options.texts, "utf-8");
3262
3359
  const textsData = JSON.parse(content);
3263
3360
  if (!Array.isArray(textsData)) {
3264
3361
  outputError(
@@ -3334,7 +3431,7 @@ async function deleteKnowledgeBaseCommand(knowledgeBaseId) {
3334
3431
  }
3335
3432
 
3336
3433
  // src/commands/kb/sources/add.ts
3337
- var import_fs12 = require("fs");
3434
+ var import_fs13 = require("fs");
3338
3435
  async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
3339
3436
  try {
3340
3437
  if (!options.urls && !options.texts) {
@@ -3352,12 +3449,12 @@ async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
3352
3449
  }
3353
3450
  }
3354
3451
  if (options.texts) {
3355
- if (!(0, import_fs12.existsSync)(options.texts)) {
3452
+ if (!(0, import_fs13.existsSync)(options.texts)) {
3356
3453
  outputError(`Texts file not found: ${options.texts}`, "FILE_NOT_FOUND");
3357
3454
  return;
3358
3455
  }
3359
3456
  try {
3360
- const content = (0, import_fs12.readFileSync)(options.texts, "utf-8");
3457
+ const content = (0, import_fs13.readFileSync)(options.texts, "utf-8");
3361
3458
  const textsData = JSON.parse(content);
3362
3459
  if (!Array.isArray(textsData)) {
3363
3460
  outputError(
@@ -3483,16 +3580,16 @@ async function getFlowCommand(conversationFlowId, options) {
3483
3580
  }
3484
3581
 
3485
3582
  // src/commands/flows/create.ts
3486
- var import_fs13 = require("fs");
3583
+ var import_fs14 = require("fs");
3487
3584
  async function createFlowCommand(options) {
3488
3585
  try {
3489
- if (!(0, import_fs13.existsSync)(options.file)) {
3586
+ if (!(0, import_fs14.existsSync)(options.file)) {
3490
3587
  outputError(`Flow file not found: ${options.file}`, "FILE_NOT_FOUND");
3491
3588
  return;
3492
3589
  }
3493
3590
  let flowConfig;
3494
3591
  try {
3495
- const content = (0, import_fs13.readFileSync)(options.file, "utf-8");
3592
+ const content = (0, import_fs14.readFileSync)(options.file, "utf-8");
3496
3593
  flowConfig = JSON.parse(content);
3497
3594
  } catch (error) {
3498
3595
  if (error instanceof SyntaxError) {
@@ -3530,16 +3627,16 @@ async function createFlowCommand(options) {
3530
3627
  }
3531
3628
 
3532
3629
  // src/commands/flows/update.ts
3533
- var import_fs14 = require("fs");
3630
+ var import_fs15 = require("fs");
3534
3631
  async function updateFlowCommand(conversationFlowId, options) {
3535
3632
  try {
3536
- if (!(0, import_fs14.existsSync)(options.file)) {
3633
+ if (!(0, import_fs15.existsSync)(options.file)) {
3537
3634
  outputError(`Flow file not found: ${options.file}`, "FILE_NOT_FOUND");
3538
3635
  return;
3539
3636
  }
3540
3637
  let flowUpdates;
3541
3638
  try {
3542
- const content = (0, import_fs14.readFileSync)(options.file, "utf-8");
3639
+ const content = (0, import_fs15.readFileSync)(options.file, "utf-8");
3543
3640
  flowUpdates = JSON.parse(content);
3544
3641
  } catch (error) {
3545
3642
  if (error instanceof SyntaxError) {
@@ -3593,7 +3690,7 @@ async function deleteFlowCommand(conversationFlowId) {
3593
3690
 
3594
3691
  // src/index.ts
3595
3692
  var packageJson = JSON.parse(
3596
- (0, import_fs15.readFileSync)((0, import_path6.join)(__dirname, "../package.json"), "utf-8")
3693
+ (0, import_fs16.readFileSync)((0, import_path6.join)(__dirname, "../package.json"), "utf-8")
3597
3694
  );
3598
3695
  var program = new import_commander.Command();
3599
3696
  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);
@@ -3818,6 +3915,68 @@ Examples:
3818
3915
  ).action(async (agentId) => {
3819
3916
  await publishAgentCommand(agentId);
3820
3917
  });
3918
+ var agent = program.command("agent").description(
3919
+ "Manage agent-level configuration (voice, webhooks, post-call analysis, etc.)"
3920
+ );
3921
+ agent.command("get <agent_id>").description("Get agent configuration").option(
3922
+ "--version <number>",
3923
+ "Specific version to retrieve (defaults to latest)"
3924
+ ).option(
3925
+ "--fields <fields>",
3926
+ "Comma-separated list of fields to return (e.g., agent_name,post_call_analysis_data)"
3927
+ ).addHelpText(
3928
+ "after",
3929
+ `
3930
+ Examples:
3931
+ $ retell agent get agent_123abc
3932
+ $ retell agent get agent_123abc --version 2
3933
+ $ retell agent get agent_123abc --fields agent_name,post_call_analysis_data
3934
+ $ retell agent get agent_123abc > config.json
3935
+ `
3936
+ ).action(async (agentId, options) => {
3937
+ await getAgentCommand(agentId, {
3938
+ version: options.version ? parseInt(options.version, 10) : void 0,
3939
+ fields: options.fields
3940
+ });
3941
+ });
3942
+ agent.command("update <agent_id>").description("Update agent configuration from a JSON file").requiredOption(
3943
+ "-f, --file <path>",
3944
+ "Path to JSON file containing agent configuration updates"
3945
+ ).option("--dry-run", "Preview changes without applying them").option(
3946
+ "--version <number>",
3947
+ "Specific version to update (defaults to latest draft)"
3948
+ ).addHelpText(
3949
+ "after",
3950
+ `
3951
+ Examples:
3952
+ $ retell agent update agent_123abc --file config.json
3953
+ $ retell agent update agent_123abc --file config.json --dry-run
3954
+ $ retell agent update agent_123abc --file analysis.json --version 2
3955
+
3956
+ Example JSON for post-call analysis:
3957
+ {
3958
+ "post_call_analysis_model": "claude-4.5-sonnet",
3959
+ "post_call_analysis_data": [
3960
+ {
3961
+ "name": "call_outcome",
3962
+ "type": "enum",
3963
+ "description": "Result of the call",
3964
+ "choices": ["successful", "unsuccessful", "callback_needed"]
3965
+ }
3966
+ ],
3967
+ "analysis_successful_prompt": "Determine if the issue was resolved.",
3968
+ "analysis_summary_prompt": "Summarize the call in 2 sentences."
3969
+ }
3970
+
3971
+ Note: Run 'retell agent-publish <agent_id>' after updating to publish changes.
3972
+ `
3973
+ ).action(async (agentId, options) => {
3974
+ await updateAgentCommand(agentId, {
3975
+ file: options.file,
3976
+ dryRun: options.dryRun,
3977
+ version: options.version ? parseInt(options.version, 10) : void 0
3978
+ });
3979
+ });
3821
3980
  var tools = program.command("tools").description("Manage agent tools (custom functions, webhooks, etc.)");
3822
3981
  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
3982
  "after",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "retell-cli",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Community CLI for Retell AI - efficient access to transcripts, agents, and prompts for AI assistants without MCP overhead",
5
5
  "main": "dist/index.js",
6
6
  "bin": {