@juspay/neurolink 7.29.2 → 7.30.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 +12 -0
- package/dist/cli/commands/config.d.ts +83 -83
- package/dist/cli/commands/mcp.js +39 -9
- package/dist/cli/commands/models.js +25 -21
- package/dist/cli/commands/ollama.js +2 -2
- package/dist/cli/factories/commandFactory.d.ts +8 -0
- package/dist/cli/factories/commandFactory.js +65 -65
- 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 +11 -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/config/conversationMemoryConfig.js +5 -0
- 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/conversationMemoryManager.d.ts +9 -15
- package/dist/core/conversationMemoryManager.js +98 -57
- 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/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 +22 -110
- package/dist/core/types.js +13 -0
- package/dist/factories/providerFactory.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/lib/config/configManager.js +5 -2
- package/dist/lib/config/conversationMemoryConfig.js +5 -0
- 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/conversationMemoryManager.d.ts +9 -15
- package/dist/lib/core/conversationMemoryManager.js +98 -57
- 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/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 +22 -110
- package/dist/lib/core/types.js +13 -0
- package/dist/lib/factories/providerFactory.js +1 -1
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/mcp/externalServerManager.js +15 -6
- package/dist/lib/mcp/factory.js +1 -1
- 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.js +4 -4
- 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 +116 -9
- package/dist/lib/neurolink.js +718 -956
- 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/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.js +1 -1
- 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/conversationTypes.d.ts +10 -0
- package/dist/lib/types/generateTypes.d.ts +2 -5
- package/dist/lib/types/providers.d.ts +81 -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/conversationMemoryUtils.d.ts +1 -2
- package/dist/lib/utils/conversationMemoryUtils.js +6 -7
- 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/providerHealth.d.ts +48 -0
- package/dist/lib/utils/providerHealth.js +199 -254
- package/dist/lib/utils/providerUtils.js +2 -2
- package/dist/lib/utils/timeout.js +8 -3
- package/dist/mcp/externalServerManager.js +15 -6
- package/dist/mcp/factory.js +1 -1
- 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.js +4 -4
- 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 +116 -9
- package/dist/neurolink.js +718 -956
- 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/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.js +1 -1
- 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/conversationTypes.d.ts +10 -0
- package/dist/types/generateTypes.d.ts +2 -5
- package/dist/types/providers.d.ts +81 -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/conversationMemoryUtils.d.ts +1 -2
- package/dist/utils/conversationMemoryUtils.js +6 -7
- 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/providerHealth.d.ts +48 -0
- package/dist/utils/providerHealth.js +199 -254
- package/dist/utils/providerUtils.js +2 -2
- package/dist/utils/timeout.js +8 -3
- package/package.json +1 -1
- package/dist/context/ContextManager.d.ts +0 -28
- package/dist/context/ContextManager.js +0 -113
- package/dist/context/config.d.ts +0 -5
- package/dist/context/config.js +0 -42
- package/dist/context/types.d.ts +0 -20
- package/dist/context/types.js +0 -1
- package/dist/context/utils.d.ts +0 -7
- package/dist/context/utils.js +0 -8
- package/dist/lib/context/ContextManager.d.ts +0 -28
- package/dist/lib/context/ContextManager.js +0 -113
- package/dist/lib/context/config.d.ts +0 -5
- package/dist/lib/context/config.js +0 -42
- package/dist/lib/context/types.d.ts +0 -20
- package/dist/lib/context/types.js +0 -1
- package/dist/lib/context/utils.d.ts +0 -7
- package/dist/lib/context/utils.js +0 -8
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
119
|
+
catch {
|
|
120
120
|
return false;
|
|
121
121
|
}
|
|
122
122
|
}
|
package/dist/utils/timeout.js
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
-
|
|
297
|
+
if (timeoutId) {
|
|
298
|
+
clearTimeout(timeoutId);
|
|
299
|
+
}
|
|
295
300
|
}
|
|
296
301
|
}
|
|
297
302
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.30.0",
|
|
4
4
|
"description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 9 major providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Juspay Technologies",
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { TextGenerationOptions, TextGenerationResult } from "../core/types.js";
|
|
2
|
-
import type { ContextManagerConfig } from "./types.js";
|
|
3
|
-
type InternalGenerator = (options: TextGenerationOptions) => Promise<TextGenerationResult>;
|
|
4
|
-
/**
|
|
5
|
-
* Manages conversation context, automatically summarizing it when it
|
|
6
|
-
* exceeds a specified word count limit.
|
|
7
|
-
*/
|
|
8
|
-
export declare class ContextManager {
|
|
9
|
-
private static readonly SUMMARIZATION_FAILED_WARNING;
|
|
10
|
-
private static readonly SUMMARIZATION_EMPTY_WARNING;
|
|
11
|
-
private history;
|
|
12
|
-
private wordCount;
|
|
13
|
-
private readonly internalGenerator;
|
|
14
|
-
private readonly config;
|
|
15
|
-
constructor(generatorFunction: InternalGenerator, config: ContextManagerConfig, initialContext?: string);
|
|
16
|
-
addTurn(role: "user" | "assistant", message: string): Promise<void>;
|
|
17
|
-
/**
|
|
18
|
-
* Formats the history including the latest user turn for the prompt, without modifying the permanent history.
|
|
19
|
-
*/
|
|
20
|
-
getContextForPrompt(role: "user", message: string): string;
|
|
21
|
-
getCurrentContext(): string;
|
|
22
|
-
private _summarize;
|
|
23
|
-
/**
|
|
24
|
-
* Truncates the history to a specific word count, preserving the most recent messages.
|
|
25
|
-
*/
|
|
26
|
-
private _truncateHistory;
|
|
27
|
-
}
|
|
28
|
-
export {};
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { logger } from "../utils/logger.js";
|
|
2
|
-
import { formatHistoryToString } from "./utils.js";
|
|
3
|
-
/**
|
|
4
|
-
* Manages conversation context, automatically summarizing it when it
|
|
5
|
-
* exceeds a specified word count limit.
|
|
6
|
-
*/
|
|
7
|
-
export class ContextManager {
|
|
8
|
-
static SUMMARIZATION_FAILED_WARNING = "[System Warning: Context summarization failed. Conversation history has been truncated.]";
|
|
9
|
-
static SUMMARIZATION_EMPTY_WARNING = "[System Warning: Context summarization failed to return valid content. Conversation history has been truncated.]";
|
|
10
|
-
history;
|
|
11
|
-
wordCount;
|
|
12
|
-
internalGenerator;
|
|
13
|
-
config;
|
|
14
|
-
constructor(generatorFunction, config, initialContext = "This is the start of the conversation.") {
|
|
15
|
-
this.internalGenerator = generatorFunction;
|
|
16
|
-
this.config = config;
|
|
17
|
-
const initialMessage = {
|
|
18
|
-
role: "system",
|
|
19
|
-
content: initialContext,
|
|
20
|
-
};
|
|
21
|
-
initialMessage.wordCount = this.config.estimateWordCount([initialMessage]);
|
|
22
|
-
this.history = [initialMessage];
|
|
23
|
-
this.wordCount = initialMessage.wordCount;
|
|
24
|
-
}
|
|
25
|
-
async addTurn(role, message) {
|
|
26
|
-
const newMessage = { role, content: message };
|
|
27
|
-
newMessage.wordCount = this.config.estimateWordCount([newMessage]);
|
|
28
|
-
this.history.push(newMessage);
|
|
29
|
-
this.wordCount += newMessage.wordCount;
|
|
30
|
-
logger.info(`[ContextManager] Current word count: ${this.wordCount} / ${this.config.highWaterMarkWords}`);
|
|
31
|
-
if (this.wordCount > this.config.highWaterMarkWords) {
|
|
32
|
-
await this._summarize();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Formats the history including the latest user turn for the prompt, without modifying the permanent history.
|
|
37
|
-
*/
|
|
38
|
-
getContextForPrompt(role, message) {
|
|
39
|
-
const tempHistory = [...this.history, { role, content: message }];
|
|
40
|
-
return formatHistoryToString(tempHistory);
|
|
41
|
-
}
|
|
42
|
-
getCurrentContext() {
|
|
43
|
-
// Format the history into a single string for the provider prompt
|
|
44
|
-
return formatHistoryToString(this.history);
|
|
45
|
-
}
|
|
46
|
-
async _summarize() {
|
|
47
|
-
try {
|
|
48
|
-
const prompt = this.config.getSummarizationPrompt(this.history, this.config.lowWaterMarkWords);
|
|
49
|
-
// Construct options for the internal method, bypassing the main 'generate' entry point
|
|
50
|
-
const textOptions = {
|
|
51
|
-
prompt,
|
|
52
|
-
provider: this.config.summarizationProvider,
|
|
53
|
-
model: this.config.summarizationModel,
|
|
54
|
-
// Ensure summarization does not trigger more context management or tools
|
|
55
|
-
disableTools: true,
|
|
56
|
-
};
|
|
57
|
-
// Call the internal generation function directly to avoid recursion
|
|
58
|
-
const result = await this.internalGenerator(textOptions);
|
|
59
|
-
if (typeof result.content === "string" && result.content.length > 0) {
|
|
60
|
-
// Replace the history with a single system message containing the summary
|
|
61
|
-
const newHistory = [
|
|
62
|
-
{ role: "system", content: result.content },
|
|
63
|
-
];
|
|
64
|
-
this.history = newHistory;
|
|
65
|
-
this.wordCount = this.config.estimateWordCount(this.history);
|
|
66
|
-
logger.info(`[ContextManager] Summarization complete. New history length: ${this.wordCount} words.`);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
logger.warn("[ContextManager] Summarization returned empty or non-string content; truncating history as a fallback.");
|
|
70
|
-
this._truncateHistory(this.config.lowWaterMarkWords);
|
|
71
|
-
this.history.unshift({
|
|
72
|
-
role: "system",
|
|
73
|
-
content: ContextManager.SUMMARIZATION_EMPTY_WARNING,
|
|
74
|
-
});
|
|
75
|
-
this.wordCount = this.config.estimateWordCount(this.history);
|
|
76
|
-
}
|
|
77
|
-
logger.debug(`[ContextManager] New history: ${JSON.stringify(this.history)}`);
|
|
78
|
-
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
logger.error("Context summarization failed:", { error });
|
|
81
|
-
// Fallback strategy: truncate the history to the target word count.
|
|
82
|
-
this._truncateHistory(this.config.lowWaterMarkWords);
|
|
83
|
-
this.history.unshift({
|
|
84
|
-
role: "system",
|
|
85
|
-
content: ContextManager.SUMMARIZATION_FAILED_WARNING,
|
|
86
|
-
});
|
|
87
|
-
this.wordCount = this.config.estimateWordCount(this.history);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Truncates the history to a specific word count, preserving the most recent messages.
|
|
92
|
-
*/
|
|
93
|
-
_truncateHistory(wordLimit) {
|
|
94
|
-
if (this.wordCount <= wordLimit) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
let runningCount = 0;
|
|
98
|
-
let sliceIndex = this.history.length;
|
|
99
|
-
for (let i = this.history.length - 1; i >= 0; i--) {
|
|
100
|
-
let wordCount = this.history[i].wordCount;
|
|
101
|
-
if (wordCount === undefined) {
|
|
102
|
-
logger.warn(`[ContextManager] Word count cache missing for message at index ${i}. Recalculating.`);
|
|
103
|
-
wordCount = this.config.estimateWordCount([this.history[i]]);
|
|
104
|
-
}
|
|
105
|
-
runningCount += wordCount;
|
|
106
|
-
if (runningCount > wordLimit) {
|
|
107
|
-
sliceIndex = i + 1;
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
this.history = this.history.slice(sliceIndex);
|
|
112
|
-
}
|
|
113
|
-
}
|