retell-cli 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -0
- package/README.md +115 -1
- package/dist/index.js +323 -63
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,65 @@ All notable changes to the Retell AI CLI will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.4.0] - 2026-01-27
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Agent CRUD Commands
|
|
13
|
+
- **`retell agents create`** - Create new agents with configurable response engines
|
|
14
|
+
- `--voice` - Voice ID for the agent (required)
|
|
15
|
+
- `--name` - Agent name
|
|
16
|
+
- `--llm-id` - Retell LLM ID (creates retell-llm response engine)
|
|
17
|
+
- `--flow-id` - Conversation Flow ID (creates conversation-flow response engine)
|
|
18
|
+
- `--custom-llm` - Custom LLM WebSocket URL
|
|
19
|
+
- `--file` - Full agent config from JSON file
|
|
20
|
+
- `--fields` - Filter output fields
|
|
21
|
+
- Validates exactly one response engine type is specified
|
|
22
|
+
|
|
23
|
+
- **`retell agents delete <agent_id>`** - Delete an agent
|
|
24
|
+
- Returns success confirmation with deleted agent ID
|
|
25
|
+
|
|
26
|
+
- **`retell agents versions <agent_id>`** - List all versions of an agent
|
|
27
|
+
- Shows version number, publish status, agent name, and timestamp
|
|
28
|
+
- `--fields` - Filter output fields
|
|
29
|
+
|
|
30
|
+
#### Phone Number Commands
|
|
31
|
+
- **`retell phone-numbers list`** - List all phone numbers
|
|
32
|
+
- Shows phone number, pretty format, type, nickname, and agent IDs
|
|
33
|
+
- `--fields` - Filter output fields
|
|
34
|
+
|
|
35
|
+
- **`retell phone-numbers get <phone_number>`** - Get phone number details
|
|
36
|
+
- Retrieves full phone number configuration
|
|
37
|
+
- `--fields` - Filter output fields
|
|
38
|
+
|
|
39
|
+
- **`retell phone-numbers import`** - Import phone number from custom telephony
|
|
40
|
+
- `--number` - Phone number in E.164 format (required)
|
|
41
|
+
- `--termination-uri` - SIP trunk termination URI (required)
|
|
42
|
+
- `--nickname` - Friendly name for reference
|
|
43
|
+
- `--inbound-agent` - Agent ID for inbound calls
|
|
44
|
+
- `--outbound-agent` - Agent ID for outbound calls
|
|
45
|
+
- `--sip-username` - SIP trunk auth username
|
|
46
|
+
- `--sip-password` - SIP trunk auth password
|
|
47
|
+
- `--fields` - Filter output fields
|
|
48
|
+
|
|
49
|
+
#### Testing
|
|
50
|
+
- Added 32 new unit tests for all new commands
|
|
51
|
+
- 11 tests for `agents create` (validation, response engines, file loading)
|
|
52
|
+
- 3 tests for `agents delete` (success, error handling)
|
|
53
|
+
- 4 tests for `agents versions` (listing, filtering, errors)
|
|
54
|
+
- 4 tests for `phone-numbers list` (listing, filtering, errors)
|
|
55
|
+
- 4 tests for `phone-numbers get` (retrieval, filtering, errors)
|
|
56
|
+
- 6 tests for `phone-numbers import` (options, filtering, errors)
|
|
57
|
+
|
|
58
|
+
**Total: 138 tests passing** ✅
|
|
59
|
+
|
|
60
|
+
#### Documentation
|
|
61
|
+
- Updated README.md with complete command documentation
|
|
62
|
+
- Added examples for all new commands
|
|
63
|
+
- Updated features list to include phone number management
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
8
67
|
## [Unreleased] - v1.0.1
|
|
9
68
|
|
|
10
69
|
### Added - Phase 1: Foundation & Utilities
|
package/README.md
CHANGED
|
@@ -8,7 +8,8 @@ Community-built command-line tool for Retell AI - designed to give AI assistants
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
10
|
- **Transcript Management** - List, retrieve, and analyze call transcripts
|
|
11
|
-
- **Agent Management** -
|
|
11
|
+
- **Agent Management** - Full CRUD for Retell AI agents (create, list, update, delete, versions)
|
|
12
|
+
- **Phone Number Management** - List, retrieve, and import phone numbers
|
|
12
13
|
- **Prompt Engineering** - Pull, edit, and update agent prompts
|
|
13
14
|
- **Tool Management** - Full CRUD for agent tools (webhooks, custom functions, etc.)
|
|
14
15
|
- **Multi-format Support** - Works with Retell LLM and Conversation Flows
|
|
@@ -220,6 +221,55 @@ Get detailed information about a specific agent.
|
|
|
220
221
|
retell agents info agent_123abc
|
|
221
222
|
```
|
|
222
223
|
|
|
224
|
+
#### `retell agents create [options]`
|
|
225
|
+
|
|
226
|
+
Create a new agent with the specified configuration.
|
|
227
|
+
|
|
228
|
+
**Options:**
|
|
229
|
+
- `--voice <voice_id>` - Voice ID for the agent (required)
|
|
230
|
+
- `--name <name>` - Agent name
|
|
231
|
+
- `--llm-id <id>` - Retell LLM ID (creates retell-llm response engine)
|
|
232
|
+
- `--flow-id <id>` - Conversation Flow ID (creates conversation-flow response engine)
|
|
233
|
+
- `--custom-llm <url>` - Custom LLM WebSocket URL
|
|
234
|
+
- `-f, --file <path>` - Full agent config from JSON file (overrides other options)
|
|
235
|
+
- `--fields <fields>` - Comma-separated list of fields to return
|
|
236
|
+
|
|
237
|
+
**Note:** You must specify exactly one of `--llm-id`, `--flow-id`, `--custom-llm`, or `--file`.
|
|
238
|
+
|
|
239
|
+
**Examples:**
|
|
240
|
+
```bash
|
|
241
|
+
# Create agent with Retell LLM
|
|
242
|
+
retell agents create --voice 11labs-Adrian --llm-id llm_xxx --name "Support Agent"
|
|
243
|
+
|
|
244
|
+
# Create agent with Conversation Flow
|
|
245
|
+
retell agents create --voice 11labs-Adrian --flow-id cf_xxx
|
|
246
|
+
|
|
247
|
+
# Create agent from JSON config file
|
|
248
|
+
retell agents create --file agent-config.json
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### `retell agents delete <agent_id>`
|
|
252
|
+
|
|
253
|
+
Delete an agent.
|
|
254
|
+
|
|
255
|
+
**Example:**
|
|
256
|
+
```bash
|
|
257
|
+
retell agents delete agent_123abc
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### `retell agents versions <agent_id> [options]`
|
|
261
|
+
|
|
262
|
+
List all versions of an agent.
|
|
263
|
+
|
|
264
|
+
**Options:**
|
|
265
|
+
- `--fields <fields>` - Comma-separated list of fields to return
|
|
266
|
+
|
|
267
|
+
**Example:**
|
|
268
|
+
```bash
|
|
269
|
+
retell agents versions agent_123abc
|
|
270
|
+
retell agents versions agent_123abc --fields version,is_published
|
|
271
|
+
```
|
|
272
|
+
|
|
223
273
|
### Prompts
|
|
224
274
|
|
|
225
275
|
#### `retell prompts pull <agent_id> [options]`
|
|
@@ -538,6 +588,70 @@ retell tools import agent_123abc --file tools.json --replace
|
|
|
538
588
|
retell agent-publish agent_123abc
|
|
539
589
|
```
|
|
540
590
|
|
|
591
|
+
### Phone Numbers
|
|
592
|
+
|
|
593
|
+
Manage phone numbers for your Retell AI agents.
|
|
594
|
+
|
|
595
|
+
#### `retell phone-numbers list [options]`
|
|
596
|
+
|
|
597
|
+
List all phone numbers in your account.
|
|
598
|
+
|
|
599
|
+
**Options:**
|
|
600
|
+
- `--fields <fields>` - Comma-separated list of fields to return
|
|
601
|
+
|
|
602
|
+
**Example:**
|
|
603
|
+
```bash
|
|
604
|
+
retell phone-numbers list
|
|
605
|
+
retell phone-numbers list --fields phone_number,nickname,inbound_agent_id
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
#### `retell phone-numbers get <phone_number> [options]`
|
|
609
|
+
|
|
610
|
+
Get details of a specific phone number.
|
|
611
|
+
|
|
612
|
+
**Options:**
|
|
613
|
+
- `--fields <fields>` - Comma-separated list of fields to return
|
|
614
|
+
|
|
615
|
+
**Example:**
|
|
616
|
+
```bash
|
|
617
|
+
retell phone-numbers get +14157774444
|
|
618
|
+
retell phone-numbers get +14157774444 --fields phone_number,inbound_agent_id
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
#### `retell phone-numbers import [options]`
|
|
622
|
+
|
|
623
|
+
Import a phone number from custom telephony (e.g., Twilio, Vonage).
|
|
624
|
+
|
|
625
|
+
**Options:**
|
|
626
|
+
- `--number <number>` - Phone number in E.164 format (required)
|
|
627
|
+
- `--termination-uri <uri>` - SIP trunk termination URI (required)
|
|
628
|
+
- `--nickname <name>` - Friendly name for reference
|
|
629
|
+
- `--inbound-agent <id>` - Agent ID for inbound calls
|
|
630
|
+
- `--outbound-agent <id>` - Agent ID for outbound calls
|
|
631
|
+
- `--sip-username <user>` - SIP trunk auth username
|
|
632
|
+
- `--sip-password <pass>` - SIP trunk auth password
|
|
633
|
+
- `--fields <fields>` - Comma-separated list of fields to return
|
|
634
|
+
|
|
635
|
+
**Examples:**
|
|
636
|
+
```bash
|
|
637
|
+
# Basic import
|
|
638
|
+
retell phone-numbers import --number +14157774444 --termination-uri someuri.pstn.twilio.com
|
|
639
|
+
|
|
640
|
+
# Import with nickname and agent assignment
|
|
641
|
+
retell phone-numbers import \
|
|
642
|
+
--number +14157774444 \
|
|
643
|
+
--termination-uri someuri.pstn.twilio.com \
|
|
644
|
+
--nickname "Support Line" \
|
|
645
|
+
--inbound-agent agent_123abc
|
|
646
|
+
|
|
647
|
+
# Import with SIP authentication
|
|
648
|
+
retell phone-numbers import \
|
|
649
|
+
--number +14157774444 \
|
|
650
|
+
--termination-uri someuri.pstn.twilio.com \
|
|
651
|
+
--sip-username myuser \
|
|
652
|
+
--sip-password mypass
|
|
653
|
+
```
|
|
654
|
+
|
|
541
655
|
### Field Selection
|
|
542
656
|
|
|
543
657
|
Reduce output size and token usage by selecting specific fields:
|
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_fs17 = require("fs");
|
|
29
29
|
var import_path6 = require("path");
|
|
30
30
|
|
|
31
31
|
// src/commands/login.ts
|
|
@@ -800,8 +800,128 @@ async function agentInfoCommand(agentId, options = {}) {
|
|
|
800
800
|
}
|
|
801
801
|
}
|
|
802
802
|
|
|
803
|
-
// src/commands/
|
|
803
|
+
// src/commands/agents/create.ts
|
|
804
804
|
var import_fs2 = require("fs");
|
|
805
|
+
async function createAgentCommand(options) {
|
|
806
|
+
try {
|
|
807
|
+
const client = getRetellClient();
|
|
808
|
+
let config;
|
|
809
|
+
if (options.file) {
|
|
810
|
+
if (!(0, import_fs2.existsSync)(options.file)) {
|
|
811
|
+
outputError(`Config file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
try {
|
|
815
|
+
const content = (0, import_fs2.readFileSync)(options.file, "utf-8");
|
|
816
|
+
config = JSON.parse(content);
|
|
817
|
+
} catch (error) {
|
|
818
|
+
if (error instanceof SyntaxError) {
|
|
819
|
+
outputError(
|
|
820
|
+
`Invalid JSON in config file: ${error.message}`,
|
|
821
|
+
"INVALID_JSON"
|
|
822
|
+
);
|
|
823
|
+
} else if (error instanceof Error) {
|
|
824
|
+
outputError(
|
|
825
|
+
`Error reading config file: ${error.message}`,
|
|
826
|
+
"FILE_ERROR"
|
|
827
|
+
);
|
|
828
|
+
}
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
} else {
|
|
832
|
+
const engineCount = [
|
|
833
|
+
options.llmId,
|
|
834
|
+
options.flowId,
|
|
835
|
+
options.customLlm
|
|
836
|
+
].filter(Boolean).length;
|
|
837
|
+
if (engineCount === 0) {
|
|
838
|
+
outputError(
|
|
839
|
+
"Must specify one of: --llm-id, --flow-id, or --custom-llm",
|
|
840
|
+
"MISSING_RESPONSE_ENGINE"
|
|
841
|
+
);
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
if (engineCount > 1) {
|
|
845
|
+
outputError(
|
|
846
|
+
"Only one of --llm-id, --flow-id, or --custom-llm can be specified",
|
|
847
|
+
"MULTIPLE_RESPONSE_ENGINES"
|
|
848
|
+
);
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
let responseEngine;
|
|
852
|
+
if (options.llmId) {
|
|
853
|
+
responseEngine = {
|
|
854
|
+
type: "retell-llm",
|
|
855
|
+
llm_id: options.llmId
|
|
856
|
+
};
|
|
857
|
+
} else if (options.flowId) {
|
|
858
|
+
responseEngine = {
|
|
859
|
+
type: "conversation-flow",
|
|
860
|
+
conversation_flow_id: options.flowId
|
|
861
|
+
};
|
|
862
|
+
} else {
|
|
863
|
+
responseEngine = {
|
|
864
|
+
type: "custom-llm",
|
|
865
|
+
llm_websocket_url: options.customLlm
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
config = {
|
|
869
|
+
voice_id: options.voice,
|
|
870
|
+
response_engine: responseEngine
|
|
871
|
+
};
|
|
872
|
+
if (options.name) {
|
|
873
|
+
config.agent_name = options.name;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
const agent2 = await client.agent.create(config);
|
|
877
|
+
const output = options.fields ? filterFields(
|
|
878
|
+
agent2,
|
|
879
|
+
options.fields.split(",").map((f) => f.trim())
|
|
880
|
+
) : agent2;
|
|
881
|
+
outputJson(output);
|
|
882
|
+
} catch (error) {
|
|
883
|
+
handleSdkError(error);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
// src/commands/agents/delete.ts
|
|
888
|
+
async function deleteAgentCommand(agentId) {
|
|
889
|
+
try {
|
|
890
|
+
const client = getRetellClient();
|
|
891
|
+
await client.agent.delete(agentId);
|
|
892
|
+
outputJson({
|
|
893
|
+
message: "Agent deleted successfully",
|
|
894
|
+
agent_id: agentId,
|
|
895
|
+
operation: "delete"
|
|
896
|
+
});
|
|
897
|
+
} catch (error) {
|
|
898
|
+
handleSdkError(error);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// src/commands/agents/versions.ts
|
|
903
|
+
async function agentVersionsCommand(agentId, options = {}) {
|
|
904
|
+
try {
|
|
905
|
+
const client = getRetellClient();
|
|
906
|
+
const versions = await client.agent.getVersions(agentId);
|
|
907
|
+
const formatted = versions.map((v) => ({
|
|
908
|
+
version: v.version,
|
|
909
|
+
is_published: v.is_published,
|
|
910
|
+
agent_name: v.agent_name,
|
|
911
|
+
last_modification_timestamp: v.last_modification_timestamp
|
|
912
|
+
}));
|
|
913
|
+
const output = options.fields ? filterFields(
|
|
914
|
+
formatted,
|
|
915
|
+
options.fields.split(",").map((f) => f.trim())
|
|
916
|
+
) : formatted;
|
|
917
|
+
outputJson(output);
|
|
918
|
+
} catch (error) {
|
|
919
|
+
handleSdkError(error);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// src/commands/prompts/pull.ts
|
|
924
|
+
var import_fs3 = require("fs");
|
|
805
925
|
var import_path2 = require("path");
|
|
806
926
|
|
|
807
927
|
// src/services/prompt-resolver.ts
|
|
@@ -864,7 +984,7 @@ async function pullPromptsCommand(agentId, options) {
|
|
|
864
984
|
const baseDir = options.output || ".retell-prompts";
|
|
865
985
|
const agentDir = (0, import_path2.join)(baseDir, agentId);
|
|
866
986
|
try {
|
|
867
|
-
(0,
|
|
987
|
+
(0, import_fs3.mkdirSync)(agentDir, { recursive: true });
|
|
868
988
|
} catch (error) {
|
|
869
989
|
if (error.code === "EACCES") {
|
|
870
990
|
outputError(
|
|
@@ -921,26 +1041,26 @@ function saveRetellLlmPrompts(agentDir, promptSource) {
|
|
|
921
1041
|
version: prompts2.version,
|
|
922
1042
|
pulled_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
923
1043
|
};
|
|
924
|
-
(0,
|
|
1044
|
+
(0, import_fs3.writeFileSync)(
|
|
925
1045
|
(0, import_path2.join)(agentDir, "metadata.json"),
|
|
926
1046
|
JSON.stringify(metadata, null, 2)
|
|
927
1047
|
);
|
|
928
|
-
(0,
|
|
1048
|
+
(0, import_fs3.writeFileSync)(
|
|
929
1049
|
(0, import_path2.join)(agentDir, "general_prompt.md"),
|
|
930
1050
|
prompts2.general_prompt || ""
|
|
931
1051
|
);
|
|
932
1052
|
if (prompts2.begin_message) {
|
|
933
|
-
(0,
|
|
1053
|
+
(0, import_fs3.writeFileSync)((0, import_path2.join)(agentDir, "begin_message.txt"), prompts2.begin_message);
|
|
934
1054
|
}
|
|
935
1055
|
if (prompts2.states && prompts2.states.length > 0) {
|
|
936
1056
|
const statesDir = (0, import_path2.join)(agentDir, "states");
|
|
937
|
-
(0,
|
|
1057
|
+
(0, import_fs3.mkdirSync)(statesDir, { recursive: true });
|
|
938
1058
|
prompts2.states.forEach((state) => {
|
|
939
1059
|
const filename = `${state.name}.md`;
|
|
940
1060
|
const content = `# State: ${state.name}
|
|
941
1061
|
|
|
942
1062
|
${state.state_prompt}`;
|
|
943
|
-
(0,
|
|
1063
|
+
(0, import_fs3.writeFileSync)((0, import_path2.join)(statesDir, filename), content);
|
|
944
1064
|
});
|
|
945
1065
|
}
|
|
946
1066
|
}
|
|
@@ -953,15 +1073,15 @@ function saveConversationFlowPrompts(agentDir, promptSource) {
|
|
|
953
1073
|
version: prompts2.version,
|
|
954
1074
|
pulled_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
955
1075
|
};
|
|
956
|
-
(0,
|
|
1076
|
+
(0, import_fs3.writeFileSync)(
|
|
957
1077
|
(0, import_path2.join)(agentDir, "metadata.json"),
|
|
958
1078
|
JSON.stringify(metadata, null, 2)
|
|
959
1079
|
);
|
|
960
|
-
(0,
|
|
1080
|
+
(0, import_fs3.writeFileSync)(
|
|
961
1081
|
(0, import_path2.join)(agentDir, "global_prompt.md"),
|
|
962
1082
|
prompts2.global_prompt || ""
|
|
963
1083
|
);
|
|
964
|
-
(0,
|
|
1084
|
+
(0, import_fs3.writeFileSync)(
|
|
965
1085
|
(0, import_path2.join)(agentDir, "nodes.json"),
|
|
966
1086
|
JSON.stringify(prompts2.nodes, null, 2)
|
|
967
1087
|
);
|
|
@@ -984,27 +1104,27 @@ function getFilesCreated(type, promptSource) {
|
|
|
984
1104
|
}
|
|
985
1105
|
|
|
986
1106
|
// src/commands/prompts/update.ts
|
|
987
|
-
var
|
|
1107
|
+
var import_fs5 = require("fs");
|
|
988
1108
|
var import_path4 = require("path");
|
|
989
1109
|
|
|
990
1110
|
// src/services/prompt-loader.ts
|
|
991
|
-
var
|
|
1111
|
+
var import_fs4 = require("fs");
|
|
992
1112
|
var import_path3 = require("path");
|
|
993
1113
|
function loadLocalPrompts(agentId, agentDir) {
|
|
994
|
-
if (!(0,
|
|
1114
|
+
if (!(0, import_fs4.existsSync)(agentDir)) {
|
|
995
1115
|
throw new Error(
|
|
996
1116
|
`Prompts directory not found: ${agentDir}. Run 'retell prompts pull ${agentId}' first.`
|
|
997
1117
|
);
|
|
998
1118
|
}
|
|
999
1119
|
const metadataPath = (0, import_path3.join)(agentDir, "metadata.json");
|
|
1000
|
-
if (!(0,
|
|
1120
|
+
if (!(0, import_fs4.existsSync)(metadataPath)) {
|
|
1001
1121
|
throw new Error(
|
|
1002
1122
|
`metadata.json not found in ${agentDir}. Directory may be corrupted.`
|
|
1003
1123
|
);
|
|
1004
1124
|
}
|
|
1005
1125
|
let metadata;
|
|
1006
1126
|
try {
|
|
1007
|
-
metadata = JSON.parse((0,
|
|
1127
|
+
metadata = JSON.parse((0, import_fs4.readFileSync)(metadataPath, "utf-8"));
|
|
1008
1128
|
} catch (error) {
|
|
1009
1129
|
if (error instanceof SyntaxError) {
|
|
1010
1130
|
throw new Error(`Invalid JSON in metadata.json: ${error.message}`);
|
|
@@ -1034,18 +1154,18 @@ function loadLocalPrompts(agentId, agentDir) {
|
|
|
1034
1154
|
function loadRetellLlmPrompts(agentDir) {
|
|
1035
1155
|
const prompts2 = {};
|
|
1036
1156
|
const generalPromptPath = (0, import_path3.join)(agentDir, "general_prompt.md");
|
|
1037
|
-
if (!(0,
|
|
1157
|
+
if (!(0, import_fs4.existsSync)(generalPromptPath)) {
|
|
1038
1158
|
throw new Error("general_prompt.md not found");
|
|
1039
1159
|
}
|
|
1040
1160
|
try {
|
|
1041
|
-
prompts2.general_prompt = (0,
|
|
1161
|
+
prompts2.general_prompt = (0, import_fs4.readFileSync)(generalPromptPath, "utf-8");
|
|
1042
1162
|
} catch (error) {
|
|
1043
1163
|
throw new Error(`Failed to read general_prompt.md: ${error.message}`);
|
|
1044
1164
|
}
|
|
1045
1165
|
const beginMessagePath = (0, import_path3.join)(agentDir, "begin_message.txt");
|
|
1046
|
-
if ((0,
|
|
1166
|
+
if ((0, import_fs4.existsSync)(beginMessagePath)) {
|
|
1047
1167
|
try {
|
|
1048
|
-
const beginMessage = (0,
|
|
1168
|
+
const beginMessage = (0, import_fs4.readFileSync)(beginMessagePath, "utf-8");
|
|
1049
1169
|
if (beginMessage) {
|
|
1050
1170
|
prompts2.begin_message = beginMessage;
|
|
1051
1171
|
}
|
|
@@ -1054,9 +1174,9 @@ function loadRetellLlmPrompts(agentDir) {
|
|
|
1054
1174
|
}
|
|
1055
1175
|
}
|
|
1056
1176
|
const statesDir = (0, import_path3.join)(agentDir, "states");
|
|
1057
|
-
if ((0,
|
|
1177
|
+
if ((0, import_fs4.existsSync)(statesDir)) {
|
|
1058
1178
|
try {
|
|
1059
|
-
const stateFiles = (0,
|
|
1179
|
+
const stateFiles = (0, import_fs4.readdirSync)(statesDir).filter(
|
|
1060
1180
|
(f) => f.endsWith(".md")
|
|
1061
1181
|
);
|
|
1062
1182
|
if (stateFiles.length > 0) {
|
|
@@ -1064,7 +1184,7 @@ function loadRetellLlmPrompts(agentDir) {
|
|
|
1064
1184
|
const stateName = file.replace(".md", "");
|
|
1065
1185
|
let content;
|
|
1066
1186
|
try {
|
|
1067
|
-
content = (0,
|
|
1187
|
+
content = (0, import_fs4.readFileSync)((0, import_path3.join)(statesDir, file), "utf-8");
|
|
1068
1188
|
} catch (error) {
|
|
1069
1189
|
throw new Error(
|
|
1070
1190
|
`Failed to read state file ${file}: ${error.message}`
|
|
@@ -1096,20 +1216,20 @@ function loadRetellLlmPrompts(agentDir) {
|
|
|
1096
1216
|
function loadConversationFlowPrompts(agentDir) {
|
|
1097
1217
|
const prompts2 = {};
|
|
1098
1218
|
const globalPromptPath = (0, import_path3.join)(agentDir, "global_prompt.md");
|
|
1099
|
-
if (!(0,
|
|
1219
|
+
if (!(0, import_fs4.existsSync)(globalPromptPath)) {
|
|
1100
1220
|
throw new Error("global_prompt.md not found");
|
|
1101
1221
|
}
|
|
1102
1222
|
try {
|
|
1103
|
-
prompts2.global_prompt = (0,
|
|
1223
|
+
prompts2.global_prompt = (0, import_fs4.readFileSync)(globalPromptPath, "utf-8");
|
|
1104
1224
|
} catch (error) {
|
|
1105
1225
|
throw new Error(`Failed to read global_prompt.md: ${error.message}`);
|
|
1106
1226
|
}
|
|
1107
1227
|
const nodesPath = (0, import_path3.join)(agentDir, "nodes.json");
|
|
1108
|
-
if (!(0,
|
|
1228
|
+
if (!(0, import_fs4.existsSync)(nodesPath)) {
|
|
1109
1229
|
throw new Error("nodes.json not found");
|
|
1110
1230
|
}
|
|
1111
1231
|
try {
|
|
1112
|
-
const nodesContent = JSON.parse((0,
|
|
1232
|
+
const nodesContent = JSON.parse((0, import_fs4.readFileSync)(nodesPath, "utf-8"));
|
|
1113
1233
|
if (!Array.isArray(nodesContent)) {
|
|
1114
1234
|
throw new Error("nodes.json must contain an array");
|
|
1115
1235
|
}
|
|
@@ -1313,7 +1433,7 @@ async function updatePromptsCommand(agentId, options) {
|
|
|
1313
1433
|
validateAgentId2(agentId);
|
|
1314
1434
|
const baseDir = options.source || ".retell-prompts";
|
|
1315
1435
|
const agentDir = (0, import_path4.join)(baseDir, agentId);
|
|
1316
|
-
if (!(0,
|
|
1436
|
+
if (!(0, import_fs5.existsSync)(agentDir)) {
|
|
1317
1437
|
outputError(
|
|
1318
1438
|
`Prompts directory not found: ${agentDir}. Run 'retell prompts pull ${agentId}' first.`,
|
|
1319
1439
|
"DIRECTORY_NOT_FOUND"
|
|
@@ -1321,7 +1441,7 @@ async function updatePromptsCommand(agentId, options) {
|
|
|
1321
1441
|
return;
|
|
1322
1442
|
}
|
|
1323
1443
|
const metadataPath = (0, import_path4.join)(agentDir, "metadata.json");
|
|
1324
|
-
if (!(0,
|
|
1444
|
+
if (!(0, import_fs5.existsSync)(metadataPath)) {
|
|
1325
1445
|
outputError(
|
|
1326
1446
|
`metadata.json not found in ${agentDir}. Directory may be corrupted.`,
|
|
1327
1447
|
"METADATA_NOT_FOUND"
|
|
@@ -1329,7 +1449,7 @@ async function updatePromptsCommand(agentId, options) {
|
|
|
1329
1449
|
return;
|
|
1330
1450
|
}
|
|
1331
1451
|
const metadata = JSON.parse(
|
|
1332
|
-
(0,
|
|
1452
|
+
(0, import_fs5.readFileSync)(metadataPath, "utf-8")
|
|
1333
1453
|
);
|
|
1334
1454
|
const promptSource = await resolvePromptSource(agentId);
|
|
1335
1455
|
if (promptSource.type === "custom-llm") {
|
|
@@ -1488,7 +1608,7 @@ async function getAgentCommand(agentId, options) {
|
|
|
1488
1608
|
}
|
|
1489
1609
|
|
|
1490
1610
|
// src/commands/agent/update.ts
|
|
1491
|
-
var
|
|
1611
|
+
var import_fs6 = require("fs");
|
|
1492
1612
|
function validateFilePath(filePath) {
|
|
1493
1613
|
if (filePath.includes("\0")) {
|
|
1494
1614
|
throw new Error("Invalid file path: contains null bytes");
|
|
@@ -1498,13 +1618,13 @@ async function updateAgentCommand(agentId, options) {
|
|
|
1498
1618
|
const client = getRetellClient();
|
|
1499
1619
|
try {
|
|
1500
1620
|
validateFilePath(options.file);
|
|
1501
|
-
if (!(0,
|
|
1621
|
+
if (!(0, import_fs6.existsSync)(options.file)) {
|
|
1502
1622
|
outputError(`File not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
1503
1623
|
return;
|
|
1504
1624
|
}
|
|
1505
1625
|
let updateParams;
|
|
1506
1626
|
try {
|
|
1507
|
-
const fileContent = (0,
|
|
1627
|
+
const fileContent = (0, import_fs6.readFileSync)(options.file, "utf-8");
|
|
1508
1628
|
updateParams = JSON.parse(fileContent);
|
|
1509
1629
|
} catch (error) {
|
|
1510
1630
|
if (error instanceof SyntaxError) {
|
|
@@ -1893,16 +2013,16 @@ async function getToolCommand(agentId, toolName, options) {
|
|
|
1893
2013
|
}
|
|
1894
2014
|
|
|
1895
2015
|
// src/commands/tools/add.ts
|
|
1896
|
-
var
|
|
2016
|
+
var import_fs7 = require("fs");
|
|
1897
2017
|
async function addToolCommand(agentId, options) {
|
|
1898
2018
|
try {
|
|
1899
|
-
if (!(0,
|
|
2019
|
+
if (!(0, import_fs7.existsSync)(options.file)) {
|
|
1900
2020
|
outputError(`Tool file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
1901
2021
|
return;
|
|
1902
2022
|
}
|
|
1903
2023
|
let tool;
|
|
1904
2024
|
try {
|
|
1905
|
-
const content = (0,
|
|
2025
|
+
const content = (0, import_fs7.readFileSync)(options.file, "utf-8");
|
|
1906
2026
|
tool = JSON.parse(content);
|
|
1907
2027
|
} catch (error) {
|
|
1908
2028
|
if (error instanceof SyntaxError) {
|
|
@@ -2077,16 +2197,16 @@ async function addToolCommand(agentId, options) {
|
|
|
2077
2197
|
}
|
|
2078
2198
|
|
|
2079
2199
|
// src/commands/tools/update.ts
|
|
2080
|
-
var
|
|
2200
|
+
var import_fs8 = require("fs");
|
|
2081
2201
|
async function updateToolCommand(agentId, toolName, options) {
|
|
2082
2202
|
try {
|
|
2083
|
-
if (!(0,
|
|
2203
|
+
if (!(0, import_fs8.existsSync)(options.file)) {
|
|
2084
2204
|
outputError(`Tool file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
2085
2205
|
return;
|
|
2086
2206
|
}
|
|
2087
2207
|
let newTool;
|
|
2088
2208
|
try {
|
|
2089
|
-
const content = (0,
|
|
2209
|
+
const content = (0, import_fs8.readFileSync)(options.file, "utf-8");
|
|
2090
2210
|
newTool = JSON.parse(content);
|
|
2091
2211
|
} catch (error) {
|
|
2092
2212
|
if (error instanceof SyntaxError) {
|
|
@@ -2470,7 +2590,7 @@ async function removeToolCommand(agentId, toolName, options) {
|
|
|
2470
2590
|
}
|
|
2471
2591
|
|
|
2472
2592
|
// src/commands/tools/export.ts
|
|
2473
|
-
var
|
|
2593
|
+
var import_fs9 = require("fs");
|
|
2474
2594
|
async function exportToolsCommand(agentId, options) {
|
|
2475
2595
|
try {
|
|
2476
2596
|
const source = await resolveToolsSource(agentId);
|
|
@@ -2518,7 +2638,7 @@ async function exportToolsCommand(agentId, options) {
|
|
|
2518
2638
|
}
|
|
2519
2639
|
if (options.output) {
|
|
2520
2640
|
try {
|
|
2521
|
-
(0,
|
|
2641
|
+
(0, import_fs9.writeFileSync)(
|
|
2522
2642
|
options.output,
|
|
2523
2643
|
JSON.stringify(exportData, null, 2),
|
|
2524
2644
|
"utf-8"
|
|
@@ -2552,16 +2672,16 @@ async function exportToolsCommand(agentId, options) {
|
|
|
2552
2672
|
}
|
|
2553
2673
|
|
|
2554
2674
|
// src/commands/tools/import.ts
|
|
2555
|
-
var
|
|
2675
|
+
var import_fs10 = require("fs");
|
|
2556
2676
|
async function importToolsCommand(agentId, options) {
|
|
2557
2677
|
try {
|
|
2558
|
-
if (!(0,
|
|
2678
|
+
if (!(0, import_fs10.existsSync)(options.file)) {
|
|
2559
2679
|
outputError(`Import file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
2560
2680
|
return;
|
|
2561
2681
|
}
|
|
2562
2682
|
let importData;
|
|
2563
2683
|
try {
|
|
2564
|
-
const content = (0,
|
|
2684
|
+
const content = (0, import_fs10.readFileSync)(options.file, "utf-8");
|
|
2565
2685
|
importData = JSON.parse(content);
|
|
2566
2686
|
} catch (error) {
|
|
2567
2687
|
if (error instanceof SyntaxError) {
|
|
@@ -2961,7 +3081,7 @@ async function getTestCaseCommand(testCaseDefinitionId, options) {
|
|
|
2961
3081
|
}
|
|
2962
3082
|
|
|
2963
3083
|
// src/commands/tests/cases/create.ts
|
|
2964
|
-
var
|
|
3084
|
+
var import_fs11 = require("fs");
|
|
2965
3085
|
function buildResponseEngine2(options) {
|
|
2966
3086
|
if (options.llmId && options.flowId) {
|
|
2967
3087
|
outputError(
|
|
@@ -2999,7 +3119,7 @@ function buildResponseEngine2(options) {
|
|
|
2999
3119
|
}
|
|
3000
3120
|
async function createTestCaseCommand(options) {
|
|
3001
3121
|
try {
|
|
3002
|
-
if (!(0,
|
|
3122
|
+
if (!(0, import_fs11.existsSync)(options.file)) {
|
|
3003
3123
|
outputError(
|
|
3004
3124
|
`Test case file not found: ${options.file}`,
|
|
3005
3125
|
"FILE_NOT_FOUND"
|
|
@@ -3008,7 +3128,7 @@ async function createTestCaseCommand(options) {
|
|
|
3008
3128
|
}
|
|
3009
3129
|
let input;
|
|
3010
3130
|
try {
|
|
3011
|
-
const content = (0,
|
|
3131
|
+
const content = (0, import_fs11.readFileSync)(options.file, "utf-8");
|
|
3012
3132
|
input = JSON.parse(content);
|
|
3013
3133
|
} catch (error) {
|
|
3014
3134
|
if (error instanceof SyntaxError) {
|
|
@@ -3058,10 +3178,10 @@ async function createTestCaseCommand(options) {
|
|
|
3058
3178
|
}
|
|
3059
3179
|
|
|
3060
3180
|
// src/commands/tests/cases/update.ts
|
|
3061
|
-
var
|
|
3181
|
+
var import_fs12 = require("fs");
|
|
3062
3182
|
async function updateTestCaseCommand(testCaseDefinitionId, options) {
|
|
3063
3183
|
try {
|
|
3064
|
-
if (!(0,
|
|
3184
|
+
if (!(0, import_fs12.existsSync)(options.file)) {
|
|
3065
3185
|
outputError(
|
|
3066
3186
|
`Test case file not found: ${options.file}`,
|
|
3067
3187
|
"FILE_NOT_FOUND"
|
|
@@ -3070,7 +3190,7 @@ async function updateTestCaseCommand(testCaseDefinitionId, options) {
|
|
|
3070
3190
|
}
|
|
3071
3191
|
let input;
|
|
3072
3192
|
try {
|
|
3073
|
-
const content = (0,
|
|
3193
|
+
const content = (0, import_fs12.readFileSync)(options.file, "utf-8");
|
|
3074
3194
|
input = JSON.parse(content);
|
|
3075
3195
|
} catch (error) {
|
|
3076
3196
|
if (error instanceof SyntaxError) {
|
|
@@ -3327,7 +3447,7 @@ async function getKnowledgeBaseCommand(knowledgeBaseId, options) {
|
|
|
3327
3447
|
}
|
|
3328
3448
|
|
|
3329
3449
|
// src/commands/kb/create.ts
|
|
3330
|
-
var
|
|
3450
|
+
var import_fs13 = require("fs");
|
|
3331
3451
|
async function createKnowledgeBaseCommand(options) {
|
|
3332
3452
|
try {
|
|
3333
3453
|
if (options.name.length > 40) {
|
|
@@ -3350,12 +3470,12 @@ async function createKnowledgeBaseCommand(options) {
|
|
|
3350
3470
|
}
|
|
3351
3471
|
}
|
|
3352
3472
|
if (options.texts) {
|
|
3353
|
-
if (!(0,
|
|
3473
|
+
if (!(0, import_fs13.existsSync)(options.texts)) {
|
|
3354
3474
|
outputError(`Texts file not found: ${options.texts}`, "FILE_NOT_FOUND");
|
|
3355
3475
|
return;
|
|
3356
3476
|
}
|
|
3357
3477
|
try {
|
|
3358
|
-
const content = (0,
|
|
3478
|
+
const content = (0, import_fs13.readFileSync)(options.texts, "utf-8");
|
|
3359
3479
|
const textsData = JSON.parse(content);
|
|
3360
3480
|
if (!Array.isArray(textsData)) {
|
|
3361
3481
|
outputError(
|
|
@@ -3431,7 +3551,7 @@ async function deleteKnowledgeBaseCommand(knowledgeBaseId) {
|
|
|
3431
3551
|
}
|
|
3432
3552
|
|
|
3433
3553
|
// src/commands/kb/sources/add.ts
|
|
3434
|
-
var
|
|
3554
|
+
var import_fs14 = require("fs");
|
|
3435
3555
|
async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
|
|
3436
3556
|
try {
|
|
3437
3557
|
if (!options.urls && !options.texts) {
|
|
@@ -3449,12 +3569,12 @@ async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
|
|
|
3449
3569
|
}
|
|
3450
3570
|
}
|
|
3451
3571
|
if (options.texts) {
|
|
3452
|
-
if (!(0,
|
|
3572
|
+
if (!(0, import_fs14.existsSync)(options.texts)) {
|
|
3453
3573
|
outputError(`Texts file not found: ${options.texts}`, "FILE_NOT_FOUND");
|
|
3454
3574
|
return;
|
|
3455
3575
|
}
|
|
3456
3576
|
try {
|
|
3457
|
-
const content = (0,
|
|
3577
|
+
const content = (0, import_fs14.readFileSync)(options.texts, "utf-8");
|
|
3458
3578
|
const textsData = JSON.parse(content);
|
|
3459
3579
|
if (!Array.isArray(textsData)) {
|
|
3460
3580
|
outputError(
|
|
@@ -3580,16 +3700,16 @@ async function getFlowCommand(conversationFlowId, options) {
|
|
|
3580
3700
|
}
|
|
3581
3701
|
|
|
3582
3702
|
// src/commands/flows/create.ts
|
|
3583
|
-
var
|
|
3703
|
+
var import_fs15 = require("fs");
|
|
3584
3704
|
async function createFlowCommand(options) {
|
|
3585
3705
|
try {
|
|
3586
|
-
if (!(0,
|
|
3706
|
+
if (!(0, import_fs15.existsSync)(options.file)) {
|
|
3587
3707
|
outputError(`Flow file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
3588
3708
|
return;
|
|
3589
3709
|
}
|
|
3590
3710
|
let flowConfig;
|
|
3591
3711
|
try {
|
|
3592
|
-
const content = (0,
|
|
3712
|
+
const content = (0, import_fs15.readFileSync)(options.file, "utf-8");
|
|
3593
3713
|
flowConfig = JSON.parse(content);
|
|
3594
3714
|
} catch (error) {
|
|
3595
3715
|
if (error instanceof SyntaxError) {
|
|
@@ -3627,16 +3747,16 @@ async function createFlowCommand(options) {
|
|
|
3627
3747
|
}
|
|
3628
3748
|
|
|
3629
3749
|
// src/commands/flows/update.ts
|
|
3630
|
-
var
|
|
3750
|
+
var import_fs16 = require("fs");
|
|
3631
3751
|
async function updateFlowCommand(conversationFlowId, options) {
|
|
3632
3752
|
try {
|
|
3633
|
-
if (!(0,
|
|
3753
|
+
if (!(0, import_fs16.existsSync)(options.file)) {
|
|
3634
3754
|
outputError(`Flow file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
3635
3755
|
return;
|
|
3636
3756
|
}
|
|
3637
3757
|
let flowUpdates;
|
|
3638
3758
|
try {
|
|
3639
|
-
const content = (0,
|
|
3759
|
+
const content = (0, import_fs16.readFileSync)(options.file, "utf-8");
|
|
3640
3760
|
flowUpdates = JSON.parse(content);
|
|
3641
3761
|
} catch (error) {
|
|
3642
3762
|
if (error instanceof SyntaxError) {
|
|
@@ -3688,9 +3808,81 @@ async function deleteFlowCommand(conversationFlowId) {
|
|
|
3688
3808
|
}
|
|
3689
3809
|
}
|
|
3690
3810
|
|
|
3811
|
+
// src/commands/phone-numbers/list.ts
|
|
3812
|
+
async function listPhoneNumbersCommand(options = {}) {
|
|
3813
|
+
try {
|
|
3814
|
+
const client = getRetellClient();
|
|
3815
|
+
const phoneNumbers2 = await client.phoneNumber.list();
|
|
3816
|
+
const formatted = phoneNumbers2.map((pn) => ({
|
|
3817
|
+
phone_number: pn.phone_number,
|
|
3818
|
+
phone_number_pretty: pn.phone_number_pretty,
|
|
3819
|
+
phone_number_type: pn.phone_number_type,
|
|
3820
|
+
nickname: pn.nickname,
|
|
3821
|
+
inbound_agent_id: pn.inbound_agent_id,
|
|
3822
|
+
outbound_agent_id: pn.outbound_agent_id
|
|
3823
|
+
}));
|
|
3824
|
+
const output = options.fields ? filterFields(
|
|
3825
|
+
formatted,
|
|
3826
|
+
options.fields.split(",").map((f) => f.trim())
|
|
3827
|
+
) : formatted;
|
|
3828
|
+
outputJson(output);
|
|
3829
|
+
} catch (error) {
|
|
3830
|
+
handleSdkError(error);
|
|
3831
|
+
}
|
|
3832
|
+
}
|
|
3833
|
+
|
|
3834
|
+
// src/commands/phone-numbers/get.ts
|
|
3835
|
+
async function getPhoneNumberCommand(phoneNumber, options = {}) {
|
|
3836
|
+
try {
|
|
3837
|
+
const client = getRetellClient();
|
|
3838
|
+
const pn = await client.phoneNumber.retrieve(phoneNumber);
|
|
3839
|
+
const output = options.fields ? filterFields(
|
|
3840
|
+
pn,
|
|
3841
|
+
options.fields.split(",").map((f) => f.trim())
|
|
3842
|
+
) : pn;
|
|
3843
|
+
outputJson(output);
|
|
3844
|
+
} catch (error) {
|
|
3845
|
+
handleSdkError(error);
|
|
3846
|
+
}
|
|
3847
|
+
}
|
|
3848
|
+
|
|
3849
|
+
// src/commands/phone-numbers/import.ts
|
|
3850
|
+
async function importPhoneNumberCommand(options) {
|
|
3851
|
+
try {
|
|
3852
|
+
const client = getRetellClient();
|
|
3853
|
+
const importParams = {
|
|
3854
|
+
phone_number: options.number,
|
|
3855
|
+
termination_uri: options.terminationUri
|
|
3856
|
+
};
|
|
3857
|
+
if (options.nickname) {
|
|
3858
|
+
importParams.nickname = options.nickname;
|
|
3859
|
+
}
|
|
3860
|
+
if (options.inboundAgent) {
|
|
3861
|
+
importParams.inbound_agent_id = options.inboundAgent;
|
|
3862
|
+
}
|
|
3863
|
+
if (options.outboundAgent) {
|
|
3864
|
+
importParams.outbound_agent_id = options.outboundAgent;
|
|
3865
|
+
}
|
|
3866
|
+
if (options.sipUsername) {
|
|
3867
|
+
importParams.sip_trunk_auth_username = options.sipUsername;
|
|
3868
|
+
}
|
|
3869
|
+
if (options.sipPassword) {
|
|
3870
|
+
importParams.sip_trunk_auth_password = options.sipPassword;
|
|
3871
|
+
}
|
|
3872
|
+
const pn = await client.phoneNumber.import(importParams);
|
|
3873
|
+
const output = options.fields ? filterFields(
|
|
3874
|
+
pn,
|
|
3875
|
+
options.fields.split(",").map((f) => f.trim())
|
|
3876
|
+
) : pn;
|
|
3877
|
+
outputJson(output);
|
|
3878
|
+
} catch (error) {
|
|
3879
|
+
handleSdkError(error);
|
|
3880
|
+
}
|
|
3881
|
+
}
|
|
3882
|
+
|
|
3691
3883
|
// src/index.ts
|
|
3692
3884
|
var packageJson = JSON.parse(
|
|
3693
|
-
(0,
|
|
3885
|
+
(0, import_fs17.readFileSync)((0, import_path6.join)(__dirname, "../package.json"), "utf-8")
|
|
3694
3886
|
);
|
|
3695
3887
|
var program = new import_commander.Command();
|
|
3696
3888
|
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);
|
|
@@ -3860,6 +4052,42 @@ Examples:
|
|
|
3860
4052
|
fields: options.fields
|
|
3861
4053
|
});
|
|
3862
4054
|
});
|
|
4055
|
+
agents.command("create").description("Create a new agent").requiredOption("--voice <voice_id>", "Voice ID for the agent").option("--name <name>", "Agent name").option("--llm-id <id>", "Retell LLM ID (creates retell-llm response engine)").option(
|
|
4056
|
+
"--flow-id <id>",
|
|
4057
|
+
"Conversation Flow ID (creates conversation-flow response engine)"
|
|
4058
|
+
).option("--custom-llm <url>", "Custom LLM WebSocket URL").option(
|
|
4059
|
+
"-f, --file <path>",
|
|
4060
|
+
"Full agent config from JSON file (overrides other options)"
|
|
4061
|
+
).option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
|
|
4062
|
+
"after",
|
|
4063
|
+
`
|
|
4064
|
+
Examples:
|
|
4065
|
+
$ retell agents create --voice 11labs-Adrian --llm-id llm_xxx --name "Test Agent"
|
|
4066
|
+
$ retell agents create --voice 11labs-Adrian --flow-id cf_xxx
|
|
4067
|
+
$ retell agents create --file agent-config.json
|
|
4068
|
+
`
|
|
4069
|
+
).action(async (options) => {
|
|
4070
|
+
await createAgentCommand(options);
|
|
4071
|
+
});
|
|
4072
|
+
agents.command("delete <agent_id>").description("Delete an agent").addHelpText(
|
|
4073
|
+
"after",
|
|
4074
|
+
`
|
|
4075
|
+
Examples:
|
|
4076
|
+
$ retell agents delete agent_123abc
|
|
4077
|
+
`
|
|
4078
|
+
).action(async (agentId) => {
|
|
4079
|
+
await deleteAgentCommand(agentId);
|
|
4080
|
+
});
|
|
4081
|
+
agents.command("versions <agent_id>").description("List all versions of an agent").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
|
|
4082
|
+
"after",
|
|
4083
|
+
`
|
|
4084
|
+
Examples:
|
|
4085
|
+
$ retell agents versions agent_123abc
|
|
4086
|
+
$ retell agents versions agent_123abc --fields version,is_published
|
|
4087
|
+
`
|
|
4088
|
+
).action(async (agentId, options) => {
|
|
4089
|
+
await agentVersionsCommand(agentId, options);
|
|
4090
|
+
});
|
|
3863
4091
|
var prompts = program.command("prompts").description("Manage agent prompts");
|
|
3864
4092
|
prompts.command("pull <agent_id>").description("Download agent prompts to a local file").option(
|
|
3865
4093
|
"-o, --output <path>",
|
|
@@ -4460,6 +4688,38 @@ Examples:
|
|
|
4460
4688
|
).action(async (conversationFlowId) => {
|
|
4461
4689
|
await deleteFlowCommand(conversationFlowId);
|
|
4462
4690
|
});
|
|
4691
|
+
var phoneNumbers = program.command("phone-numbers").description("Manage phone numbers");
|
|
4692
|
+
phoneNumbers.command("list").description("List all phone numbers").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
|
|
4693
|
+
"after",
|
|
4694
|
+
`
|
|
4695
|
+
Examples:
|
|
4696
|
+
$ retell phone-numbers list
|
|
4697
|
+
$ retell phone-numbers list --fields phone_number,nickname,inbound_agent_id
|
|
4698
|
+
`
|
|
4699
|
+
).action(async (options) => {
|
|
4700
|
+
await listPhoneNumbersCommand(options);
|
|
4701
|
+
});
|
|
4702
|
+
phoneNumbers.command("get <phone_number>").description("Get phone number details").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
|
|
4703
|
+
"after",
|
|
4704
|
+
`
|
|
4705
|
+
Examples:
|
|
4706
|
+
$ retell phone-numbers get +14157774444
|
|
4707
|
+
$ retell phone-numbers get +14157774444 --fields phone_number,inbound_agent_id
|
|
4708
|
+
`
|
|
4709
|
+
).action(async (phoneNumber, options) => {
|
|
4710
|
+
await getPhoneNumberCommand(phoneNumber, options);
|
|
4711
|
+
});
|
|
4712
|
+
phoneNumbers.command("import").description("Import a phone number from custom telephony").requiredOption("--number <number>", "Phone number in E.164 format").requiredOption("--termination-uri <uri>", "SIP trunk termination URI").option("--nickname <name>", "Friendly name for reference").option("--inbound-agent <id>", "Agent ID for inbound calls").option("--outbound-agent <id>", "Agent ID for outbound calls").option("--sip-username <user>", "SIP trunk auth username").option("--sip-password <pass>", "SIP trunk auth password").option("--fields <fields>", "Comma-separated list of fields to return").addHelpText(
|
|
4713
|
+
"after",
|
|
4714
|
+
`
|
|
4715
|
+
Examples:
|
|
4716
|
+
$ retell phone-numbers import --number +14157774444 --termination-uri someuri.pstn.twilio.com
|
|
4717
|
+
$ retell phone-numbers import --number +14157774444 --termination-uri someuri.pstn.twilio.com --nickname "Support Line"
|
|
4718
|
+
$ retell phone-numbers import --number +14157774444 --termination-uri someuri.pstn.twilio.com --inbound-agent agent_xxx
|
|
4719
|
+
`
|
|
4720
|
+
).action(async (options) => {
|
|
4721
|
+
await importPhoneNumberCommand(options);
|
|
4722
|
+
});
|
|
4463
4723
|
program.parse(process.argv);
|
|
4464
4724
|
if (!process.argv.slice(2).length) {
|
|
4465
4725
|
program.outputHelp();
|
package/package.json
CHANGED