@juspay/neurolink 7.29.2 → 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.
Files changed (198) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cli/commands/config.d.ts +83 -83
  3. package/dist/cli/commands/mcp.js +39 -9
  4. package/dist/cli/commands/models.js +25 -21
  5. package/dist/cli/commands/ollama.js +2 -2
  6. package/dist/cli/factories/commandFactory.d.ts +8 -0
  7. package/dist/cli/factories/commandFactory.js +65 -65
  8. package/dist/cli/factories/ollamaCommandFactory.js +3 -1
  9. package/dist/cli/factories/sagemakerCommandFactory.js +3 -2
  10. package/dist/cli/index.d.ts +1 -1
  11. package/dist/cli/index.js +11 -11
  12. package/dist/cli/utils/envManager.js +5 -5
  13. package/dist/cli/utils/ollamaUtils.d.ts +12 -0
  14. package/dist/cli/utils/ollamaUtils.js +58 -42
  15. package/dist/config/configManager.js +5 -2
  16. package/dist/core/analytics.d.ts +2 -24
  17. package/dist/core/analytics.js +12 -17
  18. package/dist/core/baseProvider.d.ts +30 -1
  19. package/dist/core/baseProvider.js +180 -198
  20. package/dist/core/dynamicModels.d.ts +4 -4
  21. package/dist/core/dynamicModels.js +7 -7
  22. package/dist/core/evaluation.d.ts +9 -9
  23. package/dist/core/evaluation.js +117 -65
  24. package/dist/core/evaluationProviders.d.ts +18 -2
  25. package/dist/core/evaluationProviders.js +15 -13
  26. package/dist/core/modelConfiguration.d.ts +63 -0
  27. package/dist/core/modelConfiguration.js +354 -290
  28. package/dist/core/streamAnalytics.d.ts +10 -5
  29. package/dist/core/streamAnalytics.js +10 -10
  30. package/dist/core/types.d.ts +19 -109
  31. package/dist/core/types.js +13 -0
  32. package/dist/factories/providerFactory.js +1 -1
  33. package/dist/index.d.ts +2 -1
  34. package/dist/lib/config/configManager.js +5 -2
  35. package/dist/lib/core/analytics.d.ts +2 -24
  36. package/dist/lib/core/analytics.js +12 -17
  37. package/dist/lib/core/baseProvider.d.ts +30 -1
  38. package/dist/lib/core/baseProvider.js +180 -198
  39. package/dist/lib/core/dynamicModels.js +7 -7
  40. package/dist/lib/core/evaluation.d.ts +9 -9
  41. package/dist/lib/core/evaluation.js +117 -65
  42. package/dist/lib/core/evaluationProviders.d.ts +18 -2
  43. package/dist/lib/core/evaluationProviders.js +15 -13
  44. package/dist/lib/core/modelConfiguration.d.ts +63 -0
  45. package/dist/lib/core/modelConfiguration.js +354 -290
  46. package/dist/lib/core/streamAnalytics.d.ts +10 -5
  47. package/dist/lib/core/streamAnalytics.js +10 -10
  48. package/dist/lib/core/types.d.ts +19 -109
  49. package/dist/lib/core/types.js +13 -0
  50. package/dist/lib/factories/providerFactory.js +1 -1
  51. package/dist/lib/index.d.ts +2 -1
  52. package/dist/lib/mcp/externalServerManager.js +15 -6
  53. package/dist/lib/mcp/factory.js +1 -1
  54. package/dist/lib/mcp/index.d.ts +1 -1
  55. package/dist/lib/mcp/index.js +1 -1
  56. package/dist/lib/mcp/mcpCircuitBreaker.js +5 -1
  57. package/dist/lib/mcp/mcpClientFactory.js +3 -0
  58. package/dist/lib/mcp/registry.d.ts +3 -3
  59. package/dist/lib/mcp/registry.js +3 -3
  60. package/dist/lib/mcp/servers/aiProviders/aiAnalysisTools.js +5 -5
  61. package/dist/lib/mcp/servers/aiProviders/aiWorkflowTools.js +6 -6
  62. package/dist/lib/mcp/servers/utilities/utilityServer.js +1 -1
  63. package/dist/lib/mcp/toolDiscoveryService.js +8 -2
  64. package/dist/lib/mcp/toolRegistry.js +4 -4
  65. package/dist/lib/middleware/builtin/analytics.js +4 -4
  66. package/dist/lib/middleware/builtin/guardrails.js +2 -2
  67. package/dist/lib/middleware/registry.js +11 -2
  68. package/dist/lib/models/modelRegistry.d.ts +1 -1
  69. package/dist/lib/models/modelRegistry.js +3 -3
  70. package/dist/lib/models/modelResolver.d.ts +1 -1
  71. package/dist/lib/models/modelResolver.js +2 -2
  72. package/dist/lib/neurolink.d.ts +116 -0
  73. package/dist/lib/neurolink.js +716 -922
  74. package/dist/lib/providers/amazonSagemaker.d.ts +1 -1
  75. package/dist/lib/providers/amazonSagemaker.js +12 -3
  76. package/dist/lib/providers/anthropic.d.ts +1 -1
  77. package/dist/lib/providers/anthropic.js +7 -6
  78. package/dist/lib/providers/anthropicBaseProvider.d.ts +1 -1
  79. package/dist/lib/providers/anthropicBaseProvider.js +4 -3
  80. package/dist/lib/providers/azureOpenai.d.ts +1 -1
  81. package/dist/lib/providers/azureOpenai.js +1 -1
  82. package/dist/lib/providers/googleAiStudio.d.ts +1 -1
  83. package/dist/lib/providers/googleAiStudio.js +2 -2
  84. package/dist/lib/providers/googleVertex.d.ts +40 -0
  85. package/dist/lib/providers/googleVertex.js +330 -274
  86. package/dist/lib/providers/huggingFace.js +1 -1
  87. package/dist/lib/providers/mistral.d.ts +1 -1
  88. package/dist/lib/providers/mistral.js +2 -2
  89. package/dist/lib/providers/ollama.d.ts +4 -0
  90. package/dist/lib/providers/ollama.js +38 -18
  91. package/dist/lib/providers/openAI.d.ts +1 -1
  92. package/dist/lib/providers/openAI.js +2 -2
  93. package/dist/lib/providers/sagemaker/adaptive-semaphore.js +7 -4
  94. package/dist/lib/providers/sagemaker/client.js +13 -3
  95. package/dist/lib/providers/sagemaker/config.js +5 -1
  96. package/dist/lib/providers/sagemaker/detection.js +19 -9
  97. package/dist/lib/providers/sagemaker/errors.d.ts +8 -1
  98. package/dist/lib/providers/sagemaker/errors.js +103 -20
  99. package/dist/lib/providers/sagemaker/language-model.d.ts +3 -3
  100. package/dist/lib/providers/sagemaker/language-model.js +4 -4
  101. package/dist/lib/providers/sagemaker/parsers.js +14 -6
  102. package/dist/lib/providers/sagemaker/streaming.js +14 -3
  103. package/dist/lib/providers/sagemaker/types.d.ts +1 -1
  104. package/dist/lib/proxy/awsProxyIntegration.js +1 -1
  105. package/dist/lib/sdk/toolRegistration.d.ts +1 -1
  106. package/dist/lib/types/cli.d.ts +80 -8
  107. package/dist/lib/types/contextTypes.js +2 -2
  108. package/dist/lib/types/generateTypes.d.ts +4 -6
  109. package/dist/lib/types/providers.d.ts +81 -19
  110. package/dist/lib/types/providers.js +6 -6
  111. package/dist/lib/types/streamTypes.d.ts +4 -6
  112. package/dist/lib/types/typeAliases.d.ts +1 -1
  113. package/dist/lib/utils/analyticsUtils.d.ts +33 -0
  114. package/dist/lib/utils/analyticsUtils.js +76 -0
  115. package/dist/lib/utils/errorHandling.js +4 -1
  116. package/dist/lib/utils/evaluationUtils.d.ts +27 -0
  117. package/dist/lib/utils/evaluationUtils.js +131 -0
  118. package/dist/lib/utils/optionsUtils.js +10 -1
  119. package/dist/lib/utils/performance.d.ts +1 -1
  120. package/dist/lib/utils/performance.js +15 -3
  121. package/dist/lib/utils/providerHealth.d.ts +48 -0
  122. package/dist/lib/utils/providerHealth.js +199 -254
  123. package/dist/lib/utils/providerUtils.js +2 -2
  124. package/dist/lib/utils/timeout.js +8 -3
  125. package/dist/mcp/externalServerManager.js +15 -6
  126. package/dist/mcp/factory.js +1 -1
  127. package/dist/mcp/index.d.ts +1 -1
  128. package/dist/mcp/index.js +1 -1
  129. package/dist/mcp/mcpCircuitBreaker.js +5 -1
  130. package/dist/mcp/mcpClientFactory.js +3 -0
  131. package/dist/mcp/registry.d.ts +3 -3
  132. package/dist/mcp/registry.js +3 -3
  133. package/dist/mcp/servers/aiProviders/aiAnalysisTools.js +5 -5
  134. package/dist/mcp/servers/aiProviders/aiWorkflowTools.js +6 -6
  135. package/dist/mcp/servers/utilities/utilityServer.js +1 -1
  136. package/dist/mcp/toolDiscoveryService.js +8 -2
  137. package/dist/mcp/toolRegistry.js +4 -4
  138. package/dist/middleware/builtin/analytics.js +4 -4
  139. package/dist/middleware/builtin/guardrails.js +2 -2
  140. package/dist/middleware/registry.js +11 -2
  141. package/dist/models/modelRegistry.d.ts +1 -1
  142. package/dist/models/modelRegistry.js +3 -3
  143. package/dist/models/modelResolver.d.ts +1 -1
  144. package/dist/models/modelResolver.js +2 -2
  145. package/dist/neurolink.d.ts +116 -0
  146. package/dist/neurolink.js +716 -922
  147. package/dist/providers/amazonSagemaker.d.ts +1 -1
  148. package/dist/providers/amazonSagemaker.js +12 -3
  149. package/dist/providers/anthropic.d.ts +1 -1
  150. package/dist/providers/anthropic.js +7 -6
  151. package/dist/providers/anthropicBaseProvider.d.ts +1 -1
  152. package/dist/providers/anthropicBaseProvider.js +4 -3
  153. package/dist/providers/azureOpenai.d.ts +1 -1
  154. package/dist/providers/azureOpenai.js +1 -1
  155. package/dist/providers/googleAiStudio.d.ts +1 -1
  156. package/dist/providers/googleAiStudio.js +2 -2
  157. package/dist/providers/googleVertex.d.ts +40 -0
  158. package/dist/providers/googleVertex.js +330 -274
  159. package/dist/providers/huggingFace.js +1 -1
  160. package/dist/providers/mistral.d.ts +1 -1
  161. package/dist/providers/mistral.js +2 -2
  162. package/dist/providers/ollama.d.ts +4 -0
  163. package/dist/providers/ollama.js +38 -18
  164. package/dist/providers/openAI.d.ts +1 -1
  165. package/dist/providers/openAI.js +2 -2
  166. package/dist/providers/sagemaker/adaptive-semaphore.js +7 -4
  167. package/dist/providers/sagemaker/client.js +13 -3
  168. package/dist/providers/sagemaker/config.js +5 -1
  169. package/dist/providers/sagemaker/detection.js +19 -9
  170. package/dist/providers/sagemaker/errors.d.ts +8 -1
  171. package/dist/providers/sagemaker/errors.js +103 -20
  172. package/dist/providers/sagemaker/language-model.d.ts +3 -3
  173. package/dist/providers/sagemaker/language-model.js +4 -4
  174. package/dist/providers/sagemaker/parsers.js +14 -6
  175. package/dist/providers/sagemaker/streaming.js +14 -3
  176. package/dist/providers/sagemaker/types.d.ts +1 -1
  177. package/dist/proxy/awsProxyIntegration.js +1 -1
  178. package/dist/sdk/toolRegistration.d.ts +1 -1
  179. package/dist/types/cli.d.ts +80 -8
  180. package/dist/types/contextTypes.js +2 -2
  181. package/dist/types/generateTypes.d.ts +4 -6
  182. package/dist/types/providers.d.ts +81 -19
  183. package/dist/types/providers.js +6 -6
  184. package/dist/types/streamTypes.d.ts +4 -6
  185. package/dist/types/typeAliases.d.ts +1 -1
  186. package/dist/utils/analyticsUtils.d.ts +33 -0
  187. package/dist/utils/analyticsUtils.js +76 -0
  188. package/dist/utils/errorHandling.js +4 -1
  189. package/dist/utils/evaluationUtils.d.ts +27 -0
  190. package/dist/utils/evaluationUtils.js +131 -0
  191. package/dist/utils/optionsUtils.js +10 -1
  192. package/dist/utils/performance.d.ts +1 -1
  193. package/dist/utils/performance.js +15 -3
  194. package/dist/utils/providerHealth.d.ts +48 -0
  195. package/dist/utils/providerHealth.js +199 -254
  196. package/dist/utils/providerUtils.js +2 -2
  197. package/dist/utils/timeout.js +8 -3
  198. package/package.json +1 -1
@@ -445,265 +445,210 @@ export class ProviderHealthChecker {
445
445
  */
446
446
  static async checkProviderSpecificConfig(providerName, healthStatus) {
447
447
  switch (providerName) {
448
- case AIProviderName.VERTEX: {
449
- logger.debug("Starting Vertex AI health check", {
450
- providerName,
451
- });
452
- // Check for Google Cloud project ID (with fallbacks)
453
- const projectId = process.env.GOOGLE_PROJECT_ID ||
454
- process.env.GOOGLE_CLOUD_PROJECT_ID ||
455
- process.env.GOOGLE_VERTEX_PROJECT ||
456
- process.env.GOOGLE_CLOUD_PROJECT ||
457
- process.env.VERTEX_PROJECT_ID;
458
- logger.debug("Project ID validation", {
459
- hasProjectId: !!projectId,
460
- });
461
- if (!projectId) {
462
- healthStatus.configurationIssues.push("Google Cloud project ID not set");
463
- healthStatus.recommendations.push("Set one of: GOOGLE_VERTEX_PROJECT, GOOGLE_CLOUD_PROJECT_ID, GOOGLE_PROJECT_ID, or GOOGLE_CLOUD_PROJECT");
464
- }
465
- // Check for authentication with proper file existence validation
466
- // This aligns with the authentication logic fix in googleVertex.ts
467
- let hasValidAuth = false;
468
- logger.debug("Authentication validation starting", {
469
- hasGoogleApplicationCredentials: !!process.env.GOOGLE_APPLICATION_CREDENTIALS,
470
- });
471
- // Check for principal account authentication first (recommended for production)
472
- // BUT CRITICALLY: Also verify the file actually exists
473
- if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
474
- const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
475
- logger.debug("Checking GOOGLE_APPLICATION_CREDENTIALS file");
476
- // Check if the credentials file actually exists
477
- let fileExists = false;
478
- try {
479
- const { promises: fs } = await import("fs");
480
- try {
481
- await fs.access(credentialsPath);
482
- fileExists = true;
483
- }
484
- catch {
485
- fileExists = false;
486
- }
487
- logger.debug("File existence check completed", {
488
- fileExists,
489
- });
490
- }
491
- catch (error) {
492
- logger.debug("File existence check failed", {
493
- error: String(error),
494
- });
495
- healthStatus.warning = `Failed to check credentials file existence: ${error}`;
496
- fileExists = false;
497
- }
498
- if (fileExists) {
499
- // Validate file format
500
- const fileName = basename(credentialsPath);
501
- const jsonFilePattern = /\.json(\.\w+)?$/;
502
- if (!jsonFilePattern.test(fileName)) {
503
- healthStatus.warning =
504
- "GOOGLE_APPLICATION_CREDENTIALS should point to a JSON file (e.g., 'credentials.json' or 'key.json.backup')";
505
- }
506
- hasValidAuth = true;
507
- healthStatus.hasApiKey = true;
508
- logger.debug("GOOGLE_APPLICATION_CREDENTIALS file validated", {
509
- fileName,
510
- hasValidAuth,
511
- });
512
- }
513
- else {
514
- healthStatus.warning = `GOOGLE_APPLICATION_CREDENTIALS file does not exist: ${credentialsPath}`;
515
- logger.debug("GOOGLE_APPLICATION_CREDENTIALS file missing, falling back to individual env vars");
516
- // Fall through to check individual environment variables
517
- }
518
- }
519
- else {
520
- logger.debug("GOOGLE_APPLICATION_CREDENTIALS not set, checking individual env vars");
521
- }
522
- // Fallback to individual credentials for development and production
523
- // Enhanced to check ALL required fields from the .env file configuration
524
- if (!hasValidAuth) {
525
- const hasServiceAccountKey = !!process.env.GOOGLE_SERVICE_ACCOUNT_KEY;
526
- const hasIndividualCredentials = !!(process.env.GOOGLE_AUTH_CLIENT_EMAIL &&
527
- process.env.GOOGLE_AUTH_PRIVATE_KEY);
528
- logger.debug("Individual credentials check", {
529
- hasServiceAccountKey,
530
- hasGoogleAuthClientEmail: !!process.env.GOOGLE_AUTH_CLIENT_EMAIL,
531
- hasGoogleAuthPrivateKey: !!process.env.GOOGLE_AUTH_PRIVATE_KEY,
532
- hasIndividualCredentials,
533
- });
534
- if (hasServiceAccountKey || hasIndividualCredentials) {
535
- hasValidAuth = true;
536
- healthStatus.hasApiKey = true;
537
- logger.debug("Individual credentials validated successfully", {
538
- hasServiceAccountKey,
539
- hasIndividualCredentials,
540
- hasValidAuth,
541
- });
542
- }
543
- else {
544
- logger.debug("Individual credentials validation failed", {
545
- hasServiceAccountKey,
546
- hasIndividualCredentials,
547
- });
548
- }
549
- }
550
- // Final validation
551
- if (!hasValidAuth) {
552
- healthStatus.configurationIssues.push("Google Cloud authentication not configured or credentials file missing");
553
- healthStatus.recommendations.push("Set either GOOGLE_APPLICATION_CREDENTIALS (valid file path), GOOGLE_SERVICE_ACCOUNT_KEY (base64), or both GOOGLE_AUTH_CLIENT_EMAIL and GOOGLE_AUTH_PRIVATE_KEY");
554
- logger.debug("Final auth validation FAILED", {
555
- hasValidAuth,
556
- });
557
- }
558
- else {
559
- logger.debug("Final auth validation SUCCESS", {
560
- hasValidAuth,
561
- });
562
- }
563
- // Mark as configured if we have both project ID and auth
564
- if (projectId && hasValidAuth) {
565
- healthStatus.isConfigured = true;
566
- logger.debug("Vertex AI health check PASSED", {
567
- hasProjectId: !!projectId,
568
- hasValidAuth,
569
- isConfigured: healthStatus.isConfigured,
570
- });
571
- }
572
- else {
573
- logger.debug("Vertex AI health check FAILED", {
574
- hasProjectId: !!projectId,
575
- hasValidAuth,
576
- isConfigured: healthStatus.isConfigured,
577
- });
578
- }
448
+ case AIProviderName.VERTEX:
449
+ await this.checkVertexAIConfig(healthStatus);
579
450
  break;
580
- }
581
- case AIProviderName.BEDROCK: {
582
- logger.debug("Starting AWS Bedrock comprehensive health check", {
583
- providerName,
584
- });
585
- // Check AWS region configuration
586
- const awsRegion = process.env.AWS_REGION;
587
- const validBedrockRegions = [
588
- "us-east-1",
589
- "us-west-2",
590
- "ap-southeast-1",
591
- "ap-northeast-1",
592
- "eu-central-1",
593
- "eu-west-1",
594
- "ap-south-1",
595
- ];
596
- logger.debug("AWS Region validation", {
597
- hasAwsRegion: !!awsRegion,
598
- awsRegion: awsRegion || "not set",
599
- validBedrockRegions,
600
- });
601
- if (!awsRegion) {
602
- healthStatus.configurationIssues.push("AWS_REGION not set");
603
- healthStatus.recommendations.push(`Set AWS_REGION to a Bedrock-supported region: ${validBedrockRegions.join(", ")}`);
604
- }
605
- else if (!validBedrockRegions.includes(awsRegion)) {
606
- healthStatus.configurationIssues.push(`AWS_REGION '${awsRegion}' may not support all Bedrock models`);
607
- healthStatus.recommendations.push(`Consider using a primary Bedrock region: ${validBedrockRegions.slice(0, 3).join(", ")}`);
608
- }
609
- // Check AWS credentials configuration
610
- const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID;
611
- const awsSecretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
612
- const awsSessionToken = process.env.AWS_SESSION_TOKEN;
613
- const awsProfile = process.env.AWS_PROFILE;
614
- logger.debug("AWS Credentials validation", {
615
- hasAccessKeyId: !!awsAccessKeyId,
616
- hasSecretAccessKey: !!awsSecretAccessKey,
617
- hasSessionToken: !!awsSessionToken,
618
- hasProfile: !!awsProfile,
619
- authMethod: awsProfile
620
- ? "AWS Profile"
621
- : awsAccessKeyId
622
- ? "Access Keys"
623
- : "None detected",
624
- });
625
- if (!awsAccessKeyId && !awsProfile) {
626
- healthStatus.configurationIssues.push("No AWS credentials found");
627
- healthStatus.recommendations.push("Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, or configure AWS_PROFILE");
628
- }
629
- else if (awsAccessKeyId && !awsSecretAccessKey) {
630
- healthStatus.configurationIssues.push("AWS_ACCESS_KEY_ID set but AWS_SECRET_ACCESS_KEY missing");
631
- healthStatus.recommendations.push("Set AWS_SECRET_ACCESS_KEY to match your AWS_ACCESS_KEY_ID");
632
- }
633
- // Check for Bedrock-specific model configuration
634
- const bedrockModel = process.env.BEDROCK_MODEL || process.env.BEDROCK_MODEL_ID;
635
- const supportedModels = [
636
- "anthropic.claude-3-sonnet-20240229-v1:0",
637
- "anthropic.claude-3-haiku-20240307-v1:0",
638
- "anthropic.claude-3-opus-20240229-v1:0",
639
- "anthropic.claude-v2:1",
640
- "amazon.titan-text-express-v1",
641
- ];
642
- logger.debug("Bedrock Model validation", {
643
- hasBedrockModel: !!bedrockModel,
644
- bedrockModel: bedrockModel || "not set",
645
- supportedModels: supportedModels.slice(0, 3),
646
- });
647
- if (!bedrockModel) {
648
- healthStatus.recommendations.push("Set BEDROCK_MODEL or BEDROCK_MODEL_ID for faster startup (e.g., anthropic.claude-3-sonnet-20240229-v1:0)");
649
- }
650
- else if (!supportedModels.some((model) => model === bedrockModel)) {
651
- healthStatus.recommendations.push(`Consider using a popular Bedrock model: ${supportedModels.slice(0, 3).join(", ")}`);
652
- }
653
- // Check for additional Bedrock configuration
654
- const bedrockEndpoint = process.env.BEDROCK_ENDPOINT_URL;
655
- if (bedrockEndpoint) {
656
- logger.debug("Custom Bedrock endpoint detected", {
657
- endpoint: bedrockEndpoint,
658
- });
659
- if (!bedrockEndpoint.startsWith("https://")) {
660
- healthStatus.configurationIssues.push("BEDROCK_ENDPOINT_URL should use HTTPS");
661
- healthStatus.recommendations.push("Update BEDROCK_ENDPOINT_URL to use HTTPS protocol");
662
- }
663
- }
664
- // AWS SDK Configuration checks
665
- const awsConfig = {
666
- maxAttempts: process.env.AWS_MAX_ATTEMPTS,
667
- retryMode: process.env.AWS_RETRY_MODE,
668
- defaultsMode: process.env.AWS_DEFAULTS_MODE,
669
- };
670
- logger.debug("AWS SDK Configuration", {
671
- awsConfig,
672
- hasAdvancedConfig: Object.values(awsConfig).some(Boolean),
673
- });
674
- if (healthStatus.configurationIssues.length === 0) {
675
- healthStatus.hasApiKey = true;
676
- logger.debug("AWS Bedrock configuration appears valid", {
677
- region: awsRegion,
678
- hasCredentials: !!(awsAccessKeyId || awsProfile),
679
- hasModel: !!bedrockModel,
680
- });
681
- }
451
+ case AIProviderName.BEDROCK:
452
+ await this.checkBedrockConfig(healthStatus);
682
453
  break;
683
- }
684
- case AIProviderName.AZURE: {
685
- // Check Azure OpenAI endpoint
686
- const azureEndpoint = process.env.AZURE_OPENAI_ENDPOINT;
687
- if (azureEndpoint && !azureEndpoint.startsWith("https://")) {
688
- healthStatus.configurationIssues.push("Invalid AZURE_OPENAI_ENDPOINT format");
689
- healthStatus.recommendations.push("Set AZURE_OPENAI_ENDPOINT to a valid URL (e.g., https://your-resource.openai.azure.com/)");
690
- }
691
- // Check for deployment name
692
- if (!process.env.AZURE_OPENAI_DEPLOYMENT_NAME) {
693
- healthStatus.configurationIssues.push("AZURE_OPENAI_DEPLOYMENT_NAME not set");
694
- healthStatus.recommendations.push("Set AZURE_OPENAI_DEPLOYMENT_NAME to your deployment name");
695
- }
454
+ case AIProviderName.AZURE:
455
+ await this.checkAzureConfig(healthStatus);
696
456
  break;
697
- }
698
- case AIProviderName.OLLAMA: {
699
- // Check if custom endpoint is set
700
- const ollamaBase = process.env.OLLAMA_API_BASE || "http://localhost:11434";
701
- if (!ollamaBase.startsWith("http")) {
702
- healthStatus.configurationIssues.push("Invalid OLLAMA_API_BASE format");
703
- healthStatus.recommendations.push("Set OLLAMA_API_BASE to a valid URL (e.g., http://localhost:11434)");
704
- }
457
+ case AIProviderName.OLLAMA:
458
+ await this.checkOllamaConfig(healthStatus);
705
459
  break;
460
+ }
461
+ }
462
+ /**
463
+ * Check Vertex AI configuration
464
+ */
465
+ static async checkVertexAIConfig(healthStatus) {
466
+ logger.debug("Starting Vertex AI health check");
467
+ const projectId = this.getVertexProjectId();
468
+ if (!projectId) {
469
+ healthStatus.configurationIssues.push("Google Cloud project ID not set");
470
+ healthStatus.recommendations.push("Set one of: GOOGLE_VERTEX_PROJECT, GOOGLE_CLOUD_PROJECT_ID, GOOGLE_PROJECT_ID, or GOOGLE_CLOUD_PROJECT");
471
+ }
472
+ const hasValidAuth = await this.checkVertexAuthentication(healthStatus);
473
+ if (projectId && hasValidAuth) {
474
+ healthStatus.isConfigured = true;
475
+ logger.debug("Vertex AI health check PASSED");
476
+ }
477
+ else {
478
+ logger.debug("Vertex AI health check FAILED");
479
+ }
480
+ }
481
+ /**
482
+ * Get Vertex AI project ID from environment variables
483
+ */
484
+ static getVertexProjectId() {
485
+ return (process.env.GOOGLE_PROJECT_ID ||
486
+ process.env.GOOGLE_CLOUD_PROJECT_ID ||
487
+ process.env.GOOGLE_VERTEX_PROJECT ||
488
+ process.env.GOOGLE_CLOUD_PROJECT ||
489
+ process.env.VERTEX_PROJECT_ID);
490
+ }
491
+ /**
492
+ * Check Vertex AI authentication
493
+ */
494
+ static async checkVertexAuthentication(healthStatus) {
495
+ let hasValidAuth = false;
496
+ if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
497
+ hasValidAuth = await this.checkGoogleApplicationCredentials(healthStatus);
498
+ }
499
+ if (!hasValidAuth) {
500
+ hasValidAuth = this.checkIndividualGoogleCredentials(healthStatus);
501
+ }
502
+ if (!hasValidAuth) {
503
+ healthStatus.configurationIssues.push("Google Cloud authentication not configured or credentials file missing");
504
+ healthStatus.recommendations.push("Set either GOOGLE_APPLICATION_CREDENTIALS (valid file path), GOOGLE_SERVICE_ACCOUNT_KEY (base64), or both GOOGLE_AUTH_CLIENT_EMAIL and GOOGLE_AUTH_PRIVATE_KEY");
505
+ }
506
+ return hasValidAuth;
507
+ }
508
+ /**
509
+ * Check Google Application Credentials file
510
+ */
511
+ static async checkGoogleApplicationCredentials(healthStatus) {
512
+ const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
513
+ if (!credentialsPath) {
514
+ healthStatus.warning =
515
+ "GOOGLE_APPLICATION_CREDENTIALS environment variable not set";
516
+ return false;
517
+ }
518
+ try {
519
+ const { promises: fs } = await import("fs");
520
+ await fs.access(credentialsPath);
521
+ const fileName = basename(credentialsPath);
522
+ const jsonFilePattern = /\.json(\.\w+)?$/;
523
+ if (!jsonFilePattern.test(fileName)) {
524
+ healthStatus.warning =
525
+ "GOOGLE_APPLICATION_CREDENTIALS should point to a JSON file";
706
526
  }
527
+ healthStatus.hasApiKey = true;
528
+ return true;
529
+ }
530
+ catch {
531
+ healthStatus.warning = `GOOGLE_APPLICATION_CREDENTIALS file does not exist: ${credentialsPath}`;
532
+ return false;
533
+ }
534
+ }
535
+ /**
536
+ * Check individual Google credentials
537
+ */
538
+ static checkIndividualGoogleCredentials(healthStatus) {
539
+ const hasServiceAccountKey = !!process.env.GOOGLE_SERVICE_ACCOUNT_KEY;
540
+ const hasIndividualCredentials = !!(process.env.GOOGLE_AUTH_CLIENT_EMAIL &&
541
+ process.env.GOOGLE_AUTH_PRIVATE_KEY);
542
+ if (hasServiceAccountKey || hasIndividualCredentials) {
543
+ healthStatus.hasApiKey = true;
544
+ return true;
545
+ }
546
+ return false;
547
+ }
548
+ /**
549
+ * Check AWS Bedrock configuration
550
+ */
551
+ static async checkBedrockConfig(healthStatus) {
552
+ logger.debug("Starting AWS Bedrock comprehensive health check");
553
+ this.checkAWSRegion(healthStatus);
554
+ this.checkAWSCredentials(healthStatus);
555
+ this.checkBedrockModels(healthStatus);
556
+ this.checkBedrockEndpoint(healthStatus);
557
+ if (healthStatus.configurationIssues.length === 0) {
558
+ healthStatus.hasApiKey = true;
559
+ logger.debug("AWS Bedrock configuration appears valid");
560
+ }
561
+ }
562
+ /**
563
+ * Check AWS region configuration
564
+ */
565
+ static checkAWSRegion(healthStatus) {
566
+ const awsRegion = process.env.AWS_REGION;
567
+ const validBedrockRegions = [
568
+ "us-east-1",
569
+ "us-west-2",
570
+ "ap-southeast-1",
571
+ "ap-northeast-1",
572
+ "eu-central-1",
573
+ "eu-west-1",
574
+ "ap-south-1",
575
+ ];
576
+ if (!awsRegion) {
577
+ healthStatus.configurationIssues.push("AWS_REGION not set");
578
+ healthStatus.recommendations.push(`Set AWS_REGION to a Bedrock-supported region: ${validBedrockRegions.join(", ")}`);
579
+ }
580
+ else if (!validBedrockRegions.includes(awsRegion)) {
581
+ healthStatus.configurationIssues.push(`AWS_REGION '${awsRegion}' may not support all Bedrock models`);
582
+ healthStatus.recommendations.push(`Consider using a primary Bedrock region: ${validBedrockRegions.slice(0, 3).join(", ")}`);
583
+ }
584
+ }
585
+ /**
586
+ * Check AWS credentials
587
+ */
588
+ static checkAWSCredentials(healthStatus) {
589
+ const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID;
590
+ const awsSecretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
591
+ const awsProfile = process.env.AWS_PROFILE;
592
+ if (!awsAccessKeyId && !awsProfile) {
593
+ healthStatus.configurationIssues.push("No AWS credentials found");
594
+ healthStatus.recommendations.push("Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, or configure AWS_PROFILE");
595
+ }
596
+ else if (awsAccessKeyId && !awsSecretAccessKey) {
597
+ healthStatus.configurationIssues.push("AWS_ACCESS_KEY_ID set but AWS_SECRET_ACCESS_KEY missing");
598
+ healthStatus.recommendations.push("Set AWS_SECRET_ACCESS_KEY to match your AWS_ACCESS_KEY_ID");
599
+ }
600
+ }
601
+ /**
602
+ * Check Bedrock models
603
+ */
604
+ static checkBedrockModels(healthStatus) {
605
+ const bedrockModel = process.env.BEDROCK_MODEL || process.env.BEDROCK_MODEL_ID;
606
+ const supportedModels = [
607
+ "anthropic.claude-3-sonnet-20240229-v1:0",
608
+ "anthropic.claude-3-haiku-20240307-v1:0",
609
+ "anthropic.claude-3-opus-20240229-v1:0",
610
+ "anthropic.claude-v2:1",
611
+ "amazon.titan-text-express-v1",
612
+ ];
613
+ if (!bedrockModel) {
614
+ healthStatus.recommendations.push("Set BEDROCK_MODEL or BEDROCK_MODEL_ID for faster startup (e.g., anthropic.claude-3-sonnet-20240229-v1:0)");
615
+ }
616
+ else if (!supportedModels.includes(bedrockModel)) {
617
+ healthStatus.recommendations.push(`Consider using a popular Bedrock model: ${supportedModels.slice(0, 3).join(", ")}`);
618
+ }
619
+ }
620
+ /**
621
+ * Check Bedrock endpoint
622
+ */
623
+ static checkBedrockEndpoint(healthStatus) {
624
+ const bedrockEndpoint = process.env.BEDROCK_ENDPOINT_URL;
625
+ if (bedrockEndpoint && !bedrockEndpoint.startsWith("https://")) {
626
+ healthStatus.configurationIssues.push("BEDROCK_ENDPOINT_URL should use HTTPS");
627
+ healthStatus.recommendations.push("Update BEDROCK_ENDPOINT_URL to use HTTPS protocol");
628
+ }
629
+ }
630
+ /**
631
+ * Check Azure OpenAI configuration
632
+ */
633
+ static async checkAzureConfig(healthStatus) {
634
+ const azureEndpoint = process.env.AZURE_OPENAI_ENDPOINT;
635
+ if (azureEndpoint && !azureEndpoint.startsWith("https://")) {
636
+ healthStatus.configurationIssues.push("Invalid AZURE_OPENAI_ENDPOINT format");
637
+ healthStatus.recommendations.push("Set AZURE_OPENAI_ENDPOINT to a valid URL (e.g., https://your-resource.openai.azure.com/)");
638
+ }
639
+ if (!process.env.AZURE_OPENAI_DEPLOYMENT_NAME) {
640
+ healthStatus.configurationIssues.push("AZURE_OPENAI_DEPLOYMENT_NAME not set");
641
+ healthStatus.recommendations.push("Set AZURE_OPENAI_DEPLOYMENT_NAME to your deployment name");
642
+ }
643
+ }
644
+ /**
645
+ * Check Ollama configuration
646
+ */
647
+ static async checkOllamaConfig(healthStatus) {
648
+ const ollamaBase = process.env.OLLAMA_API_BASE || "http://localhost:11434";
649
+ if (!ollamaBase.startsWith("http")) {
650
+ healthStatus.configurationIssues.push("Invalid OLLAMA_API_BASE format");
651
+ healthStatus.recommendations.push("Set OLLAMA_API_BASE to a valid URL (e.g., http://localhost:11434)");
707
652
  }
708
653
  }
709
654
  /**
@@ -107,7 +107,7 @@ async function isProviderAvailable(providerName) {
107
107
  }
108
108
  return false;
109
109
  }
110
- catch (error) {
110
+ catch {
111
111
  return false;
112
112
  }
113
113
  }
@@ -116,7 +116,7 @@ async function isProviderAvailable(providerName) {
116
116
  await provider.generate({ prompt: "test", maxTokens: 1 });
117
117
  return true;
118
118
  }
119
- catch (error) {
119
+ catch {
120
120
  return false;
121
121
  }
122
122
  }
@@ -214,14 +214,17 @@ export class TimeoutManager {
214
214
  generateOperationId(operation) {
215
215
  return `${operation}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
216
216
  }
217
- createTimeoutPromise(timeoutMs, operationId) {
217
+ createTimeoutPromise(timeoutMs, _operationId) {
218
218
  let timer;
219
219
  const promise = new Promise((_, reject) => {
220
220
  timer = setTimeout(() => {
221
221
  reject(new TimeoutError(`Operation timeout after ${timeoutMs}ms`, timeoutMs));
222
222
  }, timeoutMs);
223
223
  });
224
- return { promise, timer: timer };
224
+ if (!timer) {
225
+ throw new Error("Failed to create timeout timer");
226
+ }
227
+ return { promise, timer };
225
228
  }
226
229
  registerTimeout(operationId, timer, controller, cleanup) {
227
230
  this.activeTimeouts.set(operationId, { timer, controller, cleanup });
@@ -291,7 +294,9 @@ export async function* withStreamingTimeout(generator, timeout, provider) {
291
294
  }
292
295
  }
293
296
  finally {
294
- clearTimeout(timeoutId);
297
+ if (timeoutId) {
298
+ clearTimeout(timeoutId);
299
+ }
295
300
  }
296
301
  }
297
302
  /**
@@ -357,6 +357,9 @@ export class ExternalServerManager extends EventEmitter {
357
357
  // Start the server
358
358
  await this.startServer(serverId);
359
359
  const finalInstance = this.servers.get(serverId);
360
+ if (!finalInstance) {
361
+ throw new Error(`Server ${serverId} not found after registration`);
362
+ }
360
363
  // Convert RuntimeMCPServerInfo to ExternalMCPServerInstance for return
361
364
  const convertedInstance = {
362
365
  config: finalInstance.config,
@@ -927,11 +930,18 @@ export class ExternalServerManager extends EventEmitter {
927
930
  serverId: serverId,
928
931
  category: detectCategory({ isExternal: true, serverId }),
929
932
  };
930
- registrations.push(toolRegistry.registerTool(toolId, toolInfo, {
931
- execute: async (params) => await this.executeTool(serverId, toolName, params, {
932
- timeout: this.config.defaultTimeout,
933
- }),
934
- }));
933
+ try {
934
+ registrations.push(toolRegistry.registerTool(toolId, toolInfo, {
935
+ execute: async (params, _context) => {
936
+ // Execute tool via ExternalServerManager for proper lifecycle management
937
+ return await this.executeTool(serverId, toolName, params, { timeout: this.config.defaultTimeout });
938
+ },
939
+ }));
940
+ mcpLogger.debug(`[ExternalServerManager] Registered tool with main registry: ${toolId}`);
941
+ }
942
+ catch (registrationError) {
943
+ mcpLogger.warn(`[ExternalServerManager] Failed to register tool ${toolId} with main registry:`, registrationError);
944
+ }
935
945
  }
936
946
  const results = await Promise.allSettled(registrations);
937
947
  const ok = results.filter((r) => r.status === "fulfilled").length;
@@ -1009,7 +1019,6 @@ export class ExternalServerManager extends EventEmitter {
1009
1019
  }
1010
1020
  }
1011
1021
  catch (error) {
1012
- const duration = Date.now() - startTime;
1013
1022
  instance.metrics.totalErrors++;
1014
1023
  mcpLogger.error(`[ExternalServerManager] Tool execution failed: ${toolName} on ${serverId}`, error);
1015
1024
  throw error;
@@ -116,7 +116,7 @@ export function validateTool(tool) {
116
116
  const validation = validateMCPTool(tool);
117
117
  return validation.isValid;
118
118
  }
119
- catch (error) {
119
+ catch {
120
120
  return false;
121
121
  }
122
122
  }
@@ -18,7 +18,7 @@ export declare function listMCPs(): Promise<McpMetadata[]>;
18
18
  /**
19
19
  * Execute an MCP operation - simplified
20
20
  */
21
- export declare function executeMCP<T = unknown>(name: string, config: unknown, args: unknown, context?: {
21
+ export declare function executeMCP<T = unknown>(_name: string, _config: unknown, _args: unknown, _context?: {
22
22
  sessionId?: string;
23
23
  userId?: string;
24
24
  }): Promise<T>;
package/dist/mcp/index.js CHANGED
@@ -21,7 +21,7 @@ export async function listMCPs() {
21
21
  /**
22
22
  * Execute an MCP operation - simplified
23
23
  */
24
- export async function executeMCP(name, config, args, context) {
24
+ export async function executeMCP(_name, _config, _args, _context) {
25
25
  throw new Error("MCP execution not available - ecosystem removed");
26
26
  }
27
27
  /**
@@ -285,7 +285,11 @@ export class CircuitBreakerManager {
285
285
  this.breakers.set(name, breaker);
286
286
  mcpLogger.debug(`[CircuitBreakerManager] Created circuit breaker: ${name}`);
287
287
  }
288
- return this.breakers.get(name);
288
+ const breaker = this.breakers.get(name);
289
+ if (!breaker) {
290
+ throw new Error(`Circuit breaker ${name} not found after creation`);
291
+ }
292
+ return breaker;
289
293
  }
290
294
  /**
291
295
  * Remove a circuit breaker and clean up its resources
@@ -192,6 +192,9 @@ export class MCPClientFactory {
192
192
  throw new Error("Process failed to start or exited immediately");
193
193
  }
194
194
  // Create transport
195
+ if (!config.command) {
196
+ throw new Error(`Command is required for stdio transport`);
197
+ }
195
198
  const transport = new StdioClientTransport({
196
199
  command: config.command,
197
200
  args: config.args || [],
@@ -44,15 +44,15 @@ export declare class MCPRegistry implements McpRegistry {
44
44
  /**
45
45
  * Register a server (compatible with new interface)
46
46
  */
47
- registerServer(serverId: string, serverConfig?: unknown, context?: ExecutionContext): Promise<void>;
47
+ registerServer(serverId: string, serverConfig?: unknown, _context?: ExecutionContext): Promise<void>;
48
48
  /**
49
49
  * Execute a tool (mock implementation for tests)
50
50
  */
51
- executeTool<T = unknown>(toolName: string, args?: unknown, context?: ExecutionContext): Promise<T>;
51
+ executeTool<T = unknown>(toolName: string, args?: unknown, _context?: ExecutionContext): Promise<T>;
52
52
  /**
53
53
  * List all tools (compatible with new interface)
54
54
  */
55
- listTools(context?: ExecutionContext): Promise<ToolInfo[]>;
55
+ listTools(_context?: ExecutionContext): Promise<ToolInfo[]>;
56
56
  /**
57
57
  * Register a server (legacy sync version)
58
58
  */
@@ -53,7 +53,7 @@ export class MCPRegistry {
53
53
  /**
54
54
  * Register a server (compatible with new interface)
55
55
  */
56
- async registerServer(serverId, serverConfig, context) {
56
+ async registerServer(serverId, serverConfig, _context) {
57
57
  const plugin = {
58
58
  metadata: {
59
59
  name: serverId,
@@ -74,14 +74,14 @@ export class MCPRegistry {
74
74
  /**
75
75
  * Execute a tool (mock implementation for tests)
76
76
  */
77
- async executeTool(toolName, args, context) {
77
+ async executeTool(toolName, args, _context) {
78
78
  registryLogger.info(`Executing tool: ${toolName}`);
79
79
  return { result: `Mock execution of ${toolName}`, args };
80
80
  }
81
81
  /**
82
82
  * List all tools (compatible with new interface)
83
83
  */
84
- async listTools(context) {
84
+ async listTools(_context) {
85
85
  const tools = this.list().map((plugin) => ({
86
86
  name: plugin.metadata.name,
87
87
  description: plugin.metadata.description || "No description",