@juspay/neurolink 7.23.0 → 7.24.1
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 +8 -0
- package/dist/cli/index.js +8 -66
- package/dist/lib/providers/anthropic.js +25 -33
- package/dist/lib/providers/googleAiStudio.js +10 -11
- package/dist/lib/providers/openAI.js +15 -6
- package/dist/lib/types/errors.d.ts +44 -0
- package/dist/lib/types/errors.js +60 -0
- package/dist/providers/anthropic.js +25 -33
- package/dist/providers/googleAiStudio.js +10 -11
- package/dist/providers/openAI.js +15 -6
- package/dist/types/errors.d.ts +44 -0
- package/dist/types/errors.js +60 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [7.24.1](https://github.com/juspay/neurolink/compare/v7.24.0...v7.24.1) (2025-08-21)
|
|
2
|
+
|
|
3
|
+
## [7.24.0](https://github.com/juspay/neurolink/compare/v7.23.0...v7.24.0) (2025-08-20)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **(deploy):** Added a configurable force-rebuild flag for the deploy command. ([e5a81d4](https://github.com/juspay/neurolink/commit/e5a81d4df2ff3dd6a1b81d74beb0bca50015f207))
|
|
8
|
+
|
|
1
9
|
## [7.23.0](https://github.com/juspay/neurolink/compare/v7.22.0...v7.23.0) (2025-08-19)
|
|
2
10
|
|
|
3
11
|
### Features
|
package/dist/cli/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { fileURLToPath } from "url";
|
|
|
14
14
|
import { addOllamaCommands } from "./commands/ollama.js";
|
|
15
15
|
import { addSageMakerCommands } from "./commands/sagemaker.js";
|
|
16
16
|
import { CLICommandFactory } from "./factories/commandFactory.js";
|
|
17
|
+
import { AuthenticationError, AuthorizationError, NetworkError, RateLimitError, } from "../lib/types/errors.js";
|
|
17
18
|
import { logger } from "../lib/utils/logger.js";
|
|
18
19
|
// Get version from package.json
|
|
19
20
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -32,69 +33,8 @@ catch (error) {
|
|
|
32
33
|
}
|
|
33
34
|
// Utility Functions (Simple, Zero Maintenance)
|
|
34
35
|
function handleError(error, context) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
? error.message.toLowerCase()
|
|
38
|
-
: "";
|
|
39
|
-
const errorStringLowerCase = String(error).toLowerCase();
|
|
40
|
-
let isAuthError = false;
|
|
41
|
-
let genericMessage = specificErrorMessage; // Initialize genericMessage with the specific one
|
|
42
|
-
if (originalErrorMessageLowerCase.includes("api_key") ||
|
|
43
|
-
originalErrorMessageLowerCase.includes("google_ai_api_key") ||
|
|
44
|
-
originalErrorMessageLowerCase.includes("aws_access_key_id") ||
|
|
45
|
-
originalErrorMessageLowerCase.includes("aws_secret_access_key") ||
|
|
46
|
-
originalErrorMessageLowerCase.includes("aws_session_token") ||
|
|
47
|
-
originalErrorMessageLowerCase.includes("google_application_credentials") ||
|
|
48
|
-
originalErrorMessageLowerCase.includes("google_service_account_key") ||
|
|
49
|
-
originalErrorMessageLowerCase.includes("google_auth_client_email") ||
|
|
50
|
-
originalErrorMessageLowerCase.includes("anthropic_api_key") ||
|
|
51
|
-
originalErrorMessageLowerCase.includes("azure_openai_api_key")) {
|
|
52
|
-
isAuthError = true;
|
|
53
|
-
}
|
|
54
|
-
else if (
|
|
55
|
-
// Fallback to checking the full stringified error if direct message didn't match
|
|
56
|
-
errorStringLowerCase.includes("api_key") ||
|
|
57
|
-
errorStringLowerCase.includes("google_ai_api_key") ||
|
|
58
|
-
errorStringLowerCase.includes("aws_access_key_id") ||
|
|
59
|
-
errorStringLowerCase.includes("aws_secret_access_key") ||
|
|
60
|
-
errorStringLowerCase.includes("aws_session_token") ||
|
|
61
|
-
errorStringLowerCase.includes("google_application_credentials") ||
|
|
62
|
-
errorStringLowerCase.includes("google_service_account_key") ||
|
|
63
|
-
errorStringLowerCase.includes("google_auth_client_email") ||
|
|
64
|
-
errorStringLowerCase.includes("anthropic_api_key") ||
|
|
65
|
-
errorStringLowerCase.includes("azure_openai_api_key")) {
|
|
66
|
-
isAuthError = true;
|
|
67
|
-
}
|
|
68
|
-
if (isAuthError) {
|
|
69
|
-
genericMessage =
|
|
70
|
-
"Authentication error: Missing or invalid API key/credentials for the selected provider.";
|
|
71
|
-
}
|
|
72
|
-
else if (originalErrorMessageLowerCase.includes("enotfound") || // Prefer direct message checks
|
|
73
|
-
originalErrorMessageLowerCase.includes("econnrefused") ||
|
|
74
|
-
originalErrorMessageLowerCase.includes("invalid-endpoint") ||
|
|
75
|
-
originalErrorMessageLowerCase.includes("network error") ||
|
|
76
|
-
originalErrorMessageLowerCase.includes("could not connect") ||
|
|
77
|
-
originalErrorMessageLowerCase.includes("timeout") ||
|
|
78
|
-
errorStringLowerCase.includes("enotfound") || // Fallback to full string
|
|
79
|
-
errorStringLowerCase.includes("econnrefused") ||
|
|
80
|
-
errorStringLowerCase.includes("invalid-endpoint") ||
|
|
81
|
-
errorStringLowerCase.includes("network error") ||
|
|
82
|
-
errorStringLowerCase.includes("could not connect") ||
|
|
83
|
-
errorStringLowerCase.includes("timeout") // General timeout
|
|
84
|
-
) {
|
|
85
|
-
genericMessage =
|
|
86
|
-
"Network error: Could not connect to the API endpoint or the request timed out.";
|
|
87
|
-
}
|
|
88
|
-
else if (errorStringLowerCase.includes("not authorized") ||
|
|
89
|
-
errorStringLowerCase.includes("permission denied")) {
|
|
90
|
-
genericMessage =
|
|
91
|
-
"Authorization error: You are not authorized to perform this action or access this resource.";
|
|
92
|
-
}
|
|
93
|
-
// If no specific condition matched, genericMessage remains error.message
|
|
94
|
-
logger.error(chalk.red(`❌ ${context} failed: ${genericMessage}`));
|
|
95
|
-
// Smart hints for common errors (just string matching!)
|
|
96
|
-
if (genericMessage.toLowerCase().includes("api key") ||
|
|
97
|
-
genericMessage.toLowerCase().includes("credential")) {
|
|
36
|
+
logger.error(chalk.red(`❌ ${context} failed: ${error.message}`));
|
|
37
|
+
if (error instanceof AuthenticationError) {
|
|
98
38
|
logger.error(chalk.yellow("💡 Set Google AI Studio API key (RECOMMENDED): export GOOGLE_AI_API_KEY=AIza-..."));
|
|
99
39
|
logger.error(chalk.yellow("💡 Or set OpenAI API key: export OPENAI_API_KEY=sk-..."));
|
|
100
40
|
logger.error(chalk.yellow("💡 Or set AWS Bedrock credentials: export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... AWS_REGION=us-east-1"));
|
|
@@ -102,14 +42,16 @@ function handleError(error, context) {
|
|
|
102
42
|
logger.error(chalk.yellow("💡 Or set Anthropic API key: export ANTHROPIC_API_KEY=sk-ant-..."));
|
|
103
43
|
logger.error(chalk.yellow("💡 Or set Azure OpenAI credentials: export AZURE_OPENAI_API_KEY=... AZURE_OPENAI_ENDPOINT=..."));
|
|
104
44
|
}
|
|
105
|
-
if (error
|
|
45
|
+
else if (error instanceof RateLimitError) {
|
|
106
46
|
logger.error(chalk.yellow("💡 Try again in a few moments or use --provider vertex"));
|
|
107
47
|
}
|
|
108
|
-
if (error
|
|
109
|
-
error.message.toLowerCase().includes("permission denied")) {
|
|
48
|
+
else if (error instanceof AuthorizationError) {
|
|
110
49
|
logger.error(chalk.yellow("💡 Check your account permissions for the selected model/service."));
|
|
111
50
|
logger.error(chalk.yellow("💡 For AWS Bedrock, ensure you have permissions for the specific model and consider using inference profile ARNs."));
|
|
112
51
|
}
|
|
52
|
+
else if (error instanceof NetworkError) {
|
|
53
|
+
logger.error(chalk.yellow("💡 Check your internet connection and the provider's status page."));
|
|
54
|
+
}
|
|
113
55
|
process.exit(1);
|
|
114
56
|
}
|
|
115
57
|
// Manual pre-validation for unknown flags
|
|
@@ -3,6 +3,7 @@ import { streamText } from "ai";
|
|
|
3
3
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
4
4
|
import { logger } from "../utils/logger.js";
|
|
5
5
|
import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
|
|
6
|
+
import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
|
|
6
7
|
import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
|
|
7
8
|
import { validateApiKey, createAnthropicConfig, getProviderModel, } from "../utils/providerConfig.js";
|
|
8
9
|
import { buildMessagesArray } from "../utils/messageBuilder.js";
|
|
@@ -50,45 +51,36 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
50
51
|
}
|
|
51
52
|
handleProviderError(error) {
|
|
52
53
|
if (error instanceof TimeoutError) {
|
|
53
|
-
|
|
54
|
+
throw new NetworkError(`Request timed out after ${error.timeout}ms`, this.providerName);
|
|
54
55
|
}
|
|
55
56
|
const errorRecord = error;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
const message = typeof errorRecord?.message === "string"
|
|
58
|
+
? errorRecord.message
|
|
59
|
+
: "Unknown error";
|
|
60
|
+
if (message.includes("API_KEY_INVALID") ||
|
|
61
|
+
message.includes("Invalid API key")) {
|
|
62
|
+
throw new AuthenticationError("Invalid Anthropic API key. Please check your ANTHROPIC_API_KEY environment variable.", this.providerName);
|
|
62
63
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
errorRecord.message.includes("429"))) {
|
|
68
|
-
return new Error("Anthropic rate limit exceeded. Please try again later.");
|
|
64
|
+
if (message.includes("rate limit") ||
|
|
65
|
+
message.includes("too_many_requests") ||
|
|
66
|
+
message.includes("429")) {
|
|
67
|
+
throw new RateLimitError("Anthropic rate limit exceeded. Please try again later.", this.providerName);
|
|
69
68
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
errorRecord.message.includes("connection"))) {
|
|
77
|
-
return new Error("Anthropic API connection error. Please check your internet connection and try again.");
|
|
69
|
+
if (message.includes("ECONNRESET") ||
|
|
70
|
+
message.includes("ENOTFOUND") ||
|
|
71
|
+
message.includes("ECONNREFUSED") ||
|
|
72
|
+
message.includes("network") ||
|
|
73
|
+
message.includes("connection")) {
|
|
74
|
+
throw new NetworkError(`Connection error: ${message}`, this.providerName);
|
|
78
75
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
errorRecord.message.includes("server error"))) {
|
|
86
|
-
return new Error("Anthropic API server error. Please try again in a few moments.");
|
|
76
|
+
if (message.includes("500") ||
|
|
77
|
+
message.includes("502") ||
|
|
78
|
+
message.includes("503") ||
|
|
79
|
+
message.includes("504") ||
|
|
80
|
+
message.includes("server error")) {
|
|
81
|
+
throw new ProviderError(`Server error: ${message}`, this.providerName);
|
|
87
82
|
}
|
|
88
|
-
|
|
89
|
-
? errorRecord.message
|
|
90
|
-
: "Unknown error";
|
|
91
|
-
return new Error(`Anthropic error: ${message}`);
|
|
83
|
+
throw new ProviderError(`Anthropic error: ${message}`, this.providerName);
|
|
92
84
|
}
|
|
93
85
|
// executeGenerate removed - BaseProvider handles all generation with tools
|
|
94
86
|
async executeStream(options, analysisSchema) {
|
|
@@ -4,6 +4,7 @@ import { GoogleAIModels } from "../core/types.js";
|
|
|
4
4
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
5
5
|
import { logger } from "../utils/logger.js";
|
|
6
6
|
import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
|
|
7
|
+
import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
|
|
7
8
|
import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
|
|
8
9
|
import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
|
|
9
10
|
import { buildMessagesArray } from "../utils/messageBuilder.js";
|
|
@@ -44,21 +45,19 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
44
45
|
}
|
|
45
46
|
handleProviderError(error) {
|
|
46
47
|
if (error instanceof TimeoutError) {
|
|
47
|
-
|
|
48
|
+
throw new NetworkError(error.message, this.providerName);
|
|
48
49
|
}
|
|
49
50
|
const errorRecord = error;
|
|
50
|
-
if (typeof errorRecord?.message === "string" &&
|
|
51
|
-
errorRecord.message.includes("API_KEY_INVALID")) {
|
|
52
|
-
return new Error("Invalid Google AI API key. Please check your GOOGLE_AI_API_KEY environment variable.");
|
|
53
|
-
}
|
|
54
|
-
if (typeof errorRecord?.message === "string" &&
|
|
55
|
-
errorRecord.message.includes("RATE_LIMIT_EXCEEDED")) {
|
|
56
|
-
return new Error("Google AI rate limit exceeded. Please try again later.");
|
|
57
|
-
}
|
|
58
51
|
const message = typeof errorRecord?.message === "string"
|
|
59
52
|
? errorRecord.message
|
|
60
53
|
: "Unknown error";
|
|
61
|
-
|
|
54
|
+
if (message.includes("API_KEY_INVALID")) {
|
|
55
|
+
throw new AuthenticationError("Invalid Google AI API key. Please check your GOOGLE_AI_API_KEY environment variable.", this.providerName);
|
|
56
|
+
}
|
|
57
|
+
if (message.includes("RATE_LIMIT_EXCEEDED")) {
|
|
58
|
+
throw new RateLimitError("Google AI rate limit exceeded. Please try again later.", this.providerName);
|
|
59
|
+
}
|
|
60
|
+
throw new ProviderError(`Google AI error: ${message}`, this.providerName);
|
|
62
61
|
}
|
|
63
62
|
// executeGenerate removed - BaseProvider handles all generation with tools
|
|
64
63
|
async executeStream(options, analysisSchema) {
|
|
@@ -119,7 +118,7 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
119
118
|
getApiKey() {
|
|
120
119
|
const apiKey = process.env.GOOGLE_AI_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
121
120
|
if (!apiKey) {
|
|
122
|
-
throw new
|
|
121
|
+
throw new AuthenticationError("GOOGLE_AI_API_KEY or GOOGLE_GENERATIVE_AI_API_KEY environment variable is not set", this.providerName);
|
|
123
122
|
}
|
|
124
123
|
return apiKey;
|
|
125
124
|
}
|
|
@@ -4,6 +4,7 @@ import { AIProviderName } from "../core/types.js";
|
|
|
4
4
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
5
5
|
import { logger } from "../utils/logger.js";
|
|
6
6
|
import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
|
|
7
|
+
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
|
|
7
8
|
import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
|
|
8
9
|
import { validateApiKey, createOpenAIConfig, getProviderModel, } from "../utils/providerConfig.js";
|
|
9
10
|
import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
|
|
@@ -53,20 +54,28 @@ export class OpenAIProvider extends BaseProvider {
|
|
|
53
54
|
}
|
|
54
55
|
handleProviderError(error) {
|
|
55
56
|
if (error instanceof TimeoutError) {
|
|
56
|
-
|
|
57
|
+
throw new NetworkError(error.message, this.providerName);
|
|
57
58
|
}
|
|
58
59
|
const errorObj = error;
|
|
59
60
|
const message = errorObj?.message && typeof errorObj.message === "string"
|
|
60
61
|
? errorObj.message
|
|
61
62
|
: "Unknown error";
|
|
63
|
+
const errorType = errorObj?.type && typeof errorObj.type === "string"
|
|
64
|
+
? errorObj.type
|
|
65
|
+
: undefined;
|
|
62
66
|
if (message.includes("API_KEY_INVALID") ||
|
|
63
|
-
message.includes("Invalid API key")
|
|
64
|
-
|
|
67
|
+
message.includes("Invalid API key") ||
|
|
68
|
+
errorType === "invalid_api_key") {
|
|
69
|
+
throw new AuthenticationError("Invalid OpenAI API key. Please check your OPENAI_API_KEY environment variable.", this.providerName);
|
|
65
70
|
}
|
|
66
|
-
if (message.includes("rate limit")) {
|
|
67
|
-
|
|
71
|
+
if (message.includes("rate limit") || errorType === "rate_limit_error") {
|
|
72
|
+
throw new RateLimitError("OpenAI rate limit exceeded. Please try again later.", this.providerName);
|
|
68
73
|
}
|
|
69
|
-
|
|
74
|
+
if (message.includes("model_not_found")) {
|
|
75
|
+
throw new InvalidModelError(`Model not found: ${this.modelName}`, this.providerName);
|
|
76
|
+
}
|
|
77
|
+
// Generic provider error
|
|
78
|
+
throw new ProviderError(`OpenAI error: ${message}`, this.providerName);
|
|
70
79
|
}
|
|
71
80
|
/**
|
|
72
81
|
* executeGenerate method removed - generation is now handled by BaseProvider.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all NeuroLink-specific errors.
|
|
3
|
+
* This allows for easy identification of errors thrown by the SDK.
|
|
4
|
+
*/
|
|
5
|
+
export declare class BaseError extends Error {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Thrown when a provider encounters a generic error.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ProviderError extends BaseError {
|
|
12
|
+
provider?: string | undefined;
|
|
13
|
+
constructor(message: string, provider?: string | undefined);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Thrown for authentication-related errors, such as invalid or missing API keys.
|
|
17
|
+
*/
|
|
18
|
+
export declare class AuthenticationError extends ProviderError {
|
|
19
|
+
constructor(message: string, provider?: string);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Thrown for authorization errors, where the user does not have permission.
|
|
23
|
+
*/
|
|
24
|
+
export declare class AuthorizationError extends ProviderError {
|
|
25
|
+
constructor(message: string, provider?: string);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Thrown for network-related issues, such as connectivity problems or timeouts.
|
|
29
|
+
*/
|
|
30
|
+
export declare class NetworkError extends ProviderError {
|
|
31
|
+
constructor(message: string, provider?: string);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Thrown when an API rate limit has been exceeded.
|
|
35
|
+
*/
|
|
36
|
+
export declare class RateLimitError extends ProviderError {
|
|
37
|
+
constructor(message: string, provider?: string);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Thrown when a specified model is not found or is invalid for the provider.
|
|
41
|
+
*/
|
|
42
|
+
export declare class InvalidModelError extends ProviderError {
|
|
43
|
+
constructor(message: string, provider?: string);
|
|
44
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all NeuroLink-specific errors.
|
|
3
|
+
* This allows for easy identification of errors thrown by the SDK.
|
|
4
|
+
*/
|
|
5
|
+
export class BaseError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = this.constructor.name;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Thrown when a provider encounters a generic error.
|
|
13
|
+
*/
|
|
14
|
+
export class ProviderError extends BaseError {
|
|
15
|
+
provider;
|
|
16
|
+
constructor(message, provider) {
|
|
17
|
+
super(provider ? `[${provider}] ${message}` : message);
|
|
18
|
+
this.provider = provider;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Thrown for authentication-related errors, such as invalid or missing API keys.
|
|
23
|
+
*/
|
|
24
|
+
export class AuthenticationError extends ProviderError {
|
|
25
|
+
constructor(message, provider) {
|
|
26
|
+
super(message, provider);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Thrown for authorization errors, where the user does not have permission.
|
|
31
|
+
*/
|
|
32
|
+
export class AuthorizationError extends ProviderError {
|
|
33
|
+
constructor(message, provider) {
|
|
34
|
+
super(message, provider);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Thrown for network-related issues, such as connectivity problems or timeouts.
|
|
39
|
+
*/
|
|
40
|
+
export class NetworkError extends ProviderError {
|
|
41
|
+
constructor(message, provider) {
|
|
42
|
+
super(message, provider);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Thrown when an API rate limit has been exceeded.
|
|
47
|
+
*/
|
|
48
|
+
export class RateLimitError extends ProviderError {
|
|
49
|
+
constructor(message, provider) {
|
|
50
|
+
super(message, provider);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Thrown when a specified model is not found or is invalid for the provider.
|
|
55
|
+
*/
|
|
56
|
+
export class InvalidModelError extends ProviderError {
|
|
57
|
+
constructor(message, provider) {
|
|
58
|
+
super(message, provider);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -3,6 +3,7 @@ import { streamText } from "ai";
|
|
|
3
3
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
4
4
|
import { logger } from "../utils/logger.js";
|
|
5
5
|
import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
|
|
6
|
+
import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
|
|
6
7
|
import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
|
|
7
8
|
import { validateApiKey, createAnthropicConfig, getProviderModel, } from "../utils/providerConfig.js";
|
|
8
9
|
import { buildMessagesArray } from "../utils/messageBuilder.js";
|
|
@@ -50,45 +51,36 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
50
51
|
}
|
|
51
52
|
handleProviderError(error) {
|
|
52
53
|
if (error instanceof TimeoutError) {
|
|
53
|
-
|
|
54
|
+
throw new NetworkError(`Request timed out after ${error.timeout}ms`, this.providerName);
|
|
54
55
|
}
|
|
55
56
|
const errorRecord = error;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
const message = typeof errorRecord?.message === "string"
|
|
58
|
+
? errorRecord.message
|
|
59
|
+
: "Unknown error";
|
|
60
|
+
if (message.includes("API_KEY_INVALID") ||
|
|
61
|
+
message.includes("Invalid API key")) {
|
|
62
|
+
throw new AuthenticationError("Invalid Anthropic API key. Please check your ANTHROPIC_API_KEY environment variable.", this.providerName);
|
|
62
63
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
errorRecord.message.includes("429"))) {
|
|
68
|
-
return new Error("Anthropic rate limit exceeded. Please try again later.");
|
|
64
|
+
if (message.includes("rate limit") ||
|
|
65
|
+
message.includes("too_many_requests") ||
|
|
66
|
+
message.includes("429")) {
|
|
67
|
+
throw new RateLimitError("Anthropic rate limit exceeded. Please try again later.", this.providerName);
|
|
69
68
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
errorRecord.message.includes("connection"))) {
|
|
77
|
-
return new Error("Anthropic API connection error. Please check your internet connection and try again.");
|
|
69
|
+
if (message.includes("ECONNRESET") ||
|
|
70
|
+
message.includes("ENOTFOUND") ||
|
|
71
|
+
message.includes("ECONNREFUSED") ||
|
|
72
|
+
message.includes("network") ||
|
|
73
|
+
message.includes("connection")) {
|
|
74
|
+
throw new NetworkError(`Connection error: ${message}`, this.providerName);
|
|
78
75
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
errorRecord.message.includes("server error"))) {
|
|
86
|
-
return new Error("Anthropic API server error. Please try again in a few moments.");
|
|
76
|
+
if (message.includes("500") ||
|
|
77
|
+
message.includes("502") ||
|
|
78
|
+
message.includes("503") ||
|
|
79
|
+
message.includes("504") ||
|
|
80
|
+
message.includes("server error")) {
|
|
81
|
+
throw new ProviderError(`Server error: ${message}`, this.providerName);
|
|
87
82
|
}
|
|
88
|
-
|
|
89
|
-
? errorRecord.message
|
|
90
|
-
: "Unknown error";
|
|
91
|
-
return new Error(`Anthropic error: ${message}`);
|
|
83
|
+
throw new ProviderError(`Anthropic error: ${message}`, this.providerName);
|
|
92
84
|
}
|
|
93
85
|
// executeGenerate removed - BaseProvider handles all generation with tools
|
|
94
86
|
async executeStream(options, analysisSchema) {
|
|
@@ -4,6 +4,7 @@ import { GoogleAIModels } from "../core/types.js";
|
|
|
4
4
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
5
5
|
import { logger } from "../utils/logger.js";
|
|
6
6
|
import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
|
|
7
|
+
import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
|
|
7
8
|
import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
|
|
8
9
|
import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
|
|
9
10
|
import { buildMessagesArray } from "../utils/messageBuilder.js";
|
|
@@ -44,21 +45,19 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
44
45
|
}
|
|
45
46
|
handleProviderError(error) {
|
|
46
47
|
if (error instanceof TimeoutError) {
|
|
47
|
-
|
|
48
|
+
throw new NetworkError(error.message, this.providerName);
|
|
48
49
|
}
|
|
49
50
|
const errorRecord = error;
|
|
50
|
-
if (typeof errorRecord?.message === "string" &&
|
|
51
|
-
errorRecord.message.includes("API_KEY_INVALID")) {
|
|
52
|
-
return new Error("Invalid Google AI API key. Please check your GOOGLE_AI_API_KEY environment variable.");
|
|
53
|
-
}
|
|
54
|
-
if (typeof errorRecord?.message === "string" &&
|
|
55
|
-
errorRecord.message.includes("RATE_LIMIT_EXCEEDED")) {
|
|
56
|
-
return new Error("Google AI rate limit exceeded. Please try again later.");
|
|
57
|
-
}
|
|
58
51
|
const message = typeof errorRecord?.message === "string"
|
|
59
52
|
? errorRecord.message
|
|
60
53
|
: "Unknown error";
|
|
61
|
-
|
|
54
|
+
if (message.includes("API_KEY_INVALID")) {
|
|
55
|
+
throw new AuthenticationError("Invalid Google AI API key. Please check your GOOGLE_AI_API_KEY environment variable.", this.providerName);
|
|
56
|
+
}
|
|
57
|
+
if (message.includes("RATE_LIMIT_EXCEEDED")) {
|
|
58
|
+
throw new RateLimitError("Google AI rate limit exceeded. Please try again later.", this.providerName);
|
|
59
|
+
}
|
|
60
|
+
throw new ProviderError(`Google AI error: ${message}`, this.providerName);
|
|
62
61
|
}
|
|
63
62
|
// executeGenerate removed - BaseProvider handles all generation with tools
|
|
64
63
|
async executeStream(options, analysisSchema) {
|
|
@@ -119,7 +118,7 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
119
118
|
getApiKey() {
|
|
120
119
|
const apiKey = process.env.GOOGLE_AI_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
121
120
|
if (!apiKey) {
|
|
122
|
-
throw new
|
|
121
|
+
throw new AuthenticationError("GOOGLE_AI_API_KEY or GOOGLE_GENERATIVE_AI_API_KEY environment variable is not set", this.providerName);
|
|
123
122
|
}
|
|
124
123
|
return apiKey;
|
|
125
124
|
}
|
package/dist/providers/openAI.js
CHANGED
|
@@ -4,6 +4,7 @@ import { AIProviderName } from "../core/types.js";
|
|
|
4
4
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
5
5
|
import { logger } from "../utils/logger.js";
|
|
6
6
|
import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
|
|
7
|
+
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
|
|
7
8
|
import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
|
|
8
9
|
import { validateApiKey, createOpenAIConfig, getProviderModel, } from "../utils/providerConfig.js";
|
|
9
10
|
import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
|
|
@@ -53,20 +54,28 @@ export class OpenAIProvider extends BaseProvider {
|
|
|
53
54
|
}
|
|
54
55
|
handleProviderError(error) {
|
|
55
56
|
if (error instanceof TimeoutError) {
|
|
56
|
-
|
|
57
|
+
throw new NetworkError(error.message, this.providerName);
|
|
57
58
|
}
|
|
58
59
|
const errorObj = error;
|
|
59
60
|
const message = errorObj?.message && typeof errorObj.message === "string"
|
|
60
61
|
? errorObj.message
|
|
61
62
|
: "Unknown error";
|
|
63
|
+
const errorType = errorObj?.type && typeof errorObj.type === "string"
|
|
64
|
+
? errorObj.type
|
|
65
|
+
: undefined;
|
|
62
66
|
if (message.includes("API_KEY_INVALID") ||
|
|
63
|
-
message.includes("Invalid API key")
|
|
64
|
-
|
|
67
|
+
message.includes("Invalid API key") ||
|
|
68
|
+
errorType === "invalid_api_key") {
|
|
69
|
+
throw new AuthenticationError("Invalid OpenAI API key. Please check your OPENAI_API_KEY environment variable.", this.providerName);
|
|
65
70
|
}
|
|
66
|
-
if (message.includes("rate limit")) {
|
|
67
|
-
|
|
71
|
+
if (message.includes("rate limit") || errorType === "rate_limit_error") {
|
|
72
|
+
throw new RateLimitError("OpenAI rate limit exceeded. Please try again later.", this.providerName);
|
|
68
73
|
}
|
|
69
|
-
|
|
74
|
+
if (message.includes("model_not_found")) {
|
|
75
|
+
throw new InvalidModelError(`Model not found: ${this.modelName}`, this.providerName);
|
|
76
|
+
}
|
|
77
|
+
// Generic provider error
|
|
78
|
+
throw new ProviderError(`OpenAI error: ${message}`, this.providerName);
|
|
70
79
|
}
|
|
71
80
|
/**
|
|
72
81
|
* executeGenerate method removed - generation is now handled by BaseProvider.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all NeuroLink-specific errors.
|
|
3
|
+
* This allows for easy identification of errors thrown by the SDK.
|
|
4
|
+
*/
|
|
5
|
+
export declare class BaseError extends Error {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Thrown when a provider encounters a generic error.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ProviderError extends BaseError {
|
|
12
|
+
provider?: string | undefined;
|
|
13
|
+
constructor(message: string, provider?: string | undefined);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Thrown for authentication-related errors, such as invalid or missing API keys.
|
|
17
|
+
*/
|
|
18
|
+
export declare class AuthenticationError extends ProviderError {
|
|
19
|
+
constructor(message: string, provider?: string);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Thrown for authorization errors, where the user does not have permission.
|
|
23
|
+
*/
|
|
24
|
+
export declare class AuthorizationError extends ProviderError {
|
|
25
|
+
constructor(message: string, provider?: string);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Thrown for network-related issues, such as connectivity problems or timeouts.
|
|
29
|
+
*/
|
|
30
|
+
export declare class NetworkError extends ProviderError {
|
|
31
|
+
constructor(message: string, provider?: string);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Thrown when an API rate limit has been exceeded.
|
|
35
|
+
*/
|
|
36
|
+
export declare class RateLimitError extends ProviderError {
|
|
37
|
+
constructor(message: string, provider?: string);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Thrown when a specified model is not found or is invalid for the provider.
|
|
41
|
+
*/
|
|
42
|
+
export declare class InvalidModelError extends ProviderError {
|
|
43
|
+
constructor(message: string, provider?: string);
|
|
44
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all NeuroLink-specific errors.
|
|
3
|
+
* This allows for easy identification of errors thrown by the SDK.
|
|
4
|
+
*/
|
|
5
|
+
export class BaseError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = this.constructor.name;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Thrown when a provider encounters a generic error.
|
|
13
|
+
*/
|
|
14
|
+
export class ProviderError extends BaseError {
|
|
15
|
+
provider;
|
|
16
|
+
constructor(message, provider) {
|
|
17
|
+
super(provider ? `[${provider}] ${message}` : message);
|
|
18
|
+
this.provider = provider;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Thrown for authentication-related errors, such as invalid or missing API keys.
|
|
23
|
+
*/
|
|
24
|
+
export class AuthenticationError extends ProviderError {
|
|
25
|
+
constructor(message, provider) {
|
|
26
|
+
super(message, provider);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Thrown for authorization errors, where the user does not have permission.
|
|
31
|
+
*/
|
|
32
|
+
export class AuthorizationError extends ProviderError {
|
|
33
|
+
constructor(message, provider) {
|
|
34
|
+
super(message, provider);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Thrown for network-related issues, such as connectivity problems or timeouts.
|
|
39
|
+
*/
|
|
40
|
+
export class NetworkError extends ProviderError {
|
|
41
|
+
constructor(message, provider) {
|
|
42
|
+
super(message, provider);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Thrown when an API rate limit has been exceeded.
|
|
47
|
+
*/
|
|
48
|
+
export class RateLimitError extends ProviderError {
|
|
49
|
+
constructor(message, provider) {
|
|
50
|
+
super(message, provider);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Thrown when a specified model is not found or is invalid for the provider.
|
|
55
|
+
*/
|
|
56
|
+
export class InvalidModelError extends ProviderError {
|
|
57
|
+
constructor(message, provider) {
|
|
58
|
+
super(message, provider);
|
|
59
|
+
}
|
|
60
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.24.1",
|
|
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",
|