retell-cli 1.2.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 +190 -1
- package/dist/index.js +511 -92
- 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]`
|
|
@@ -305,6 +355,81 @@ Publish a draft agent to make changes live.
|
|
|
305
355
|
retell agent-publish agent_123abc
|
|
306
356
|
```
|
|
307
357
|
|
|
358
|
+
### Agent Configuration
|
|
359
|
+
|
|
360
|
+
Manage agent-level settings that aren't part of prompts (voice, webhooks, post-call analysis, etc.).
|
|
361
|
+
|
|
362
|
+
#### `retell agent get <agent_id> [options]`
|
|
363
|
+
|
|
364
|
+
Get agent configuration including all agent-level settings.
|
|
365
|
+
|
|
366
|
+
**Options:**
|
|
367
|
+
- `--version <number>` - Specific version to retrieve (defaults to latest)
|
|
368
|
+
- `--fields <fields>` - Comma-separated list of fields to return
|
|
369
|
+
|
|
370
|
+
**Examples:**
|
|
371
|
+
```bash
|
|
372
|
+
# Get full agent config
|
|
373
|
+
retell agent get agent_123abc
|
|
374
|
+
|
|
375
|
+
# Get specific version
|
|
376
|
+
retell agent get agent_123abc --version 2
|
|
377
|
+
|
|
378
|
+
# Get specific fields only
|
|
379
|
+
retell agent get agent_123abc --fields agent_name,post_call_analysis_data
|
|
380
|
+
|
|
381
|
+
# Save config to file for editing
|
|
382
|
+
retell agent get agent_123abc > config.json
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
#### `retell agent update <agent_id> [options]`
|
|
386
|
+
|
|
387
|
+
Update agent configuration from a JSON file. This is useful for updating agent-level fields that aren't accessible through `prompts update`, such as:
|
|
388
|
+
- `post_call_analysis_data` - Custom data extraction from calls
|
|
389
|
+
- `post_call_analysis_model` - Model for analysis
|
|
390
|
+
- `analysis_successful_prompt` - Success criteria prompt
|
|
391
|
+
- `analysis_summary_prompt` - Summary generation prompt
|
|
392
|
+
- Voice settings, language, webhooks, and more
|
|
393
|
+
|
|
394
|
+
**Options:**
|
|
395
|
+
- `-f, --file <path>` - Path to JSON file containing agent configuration updates (required)
|
|
396
|
+
- `--dry-run` - Preview changes without applying them
|
|
397
|
+
- `--version <number>` - Specific version to update (defaults to latest draft)
|
|
398
|
+
|
|
399
|
+
**Example JSON for post-call analysis:**
|
|
400
|
+
```json
|
|
401
|
+
{
|
|
402
|
+
"post_call_analysis_model": "claude-4.5-sonnet",
|
|
403
|
+
"post_call_analysis_data": [
|
|
404
|
+
{
|
|
405
|
+
"name": "call_outcome",
|
|
406
|
+
"type": "enum",
|
|
407
|
+
"description": "Result of the call",
|
|
408
|
+
"choices": ["successful", "unsuccessful", "callback_needed"]
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
"name": "customer_sentiment",
|
|
412
|
+
"type": "string",
|
|
413
|
+
"description": "Overall customer sentiment"
|
|
414
|
+
}
|
|
415
|
+
],
|
|
416
|
+
"analysis_successful_prompt": "Determine if the issue was resolved.",
|
|
417
|
+
"analysis_summary_prompt": "Summarize the call in 2 sentences."
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**Examples:**
|
|
422
|
+
```bash
|
|
423
|
+
# Preview changes first (recommended)
|
|
424
|
+
retell agent update agent_123abc --file config.json --dry-run
|
|
425
|
+
|
|
426
|
+
# Apply changes
|
|
427
|
+
retell agent update agent_123abc --file config.json
|
|
428
|
+
|
|
429
|
+
# Remember to publish after updating
|
|
430
|
+
retell agent-publish agent_123abc
|
|
431
|
+
```
|
|
432
|
+
|
|
308
433
|
### Tools
|
|
309
434
|
|
|
310
435
|
Manage agent tools (custom functions, webhooks, etc.). Tools are embedded within Retell LLM and Conversation Flow configurations.
|
|
@@ -463,6 +588,70 @@ retell tools import agent_123abc --file tools.json --replace
|
|
|
463
588
|
retell agent-publish agent_123abc
|
|
464
589
|
```
|
|
465
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
|
+
|
|
466
655
|
### Field Selection
|
|
467
656
|
|
|
468
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
|
|
@@ -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,31 +789,151 @@ 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);
|
|
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
|
|
808
928
|
async function resolvePromptSource(agentId) {
|
|
809
929
|
const client = getRetellClient();
|
|
810
|
-
const
|
|
811
|
-
if (
|
|
812
|
-
const llm = await client.llm.retrieve(
|
|
930
|
+
const agent2 = await client.agent.retrieve(agentId);
|
|
931
|
+
if (agent2.response_engine.type === "retell-llm") {
|
|
932
|
+
const llm = await client.llm.retrieve(agent2.response_engine.llm_id);
|
|
813
933
|
return {
|
|
814
934
|
type: "retell-llm",
|
|
815
935
|
llmId: llm.llm_id,
|
|
816
|
-
agentName:
|
|
936
|
+
agentName: agent2.agent_name,
|
|
817
937
|
prompts: {
|
|
818
938
|
llm_id: llm.llm_id,
|
|
819
939
|
version: llm.version,
|
|
@@ -823,14 +943,14 @@ async function resolvePromptSource(agentId) {
|
|
|
823
943
|
}
|
|
824
944
|
};
|
|
825
945
|
}
|
|
826
|
-
if (
|
|
946
|
+
if (agent2.response_engine.type === "conversation-flow") {
|
|
827
947
|
const flow = await client.conversationFlow.retrieve(
|
|
828
|
-
|
|
948
|
+
agent2.response_engine.conversation_flow_id
|
|
829
949
|
);
|
|
830
950
|
return {
|
|
831
951
|
type: "conversation-flow",
|
|
832
952
|
flowId: flow.conversation_flow_id,
|
|
833
|
-
agentName:
|
|
953
|
+
agentName: agent2.agent_name,
|
|
834
954
|
prompts: {
|
|
835
955
|
conversation_flow_id: flow.conversation_flow_id,
|
|
836
956
|
version: flow.version,
|
|
@@ -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") {
|
|
@@ -1454,13 +1574,13 @@ async function publishAgentCommand(agentId) {
|
|
|
1454
1574
|
}
|
|
1455
1575
|
}
|
|
1456
1576
|
try {
|
|
1457
|
-
const
|
|
1577
|
+
const agent2 = await client.agent.retrieve(agentId);
|
|
1458
1578
|
outputJson({
|
|
1459
1579
|
message: "Agent published successfully",
|
|
1460
|
-
agent_id:
|
|
1461
|
-
agent_name:
|
|
1462
|
-
version:
|
|
1463
|
-
is_published:
|
|
1580
|
+
agent_id: agent2.agent_id,
|
|
1581
|
+
agent_name: agent2.agent_name || "Unknown",
|
|
1582
|
+
version: agent2.version || "Unknown",
|
|
1583
|
+
is_published: agent2.is_published ?? true,
|
|
1464
1584
|
note: "Draft version incremented and ready for new changes"
|
|
1465
1585
|
});
|
|
1466
1586
|
} catch (error) {
|
|
@@ -1468,12 +1588,109 @@ async function publishAgentCommand(agentId) {
|
|
|
1468
1588
|
}
|
|
1469
1589
|
}
|
|
1470
1590
|
|
|
1591
|
+
// src/commands/agent/get.ts
|
|
1592
|
+
async function getAgentCommand(agentId, options) {
|
|
1593
|
+
const client = getRetellClient();
|
|
1594
|
+
try {
|
|
1595
|
+
const agent2 = await client.agent.retrieve(agentId, {
|
|
1596
|
+
version: options.version
|
|
1597
|
+
});
|
|
1598
|
+
if (options.fields) {
|
|
1599
|
+
const fields = options.fields.split(",").map((f) => f.trim());
|
|
1600
|
+
const filtered = filterFields(agent2, fields);
|
|
1601
|
+
outputJson(filtered);
|
|
1602
|
+
} else {
|
|
1603
|
+
outputJson(agent2);
|
|
1604
|
+
}
|
|
1605
|
+
} catch (error) {
|
|
1606
|
+
handleSdkError(error);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
// src/commands/agent/update.ts
|
|
1611
|
+
var import_fs6 = require("fs");
|
|
1612
|
+
function validateFilePath(filePath) {
|
|
1613
|
+
if (filePath.includes("\0")) {
|
|
1614
|
+
throw new Error("Invalid file path: contains null bytes");
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
async function updateAgentCommand(agentId, options) {
|
|
1618
|
+
const client = getRetellClient();
|
|
1619
|
+
try {
|
|
1620
|
+
validateFilePath(options.file);
|
|
1621
|
+
if (!(0, import_fs6.existsSync)(options.file)) {
|
|
1622
|
+
outputError(`File not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
1623
|
+
return;
|
|
1624
|
+
}
|
|
1625
|
+
let updateParams;
|
|
1626
|
+
try {
|
|
1627
|
+
const fileContent = (0, import_fs6.readFileSync)(options.file, "utf-8");
|
|
1628
|
+
updateParams = JSON.parse(fileContent);
|
|
1629
|
+
} catch (error) {
|
|
1630
|
+
if (error instanceof SyntaxError) {
|
|
1631
|
+
outputError(`Invalid JSON in file: ${error.message}`, "INVALID_JSON");
|
|
1632
|
+
return;
|
|
1633
|
+
}
|
|
1634
|
+
throw error;
|
|
1635
|
+
}
|
|
1636
|
+
if (typeof updateParams !== "object" || updateParams === null || Array.isArray(updateParams)) {
|
|
1637
|
+
outputError(
|
|
1638
|
+
"File must contain a JSON object with agent configuration fields",
|
|
1639
|
+
"INVALID_FORMAT"
|
|
1640
|
+
);
|
|
1641
|
+
return;
|
|
1642
|
+
}
|
|
1643
|
+
if (options.dryRun) {
|
|
1644
|
+
const currentAgent = await client.agent.retrieve(agentId, {
|
|
1645
|
+
version: options.version
|
|
1646
|
+
});
|
|
1647
|
+
const changes = {};
|
|
1648
|
+
for (const [key, newValue] of Object.entries(updateParams)) {
|
|
1649
|
+
const currentValue = currentAgent[key];
|
|
1650
|
+
if (JSON.stringify(currentValue) !== JSON.stringify(newValue)) {
|
|
1651
|
+
changes[key] = {
|
|
1652
|
+
current: currentValue,
|
|
1653
|
+
new: newValue
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
outputJson({
|
|
1658
|
+
message: "Dry run - no changes applied",
|
|
1659
|
+
agent_id: agentId,
|
|
1660
|
+
agent_name: currentAgent.agent_name || "Unknown",
|
|
1661
|
+
fields_to_update: Object.keys(updateParams),
|
|
1662
|
+
changes: Object.keys(changes).length > 0 ? changes : "No changes detected (values are identical)",
|
|
1663
|
+
note: `Run without --dry-run to apply changes`
|
|
1664
|
+
});
|
|
1665
|
+
return;
|
|
1666
|
+
}
|
|
1667
|
+
const updatedAgent = await client.agent.update(
|
|
1668
|
+
agentId,
|
|
1669
|
+
updateParams
|
|
1670
|
+
);
|
|
1671
|
+
outputJson({
|
|
1672
|
+
message: "Agent updated successfully (draft version)",
|
|
1673
|
+
agent_id: updatedAgent.agent_id,
|
|
1674
|
+
agent_name: updatedAgent.agent_name || "Unknown",
|
|
1675
|
+
version: updatedAgent.version,
|
|
1676
|
+
fields_updated: Object.keys(updateParams),
|
|
1677
|
+
note: `Run 'retell agent-publish ${agentId}' to publish changes to production`
|
|
1678
|
+
});
|
|
1679
|
+
} catch (error) {
|
|
1680
|
+
if (error instanceof SyntaxError) {
|
|
1681
|
+
outputError(`Invalid JSON in file: ${error.message}`, "INVALID_JSON");
|
|
1682
|
+
return;
|
|
1683
|
+
}
|
|
1684
|
+
handleSdkError(error);
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1471
1688
|
// src/services/tool-resolver.ts
|
|
1472
1689
|
async function resolveToolsSource(agentId) {
|
|
1473
1690
|
const client = getRetellClient();
|
|
1474
|
-
const
|
|
1475
|
-
if (
|
|
1476
|
-
const llm = await client.llm.retrieve(
|
|
1691
|
+
const agent2 = await client.agent.retrieve(agentId);
|
|
1692
|
+
if (agent2.response_engine.type === "retell-llm") {
|
|
1693
|
+
const llm = await client.llm.retrieve(agent2.response_engine.llm_id);
|
|
1477
1694
|
const generalTools = llm.general_tools ?? [];
|
|
1478
1695
|
const stateTools = {};
|
|
1479
1696
|
if (llm.states) {
|
|
@@ -1492,16 +1709,16 @@ async function resolveToolsSource(agentId) {
|
|
|
1492
1709
|
return {
|
|
1493
1710
|
type: "retell-llm",
|
|
1494
1711
|
agentId,
|
|
1495
|
-
agentName:
|
|
1712
|
+
agentName: agent2.agent_name ?? "Unknown",
|
|
1496
1713
|
llmId: llm.llm_id,
|
|
1497
1714
|
generalTools,
|
|
1498
1715
|
stateTools,
|
|
1499
1716
|
totalCount
|
|
1500
1717
|
};
|
|
1501
1718
|
}
|
|
1502
|
-
if (
|
|
1719
|
+
if (agent2.response_engine.type === "conversation-flow") {
|
|
1503
1720
|
const flow = await client.conversationFlow.retrieve(
|
|
1504
|
-
|
|
1721
|
+
agent2.response_engine.conversation_flow_id
|
|
1505
1722
|
);
|
|
1506
1723
|
const flowTools = flow.tools ?? [];
|
|
1507
1724
|
const componentTools = {};
|
|
@@ -1521,7 +1738,7 @@ async function resolveToolsSource(agentId) {
|
|
|
1521
1738
|
return {
|
|
1522
1739
|
type: "conversation-flow",
|
|
1523
1740
|
agentId,
|
|
1524
|
-
agentName:
|
|
1741
|
+
agentName: agent2.agent_name ?? "Unknown",
|
|
1525
1742
|
flowId: flow.conversation_flow_id,
|
|
1526
1743
|
flowTools,
|
|
1527
1744
|
componentTools,
|
|
@@ -1796,16 +2013,16 @@ async function getToolCommand(agentId, toolName, options) {
|
|
|
1796
2013
|
}
|
|
1797
2014
|
|
|
1798
2015
|
// src/commands/tools/add.ts
|
|
1799
|
-
var
|
|
2016
|
+
var import_fs7 = require("fs");
|
|
1800
2017
|
async function addToolCommand(agentId, options) {
|
|
1801
2018
|
try {
|
|
1802
|
-
if (!(0,
|
|
2019
|
+
if (!(0, import_fs7.existsSync)(options.file)) {
|
|
1803
2020
|
outputError(`Tool file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
1804
2021
|
return;
|
|
1805
2022
|
}
|
|
1806
2023
|
let tool;
|
|
1807
2024
|
try {
|
|
1808
|
-
const content = (0,
|
|
2025
|
+
const content = (0, import_fs7.readFileSync)(options.file, "utf-8");
|
|
1809
2026
|
tool = JSON.parse(content);
|
|
1810
2027
|
} catch (error) {
|
|
1811
2028
|
if (error instanceof SyntaxError) {
|
|
@@ -1980,16 +2197,16 @@ async function addToolCommand(agentId, options) {
|
|
|
1980
2197
|
}
|
|
1981
2198
|
|
|
1982
2199
|
// src/commands/tools/update.ts
|
|
1983
|
-
var
|
|
2200
|
+
var import_fs8 = require("fs");
|
|
1984
2201
|
async function updateToolCommand(agentId, toolName, options) {
|
|
1985
2202
|
try {
|
|
1986
|
-
if (!(0,
|
|
2203
|
+
if (!(0, import_fs8.existsSync)(options.file)) {
|
|
1987
2204
|
outputError(`Tool file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
1988
2205
|
return;
|
|
1989
2206
|
}
|
|
1990
2207
|
let newTool;
|
|
1991
2208
|
try {
|
|
1992
|
-
const content = (0,
|
|
2209
|
+
const content = (0, import_fs8.readFileSync)(options.file, "utf-8");
|
|
1993
2210
|
newTool = JSON.parse(content);
|
|
1994
2211
|
} catch (error) {
|
|
1995
2212
|
if (error instanceof SyntaxError) {
|
|
@@ -2373,7 +2590,7 @@ async function removeToolCommand(agentId, toolName, options) {
|
|
|
2373
2590
|
}
|
|
2374
2591
|
|
|
2375
2592
|
// src/commands/tools/export.ts
|
|
2376
|
-
var
|
|
2593
|
+
var import_fs9 = require("fs");
|
|
2377
2594
|
async function exportToolsCommand(agentId, options) {
|
|
2378
2595
|
try {
|
|
2379
2596
|
const source = await resolveToolsSource(agentId);
|
|
@@ -2421,7 +2638,7 @@ async function exportToolsCommand(agentId, options) {
|
|
|
2421
2638
|
}
|
|
2422
2639
|
if (options.output) {
|
|
2423
2640
|
try {
|
|
2424
|
-
(0,
|
|
2641
|
+
(0, import_fs9.writeFileSync)(
|
|
2425
2642
|
options.output,
|
|
2426
2643
|
JSON.stringify(exportData, null, 2),
|
|
2427
2644
|
"utf-8"
|
|
@@ -2455,16 +2672,16 @@ async function exportToolsCommand(agentId, options) {
|
|
|
2455
2672
|
}
|
|
2456
2673
|
|
|
2457
2674
|
// src/commands/tools/import.ts
|
|
2458
|
-
var
|
|
2675
|
+
var import_fs10 = require("fs");
|
|
2459
2676
|
async function importToolsCommand(agentId, options) {
|
|
2460
2677
|
try {
|
|
2461
|
-
if (!(0,
|
|
2678
|
+
if (!(0, import_fs10.existsSync)(options.file)) {
|
|
2462
2679
|
outputError(`Import file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
2463
2680
|
return;
|
|
2464
2681
|
}
|
|
2465
2682
|
let importData;
|
|
2466
2683
|
try {
|
|
2467
|
-
const content = (0,
|
|
2684
|
+
const content = (0, import_fs10.readFileSync)(options.file, "utf-8");
|
|
2468
2685
|
importData = JSON.parse(content);
|
|
2469
2686
|
} catch (error) {
|
|
2470
2687
|
if (error instanceof SyntaxError) {
|
|
@@ -2864,7 +3081,7 @@ async function getTestCaseCommand(testCaseDefinitionId, options) {
|
|
|
2864
3081
|
}
|
|
2865
3082
|
|
|
2866
3083
|
// src/commands/tests/cases/create.ts
|
|
2867
|
-
var
|
|
3084
|
+
var import_fs11 = require("fs");
|
|
2868
3085
|
function buildResponseEngine2(options) {
|
|
2869
3086
|
if (options.llmId && options.flowId) {
|
|
2870
3087
|
outputError(
|
|
@@ -2902,7 +3119,7 @@ function buildResponseEngine2(options) {
|
|
|
2902
3119
|
}
|
|
2903
3120
|
async function createTestCaseCommand(options) {
|
|
2904
3121
|
try {
|
|
2905
|
-
if (!(0,
|
|
3122
|
+
if (!(0, import_fs11.existsSync)(options.file)) {
|
|
2906
3123
|
outputError(
|
|
2907
3124
|
`Test case file not found: ${options.file}`,
|
|
2908
3125
|
"FILE_NOT_FOUND"
|
|
@@ -2911,7 +3128,7 @@ async function createTestCaseCommand(options) {
|
|
|
2911
3128
|
}
|
|
2912
3129
|
let input;
|
|
2913
3130
|
try {
|
|
2914
|
-
const content = (0,
|
|
3131
|
+
const content = (0, import_fs11.readFileSync)(options.file, "utf-8");
|
|
2915
3132
|
input = JSON.parse(content);
|
|
2916
3133
|
} catch (error) {
|
|
2917
3134
|
if (error instanceof SyntaxError) {
|
|
@@ -2961,10 +3178,10 @@ async function createTestCaseCommand(options) {
|
|
|
2961
3178
|
}
|
|
2962
3179
|
|
|
2963
3180
|
// src/commands/tests/cases/update.ts
|
|
2964
|
-
var
|
|
3181
|
+
var import_fs12 = require("fs");
|
|
2965
3182
|
async function updateTestCaseCommand(testCaseDefinitionId, options) {
|
|
2966
3183
|
try {
|
|
2967
|
-
if (!(0,
|
|
3184
|
+
if (!(0, import_fs12.existsSync)(options.file)) {
|
|
2968
3185
|
outputError(
|
|
2969
3186
|
`Test case file not found: ${options.file}`,
|
|
2970
3187
|
"FILE_NOT_FOUND"
|
|
@@ -2973,7 +3190,7 @@ async function updateTestCaseCommand(testCaseDefinitionId, options) {
|
|
|
2973
3190
|
}
|
|
2974
3191
|
let input;
|
|
2975
3192
|
try {
|
|
2976
|
-
const content = (0,
|
|
3193
|
+
const content = (0, import_fs12.readFileSync)(options.file, "utf-8");
|
|
2977
3194
|
input = JSON.parse(content);
|
|
2978
3195
|
} catch (error) {
|
|
2979
3196
|
if (error instanceof SyntaxError) {
|
|
@@ -3230,7 +3447,7 @@ async function getKnowledgeBaseCommand(knowledgeBaseId, options) {
|
|
|
3230
3447
|
}
|
|
3231
3448
|
|
|
3232
3449
|
// src/commands/kb/create.ts
|
|
3233
|
-
var
|
|
3450
|
+
var import_fs13 = require("fs");
|
|
3234
3451
|
async function createKnowledgeBaseCommand(options) {
|
|
3235
3452
|
try {
|
|
3236
3453
|
if (options.name.length > 40) {
|
|
@@ -3253,12 +3470,12 @@ async function createKnowledgeBaseCommand(options) {
|
|
|
3253
3470
|
}
|
|
3254
3471
|
}
|
|
3255
3472
|
if (options.texts) {
|
|
3256
|
-
if (!(0,
|
|
3473
|
+
if (!(0, import_fs13.existsSync)(options.texts)) {
|
|
3257
3474
|
outputError(`Texts file not found: ${options.texts}`, "FILE_NOT_FOUND");
|
|
3258
3475
|
return;
|
|
3259
3476
|
}
|
|
3260
3477
|
try {
|
|
3261
|
-
const content = (0,
|
|
3478
|
+
const content = (0, import_fs13.readFileSync)(options.texts, "utf-8");
|
|
3262
3479
|
const textsData = JSON.parse(content);
|
|
3263
3480
|
if (!Array.isArray(textsData)) {
|
|
3264
3481
|
outputError(
|
|
@@ -3334,7 +3551,7 @@ async function deleteKnowledgeBaseCommand(knowledgeBaseId) {
|
|
|
3334
3551
|
}
|
|
3335
3552
|
|
|
3336
3553
|
// src/commands/kb/sources/add.ts
|
|
3337
|
-
var
|
|
3554
|
+
var import_fs14 = require("fs");
|
|
3338
3555
|
async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
|
|
3339
3556
|
try {
|
|
3340
3557
|
if (!options.urls && !options.texts) {
|
|
@@ -3352,12 +3569,12 @@ async function addKnowledgeBaseSourcesCommand(knowledgeBaseId, options) {
|
|
|
3352
3569
|
}
|
|
3353
3570
|
}
|
|
3354
3571
|
if (options.texts) {
|
|
3355
|
-
if (!(0,
|
|
3572
|
+
if (!(0, import_fs14.existsSync)(options.texts)) {
|
|
3356
3573
|
outputError(`Texts file not found: ${options.texts}`, "FILE_NOT_FOUND");
|
|
3357
3574
|
return;
|
|
3358
3575
|
}
|
|
3359
3576
|
try {
|
|
3360
|
-
const content = (0,
|
|
3577
|
+
const content = (0, import_fs14.readFileSync)(options.texts, "utf-8");
|
|
3361
3578
|
const textsData = JSON.parse(content);
|
|
3362
3579
|
if (!Array.isArray(textsData)) {
|
|
3363
3580
|
outputError(
|
|
@@ -3483,16 +3700,16 @@ async function getFlowCommand(conversationFlowId, options) {
|
|
|
3483
3700
|
}
|
|
3484
3701
|
|
|
3485
3702
|
// src/commands/flows/create.ts
|
|
3486
|
-
var
|
|
3703
|
+
var import_fs15 = require("fs");
|
|
3487
3704
|
async function createFlowCommand(options) {
|
|
3488
3705
|
try {
|
|
3489
|
-
if (!(0,
|
|
3706
|
+
if (!(0, import_fs15.existsSync)(options.file)) {
|
|
3490
3707
|
outputError(`Flow file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
3491
3708
|
return;
|
|
3492
3709
|
}
|
|
3493
3710
|
let flowConfig;
|
|
3494
3711
|
try {
|
|
3495
|
-
const content = (0,
|
|
3712
|
+
const content = (0, import_fs15.readFileSync)(options.file, "utf-8");
|
|
3496
3713
|
flowConfig = JSON.parse(content);
|
|
3497
3714
|
} catch (error) {
|
|
3498
3715
|
if (error instanceof SyntaxError) {
|
|
@@ -3530,16 +3747,16 @@ async function createFlowCommand(options) {
|
|
|
3530
3747
|
}
|
|
3531
3748
|
|
|
3532
3749
|
// src/commands/flows/update.ts
|
|
3533
|
-
var
|
|
3750
|
+
var import_fs16 = require("fs");
|
|
3534
3751
|
async function updateFlowCommand(conversationFlowId, options) {
|
|
3535
3752
|
try {
|
|
3536
|
-
if (!(0,
|
|
3753
|
+
if (!(0, import_fs16.existsSync)(options.file)) {
|
|
3537
3754
|
outputError(`Flow file not found: ${options.file}`, "FILE_NOT_FOUND");
|
|
3538
3755
|
return;
|
|
3539
3756
|
}
|
|
3540
3757
|
let flowUpdates;
|
|
3541
3758
|
try {
|
|
3542
|
-
const content = (0,
|
|
3759
|
+
const content = (0, import_fs16.readFileSync)(options.file, "utf-8");
|
|
3543
3760
|
flowUpdates = JSON.parse(content);
|
|
3544
3761
|
} catch (error) {
|
|
3545
3762
|
if (error instanceof SyntaxError) {
|
|
@@ -3591,9 +3808,81 @@ async function deleteFlowCommand(conversationFlowId) {
|
|
|
3591
3808
|
}
|
|
3592
3809
|
}
|
|
3593
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
|
+
|
|
3594
3883
|
// src/index.ts
|
|
3595
3884
|
var packageJson = JSON.parse(
|
|
3596
|
-
(0,
|
|
3885
|
+
(0, import_fs17.readFileSync)((0, import_path6.join)(__dirname, "../package.json"), "utf-8")
|
|
3597
3886
|
);
|
|
3598
3887
|
var program = new import_commander.Command();
|
|
3599
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);
|
|
@@ -3763,6 +4052,42 @@ Examples:
|
|
|
3763
4052
|
fields: options.fields
|
|
3764
4053
|
});
|
|
3765
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
|
+
});
|
|
3766
4091
|
var prompts = program.command("prompts").description("Manage agent prompts");
|
|
3767
4092
|
prompts.command("pull <agent_id>").description("Download agent prompts to a local file").option(
|
|
3768
4093
|
"-o, --output <path>",
|
|
@@ -3818,6 +4143,68 @@ Examples:
|
|
|
3818
4143
|
).action(async (agentId) => {
|
|
3819
4144
|
await publishAgentCommand(agentId);
|
|
3820
4145
|
});
|
|
4146
|
+
var agent = program.command("agent").description(
|
|
4147
|
+
"Manage agent-level configuration (voice, webhooks, post-call analysis, etc.)"
|
|
4148
|
+
);
|
|
4149
|
+
agent.command("get <agent_id>").description("Get agent configuration").option(
|
|
4150
|
+
"--version <number>",
|
|
4151
|
+
"Specific version to retrieve (defaults to latest)"
|
|
4152
|
+
).option(
|
|
4153
|
+
"--fields <fields>",
|
|
4154
|
+
"Comma-separated list of fields to return (e.g., agent_name,post_call_analysis_data)"
|
|
4155
|
+
).addHelpText(
|
|
4156
|
+
"after",
|
|
4157
|
+
`
|
|
4158
|
+
Examples:
|
|
4159
|
+
$ retell agent get agent_123abc
|
|
4160
|
+
$ retell agent get agent_123abc --version 2
|
|
4161
|
+
$ retell agent get agent_123abc --fields agent_name,post_call_analysis_data
|
|
4162
|
+
$ retell agent get agent_123abc > config.json
|
|
4163
|
+
`
|
|
4164
|
+
).action(async (agentId, options) => {
|
|
4165
|
+
await getAgentCommand(agentId, {
|
|
4166
|
+
version: options.version ? parseInt(options.version, 10) : void 0,
|
|
4167
|
+
fields: options.fields
|
|
4168
|
+
});
|
|
4169
|
+
});
|
|
4170
|
+
agent.command("update <agent_id>").description("Update agent configuration from a JSON file").requiredOption(
|
|
4171
|
+
"-f, --file <path>",
|
|
4172
|
+
"Path to JSON file containing agent configuration updates"
|
|
4173
|
+
).option("--dry-run", "Preview changes without applying them").option(
|
|
4174
|
+
"--version <number>",
|
|
4175
|
+
"Specific version to update (defaults to latest draft)"
|
|
4176
|
+
).addHelpText(
|
|
4177
|
+
"after",
|
|
4178
|
+
`
|
|
4179
|
+
Examples:
|
|
4180
|
+
$ retell agent update agent_123abc --file config.json
|
|
4181
|
+
$ retell agent update agent_123abc --file config.json --dry-run
|
|
4182
|
+
$ retell agent update agent_123abc --file analysis.json --version 2
|
|
4183
|
+
|
|
4184
|
+
Example JSON for post-call analysis:
|
|
4185
|
+
{
|
|
4186
|
+
"post_call_analysis_model": "claude-4.5-sonnet",
|
|
4187
|
+
"post_call_analysis_data": [
|
|
4188
|
+
{
|
|
4189
|
+
"name": "call_outcome",
|
|
4190
|
+
"type": "enum",
|
|
4191
|
+
"description": "Result of the call",
|
|
4192
|
+
"choices": ["successful", "unsuccessful", "callback_needed"]
|
|
4193
|
+
}
|
|
4194
|
+
],
|
|
4195
|
+
"analysis_successful_prompt": "Determine if the issue was resolved.",
|
|
4196
|
+
"analysis_summary_prompt": "Summarize the call in 2 sentences."
|
|
4197
|
+
}
|
|
4198
|
+
|
|
4199
|
+
Note: Run 'retell agent-publish <agent_id>' after updating to publish changes.
|
|
4200
|
+
`
|
|
4201
|
+
).action(async (agentId, options) => {
|
|
4202
|
+
await updateAgentCommand(agentId, {
|
|
4203
|
+
file: options.file,
|
|
4204
|
+
dryRun: options.dryRun,
|
|
4205
|
+
version: options.version ? parseInt(options.version, 10) : void 0
|
|
4206
|
+
});
|
|
4207
|
+
});
|
|
3821
4208
|
var tools = program.command("tools").description("Manage agent tools (custom functions, webhooks, etc.)");
|
|
3822
4209
|
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
4210
|
"after",
|
|
@@ -4301,6 +4688,38 @@ Examples:
|
|
|
4301
4688
|
).action(async (conversationFlowId) => {
|
|
4302
4689
|
await deleteFlowCommand(conversationFlowId);
|
|
4303
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
|
+
});
|
|
4304
4723
|
program.parse(process.argv);
|
|
4305
4724
|
if (!process.argv.slice(2).length) {
|
|
4306
4725
|
program.outputHelp();
|
package/package.json
CHANGED