retell-cli 1.1.1 → 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.
- package/README.md +75 -0
- package/dist/index.js +230 -65
- 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
|
|
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((
|
|
754
|
+
const formatted = agents2.map((agent2) => {
|
|
755
755
|
let response_engine_id;
|
|
756
|
-
switch (
|
|
756
|
+
switch (agent2.response_engine.type) {
|
|
757
757
|
case "retell-llm":
|
|
758
|
-
response_engine_id =
|
|
758
|
+
response_engine_id = agent2.response_engine.llm_id || "unknown";
|
|
759
759
|
break;
|
|
760
760
|
case "conversation-flow":
|
|
761
|
-
response_engine_id =
|
|
761
|
+
response_engine_id = agent2.response_engine.conversation_flow_id || "unknown";
|
|
762
762
|
break;
|
|
763
763
|
case "custom-llm":
|
|
764
|
-
response_engine_id =
|
|
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:
|
|
771
|
-
agent_name:
|
|
772
|
-
version:
|
|
773
|
-
is_published:
|
|
774
|
-
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
|
|
792
|
+
const agent2 = await client.agent.retrieve(agentId);
|
|
793
793
|
const output = options.fields ? filterFields(
|
|
794
|
-
|
|
794
|
+
agent2,
|
|
795
795
|
options.fields.split(",").map((f) => f.trim())
|
|
796
|
-
) :
|
|
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
|
|
811
|
-
if (
|
|
812
|
-
const llm = await client.llm.retrieve(
|
|
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:
|
|
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 (
|
|
826
|
+
if (agent2.response_engine.type === "conversation-flow") {
|
|
827
827
|
const flow = await client.conversationFlow.retrieve(
|
|
828
|
-
|
|
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:
|
|
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
|
|
1457
|
+
const agent2 = await client.agent.retrieve(agentId);
|
|
1458
1458
|
outputJson({
|
|
1459
1459
|
message: "Agent published successfully",
|
|
1460
|
-
agent_id:
|
|
1461
|
-
agent_name:
|
|
1462
|
-
version:
|
|
1463
|
-
is_published:
|
|
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
|
|
1475
|
-
if (
|
|
1476
|
-
const llm = await client.llm.retrieve(
|
|
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:
|
|
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 (
|
|
1599
|
+
if (agent2.response_engine.type === "conversation-flow") {
|
|
1503
1600
|
const flow = await client.conversationFlow.retrieve(
|
|
1504
|
-
|
|
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:
|
|
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
|
|
1896
|
+
var import_fs6 = require("fs");
|
|
1800
1897
|
async function addToolCommand(agentId, options) {
|
|
1801
1898
|
try {
|
|
1802
|
-
if (!(0,
|
|
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,
|
|
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
|
|
2080
|
+
var import_fs7 = require("fs");
|
|
1984
2081
|
async function updateToolCommand(agentId, toolName, options) {
|
|
1985
2082
|
try {
|
|
1986
|
-
if (!(0,
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
2555
|
+
var import_fs9 = require("fs");
|
|
2459
2556
|
async function importToolsCommand(agentId, options) {
|
|
2460
2557
|
try {
|
|
2461
|
-
if (!(0,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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) {
|
|
@@ -2938,7 +3035,10 @@ async function createTestCaseCommand(options) {
|
|
|
2938
3035
|
user_prompt: input.user_prompt,
|
|
2939
3036
|
scenario: input.scenario,
|
|
2940
3037
|
metrics: input.metrics,
|
|
2941
|
-
response_engine: responseEngine
|
|
3038
|
+
response_engine: responseEngine,
|
|
3039
|
+
dynamic_variables: input.dynamic_variables,
|
|
3040
|
+
tool_mocks: input.tool_mocks,
|
|
3041
|
+
llm_model: input.llm_model
|
|
2942
3042
|
});
|
|
2943
3043
|
const output = {
|
|
2944
3044
|
message: "Test case definition created successfully",
|
|
@@ -2958,10 +3058,10 @@ async function createTestCaseCommand(options) {
|
|
|
2958
3058
|
}
|
|
2959
3059
|
|
|
2960
3060
|
// src/commands/tests/cases/update.ts
|
|
2961
|
-
var
|
|
3061
|
+
var import_fs11 = require("fs");
|
|
2962
3062
|
async function updateTestCaseCommand(testCaseDefinitionId, options) {
|
|
2963
3063
|
try {
|
|
2964
|
-
if (!(0,
|
|
3064
|
+
if (!(0, import_fs11.existsSync)(options.file)) {
|
|
2965
3065
|
outputError(
|
|
2966
3066
|
`Test case file not found: ${options.file}`,
|
|
2967
3067
|
"FILE_NOT_FOUND"
|
|
@@ -2970,7 +3070,7 @@ async function updateTestCaseCommand(testCaseDefinitionId, options) {
|
|
|
2970
3070
|
}
|
|
2971
3071
|
let input;
|
|
2972
3072
|
try {
|
|
2973
|
-
const content = (0,
|
|
3073
|
+
const content = (0, import_fs11.readFileSync)(options.file, "utf-8");
|
|
2974
3074
|
input = JSON.parse(content);
|
|
2975
3075
|
} catch (error) {
|
|
2976
3076
|
if (error instanceof SyntaxError) {
|
|
@@ -2990,7 +3090,10 @@ async function updateTestCaseCommand(testCaseDefinitionId, options) {
|
|
|
2990
3090
|
name: input.name,
|
|
2991
3091
|
user_prompt: input.user_prompt,
|
|
2992
3092
|
scenario: input.scenario,
|
|
2993
|
-
metrics: input.metrics
|
|
3093
|
+
metrics: input.metrics,
|
|
3094
|
+
dynamic_variables: input.dynamic_variables,
|
|
3095
|
+
tool_mocks: input.tool_mocks,
|
|
3096
|
+
llm_model: input.llm_model
|
|
2994
3097
|
});
|
|
2995
3098
|
const output = {
|
|
2996
3099
|
message: "Test case definition updated successfully",
|
|
@@ -3224,7 +3327,7 @@ async function getKnowledgeBaseCommand(knowledgeBaseId, options) {
|
|
|
3224
3327
|
}
|
|
3225
3328
|
|
|
3226
3329
|
// src/commands/kb/create.ts
|
|
3227
|
-
var
|
|
3330
|
+
var import_fs12 = require("fs");
|
|
3228
3331
|
async function createKnowledgeBaseCommand(options) {
|
|
3229
3332
|
try {
|
|
3230
3333
|
if (options.name.length > 40) {
|
|
@@ -3247,12 +3350,12 @@ async function createKnowledgeBaseCommand(options) {
|
|
|
3247
3350
|
}
|
|
3248
3351
|
}
|
|
3249
3352
|
if (options.texts) {
|
|
3250
|
-
if (!(0,
|
|
3353
|
+
if (!(0, import_fs12.existsSync)(options.texts)) {
|
|
3251
3354
|
outputError(`Texts file not found: ${options.texts}`, "FILE_NOT_FOUND");
|
|
3252
3355
|
return;
|
|
3253
3356
|
}
|
|
3254
3357
|
try {
|
|
3255
|
-
const content = (0,
|
|
3358
|
+
const content = (0, import_fs12.readFileSync)(options.texts, "utf-8");
|
|
3256
3359
|
const textsData = JSON.parse(content);
|
|
3257
3360
|
if (!Array.isArray(textsData)) {
|
|
3258
3361
|
outputError(
|
|
@@ -3328,7 +3431,7 @@ async function deleteKnowledgeBaseCommand(knowledgeBaseId) {
|
|
|
3328
3431
|
}
|
|
3329
3432
|
|
|
3330
3433
|
// src/commands/kb/sources/add.ts
|
|
3331
|
-
var
|
|
3434
|
+
var import_fs13 = require("fs");
|
|
3332
3435
|
async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
|
|
3333
3436
|
try {
|
|
3334
3437
|
if (!options.urls && !options.texts) {
|
|
@@ -3346,12 +3449,12 @@ async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
|
|
|
3346
3449
|
}
|
|
3347
3450
|
}
|
|
3348
3451
|
if (options.texts) {
|
|
3349
|
-
if (!(0,
|
|
3452
|
+
if (!(0, import_fs13.existsSync)(options.texts)) {
|
|
3350
3453
|
outputError(`Texts file not found: ${options.texts}`, "FILE_NOT_FOUND");
|
|
3351
3454
|
return;
|
|
3352
3455
|
}
|
|
3353
3456
|
try {
|
|
3354
|
-
const content = (0,
|
|
3457
|
+
const content = (0, import_fs13.readFileSync)(options.texts, "utf-8");
|
|
3355
3458
|
const textsData = JSON.parse(content);
|
|
3356
3459
|
if (!Array.isArray(textsData)) {
|
|
3357
3460
|
outputError(
|
|
@@ -3477,16 +3580,16 @@ async function getFlowCommand(conversationFlowId, options) {
|
|
|
3477
3580
|
}
|
|
3478
3581
|
|
|
3479
3582
|
// src/commands/flows/create.ts
|
|
3480
|
-
var
|
|
3583
|
+
var import_fs14 = require("fs");
|
|
3481
3584
|
async function createFlowCommand(options) {
|
|
3482
3585
|
try {
|
|
3483
|
-
if (!(0,
|
|
3586
|
+
if (!(0, import_fs14.existsSync)(options.file)) {
|
|
3484
3587
|
outputError(`Flow file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
3485
3588
|
return;
|
|
3486
3589
|
}
|
|
3487
3590
|
let flowConfig;
|
|
3488
3591
|
try {
|
|
3489
|
-
const content = (0,
|
|
3592
|
+
const content = (0, import_fs14.readFileSync)(options.file, "utf-8");
|
|
3490
3593
|
flowConfig = JSON.parse(content);
|
|
3491
3594
|
} catch (error) {
|
|
3492
3595
|
if (error instanceof SyntaxError) {
|
|
@@ -3524,16 +3627,16 @@ async function createFlowCommand(options) {
|
|
|
3524
3627
|
}
|
|
3525
3628
|
|
|
3526
3629
|
// src/commands/flows/update.ts
|
|
3527
|
-
var
|
|
3630
|
+
var import_fs15 = require("fs");
|
|
3528
3631
|
async function updateFlowCommand(conversationFlowId, options) {
|
|
3529
3632
|
try {
|
|
3530
|
-
if (!(0,
|
|
3633
|
+
if (!(0, import_fs15.existsSync)(options.file)) {
|
|
3531
3634
|
outputError(`Flow file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
3532
3635
|
return;
|
|
3533
3636
|
}
|
|
3534
3637
|
let flowUpdates;
|
|
3535
3638
|
try {
|
|
3536
|
-
const content = (0,
|
|
3639
|
+
const content = (0, import_fs15.readFileSync)(options.file, "utf-8");
|
|
3537
3640
|
flowUpdates = JSON.parse(content);
|
|
3538
3641
|
} catch (error) {
|
|
3539
3642
|
if (error instanceof SyntaxError) {
|
|
@@ -3587,7 +3690,7 @@ async function deleteFlowCommand(conversationFlowId) {
|
|
|
3587
3690
|
|
|
3588
3691
|
// src/index.ts
|
|
3589
3692
|
var packageJson = JSON.parse(
|
|
3590
|
-
(0,
|
|
3693
|
+
(0, import_fs16.readFileSync)((0, import_path6.join)(__dirname, "../package.json"), "utf-8")
|
|
3591
3694
|
);
|
|
3592
3695
|
var program = new import_commander.Command();
|
|
3593
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);
|
|
@@ -3812,6 +3915,68 @@ Examples:
|
|
|
3812
3915
|
).action(async (agentId) => {
|
|
3813
3916
|
await publishAgentCommand(agentId);
|
|
3814
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
|
+
});
|
|
3815
3980
|
var tools = program.command("tools").description("Manage agent tools (custom functions, webhooks, etc.)");
|
|
3816
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(
|
|
3817
3982
|
"after",
|
package/package.json
CHANGED