@elevenlabs/convai-cli
Version:
CLI tool to manage ElevenLabs conversational AI agents
242 lines • 8.55 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.LOCK_FILE_AGENTS_KEY = void 0;
exports.calculateConfigHash = calculateConfigHash;
exports.readAgentConfig = readAgentConfig;
exports.writeAgentConfig = writeAgentConfig;
exports.loadLockFile = loadLockFile;
exports.saveLockFile = saveLockFile;
exports.getAgentFromLock = getAgentFromLock;
exports.updateAgentInLock = updateAgentInLock;
exports.updateToolInLock = updateToolInLock;
exports.getToolFromLock = getToolFromLock;
const crypto_1 = require("crypto");
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
exports.LOCK_FILE_AGENTS_KEY = "agents";
/**
* Recursively sorts object keys to ensure consistent serialization.
*
* @param obj - The object to sort
* @returns A new object with recursively sorted keys
*/
function sortObjectKeysRecursively(obj) {
if (obj === null || typeof obj !== "object") {
return obj;
}
if (Array.isArray(obj)) {
return obj.map(sortObjectKeysRecursively);
}
const sortedObj = {};
const keys = Object.keys(obj).sort();
for (const key of keys) {
sortedObj[key] = sortObjectKeysRecursively(obj[key]);
}
return sortedObj;
}
/**
* Calculates the MD5 hash of a configuration object.
*
* @param config - The configuration object
* @returns The hexadecimal representation of the MD5 hash
*/
function calculateConfigHash(config) {
// Recursively sort all object keys to ensure consistent hashes
const sortedConfig = sortObjectKeysRecursively(config);
const configString = JSON.stringify(sortedConfig);
// Calculate MD5 hash
const hash = (0, crypto_1.createHash)("md5");
hash.update(configString, "utf-8");
return hash.digest("hex");
}
/**
* Reads an agent configuration file.
*
* @param filePath - The path to the JSON configuration file
* @returns A promise that resolves to the agent configuration object
* @throws {Error} If the configuration file is not found or contains invalid JSON
*/
async function readAgentConfig(filePath) {
try {
const data = await fs.readFile(filePath, "utf-8");
return JSON.parse(data);
}
catch (error) {
if (error.code === "ENOENT") {
throw new Error(`Configuration file not found at ${filePath}`);
}
if (error instanceof SyntaxError) {
throw new Error(`Invalid JSON in configuration file ${filePath}`);
}
throw error;
}
}
/**
* Writes an agent configuration to a file.
*
* @param filePath - The path to write the JSON configuration file
* @param config - The object containing the agent configuration
* @throws {Error} If there is an error writing the file
*/
async function writeAgentConfig(filePath, config) {
try {
// Ensure the directory exists before writing
const directory = path.dirname(filePath);
if (directory) {
await fs.ensureDir(directory);
}
await fs.writeFile(filePath, JSON.stringify(config, null, 4), "utf-8");
}
catch (error) {
throw new Error(`Could not write configuration file to ${filePath}: ${error}`);
}
}
/**
* Loads the lock file. If it doesn't exist or is invalid, returns a default structure.
*
* @param lockFilePath - Path to the lock file
* @returns Promise that resolves to the lock file data
*/
async function loadLockFile(lockFilePath) {
try {
const exists = await fs.pathExists(lockFilePath);
if (!exists) {
return { [exports.LOCK_FILE_AGENTS_KEY]: {}, tools: {} };
}
const data = await fs.readFile(lockFilePath, "utf-8");
const parsed = JSON.parse(data);
if (!parsed[exports.LOCK_FILE_AGENTS_KEY] ||
typeof parsed[exports.LOCK_FILE_AGENTS_KEY] !== "object") {
console.warn(`Warning: Lock file ${lockFilePath} is malformed or missing '${exports.LOCK_FILE_AGENTS_KEY}' key. Initializing with empty agent list.`);
parsed[exports.LOCK_FILE_AGENTS_KEY] = {};
}
if (!parsed.tools || typeof parsed.tools !== "object") {
parsed.tools = {};
}
return parsed;
}
catch (error) {
if (error instanceof SyntaxError) {
console.warn(`Warning: Could not decode JSON from lock file ${lockFilePath}. Initializing with empty lists.`);
}
else {
console.warn(`Warning: Could not read lock file ${lockFilePath}. Initializing with empty lists.`);
}
return { [exports.LOCK_FILE_AGENTS_KEY]: {}, tools: {} };
}
}
/**
* Saves the lock data to the lock file.
*
* @param lockFilePath - Path to the lock file
* @param lockData - The lock data to save
* @throws {Error} If there is an error writing the file
*/
async function saveLockFile(lockFilePath, lockData) {
try {
// Ensure the directory exists before writing
const directory = path.dirname(lockFilePath);
if (directory) {
await fs.ensureDir(directory);
}
await fs.writeFile(lockFilePath, JSON.stringify(lockData, null, 4), "utf-8");
}
catch (error) {
throw new Error(`Could not write lock file to ${lockFilePath}: ${error}`);
}
}
/**
* Retrieves agent ID and hash from lock data by agent name and tag.
*
* @param lockData - The lock file data
* @param agentName - The agent name
* @param tag - The environment tag
* @returns The agent data if found, undefined otherwise
*/
function getAgentFromLock(lockData, agentName, tag) {
return lockData[exports.LOCK_FILE_AGENTS_KEY]?.[agentName]?.[tag];
}
/**
* Updates or adds an agent's ID and hash in the lock data.
*
* @param lockData - The lock file data to update
* @param agentName - The agent name
* @param tag - The environment tag
* @param agentId - The agent ID
* @param configHash - The configuration hash
*/
function updateAgentInLock(lockData, agentName, tag, agentId, configHash) {
if (!lockData[exports.LOCK_FILE_AGENTS_KEY] ||
typeof lockData[exports.LOCK_FILE_AGENTS_KEY] !== "object") {
lockData[exports.LOCK_FILE_AGENTS_KEY] = {};
}
const agents = lockData[exports.LOCK_FILE_AGENTS_KEY];
if (!agents[agentName]) {
agents[agentName] = {};
}
agents[agentName][tag] = {
id: agentId,
hash: configHash,
};
}
/**
* Updates or adds a tool's ID and hash in the lock data.
*
* @param lockData - The lock file data to update
* @param toolName - The tool name
* @param toolId - The tool ID
* @param configHash - The configuration hash
*/
function updateToolInLock(lockData, toolName, toolId, configHash) {
if (!lockData.tools || typeof lockData.tools !== "object") {
lockData.tools = {};
}
lockData.tools[toolName] = {
id: toolId,
hash: configHash,
};
}
/**
* Retrieves tool ID and hash from lock data by tool name.
*
* @param lockData - The lock file data
* @param toolName - The tool name
* @returns The tool data if found, undefined otherwise
*/
function getToolFromLock(lockData, toolName) {
return lockData.tools?.[toolName];
}
//# sourceMappingURL=utils.js.map