retell-sync-cli 3.7.0 → 3.8.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 +159 -5
- package/package.json +1 -1
- package/.env.local +0 -1
- package/.oxlintrc.json +0 -12
- package/.prettierrc.json +0 -7
- package/.vscode/settings.json +0 -9
- package/test/raw-agents-list-response.json +0 -7264
- package/test/raw-conversation-flow-list-response.json +0 -56946
- package/test/raw-llms-list-response.json +0 -29782
- package/tsconfig.json +0 -29
package/dist/cli.js
CHANGED
|
@@ -98673,6 +98673,9 @@ function diff(obj, newObj, options = { cyclesFix: true }, _stack = []) {
|
|
|
98673
98673
|
return diffs;
|
|
98674
98674
|
}
|
|
98675
98675
|
|
|
98676
|
+
// src/commands/deploy.ts
|
|
98677
|
+
import path17 from "path";
|
|
98678
|
+
|
|
98676
98679
|
// node_modules/remeda/dist/lazyDataLastImpl-BDhrIOwR.js
|
|
98677
98680
|
function e(e2, t, n) {
|
|
98678
98681
|
let r = (n2) => e2(n2, ...t);
|
|
@@ -135192,7 +135195,7 @@ async function getTestCaseDefinitions(responseEngine) {
|
|
|
135192
135195
|
params.set("version", String(responseEngine.version));
|
|
135193
135196
|
}
|
|
135194
135197
|
}
|
|
135195
|
-
const response = await fetch(`https://api.retellai.com/list-test-case-definitions?${params}`, {
|
|
135198
|
+
const response = await fetch(`https://api.retellai.com/list-test-case-definitions?${params.toString()}`, {
|
|
135196
135199
|
headers: {
|
|
135197
135200
|
Authorization: `Bearer ${process.env.RETELL_API_KEY}`,
|
|
135198
135201
|
"Content-Type": "application/json"
|
|
@@ -135213,6 +135216,73 @@ async function getTestCaseDefinitions(responseEngine) {
|
|
|
135213
135216
|
}
|
|
135214
135217
|
return result.data;
|
|
135215
135218
|
}
|
|
135219
|
+
function canonicalizeTestCases(testCases) {
|
|
135220
|
+
return testCases.map(({ test_case_definition_id, response_engine: _10, ...rest }) => ({
|
|
135221
|
+
...rest,
|
|
135222
|
+
_id: test_case_definition_id
|
|
135223
|
+
}));
|
|
135224
|
+
}
|
|
135225
|
+
async function getLocalTestCases(agentDirPath) {
|
|
135226
|
+
const testsDir = path15.join(agentDirPath, "tests");
|
|
135227
|
+
const metaFile = Bun.file(path15.join(testsDir, ".tests.json"));
|
|
135228
|
+
if (!await metaFile.exists()) {
|
|
135229
|
+
return [];
|
|
135230
|
+
}
|
|
135231
|
+
const metaContent = await metaFile.text();
|
|
135232
|
+
const metadata = await readJson2(metaContent, zod_default.object({
|
|
135233
|
+
response_engine: zod_default.object({}).passthrough(),
|
|
135234
|
+
test_cases: zod_default.array(zod_default.object({
|
|
135235
|
+
id: zod_default.string(),
|
|
135236
|
+
name: zod_default.string()
|
|
135237
|
+
}))
|
|
135238
|
+
}));
|
|
135239
|
+
const testCases = [];
|
|
135240
|
+
for (const testCaseMeta of metadata.test_cases) {
|
|
135241
|
+
const testCaseName = toSnakeCase(testCaseMeta.name);
|
|
135242
|
+
let configContent = null;
|
|
135243
|
+
let reader = readYaml;
|
|
135244
|
+
for (const ext of ["yaml", "yml", "jsonc", "json"]) {
|
|
135245
|
+
const configPath = path15.join(testsDir, `${testCaseName}.${ext}`);
|
|
135246
|
+
const file2 = Bun.file(configPath);
|
|
135247
|
+
if (await file2.exists()) {
|
|
135248
|
+
configContent = await file2.text();
|
|
135249
|
+
reader = ext === "jsonc" ? readJsonc : ext === "json" ? readJson2 : readYaml;
|
|
135250
|
+
break;
|
|
135251
|
+
}
|
|
135252
|
+
}
|
|
135253
|
+
if (!configContent) {
|
|
135254
|
+
console.warn(`Warning: Could not find config file for test case ${testCaseMeta.name}`);
|
|
135255
|
+
continue;
|
|
135256
|
+
}
|
|
135257
|
+
const config2 = await reader(configContent, zod_default.looseObject({}));
|
|
135258
|
+
const resolveFileContent = async (filePath) => {
|
|
135259
|
+
const normalizedPath = filePath.replace(/^\.\//, "");
|
|
135260
|
+
const fullPath = path15.join(testsDir, normalizedPath);
|
|
135261
|
+
const content = await Bun.file(fullPath).text();
|
|
135262
|
+
return content;
|
|
135263
|
+
};
|
|
135264
|
+
await resolveFilePlaceholders(config2, resolveFileContent);
|
|
135265
|
+
testCases.push({
|
|
135266
|
+
...config2,
|
|
135267
|
+
_id: testCaseMeta.id
|
|
135268
|
+
});
|
|
135269
|
+
}
|
|
135270
|
+
return testCases;
|
|
135271
|
+
}
|
|
135272
|
+
async function updateTestCaseDefinition(testCaseId, update) {
|
|
135273
|
+
const response = await fetch(`https://api.retellai.com/update-test-case-definition/${testCaseId}`, {
|
|
135274
|
+
method: "PUT",
|
|
135275
|
+
headers: {
|
|
135276
|
+
Authorization: `Bearer ${process.env.RETELL_API_KEY}`,
|
|
135277
|
+
"Content-Type": "application/json"
|
|
135278
|
+
},
|
|
135279
|
+
body: JSON.stringify(update)
|
|
135280
|
+
});
|
|
135281
|
+
if (!response.ok) {
|
|
135282
|
+
const errorText = await response.text();
|
|
135283
|
+
throw new Error(`Failed to update test case ${testCaseId}: ${response.status} ${errorText}`);
|
|
135284
|
+
}
|
|
135285
|
+
}
|
|
135216
135286
|
async function fetchAndWriteTestCases({
|
|
135217
135287
|
state,
|
|
135218
135288
|
agentsDir = DEFAULT_AGENTS_DIR,
|
|
@@ -135250,7 +135320,8 @@ async function fetchAndWriteTestCases({
|
|
|
135250
135320
|
try {
|
|
135251
135321
|
testCases = await getTestCaseDefinitions(normalizedEngine);
|
|
135252
135322
|
} catch (err) {
|
|
135253
|
-
|
|
135323
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
135324
|
+
console.warn(`Warning: Could not fetch test cases for ${agentName}: ${message}`);
|
|
135254
135325
|
continue;
|
|
135255
135326
|
}
|
|
135256
135327
|
if (testCases.length === 0) {
|
|
@@ -135805,10 +135876,78 @@ async function deploy({
|
|
|
135805
135876
|
const totalRemoteAgents = remoteState.voiceAgents.length + remoteState.chatAgents.length;
|
|
135806
135877
|
spinner.stop(source_default.dim(`Local: ${totalLocalAgents} agents | Remote: ${totalRemoteAgents} agents`));
|
|
135807
135878
|
spinner = createSpinner2("Computing differences...");
|
|
135808
|
-
const
|
|
135879
|
+
const baseChanges = computeChanges(localState, remoteState);
|
|
135880
|
+
const testCaseChanges = [];
|
|
135881
|
+
const allAgents = [
|
|
135882
|
+
...localState.voiceAgents.map((a7) => ({
|
|
135883
|
+
...a7,
|
|
135884
|
+
agentType: "voice"
|
|
135885
|
+
})),
|
|
135886
|
+
...localState.chatAgents.map((a7) => ({ ...a7, agentType: "chat" }))
|
|
135887
|
+
];
|
|
135888
|
+
for (const agent of allAgents) {
|
|
135889
|
+
if (agent.response_engine.type !== "retell-llm" && agent.response_engine.type !== "conversation-flow") {
|
|
135890
|
+
continue;
|
|
135891
|
+
}
|
|
135892
|
+
const agentName = agent.agent_name ?? agent._id;
|
|
135893
|
+
const hash2 = agent._id.slice(-FILE_HASH_LENGTH);
|
|
135894
|
+
const agentDirName = `${toSnakeCase(agentName)}_${hash2}`;
|
|
135895
|
+
const agentDirPath = path17.join(agentsDir, agentDirName);
|
|
135896
|
+
const localTestCases = await getLocalTestCases(agentDirPath);
|
|
135897
|
+
if (localTestCases.length === 0)
|
|
135898
|
+
continue;
|
|
135899
|
+
const normalizedEngine = agent.response_engine.type === "retell-llm" ? {
|
|
135900
|
+
type: "retell-llm",
|
|
135901
|
+
llm_id: agent.response_engine.llm_id,
|
|
135902
|
+
version: agent.response_engine.version ?? undefined
|
|
135903
|
+
} : {
|
|
135904
|
+
type: "conversation-flow",
|
|
135905
|
+
conversation_flow_id: agent.response_engine.conversation_flow_id,
|
|
135906
|
+
version: agent.response_engine.version ?? undefined
|
|
135907
|
+
};
|
|
135908
|
+
let remoteTestCases = [];
|
|
135909
|
+
try {
|
|
135910
|
+
const rawRemote = await getTestCaseDefinitions(normalizedEngine);
|
|
135911
|
+
remoteTestCases = canonicalizeTestCases(rawRemote);
|
|
135912
|
+
} catch {
|
|
135913
|
+
continue;
|
|
135914
|
+
}
|
|
135915
|
+
const testCaseMetadataFields = [
|
|
135916
|
+
"_id",
|
|
135917
|
+
"creation_timestamp",
|
|
135918
|
+
"user_modified_timestamp",
|
|
135919
|
+
"type"
|
|
135920
|
+
];
|
|
135921
|
+
const remoteTestCaseMap = new Map(remoteTestCases.map((tc3) => [tc3._id, tc3]));
|
|
135922
|
+
for (const localTC of localTestCases) {
|
|
135923
|
+
const remoteTC = remoteTestCaseMap.get(localTC._id);
|
|
135924
|
+
if (!remoteTC)
|
|
135925
|
+
continue;
|
|
135926
|
+
const normalizePrompt = (s5) => s5.trim().replace(/\r\n/g, `
|
|
135927
|
+
`);
|
|
135928
|
+
const localComparable = {
|
|
135929
|
+
...n9(localTC, testCaseMetadataFields),
|
|
135930
|
+
user_prompt: normalizePrompt(localTC.user_prompt)
|
|
135931
|
+
};
|
|
135932
|
+
const remoteComparable = {
|
|
135933
|
+
...n9(remoteTC, testCaseMetadataFields),
|
|
135934
|
+
user_prompt: normalizePrompt(remoteTC.user_prompt)
|
|
135935
|
+
};
|
|
135936
|
+
const differences = diff(remoteComparable, localComparable);
|
|
135937
|
+
if (differences.length > 0) {
|
|
135938
|
+
testCaseChanges.push({
|
|
135939
|
+
id: localTC._id,
|
|
135940
|
+
name: localTC.name,
|
|
135941
|
+
current: localTC,
|
|
135942
|
+
differences
|
|
135943
|
+
});
|
|
135944
|
+
}
|
|
135945
|
+
}
|
|
135946
|
+
}
|
|
135947
|
+
const changes = { ...baseChanges, testCases: testCaseChanges };
|
|
135809
135948
|
const totalAgentChanges = changes.voiceAgents.length + changes.chatAgents.length;
|
|
135810
|
-
spinner.stop(source_default.dim(`Found ${source_default.white(totalAgentChanges)} agent changes, ${source_default.white(changes.llms.length)} LLM changes, ${source_default.white(changes.flows.length)} flow changes`));
|
|
135811
|
-
const totalChanges = totalAgentChanges + changes.llms.length + changes.flows.length;
|
|
135949
|
+
spinner.stop(source_default.dim(`Found ${source_default.white(totalAgentChanges)} agent changes, ${source_default.white(changes.llms.length)} LLM changes, ${source_default.white(changes.flows.length)} flow changes, ${source_default.white(changes.testCases.length)} test case changes`));
|
|
135950
|
+
const totalChanges = totalAgentChanges + changes.llms.length + changes.flows.length + changes.testCases.length;
|
|
135812
135951
|
const affectedAgentIds = new Set;
|
|
135813
135952
|
for (const change of changes.voiceAgents) {
|
|
135814
135953
|
affectedAgentIds.add(change.id);
|
|
@@ -135868,6 +136007,11 @@ async function deploy({
|
|
|
135868
136007
|
const { _id, _version, ...updateData } = change.current;
|
|
135869
136008
|
await retell.conversationFlow.update(_id, updateData);
|
|
135870
136009
|
return { type: "flow", id: _id, name: change.name };
|
|
136010
|
+
}),
|
|
136011
|
+
...changes.testCases.map(async (change) => {
|
|
136012
|
+
const { _id, ...updateData } = change.current;
|
|
136013
|
+
await updateTestCaseDefinition(_id, updateData);
|
|
136014
|
+
return { type: "test case", id: _id, name: change.name };
|
|
135871
136015
|
})
|
|
135872
136016
|
]);
|
|
135873
136017
|
spinner.stop(source_default.dim("Done"));
|
|
@@ -136059,6 +136203,16 @@ Flows to update:`));
|
|
|
136059
136203
|
}
|
|
136060
136204
|
}
|
|
136061
136205
|
}
|
|
136206
|
+
if (changes.testCases.length > 0) {
|
|
136207
|
+
console.log(source_default.cyan(`
|
|
136208
|
+
Test cases to update:`));
|
|
136209
|
+
for (const change of changes.testCases) {
|
|
136210
|
+
console.log(` ${source_default.bold(change.name)} ${source_default.dim(`(${change.id})`)}`);
|
|
136211
|
+
for (const d5 of change.differences) {
|
|
136212
|
+
printDiff(d5, { verbose });
|
|
136213
|
+
}
|
|
136214
|
+
}
|
|
136215
|
+
}
|
|
136062
136216
|
}
|
|
136063
136217
|
|
|
136064
136218
|
// src/commands/publish.ts
|
package/package.json
CHANGED
package/.env.local
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
RETELL_API_KEY="key_12a24954adfaf146f4a3cd6616a3"
|
package/.oxlintrc.json
DELETED
package/.prettierrc.json
DELETED