@nestbox-ai/cli 1.0.37 → 1.0.39

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 (36) hide show
  1. package/.github/workflows/test.yml +54 -0
  2. package/README.md +2 -1
  3. package/dist/commands/agent/apiUtils.d.ts +20 -0
  4. package/dist/commands/agent/apiUtils.js +75 -2
  5. package/dist/commands/agent/apiUtils.js.map +1 -1
  6. package/dist/commands/agent/create.d.ts +2 -29
  7. package/dist/commands/agent/create.js +123 -61
  8. package/dist/commands/agent/create.js.map +1 -1
  9. package/dist/commands/agent/deploy.js +183 -137
  10. package/dist/commands/agent/deploy.js.map +1 -1
  11. package/dist/commands/agent/index.d.ts +1 -2
  12. package/dist/commands/agent/index.js +3 -6
  13. package/dist/commands/agent/index.js.map +1 -1
  14. package/dist/commands/agent/yaml-schema.d.ts +72 -0
  15. package/dist/commands/agent/yaml-schema.js +61 -0
  16. package/dist/commands/agent/yaml-schema.js.map +1 -0
  17. package/dist/commands/agent.js +2 -2
  18. package/dist/commands/agent.js.map +1 -1
  19. package/dist/commands/generate/project.js +32 -28
  20. package/dist/commands/generate/project.js.map +1 -1
  21. package/dist/utils/agent.js +18 -20
  22. package/dist/utils/agent.js.map +1 -1
  23. package/package.json +3 -2
  24. package/src/commands/agent/apiUtils.ts +103 -14
  25. package/src/commands/agent/create.ts +266 -100
  26. package/src/commands/agent/deploy.ts +515 -264
  27. package/src/commands/agent/index.ts +1 -4
  28. package/src/commands/agent/yaml-schema.ts +57 -0
  29. package/src/commands/agent.ts +10 -10
  30. package/src/commands/generate/project.ts +179 -147
  31. package/src/utils/agent.ts +141 -125
  32. package/test/agent.test.ts +153 -124
  33. package/dist/commands/agent/createFromYaml.d.ts +0 -2
  34. package/dist/commands/agent/createFromYaml.js +0 -172
  35. package/dist/commands/agent/createFromYaml.js.map +0 -1
  36. package/src/commands/agent/createFromYaml.ts +0 -192
@@ -1,105 +1,271 @@
1
- import { Configuration, MachineAgentApi, ProjectsApi } from "@nestbox-ai/admin";
2
- import { getAuthToken } from "../../utils/auth";
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
3
  import { resolveProject } from "../../utils/project";
4
+ import { loadNestboxConfig } from "../../utils/agent";
5
+ import {
6
+ createApis,
7
+ loadAgentFromYaml,
8
+ loadAllAgentNamesFromYaml,
9
+ } from "./apiUtils";
4
10
 
5
- export interface CreateAgentOptions {
6
- lang?: string;
7
- template?: string;
8
- project?: string;
9
- instanceName?: string;
10
- machineManifestId?: string;
11
- type?: string;
12
- goal?: string;
13
- modelBaseId?: string;
14
- machineName?: string;
15
- machineInstanceId?: number;
16
- instanceIP?: string;
17
- userId?: number;
18
- parameters?: Array<{name: string; description: string; default: any}>;
11
+ type CreateAgentOptions = {
12
+ agent: string; // agent name
13
+ description: string;
14
+ inputSchema: any;
15
+ instance: string;
16
+ project?: string;
17
+ type?: string;
18
+ prefix?: string;
19
+ all?: boolean;
20
+ };
21
+
22
+ type AgentCreateData = {
23
+ type: string;
24
+ agentName: string;
25
+ goal: string;
26
+ inputSchema: object;
27
+ machineManifestId: string;
28
+ projectId: string;
29
+ machineName: string;
30
+ machineInstanceId: number;
31
+ instanceIP: string;
32
+ userId: number;
33
+ entryFunctionName: string;
34
+ modelBaseId: string;
35
+ };
36
+
37
+ type MachineInstanceData = {
38
+ machineId?: string;
39
+ id?: number;
40
+ internalIP?: string;
41
+ };
42
+
43
+ async function buildAgentData(
44
+ options: CreateAgentOptions,
45
+ machineInstanceData: MachineInstanceData = {}
46
+ ): Promise<AgentCreateData> {
47
+ const createAgentData = {
48
+ agentName: "",
49
+ goal: "",
50
+ inputSchema: {},
51
+
52
+ machineManifestId: machineInstanceData.machineId,
53
+ machineName: options.instance,
54
+ machineInstanceId: machineInstanceData.id,
55
+ instanceIP: machineInstanceData.internalIP,
56
+
57
+ projectId: options.project,
58
+ type: options?.type || "REGULAR",
59
+ userId: 0,
60
+ modelBaseId: "",
61
+ entryFunctionName: "",
62
+ };
63
+
64
+ // check agent name and add prefix
65
+ if (!options.agent) {
66
+ throw new Error("Missing required argument <agent>.");
67
+ }
68
+ createAgentData.agentName = options.prefix
69
+ ? options.prefix + "-" + options.agent
70
+ : options.agent;
71
+
72
+ // agent creation using arguments
73
+ if (options.description || options.inputSchema) {
74
+ if (!options.description) {
75
+ throw new Error("Missing required argument <description>.");
76
+ }
77
+ if (!options.inputSchema) {
78
+ throw new Error("Missing required argument <inputSchema>.");
79
+ }
80
+ createAgentData.goal = options.description;
81
+ createAgentData.inputSchema = JSON.parse(options.inputSchema);
82
+ } else {
83
+ const manifestAgent = await loadAgentFromYaml(options.agent);
84
+
85
+ if (!manifestAgent) {
86
+ throw new Error(
87
+ "Could not find a yaml file definition of an agent or agent not defined in yaml file."
88
+ );
89
+ }
90
+
91
+ createAgentData.goal = manifestAgent.description;
92
+ createAgentData.inputSchema = manifestAgent.inputSchema || {};
93
+ createAgentData.type = options.type || manifestAgent?.type || "REGULAR";
94
+ }
95
+
96
+ return createAgentData as AgentCreateData;
19
97
  }
20
98
 
21
- /**
22
- * Create a new agent in the Nestbox platform
23
- *
24
- * @param agentName The name of the agent
25
- * @param options Options including lang, template, and project
26
- * @param agentsApi The MachineAgentApi instance
27
- * @param projectsApi The ProjectsApi instance
28
- */
29
- export async function createAgent(
30
- agentName: string,
31
- options: CreateAgentOptions,
32
- agentsApi?: MachineAgentApi,
33
- projectsApi?: ProjectsApi
34
- ): Promise<any> {
35
- const authToken = getAuthToken();
36
- if (!authToken) {
37
- throw new Error("No authentication token found. Please login first.");
38
- }
39
-
40
- // Create API instances if not provided
41
- if (!agentsApi || !projectsApi) {
42
- const configuration = new Configuration({
43
- basePath: authToken?.serverUrl,
44
- baseOptions: {
45
- headers: {
46
- Authorization: authToken?.token,
47
- },
48
- },
49
- });
50
-
51
- agentsApi = agentsApi || new MachineAgentApi(configuration);
52
- projectsApi = projectsApi || new ProjectsApi(configuration);
53
- }
54
-
55
- // Resolve project - convert options to match CommandOptions interface
56
- const projectData = await resolveProject(projectsApi, {
57
- project: options.project,
58
- instance: options.instanceName || '',
59
- ...options
60
- });
61
-
62
- // Prepare agent creation payload
63
- // Determine the correct type value based on options.type
64
- const agentTypeValue = options.type?.includes("AGENT") ? "REGULAR" : options.type || "CHAT";
65
-
66
- const payload: any = {
67
- agentName,
68
- goal: options.goal || `AI agent for ${agentName}`,
69
- modelBaseId: options.modelBaseId || "",
70
- machineName: options.machineName,
71
- machineInstanceId: options.machineInstanceId,
72
- instanceIP: options.instanceIP,
73
- machineManifestId: options.machineManifestId,
74
- parameters: options.parameters?.map((param: any) => ({
75
- name: param.name,
76
- description: param.description,
77
- default_value: param.default || "",
78
- isUserParam: param.isUserParam !== undefined ? param.isUserParam : true
79
- })) || [],
80
- projectId: projectData.id,
81
- type: agentTypeValue,
82
- userId: options.userId || 0,
83
- };
84
-
85
- // Determine the type of resource (Agent or Chat)
86
- const agentType = options.type || "CHAT";
87
- const resourceType = agentType === "AGENT" || agentType === "REGULAR" ? "Agent" : "Chatbot";
88
-
89
- // Create the agent
90
- try {
91
- const response = await agentsApi.machineAgentControllerCreateMachineAgent(
92
- projectData.id,
93
- payload
94
- );
95
- return response.data;
96
- } catch (error: any) {
97
- if (error.response && error.response.status === 401) {
98
- throw new Error('Authentication token has expired. Please login again using "nestbox login <domain>".');
99
- } else if (error.response) {
100
- throw new Error(`API Error (${error.response.status}): ${error.response.data?.message || "Unknown error"}`);
101
- } else {
102
- throw new Error(error.message || "Unknown error");
103
- }
104
- }
99
+ export function registerCreateCommand(agentCommand: Command) {
100
+ agentCommand
101
+ .command("create")
102
+ .description("Create an agent with direct arguments or YAML.")
103
+ .option("--agent <agent>", "Agent name to deploy")
104
+ .option("--all", "Deploy all agents defined in nestbox-agents.yaml")
105
+ .option(
106
+ "--project <project>",
107
+ "Project ID (defaults to current project)"
108
+ )
109
+ .option("--type <type>", "Agent type (e.g. CHAT, AGENT, REGULAR)")
110
+ .option(
111
+ "--prefix <prefix>",
112
+ "A prefix added to beginning of the agent name."
113
+ )
114
+ .option("--description <description>", "Description of the agent")
115
+ .option("--instance <instance>", "Machine name")
116
+ .option("--inputSchema <inputSchema>", "Agent input schema")
117
+ .action(async (options): Promise<any> => {
118
+ try {
119
+ const apis = createApis();
120
+
121
+ // resolve project
122
+ const projectData = await resolveProject(apis.projectsApi, {
123
+ project: options?.project || "",
124
+ instance: options?.instance || "",
125
+ ...options,
126
+ });
127
+
128
+ const projectRoot = process.cwd();
129
+ const nestboxConfig = loadNestboxConfig(projectRoot);
130
+
131
+ if (!options?.instance && !nestboxConfig?.instance) {
132
+ console.log(
133
+ chalk.red("Parameter <instance> not provided.")
134
+ );
135
+ return;
136
+ }
137
+
138
+ const machineName =
139
+ options?.instance || nestboxConfig?.instance;
140
+
141
+ const instanceData: any =
142
+ await apis.instanceApi.machineInstancesControllerGetMachineInstanceByUserId(
143
+ projectData.id,
144
+ 0,
145
+ 10
146
+ );
147
+
148
+ const targetInstance = instanceData.data.machineInstances.find(
149
+ (instance: any) => instance.instanceName === machineName
150
+ );
151
+
152
+ if (!targetInstance) {
153
+ console.error(
154
+ chalk.red(
155
+ `Instance with name "${machineName}" not found in project "${projectData.name}".`
156
+ )
157
+ );
158
+ console.log(chalk.yellow("Available instances:"));
159
+ instanceData.data.machineInstances.forEach(
160
+ (instance: any) => {
161
+ console.log(
162
+ chalk.yellow(
163
+ ` - ${instance.instanceName} (ID: ${instance.id})`
164
+ )
165
+ );
166
+ }
167
+ );
168
+ return;
169
+ }
170
+
171
+ // handle --all (iterate all manifest agent names)
172
+ if (options.all) {
173
+ let created = 0;
174
+ let failed = 0;
175
+ const names = await loadAllAgentNamesFromYaml();
176
+
177
+ if (!names.length) {
178
+ console.log(
179
+ chalk.yellow("No agents found in YAML manifest.")
180
+ );
181
+ return;
182
+ }
183
+
184
+ console.log(
185
+ chalk.cyan(
186
+ `Deploying ${names.length} agent(s) from YAML${options.prefix ? ` with prefix "${options.prefix}"` : ""}...`
187
+ )
188
+ );
189
+
190
+ const results: any[] = [];
191
+ for (const name of names) {
192
+ try {
193
+ const data = await buildAgentData(
194
+ {
195
+ ...options,
196
+ project: projectData.id,
197
+ agent: name, // use name; buildAgentData will fetch full definition via loadAgentFromYaml
198
+ },
199
+ targetInstance
200
+ );
201
+
202
+ const res =
203
+ await apis.agentsApi.machineAgentControllerCreateMachineAgent(
204
+ projectData.id,
205
+ { ...data }
206
+ );
207
+
208
+ created++;
209
+ results.push(res.data);
210
+ console.log(
211
+ chalk.green(`✔ Created: ${data.agentName}`)
212
+ );
213
+ } catch (err: any) {
214
+ failed++;
215
+ const msg =
216
+ err?.response?.data?.message ||
217
+ err?.message ||
218
+ "Unknown error";
219
+ console.log(
220
+ chalk.red(`✖ Failed: ${name} — ${msg}`)
221
+ );
222
+ }
223
+ }
224
+
225
+ console.log(
226
+ chalk.cyan(
227
+ `Done. ${chalk.green(`${created} created`)}, ${chalk.red(
228
+ `${failed} failed`
229
+ )}.`
230
+ )
231
+ );
232
+ return results;
233
+ }
234
+
235
+ // original single-agent flow
236
+ const data = await buildAgentData(
237
+ { ...options, project: projectData.id },
238
+ targetInstance
239
+ );
240
+
241
+ const response =
242
+ await apis.agentsApi.machineAgentControllerCreateMachineAgent(
243
+ projectData.id,
244
+ {
245
+ ...data,
246
+ }
247
+ );
248
+
249
+ console.log(chalk.green("Agent successfully created."));
250
+ return response.data;
251
+ } catch (error: any) {
252
+ if (error.response && error.response.status === 401) {
253
+ console.log(
254
+ chalk.red(
255
+ 'Authentication token has expired. Please login again using "nestbox login <domain>".'
256
+ )
257
+ );
258
+ } else if (error.response) {
259
+ console.log(
260
+ chalk.red(
261
+ `API Error (${error.response.status}): ${
262
+ error.response.data?.message || "Unknown error"
263
+ }`
264
+ )
265
+ );
266
+ } else {
267
+ console.log(chalk.red(error.message || "Unknown error"));
268
+ }
269
+ }
270
+ });
105
271
  }