@juspay/neurolink 1.9.0 → 1.11.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 +41 -31
- package/README.md +17 -1
- package/dist/agent/direct-tools.d.ts +9 -9
- package/dist/cli/commands/agent-generate.d.ts +1 -2
- package/dist/cli/commands/agent-generate.js +5 -8
- package/dist/cli/commands/config.d.ts +2 -2
- package/dist/cli/commands/config.js +1 -1
- package/dist/cli/commands/mcp.js +91 -100
- package/dist/cli/commands/ollama.d.ts +2 -7
- package/dist/cli/commands/ollama.js +5 -8
- package/dist/cli/index.js +263 -258
- package/dist/core/factory.js +11 -12
- package/dist/index.d.ts +24 -1
- package/dist/index.js +36 -1
- package/dist/lib/agent/direct-tools.d.ts +9 -9
- package/dist/lib/core/factory.js +11 -12
- package/dist/lib/index.d.ts +24 -1
- package/dist/lib/index.js +36 -1
- package/dist/lib/mcp/adapters/plugin-bridge.d.ts +39 -0
- package/dist/lib/mcp/adapters/plugin-bridge.js +82 -0
- package/dist/lib/mcp/auto-discovery.d.ts +38 -96
- package/dist/lib/mcp/auto-discovery.js +100 -744
- package/dist/lib/mcp/client.js +4 -4
- package/dist/lib/mcp/context-manager.js +72 -1
- package/dist/lib/mcp/contracts/mcp-contract.d.ts +162 -0
- package/dist/lib/mcp/contracts/mcp-contract.js +58 -0
- package/dist/lib/mcp/core/plugin-manager.d.ts +45 -0
- package/dist/lib/mcp/core/plugin-manager.js +110 -0
- package/dist/lib/mcp/demo/plugin-demo.d.ts +20 -0
- package/dist/lib/mcp/demo/plugin-demo.js +116 -0
- package/dist/lib/mcp/ecosystem.d.ts +75 -0
- package/dist/lib/mcp/ecosystem.js +161 -0
- package/dist/lib/mcp/external-client.d.ts +88 -0
- package/dist/lib/mcp/external-client.js +323 -0
- package/dist/lib/mcp/external-manager.d.ts +112 -0
- package/dist/lib/mcp/external-manager.js +302 -0
- package/dist/lib/mcp/factory.d.ts +4 -4
- package/dist/lib/mcp/function-calling.js +59 -34
- package/dist/lib/mcp/index.d.ts +39 -184
- package/dist/lib/mcp/index.js +72 -150
- package/dist/lib/mcp/initialize.js +5 -5
- package/dist/lib/mcp/logging.d.ts +27 -60
- package/dist/lib/mcp/logging.js +77 -165
- package/dist/lib/mcp/neurolink-mcp-client.js +31 -3
- package/dist/lib/mcp/orchestrator.d.ts +1 -1
- package/dist/lib/mcp/orchestrator.js +13 -12
- package/dist/lib/mcp/plugin-manager.d.ts +98 -0
- package/dist/lib/mcp/plugin-manager.js +294 -0
- package/dist/lib/mcp/plugins/core/filesystem-mcp.d.ts +35 -0
- package/dist/lib/mcp/plugins/core/filesystem-mcp.js +139 -0
- package/dist/lib/mcp/plugins/filesystem-mcp.d.ts +36 -0
- package/dist/lib/mcp/plugins/filesystem-mcp.js +54 -0
- package/dist/lib/mcp/registry.d.ts +26 -167
- package/dist/lib/mcp/registry.js +31 -354
- package/dist/lib/mcp/security-manager.d.ts +85 -0
- package/dist/lib/mcp/security-manager.js +344 -0
- package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.js +1 -1
- package/dist/lib/mcp/servers/ai-providers/ai-core-server.js +1 -1
- package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
- package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.js +1 -1
- package/dist/lib/mcp/tool-integration.d.ts +4 -14
- package/dist/lib/mcp/tool-integration.js +43 -21
- package/dist/lib/mcp/tool-registry.d.ts +66 -0
- package/dist/lib/mcp/tool-registry.js +160 -0
- package/dist/lib/mcp/unified-mcp.d.ts +123 -0
- package/dist/lib/mcp/unified-mcp.js +246 -0
- package/dist/lib/mcp/unified-registry.d.ts +42 -229
- package/dist/lib/mcp/unified-registry.js +96 -1346
- package/dist/lib/neurolink.d.ts +3 -4
- package/dist/lib/neurolink.js +18 -19
- package/dist/lib/providers/agent-enhanced-provider.js +2 -2
- package/dist/lib/providers/amazonBedrock.js +2 -2
- package/dist/lib/providers/anthropic.js +3 -3
- package/dist/lib/providers/azureOpenAI.js +3 -3
- package/dist/lib/providers/function-calling-provider.js +34 -25
- package/dist/lib/providers/googleAIStudio.js +3 -3
- package/dist/lib/providers/googleVertexAI.js +2 -2
- package/dist/lib/providers/huggingFace.js +2 -2
- package/dist/lib/providers/mcp-provider.js +33 -5
- package/dist/lib/providers/mistralAI.js +2 -2
- package/dist/lib/providers/ollama.js +17 -2
- package/dist/lib/providers/openAI.js +2 -2
- package/dist/lib/utils/providerUtils-fixed.d.ts +8 -0
- package/dist/lib/utils/providerUtils-fixed.js +75 -0
- package/dist/lib/utils/providerUtils.d.ts +8 -1
- package/dist/lib/utils/providerUtils.js +10 -1
- package/dist/mcp/adapters/plugin-bridge.d.ts +39 -0
- package/dist/mcp/adapters/plugin-bridge.js +82 -0
- package/dist/mcp/auto-discovery.d.ts +38 -96
- package/dist/mcp/auto-discovery.js +100 -745
- package/dist/mcp/client.js +4 -4
- package/dist/mcp/context-manager.js +72 -1
- package/dist/mcp/contracts/mcp-contract.d.ts +162 -0
- package/dist/mcp/contracts/mcp-contract.js +58 -0
- package/dist/mcp/core/plugin-manager.d.ts +45 -0
- package/dist/mcp/core/plugin-manager.js +110 -0
- package/dist/mcp/demo/plugin-demo.d.ts +20 -0
- package/dist/mcp/demo/plugin-demo.js +116 -0
- package/dist/mcp/ecosystem.d.ts +75 -0
- package/dist/mcp/ecosystem.js +162 -0
- package/dist/mcp/external-client.d.ts +88 -0
- package/dist/mcp/external-client.js +323 -0
- package/dist/mcp/external-manager.d.ts +112 -0
- package/dist/mcp/external-manager.js +302 -0
- package/dist/mcp/factory.d.ts +4 -4
- package/dist/mcp/function-calling.js +59 -34
- package/dist/mcp/index.d.ts +39 -184
- package/dist/mcp/index.js +72 -150
- package/dist/mcp/initialize.js +5 -5
- package/dist/mcp/logging.d.ts +27 -60
- package/dist/mcp/logging.js +77 -165
- package/dist/mcp/neurolink-mcp-client.js +31 -3
- package/dist/mcp/orchestrator.d.ts +1 -1
- package/dist/mcp/orchestrator.js +13 -12
- package/dist/mcp/plugin-manager.d.ts +98 -0
- package/dist/mcp/plugin-manager.js +295 -0
- package/dist/mcp/plugins/core/filesystem-mcp.d.ts +35 -0
- package/dist/mcp/plugins/core/filesystem-mcp.js +139 -0
- package/dist/mcp/plugins/core/neurolink-mcp.json +17 -0
- package/dist/mcp/plugins/filesystem-mcp.d.ts +36 -0
- package/dist/mcp/plugins/filesystem-mcp.js +54 -0
- package/dist/mcp/registry.d.ts +26 -167
- package/dist/mcp/registry.js +31 -354
- package/dist/mcp/security-manager.d.ts +85 -0
- package/dist/mcp/security-manager.js +344 -0
- package/dist/mcp/servers/ai-providers/ai-analysis-tools.js +1 -1
- package/dist/mcp/servers/ai-providers/ai-core-server.js +1 -1
- package/dist/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
- package/dist/mcp/servers/ai-providers/ai-workflow-tools.js +1 -1
- package/dist/mcp/tool-integration.d.ts +4 -14
- package/dist/mcp/tool-integration.js +43 -21
- package/dist/mcp/tool-registry.d.ts +66 -0
- package/dist/mcp/tool-registry.js +160 -0
- package/dist/mcp/unified-mcp.d.ts +123 -0
- package/dist/mcp/unified-mcp.js +246 -0
- package/dist/mcp/unified-registry.d.ts +42 -229
- package/dist/mcp/unified-registry.js +96 -1345
- package/dist/neurolink.d.ts +3 -4
- package/dist/neurolink.js +18 -19
- package/dist/providers/agent-enhanced-provider.js +2 -2
- package/dist/providers/amazonBedrock.js +2 -2
- package/dist/providers/anthropic.js +3 -3
- package/dist/providers/azureOpenAI.js +3 -3
- package/dist/providers/function-calling-provider.js +34 -25
- package/dist/providers/googleAIStudio.js +3 -3
- package/dist/providers/googleVertexAI.js +2 -2
- package/dist/providers/huggingFace.js +2 -2
- package/dist/providers/mcp-provider.js +33 -5
- package/dist/providers/mistralAI.js +2 -2
- package/dist/providers/ollama.js +17 -2
- package/dist/providers/openAI.js +2 -2
- package/dist/utils/providerUtils-fixed.d.ts +8 -0
- package/dist/utils/providerUtils-fixed.js +75 -0
- package/dist/utils/providerUtils.d.ts +8 -1
- package/dist/utils/providerUtils.js +10 -1
- package/package.json +28 -20
package/dist/cli/index.js
CHANGED
|
@@ -13,8 +13,9 @@ import ora from "ora";
|
|
|
13
13
|
import chalk from "chalk";
|
|
14
14
|
import fs from "fs";
|
|
15
15
|
import { addMCPCommands } from "./commands/mcp.js";
|
|
16
|
-
import
|
|
16
|
+
import { addOllamaCommands } from "./commands/ollama.js";
|
|
17
17
|
import { agentGenerateCommand } from "./commands/agent-generate.js";
|
|
18
|
+
import { AgentEnhancedProvider } from "../lib/providers/agent-enhanced-provider.js";
|
|
18
19
|
// Load environment variables from .env file
|
|
19
20
|
try {
|
|
20
21
|
// Try to import and configure dotenv
|
|
@@ -233,7 +234,7 @@ const cli = yargs(args)
|
|
|
233
234
|
})
|
|
234
235
|
.option("max-tokens", {
|
|
235
236
|
type: "number",
|
|
236
|
-
default:
|
|
237
|
+
default: 1000,
|
|
237
238
|
description: "Maximum tokens to generate",
|
|
238
239
|
})
|
|
239
240
|
.option("system", {
|
|
@@ -282,18 +283,41 @@ const cli = yargs(args)
|
|
|
282
283
|
const timeoutPromise = new Promise((_, reject) => {
|
|
283
284
|
setTimeout(() => reject(new Error(`Request timeout (${argv.timeout}ms)`)), argv.timeout);
|
|
284
285
|
});
|
|
285
|
-
// Use
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
: argv.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
286
|
+
// Use AgentEnhancedProvider when tools are enabled, otherwise use standard SDK
|
|
287
|
+
let generatePromise;
|
|
288
|
+
if (argv.disableTools === true) {
|
|
289
|
+
// Tools disabled - use standard SDK
|
|
290
|
+
generatePromise = sdk.generateText({
|
|
291
|
+
prompt: argv.prompt,
|
|
292
|
+
provider: argv.provider === "auto"
|
|
293
|
+
? undefined
|
|
294
|
+
: argv.provider,
|
|
295
|
+
temperature: argv.temperature,
|
|
296
|
+
maxTokens: argv.maxTokens,
|
|
297
|
+
systemPrompt: argv.system,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
// Tools enabled - use AgentEnhancedProvider for tool calling capabilities
|
|
302
|
+
// Map provider to supported AgentEnhancedProvider types
|
|
303
|
+
const supportedProvider = (() => {
|
|
304
|
+
switch (argv.provider) {
|
|
305
|
+
case "openai":
|
|
306
|
+
case "anthropic":
|
|
307
|
+
case "google-ai":
|
|
308
|
+
return argv.provider;
|
|
309
|
+
case "auto":
|
|
310
|
+
default:
|
|
311
|
+
return "google-ai"; // Default to google-ai for best tool support
|
|
312
|
+
}
|
|
313
|
+
})();
|
|
314
|
+
const agentProvider = new AgentEnhancedProvider({
|
|
315
|
+
provider: supportedProvider,
|
|
316
|
+
model: undefined, // Use default model for provider
|
|
317
|
+
toolCategory: "all", // Enable all tool categories
|
|
318
|
+
});
|
|
319
|
+
generatePromise = agentProvider.generateText(argv.prompt);
|
|
320
|
+
}
|
|
297
321
|
const result = (await Promise.race([
|
|
298
322
|
generatePromise,
|
|
299
323
|
timeoutPromise,
|
|
@@ -304,37 +328,60 @@ const cli = yargs(args)
|
|
|
304
328
|
if (spinner) {
|
|
305
329
|
spinner.succeed(chalk.green("✅ Text generated successfully!"));
|
|
306
330
|
}
|
|
331
|
+
// Handle both AgentEnhancedProvider (AI SDK) and standard NeuroLink SDK responses
|
|
332
|
+
const responseText = result.text || result.content || "";
|
|
333
|
+
const responseUsage = result.usage || {
|
|
334
|
+
promptTokens: 0,
|
|
335
|
+
completionTokens: 0,
|
|
336
|
+
totalTokens: 0,
|
|
337
|
+
};
|
|
307
338
|
if (argv.format === "json") {
|
|
308
339
|
const jsonOutput = {
|
|
309
|
-
content:
|
|
310
|
-
provider: result.provider,
|
|
311
|
-
usage:
|
|
312
|
-
promptTokens: 0,
|
|
313
|
-
completionTokens: 0,
|
|
314
|
-
totalTokens: 0,
|
|
315
|
-
},
|
|
340
|
+
content: responseText,
|
|
341
|
+
provider: result.provider || argv.provider,
|
|
342
|
+
usage: responseUsage,
|
|
316
343
|
responseTime: result.responseTime || 0,
|
|
344
|
+
toolCalls: result.toolCalls || [],
|
|
345
|
+
toolResults: result.toolResults || [],
|
|
317
346
|
};
|
|
318
347
|
process.stdout.write(JSON.stringify(jsonOutput, null, 2) + "\n");
|
|
319
348
|
}
|
|
320
349
|
else if (argv.debug) {
|
|
321
350
|
// Debug mode: Show AI response + full metadata
|
|
322
|
-
if (
|
|
323
|
-
console.log("\n" +
|
|
351
|
+
if (responseText) {
|
|
352
|
+
console.log("\n" + responseText + "\n");
|
|
353
|
+
}
|
|
354
|
+
// Show tool calls if any
|
|
355
|
+
if (result.toolCalls && result.toolCalls.length > 0) {
|
|
356
|
+
console.log(chalk.blue("🔧 Tools Called:"));
|
|
357
|
+
for (const toolCall of result.toolCalls) {
|
|
358
|
+
console.log(`- ${toolCall.toolName}`);
|
|
359
|
+
console.log(` Args: ${JSON.stringify(toolCall.args)}`);
|
|
360
|
+
}
|
|
361
|
+
console.log();
|
|
362
|
+
}
|
|
363
|
+
// Show tool results if any
|
|
364
|
+
if (result.toolResults && result.toolResults.length > 0) {
|
|
365
|
+
console.log(chalk.blue("📋 Tool Results:"));
|
|
366
|
+
for (const toolResult of result.toolResults) {
|
|
367
|
+
console.log(`- ${toolResult.toolCallId}`);
|
|
368
|
+
console.log(` Result: ${JSON.stringify(toolResult.result).substring(0, 200)}...`);
|
|
369
|
+
}
|
|
370
|
+
console.log();
|
|
324
371
|
}
|
|
325
372
|
console.log(JSON.stringify({
|
|
326
|
-
provider: result.provider,
|
|
327
|
-
usage:
|
|
328
|
-
responseTime: result.responseTime,
|
|
373
|
+
provider: result.provider || argv.provider,
|
|
374
|
+
usage: responseUsage,
|
|
375
|
+
responseTime: result.responseTime || 0,
|
|
329
376
|
}, null, 2));
|
|
330
|
-
if (
|
|
331
|
-
console.log(chalk.blue(`ℹ️ ${
|
|
377
|
+
if (responseUsage.totalTokens) {
|
|
378
|
+
console.log(chalk.blue(`ℹ️ ${responseUsage.totalTokens} tokens used`));
|
|
332
379
|
}
|
|
333
380
|
}
|
|
334
381
|
else {
|
|
335
382
|
// Default mode: Clean AI response only
|
|
336
|
-
if (
|
|
337
|
-
console.log(
|
|
383
|
+
if (responseText) {
|
|
384
|
+
console.log(responseText);
|
|
338
385
|
}
|
|
339
386
|
}
|
|
340
387
|
// Explicitly exit to prevent hanging, especially with Google AI Studio
|
|
@@ -582,8 +629,6 @@ const cli = yargs(args)
|
|
|
582
629
|
const spinner = argv.quiet
|
|
583
630
|
? null
|
|
584
631
|
: ora("🔍 Checking AI provider status...\n").start();
|
|
585
|
-
// Middleware sets argv.verbose if NEUROLINK_DEBUG is true and --verbose is not specified
|
|
586
|
-
// Removed the spinner.stopAndPersist logic from here as it's handled before spinner start
|
|
587
632
|
const providers = [
|
|
588
633
|
"openai",
|
|
589
634
|
"bedrock",
|
|
@@ -595,22 +640,105 @@ const cli = yargs(args)
|
|
|
595
640
|
"ollama",
|
|
596
641
|
"mistral",
|
|
597
642
|
];
|
|
643
|
+
// Import hasProviderEnvVars to check environment variables
|
|
644
|
+
const { hasProviderEnvVars } = await import("../lib/utils/providerUtils.js");
|
|
598
645
|
const results = [];
|
|
599
646
|
for (const p of providers) {
|
|
600
647
|
if (spinner) {
|
|
601
648
|
spinner.text = `Testing ${p}...`;
|
|
602
649
|
}
|
|
650
|
+
// First check if provider has env vars configured
|
|
651
|
+
const hasEnvVars = hasProviderEnvVars(p);
|
|
652
|
+
if (!hasEnvVars && p !== "ollama") {
|
|
653
|
+
// No env vars, don't even try to test
|
|
654
|
+
results.push({
|
|
655
|
+
provider: p,
|
|
656
|
+
status: "not-configured",
|
|
657
|
+
configured: false,
|
|
658
|
+
error: "Missing required environment variables",
|
|
659
|
+
});
|
|
660
|
+
if (spinner) {
|
|
661
|
+
spinner.fail(`${p}: ${chalk.gray("⚪ Not configured")} - Missing environment variables`);
|
|
662
|
+
}
|
|
663
|
+
else if (!argv.quiet) {
|
|
664
|
+
console.log(`${p}: ${chalk.gray("⚪ Not configured")} - Missing environment variables`);
|
|
665
|
+
}
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
// Special handling for Ollama
|
|
669
|
+
if (p === "ollama") {
|
|
670
|
+
try {
|
|
671
|
+
// First, check if the service is running
|
|
672
|
+
const serviceResponse = await fetch("http://localhost:11434/api/tags", {
|
|
673
|
+
method: "GET",
|
|
674
|
+
signal: AbortSignal.timeout(2000),
|
|
675
|
+
});
|
|
676
|
+
if (!serviceResponse.ok) {
|
|
677
|
+
throw new Error("Ollama service not responding");
|
|
678
|
+
}
|
|
679
|
+
// Service is running, now check if the default model is available
|
|
680
|
+
const { models } = await serviceResponse.json();
|
|
681
|
+
const defaultOllamaModel = "llama3.2:latest";
|
|
682
|
+
const modelIsAvailable = models.some((m) => m.name === defaultOllamaModel);
|
|
683
|
+
if (modelIsAvailable) {
|
|
684
|
+
results.push({
|
|
685
|
+
provider: p,
|
|
686
|
+
status: "working",
|
|
687
|
+
configured: true,
|
|
688
|
+
authenticated: true,
|
|
689
|
+
responseTime: 0,
|
|
690
|
+
});
|
|
691
|
+
if (spinner) {
|
|
692
|
+
spinner.succeed(`${p}: ${chalk.green("✅ Working")} - Service running and model '${defaultOllamaModel}' is available.`);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
else {
|
|
696
|
+
results.push({
|
|
697
|
+
provider: p,
|
|
698
|
+
status: "failed",
|
|
699
|
+
configured: true,
|
|
700
|
+
authenticated: false,
|
|
701
|
+
error: `Ollama service is running, but model '${defaultOllamaModel}' is not found. Please run 'ollama pull ${defaultOllamaModel}'.`,
|
|
702
|
+
});
|
|
703
|
+
if (spinner) {
|
|
704
|
+
spinner.fail(`${p}: ${chalk.red("❌ Model Not Found")} - Run 'ollama pull ${defaultOllamaModel}'`);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
catch (error) {
|
|
709
|
+
results.push({
|
|
710
|
+
provider: p,
|
|
711
|
+
status: "failed",
|
|
712
|
+
configured: false,
|
|
713
|
+
authenticated: false,
|
|
714
|
+
error: "Ollama is not running. Please start with: ollama serve",
|
|
715
|
+
});
|
|
716
|
+
if (spinner) {
|
|
717
|
+
spinner.fail(`${p}: ${chalk.red("❌ Failed")} - Service not running`);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
// Provider has env vars, now test authentication
|
|
603
723
|
try {
|
|
604
724
|
const start = Date.now();
|
|
605
|
-
|
|
725
|
+
// Add timeout to prevent hanging
|
|
726
|
+
const testPromise = sdk.generateText({
|
|
606
727
|
prompt: "test",
|
|
607
728
|
provider: p,
|
|
608
729
|
maxTokens: 1,
|
|
730
|
+
disableTools: true, // Disable tools for faster status check
|
|
609
731
|
});
|
|
732
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
733
|
+
setTimeout(() => reject(new Error("Provider test timeout (5s)")), 5000);
|
|
734
|
+
});
|
|
735
|
+
await Promise.race([testPromise, timeoutPromise]);
|
|
610
736
|
const duration = Date.now() - start;
|
|
611
737
|
results.push({
|
|
612
738
|
provider: p,
|
|
613
739
|
status: "working",
|
|
740
|
+
configured: true,
|
|
741
|
+
authenticated: true,
|
|
614
742
|
responseTime: duration,
|
|
615
743
|
});
|
|
616
744
|
if (spinner) {
|
|
@@ -621,280 +749,157 @@ const cli = yargs(args)
|
|
|
621
749
|
}
|
|
622
750
|
}
|
|
623
751
|
catch (error) {
|
|
752
|
+
const errorMsg = error.message.includes("timeout")
|
|
753
|
+
? "Connection timeout"
|
|
754
|
+
: error.message.split("\n")[0];
|
|
624
755
|
results.push({
|
|
625
756
|
provider: p,
|
|
626
757
|
status: "failed",
|
|
627
|
-
|
|
758
|
+
configured: true,
|
|
759
|
+
authenticated: false,
|
|
760
|
+
error: errorMsg,
|
|
628
761
|
});
|
|
629
762
|
if (spinner) {
|
|
630
|
-
spinner.fail(`${p}: ${chalk.red("❌ Failed")} - ${
|
|
763
|
+
spinner.fail(`${p}: ${chalk.red("❌ Failed")} - ${errorMsg}`);
|
|
631
764
|
}
|
|
632
765
|
else if (!argv.quiet) {
|
|
633
|
-
console.error(`${p}: ${chalk.red("❌ Failed")} - ${
|
|
766
|
+
console.error(`${p}: ${chalk.red("❌ Failed")} - ${errorMsg}`);
|
|
634
767
|
}
|
|
635
768
|
}
|
|
636
769
|
}
|
|
637
770
|
const working = results.filter((r) => r.status === "working").length;
|
|
771
|
+
const configured = results.filter((r) => r.configured).length;
|
|
638
772
|
if (spinner) {
|
|
639
|
-
spinner.info(chalk.blue(`\n📊 Summary: ${working}/${results.length} providers working`));
|
|
773
|
+
spinner.info(chalk.blue(`\n📊 Summary: ${working}/${results.length} providers working, ${configured}/${results.length} configured`));
|
|
640
774
|
}
|
|
641
775
|
else if (!argv.quiet) {
|
|
642
|
-
console.log(chalk.blue(`\n📊 Summary: ${working}/${results.length} providers working`));
|
|
776
|
+
console.log(chalk.blue(`\n📊 Summary: ${working}/${results.length} providers working, ${configured}/${results.length} configured`));
|
|
643
777
|
}
|
|
644
778
|
if (argv.verbose && !argv.quiet) {
|
|
645
779
|
console.log(chalk.blue("\n📋 Detailed Results:"));
|
|
646
780
|
console.log(JSON.stringify(results, null, 2));
|
|
647
781
|
}
|
|
648
782
|
})
|
|
649
|
-
.
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
783
|
+
.demandCommand(1, "")
|
|
784
|
+
.example("$0 provider status", "Check all providers");
|
|
785
|
+
})
|
|
786
|
+
// Status command alias
|
|
787
|
+
.command("status", "Check AI provider connectivity and performance (alias for provider status)", (yargsConfig) => yargsConfig.example("$0 status", "Quick provider status check"), async (argv) => {
|
|
788
|
+
// Simply redirect to provider status
|
|
789
|
+
process.argv = [
|
|
790
|
+
process.argv[0],
|
|
791
|
+
process.argv[1],
|
|
792
|
+
"provider",
|
|
793
|
+
"status",
|
|
794
|
+
...process.argv.slice(3),
|
|
795
|
+
];
|
|
796
|
+
const { hideBin } = await import("yargs/helpers");
|
|
797
|
+
const redirectedCli = yargs(hideBin(process.argv));
|
|
798
|
+
// Re-run with provider status
|
|
799
|
+
await cli.parse("provider status");
|
|
800
|
+
})
|
|
801
|
+
// Configuration Command Group
|
|
802
|
+
.command("config <subcommand>", "Manage NeuroLink configuration", (yargsConfig) => {
|
|
803
|
+
yargsConfig
|
|
804
|
+
.usage("Usage: $0 config <subcommand> [options]")
|
|
805
|
+
.command("export", "Export current configuration", (y) => y
|
|
806
|
+
.usage("Usage: $0 config export [options]")
|
|
807
|
+
.option("output", {
|
|
655
808
|
type: "string",
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
"bedrock",
|
|
659
|
-
"vertex",
|
|
660
|
-
"anthropic",
|
|
661
|
-
"azure",
|
|
662
|
-
"google-ai",
|
|
663
|
-
"huggingface",
|
|
664
|
-
"ollama",
|
|
665
|
-
"mistral",
|
|
666
|
-
],
|
|
667
|
-
description: "Name of the provider to configure",
|
|
668
|
-
demandOption: true,
|
|
669
|
-
})
|
|
670
|
-
.example("$0 provider configure openai", "Show OpenAI configuration help"), async (argv) => {
|
|
671
|
-
console.log(chalk.blue(`\n🔧 Configuration guidance for ${chalk.bold(argv.providerName)}:`));
|
|
672
|
-
console.log(chalk.yellow("💡 Set relevant environment variables for API keys and other settings."));
|
|
673
|
-
console.log(chalk.gray(" Refer to the documentation for details: https://github.com/juspay/neurolink#configuration"));
|
|
809
|
+
alias: "o",
|
|
810
|
+
description: "Output file for configuration",
|
|
674
811
|
})
|
|
675
|
-
.
|
|
676
|
-
|
|
677
|
-
// Status Command (Standalone, for backward compatibility or direct access)
|
|
678
|
-
.command("status", "Check AI provider connectivity and performance (alias for provider status)", (yargsInstance) => yargsInstance
|
|
679
|
-
.usage("Usage: $0 status [options]")
|
|
680
|
-
.option("verbose", {
|
|
681
|
-
// Ensure status alias also defines verbose
|
|
682
|
-
type: "boolean",
|
|
683
|
-
alias: "v", // Default is handled by middleware if NEUROLINK_DEBUG is set
|
|
684
|
-
description: "Show detailed information",
|
|
685
|
-
})
|
|
686
|
-
.example("$0 status", "Check all providers")
|
|
687
|
-
.example("$0 status --verbose", "Show detailed status information"), async (argv) => {
|
|
688
|
-
// This logic is duplicated from 'provider status' for the alias
|
|
689
|
-
if (argv.verbose && !argv.quiet) {
|
|
690
|
-
console.log(chalk.yellow("ℹ️ Verbose mode enabled. Displaying detailed status.\n")); // Added newline
|
|
691
|
-
}
|
|
692
|
-
const spinner = argv.quiet
|
|
693
|
-
? null
|
|
694
|
-
: ora("🔍 Checking AI provider status...\n").start();
|
|
695
|
-
// Middleware sets argv.verbose if NEUROLINK_DEBUG is true and --verbose is not specified
|
|
696
|
-
// Removed the spinner.stopAndPersist logic from here as it's handled before spinner start
|
|
697
|
-
const providers = [
|
|
698
|
-
"openai",
|
|
699
|
-
"bedrock",
|
|
700
|
-
"vertex",
|
|
701
|
-
"anthropic",
|
|
702
|
-
"azure",
|
|
703
|
-
"google-ai",
|
|
704
|
-
"huggingface",
|
|
705
|
-
"ollama",
|
|
706
|
-
"mistral",
|
|
707
|
-
];
|
|
708
|
-
const results = [];
|
|
709
|
-
for (const p of providers) {
|
|
710
|
-
if (spinner) {
|
|
711
|
-
spinner.text = `Testing ${p}...`;
|
|
712
|
-
}
|
|
812
|
+
.example("$0 config export", "Export to stdout")
|
|
813
|
+
.example("$0 config export -o config.json", "Export to file"), async (argv) => {
|
|
713
814
|
try {
|
|
714
|
-
const
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
815
|
+
const config = {
|
|
816
|
+
providers: {
|
|
817
|
+
openai: !!process.env.OPENAI_API_KEY,
|
|
818
|
+
bedrock: !!(process.env.AWS_ACCESS_KEY_ID &&
|
|
819
|
+
process.env.AWS_SECRET_ACCESS_KEY),
|
|
820
|
+
vertex: !!(process.env.GOOGLE_APPLICATION_CREDENTIALS ||
|
|
821
|
+
process.env.GOOGLE_SERVICE_ACCOUNT_KEY ||
|
|
822
|
+
(process.env.GOOGLE_AUTH_CLIENT_EMAIL &&
|
|
823
|
+
process.env.GOOGLE_AUTH_PRIVATE_KEY)),
|
|
824
|
+
anthropic: !!process.env.ANTHROPIC_API_KEY,
|
|
825
|
+
azure: !!(process.env.AZURE_OPENAI_API_KEY &&
|
|
826
|
+
process.env.AZURE_OPENAI_ENDPOINT),
|
|
827
|
+
"google-ai": !!process.env.GOOGLE_AI_API_KEY,
|
|
828
|
+
},
|
|
829
|
+
defaults: {
|
|
830
|
+
temperature: 0.7,
|
|
831
|
+
maxTokens: 500,
|
|
832
|
+
},
|
|
833
|
+
timestamp: new Date().toISOString(),
|
|
834
|
+
};
|
|
835
|
+
const output = JSON.stringify(config, null, 2);
|
|
836
|
+
if (argv.output) {
|
|
837
|
+
fs.writeFileSync(argv.output, output);
|
|
838
|
+
if (!argv.quiet) {
|
|
839
|
+
console.log(chalk.green(`✅ Configuration exported to ${argv.output}`));
|
|
840
|
+
}
|
|
724
841
|
}
|
|
725
|
-
else
|
|
726
|
-
|
|
842
|
+
else {
|
|
843
|
+
process.stdout.write(output + "\n");
|
|
727
844
|
}
|
|
728
845
|
}
|
|
729
846
|
catch (error) {
|
|
730
|
-
|
|
731
|
-
provider: p,
|
|
732
|
-
status: "failed",
|
|
733
|
-
error: error.message,
|
|
734
|
-
});
|
|
735
|
-
if (spinner) {
|
|
736
|
-
spinner.fail(`${p}: ${chalk.red("❌ Failed")} - ${error.message.split("\n")[0]}`);
|
|
737
|
-
}
|
|
738
|
-
else if (!argv.quiet) {
|
|
739
|
-
console.error(`${p}: ${chalk.red("❌ Failed")} - ${error.message.split("\n")[0]}`);
|
|
740
|
-
}
|
|
847
|
+
handleError(error, "Configuration export");
|
|
741
848
|
}
|
|
742
|
-
}
|
|
743
|
-
const working = results.filter((r) => r.status === "working").length;
|
|
744
|
-
if (spinner) {
|
|
745
|
-
spinner.info(chalk.blue(`\n📊 Summary: ${working}/${results.length} providers working`));
|
|
746
|
-
}
|
|
747
|
-
else if (!argv.quiet) {
|
|
748
|
-
console.log(chalk.blue(`\n📊 Summary: ${working}/${results.length} providers working`));
|
|
749
|
-
}
|
|
750
|
-
if (argv.verbose && !argv.quiet) {
|
|
751
|
-
console.log(chalk.blue("\n📋 Detailed Results:"));
|
|
752
|
-
console.log(JSON.stringify(results, null, 2));
|
|
753
|
-
}
|
|
754
|
-
})
|
|
755
|
-
// Configuration Commands Refactored
|
|
756
|
-
.command("config <subcommand>", "Manage NeuroLink configuration", (yargsConfig) => {
|
|
757
|
-
yargsConfig
|
|
758
|
-
.usage("Usage: $0 config <subcommand> [options]") // Add usage here
|
|
759
|
-
.command("setup", "Interactive setup for NeuroLink configuration", (y) => y
|
|
760
|
-
.usage("Usage: $0 config setup [options]")
|
|
761
|
-
.option("quiet", {
|
|
762
|
-
type: "boolean",
|
|
763
|
-
alias: "q",
|
|
764
|
-
description: "Suppress progress messages and interactive prompts",
|
|
765
|
-
})
|
|
766
|
-
.example("$0 config setup", "Run interactive setup wizard")
|
|
767
|
-
.example("$0 config setup --quiet", "Run setup with minimal output"), async (argv) => {
|
|
768
|
-
const { configSetup } = await import("./utils/complete-setup.js");
|
|
769
|
-
await configSetup(argv.quiet);
|
|
770
|
-
})
|
|
771
|
-
.command("init", "Alias for setup: Interactive setup for NeuroLink configuration", (y) => y
|
|
772
|
-
.usage("Usage: $0 config init [options]")
|
|
773
|
-
.option("quiet", {
|
|
774
|
-
type: "boolean",
|
|
775
|
-
alias: "q",
|
|
776
|
-
description: "Suppress progress messages and interactive prompts",
|
|
777
|
-
})
|
|
778
|
-
.example("$0 config init", "Run interactive setup wizard (alias for setup)")
|
|
779
|
-
.example("$0 config init --quiet", "Run setup with minimal output"), async (argv) => {
|
|
780
|
-
const { configInit } = await import("./utils/complete-setup.js");
|
|
781
|
-
await configInit(argv.quiet);
|
|
782
|
-
})
|
|
783
|
-
.command("show", "Show current NeuroLink configuration", () => { }, async (argv) => {
|
|
784
|
-
console.log("Config show: Displaying current configuration...");
|
|
785
|
-
// Actual show logic here
|
|
786
|
-
})
|
|
787
|
-
.command("set <key> <value>", "Set a configuration key-value pair", (y) => y
|
|
788
|
-
.positional("key", {
|
|
789
|
-
type: "string",
|
|
790
|
-
description: "Configuration key to set",
|
|
791
|
-
demandOption: true,
|
|
792
849
|
})
|
|
793
|
-
.
|
|
794
|
-
|
|
795
|
-
description: "Value to set for the key",
|
|
796
|
-
demandOption: true,
|
|
797
|
-
}), async (argv) => {
|
|
798
|
-
console.log(`Config set: Key: ${argv.key}, Value: ${argv.value}`);
|
|
799
|
-
// Actual set logic here
|
|
800
|
-
})
|
|
801
|
-
.command("import <file>", "Import configuration from a file", (y) => y.positional("file", {
|
|
802
|
-
type: "string",
|
|
803
|
-
description: "File path to import from",
|
|
804
|
-
demandOption: true,
|
|
805
|
-
}), async (argv) => {
|
|
806
|
-
console.log(`Config import: Importing from ${argv.file}`);
|
|
807
|
-
if (argv.file.includes("invalid-config.json")) {
|
|
808
|
-
handleError(new Error("Invalid or unparseable JSON in config file."), "Config import");
|
|
809
|
-
}
|
|
810
|
-
// Actual import logic here
|
|
811
|
-
})
|
|
812
|
-
.command("export <file>", "Export current configuration to a file", (y) => y.positional("file", {
|
|
813
|
-
type: "string",
|
|
814
|
-
description: "File path to export to",
|
|
815
|
-
demandOption: true,
|
|
816
|
-
}), async (argv) => {
|
|
817
|
-
console.log(`Config export: Exporting to ${argv.file}`);
|
|
818
|
-
if (argv.file.includes("read-only-dir")) {
|
|
819
|
-
handleError(new Error("Permission denied. Cannot write to read-only directory."), "Config export");
|
|
820
|
-
}
|
|
821
|
-
// Actual export logic here
|
|
822
|
-
})
|
|
823
|
-
.command("validate", "Validate the current configuration", () => { }, async (argv) => {
|
|
824
|
-
console.log("Config validate: Validating configuration...");
|
|
825
|
-
// Actual validation logic here
|
|
826
|
-
})
|
|
827
|
-
.command("reset", "Reset NeuroLink configuration to defaults", () => { }, async (argv) => {
|
|
828
|
-
console.log("Config reset: Resetting configuration...");
|
|
829
|
-
// Actual reset logic here
|
|
830
|
-
})
|
|
831
|
-
.demandCommand(1, "Please specify a config subcommand (e.g., setup, show, set).")
|
|
832
|
-
.example("$0 config setup", "Run interactive setup")
|
|
833
|
-
.example("$0 config set provider openai", "Set default provider (using key/value)");
|
|
850
|
+
.demandCommand(1, "")
|
|
851
|
+
.example("$0 config export", "Export configuration");
|
|
834
852
|
})
|
|
835
853
|
// Get Best Provider Command
|
|
836
854
|
.command("get-best-provider", "Show the best available AI provider", (yargsInstance) => yargsInstance
|
|
837
855
|
.usage("Usage: $0 get-best-provider [options]")
|
|
838
|
-
.option("
|
|
839
|
-
|
|
840
|
-
default:
|
|
841
|
-
description: "
|
|
856
|
+
.option("format", {
|
|
857
|
+
choices: ["text", "json"],
|
|
858
|
+
default: "text",
|
|
859
|
+
description: "Output format",
|
|
842
860
|
})
|
|
843
|
-
.example("$0 get-best-provider", "
|
|
844
|
-
.example("$0 get-best-provider --
|
|
845
|
-
const spinner = argv.quiet
|
|
846
|
-
? null
|
|
847
|
-
: ora("🎯 Finding best provider...").start();
|
|
861
|
+
.example("$0 get-best-provider", "Show best provider")
|
|
862
|
+
.example("$0 get-best-provider --format json", "Show in JSON format"), async (argv) => {
|
|
848
863
|
try {
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
864
|
+
const { getBestProvider } = await import("../lib/utils/providerUtils-fixed.js");
|
|
865
|
+
const bestProvider = getBestProvider();
|
|
866
|
+
if (argv.format === "json") {
|
|
867
|
+
process.stdout.write(JSON.stringify({ provider: bestProvider }, null, 2) + "\n");
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
if (!argv.quiet) {
|
|
871
|
+
console.log(chalk.green(`🎯 Best available provider: ${bestProvider}`));
|
|
853
872
|
}
|
|
854
873
|
else {
|
|
855
|
-
|
|
874
|
+
process.stdout.write(bestProvider + "\n");
|
|
856
875
|
}
|
|
857
876
|
}
|
|
858
|
-
if (argv.debug) {
|
|
859
|
-
// Debug mode: Show selection reasoning and metadata
|
|
860
|
-
console.log(`\nBest available provider: ${provider}`);
|
|
861
|
-
console.log(`Selection based on: availability, performance, and configuration`);
|
|
862
|
-
}
|
|
863
|
-
else {
|
|
864
|
-
// Default mode: Clean provider name only
|
|
865
|
-
console.log(provider);
|
|
866
|
-
}
|
|
867
877
|
}
|
|
868
878
|
catch (error) {
|
|
869
|
-
if (spinner && spinner.isSpinning) {
|
|
870
|
-
spinner.fail();
|
|
871
|
-
}
|
|
872
879
|
handleError(error, "Provider selection");
|
|
873
880
|
}
|
|
874
881
|
})
|
|
875
|
-
|
|
876
|
-
|
|
882
|
+
// Completion Command
|
|
883
|
+
.command("completion", "Generate shell completion script", (yargsInstance) => yargsInstance
|
|
884
|
+
.usage("Usage: $0 completion")
|
|
885
|
+
.example("$0 completion >> ~/.bashrc", "Add to bash")
|
|
886
|
+
.example("$0 completion >> ~/.zshrc", "Add to zsh"), async (argv) => {
|
|
887
|
+
cli.showCompletionScript();
|
|
888
|
+
});
|
|
889
|
+
// Add MCP Commands
|
|
877
890
|
addMCPCommands(cli);
|
|
878
|
-
// Add Ollama
|
|
879
|
-
cli
|
|
880
|
-
// Add Agent
|
|
881
|
-
cli
|
|
882
|
-
//
|
|
891
|
+
// Add Ollama Commands
|
|
892
|
+
addOllamaCommands(cli);
|
|
893
|
+
// Add Agent Generate Command
|
|
894
|
+
agentGenerateCommand(cli);
|
|
895
|
+
// Execute CLI
|
|
883
896
|
(async () => {
|
|
884
897
|
try {
|
|
885
|
-
await cli.
|
|
898
|
+
await cli.parse();
|
|
886
899
|
}
|
|
887
900
|
catch (error) {
|
|
888
|
-
//
|
|
889
|
-
|
|
890
|
-
// handleError is not called here because .fail() or command handlers should have already done so.
|
|
891
|
-
// If an error reaches here, it's likely an unhandled exception not caught by yargs.
|
|
892
|
-
if (error instanceof Error) {
|
|
893
|
-
console.error(chalk.red(`Unhandled CLI Error: ${error.message}`));
|
|
894
|
-
}
|
|
895
|
-
else {
|
|
896
|
-
console.error(chalk.red(`Unhandled CLI Error: ${String(error)}`));
|
|
897
|
-
}
|
|
901
|
+
// Global error handler - should not reach here due to fail() handler
|
|
902
|
+
process.stderr.write(chalk.red(`Unexpected CLI error: ${error.message}\n`));
|
|
898
903
|
process.exit(1);
|
|
899
904
|
}
|
|
900
905
|
})();
|