retell-sync-cli 3.11.0 → 3.13.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/dist/cli.js +31 -130
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -133802,8 +133802,6 @@ async function formatWithPrettier(content, opts) {
|
|
|
133802
133802
|
// src/lib/utils.ts
|
|
133803
133803
|
var DEFAULT_AGENTS_DIR = "./agents";
|
|
133804
133804
|
var FILE_HASH_LENGTH = 6;
|
|
133805
|
-
var CONFIG_FORMATS = ["yaml", "yml", "json", "jsonc"];
|
|
133806
|
-
var DEFAULT_CONFIG_FORMAT = "yaml";
|
|
133807
133805
|
async function readMarkdown(content) {
|
|
133808
133806
|
const trimmed = content.trim();
|
|
133809
133807
|
if (!trimmed.startsWith("---")) {
|
|
@@ -133843,69 +133841,9 @@ function readJson2(content, schema) {
|
|
|
133843
133841
|
}
|
|
133844
133842
|
return parsed;
|
|
133845
133843
|
}
|
|
133846
|
-
function stripJsoncComments(content) {
|
|
133847
|
-
return content.split(`
|
|
133848
|
-
`).map((line3) => {
|
|
133849
|
-
let inString = false;
|
|
133850
|
-
let escaped = false;
|
|
133851
|
-
for (let i5 = 0;i5 < line3.length; i5++) {
|
|
133852
|
-
const char = line3[i5];
|
|
133853
|
-
if (escaped) {
|
|
133854
|
-
escaped = false;
|
|
133855
|
-
continue;
|
|
133856
|
-
}
|
|
133857
|
-
if (char === "\\") {
|
|
133858
|
-
escaped = true;
|
|
133859
|
-
continue;
|
|
133860
|
-
}
|
|
133861
|
-
if (char === '"') {
|
|
133862
|
-
inString = !inString;
|
|
133863
|
-
continue;
|
|
133864
|
-
}
|
|
133865
|
-
if (!inString && char === "/" && line3[i5 + 1] === "/") {
|
|
133866
|
-
return line3.slice(0, i5).trimEnd();
|
|
133867
|
-
}
|
|
133868
|
-
}
|
|
133869
|
-
return line3;
|
|
133870
|
-
}).join(`
|
|
133871
|
-
`);
|
|
133872
|
-
}
|
|
133873
|
-
function readJsonc(content, schema) {
|
|
133874
|
-
const stripped = stripJsoncComments(content);
|
|
133875
|
-
return readJson2(stripped, schema);
|
|
133876
|
-
}
|
|
133877
133844
|
async function writeJson(obj) {
|
|
133878
133845
|
return formatWithPrettier(JSON.stringify(obj), { parser: "json" });
|
|
133879
133846
|
}
|
|
133880
|
-
async function writeJsonc(obj, { comments = {} } = {}) {
|
|
133881
|
-
const json2 = await formatWithPrettier(JSON.stringify(obj), {
|
|
133882
|
-
parser: "json"
|
|
133883
|
-
});
|
|
133884
|
-
if (Object.keys(comments).length === 0) {
|
|
133885
|
-
return json2;
|
|
133886
|
-
}
|
|
133887
|
-
const lines = json2.split(`
|
|
133888
|
-
`);
|
|
133889
|
-
const result2 = [];
|
|
133890
|
-
let isFirstKey = true;
|
|
133891
|
-
for (const line3 of lines) {
|
|
133892
|
-
const keyMatch = line3.match(/^ {2}"([^"]+)":\s*/);
|
|
133893
|
-
if (keyMatch?.[1]) {
|
|
133894
|
-
const key2 = keyMatch[1];
|
|
133895
|
-
const comment = comments[key2];
|
|
133896
|
-
if (comment) {
|
|
133897
|
-
if (!isFirstKey) {
|
|
133898
|
-
result2.push("");
|
|
133899
|
-
}
|
|
133900
|
-
result2.push(` // ${comment}`);
|
|
133901
|
-
}
|
|
133902
|
-
isFirstKey = false;
|
|
133903
|
-
}
|
|
133904
|
-
result2.push(line3);
|
|
133905
|
-
}
|
|
133906
|
-
return result2.join(`
|
|
133907
|
-
`);
|
|
133908
|
-
}
|
|
133909
133847
|
function readYaml(content, schema) {
|
|
133910
133848
|
const parsed = import_yaml2.default.parse(content);
|
|
133911
133849
|
if (schema) {
|
|
@@ -134225,10 +134163,9 @@ async function getLocalState({
|
|
|
134225
134163
|
}
|
|
134226
134164
|
async function writeState(state, {
|
|
134227
134165
|
agentsDir = DEFAULT_AGENTS_DIR,
|
|
134228
|
-
configFormat = DEFAULT_CONFIG_FORMAT,
|
|
134229
134166
|
agentIds = null
|
|
134230
134167
|
} = {}) {
|
|
134231
|
-
const files = await serializeState(state, { agentsDir
|
|
134168
|
+
const files = await serializeState(state, { agentsDir });
|
|
134232
134169
|
const writtenFiles = new Set;
|
|
134233
134170
|
for (const [filePath, content] of Object.entries(files)) {
|
|
134234
134171
|
const fullPath = path15.resolve(filePath);
|
|
@@ -134282,13 +134219,7 @@ async function listFilesRecursive(dir) {
|
|
|
134282
134219
|
}
|
|
134283
134220
|
return files;
|
|
134284
134221
|
}
|
|
134285
|
-
async function serializeState(state, {
|
|
134286
|
-
agentsDir = DEFAULT_AGENTS_DIR,
|
|
134287
|
-
configFormat = DEFAULT_CONFIG_FORMAT
|
|
134288
|
-
} = {}) {
|
|
134289
|
-
const isYaml = configFormat === "yaml" || configFormat === "yml";
|
|
134290
|
-
const isJsonc = configFormat === "jsonc";
|
|
134291
|
-
const configExt = configFormat;
|
|
134222
|
+
async function serializeState(state, { agentsDir = DEFAULT_AGENTS_DIR } = {}) {
|
|
134292
134223
|
const files = {};
|
|
134293
134224
|
const llmMap = new Map(state.llms.map((llm) => [llm._id, llm]));
|
|
134294
134225
|
const flowMap = new Map(state.conversationFlows.map((flow) => [flow._id, flow]));
|
|
@@ -134301,7 +134232,7 @@ async function serializeState(state, {
|
|
|
134301
134232
|
files[path15.join(agentDirPath, "general_prompt.md")] = await writeMarkdown(llmConfig.general_prompt);
|
|
134302
134233
|
llmConfig.general_prompt = "file://./general_prompt.md";
|
|
134303
134234
|
}
|
|
134304
|
-
files[path15.join(agentDirPath,
|
|
134235
|
+
files[path15.join(agentDirPath, "llm.yaml")] = await writeYaml(llmConfig, { comments: llmFieldDocs });
|
|
134305
134236
|
}
|
|
134306
134237
|
} else if (agent.response_engine.type === "conversation-flow") {
|
|
134307
134238
|
const flow = flowMap.get(agent.response_engine.conversation_flow_id);
|
|
@@ -134378,7 +134309,7 @@ async function serializeState(state, {
|
|
|
134378
134309
|
if (Object.keys(positions).length > 0) {
|
|
134379
134310
|
files[path15.join(agentDirPath, ".positions.json")] = await writeJson(positions);
|
|
134380
134311
|
}
|
|
134381
|
-
files[path15.join(agentDirPath,
|
|
134312
|
+
files[path15.join(agentDirPath, "conversation-flow.yaml")] = await writeYaml(flowConfig, { comments: flowFieldDocs });
|
|
134382
134313
|
}
|
|
134383
134314
|
}
|
|
134384
134315
|
};
|
|
@@ -134403,7 +134334,7 @@ async function serializeState(state, {
|
|
|
134403
134334
|
llm_websocket_url: agent.response_engine.llm_websocket_url
|
|
134404
134335
|
} : voiceAgentConfig;
|
|
134405
134336
|
await serializeResponseEngine(agent, agentDirPath);
|
|
134406
|
-
files[path15.join(agentDirPath,
|
|
134337
|
+
files[path15.join(agentDirPath, "config.yaml")] = await writeYaml(configToWrite, { comments: agentFieldDocs });
|
|
134407
134338
|
}
|
|
134408
134339
|
for (const agent of state.chatAgents) {
|
|
134409
134340
|
const agentDirName = getAgentDirName(agent);
|
|
@@ -134426,7 +134357,7 @@ async function serializeState(state, {
|
|
|
134426
134357
|
llm_websocket_url: agent.response_engine.llm_websocket_url
|
|
134427
134358
|
} : chatAgentConfig;
|
|
134428
134359
|
await serializeResponseEngine(agent, agentDirPath);
|
|
134429
|
-
files[path15.join(agentDirPath,
|
|
134360
|
+
files[path15.join(agentDirPath, "config.yaml")] = await writeYaml(chatConfigToWrite, { comments: chatAgentFieldDocs });
|
|
134430
134361
|
}
|
|
134431
134362
|
return files;
|
|
134432
134363
|
}
|
|
@@ -134461,20 +134392,10 @@ async function canonicalizeFromFiles(files) {
|
|
|
134461
134392
|
})
|
|
134462
134393
|
])
|
|
134463
134394
|
}));
|
|
134464
|
-
const
|
|
134465
|
-
|
|
134466
|
-
const content = fileMap[`${agentDir}/${baseName}.${ext}`];
|
|
134467
|
-
if (content) {
|
|
134468
|
-
const reader = ext === "jsonc" ? readJsonc : ext === "json" ? readJson2 : readYaml;
|
|
134469
|
-
return { content, reader };
|
|
134470
|
-
}
|
|
134471
|
-
}
|
|
134472
|
-
return null;
|
|
134473
|
-
};
|
|
134474
|
-
const configResult = findConfigFile("config");
|
|
134475
|
-
if (!configResult)
|
|
134395
|
+
const configContent = fileMap[`${agentDir}/config.yaml`];
|
|
134396
|
+
if (!configContent)
|
|
134476
134397
|
continue;
|
|
134477
|
-
const agentConfig =
|
|
134398
|
+
const agentConfig = readYaml(configContent, zod_default.looseObject({}));
|
|
134478
134399
|
const resolveFileContent = (filePath) => {
|
|
134479
134400
|
const normalizedPath = filePath.replace(/^\.\//, "");
|
|
134480
134401
|
const fullPath = `${agentDir}/${normalizedPath}`;
|
|
@@ -134486,9 +134407,9 @@ async function canonicalizeFromFiles(files) {
|
|
|
134486
134407
|
};
|
|
134487
134408
|
await resolveFilePlaceholders2(agentConfig, resolveFileContent);
|
|
134488
134409
|
if (agentMeta.response_engine.type === "retell-llm") {
|
|
134489
|
-
const
|
|
134490
|
-
if (
|
|
134491
|
-
const llmConfig =
|
|
134410
|
+
const llmContent = fileMap[`${agentDir}/llm.yaml`];
|
|
134411
|
+
if (llmContent) {
|
|
134412
|
+
const llmConfig = readYaml(llmContent, zod_default.looseObject({}));
|
|
134492
134413
|
await resolveFilePlaceholders2(llmConfig, resolveFileContent);
|
|
134493
134414
|
llms.push({
|
|
134494
134415
|
...llmConfig,
|
|
@@ -134497,9 +134418,9 @@ async function canonicalizeFromFiles(files) {
|
|
|
134497
134418
|
});
|
|
134498
134419
|
}
|
|
134499
134420
|
} else if (agentMeta.response_engine.type === "conversation-flow") {
|
|
134500
|
-
const
|
|
134501
|
-
if (
|
|
134502
|
-
const flowConfig =
|
|
134421
|
+
const flowContent = fileMap[`${agentDir}/conversation-flow.yaml`];
|
|
134422
|
+
if (flowContent) {
|
|
134423
|
+
const flowConfig = readYaml(flowContent, zod_default.looseObject({}));
|
|
134503
134424
|
await resolveFilePlaceholders2(flowConfig, resolveFileContent);
|
|
134504
134425
|
const positionsFile = fileMap[`${agentDir}/.positions.json`];
|
|
134505
134426
|
if (positionsFile) {
|
|
@@ -134608,22 +134529,13 @@ async function getLocalTestCases(agentDirPath) {
|
|
|
134608
134529
|
const testCases = [];
|
|
134609
134530
|
for (const testCaseMeta of metadata.test_cases) {
|
|
134610
134531
|
const testCaseName = toSnakeCase(testCaseMeta.name);
|
|
134611
|
-
|
|
134612
|
-
|
|
134613
|
-
|
|
134614
|
-
const configPath = path15.join(testsDir, `${testCaseName}.${ext}`);
|
|
134615
|
-
const file2 = Bun.file(configPath);
|
|
134616
|
-
if (await file2.exists()) {
|
|
134617
|
-
configContent = await file2.text();
|
|
134618
|
-
reader = ext === "jsonc" ? readJsonc : ext === "json" ? readJson2 : readYaml;
|
|
134619
|
-
break;
|
|
134620
|
-
}
|
|
134621
|
-
}
|
|
134622
|
-
if (!configContent) {
|
|
134532
|
+
const configPath = path15.join(testsDir, `${testCaseName}.yaml`);
|
|
134533
|
+
const configFile = Bun.file(configPath);
|
|
134534
|
+
if (!await configFile.exists()) {
|
|
134623
134535
|
console.warn(`Warning: Could not find config file for test case ${testCaseMeta.name}`);
|
|
134624
134536
|
continue;
|
|
134625
134537
|
}
|
|
134626
|
-
const config2 =
|
|
134538
|
+
const config2 = readYaml(await configFile.text(), zod_default.looseObject({}));
|
|
134627
134539
|
const resolveFileContent = async (filePath) => {
|
|
134628
134540
|
const normalizedPath = filePath.replace(/^\.\//, "");
|
|
134629
134541
|
const fullPath = path15.join(testsDir, normalizedPath);
|
|
@@ -134646,8 +134558,7 @@ async function updateTestCaseDefinition(testCaseId, update) {
|
|
|
134646
134558
|
}
|
|
134647
134559
|
async function fetchAndWriteTestCases({
|
|
134648
134560
|
state,
|
|
134649
|
-
agentsDir = DEFAULT_AGENTS_DIR
|
|
134650
|
-
configFormat = DEFAULT_CONFIG_FORMAT
|
|
134561
|
+
agentsDir = DEFAULT_AGENTS_DIR
|
|
134651
134562
|
}) {
|
|
134652
134563
|
const results = [];
|
|
134653
134564
|
const allAgents = [
|
|
@@ -134681,8 +134592,7 @@ async function fetchAndWriteTestCases({
|
|
|
134681
134592
|
}
|
|
134682
134593
|
await writeTestCases(testCases, {
|
|
134683
134594
|
agentDirPath,
|
|
134684
|
-
responseEngine: engine
|
|
134685
|
-
configFormat
|
|
134595
|
+
responseEngine: engine
|
|
134686
134596
|
});
|
|
134687
134597
|
results.push({ agentDir: agentDirName, testCount: testCases.length });
|
|
134688
134598
|
}
|
|
@@ -134690,14 +134600,10 @@ async function fetchAndWriteTestCases({
|
|
|
134690
134600
|
}
|
|
134691
134601
|
async function writeTestCases(testCases, {
|
|
134692
134602
|
agentDirPath,
|
|
134693
|
-
responseEngine
|
|
134694
|
-
configFormat = DEFAULT_CONFIG_FORMAT
|
|
134603
|
+
responseEngine
|
|
134695
134604
|
}) {
|
|
134696
134605
|
const testsDir = path15.join(agentDirPath, "tests");
|
|
134697
134606
|
await fs8.mkdir(testsDir, { recursive: true });
|
|
134698
|
-
const isYaml = configFormat === "yaml" || configFormat === "yml";
|
|
134699
|
-
const isJsonc = configFormat === "jsonc";
|
|
134700
|
-
const configExt = configFormat;
|
|
134701
134607
|
const metadata = {
|
|
134702
134608
|
response_engine: responseEngine,
|
|
134703
134609
|
test_cases: testCases.map((tc3) => ({
|
|
@@ -134725,8 +134631,10 @@ async function writeTestCases(testCases, {
|
|
|
134725
134631
|
...config2,
|
|
134726
134632
|
user_prompt: `file://./${promptFileName}`
|
|
134727
134633
|
};
|
|
134728
|
-
const configFileName = `${testCaseName}
|
|
134729
|
-
const configContent =
|
|
134634
|
+
const configFileName = `${testCaseName}.yaml`;
|
|
134635
|
+
const configContent = await writeYaml(configWithFileRef, {
|
|
134636
|
+
comments: testCaseFieldDocs
|
|
134637
|
+
});
|
|
134730
134638
|
await Bun.write(path15.join(testsDir, configFileName), configContent);
|
|
134731
134639
|
writtenFiles.add(configFileName);
|
|
134732
134640
|
}
|
|
@@ -137818,7 +137726,6 @@ async function pullCommand(agentIdArgs, opts, cmd) {
|
|
|
137818
137726
|
}
|
|
137819
137727
|
await pull({
|
|
137820
137728
|
agentsDir: globalOpts.agentsDir,
|
|
137821
|
-
configFormat: globalOpts.configFormat,
|
|
137822
137729
|
agentIds,
|
|
137823
137730
|
yes: opts.yes,
|
|
137824
137731
|
version: version2,
|
|
@@ -137834,7 +137741,6 @@ async function pullCommand(agentIdArgs, opts, cmd) {
|
|
|
137834
137741
|
}
|
|
137835
137742
|
async function pull({
|
|
137836
137743
|
agentsDir = DEFAULT_AGENTS_DIR,
|
|
137837
|
-
configFormat = DEFAULT_CONFIG_FORMAT,
|
|
137838
137744
|
agentIds = null,
|
|
137839
137745
|
yes = false,
|
|
137840
137746
|
version: version2,
|
|
@@ -137863,14 +137769,13 @@ async function pull({
|
|
|
137863
137769
|
const totalAgents = remoteState.voiceAgents.length + remoteState.chatAgents.length;
|
|
137864
137770
|
spinner.stop(source_default.dim(`${pluralize("agent", totalAgents, true)} (${remoteState.voiceAgents.length} voice, ${remoteState.chatAgents.length} chat), ${pluralize("LLM", remoteState.llms.length, true)}, ${pluralize("flow", remoteState.conversationFlows.length, true)}`));
|
|
137865
137771
|
const writeSpinner = createSpinner("Writing files...");
|
|
137866
|
-
await writeState(remoteState, { agentsDir,
|
|
137772
|
+
await writeState(remoteState, { agentsDir, agentIds });
|
|
137867
137773
|
writeSpinner.stop(source_default.green("Done"));
|
|
137868
137774
|
if (tests) {
|
|
137869
137775
|
const testSpinner = createSpinner("Fetching test cases...");
|
|
137870
137776
|
const testResults = await fetchAndWriteTestCases({
|
|
137871
137777
|
state: remoteState,
|
|
137872
|
-
agentsDir
|
|
137873
|
-
configFormat
|
|
137778
|
+
agentsDir
|
|
137874
137779
|
});
|
|
137875
137780
|
const totalTests = testResults.reduce((sum, r5) => sum + r5.testCount, 0);
|
|
137876
137781
|
const agentsWithTests = testResults.filter((r5) => r5.testCount > 0).length;
|
|
@@ -137891,7 +137796,6 @@ async function deployCommand(agentIdArgs, opts, cmd) {
|
|
|
137891
137796
|
});
|
|
137892
137797
|
const affectedIds = await deploy({
|
|
137893
137798
|
agentsDir: globalOpts.agentsDir,
|
|
137894
|
-
configFormat: globalOpts.configFormat,
|
|
137895
137799
|
agentIds,
|
|
137896
137800
|
dryRun: opts.dryRun,
|
|
137897
137801
|
verbose: opts.verbose
|
|
@@ -137909,7 +137813,6 @@ async function deployCommand(agentIdArgs, opts, cmd) {
|
|
|
137909
137813
|
}
|
|
137910
137814
|
async function deploy({
|
|
137911
137815
|
agentsDir = DEFAULT_AGENTS_DIR,
|
|
137912
|
-
configFormat = DEFAULT_CONFIG_FORMAT,
|
|
137913
137816
|
agentIds = null,
|
|
137914
137817
|
dryRun = false,
|
|
137915
137818
|
verbose = false
|
|
@@ -138056,7 +137959,7 @@ async function deploy({
|
|
|
138056
137959
|
success2(`Deployed ${pluralize("change", totalChanges, true)}`);
|
|
138057
137960
|
if (!isQuiet()) {
|
|
138058
137961
|
bold("Syncing latest state...");
|
|
138059
|
-
await pull({ agentsDir,
|
|
137962
|
+
await pull({ agentsDir, agentIds });
|
|
138060
137963
|
}
|
|
138061
137964
|
return [...affectedAgentIds];
|
|
138062
137965
|
}
|
|
@@ -138176,7 +138079,6 @@ async function publishCommand(agentIdArgs, opts, cmd) {
|
|
|
138176
138079
|
});
|
|
138177
138080
|
const publishedIds = await publish({
|
|
138178
138081
|
agentsDir: globalOpts.agentsDir,
|
|
138179
|
-
configFormat: globalOpts.configFormat,
|
|
138180
138082
|
agentIds,
|
|
138181
138083
|
dryRun: opts.dryRun
|
|
138182
138084
|
});
|
|
@@ -138193,7 +138095,6 @@ async function publishCommand(agentIdArgs, opts, cmd) {
|
|
|
138193
138095
|
}
|
|
138194
138096
|
async function publish({
|
|
138195
138097
|
agentsDir = DEFAULT_AGENTS_DIR,
|
|
138196
|
-
configFormat = DEFAULT_CONFIG_FORMAT,
|
|
138197
138098
|
agentIds = null,
|
|
138198
138099
|
dryRun = false
|
|
138199
138100
|
} = {}) {
|
|
@@ -138264,7 +138165,7 @@ Would publish ${pluralize("agent", agentIdsToPublish.size, true)}:`));
|
|
|
138264
138165
|
}
|
|
138265
138166
|
if (!isQuiet()) {
|
|
138266
138167
|
bold("Syncing latest state...");
|
|
138267
|
-
await pull({ agentsDir,
|
|
138168
|
+
await pull({ agentsDir, agentIds });
|
|
138268
138169
|
}
|
|
138269
138170
|
return publishedAgentIds;
|
|
138270
138171
|
}
|
|
@@ -138339,7 +138240,7 @@ function patchAgentList(agents, publishedIds, publishedVersions, agentNames, dir
|
|
|
138339
138240
|
|
|
138340
138241
|
// src/cli.ts
|
|
138341
138242
|
var program2 = new Command;
|
|
138342
|
-
program2.name("retell").description("Retell AI agent management CLI").option("-w, --agents-dir <dir>", "Directory for agent files", DEFAULT_AGENTS_DIR)
|
|
138243
|
+
program2.name("retell").description("Retell AI agent management CLI").option("-w, --agents-dir <dir>", "Directory for agent files", DEFAULT_AGENTS_DIR);
|
|
138343
138244
|
program2.command("pull [agentIds...]").description("Pull agents from Retell API (pulls latest draft state by default)").option("-a, --all", "Pull all agents in the account").option("-s, --select", "Force interactive agent selection").option("-y, --yes", "Skip confirmation prompts").option("-v, --version <number>", "Pull a specific version (requires agent IDs)").option("--no-tests", "Skip pulling test case definitions").action(pullCommand);
|
|
138344
138245
|
program2.command("deploy [agentIds...]").description("Deploy local changes to Retell draft").option("-a, --all", "Deploy all agents in the account").option("-s, --select", "Force interactive agent selection").option("-n, --dry-run", "Show changes without applying").option("-v, --verbose", "Show full diff details (use with --dry-run)").option("-q, --quiet", "Output only affected agent IDs (for piping)").action(deployCommand);
|
|
138345
138246
|
program2.command("publish [agentIds...]").description("Publish agents with unpublished draft changes").option("-a, --all", "Publish all agents in the account").option("-s, --select", "Force interactive agent selection").option("-n, --dry-run", "Show what would be published without publishing").option("-q, --quiet", "Output only published agent IDs (for piping)").action(publishCommand);
|