@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.
- package/dist/commands/agent/apiUtils.d.ts +10 -0
- package/dist/commands/agent/apiUtils.js +20 -0
- package/dist/commands/agent/apiUtils.js.map +1 -0
- package/dist/commands/agent/create.d.ts +29 -0
- package/dist/commands/agent/create.js +88 -0
- package/dist/commands/agent/create.js.map +1 -0
- package/dist/commands/agent/createFromYaml.d.ts +2 -0
- package/dist/commands/agent/createFromYaml.js +172 -0
- package/dist/commands/agent/createFromYaml.js.map +1 -0
- package/dist/commands/agent/deploy.d.ts +2 -0
- package/dist/commands/agent/deploy.js +243 -0
- package/dist/commands/agent/deploy.js.map +1 -0
- package/dist/commands/agent/generate.d.ts +2 -0
- package/dist/commands/agent/generate.js +141 -0
- package/dist/commands/agent/generate.js.map +1 -0
- package/dist/commands/agent/index.d.ts +7 -0
- package/dist/commands/agent/index.js +21 -0
- package/dist/commands/agent/index.js.map +1 -0
- package/dist/commands/agent/list.d.ts +2 -0
- package/dist/commands/agent/list.js +94 -0
- package/dist/commands/agent/list.js.map +1 -0
- package/dist/commands/agent/remove.d.ts +2 -0
- package/dist/commands/agent/remove.js +85 -0
- package/dist/commands/agent/remove.js.map +1 -0
- package/dist/commands/agent.d.ts +4 -0
- package/dist/commands/agent.js +16 -731
- package/dist/commands/agent.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/agent/apiUtils.ts +24 -0
- package/src/commands/agent/create.ts +105 -0
- package/src/commands/agent/createFromYaml.ts +192 -0
- package/src/commands/agent/deploy.ts +272 -0
- package/src/commands/agent/generate.ts +151 -0
- package/src/commands/agent/index.ts +12 -0
- package/src/commands/agent/list.ts +104 -0
- package/src/commands/agent/remove.ts +103 -0
- 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
|
+
}
|