@juspay/neurolink 7.29.1 → 7.29.3
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 +12 -0
- package/dist/cli/commands/config.d.ts +86 -86
- package/dist/cli/commands/mcp.js +64 -9
- package/dist/cli/commands/models.js +25 -21
- package/dist/cli/commands/ollama.js +2 -2
- package/dist/cli/factories/commandFactory.d.ts +9 -0
- package/dist/cli/factories/commandFactory.js +177 -83
- package/dist/cli/factories/ollamaCommandFactory.js +3 -1
- package/dist/cli/factories/sagemakerCommandFactory.js +3 -2
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +19 -11
- package/dist/cli/utils/envManager.js +5 -5
- package/dist/cli/utils/ollamaUtils.d.ts +12 -0
- package/dist/cli/utils/ollamaUtils.js +58 -42
- package/dist/config/configManager.js +5 -2
- package/dist/core/analytics.d.ts +2 -24
- package/dist/core/analytics.js +12 -17
- package/dist/core/baseProvider.d.ts +30 -1
- package/dist/core/baseProvider.js +180 -198
- package/dist/core/dynamicModels.d.ts +4 -4
- package/dist/core/dynamicModels.js +7 -7
- package/dist/core/evaluation.d.ts +9 -9
- package/dist/core/evaluation.js +117 -65
- package/dist/core/evaluationProviders.d.ts +18 -2
- package/dist/core/evaluationProviders.js +15 -13
- package/dist/core/factory.js +77 -4
- package/dist/core/modelConfiguration.d.ts +63 -0
- package/dist/core/modelConfiguration.js +354 -290
- package/dist/core/streamAnalytics.d.ts +10 -5
- package/dist/core/streamAnalytics.js +10 -10
- package/dist/core/types.d.ts +19 -109
- package/dist/core/types.js +13 -0
- package/dist/factories/providerFactory.js +4 -1
- package/dist/factories/providerRegistry.js +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/lib/config/configManager.js +5 -2
- package/dist/lib/core/analytics.d.ts +2 -24
- package/dist/lib/core/analytics.js +12 -17
- package/dist/lib/core/baseProvider.d.ts +30 -1
- package/dist/lib/core/baseProvider.js +180 -198
- package/dist/lib/core/dynamicModels.js +7 -7
- package/dist/lib/core/evaluation.d.ts +9 -9
- package/dist/lib/core/evaluation.js +117 -65
- package/dist/lib/core/evaluationProviders.d.ts +18 -2
- package/dist/lib/core/evaluationProviders.js +15 -13
- package/dist/lib/core/factory.js +77 -4
- package/dist/lib/core/modelConfiguration.d.ts +63 -0
- package/dist/lib/core/modelConfiguration.js +354 -290
- package/dist/lib/core/streamAnalytics.d.ts +10 -5
- package/dist/lib/core/streamAnalytics.js +10 -10
- package/dist/lib/core/types.d.ts +19 -109
- package/dist/lib/core/types.js +13 -0
- package/dist/lib/factories/providerFactory.js +4 -1
- package/dist/lib/factories/providerRegistry.js +2 -2
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/mcp/externalServerManager.js +14 -6
- package/dist/lib/mcp/factory.js +1 -1
- package/dist/lib/mcp/flexibleToolValidator.d.ts +50 -0
- package/dist/lib/mcp/flexibleToolValidator.js +161 -0
- package/dist/lib/mcp/index.d.ts +1 -1
- package/dist/lib/mcp/index.js +1 -1
- package/dist/lib/mcp/mcpCircuitBreaker.js +5 -1
- package/dist/lib/mcp/mcpClientFactory.js +3 -0
- package/dist/lib/mcp/registry.d.ts +3 -3
- package/dist/lib/mcp/registry.js +3 -3
- package/dist/lib/mcp/servers/aiProviders/aiAnalysisTools.js +5 -5
- package/dist/lib/mcp/servers/aiProviders/aiWorkflowTools.js +6 -6
- package/dist/lib/mcp/servers/utilities/utilityServer.js +1 -1
- package/dist/lib/mcp/toolDiscoveryService.js +8 -2
- package/dist/lib/mcp/toolRegistry.d.ts +2 -2
- package/dist/lib/mcp/toolRegistry.js +29 -54
- package/dist/lib/middleware/builtin/analytics.js +4 -4
- package/dist/lib/middleware/builtin/guardrails.js +2 -2
- package/dist/lib/middleware/registry.js +11 -2
- package/dist/lib/models/modelRegistry.d.ts +1 -1
- package/dist/lib/models/modelRegistry.js +3 -3
- package/dist/lib/models/modelResolver.d.ts +1 -1
- package/dist/lib/models/modelResolver.js +2 -2
- package/dist/lib/neurolink.d.ts +118 -0
- package/dist/lib/neurolink.js +814 -952
- package/dist/lib/providers/amazonBedrock.d.ts +47 -6
- package/dist/lib/providers/amazonBedrock.js +282 -23
- package/dist/lib/providers/amazonSagemaker.d.ts +1 -1
- package/dist/lib/providers/amazonSagemaker.js +12 -3
- package/dist/lib/providers/anthropic.d.ts +1 -1
- package/dist/lib/providers/anthropic.js +7 -6
- package/dist/lib/providers/anthropicBaseProvider.d.ts +1 -1
- package/dist/lib/providers/anthropicBaseProvider.js +4 -3
- package/dist/lib/providers/aws/credentialProvider.d.ts +58 -0
- package/dist/lib/providers/aws/credentialProvider.js +267 -0
- package/dist/lib/providers/aws/credentialTester.d.ts +49 -0
- package/dist/lib/providers/aws/credentialTester.js +394 -0
- package/dist/lib/providers/azureOpenai.d.ts +1 -1
- package/dist/lib/providers/azureOpenai.js +1 -1
- package/dist/lib/providers/googleAiStudio.d.ts +1 -1
- package/dist/lib/providers/googleAiStudio.js +2 -2
- package/dist/lib/providers/googleVertex.d.ts +40 -0
- package/dist/lib/providers/googleVertex.js +330 -274
- package/dist/lib/providers/huggingFace.js +1 -1
- package/dist/lib/providers/mistral.d.ts +1 -1
- package/dist/lib/providers/mistral.js +2 -2
- package/dist/lib/providers/ollama.d.ts +4 -0
- package/dist/lib/providers/ollama.js +38 -18
- package/dist/lib/providers/openAI.d.ts +1 -1
- package/dist/lib/providers/openAI.js +2 -2
- package/dist/lib/providers/sagemaker/adaptive-semaphore.js +7 -4
- package/dist/lib/providers/sagemaker/client.js +13 -3
- package/dist/lib/providers/sagemaker/config.js +5 -1
- package/dist/lib/providers/sagemaker/detection.js +19 -9
- package/dist/lib/providers/sagemaker/errors.d.ts +8 -1
- package/dist/lib/providers/sagemaker/errors.js +103 -20
- package/dist/lib/providers/sagemaker/language-model.d.ts +3 -3
- package/dist/lib/providers/sagemaker/language-model.js +4 -4
- package/dist/lib/providers/sagemaker/parsers.js +14 -6
- package/dist/lib/providers/sagemaker/streaming.js +14 -3
- package/dist/lib/providers/sagemaker/types.d.ts +1 -1
- package/dist/lib/proxy/awsProxyIntegration.d.ts +23 -0
- package/dist/lib/proxy/awsProxyIntegration.js +285 -0
- package/dist/lib/proxy/proxyFetch.d.ts +9 -5
- package/dist/lib/proxy/proxyFetch.js +232 -98
- package/dist/lib/proxy/utils/noProxyUtils.d.ts +39 -0
- package/dist/lib/proxy/utils/noProxyUtils.js +149 -0
- package/dist/lib/sdk/toolRegistration.d.ts +1 -1
- package/dist/lib/types/cli.d.ts +80 -8
- package/dist/lib/types/contextTypes.js +2 -2
- package/dist/lib/types/generateTypes.d.ts +4 -6
- package/dist/lib/types/providers.d.ts +124 -19
- package/dist/lib/types/providers.js +6 -6
- package/dist/lib/types/streamTypes.d.ts +4 -6
- package/dist/lib/types/typeAliases.d.ts +1 -1
- package/dist/lib/utils/analyticsUtils.d.ts +33 -0
- package/dist/lib/utils/analyticsUtils.js +76 -0
- package/dist/lib/utils/errorHandling.js +4 -1
- package/dist/lib/utils/evaluationUtils.d.ts +27 -0
- package/dist/lib/utils/evaluationUtils.js +131 -0
- package/dist/lib/utils/optionsUtils.js +10 -1
- package/dist/lib/utils/performance.d.ts +1 -1
- package/dist/lib/utils/performance.js +15 -3
- package/dist/lib/utils/providerConfig.d.ts +1 -0
- package/dist/lib/utils/providerConfig.js +2 -1
- package/dist/lib/utils/providerHealth.d.ts +48 -0
- package/dist/lib/utils/providerHealth.js +221 -158
- package/dist/lib/utils/providerUtils.js +2 -2
- package/dist/lib/utils/timeout.js +8 -3
- package/dist/mcp/externalServerManager.js +14 -6
- package/dist/mcp/factory.js +1 -1
- package/dist/mcp/flexibleToolValidator.d.ts +50 -0
- package/dist/mcp/flexibleToolValidator.js +161 -0
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/mcpCircuitBreaker.js +5 -1
- package/dist/mcp/mcpClientFactory.js +3 -0
- package/dist/mcp/registry.d.ts +3 -3
- package/dist/mcp/registry.js +3 -3
- package/dist/mcp/servers/aiProviders/aiAnalysisTools.js +5 -5
- package/dist/mcp/servers/aiProviders/aiWorkflowTools.js +6 -6
- package/dist/mcp/servers/utilities/utilityServer.js +1 -1
- package/dist/mcp/toolDiscoveryService.js +8 -2
- package/dist/mcp/toolRegistry.d.ts +2 -2
- package/dist/mcp/toolRegistry.js +29 -54
- package/dist/middleware/builtin/analytics.js +4 -4
- package/dist/middleware/builtin/guardrails.js +2 -2
- package/dist/middleware/registry.js +11 -2
- package/dist/models/modelRegistry.d.ts +1 -1
- package/dist/models/modelRegistry.js +3 -3
- package/dist/models/modelResolver.d.ts +1 -1
- package/dist/models/modelResolver.js +2 -2
- package/dist/neurolink.d.ts +118 -0
- package/dist/neurolink.js +814 -952
- package/dist/providers/amazonBedrock.d.ts +47 -6
- package/dist/providers/amazonBedrock.js +282 -23
- package/dist/providers/amazonSagemaker.d.ts +1 -1
- package/dist/providers/amazonSagemaker.js +12 -3
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/anthropic.js +7 -6
- package/dist/providers/anthropicBaseProvider.d.ts +1 -1
- package/dist/providers/anthropicBaseProvider.js +4 -3
- package/dist/providers/aws/credentialProvider.d.ts +58 -0
- package/dist/providers/aws/credentialProvider.js +267 -0
- package/dist/providers/aws/credentialTester.d.ts +49 -0
- package/dist/providers/aws/credentialTester.js +394 -0
- package/dist/providers/azureOpenai.d.ts +1 -1
- package/dist/providers/azureOpenai.js +1 -1
- package/dist/providers/googleAiStudio.d.ts +1 -1
- package/dist/providers/googleAiStudio.js +2 -2
- package/dist/providers/googleVertex.d.ts +40 -0
- package/dist/providers/googleVertex.js +330 -274
- package/dist/providers/huggingFace.js +1 -1
- package/dist/providers/mistral.d.ts +1 -1
- package/dist/providers/mistral.js +2 -2
- package/dist/providers/ollama.d.ts +4 -0
- package/dist/providers/ollama.js +38 -18
- package/dist/providers/openAI.d.ts +1 -1
- package/dist/providers/openAI.js +2 -2
- package/dist/providers/sagemaker/adaptive-semaphore.js +7 -4
- package/dist/providers/sagemaker/client.js +13 -3
- package/dist/providers/sagemaker/config.js +5 -1
- package/dist/providers/sagemaker/detection.js +19 -9
- package/dist/providers/sagemaker/errors.d.ts +8 -1
- package/dist/providers/sagemaker/errors.js +103 -20
- package/dist/providers/sagemaker/language-model.d.ts +3 -3
- package/dist/providers/sagemaker/language-model.js +4 -4
- package/dist/providers/sagemaker/parsers.js +14 -6
- package/dist/providers/sagemaker/streaming.js +14 -3
- package/dist/providers/sagemaker/types.d.ts +1 -1
- package/dist/proxy/awsProxyIntegration.d.ts +23 -0
- package/dist/proxy/awsProxyIntegration.js +285 -0
- package/dist/proxy/proxyFetch.d.ts +9 -5
- package/dist/proxy/proxyFetch.js +232 -98
- package/dist/proxy/utils/noProxyUtils.d.ts +39 -0
- package/dist/proxy/utils/noProxyUtils.js +149 -0
- package/dist/sdk/toolRegistration.d.ts +1 -1
- package/dist/types/cli.d.ts +80 -8
- package/dist/types/contextTypes.js +2 -2
- package/dist/types/generateTypes.d.ts +4 -6
- package/dist/types/providers.d.ts +124 -19
- package/dist/types/providers.js +6 -6
- package/dist/types/streamTypes.d.ts +4 -6
- package/dist/types/typeAliases.d.ts +1 -1
- package/dist/utils/analyticsUtils.d.ts +33 -0
- package/dist/utils/analyticsUtils.js +76 -0
- package/dist/utils/errorHandling.js +4 -1
- package/dist/utils/evaluationUtils.d.ts +27 -0
- package/dist/utils/evaluationUtils.js +131 -0
- package/dist/utils/optionsUtils.js +10 -1
- package/dist/utils/performance.d.ts +1 -1
- package/dist/utils/performance.js +15 -3
- package/dist/utils/providerConfig.d.ts +1 -0
- package/dist/utils/providerConfig.js +2 -1
- package/dist/utils/providerHealth.d.ts +48 -0
- package/dist/utils/providerHealth.js +221 -158
- package/dist/utils/providerUtils.js +2 -2
- package/dist/utils/timeout.js +8 -3
- package/package.json +5 -1
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { NeuroLink } from "../../lib/neurolink.js";
|
|
2
2
|
import { configManager } from "../commands/config.js";
|
|
3
|
+
import { handleError } from "../index.js";
|
|
4
|
+
import { normalizeEvaluationData } from "../../lib/utils/evaluationUtils.js";
|
|
5
|
+
// Use TokenUsage from standard types - no local interface needed
|
|
3
6
|
import { ContextFactory, } from "../../lib/types/contextTypes.js";
|
|
4
7
|
import { ModelsCommandFactory } from "../commands/models.js";
|
|
5
8
|
import { MCPCommandFactory } from "../commands/mcp.js";
|
|
@@ -9,6 +12,7 @@ import ora from "ora";
|
|
|
9
12
|
import chalk from "chalk";
|
|
10
13
|
import { logger } from "../../lib/utils/logger.js";
|
|
11
14
|
import fs from "fs";
|
|
15
|
+
// Use specific command interfaces from cli.ts instead of universal interface
|
|
12
16
|
/**
|
|
13
17
|
* CLI Command Factory for generate commands
|
|
14
18
|
*/
|
|
@@ -209,7 +213,9 @@ export class CLICommandFactory {
|
|
|
209
213
|
}
|
|
210
214
|
}
|
|
211
215
|
return {
|
|
212
|
-
provider: argv.provider === "auto"
|
|
216
|
+
provider: argv.provider === "auto"
|
|
217
|
+
? undefined
|
|
218
|
+
: argv.provider,
|
|
213
219
|
model: argv.model,
|
|
214
220
|
temperature: argv.temperature,
|
|
215
221
|
maxTokens: argv.maxTokens,
|
|
@@ -273,14 +279,53 @@ export class CLICommandFactory {
|
|
|
273
279
|
logger.always(output);
|
|
274
280
|
}
|
|
275
281
|
}
|
|
276
|
-
// Helper method to validate token usage data
|
|
282
|
+
// Helper method to validate token usage data with fallback handling
|
|
277
283
|
static isValidTokenUsage(tokens) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
+
if (!tokens || typeof tokens !== "object" || tokens === null) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
const tokensObj = tokens;
|
|
288
|
+
// Check primary format: analytics.tokens {input, output, total}
|
|
289
|
+
if (typeof tokensObj.input === "number" &&
|
|
290
|
+
typeof tokensObj.output === "number" &&
|
|
291
|
+
typeof tokensObj.total === "number") {
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
// Check fallback format: tokenUsage {inputTokens, outputTokens, totalTokens}
|
|
295
|
+
if (typeof tokensObj.inputTokens === "number" &&
|
|
296
|
+
typeof tokensObj.outputTokens === "number" &&
|
|
297
|
+
typeof tokensObj.totalTokens === "number") {
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
// Helper method to normalize token usage data to standard format
|
|
303
|
+
static normalizeTokenUsage(tokens) {
|
|
304
|
+
if (!this.isValidTokenUsage(tokens)) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
const tokensObj = tokens;
|
|
308
|
+
// Primary format: analytics.tokens {input, output, total}
|
|
309
|
+
if (typeof tokensObj.input === "number" &&
|
|
310
|
+
typeof tokensObj.output === "number" &&
|
|
311
|
+
typeof tokensObj.total === "number") {
|
|
312
|
+
return {
|
|
313
|
+
input: tokensObj.input,
|
|
314
|
+
output: tokensObj.output,
|
|
315
|
+
total: tokensObj.total,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
// Fallback format: tokenUsage {inputTokens, outputTokens, totalTokens}
|
|
319
|
+
if (typeof tokensObj.inputTokens === "number" &&
|
|
320
|
+
typeof tokensObj.outputTokens === "number" &&
|
|
321
|
+
typeof tokensObj.totalTokens === "number") {
|
|
322
|
+
return {
|
|
323
|
+
input: tokensObj.inputTokens,
|
|
324
|
+
output: tokensObj.outputTokens,
|
|
325
|
+
total: tokensObj.totalTokens,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
return null;
|
|
284
329
|
}
|
|
285
330
|
// Helper method to format analytics for text mode display
|
|
286
331
|
static formatAnalyticsForTextMode(result) {
|
|
@@ -299,10 +344,10 @@ export class CLICommandFactory {
|
|
|
299
344
|
analyticsText += ` (${modelName})`;
|
|
300
345
|
}
|
|
301
346
|
analyticsText += "\n";
|
|
302
|
-
// Token usage
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
analyticsText += ` Tokens: ${
|
|
347
|
+
// Token usage with fallback handling
|
|
348
|
+
const normalizedTokens = this.normalizeTokenUsage(analytics.tokenUsage);
|
|
349
|
+
if (normalizedTokens) {
|
|
350
|
+
analyticsText += ` Tokens: ${normalizedTokens.input} input + ${normalizedTokens.output} output = ${normalizedTokens.total} total\n`;
|
|
306
351
|
}
|
|
307
352
|
// Cost information
|
|
308
353
|
if (analytics.cost !== undefined &&
|
|
@@ -310,9 +355,12 @@ export class CLICommandFactory {
|
|
|
310
355
|
typeof analytics.cost === "number") {
|
|
311
356
|
analyticsText += ` Cost: $${analytics.cost.toFixed(5)}\n`;
|
|
312
357
|
}
|
|
313
|
-
// Response time
|
|
314
|
-
|
|
315
|
-
|
|
358
|
+
// Response time with fallback handling for requestDuration vs responseTime
|
|
359
|
+
const duration = analytics.requestDuration ||
|
|
360
|
+
analytics.responseTime ||
|
|
361
|
+
analytics.duration;
|
|
362
|
+
if (duration && typeof duration === "number") {
|
|
363
|
+
const timeInSeconds = (duration / 1000).toFixed(1);
|
|
316
364
|
analyticsText += ` Time: ${timeInSeconds}s\n`;
|
|
317
365
|
}
|
|
318
366
|
// Tools used
|
|
@@ -561,21 +609,21 @@ export class CLICommandFactory {
|
|
|
561
609
|
provider: "google-ai",
|
|
562
610
|
status: "working",
|
|
563
611
|
configured: true,
|
|
564
|
-
|
|
612
|
+
requestDuration: 150,
|
|
565
613
|
model: "gemini-2.5-flash",
|
|
566
614
|
},
|
|
567
615
|
{
|
|
568
616
|
provider: "openai",
|
|
569
617
|
status: "working",
|
|
570
618
|
configured: true,
|
|
571
|
-
|
|
619
|
+
requestDuration: 200,
|
|
572
620
|
model: "gpt-4o-mini",
|
|
573
621
|
},
|
|
574
622
|
{
|
|
575
623
|
provider: "anthropic",
|
|
576
624
|
status: "working",
|
|
577
625
|
configured: true,
|
|
578
|
-
|
|
626
|
+
requestDuration: 180,
|
|
579
627
|
model: "claude-3-haiku",
|
|
580
628
|
},
|
|
581
629
|
{ provider: "bedrock", status: "not configured", configured: false },
|
|
@@ -591,7 +639,9 @@ export class CLICommandFactory {
|
|
|
591
639
|
: result.status === "failed"
|
|
592
640
|
? chalk.red("❌ Failed")
|
|
593
641
|
: chalk.gray("⚪ Not configured");
|
|
594
|
-
const time = result.
|
|
642
|
+
const time = result.requestDuration
|
|
643
|
+
? ` (${result.requestDuration}ms)`
|
|
644
|
+
: "";
|
|
595
645
|
const model = result.model ? ` [${result.model}]` : "";
|
|
596
646
|
logger.always(`${result.provider}: ${status}${time}${model}`);
|
|
597
647
|
}
|
|
@@ -692,33 +742,31 @@ export class CLICommandFactory {
|
|
|
692
742
|
provider: options.provider || "auto",
|
|
693
743
|
model: options.model || "test-model",
|
|
694
744
|
usage: {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
745
|
+
input: 10,
|
|
746
|
+
output: 15,
|
|
747
|
+
total: 25,
|
|
698
748
|
},
|
|
699
749
|
responseTime: 150,
|
|
700
750
|
analytics: options.enableAnalytics
|
|
701
751
|
? {
|
|
702
752
|
provider: options.provider || "auto",
|
|
703
753
|
model: options.model || "test-model",
|
|
704
|
-
|
|
754
|
+
tokenUsage: { input: 10, output: 15, total: 25 },
|
|
705
755
|
cost: 0.00025,
|
|
706
|
-
|
|
756
|
+
requestDuration: 150,
|
|
707
757
|
context: contextMetadata,
|
|
708
758
|
}
|
|
709
759
|
: undefined,
|
|
710
760
|
evaluation: options.enableEvaluation
|
|
711
|
-
? {
|
|
761
|
+
? normalizeEvaluationData({
|
|
712
762
|
relevance: 8,
|
|
713
763
|
accuracy: 9,
|
|
714
764
|
completeness: 8,
|
|
715
765
|
overall: 8.3,
|
|
716
|
-
isOffTopic: false,
|
|
717
|
-
alertSeverity: "none",
|
|
718
766
|
reasoning: "Test evaluation response",
|
|
719
767
|
evaluationModel: "test-evaluator",
|
|
720
768
|
evaluationTime: 50,
|
|
721
|
-
}
|
|
769
|
+
})
|
|
722
770
|
: undefined,
|
|
723
771
|
};
|
|
724
772
|
if (spinner) {
|
|
@@ -732,7 +780,6 @@ export class CLICommandFactory {
|
|
|
732
780
|
logger.debug("Mode: DRY-RUN (no actual API calls made)");
|
|
733
781
|
}
|
|
734
782
|
process.exit(0);
|
|
735
|
-
return;
|
|
736
783
|
}
|
|
737
784
|
const sdk = new NeuroLink();
|
|
738
785
|
if (options.debug) {
|
|
@@ -785,18 +832,36 @@ export class CLICommandFactory {
|
|
|
785
832
|
if (spinner) {
|
|
786
833
|
spinner.fail();
|
|
787
834
|
}
|
|
788
|
-
|
|
789
|
-
if (options.debug) {
|
|
790
|
-
logger.error(chalk.gray(error.stack));
|
|
791
|
-
}
|
|
792
|
-
process.exit(1);
|
|
835
|
+
handleError(error, "Generation");
|
|
793
836
|
}
|
|
794
837
|
}
|
|
795
838
|
/**
|
|
796
|
-
*
|
|
839
|
+
* Log debug information for stream result
|
|
797
840
|
*/
|
|
798
|
-
static async
|
|
799
|
-
|
|
841
|
+
static async logStreamDebugInfo(stream) {
|
|
842
|
+
logger.debug("\n" + chalk.yellow("Debug Information (Streaming):"));
|
|
843
|
+
logger.debug("Provider:", stream.provider);
|
|
844
|
+
logger.debug("Model:", stream.model);
|
|
845
|
+
if (stream.analytics) {
|
|
846
|
+
const resolvedAnalytics = await (stream.analytics instanceof Promise
|
|
847
|
+
? stream.analytics
|
|
848
|
+
: Promise.resolve(stream.analytics));
|
|
849
|
+
logger.debug("Analytics:", JSON.stringify(resolvedAnalytics, null, 2));
|
|
850
|
+
}
|
|
851
|
+
if (stream.evaluation) {
|
|
852
|
+
const resolvedEvaluation = await (stream.evaluation instanceof Promise
|
|
853
|
+
? stream.evaluation
|
|
854
|
+
: Promise.resolve(stream.evaluation));
|
|
855
|
+
logger.debug("Evaluation:", JSON.stringify(resolvedEvaluation, null, 2));
|
|
856
|
+
}
|
|
857
|
+
if (stream.metadata) {
|
|
858
|
+
logger.debug("Metadata:", JSON.stringify(stream.metadata, null, 2));
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Handle stdin input for stream command
|
|
863
|
+
*/
|
|
864
|
+
static async handleStdinInput(argv) {
|
|
800
865
|
if (!argv.input && !process.stdin.isTTY) {
|
|
801
866
|
let stdinData = "";
|
|
802
867
|
process.stdin.setEncoding("utf8");
|
|
@@ -811,6 +876,12 @@ export class CLICommandFactory {
|
|
|
811
876
|
else if (!argv.input) {
|
|
812
877
|
throw new Error('Input required. Use: neurolink stream "your prompt" or echo "prompt" | neurolink stream');
|
|
813
878
|
}
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Execute the stream command
|
|
882
|
+
*/
|
|
883
|
+
static async executeStream(argv) {
|
|
884
|
+
await this.handleStdinInput(argv);
|
|
814
885
|
const options = this.processOptions(argv);
|
|
815
886
|
if (!options.quiet) {
|
|
816
887
|
logger.always(chalk.blue("🔄 Streaming..."));
|
|
@@ -873,11 +944,11 @@ export class CLICommandFactory {
|
|
|
873
944
|
model: options.model || "test-model",
|
|
874
945
|
requestDuration: 300,
|
|
875
946
|
tokenUsage: {
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
947
|
+
input: 10,
|
|
948
|
+
output: 15,
|
|
949
|
+
total: 25,
|
|
879
950
|
},
|
|
880
|
-
timestamp: Date.
|
|
951
|
+
timestamp: new Date().toISOString(),
|
|
881
952
|
context: contextMetadata,
|
|
882
953
|
};
|
|
883
954
|
const mockGenerateResult = {
|
|
@@ -911,7 +982,6 @@ export class CLICommandFactory {
|
|
|
911
982
|
logger.debug("Mode: DRY-RUN (no actual API calls made)");
|
|
912
983
|
}
|
|
913
984
|
process.exit(0);
|
|
914
|
-
return;
|
|
915
985
|
}
|
|
916
986
|
const sdk = new NeuroLink();
|
|
917
987
|
const stream = await sdk.stream({
|
|
@@ -935,14 +1005,66 @@ export class CLICommandFactory {
|
|
|
935
1005
|
: undefined,
|
|
936
1006
|
});
|
|
937
1007
|
let fullContent = "";
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1008
|
+
let contentReceived = false;
|
|
1009
|
+
const abortController = new AbortController();
|
|
1010
|
+
// Create timeout promise for stream consumption (30 seconds)
|
|
1011
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1012
|
+
const timeoutId = setTimeout(() => {
|
|
1013
|
+
if (!contentReceived) {
|
|
1014
|
+
const timeoutError = new Error("\n❌ Stream timeout - no content received within 30 seconds\n" +
|
|
1015
|
+
"This usually indicates authentication or network issues\n\n" +
|
|
1016
|
+
"🔧 Try these steps:\n" +
|
|
1017
|
+
"1. Check your provider credentials are configured correctly\n" +
|
|
1018
|
+
`2. Test generate mode: neurolink generate "test" --provider ${options.provider}\n` +
|
|
1019
|
+
`3. Use debug mode: neurolink stream "test" --provider ${options.provider} --debug`);
|
|
1020
|
+
reject(timeoutError);
|
|
1021
|
+
}
|
|
1022
|
+
}, 30000);
|
|
1023
|
+
// Clean up timeout when aborted
|
|
1024
|
+
abortController.signal.addEventListener("abort", () => {
|
|
1025
|
+
clearTimeout(timeoutId);
|
|
1026
|
+
});
|
|
1027
|
+
});
|
|
1028
|
+
try {
|
|
1029
|
+
// Process the stream with timeout handling
|
|
1030
|
+
const streamIterator = stream.stream[Symbol.asyncIterator]();
|
|
1031
|
+
let timeoutActive = true;
|
|
1032
|
+
while (true) {
|
|
1033
|
+
let nextResult;
|
|
1034
|
+
if (timeoutActive && !contentReceived) {
|
|
1035
|
+
// Race between next chunk and timeout for first chunk only
|
|
1036
|
+
nextResult = await Promise.race([
|
|
1037
|
+
streamIterator.next(),
|
|
1038
|
+
timeoutPromise,
|
|
1039
|
+
]);
|
|
1040
|
+
}
|
|
1041
|
+
else {
|
|
1042
|
+
// No timeout for subsequent chunks
|
|
1043
|
+
nextResult = await streamIterator.next();
|
|
1044
|
+
}
|
|
1045
|
+
if (nextResult.done) {
|
|
1046
|
+
break;
|
|
1047
|
+
}
|
|
1048
|
+
if (!contentReceived) {
|
|
1049
|
+
contentReceived = true;
|
|
1050
|
+
timeoutActive = false;
|
|
1051
|
+
abortController.abort(); // Cancel timeout
|
|
1052
|
+
}
|
|
1053
|
+
if (options.delay && options.delay > 0) {
|
|
1054
|
+
// Demo mode - add delay between chunks
|
|
1055
|
+
await new Promise((resolve) => setTimeout(resolve, options.delay));
|
|
1056
|
+
}
|
|
1057
|
+
process.stdout.write(nextResult.value.content);
|
|
1058
|
+
fullContent += nextResult.value.content;
|
|
943
1059
|
}
|
|
944
|
-
|
|
945
|
-
|
|
1060
|
+
}
|
|
1061
|
+
catch (error) {
|
|
1062
|
+
abortController.abort(); // Clean up timeout
|
|
1063
|
+
throw error;
|
|
1064
|
+
}
|
|
1065
|
+
if (!contentReceived) {
|
|
1066
|
+
throw new Error("\n❌ No content received from stream\n" +
|
|
1067
|
+
"Check your credentials and provider configuration");
|
|
946
1068
|
}
|
|
947
1069
|
if (!options.quiet) {
|
|
948
1070
|
process.stdout.write("\n");
|
|
@@ -985,33 +1107,12 @@ export class CLICommandFactory {
|
|
|
985
1107
|
}
|
|
986
1108
|
// 🔧 NEW: Debug output for streaming (similar to generate command)
|
|
987
1109
|
if (options.debug) {
|
|
988
|
-
|
|
989
|
-
logger.debug("Provider:", stream.provider);
|
|
990
|
-
logger.debug("Model:", stream.model);
|
|
991
|
-
if (stream.analytics) {
|
|
992
|
-
const resolvedAnalytics = await (stream.analytics instanceof Promise
|
|
993
|
-
? stream.analytics
|
|
994
|
-
: Promise.resolve(stream.analytics));
|
|
995
|
-
logger.debug("Analytics:", JSON.stringify(resolvedAnalytics, null, 2));
|
|
996
|
-
}
|
|
997
|
-
if (stream.evaluation) {
|
|
998
|
-
const resolvedEvaluation = await (stream.evaluation instanceof Promise
|
|
999
|
-
? stream.evaluation
|
|
1000
|
-
: Promise.resolve(stream.evaluation));
|
|
1001
|
-
logger.debug("Evaluation:", JSON.stringify(resolvedEvaluation, null, 2));
|
|
1002
|
-
}
|
|
1003
|
-
if (stream.metadata) {
|
|
1004
|
-
logger.debug("Metadata:", JSON.stringify(stream.metadata, null, 2));
|
|
1005
|
-
}
|
|
1110
|
+
await this.logStreamDebugInfo(stream);
|
|
1006
1111
|
}
|
|
1007
1112
|
process.exit(0);
|
|
1008
1113
|
}
|
|
1009
1114
|
catch (error) {
|
|
1010
|
-
|
|
1011
|
-
if (options.debug) {
|
|
1012
|
-
logger.error(chalk.gray(error.stack));
|
|
1013
|
-
}
|
|
1014
|
-
process.exit(1);
|
|
1115
|
+
handleError(error, "Streaming");
|
|
1015
1116
|
}
|
|
1016
1117
|
}
|
|
1017
1118
|
/**
|
|
@@ -1125,11 +1226,7 @@ export class CLICommandFactory {
|
|
|
1125
1226
|
if (spinner) {
|
|
1126
1227
|
spinner.fail();
|
|
1127
1228
|
}
|
|
1128
|
-
|
|
1129
|
-
if (options.debug) {
|
|
1130
|
-
logger.error(chalk.gray(error.stack));
|
|
1131
|
-
}
|
|
1132
|
-
process.exit(1);
|
|
1229
|
+
handleError(error, "Batch processing");
|
|
1133
1230
|
}
|
|
1134
1231
|
}
|
|
1135
1232
|
/**
|
|
@@ -1158,8 +1255,7 @@ export class CLICommandFactory {
|
|
|
1158
1255
|
this.handleOutput(config, options);
|
|
1159
1256
|
}
|
|
1160
1257
|
catch (error) {
|
|
1161
|
-
|
|
1162
|
-
process.exit(1);
|
|
1258
|
+
handleError(error, "Configuration export");
|
|
1163
1259
|
}
|
|
1164
1260
|
}
|
|
1165
1261
|
/**
|
|
@@ -1183,8 +1279,7 @@ export class CLICommandFactory {
|
|
|
1183
1279
|
}
|
|
1184
1280
|
}
|
|
1185
1281
|
catch (error) {
|
|
1186
|
-
|
|
1187
|
-
process.exit(1);
|
|
1282
|
+
handleError(error, "Provider selection");
|
|
1188
1283
|
}
|
|
1189
1284
|
}
|
|
1190
1285
|
/**
|
|
@@ -1323,8 +1418,7 @@ export class CLICommandFactory {
|
|
|
1323
1418
|
}
|
|
1324
1419
|
}
|
|
1325
1420
|
catch (error) {
|
|
1326
|
-
|
|
1327
|
-
process.exit(1);
|
|
1421
|
+
handleError(error, "Completion generation");
|
|
1328
1422
|
}
|
|
1329
1423
|
}
|
|
1330
1424
|
}
|
|
@@ -183,7 +183,9 @@ export class OllamaCommandFactory {
|
|
|
183
183
|
logger.always(chalk.green(`\n${modelsData.models.length} models available`));
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
|
-
catch (
|
|
186
|
+
catch (error) {
|
|
187
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
188
|
+
logger.debug("Error:", errorMessage);
|
|
187
189
|
spinner.fail("Ollama service is not running");
|
|
188
190
|
logger.always(chalk.yellow("\nStart Ollama with: ollama serve"));
|
|
189
191
|
logger.always(chalk.blue("Or restart the Ollama app if using the desktop version"));
|
|
@@ -309,9 +309,10 @@ export class SageMakerCommandFactory {
|
|
|
309
309
|
logger.always(chalk.yellow("No SageMaker endpoints found"));
|
|
310
310
|
}
|
|
311
311
|
}
|
|
312
|
-
catch (
|
|
312
|
+
catch (error) {
|
|
313
313
|
spinner.fail("Failed to list endpoints");
|
|
314
|
-
|
|
314
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
315
|
+
logger.error(chalk.red("Error:", errorMessage));
|
|
315
316
|
logger.always(chalk.yellow("\nTo list endpoints, please:"));
|
|
316
317
|
logger.always("1. Set AWS_ACCESS_KEY_ID environment variable");
|
|
317
318
|
logger.always("2. Set AWS_SECRET_ACCESS_KEY environment variable");
|
package/dist/cli/index.d.ts
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -14,6 +14,14 @@ import { fileURLToPath } from "url";
|
|
|
14
14
|
import { CLICommandFactory } from "./factories/commandFactory.js";
|
|
15
15
|
import { AuthenticationError, AuthorizationError, NetworkError, RateLimitError, } from "../lib/types/errors.js";
|
|
16
16
|
import { logger } from "../lib/utils/logger.js";
|
|
17
|
+
// Clean up pnpm-specific environment variables that cause npm warnings
|
|
18
|
+
// These variables are set by pnpm but cause "Unknown env config" warnings in npm
|
|
19
|
+
if (process.env.npm_config_verify_deps_before_run) {
|
|
20
|
+
delete process.env.npm_config_verify_deps_before_run;
|
|
21
|
+
}
|
|
22
|
+
if (process.env.npm_config__jsr_registry) {
|
|
23
|
+
delete process.env.npm_config__jsr_registry;
|
|
24
|
+
}
|
|
17
25
|
// Get version from package.json
|
|
18
26
|
const __filename = fileURLToPath(import.meta.url);
|
|
19
27
|
const __dirname = path.dirname(__filename);
|
|
@@ -25,14 +33,14 @@ try {
|
|
|
25
33
|
const { config } = await import("dotenv");
|
|
26
34
|
config(); // Load .env from current working directory
|
|
27
35
|
}
|
|
28
|
-
catch
|
|
36
|
+
catch {
|
|
29
37
|
// dotenv is not available (dev dependency only) - this is fine for production
|
|
30
38
|
// Environment variables should be set externally in production
|
|
31
39
|
}
|
|
32
40
|
// Utility Functions (Simple, Zero Maintenance)
|
|
33
|
-
function handleError(
|
|
34
|
-
logger.error(chalk.red(`❌ ${context} failed: ${
|
|
35
|
-
if (
|
|
41
|
+
export function handleError(_error, context) {
|
|
42
|
+
logger.error(chalk.red(`❌ ${context} failed: ${_error.message}`));
|
|
43
|
+
if (_error instanceof AuthenticationError) {
|
|
36
44
|
logger.error(chalk.yellow("💡 Set Google AI Studio API key (RECOMMENDED): export GOOGLE_AI_API_KEY=AIza-..."));
|
|
37
45
|
logger.error(chalk.yellow("💡 Or set OpenAI API key: export OPENAI_API_KEY=sk-..."));
|
|
38
46
|
logger.error(chalk.yellow("💡 Or set AWS Bedrock credentials: export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... AWS_REGION=us-east-1"));
|
|
@@ -40,14 +48,14 @@ function handleError(error, context) {
|
|
|
40
48
|
logger.error(chalk.yellow("💡 Or set Anthropic API key: export ANTHROPIC_API_KEY=sk-ant-..."));
|
|
41
49
|
logger.error(chalk.yellow("💡 Or set Azure OpenAI credentials: export AZURE_OPENAI_API_KEY=... AZURE_OPENAI_ENDPOINT=..."));
|
|
42
50
|
}
|
|
43
|
-
else if (
|
|
51
|
+
else if (_error instanceof RateLimitError) {
|
|
44
52
|
logger.error(chalk.yellow("💡 Try again in a few moments or use --provider vertex"));
|
|
45
53
|
}
|
|
46
|
-
else if (
|
|
54
|
+
else if (_error instanceof AuthorizationError) {
|
|
47
55
|
logger.error(chalk.yellow("💡 Check your account permissions for the selected model/service."));
|
|
48
56
|
logger.error(chalk.yellow("💡 For AWS Bedrock, ensure you have permissions for the specific model and consider using inference profile ARNs."));
|
|
49
57
|
}
|
|
50
|
-
else if (
|
|
58
|
+
else if (_error instanceof NetworkError) {
|
|
51
59
|
logger.error(chalk.yellow("💡 Check your internet connection and the provider's status page."));
|
|
52
60
|
}
|
|
53
61
|
process.exit(1);
|
|
@@ -97,9 +105,9 @@ const cli = yargs(args)
|
|
|
97
105
|
}
|
|
98
106
|
};
|
|
99
107
|
if (err) {
|
|
100
|
-
// Error likely from an async command handler (e.g., via
|
|
101
|
-
//
|
|
102
|
-
// If we're here, it means
|
|
108
|
+
// Error likely from an async command handler (e.g., via _handleError)
|
|
109
|
+
// _handleError already prints and calls process.exit(1).
|
|
110
|
+
// If we're here, it means _handleError's process.exit might not have been caught by the top-level async IIFE.
|
|
103
111
|
// Or, it's a synchronous yargs error during parsing that yargs itself throws.
|
|
104
112
|
const alreadyExitedByHandleError = err?.exitCode !== undefined;
|
|
105
113
|
// A simple heuristic: if the error message doesn't look like one of our handled generic messages,
|
|
@@ -189,7 +197,7 @@ const cli = yargs(args)
|
|
|
189
197
|
}
|
|
190
198
|
catch (error) {
|
|
191
199
|
// Global error handler - should not reach here due to fail() handler
|
|
192
|
-
process.stderr.write(chalk.red(`Unexpected CLI
|
|
200
|
+
process.stderr.write(chalk.red(`Unexpected CLI _error: ${error.message}\n`));
|
|
193
201
|
process.exit(1);
|
|
194
202
|
}
|
|
195
203
|
})();
|
|
@@ -61,7 +61,7 @@ export function parseEnvFile(content) {
|
|
|
61
61
|
*/
|
|
62
62
|
export function generateEnvContent(envVars, existingContent) {
|
|
63
63
|
const lines = [];
|
|
64
|
-
const
|
|
64
|
+
const _existingVars = existingContent ? parseEnvFile(existingContent) : {};
|
|
65
65
|
const processedKeys = new Set();
|
|
66
66
|
// If we have existing content, preserve its structure and comments
|
|
67
67
|
if (existingContent) {
|
|
@@ -121,15 +121,15 @@ export function updateEnvFile(newVars, envPath = ".env", createBackup = true) {
|
|
|
121
121
|
}
|
|
122
122
|
// Read existing content
|
|
123
123
|
let existingContent = "";
|
|
124
|
-
let
|
|
124
|
+
let _existingVars = {};
|
|
125
125
|
if (fs.existsSync(envPath)) {
|
|
126
126
|
existingContent = fs.readFileSync(envPath, "utf8");
|
|
127
|
-
|
|
127
|
+
_existingVars = parseEnvFile(existingContent);
|
|
128
128
|
}
|
|
129
129
|
// Categorize changes
|
|
130
130
|
for (const [key, value] of Object.entries(newVars)) {
|
|
131
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
132
|
-
if (
|
|
131
|
+
if (Object.prototype.hasOwnProperty.call(_existingVars, key)) {
|
|
132
|
+
if (_existingVars[key] !== value) {
|
|
133
133
|
result.updated.push(key);
|
|
134
134
|
}
|
|
135
135
|
else {
|
|
@@ -8,6 +8,18 @@ export declare class OllamaUtils {
|
|
|
8
8
|
* Secure wrapper around spawnSync to prevent command injection.
|
|
9
9
|
*/
|
|
10
10
|
static safeSpawn(command: AllowedCommand, args: string[], options?: SpawnSyncOptions): SpawnSyncReturns<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Check if Ollama command line is available
|
|
13
|
+
*/
|
|
14
|
+
private static isOllamaCommandReady;
|
|
15
|
+
/**
|
|
16
|
+
* Validate HTTP API response from Ollama
|
|
17
|
+
*/
|
|
18
|
+
private static validateApiResponse;
|
|
19
|
+
/**
|
|
20
|
+
* Check if Ollama HTTP API is ready
|
|
21
|
+
*/
|
|
22
|
+
private static isOllamaApiReady;
|
|
11
23
|
/**
|
|
12
24
|
* Wait for Ollama service to become ready with exponential backoff
|
|
13
25
|
*/
|