@juspay/neurolink 7.0.0 → 7.1.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.
- package/CHANGELOG.md +9 -4
- package/dist/cli/factories/commandFactory.d.ts +53 -2
- package/dist/cli/factories/commandFactory.js +541 -92
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +18 -990
- package/dist/core/factory.js +2 -0
- package/dist/factories/providerRegistry.js +3 -1
- package/dist/lib/core/factory.js +3 -0
- package/dist/lib/factories/providerRegistry.js +3 -1
- package/dist/lib/mcp/toolRegistry.d.ts +5 -0
- package/dist/lib/mcp/toolRegistry.js +60 -0
- package/dist/lib/neurolink.js +9 -4
- package/dist/lib/sdk/toolRegistration.js +17 -0
- package/dist/lib/utils/logger.js +5 -6
- package/dist/lib/utils/providerUtils.js +9 -2
- package/dist/mcp/toolRegistry.d.ts +5 -0
- package/dist/mcp/toolRegistry.js +60 -0
- package/dist/neurolink.js +9 -4
- package/dist/sdk/toolRegistration.js +17 -0
- package/dist/utils/logger.js +5 -6
- package/dist/utils/providerUtils.js +9 -2
- package/package.json +1 -1
|
@@ -2,94 +2,301 @@ import { NeuroLink } from "../../lib/neurolink.js";
|
|
|
2
2
|
import ora from "ora";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { logger } from "../../lib/utils/logger.js";
|
|
5
|
+
import fs from "fs";
|
|
5
6
|
/**
|
|
6
7
|
* CLI Command Factory for generate commands
|
|
7
8
|
*/
|
|
8
9
|
export class CLICommandFactory {
|
|
10
|
+
// Common options available on all commands
|
|
11
|
+
static commonOptions = {
|
|
12
|
+
// Core generation options
|
|
13
|
+
provider: {
|
|
14
|
+
choices: [
|
|
15
|
+
"auto",
|
|
16
|
+
"openai",
|
|
17
|
+
"bedrock",
|
|
18
|
+
"vertex",
|
|
19
|
+
"googleVertex",
|
|
20
|
+
"anthropic",
|
|
21
|
+
"azure",
|
|
22
|
+
"google-ai",
|
|
23
|
+
"huggingface",
|
|
24
|
+
"ollama",
|
|
25
|
+
"mistral",
|
|
26
|
+
],
|
|
27
|
+
default: "auto",
|
|
28
|
+
description: "AI provider to use (auto-selects best available)",
|
|
29
|
+
},
|
|
30
|
+
model: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "Specific model to use (e.g. gemini-2.5-pro, gemini-2.5-flash)",
|
|
33
|
+
},
|
|
34
|
+
temperature: {
|
|
35
|
+
type: "number",
|
|
36
|
+
default: 0.7,
|
|
37
|
+
description: "Creativity level (0.0 = focused, 1.0 = creative)",
|
|
38
|
+
},
|
|
39
|
+
maxTokens: {
|
|
40
|
+
type: "number",
|
|
41
|
+
default: 1000,
|
|
42
|
+
description: "Maximum tokens to generate",
|
|
43
|
+
},
|
|
44
|
+
system: {
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "System prompt to guide AI behavior",
|
|
47
|
+
},
|
|
48
|
+
// Output control options
|
|
49
|
+
format: {
|
|
50
|
+
choices: ["text", "json", "table"],
|
|
51
|
+
default: "text",
|
|
52
|
+
alias: ["f", "output-format"],
|
|
53
|
+
description: "Output format",
|
|
54
|
+
},
|
|
55
|
+
output: {
|
|
56
|
+
type: "string",
|
|
57
|
+
description: "Save output to file",
|
|
58
|
+
},
|
|
59
|
+
// Behavior control options
|
|
60
|
+
timeout: {
|
|
61
|
+
type: "number",
|
|
62
|
+
default: 120,
|
|
63
|
+
description: "Maximum execution time in seconds",
|
|
64
|
+
},
|
|
65
|
+
delay: {
|
|
66
|
+
type: "number",
|
|
67
|
+
description: "Delay between operations (ms)",
|
|
68
|
+
},
|
|
69
|
+
// Tools & features options
|
|
70
|
+
disableTools: {
|
|
71
|
+
type: "boolean",
|
|
72
|
+
default: false,
|
|
73
|
+
description: "Disable MCP tool integration (tools enabled by default)",
|
|
74
|
+
},
|
|
75
|
+
enableAnalytics: {
|
|
76
|
+
type: "boolean",
|
|
77
|
+
default: false,
|
|
78
|
+
description: "Enable usage analytics collection",
|
|
79
|
+
},
|
|
80
|
+
enableEvaluation: {
|
|
81
|
+
type: "boolean",
|
|
82
|
+
default: false,
|
|
83
|
+
description: "Enable AI response quality evaluation",
|
|
84
|
+
},
|
|
85
|
+
evaluationDomain: {
|
|
86
|
+
type: "string",
|
|
87
|
+
description: "Domain expertise for evaluation (e.g., 'AI coding assistant', 'Customer service expert')",
|
|
88
|
+
},
|
|
89
|
+
toolUsageContext: {
|
|
90
|
+
type: "string",
|
|
91
|
+
description: "Tool usage context for evaluation (e.g., 'Used sales-data MCP tools')",
|
|
92
|
+
},
|
|
93
|
+
lighthouseStyle: {
|
|
94
|
+
type: "boolean",
|
|
95
|
+
default: false,
|
|
96
|
+
description: "Use Lighthouse-compatible domain-aware evaluation",
|
|
97
|
+
},
|
|
98
|
+
context: {
|
|
99
|
+
type: "string",
|
|
100
|
+
description: "JSON context object for custom data",
|
|
101
|
+
},
|
|
102
|
+
// Debug & output options
|
|
103
|
+
debug: {
|
|
104
|
+
type: "boolean",
|
|
105
|
+
alias: ["v", "verbose"],
|
|
106
|
+
default: false,
|
|
107
|
+
description: "Enable debug mode with verbose output",
|
|
108
|
+
},
|
|
109
|
+
quiet: {
|
|
110
|
+
type: "boolean",
|
|
111
|
+
alias: "q",
|
|
112
|
+
default: false,
|
|
113
|
+
description: "Suppress non-essential output",
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
// Helper method to build options for commands
|
|
117
|
+
static buildOptions(yargs, additionalOptions = {}) {
|
|
118
|
+
return yargs.options({
|
|
119
|
+
...this.commonOptions,
|
|
120
|
+
...additionalOptions,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// Helper method to process common options
|
|
124
|
+
static processOptions(argv) {
|
|
125
|
+
return {
|
|
126
|
+
provider: argv.provider === "auto" ? undefined : argv.provider,
|
|
127
|
+
model: argv.model,
|
|
128
|
+
temperature: argv.temperature,
|
|
129
|
+
maxTokens: argv.maxTokens,
|
|
130
|
+
systemPrompt: argv.system,
|
|
131
|
+
timeout: argv.timeout,
|
|
132
|
+
disableTools: argv.disableTools,
|
|
133
|
+
enableAnalytics: argv.enableAnalytics,
|
|
134
|
+
enableEvaluation: argv.enableEvaluation,
|
|
135
|
+
evaluationDomain: argv.evaluationDomain,
|
|
136
|
+
toolUsageContext: argv.toolUsageContext,
|
|
137
|
+
lighthouseStyle: argv.lighthouseStyle,
|
|
138
|
+
context: argv.context
|
|
139
|
+
? typeof argv.context === "string"
|
|
140
|
+
? JSON.parse(argv.context)
|
|
141
|
+
: argv.context
|
|
142
|
+
: undefined,
|
|
143
|
+
debug: argv.debug,
|
|
144
|
+
quiet: argv.quiet,
|
|
145
|
+
format: argv.format,
|
|
146
|
+
output: argv.output,
|
|
147
|
+
delay: argv.delay,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// Helper method to handle output
|
|
151
|
+
static handleOutput(result, options) {
|
|
152
|
+
let output;
|
|
153
|
+
if (options.format === "json") {
|
|
154
|
+
output = JSON.stringify(result, null, 2);
|
|
155
|
+
}
|
|
156
|
+
else if (options.format === "table" && Array.isArray(result)) {
|
|
157
|
+
console.table(result);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
if (typeof result === "string") {
|
|
162
|
+
output = result;
|
|
163
|
+
}
|
|
164
|
+
else if (result && typeof result === "object" && "content" in result) {
|
|
165
|
+
output = result.content;
|
|
166
|
+
}
|
|
167
|
+
else if (result && typeof result === "object" && "text" in result) {
|
|
168
|
+
output = result.text;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
output = JSON.stringify(result);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (options.output) {
|
|
175
|
+
fs.writeFileSync(options.output, output);
|
|
176
|
+
if (!options.quiet) {
|
|
177
|
+
console.log(`Output saved to ${options.output}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
console.log(output);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
9
184
|
/**
|
|
10
185
|
* Create the new primary 'generate' command
|
|
11
186
|
*/
|
|
12
187
|
static createGenerateCommand() {
|
|
13
188
|
return {
|
|
14
|
-
command: "generate <input>",
|
|
15
|
-
describe: "Generate content using AI
|
|
189
|
+
command: ["generate <input>", "gen <input>"],
|
|
190
|
+
describe: "Generate content using AI providers",
|
|
16
191
|
builder: (yargs) => {
|
|
17
|
-
return yargs
|
|
18
|
-
.positional("input", {
|
|
19
|
-
describe: "Text input for generation",
|
|
20
|
-
type: "string",
|
|
21
|
-
})
|
|
22
|
-
.option("provider", {
|
|
23
|
-
describe: "AI provider to use",
|
|
24
|
-
type: "string",
|
|
25
|
-
choices: [
|
|
26
|
-
"google-ai",
|
|
27
|
-
"vertex",
|
|
28
|
-
"openai",
|
|
29
|
-
"anthropic",
|
|
30
|
-
"bedrock",
|
|
31
|
-
"azure",
|
|
32
|
-
"huggingface",
|
|
33
|
-
"ollama",
|
|
34
|
-
"mistral",
|
|
35
|
-
],
|
|
36
|
-
default: "google-ai",
|
|
37
|
-
})
|
|
38
|
-
.option("model", {
|
|
39
|
-
describe: "Specific model to use",
|
|
192
|
+
return this.buildOptions(yargs.positional("input", {
|
|
40
193
|
type: "string",
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
194
|
+
description: "Text prompt for AI generation (or read from stdin)",
|
|
195
|
+
}));
|
|
196
|
+
},
|
|
197
|
+
handler: async (argv) => await this.executeGenerate(argv),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Create stream command
|
|
202
|
+
*/
|
|
203
|
+
static createStreamCommand() {
|
|
204
|
+
return {
|
|
205
|
+
command: "stream <input>",
|
|
206
|
+
describe: "Stream generation in real-time",
|
|
207
|
+
builder: (yargs) => {
|
|
208
|
+
return this.buildOptions(yargs.positional("input", {
|
|
56
209
|
type: "string",
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
})
|
|
73
|
-
.option("output-format", {
|
|
74
|
-
describe: "Output format",
|
|
210
|
+
description: "Text prompt for streaming (or read from stdin)",
|
|
211
|
+
}));
|
|
212
|
+
},
|
|
213
|
+
handler: async (argv) => await this.executeStream(argv),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Create batch command
|
|
218
|
+
*/
|
|
219
|
+
static createBatchCommand() {
|
|
220
|
+
return {
|
|
221
|
+
command: "batch <file>",
|
|
222
|
+
describe: "Process multiple prompts from a file",
|
|
223
|
+
builder: (yargs) => {
|
|
224
|
+
return this.buildOptions(yargs.positional("file", {
|
|
75
225
|
type: "string",
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
})
|
|
80
|
-
.option("debug", {
|
|
81
|
-
describe: "Enable debug output",
|
|
82
|
-
type: "boolean",
|
|
83
|
-
default: false,
|
|
84
|
-
});
|
|
226
|
+
description: "File with prompts (one per line)",
|
|
227
|
+
demandOption: true,
|
|
228
|
+
}));
|
|
85
229
|
},
|
|
86
|
-
handler: async (argv) => await
|
|
230
|
+
handler: async (argv) => await this.executeBatch(argv),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Create provider commands
|
|
235
|
+
*/
|
|
236
|
+
static createProviderCommands() {
|
|
237
|
+
return {
|
|
238
|
+
command: "provider <subcommand>",
|
|
239
|
+
describe: "Manage AI provider configurations and status",
|
|
240
|
+
builder: (yargs) => {
|
|
241
|
+
return yargs
|
|
242
|
+
.command("status", "Check status of all configured AI providers", (y) => this.buildOptions(y), (argv) => CLICommandFactory.executeProviderStatus(argv))
|
|
243
|
+
.demandCommand(1, "");
|
|
244
|
+
},
|
|
245
|
+
handler: () => { }, // No-op handler as subcommands handle everything
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Create status command (alias for provider status)
|
|
250
|
+
*/
|
|
251
|
+
static createStatusCommand() {
|
|
252
|
+
return {
|
|
253
|
+
command: "status",
|
|
254
|
+
describe: "Check AI provider connectivity and performance (alias for provider status)",
|
|
255
|
+
builder: (yargs) => this.buildOptions(yargs),
|
|
256
|
+
handler: async (argv) => await CLICommandFactory.executeProviderStatus(argv),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Create config commands
|
|
261
|
+
*/
|
|
262
|
+
static createConfigCommands() {
|
|
263
|
+
return {
|
|
264
|
+
command: "config <subcommand>",
|
|
265
|
+
describe: "Manage NeuroLink configuration",
|
|
266
|
+
builder: (yargs) => {
|
|
267
|
+
return yargs
|
|
268
|
+
.command("export", "Export current configuration", (y) => this.buildOptions(y), (argv) => this.executeConfigExport(argv))
|
|
269
|
+
.demandCommand(1, "");
|
|
270
|
+
},
|
|
271
|
+
handler: () => { }, // No-op handler as subcommands handle everything
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Create get-best-provider command
|
|
276
|
+
*/
|
|
277
|
+
static createBestProviderCommand() {
|
|
278
|
+
return {
|
|
279
|
+
command: "get-best-provider",
|
|
280
|
+
describe: "Show the best available AI provider",
|
|
281
|
+
builder: (yargs) => this.buildOptions(yargs),
|
|
282
|
+
handler: async (argv) => await this.executeGetBestProvider(argv),
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Create completion command
|
|
287
|
+
*/
|
|
288
|
+
static createCompletionCommand() {
|
|
289
|
+
return {
|
|
290
|
+
command: "completion",
|
|
291
|
+
describe: "Generate shell completion script",
|
|
292
|
+
builder: (yargs) => this.buildOptions(yargs),
|
|
293
|
+
handler: async (argv) => await this.executeCompletion(argv),
|
|
87
294
|
};
|
|
88
295
|
}
|
|
89
296
|
/**
|
|
90
297
|
* Execute provider status command
|
|
91
298
|
*/
|
|
92
|
-
async executeProviderStatus(argv) {
|
|
299
|
+
static async executeProviderStatus(argv) {
|
|
93
300
|
if (argv.verbose && !argv.quiet) {
|
|
94
301
|
console.log(chalk.yellow("ℹ️ Verbose mode enabled. Displaying detailed status.\n"));
|
|
95
302
|
}
|
|
@@ -136,32 +343,50 @@ export class CLICommandFactory {
|
|
|
136
343
|
* Execute the generate command
|
|
137
344
|
*/
|
|
138
345
|
static async executeGenerate(argv) {
|
|
139
|
-
|
|
346
|
+
// Handle stdin input if no input provided
|
|
347
|
+
if (!argv.input && !process.stdin.isTTY) {
|
|
348
|
+
let stdinData = "";
|
|
349
|
+
process.stdin.setEncoding("utf8");
|
|
350
|
+
for await (const chunk of process.stdin) {
|
|
351
|
+
stdinData += chunk;
|
|
352
|
+
}
|
|
353
|
+
argv.input = stdinData.trim();
|
|
354
|
+
if (!argv.input) {
|
|
355
|
+
throw new Error("No input received from stdin");
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
else if (!argv.input) {
|
|
359
|
+
throw new Error('Input required. Use: neurolink generate "your prompt" or echo "prompt" | neurolink generate');
|
|
360
|
+
}
|
|
361
|
+
const options = this.processOptions(argv);
|
|
362
|
+
const spinner = argv.quiet ? null : ora("🤖 Generating text...").start();
|
|
140
363
|
try {
|
|
364
|
+
// Add delay if specified
|
|
365
|
+
if (options.delay) {
|
|
366
|
+
await new Promise((resolve) => setTimeout(resolve, options.delay));
|
|
367
|
+
}
|
|
141
368
|
const sdk = new NeuroLink();
|
|
142
|
-
const outputFormat = argv.outputFormat || argv.format || "text";
|
|
143
369
|
const result = await sdk.generate({
|
|
144
370
|
input: { text: argv.input },
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
enableAnalytics:
|
|
153
|
-
enableEvaluation:
|
|
371
|
+
provider: options.provider,
|
|
372
|
+
model: options.model,
|
|
373
|
+
temperature: options.temperature,
|
|
374
|
+
maxTokens: options.maxTokens,
|
|
375
|
+
systemPrompt: options.systemPrompt,
|
|
376
|
+
timeout: options.timeout,
|
|
377
|
+
disableTools: options.disableTools,
|
|
378
|
+
enableAnalytics: options.enableAnalytics,
|
|
379
|
+
enableEvaluation: options.enableEvaluation,
|
|
380
|
+
evaluationDomain: options.evaluationDomain,
|
|
381
|
+
toolUsageContext: options.toolUsageContext,
|
|
382
|
+
context: options.context,
|
|
154
383
|
});
|
|
155
|
-
spinner
|
|
156
|
-
|
|
157
|
-
if (outputFormat === "json") {
|
|
158
|
-
console.log(JSON.stringify(result, null, 2));
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
console.log("\n" + chalk.cyan("Generated Content:"));
|
|
162
|
-
console.log(result.content);
|
|
384
|
+
if (spinner) {
|
|
385
|
+
spinner.succeed(chalk.green("✅ Text generated successfully!"));
|
|
163
386
|
}
|
|
164
|
-
|
|
387
|
+
// Handle output with universal formatting
|
|
388
|
+
this.handleOutput(result, options);
|
|
389
|
+
if (options.debug) {
|
|
165
390
|
logger.debug("\n" + chalk.yellow("Debug Information:"));
|
|
166
391
|
logger.debug("Provider:", result.provider);
|
|
167
392
|
logger.debug("Model:", result.model);
|
|
@@ -172,13 +397,237 @@ export class CLICommandFactory {
|
|
|
172
397
|
logger.debug("Evaluation:", JSON.stringify(result.evaluation, null, 2));
|
|
173
398
|
}
|
|
174
399
|
}
|
|
175
|
-
// Exit successfully
|
|
176
400
|
process.exit(0);
|
|
177
401
|
}
|
|
178
402
|
catch (error) {
|
|
179
|
-
spinner
|
|
180
|
-
|
|
403
|
+
if (spinner) {
|
|
404
|
+
spinner.fail();
|
|
405
|
+
}
|
|
406
|
+
console.error(chalk.red(`❌ Generation failed: ${error.message}`));
|
|
407
|
+
if (options.debug) {
|
|
408
|
+
console.error(chalk.gray(error.stack));
|
|
409
|
+
}
|
|
410
|
+
process.exit(1);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Execute the stream command
|
|
415
|
+
*/
|
|
416
|
+
static async executeStream(argv) {
|
|
417
|
+
// Handle stdin input if no input provided
|
|
418
|
+
if (!argv.input && !process.stdin.isTTY) {
|
|
419
|
+
let stdinData = "";
|
|
420
|
+
process.stdin.setEncoding("utf8");
|
|
421
|
+
for await (const chunk of process.stdin) {
|
|
422
|
+
stdinData += chunk;
|
|
423
|
+
}
|
|
424
|
+
argv.input = stdinData.trim();
|
|
425
|
+
if (!argv.input) {
|
|
426
|
+
throw new Error("No input received from stdin");
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
else if (!argv.input) {
|
|
430
|
+
throw new Error('Input required. Use: neurolink stream "your prompt" or echo "prompt" | neurolink stream');
|
|
431
|
+
}
|
|
432
|
+
const options = this.processOptions(argv);
|
|
433
|
+
if (!options.quiet) {
|
|
434
|
+
console.log(chalk.blue("🔄 Streaming..."));
|
|
435
|
+
}
|
|
436
|
+
try {
|
|
437
|
+
// Add delay if specified
|
|
438
|
+
if (options.delay) {
|
|
439
|
+
await new Promise((resolve) => setTimeout(resolve, options.delay));
|
|
440
|
+
}
|
|
441
|
+
const sdk = new NeuroLink();
|
|
442
|
+
const stream = await sdk.stream({
|
|
443
|
+
input: { text: argv.input },
|
|
444
|
+
provider: options.provider,
|
|
445
|
+
model: options.model,
|
|
446
|
+
temperature: options.temperature,
|
|
447
|
+
maxTokens: options.maxTokens,
|
|
448
|
+
systemPrompt: options.systemPrompt,
|
|
449
|
+
timeout: options.timeout,
|
|
450
|
+
disableTools: options.disableTools,
|
|
451
|
+
enableAnalytics: options.enableAnalytics,
|
|
452
|
+
enableEvaluation: options.enableEvaluation,
|
|
453
|
+
context: options.context,
|
|
454
|
+
});
|
|
455
|
+
let fullContent = "";
|
|
456
|
+
// Process the stream
|
|
457
|
+
for await (const chunk of stream.stream) {
|
|
458
|
+
if (options.delay && options.delay > 0) {
|
|
459
|
+
// Demo mode - add delay between chunks
|
|
460
|
+
await new Promise((resolve) => setTimeout(resolve, options.delay));
|
|
461
|
+
}
|
|
462
|
+
process.stdout.write(chunk.content);
|
|
463
|
+
fullContent += chunk.content;
|
|
464
|
+
}
|
|
465
|
+
if (!options.quiet) {
|
|
466
|
+
process.stdout.write("\n");
|
|
467
|
+
}
|
|
468
|
+
// Handle output file if specified
|
|
469
|
+
if (options.output) {
|
|
470
|
+
fs.writeFileSync(options.output, fullContent);
|
|
471
|
+
if (!options.quiet) {
|
|
472
|
+
console.log(`\nOutput saved to ${options.output}`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
process.exit(0);
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
console.error(chalk.red(`❌ Streaming failed: ${error.message}`));
|
|
479
|
+
if (options.debug) {
|
|
480
|
+
console.error(chalk.gray(error.stack));
|
|
481
|
+
}
|
|
181
482
|
process.exit(1);
|
|
182
483
|
}
|
|
183
484
|
}
|
|
485
|
+
/**
|
|
486
|
+
* Execute the batch command
|
|
487
|
+
*/
|
|
488
|
+
static async executeBatch(argv) {
|
|
489
|
+
const options = this.processOptions(argv);
|
|
490
|
+
const spinner = options.quiet ? null : ora().start();
|
|
491
|
+
try {
|
|
492
|
+
if (!argv.file) {
|
|
493
|
+
throw new Error("No file specified");
|
|
494
|
+
}
|
|
495
|
+
if (!fs.existsSync(argv.file)) {
|
|
496
|
+
throw new Error(`File not found: ${argv.file}`);
|
|
497
|
+
}
|
|
498
|
+
const buffer = fs.readFileSync(argv.file);
|
|
499
|
+
const prompts = buffer
|
|
500
|
+
.toString("utf8")
|
|
501
|
+
.split("\n")
|
|
502
|
+
.map((line) => line.trim())
|
|
503
|
+
.filter(Boolean);
|
|
504
|
+
if (prompts.length === 0) {
|
|
505
|
+
throw new Error("No prompts found in file");
|
|
506
|
+
}
|
|
507
|
+
if (spinner) {
|
|
508
|
+
spinner.text = `📦 Processing ${prompts.length} prompts...`;
|
|
509
|
+
}
|
|
510
|
+
else if (!options.quiet) {
|
|
511
|
+
console.log(chalk.blue(`📦 Processing ${prompts.length} prompts...\n`));
|
|
512
|
+
}
|
|
513
|
+
const results = [];
|
|
514
|
+
const sdk = new NeuroLink();
|
|
515
|
+
for (let i = 0; i < prompts.length; i++) {
|
|
516
|
+
if (spinner) {
|
|
517
|
+
spinner.text = `Processing ${i + 1}/${prompts.length}: ${prompts[i].substring(0, 30)}...`;
|
|
518
|
+
}
|
|
519
|
+
try {
|
|
520
|
+
const result = await sdk.generate({
|
|
521
|
+
input: { text: prompts[i] },
|
|
522
|
+
provider: options.provider,
|
|
523
|
+
model: options.model,
|
|
524
|
+
temperature: options.temperature,
|
|
525
|
+
maxTokens: options.maxTokens,
|
|
526
|
+
systemPrompt: options.systemPrompt,
|
|
527
|
+
timeout: options.timeout,
|
|
528
|
+
disableTools: options.disableTools,
|
|
529
|
+
enableAnalytics: options.enableAnalytics,
|
|
530
|
+
enableEvaluation: options.enableEvaluation,
|
|
531
|
+
context: options.context,
|
|
532
|
+
});
|
|
533
|
+
results.push({ prompt: prompts[i], response: result.content });
|
|
534
|
+
if (spinner) {
|
|
535
|
+
spinner.render();
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
catch (error) {
|
|
539
|
+
results.push({
|
|
540
|
+
prompt: prompts[i],
|
|
541
|
+
error: error.message,
|
|
542
|
+
});
|
|
543
|
+
if (spinner) {
|
|
544
|
+
spinner.render();
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
// Add delay between requests
|
|
548
|
+
if (i < prompts.length - 1) {
|
|
549
|
+
await new Promise((resolve) => setTimeout(resolve, options.delay || 1000));
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
if (spinner) {
|
|
553
|
+
spinner.succeed(chalk.green("✅ Batch processing complete!"));
|
|
554
|
+
}
|
|
555
|
+
// Handle output with universal formatting
|
|
556
|
+
this.handleOutput(results, options);
|
|
557
|
+
process.exit(0);
|
|
558
|
+
}
|
|
559
|
+
catch (error) {
|
|
560
|
+
if (spinner) {
|
|
561
|
+
spinner.fail();
|
|
562
|
+
}
|
|
563
|
+
console.error(chalk.red(`❌ Batch processing failed: ${error.message}`));
|
|
564
|
+
if (options.debug) {
|
|
565
|
+
console.error(chalk.gray(error.stack));
|
|
566
|
+
}
|
|
567
|
+
process.exit(1);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Execute config export command
|
|
572
|
+
*/
|
|
573
|
+
static async executeConfigExport(argv) {
|
|
574
|
+
const options = this.processOptions(argv);
|
|
575
|
+
try {
|
|
576
|
+
const config = {
|
|
577
|
+
providers: {
|
|
578
|
+
openai: !!process.env.OPENAI_API_KEY,
|
|
579
|
+
bedrock: !!(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY),
|
|
580
|
+
vertex: !!(process.env.GOOGLE_APPLICATION_CREDENTIALS ||
|
|
581
|
+
process.env.GOOGLE_SERVICE_ACCOUNT_KEY),
|
|
582
|
+
anthropic: !!process.env.ANTHROPIC_API_KEY,
|
|
583
|
+
azure: !!(process.env.AZURE_OPENAI_API_KEY &&
|
|
584
|
+
process.env.AZURE_OPENAI_ENDPOINT),
|
|
585
|
+
"google-ai": !!process.env.GOOGLE_AI_API_KEY,
|
|
586
|
+
},
|
|
587
|
+
defaults: {
|
|
588
|
+
temperature: 0.7,
|
|
589
|
+
maxTokens: 500,
|
|
590
|
+
},
|
|
591
|
+
timestamp: new Date().toISOString(),
|
|
592
|
+
};
|
|
593
|
+
this.handleOutput(config, options);
|
|
594
|
+
}
|
|
595
|
+
catch (error) {
|
|
596
|
+
console.error(chalk.red(`❌ Configuration export failed: ${error.message}`));
|
|
597
|
+
process.exit(1);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Execute get best provider command
|
|
602
|
+
*/
|
|
603
|
+
static async executeGetBestProvider(argv) {
|
|
604
|
+
const options = this.processOptions(argv);
|
|
605
|
+
try {
|
|
606
|
+
const { getBestProvider } = await import("../../lib/utils/providerUtils.js");
|
|
607
|
+
const bestProvider = await getBestProvider();
|
|
608
|
+
if (options.format === "json") {
|
|
609
|
+
this.handleOutput({ provider: bestProvider }, options);
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
if (!options.quiet) {
|
|
613
|
+
console.log(chalk.green(`🎯 Best available provider: ${bestProvider}`));
|
|
614
|
+
}
|
|
615
|
+
else {
|
|
616
|
+
this.handleOutput(bestProvider, options);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
catch (error) {
|
|
621
|
+
console.error(chalk.red(`❌ Provider selection failed: ${error.message}`));
|
|
622
|
+
process.exit(1);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Execute completion command
|
|
627
|
+
*/
|
|
628
|
+
static async executeCompletion(argv) {
|
|
629
|
+
// This would need to be implemented with the actual CLI instance
|
|
630
|
+
console.log("# Completion script would be generated here");
|
|
631
|
+
console.log("# This requires access to the yargs CLI instance");
|
|
632
|
+
}
|
|
184
633
|
}
|