@juspay/neurolink 9.83.0 → 9.84.0

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 (117) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/agent/agent.d.ts +104 -0
  3. package/dist/agent/agent.js +401 -0
  4. package/dist/agent/agentNetwork.d.ts +87 -0
  5. package/dist/agent/agentNetwork.js +458 -0
  6. package/dist/agent/communication/index.d.ts +9 -0
  7. package/dist/agent/communication/index.js +9 -0
  8. package/dist/agent/communication/message-bus.d.ts +113 -0
  9. package/dist/agent/communication/message-bus.js +406 -0
  10. package/dist/agent/coordination/coordinator.d.ts +83 -0
  11. package/dist/agent/coordination/coordinator.js +598 -0
  12. package/dist/agent/coordination/index.d.ts +10 -0
  13. package/dist/agent/coordination/index.js +10 -0
  14. package/dist/agent/coordination/task-distributor.d.ts +113 -0
  15. package/dist/agent/coordination/task-distributor.js +585 -0
  16. package/dist/agent/index.d.ts +38 -0
  17. package/dist/agent/index.js +44 -0
  18. package/dist/agent/orchestration/index.d.ts +10 -0
  19. package/dist/agent/orchestration/index.js +10 -0
  20. package/dist/agent/orchestration/orchestrator.d.ts +114 -0
  21. package/dist/agent/orchestration/orchestrator.js +476 -0
  22. package/dist/agent/orchestration/topology.d.ts +164 -0
  23. package/dist/agent/orchestration/topology.js +520 -0
  24. package/dist/agent/prompts/routingPrompts.d.ts +63 -0
  25. package/dist/agent/prompts/routingPrompts.js +201 -0
  26. package/dist/browser/neurolink.min.js +377 -358
  27. package/dist/cli/commands/agent.d.ts +37 -0
  28. package/dist/cli/commands/agent.js +718 -0
  29. package/dist/cli/factories/commandFactory.d.ts +8 -0
  30. package/dist/cli/factories/commandFactory.js +116 -0
  31. package/dist/cli/loop/optionsSchema.d.ts +1 -1
  32. package/dist/cli/parser.js +4 -0
  33. package/dist/index.d.ts +6 -0
  34. package/dist/index.js +19 -0
  35. package/dist/lib/agent/agent.d.ts +104 -0
  36. package/dist/lib/agent/agent.js +402 -0
  37. package/dist/lib/agent/agentNetwork.d.ts +87 -0
  38. package/dist/lib/agent/agentNetwork.js +459 -0
  39. package/dist/lib/agent/communication/index.d.ts +9 -0
  40. package/dist/lib/agent/communication/index.js +10 -0
  41. package/dist/lib/agent/communication/message-bus.d.ts +113 -0
  42. package/dist/lib/agent/communication/message-bus.js +407 -0
  43. package/dist/lib/agent/coordination/coordinator.d.ts +83 -0
  44. package/dist/lib/agent/coordination/coordinator.js +599 -0
  45. package/dist/lib/agent/coordination/index.d.ts +10 -0
  46. package/dist/lib/agent/coordination/index.js +11 -0
  47. package/dist/lib/agent/coordination/task-distributor.d.ts +113 -0
  48. package/dist/lib/agent/coordination/task-distributor.js +586 -0
  49. package/dist/lib/agent/index.d.ts +38 -0
  50. package/dist/lib/agent/index.js +45 -0
  51. package/dist/lib/agent/orchestration/index.d.ts +10 -0
  52. package/dist/lib/agent/orchestration/index.js +11 -0
  53. package/dist/lib/agent/orchestration/orchestrator.d.ts +114 -0
  54. package/dist/lib/agent/orchestration/orchestrator.js +477 -0
  55. package/dist/lib/agent/orchestration/topology.d.ts +164 -0
  56. package/dist/lib/agent/orchestration/topology.js +521 -0
  57. package/dist/lib/agent/prompts/routingPrompts.d.ts +63 -0
  58. package/dist/lib/agent/prompts/routingPrompts.js +202 -0
  59. package/dist/lib/index.d.ts +6 -0
  60. package/dist/lib/index.js +19 -0
  61. package/dist/lib/neurolink.d.ts +129 -0
  62. package/dist/lib/neurolink.js +276 -0
  63. package/dist/lib/processors/config/{fileTypes.js → fileExtensions.js} +1 -1
  64. package/dist/lib/processors/config/index.d.ts +2 -2
  65. package/dist/lib/processors/config/index.js +2 -2
  66. package/dist/lib/processors/config/{mimeTypes.js → mimeConstants.js} +1 -1
  67. package/dist/lib/processors/index.js +8 -0
  68. package/dist/lib/providers/googleAiStudio.js +3 -3
  69. package/dist/lib/providers/googleNativeGemini3.d.ts +18 -0
  70. package/dist/lib/providers/googleNativeGemini3.js +47 -1
  71. package/dist/lib/providers/googleVertex.js +5 -5
  72. package/dist/lib/types/agentNetwork.d.ts +1184 -0
  73. package/dist/lib/types/agentNetwork.js +8 -0
  74. package/dist/lib/types/cli.d.ts +66 -0
  75. package/dist/lib/types/generate.d.ts +53 -0
  76. package/dist/lib/types/index.d.ts +2 -0
  77. package/dist/lib/types/index.js +3 -0
  78. package/dist/lib/types/ioProcessor.d.ts +119 -0
  79. package/dist/lib/types/ioProcessor.js +10 -0
  80. package/dist/lib/types/stream.d.ts +36 -0
  81. package/dist/lib/utils/piiDetector.d.ts +24 -0
  82. package/dist/lib/utils/piiDetector.js +221 -0
  83. package/dist/lib/utils/responseValidator.d.ts +21 -0
  84. package/dist/lib/utils/responseValidator.js +354 -0
  85. package/dist/lib/utils/tripwireEvaluator.d.ts +73 -0
  86. package/dist/lib/utils/tripwireEvaluator.js +285 -0
  87. package/dist/neurolink.d.ts +129 -0
  88. package/dist/neurolink.js +276 -0
  89. package/dist/processors/config/index.d.ts +2 -2
  90. package/dist/processors/config/index.js +2 -2
  91. package/dist/processors/index.js +8 -0
  92. package/dist/providers/googleAiStudio.js +3 -3
  93. package/dist/providers/googleNativeGemini3.d.ts +18 -0
  94. package/dist/providers/googleNativeGemini3.js +47 -1
  95. package/dist/providers/googleVertex.js +5 -5
  96. package/dist/types/agentNetwork.d.ts +1184 -0
  97. package/dist/types/agentNetwork.js +7 -0
  98. package/dist/types/cli.d.ts +66 -0
  99. package/dist/types/generate.d.ts +53 -0
  100. package/dist/types/index.d.ts +2 -0
  101. package/dist/types/index.js +3 -0
  102. package/dist/types/ioProcessor.d.ts +119 -0
  103. package/dist/types/ioProcessor.js +9 -0
  104. package/dist/types/stream.d.ts +36 -0
  105. package/dist/utils/piiDetector.d.ts +24 -0
  106. package/dist/utils/piiDetector.js +220 -0
  107. package/dist/utils/responseValidator.d.ts +21 -0
  108. package/dist/utils/responseValidator.js +353 -0
  109. package/dist/utils/tripwireEvaluator.d.ts +73 -0
  110. package/dist/utils/tripwireEvaluator.js +284 -0
  111. package/package.json +1 -1
  112. /package/dist/lib/processors/config/{fileTypes.d.ts → fileExtensions.d.ts} +0 -0
  113. /package/dist/lib/processors/config/{mimeTypes.d.ts → mimeConstants.d.ts} +0 -0
  114. /package/dist/processors/config/{fileTypes.d.ts → fileExtensions.d.ts} +0 -0
  115. /package/dist/processors/config/{fileTypes.js → fileExtensions.js} +0 -0
  116. /package/dist/processors/config/{mimeTypes.d.ts → mimeConstants.d.ts} +0 -0
  117. /package/dist/processors/config/{mimeTypes.js → mimeConstants.js} +0 -0
@@ -0,0 +1,718 @@
1
+ /**
2
+ * Agent CLI Commands for NeuroLink
3
+ * Implements comprehensive multi-agent orchestration commands
4
+ *
5
+ * Commands:
6
+ * - agent create: Create a new agent definition
7
+ * - agent list: List registered agents
8
+ * - agent execute: Execute a single agent
9
+ * - network create: Create an agent network
10
+ * - network execute: Execute a network
11
+ */
12
+ import { NeuroLink } from "../../lib/neurolink.js";
13
+ import { logger } from "../../lib/utils/logger.js";
14
+ import chalk from "chalk";
15
+ import ora from "ora";
16
+ import fs from "fs";
17
+ import path from "path";
18
+ // In-memory storage for agents and networks (session-based)
19
+ const registeredAgents = new Map();
20
+ const registeredNetworks = new Map();
21
+ /**
22
+ * Agent CLI command factory
23
+ */
24
+ export class AgentCommandFactory {
25
+ /**
26
+ * Create the main agent command with subcommands
27
+ */
28
+ static createAgentCommands() {
29
+ return {
30
+ command: "agent <subcommand>",
31
+ describe: "Manage AI agents for multi-agent orchestration",
32
+ builder: (yargs) => {
33
+ return yargs
34
+ .command("create", "Create a new agent definition", (yargs) => this.buildCreateOptions(yargs), (argv) => this.executeCreate(argv))
35
+ .command("list", "List registered agents", (yargs) => this.buildListOptions(yargs), (argv) => this.executeList(argv))
36
+ .command("execute <id> <input>", "Execute a single agent with given input", (yargs) => this.buildExecuteOptions(yargs), (argv) => this.executeAgent(argv))
37
+ .command("run <id> <input>", "Execute a single agent (alias for execute)", (yargs) => this.buildExecuteOptions(yargs), (argv) => this.executeAgent(argv))
38
+ .option("format", {
39
+ choices: ["text", "json", "table"],
40
+ default: "text",
41
+ description: "Output format",
42
+ })
43
+ .option("output", {
44
+ type: "string",
45
+ description: "Save output to file",
46
+ })
47
+ .option("quiet", {
48
+ type: "boolean",
49
+ alias: "q",
50
+ default: false,
51
+ description: "Suppress non-essential output",
52
+ })
53
+ .option("debug", {
54
+ type: "boolean",
55
+ default: false,
56
+ description: "Enable debug output",
57
+ })
58
+ .demandCommand(1, "Please specify an agent subcommand")
59
+ .help();
60
+ },
61
+ handler: () => {
62
+ // No-op handler as subcommands handle everything
63
+ },
64
+ };
65
+ }
66
+ /**
67
+ * Create the network command with subcommands
68
+ */
69
+ static createNetworkCommands() {
70
+ return {
71
+ command: "network <subcommand>",
72
+ describe: "Manage agent networks for multi-agent orchestration",
73
+ builder: (yargs) => {
74
+ return yargs
75
+ .command("create", "Create a new agent network", (yargs) => this.buildNetworkCreateOptions(yargs), (argv) => this.executeNetworkCreate(argv))
76
+ .command("list", "List registered networks", (yargs) => this.buildNetworkListOptions(yargs), (argv) => this.executeNetworkList(argv))
77
+ .command("execute <id> <input>", "Execute an agent network with given input", (yargs) => this.buildNetworkExecuteOptions(yargs), (argv) => this.executeNetwork(argv))
78
+ .command("run <id> <input>", "Execute an agent network (alias for execute)", (yargs) => this.buildNetworkExecuteOptions(yargs), (argv) => this.executeNetwork(argv))
79
+ .option("format", {
80
+ choices: ["text", "json", "table"],
81
+ default: "text",
82
+ description: "Output format",
83
+ })
84
+ .option("output", {
85
+ type: "string",
86
+ description: "Save output to file",
87
+ })
88
+ .option("quiet", {
89
+ type: "boolean",
90
+ alias: "q",
91
+ default: false,
92
+ description: "Suppress non-essential output",
93
+ })
94
+ .option("debug", {
95
+ type: "boolean",
96
+ default: false,
97
+ description: "Enable debug output",
98
+ })
99
+ .demandCommand(1, "Please specify a network subcommand")
100
+ .help();
101
+ },
102
+ handler: () => {
103
+ // No-op handler as subcommands handle everything
104
+ },
105
+ };
106
+ }
107
+ // ============================================================================
108
+ // AGENT COMMAND BUILDERS
109
+ // ============================================================================
110
+ static buildCreateOptions(yargs) {
111
+ return yargs
112
+ .option("id", {
113
+ type: "string",
114
+ description: "Unique agent identifier",
115
+ demandOption: true,
116
+ })
117
+ .option("name", {
118
+ type: "string",
119
+ description: "Human-readable agent name",
120
+ demandOption: true,
121
+ })
122
+ .option("description", {
123
+ type: "string",
124
+ description: "Description of agent capabilities (for routing)",
125
+ demandOption: true,
126
+ })
127
+ .option("instructions", {
128
+ type: "string",
129
+ description: "System instructions for the agent",
130
+ demandOption: true,
131
+ })
132
+ .option("provider", {
133
+ type: "string",
134
+ description: "AI provider (e.g., openai, anthropic, vertex)",
135
+ })
136
+ .option("model", {
137
+ type: "string",
138
+ description: "Model to use (e.g., gpt-4o, claude-3-sonnet)",
139
+ })
140
+ .option("tools", {
141
+ type: "array",
142
+ description: "Tools available to the agent",
143
+ })
144
+ .option("maxSteps", {
145
+ type: "number",
146
+ default: 10,
147
+ description: "Maximum execution steps",
148
+ })
149
+ .option("temperature", {
150
+ type: "number",
151
+ default: 0.7,
152
+ description: "Generation temperature (0-1)",
153
+ })
154
+ .option("file", {
155
+ type: "string",
156
+ description: "Load agent definition from JSON file",
157
+ })
158
+ .example('$0 agent create --id researcher --name "Research Agent" --description "Searches and analyzes information" --instructions "You are a research assistant..."', "Create a research agent")
159
+ .example("$0 agent create --file agent-config.json", "Create agent from config file");
160
+ }
161
+ static buildListOptions(yargs) {
162
+ return yargs
163
+ .option("detailed", {
164
+ type: "boolean",
165
+ default: false,
166
+ description: "Show detailed agent information",
167
+ })
168
+ .example("$0 agent list", "List all registered agents")
169
+ .example("$0 agent list --format json", "List agents in JSON format");
170
+ }
171
+ static buildExecuteOptions(yargs) {
172
+ return yargs
173
+ .positional("id", {
174
+ type: "string",
175
+ description: "Agent ID to execute",
176
+ demandOption: true,
177
+ })
178
+ .positional("input", {
179
+ type: "string",
180
+ description: "Input prompt for the agent",
181
+ demandOption: true,
182
+ })
183
+ .option("context", {
184
+ type: "string",
185
+ description: "Additional context as JSON",
186
+ })
187
+ .option("maxSteps", {
188
+ type: "number",
189
+ description: "Override maximum steps",
190
+ })
191
+ .option("stream", {
192
+ type: "boolean",
193
+ default: false,
194
+ description: "Stream output in real-time",
195
+ })
196
+ .example('$0 agent execute researcher "Find information about AI trends"', "Execute the researcher agent")
197
+ .example('$0 agent run writer "Write a blog post" --stream', "Execute with streaming");
198
+ }
199
+ // ============================================================================
200
+ // NETWORK COMMAND BUILDERS
201
+ // ============================================================================
202
+ static buildNetworkCreateOptions(yargs) {
203
+ return yargs
204
+ .option("name", {
205
+ type: "string",
206
+ description: "Network name",
207
+ demandOption: true,
208
+ })
209
+ .option("description", {
210
+ type: "string",
211
+ description: "Network description",
212
+ })
213
+ .option("file", {
214
+ type: "string",
215
+ description: "Load network configuration from JSON file",
216
+ demandOption: true,
217
+ })
218
+ .option("routerProvider", {
219
+ type: "string",
220
+ description: "Provider for the routing agent",
221
+ })
222
+ .option("routerModel", {
223
+ type: "string",
224
+ description: "Model for the routing agent",
225
+ })
226
+ .example('$0 network create --name "Content Team" --file network-config.json', "Create a content team network");
227
+ }
228
+ static buildNetworkListOptions(yargs) {
229
+ return yargs
230
+ .option("detailed", {
231
+ type: "boolean",
232
+ default: false,
233
+ description: "Show detailed network information",
234
+ })
235
+ .example("$0 network list", "List all registered networks")
236
+ .example("$0 network list --format json", "List networks in JSON format");
237
+ }
238
+ static buildNetworkExecuteOptions(yargs) {
239
+ return yargs
240
+ .positional("id", {
241
+ type: "string",
242
+ description: "Network ID to execute",
243
+ demandOption: true,
244
+ })
245
+ .positional("input", {
246
+ type: "string",
247
+ description: "Input message for the network",
248
+ demandOption: true,
249
+ })
250
+ .option("context", {
251
+ type: "string",
252
+ description: "Additional context as JSON",
253
+ })
254
+ .option("maxSteps", {
255
+ type: "number",
256
+ default: 10,
257
+ description: "Maximum execution steps",
258
+ })
259
+ .option("timeout", {
260
+ type: "number",
261
+ default: 120000,
262
+ description: "Execution timeout in milliseconds",
263
+ })
264
+ .option("stream", {
265
+ type: "boolean",
266
+ default: false,
267
+ description: "Stream output in real-time",
268
+ })
269
+ .example('$0 network execute content-team "Write an article about AI"', "Execute the content team network")
270
+ .example('$0 network run research-team "Analyze market trends" --stream', "Execute with streaming");
271
+ }
272
+ // ============================================================================
273
+ // AGENT COMMAND HANDLERS
274
+ // ============================================================================
275
+ static async executeCreate(argv) {
276
+ const spinner = ora("Creating agent...").start();
277
+ try {
278
+ let definition;
279
+ if (argv.file) {
280
+ // Load from file
281
+ const filePath = path.resolve(argv.file);
282
+ if (!fs.existsSync(filePath)) {
283
+ throw new Error(`Agent definition file not found: ${filePath}`);
284
+ }
285
+ const content = fs.readFileSync(filePath, "utf-8");
286
+ definition = JSON.parse(content);
287
+ }
288
+ else {
289
+ // Build from command line arguments
290
+ definition = {
291
+ id: argv.id,
292
+ name: argv.name,
293
+ description: argv.description,
294
+ instructions: argv.instructions,
295
+ provider: argv.provider,
296
+ model: argv.model,
297
+ tools: argv.tools,
298
+ maxSteps: argv.maxSteps,
299
+ temperature: argv.temperature,
300
+ };
301
+ }
302
+ // Validate required fields
303
+ if (!definition.id ||
304
+ !definition.name ||
305
+ !definition.description ||
306
+ !definition.instructions) {
307
+ throw new Error("Agent definition requires: id, name, description, and instructions");
308
+ }
309
+ // Register the agent
310
+ registeredAgents.set(definition.id, definition);
311
+ spinner.succeed(chalk.green(`Agent "${definition.name}" created successfully`));
312
+ if (!argv.quiet) {
313
+ logger.always(chalk.cyan("\nAgent Details:"));
314
+ logger.always(` ID: ${definition.id}`);
315
+ logger.always(` Name: ${definition.name}`);
316
+ logger.always(` Description: ${definition.description}`);
317
+ if (definition.provider) {
318
+ logger.always(` Provider: ${definition.provider}`);
319
+ }
320
+ if (definition.model) {
321
+ logger.always(` Model: ${definition.model}`);
322
+ }
323
+ if (definition.tools?.length) {
324
+ logger.always(` Tools: ${definition.tools.join(", ")}`);
325
+ }
326
+ logger.always(` Max Steps: ${definition.maxSteps || 10}`);
327
+ logger.always(` Temperature: ${definition.temperature || 0.7}`);
328
+ }
329
+ if (argv.format === "json") {
330
+ logger.always(JSON.stringify(definition, null, 2));
331
+ }
332
+ }
333
+ catch (error) {
334
+ spinner.fail(chalk.red("Failed to create agent"));
335
+ logger.error(error.message);
336
+ process.exitCode = 1;
337
+ }
338
+ }
339
+ static async executeList(argv) {
340
+ try {
341
+ const agents = Array.from(registeredAgents.values());
342
+ if (agents.length === 0) {
343
+ logger.always(chalk.yellow("No agents registered. Use 'neurolink agent create' to create one."));
344
+ return;
345
+ }
346
+ if (argv.format === "json") {
347
+ logger.always(JSON.stringify(agents, null, 2));
348
+ return;
349
+ }
350
+ if (argv.format === "table") {
351
+ const tableData = agents.map((a) => ({
352
+ ID: a.id,
353
+ Name: a.name,
354
+ Provider: a.provider || "default",
355
+ Model: a.model || "default",
356
+ Tools: a.tools?.length || 0,
357
+ }));
358
+ logger.info(JSON.stringify(tableData, null, 2));
359
+ return;
360
+ }
361
+ // Text format
362
+ logger.always(chalk.cyan(`\nRegistered Agents (${agents.length}):\n`));
363
+ for (const agent of agents) {
364
+ logger.always(chalk.bold(` ${agent.name} (${agent.id})`));
365
+ logger.always(chalk.gray(` ${agent.description}`));
366
+ if (agent.provider || agent.model) {
367
+ logger.always(chalk.gray(` Provider: ${agent.provider || "default"}, Model: ${agent.model || "default"}`));
368
+ }
369
+ if (agent.tools?.length) {
370
+ logger.always(chalk.gray(` Tools: ${agent.tools.join(", ")}`));
371
+ }
372
+ logger.always("");
373
+ }
374
+ }
375
+ catch (error) {
376
+ logger.error(`Failed to list agents: ${error.message}`);
377
+ process.exitCode = 1;
378
+ }
379
+ }
380
+ static async executeAgent(argv) {
381
+ const spinner = ora("Executing agent...").start();
382
+ try {
383
+ const agentId = argv.id;
384
+ const input = argv.input;
385
+ // Get agent definition
386
+ const definition = registeredAgents.get(agentId);
387
+ if (!definition) {
388
+ throw new Error(`Agent not found: ${agentId}. Use 'neurolink agent list' to see available agents.`);
389
+ }
390
+ // Parse context if provided
391
+ let context;
392
+ if (argv.context) {
393
+ try {
394
+ context = JSON.parse(argv.context);
395
+ }
396
+ catch {
397
+ throw new Error("Invalid JSON in --context parameter");
398
+ }
399
+ }
400
+ // Create NeuroLink instance and agent
401
+ const neurolink = new NeuroLink();
402
+ const agent = await neurolink.createAgent(definition);
403
+ if (argv.stream) {
404
+ spinner.stop();
405
+ logger.always(chalk.cyan(`\n[${definition.name}] Streaming response:\n`));
406
+ // Stream execution
407
+ for await (const chunk of agent.stream(input, {
408
+ context,
409
+ maxSteps: argv.maxSteps,
410
+ })) {
411
+ if (chunk.type === "agent-text" && chunk.content) {
412
+ process.stdout.write(chunk.content);
413
+ }
414
+ else if (chunk.type === "agent-tool-call" && chunk.toolName) {
415
+ logger.always(chalk.yellow(`\n[Tool: ${chunk.toolName}]`));
416
+ }
417
+ else if (chunk.type === "agent-tool-result") {
418
+ logger.always(chalk.green(`[Tool Result: ${chunk.success ? "Success" : "Failed"}]`));
419
+ }
420
+ else if (chunk.type === "agent-complete") {
421
+ logger.always(chalk.gray(`\n\nCompleted in ${chunk.duration}ms`));
422
+ }
423
+ else if (chunk.type === "agent-error") {
424
+ logger.always(chalk.red(`\nError: ${chunk.error}`));
425
+ process.exitCode = 1;
426
+ }
427
+ }
428
+ logger.always("");
429
+ }
430
+ else {
431
+ // Non-streaming execution
432
+ const result = await agent.execute(input, {
433
+ context,
434
+ maxSteps: argv.maxSteps,
435
+ });
436
+ spinner.succeed(chalk.green("Agent execution completed"));
437
+ if (argv.format === "json") {
438
+ logger.always(JSON.stringify(result, null, 2));
439
+ }
440
+ else {
441
+ logger.always(chalk.cyan(`\n[${definition.name}] Response:\n`));
442
+ logger.always(result.content);
443
+ if (!argv.quiet && result.toolsUsed?.length) {
444
+ logger.always(chalk.gray(`\nTools used: ${result.toolsUsed.join(", ")}`));
445
+ }
446
+ if (!argv.quiet) {
447
+ logger.always(chalk.gray(`\nCompleted in ${result.duration}ms`));
448
+ }
449
+ }
450
+ // Save to file if output specified
451
+ if (argv.output) {
452
+ const output = argv.format === "json"
453
+ ? JSON.stringify(result, null, 2)
454
+ : result.content;
455
+ fs.writeFileSync(argv.output, output);
456
+ logger.always(chalk.green(`\nOutput saved to: ${argv.output}`));
457
+ }
458
+ }
459
+ }
460
+ catch (error) {
461
+ spinner.fail(chalk.red("Agent execution failed"));
462
+ logger.error(error.message);
463
+ process.exitCode = 1;
464
+ }
465
+ }
466
+ // ============================================================================
467
+ // NETWORK COMMAND HANDLERS
468
+ // ============================================================================
469
+ static async executeNetworkCreate(argv) {
470
+ const spinner = ora("Creating agent network...").start();
471
+ try {
472
+ if (!argv.file) {
473
+ throw new Error("Network configuration file is required. Use --file to specify.");
474
+ }
475
+ // Load network configuration from file
476
+ const filePath = path.resolve(argv.file);
477
+ if (!fs.existsSync(filePath)) {
478
+ throw new Error(`Network configuration file not found: ${filePath}`);
479
+ }
480
+ const content = fs.readFileSync(filePath, "utf-8");
481
+ const config = JSON.parse(content);
482
+ // Override with command line options
483
+ if (argv.name) {
484
+ config.name = argv.name;
485
+ }
486
+ if (argv.description) {
487
+ config.description = argv.description;
488
+ }
489
+ if (argv.routerProvider || argv.routerModel) {
490
+ config.router = config.router || {};
491
+ if (argv.routerProvider) {
492
+ config.router.provider = argv.routerProvider;
493
+ }
494
+ if (argv.routerModel) {
495
+ config.router.model = argv.routerModel;
496
+ }
497
+ }
498
+ // Validate required fields
499
+ if (!config.name || !config.agents || config.agents.length === 0) {
500
+ throw new Error("Network configuration requires: name and at least one agent");
501
+ }
502
+ // Generate ID if not provided
503
+ const networkId = config.id || config.name.toLowerCase().replace(/\s+/g, "-");
504
+ config.id = networkId;
505
+ // Register the network
506
+ registeredNetworks.set(networkId, config);
507
+ // Also register individual agents
508
+ for (const agentDef of config.agents) {
509
+ registeredAgents.set(agentDef.id, agentDef);
510
+ }
511
+ spinner.succeed(chalk.green(`Network "${config.name}" created successfully`));
512
+ if (!argv.quiet) {
513
+ logger.always(chalk.cyan("\nNetwork Details:"));
514
+ logger.always(` ID: ${networkId}`);
515
+ logger.always(` Name: ${config.name}`);
516
+ if (config.description) {
517
+ logger.always(` Description: ${config.description}`);
518
+ }
519
+ logger.always(` Agents: ${config.agents.length}`);
520
+ for (const agent of config.agents) {
521
+ logger.always(` - ${agent.name} (${agent.id})`);
522
+ }
523
+ if (config.router?.provider) {
524
+ logger.always(` Router Provider: ${config.router.provider}`);
525
+ }
526
+ if (config.router?.model) {
527
+ logger.always(` Router Model: ${config.router.model}`);
528
+ }
529
+ }
530
+ if (argv.format === "json") {
531
+ logger.always(JSON.stringify(config, null, 2));
532
+ }
533
+ }
534
+ catch (error) {
535
+ spinner.fail(chalk.red("Failed to create network"));
536
+ logger.error(error.message);
537
+ process.exitCode = 1;
538
+ }
539
+ }
540
+ static async executeNetworkList(argv) {
541
+ try {
542
+ const networks = Array.from(registeredNetworks.values());
543
+ if (networks.length === 0) {
544
+ logger.always(chalk.yellow("No networks registered. Use 'neurolink network create' to create one."));
545
+ return;
546
+ }
547
+ if (argv.format === "json") {
548
+ logger.always(JSON.stringify(networks, null, 2));
549
+ return;
550
+ }
551
+ if (argv.format === "table") {
552
+ const tableData = networks.map((n) => ({
553
+ ID: n.id || n.name.toLowerCase().replace(/\s+/g, "-"),
554
+ Name: n.name,
555
+ Agents: n.agents.length,
556
+ Workflows: n.workflows?.length || 0,
557
+ Tools: n.tools?.length || 0,
558
+ }));
559
+ logger.info(JSON.stringify(tableData, null, 2));
560
+ return;
561
+ }
562
+ // Text format
563
+ logger.always(chalk.cyan(`\nRegistered Networks (${networks.length}):\n`));
564
+ for (const network of networks) {
565
+ const networkId = network.id || network.name.toLowerCase().replace(/\s+/g, "-");
566
+ logger.always(chalk.bold(` ${network.name} (${networkId})`));
567
+ if (network.description) {
568
+ logger.always(chalk.gray(` ${network.description}`));
569
+ }
570
+ logger.always(chalk.gray(` Agents: ${network.agents.map((a) => a.name).join(", ")}`));
571
+ if (network.workflows?.length) {
572
+ logger.always(chalk.gray(` Workflows: ${network.workflows.length}`));
573
+ }
574
+ if (network.tools?.length) {
575
+ logger.always(chalk.gray(` Tools: ${network.tools.join(", ")}`));
576
+ }
577
+ logger.always("");
578
+ }
579
+ }
580
+ catch (error) {
581
+ logger.error(`Failed to list networks: ${error.message}`);
582
+ process.exitCode = 1;
583
+ }
584
+ }
585
+ static async executeNetwork(argv) {
586
+ const spinner = ora("Executing agent network...").start();
587
+ try {
588
+ const networkId = argv.id;
589
+ const input = argv.input;
590
+ // Get network configuration
591
+ const config = registeredNetworks.get(networkId);
592
+ if (!config) {
593
+ throw new Error(`Network not found: ${networkId}. Use 'neurolink network list' to see available networks.`);
594
+ }
595
+ // Parse context if provided
596
+ let context;
597
+ if (argv.context) {
598
+ try {
599
+ context = JSON.parse(argv.context);
600
+ }
601
+ catch {
602
+ throw new Error("Invalid JSON in --context parameter");
603
+ }
604
+ }
605
+ // Create NeuroLink instance and network
606
+ const neurolink = new NeuroLink();
607
+ const network = await neurolink.createNetwork(config);
608
+ if (argv.stream) {
609
+ spinner.stop();
610
+ logger.always(chalk.cyan(`\n[${config.name}] Streaming execution:\n`));
611
+ // Stream execution
612
+ for await (const chunk of neurolink.streamNetwork(network, {
613
+ message: input,
614
+ context,
615
+ }, {
616
+ maxSteps: argv.maxSteps,
617
+ timeout: argv.timeout,
618
+ })) {
619
+ switch (chunk.type) {
620
+ case "network-start": {
621
+ const startChunk = chunk;
622
+ logger.always(chalk.blue(`Network started: ${startChunk.networkId}`));
623
+ break;
624
+ }
625
+ case "routing-decision": {
626
+ const routingChunk = chunk;
627
+ logger.always(chalk.yellow(`\nRouting to: ${routingChunk.decision.selectedPrimitive.name}`));
628
+ logger.always(chalk.gray(` Confidence: ${(routingChunk.decision.confidence * 100).toFixed(0)}%`));
629
+ logger.always(chalk.gray(` Reasoning: ${routingChunk.decision.reasoning}`));
630
+ break;
631
+ }
632
+ case "primitive-start": {
633
+ const primitiveStartChunk = chunk;
634
+ logger.always(chalk.cyan(`\n[${primitiveStartChunk.primitive.name}] Starting...`));
635
+ break;
636
+ }
637
+ case "agent-text": {
638
+ const textChunk = chunk;
639
+ process.stdout.write(textChunk.content);
640
+ break;
641
+ }
642
+ case "agent-tool-call": {
643
+ const toolCallChunk = chunk;
644
+ logger.always(chalk.yellow(`\n[Tool: ${toolCallChunk.toolName}]`));
645
+ break;
646
+ }
647
+ case "agent-tool-result": {
648
+ const toolResultChunk = chunk;
649
+ logger.always(chalk.green(`[Tool Result: ${toolResultChunk.success ? "Success" : "Failed"}]`));
650
+ break;
651
+ }
652
+ case "primitive-end": {
653
+ const primitiveEndChunk = chunk;
654
+ logger.always(chalk.cyan(`\n[${primitiveEndChunk.primitive.name}] Completed`));
655
+ break;
656
+ }
657
+ case "network-complete": {
658
+ const completeChunk = chunk;
659
+ logger.always(chalk.green(`\n\nNetwork completed in ${completeChunk.result.duration}ms`));
660
+ logger.always(chalk.gray(`Steps taken: ${completeChunk.result.trace.steps.length}`));
661
+ break;
662
+ }
663
+ case "network-error": {
664
+ const errorChunk = chunk;
665
+ logger.always(chalk.red(`\nNetwork error: ${errorChunk.error}`));
666
+ process.exitCode = 1;
667
+ break;
668
+ }
669
+ }
670
+ }
671
+ logger.always("");
672
+ }
673
+ else {
674
+ // Non-streaming execution
675
+ const result = await neurolink.executeNetwork(network, {
676
+ message: input,
677
+ context,
678
+ }, {
679
+ maxSteps: argv.maxSteps,
680
+ timeout: argv.timeout,
681
+ });
682
+ spinner.succeed(chalk.green("Network execution completed"));
683
+ if (argv.format === "json") {
684
+ logger.always(JSON.stringify(result, null, 2));
685
+ }
686
+ else {
687
+ logger.always(chalk.cyan(`\n[${config.name}] Result:\n`));
688
+ logger.always(result.content);
689
+ if (!argv.quiet) {
690
+ logger.always(chalk.gray(`\nStatus: ${result.status}`));
691
+ logger.always(chalk.gray(`Duration: ${result.duration}ms`));
692
+ logger.always(chalk.gray(`Steps: ${result.trace.steps.length}`));
693
+ if (result.trace.routingDecisions.length > 0) {
694
+ logger.always(chalk.gray("\nRouting History:"));
695
+ for (const decision of result.trace.routingDecisions) {
696
+ logger.always(chalk.gray(` ${decision.stepIndex + 1}. ${decision.selectedPrimitive.name} (${(decision.confidence * 100).toFixed(0)}%)`));
697
+ }
698
+ }
699
+ }
700
+ }
701
+ // Save to file if output specified
702
+ if (argv.output) {
703
+ const output = argv.format === "json"
704
+ ? JSON.stringify(result, null, 2)
705
+ : result.content;
706
+ fs.writeFileSync(argv.output, output);
707
+ logger.always(chalk.green(`\nOutput saved to: ${argv.output}`));
708
+ }
709
+ }
710
+ }
711
+ catch (error) {
712
+ spinner.fail(chalk.red("Network execution failed"));
713
+ logger.error(error.message);
714
+ process.exitCode = 1;
715
+ }
716
+ }
717
+ }
718
+ //# sourceMappingURL=agent.js.map