@nestbox-ai/cli 1.0.23 → 1.0.24

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.
Files changed (37) hide show
  1. package/dist/commands/agent/apiUtils.d.ts +10 -0
  2. package/dist/commands/agent/apiUtils.js +20 -0
  3. package/dist/commands/agent/apiUtils.js.map +1 -0
  4. package/dist/commands/agent/create.d.ts +29 -0
  5. package/dist/commands/agent/create.js +88 -0
  6. package/dist/commands/agent/create.js.map +1 -0
  7. package/dist/commands/agent/createFromYaml.d.ts +2 -0
  8. package/dist/commands/agent/createFromYaml.js +172 -0
  9. package/dist/commands/agent/createFromYaml.js.map +1 -0
  10. package/dist/commands/agent/deploy.d.ts +2 -0
  11. package/dist/commands/agent/deploy.js +243 -0
  12. package/dist/commands/agent/deploy.js.map +1 -0
  13. package/dist/commands/agent/generate.d.ts +2 -0
  14. package/dist/commands/agent/generate.js +141 -0
  15. package/dist/commands/agent/generate.js.map +1 -0
  16. package/dist/commands/agent/index.d.ts +7 -0
  17. package/dist/commands/agent/index.js +21 -0
  18. package/dist/commands/agent/index.js.map +1 -0
  19. package/dist/commands/agent/list.d.ts +2 -0
  20. package/dist/commands/agent/list.js +94 -0
  21. package/dist/commands/agent/list.js.map +1 -0
  22. package/dist/commands/agent/remove.d.ts +2 -0
  23. package/dist/commands/agent/remove.js +85 -0
  24. package/dist/commands/agent/remove.js.map +1 -0
  25. package/dist/commands/agent.d.ts +4 -0
  26. package/dist/commands/agent.js +16 -731
  27. package/dist/commands/agent.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/commands/agent/apiUtils.ts +24 -0
  30. package/src/commands/agent/create.ts +105 -0
  31. package/src/commands/agent/createFromYaml.ts +192 -0
  32. package/src/commands/agent/deploy.ts +272 -0
  33. package/src/commands/agent/generate.ts +151 -0
  34. package/src/commands/agent/index.ts +12 -0
  35. package/src/commands/agent/list.ts +104 -0
  36. package/src/commands/agent/remove.ts +103 -0
  37. package/src/commands/agent.ts +15 -909
@@ -0,0 +1,151 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import ora from "ora";
4
+ import fs from "fs";
5
+ import {
6
+ createNestboxConfig,
7
+ extractZip,
8
+ } from "../../utils/agent";
9
+ import inquirer from "inquirer";
10
+ import path from "path";
11
+
12
+ export function registerGenerateCommand(agentCommand: Command): void {
13
+ agentCommand
14
+ .command("generate <folder>")
15
+ .description("Generate a new project from templates")
16
+ .option("--lang <language>", "Project language (ts|js)")
17
+ .option("--template <type>", "Template type (agent|chatbot)")
18
+ .option("--project <projectId>", "Project ID")
19
+ .action(async (folder, options) => {
20
+ try {
21
+ const spinner = ora("Initializing project generation...").start();
22
+
23
+ // Ensure target folder doesn't exist
24
+ if (fs.existsSync(folder)) {
25
+ spinner.fail(`Folder ${folder} already exists`);
26
+ return;
27
+ }
28
+
29
+ let selectedLang = options.lang;
30
+ let selectedTemplate = options.template;
31
+
32
+ // Interactive selection if not provided
33
+ if (!selectedLang || !selectedTemplate) {
34
+ spinner.stop();
35
+
36
+ const answers = await inquirer.prompt([
37
+ {
38
+ type: 'list',
39
+ name: 'lang',
40
+ message: 'Select project language:',
41
+ choices: [
42
+ { name: 'TypeScript', value: 'ts' },
43
+ { name: 'JavaScript', value: 'js' }
44
+ ],
45
+ when: () => !selectedLang
46
+ },
47
+ {
48
+ type: 'list',
49
+ name: 'template',
50
+ message: 'Select template type:',
51
+ choices: [
52
+ { name: 'Agent', value: 'agent' },
53
+ { name: 'Chatbot', value: 'chatbot' }
54
+ ],
55
+ when: () => !selectedTemplate
56
+ }
57
+ ]);
58
+
59
+ selectedLang = selectedLang || answers.lang;
60
+ selectedTemplate = selectedTemplate || answers.template;
61
+
62
+ spinner.start("Generating project...");
63
+ }
64
+
65
+ // Find matching template in local templates folder
66
+ const templateMapping: Record<string, string> = {
67
+ 'agent': 'base',
68
+ 'chatbot': 'chatbot'
69
+ };
70
+ const mappedTemplateType = templateMapping[selectedTemplate] || selectedTemplate;
71
+ const templateKey = `template-${mappedTemplateType}-${selectedLang}.zip`;
72
+
73
+ // Try process.cwd() first, then __dirname fallback
74
+ let templatePath = path.resolve(process.cwd(), 'templates', templateKey);
75
+ if (!fs.existsSync(templatePath)) {
76
+ // fallback to __dirname
77
+ templatePath = path.resolve(__dirname, '../../../templates', templateKey);
78
+ }
79
+
80
+ if (!fs.existsSync(templatePath)) {
81
+ spinner.fail(`Template not found: ${templatePath}`);
82
+ // Show available templates in both locations
83
+ const cwdTemplates = path.resolve(process.cwd(), 'templates');
84
+ const dirTemplates = path.resolve(__dirname, '../../../templates');
85
+ let shown = false;
86
+
87
+ if (fs.existsSync(cwdTemplates)) {
88
+ console.log(chalk.yellow('Available templates in ./templates:'));
89
+ fs.readdirSync(cwdTemplates).forEach(file => {
90
+ console.log(chalk.yellow(` - ${file}`));
91
+ });
92
+ shown = true;
93
+ }
94
+
95
+ if (fs.existsSync(dirTemplates)) {
96
+ console.log(chalk.yellow('Available templates in templates:'));
97
+ fs.readdirSync(dirTemplates).forEach(file => {
98
+ console.log(chalk.yellow(` - ${file}`));
99
+ });
100
+ shown = true;
101
+ }
102
+
103
+ if (!shown) {
104
+ console.log(chalk.red('No templates directory found. Please add your templates.'));
105
+ }
106
+ return;
107
+ }
108
+
109
+ spinner.text = `Extracting template to ${folder}...`;
110
+
111
+ try {
112
+ // Extract template to target folder
113
+ extractZip(templatePath, folder);
114
+
115
+ // Create nestbox.config.json for TypeScript projects
116
+ createNestboxConfig(folder, selectedLang === 'ts');
117
+
118
+ // Update package.json with project name if it exists
119
+ const packageJsonPath = path.join(folder, 'package.json');
120
+ if (fs.existsSync(packageJsonPath)) {
121
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
122
+ packageJson.name = path.basename(folder);
123
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
124
+ }
125
+
126
+ spinner.succeed(`Successfully generated ${mappedTemplateType} project in ${folder}`);
127
+
128
+ console.log(chalk.green("\nNext steps:"));
129
+ console.log(chalk.yellow(` cd ${folder}`));
130
+ console.log(chalk.yellow(" npm install"));
131
+ if (selectedLang === 'ts') {
132
+ console.log(chalk.yellow(" npm run build"));
133
+ }
134
+ console.log(chalk.yellow(" nestbox agent deploy --agent <agent-name> --instance <instance-name>"));
135
+
136
+ } catch (error) {
137
+ // Clean up on error
138
+ if (fs.existsSync(folder)) {
139
+ fs.rmSync(folder, { recursive: true, force: true });
140
+ }
141
+ throw error;
142
+ }
143
+
144
+ } catch (error: any) {
145
+ console.error(
146
+ chalk.red("Error:"),
147
+ error.message || "Failed to generate project"
148
+ );
149
+ }
150
+ });
151
+ }
@@ -0,0 +1,12 @@
1
+ // Main agent command exports
2
+ export { createAgent, type CreateAgentOptions } from "./create";
3
+
4
+ // Individual command exports for direct usage if needed
5
+ export { registerListCommand } from "./list";
6
+ export { registerRemoveCommand } from "./remove";
7
+ export { registerDeployCommand } from "./deploy";
8
+ export { registerGenerateCommand } from "./generate";
9
+ export { registerCreateFromYamlCommand } from "./createFromYaml";
10
+
11
+ // API utilities
12
+ export { createApis, type ApiInstances } from "./apiUtils";
@@ -0,0 +1,104 @@
1
+ import { Command } from "commander";
2
+ import { withTokenRefresh } from "../../utils/error";
3
+ import chalk from "chalk";
4
+ import ora from "ora";
5
+ import Table from "cli-table3";
6
+ import { resolveProject } from "../../utils/project";
7
+ import { AgentType } from "../../types/agentType";
8
+ import { createApis } from "./apiUtils";
9
+
10
+ export function registerListCommand(agentCommand: Command): void {
11
+ agentCommand
12
+ .command("list")
13
+ .description("List all AI agents associated with the authenticated user")
14
+ .option(
15
+ "--project <projectName>",
16
+ "Project name (defaults to the current project)"
17
+ )
18
+ .action(async (options) => {
19
+ try {
20
+ let apis = createApis();
21
+
22
+ // Execute with token refresh support
23
+ await withTokenRefresh(
24
+ async () => {
25
+ // Resolve project
26
+ const projectData = await resolveProject(apis.projectsApi, options);
27
+
28
+ const spinner = ora(
29
+ `Listing agents in project ${projectData.name}...`
30
+ ).start();
31
+
32
+ try {
33
+ // Get the agents for the specific project
34
+ const agentsResponse: any =
35
+ await apis.agentsApi.machineAgentControllerGetMachineAgentByProjectId(
36
+ projectData.id,
37
+ 0,
38
+ 10,
39
+ AgentType.REGULAR
40
+ );
41
+
42
+ spinner.succeed("Successfully retrieved agents");
43
+
44
+ // Display the results
45
+ const agents = agentsResponse.data?.machineAgents || [];
46
+
47
+ if (!agents || agents.length === 0) {
48
+ console.log(
49
+ chalk.yellow(`No agents found in project ${projectData.name}`)
50
+ );
51
+ return;
52
+ }
53
+
54
+ console.log(
55
+ chalk.blue(`\nAgents in project ${projectData.name}:\n`)
56
+ );
57
+
58
+ // Create a formatted table
59
+ const table = new Table({
60
+ head: [
61
+ chalk.white.bold("ID"),
62
+ chalk.white.bold("Name"),
63
+ chalk.white.bold("URL"),
64
+ ],
65
+ style: {
66
+ head: [],
67
+ border: [],
68
+ },
69
+ });
70
+
71
+ // Add agents to the table
72
+ agents.forEach((agent: any) => {
73
+ let url = "N/A";
74
+ if (agent.instanceIP) {
75
+ url = `${agent.instanceIP}/v1/agents/${agent.modelBaseId}/query`;
76
+ }
77
+
78
+ table.push([agent.id || "N/A", agent.agentName || "N/A", url]);
79
+ });
80
+
81
+ console.log(table.toString());
82
+ console.log(`\nTotal agents: ${agents.length}`);
83
+
84
+ } catch (error: any) {
85
+ spinner.fail("Failed to retrieve agents");
86
+ throw error;
87
+ }
88
+ },
89
+ () => {
90
+ // Recreate APIs after token refresh
91
+ apis = createApis();
92
+ }
93
+ );
94
+ } catch (error: any) {
95
+ if (error.message && error.message.includes('Authentication')) {
96
+ console.error(chalk.red(error.message));
97
+ } else if (error.response?.data?.message) {
98
+ console.error(chalk.red("API Error:"), error.response.data.message);
99
+ } else {
100
+ console.error(chalk.red("Error:"), error.message || "Unknown error");
101
+ }
102
+ }
103
+ });
104
+ }
@@ -0,0 +1,103 @@
1
+ import { Command } from "commander";
2
+ import { withTokenRefresh } from "../../utils/error";
3
+ import chalk from "chalk";
4
+ import ora from "ora";
5
+ import { resolveProject } from "../../utils/project";
6
+ import { AgentType } from "../../types/agentType";
7
+ import { createApis } from "./apiUtils";
8
+
9
+ export function registerRemoveCommand(agentCommand: Command): void {
10
+ agentCommand
11
+ .command("remove")
12
+ .description("Remove an AI agent")
13
+ .requiredOption("--agent <agentId>", "Agent ID to remove")
14
+ .option(
15
+ "--project <projectName>",
16
+ "Project name (defaults to the current project)"
17
+ )
18
+ .action(async (options) => {
19
+ try {
20
+ let apis = createApis();
21
+ const { agent } = options;
22
+
23
+ await withTokenRefresh(
24
+ async () => {
25
+ // Resolve project
26
+ const projectData = await resolveProject(apis.projectsApi, options);
27
+
28
+ const spinner = ora(
29
+ `Finding agent ${agent} in project ${projectData.name}...`
30
+ ).start();
31
+
32
+ try {
33
+ // Get the list of agents to find the correct modelbaseId
34
+ const agentsResponse: any =
35
+ await apis.agentsApi.machineAgentControllerGetMachineAgentByProjectId(
36
+ projectData.id,
37
+ 0,
38
+ 100,
39
+ AgentType.REGULAR
40
+ );
41
+
42
+ const agents = agentsResponse.data?.machineAgents || [];
43
+ const targetAgent = agents.find(
44
+ (a: any) => a.id.toString() === agent.toString()
45
+ );
46
+
47
+ if (!targetAgent) {
48
+ spinner.fail(
49
+ `Agent with ID ${agent} not found in project ${projectData.name}`
50
+ );
51
+ return;
52
+ }
53
+
54
+ const modelbaseId = targetAgent.modelBaseId;
55
+ if (!modelbaseId) {
56
+ spinner.fail(
57
+ `Could not find modelbaseId for agent ${agent}. Please try again.`
58
+ );
59
+ return;
60
+ }
61
+
62
+ spinner.text = `Removing agent ${agent} from project ${projectData.name}...`;
63
+
64
+ // Remove the agent
65
+ const payload: any = [
66
+ {
67
+ id: parseInt(agent, 10),
68
+ modelbaseId: modelbaseId,
69
+ },
70
+ ];
71
+
72
+ await apis.agentsApi.machineAgentControllerDeleteMachineAgents(
73
+ projectData.id,
74
+ agent,
75
+ payload
76
+ );
77
+
78
+ spinner.succeed("Successfully removed agent");
79
+ console.log(
80
+ chalk.green(
81
+ `Agent ${agent} removed successfully from project ${projectData.name}`
82
+ )
83
+ );
84
+ } catch (error: any) {
85
+ spinner.fail("Failed to remove agent");
86
+ throw error;
87
+ }
88
+ },
89
+ () => {
90
+ apis = createApis();
91
+ }
92
+ );
93
+ } catch (error: any) {
94
+ if (error.message && error.message.includes('Authentication')) {
95
+ console.error(chalk.red(error.message));
96
+ } else if (error.response?.data?.message) {
97
+ console.error(chalk.red("API Error:"), error.response.data.message);
98
+ } else {
99
+ console.error(chalk.red("Error:"), error.message || "Unknown error");
100
+ }
101
+ }
102
+ });
103
+ }