UNPKG

@nestbox-ai/cli

Version:

The cli tools that helps developers to build agents

243 lines 16 kB
"use strict"; 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; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerDeployCommand = registerDeployCommand; const error_1 = require("../../utils/error"); const chalk_1 = __importDefault(require("chalk")); const ora_1 = __importDefault(require("ora")); const project_1 = require("../../utils/project"); const fs_1 = __importDefault(require("fs")); const agent_1 = require("../../utils/agent"); const axios_1 = __importDefault(require("axios")); const agentType_1 = require("../../types/agentType"); const path_1 = __importDefault(require("path")); const auth_1 = require("../../utils/auth"); const apiUtils_1 = require("./apiUtils"); function registerDeployCommand(agentCommand) { agentCommand .command("deploy") .description("Deploy an AI agent to the Nestbox platform") .option("--agent <agentName>", "Agent name to deploy") .option("--chatbot <chatbotName>", "Chatbot name to deploy") .requiredOption("--instance <instanceName>", "Instance name") .option("--zip <zipFileOrDirPath>", "Path to the zip file or directory to upload") .option("--project <projectName>", "Project name (defaults to the current project)") .option("--entry <entryFunction>", "Entry function name") .option("--log", "Show detailed logs during deployment") .action((options) => __awaiter(this, void 0, void 0, function* () { var _a; try { const { agent: agentName, chatbot: chatbotName, instance: instanceName, zip: customZipPath, entry, log, } = options; // Ensure either agent or chatbot is provided, but not both if ((!agentName && !chatbotName) || (agentName && chatbotName)) { console.error(chalk_1.default.red("Please provide either --agent OR --chatbot option, but not both.")); return; } let apis = (0, apiUtils_1.createApis)(); // Find project root const projectRoot = yield (0, agent_1.findProjectRoot)(); console.log(chalk_1.default.blue(`Project root detected at: ${projectRoot}`)); // Main deployment logic with token refresh yield (0, error_1.withTokenRefresh)(() => __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f, _g, _h, _j; // Resolve project const projectData = yield (0, project_1.resolveProject)(apis.projectsApi, options); // Determine if we're deploying an agent or chatbot const isAgent = !!agentName; const resourceName = isAgent ? agentName : chatbotName; const resourceType = isAgent ? "Agent" : "Chatbot"; const agentType = isAgent ? agentType_1.AgentType.REGULAR : "CHAT"; // Get agents data and find agent/chatbot by name const agentsData = yield apis.agentsApi.machineAgentControllerGetMachineAgentByProjectId(projectData.id, 0, 10, agentType); const targetAgent = agentsData.data.machineAgents.find((agent) => agent.agentName === resourceName); if (!targetAgent) { console.error(chalk_1.default.red(`${resourceType} with name "${resourceName}" not found in project "${projectData.name}".`)); console.log(chalk_1.default.yellow(`Available ${resourceType.toLowerCase()}s:`)); agentsData.data.machineAgents.forEach((agent) => { console.log(chalk_1.default.yellow(` - ${agent.agentName} (ID: ${agent.id})`)); }); return; } // Get instance data and find instance by name const instanceData = yield apis.instanceApi.machineInstancesControllerGetMachineInstanceByUserId(projectData.id, 0, 10); const targetInstance = instanceData.data.machineInstances.find((instance) => instance.instanceName === instanceName); if (!targetInstance) { console.error(chalk_1.default.red(`Instance with name "${instanceName}" not found in project "${projectData.name}".`)); console.log(chalk_1.default.yellow("Available instances:")); instanceData.data.machineInstances.forEach((instance) => { console.log(chalk_1.default.yellow(` - ${instance.instanceName} (ID: ${instance.id})`)); }); return; } // Extract IDs const agentId = targetAgent.id; const resolvedEntry = entry || targetAgent.entryFunctionName || "main"; const instanceId = targetInstance.id; // Load nestbox.config.json const config = (0, agent_1.loadNestboxConfig)(projectRoot); // Start the deployment process const spinner = (0, ora_1.default)(`Preparing to deploy ${resourceType.toLowerCase()} ${agentId} to instance ${instanceId}...`).start(); try { let zipFilePath; if (customZipPath) { // Process custom zip path if (!fs_1.default.existsSync(customZipPath)) { spinner.fail(`Path not found: ${customZipPath}`); return; } const stats = fs_1.default.statSync(customZipPath); if (stats.isFile()) { if (!customZipPath.toLowerCase().endsWith(".zip")) { spinner.fail(`File is not a zip archive: ${customZipPath}`); return; } spinner.text = `Using provided zip file: ${customZipPath}`; zipFilePath = customZipPath; } else if (stats.isDirectory()) { // Process directory spinner.text = `Processing directory: ${customZipPath}`; const isTypeScript = (0, agent_1.isTypeScriptProject)(customZipPath); if (isTypeScript && (((_a = config === null || config === void 0 ? void 0 : config.agent) === null || _a === void 0 ? void 0 : _a.predeploy) || ((_b = config === null || config === void 0 ? void 0 : config.agents) === null || _b === void 0 ? void 0 : _b.predeploy))) { const predeployScripts = ((_c = config === null || config === void 0 ? void 0 : config.agent) === null || _c === void 0 ? void 0 : _c.predeploy) || ((_d = config === null || config === void 0 ? void 0 : config.agents) === null || _d === void 0 ? void 0 : _d.predeploy); spinner.text = `Running predeploy scripts on target directory...`; yield (0, agent_1.runPredeployScripts)(predeployScripts, customZipPath); } spinner.text = `Creating zip archive from directory ${customZipPath}...`; zipFilePath = (0, agent_1.createZipFromDirectory)(customZipPath); spinner.text = `Directory zipped successfully to ${zipFilePath}`; } } else { // Use project root spinner.text = `Using project root: ${projectRoot}`; const isTypeScript = (0, agent_1.isTypeScriptProject)(projectRoot); if (isTypeScript && (((_e = config === null || config === void 0 ? void 0 : config.agent) === null || _e === void 0 ? void 0 : _e.predeploy) || ((_f = config === null || config === void 0 ? void 0 : config.agents) === null || _f === void 0 ? void 0 : _f.predeploy))) { const predeployScripts = ((_g = config === null || config === void 0 ? void 0 : config.agent) === null || _g === void 0 ? void 0 : _g.predeploy) || ((_h = config === null || config === void 0 ? void 0 : config.agents) === null || _h === void 0 ? void 0 : _h.predeploy); spinner.text = `Running predeploy scripts on project root...`; yield (0, agent_1.runPredeployScripts)(predeployScripts, projectRoot); } spinner.text = `Creating zip archive from project root ${projectRoot}...`; zipFilePath = (0, agent_1.createZipFromDirectory)(projectRoot); spinner.text = `Directory zipped successfully to ${zipFilePath}`; } spinner.text = `Deploying ${resourceType.toLowerCase()} ${agentId} to instance ${instanceId}...`; // Prepare deployment const authToken = (0, auth_1.getAuthToken)(); const baseUrl = ((_j = authToken === null || authToken === void 0 ? void 0 : authToken.serverUrl) === null || _j === void 0 ? void 0 : _j.endsWith("/")) ? authToken.serverUrl.slice(0, -1) : authToken === null || authToken === void 0 ? void 0 : authToken.serverUrl; const { default: FormData } = yield Promise.resolve().then(() => __importStar(require("form-data"))); const form = new FormData(); form.append("file", fs_1.default.createReadStream(zipFilePath)); form.append("machineAgentId", agentId.toString()); form.append("instanceId", instanceId.toString()); form.append("entryFunctionName", resolvedEntry); form.append("isSourceCodeUpdate", "true"); form.append("projectId", projectData.id); if (log) { console.log(chalk_1.default.blue("Form Details ")); console.log(chalk_1.default.blue(` - File: ${path_1.default.basename(zipFilePath)}`)); console.log(chalk_1.default.blue(` - Agent ID: ${agentId}`)); console.log(chalk_1.default.blue(` - Instance ID: ${instanceId}`)); console.log(chalk_1.default.blue(` - Entry Function: ${resolvedEntry}`)); console.log(chalk_1.default.blue(` - Project ID: ${projectData.id}`)); } const axiosInstance = axios_1.default.create({ baseURL: baseUrl, headers: Object.assign(Object.assign({}, form.getHeaders()), { Authorization: authToken === null || authToken === void 0 ? void 0 : authToken.token }), }); const endpoint = `/projects/${projectData.id}/agents/${agentId}`; spinner.text = `Deploy ${resourceType.toLowerCase()} ${agentName}...`; const res = yield axiosInstance.patch(endpoint, form); if (!customZipPath && zipFilePath && fs_1.default.existsSync(zipFilePath)) { fs_1.default.unlinkSync(zipFilePath); } if (log) { console.log(chalk_1.default.blue("\nDeployment request:")); console.log(chalk_1.default.blue(` URL: ${baseUrl}${endpoint}`)); console.log(chalk_1.default.blue(` Method: PATCH`)); console.log(chalk_1.default.blue(` File: ${path_1.default.basename(zipFilePath)}`)); console.log(chalk_1.default.blue(` Response status: ${res.status} ${res.statusText}`)); const lines = res.data.logEntries || []; console.log(chalk_1.default.blue(` Deployment log entries (${lines.length} lines):`)); lines.forEach((line) => { console.log(chalk_1.default.blue(` - [${line.type} ${line.timestamp}] ${line.message} `)); }); } spinner.succeed("Successfully deployed"); console.log(chalk_1.default.green(`${resourceType} deployed successfully!`)); console.log(chalk_1.default.cyan(`📍 Instance: ${instanceName}`)); console.log(chalk_1.default.cyan(`🤖 Agent: ${agentName} (${agentId})`)); console.log(chalk_1.default.cyan(`⚙️ Entry: ${resolvedEntry}`)); console.log(chalk_1.default.cyan(`🔄 Process: ${res.data.processName}`)); } catch (error) { spinner.fail(`Failed to deploy ${resourceType.toLowerCase()}`); throw error; } }), () => { apis = (0, apiUtils_1.createApis)(); }); } catch (error) { if (error.message && error.message.includes('Authentication')) { console.error(chalk_1.default.red(error.message)); } else if (error.response) { console.error(chalk_1.default.red(`API Error (${error.response.status}): ${((_a = error.response.data) === null || _a === void 0 ? void 0 : _a.message) || "Unknown error"}`)); if (error.response.data) { console.error(chalk_1.default.red(`Error Data: ${JSON.stringify(error.response.data, null, 2)}`)); } } else { console.error(chalk_1.default.red("Error:"), error.message || "Unknown error"); } } })); } //# sourceMappingURL=deploy.js.map