@juspay/neurolink 11.0.0 → 11.1.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 +6 -0
- package/dist/browser/neurolink.min.js +524 -524
- package/dist/cli/commands/setup.d.ts +4 -0
- package/dist/cli/commands/setup.js +19 -33
- package/dist/cli/factories/commandFactory.d.ts +1157 -1
- package/dist/cli/factories/commandFactory.js +20 -53
- package/dist/factories/providerDescriptors.d.ts +18 -0
- package/dist/factories/providerDescriptors.js +536 -0
- package/dist/factories/providerFactory.d.ts +25 -14
- package/dist/factories/providerFactory.js +46 -23
- package/dist/factories/providerRegistry.js +31 -30
- package/dist/index.d.ts +10 -1
- package/dist/index.js +13 -3
- package/dist/lib/factories/providerDescriptors.d.ts +18 -0
- package/dist/lib/factories/providerDescriptors.js +537 -0
- package/dist/lib/factories/providerFactory.d.ts +25 -14
- package/dist/lib/factories/providerFactory.js +46 -23
- package/dist/lib/factories/providerRegistry.js +31 -30
- package/dist/lib/index.d.ts +10 -1
- package/dist/lib/index.js +13 -3
- package/dist/lib/neurolink.js +25 -37
- package/dist/lib/providers/amazonBedrock/client.js +34 -16
- package/dist/lib/providers/anthropic/client.js +39 -34
- package/dist/lib/providers/azureOpenai.js +17 -15
- package/dist/lib/providers/cloudflare.js +12 -21
- package/dist/lib/providers/cohere.js +31 -25
- package/dist/lib/providers/deepseek.js +23 -26
- package/dist/lib/providers/fireworks.js +12 -21
- package/dist/lib/providers/googleAiStudio/client.d.ts +2 -0
- package/dist/lib/providers/googleAiStudio/client.js +39 -17
- package/dist/lib/providers/googleVertex/client.js +107 -99
- package/dist/lib/providers/groq.js +19 -22
- package/dist/lib/providers/huggingFace/client.js +26 -24
- package/dist/lib/providers/litellm/client.js +54 -39
- package/dist/lib/providers/llamaCpp.js +21 -18
- package/dist/lib/providers/lmStudio.js +22 -19
- package/dist/lib/providers/mistral.js +12 -24
- package/dist/lib/providers/nvidiaNim/client.js +37 -34
- package/dist/lib/providers/ollama/client.js +50 -35
- package/dist/lib/providers/openAI/client.js +37 -40
- package/dist/lib/providers/openRouter/client.js +53 -47
- package/dist/lib/providers/openaiChatCompletionsBase.js +40 -16
- package/dist/lib/providers/openaiCompatible/client.js +36 -32
- package/dist/lib/providers/perplexity.js +12 -21
- package/dist/lib/providers/togetherAi.js +12 -21
- package/dist/lib/providers/xai.js +17 -26
- package/dist/lib/server/errors.d.ts +1 -1
- package/dist/lib/server/errors.js +2 -2
- package/dist/lib/server/index.d.ts +2 -2
- package/dist/lib/server/index.js +5 -3
- package/dist/lib/server/middleware/rateLimit.d.ts +0 -4
- package/dist/lib/server/middleware/rateLimit.js +0 -4
- package/dist/lib/types/errors.d.ts +35 -0
- package/dist/lib/types/providers.d.ts +64 -0
- package/dist/lib/utils/errorClassifier.d.ts +30 -0
- package/dist/lib/utils/errorClassifier.js +94 -0
- package/dist/lib/utils/fileDetector.js +6 -43
- package/dist/lib/utils/providerHealth.d.ts +42 -7
- package/dist/lib/utils/providerHealth.js +115 -122
- package/dist/lib/utils/providerUtils.js +21 -63
- package/dist/neurolink.js +25 -37
- package/dist/providers/amazonBedrock/client.js +34 -16
- package/dist/providers/amazonSagemaker.d.ts +1 -1
- package/dist/providers/anthropic/client.js +39 -34
- package/dist/providers/azureOpenai.js +17 -15
- package/dist/providers/cloudflare.js +12 -21
- package/dist/providers/cohere.js +31 -25
- package/dist/providers/deepseek.js +23 -26
- package/dist/providers/fireworks.js +12 -21
- package/dist/providers/googleAiStudio/client.d.ts +2 -0
- package/dist/providers/googleAiStudio/client.js +39 -17
- package/dist/providers/googleVertex/client.js +107 -99
- package/dist/providers/groq.js +19 -22
- package/dist/providers/huggingFace/client.js +26 -24
- package/dist/providers/litellm/client.js +54 -39
- package/dist/providers/llamaCpp.js +21 -18
- package/dist/providers/lmStudio.js +22 -19
- package/dist/providers/mistral.js +12 -24
- package/dist/providers/nvidiaNim/client.js +37 -34
- package/dist/providers/ollama/client.js +50 -35
- package/dist/providers/openAI/client.js +37 -40
- package/dist/providers/openRouter/client.js +53 -47
- package/dist/providers/openaiChatCompletionsBase.js +40 -16
- package/dist/providers/openaiCompatible/client.js +36 -32
- package/dist/providers/perplexity.js +12 -21
- package/dist/providers/sagemaker/language-model.d.ts +2 -2
- package/dist/providers/togetherAi.js +12 -21
- package/dist/providers/xai.js +17 -26
- package/dist/server/errors.d.ts +1 -1
- package/dist/server/errors.js +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +5 -3
- package/dist/server/middleware/rateLimit.d.ts +0 -4
- package/dist/server/middleware/rateLimit.js +0 -4
- package/dist/types/errors.d.ts +35 -0
- package/dist/types/providers.d.ts +64 -0
- package/dist/utils/errorClassifier.d.ts +30 -0
- package/dist/utils/errorClassifier.js +93 -0
- package/dist/utils/fileDetector.js +6 -43
- package/dist/utils/providerHealth.d.ts +42 -7
- package/dist/utils/providerHealth.js +115 -122
- package/dist/utils/providerUtils.js +21 -63
- package/package.json +15 -70
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { AuthenticationError, InvalidModelError, NetworkError,
|
|
1
|
+
import { AuthenticationError, InvalidModelError, NetworkError, } from "../../types/index.js";
|
|
2
2
|
import { logger } from "../../utils/logger.js";
|
|
3
3
|
import { redactUrlCredentials } from "../../utils/logSanitize.js";
|
|
4
|
-
import {
|
|
4
|
+
import { classifyProviderError, DEFAULT_ERROR_RULES, } from "../../utils/errorClassifier.js";
|
|
5
5
|
import { OpenAIChatCompletionsProvider } from "../openaiChatCompletionsBase.js";
|
|
6
6
|
import { FALLBACK_OPENAI_COMPATIBLE_MODEL } from "./constants.js";
|
|
7
7
|
import { getDefaultOpenAICompatibleModel, getOpenAICompatibleConfig, } from "./utils.js";
|
|
@@ -52,36 +52,40 @@ export class OpenAICompatibleProvider extends OpenAIChatCompletionsProvider {
|
|
|
52
52
|
];
|
|
53
53
|
}
|
|
54
54
|
formatProviderError(error) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
55
|
+
const rules = [
|
|
56
|
+
// Duck-typed timeout check (name === "TimeoutError" or a "Timeout"
|
|
57
|
+
// substring) — broader than classifyProviderError's built-in
|
|
58
|
+
// `instanceof TimeoutError` handling, so it's preserved as an
|
|
59
|
+
// explicit rule rather than relying on the default.
|
|
60
|
+
{
|
|
61
|
+
match: (ctx) => ctx.errorName === "TimeoutError" || /Timeout/.test(ctx.message),
|
|
62
|
+
errorClass: NetworkError,
|
|
63
|
+
message: (ctx) => `Request timed out: ${ctx.message}`,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
match: (ctx) => /ECONNREFUSED|Failed to fetch/i.test(ctx.message),
|
|
67
|
+
errorClass: NetworkError,
|
|
68
|
+
message: () => `OpenAI Compatible endpoint not available. Please check your OPENAI_COMPATIBLE_BASE_URL: ${redactUrlCredentials(this.config.baseURL)}`,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
match: (ctx) => ctx.statusCode === 401 ||
|
|
72
|
+
/API_KEY_INVALID|Invalid API key|Unauthorized/i.test(ctx.message),
|
|
73
|
+
errorClass: AuthenticationError,
|
|
74
|
+
message: "Invalid OpenAI Compatible API key. Please check your OPENAI_COMPATIBLE_API_KEY environment variable.",
|
|
75
|
+
},
|
|
76
|
+
// "does not exist" isn't covered by DEFAULT_ERROR_RULES's
|
|
77
|
+
// model_not_found/"model not found" pattern — preserved verbatim.
|
|
78
|
+
{
|
|
79
|
+
match: (ctx) => /model/i.test(ctx.message) &&
|
|
80
|
+
(/not found/i.test(ctx.message) ||
|
|
81
|
+
/does not exist/i.test(ctx.message)),
|
|
82
|
+
errorClass: InvalidModelError,
|
|
83
|
+
message: (ctx) => `Model '${ctx.modelName}' not available on OpenAI Compatible endpoint. ` +
|
|
84
|
+
"Please check available models or use getAvailableModels() to see supported models.",
|
|
85
|
+
},
|
|
86
|
+
...DEFAULT_ERROR_RULES,
|
|
87
|
+
];
|
|
88
|
+
return classifyProviderError(error, rules, "openai-compatible", this.modelName);
|
|
85
89
|
}
|
|
86
90
|
}
|
|
87
91
|
//# sourceMappingURL=client.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PerplexityModels } from "../constants/enums.js";
|
|
2
|
-
import { AuthenticationError
|
|
2
|
+
import { AuthenticationError } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
4
|
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
5
|
+
import { classifyProviderError, DEFAULT_ERROR_RULES, } from "../utils/errorClassifier.js";
|
|
5
6
|
import { createPerplexityConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
6
|
-
import { TimeoutError } from "../utils/timeout.js";
|
|
7
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
8
8
|
const PERPLEXITY_DEFAULT_BASE_URL = "https://api.perplexity.ai";
|
|
9
9
|
const getPerplexityApiKey = () => validateApiKey(createPerplexityConfig());
|
|
@@ -54,25 +54,16 @@ export class PerplexityProvider extends OpenAIChatCompletionsProvider {
|
|
|
54
54
|
];
|
|
55
55
|
}
|
|
56
56
|
formatProviderError(error) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return new AuthenticationError("Invalid Perplexity API key. Get one at https://www.perplexity.ai/settings/api", "perplexity");
|
|
68
|
-
}
|
|
69
|
-
if (message.includes("rate limit") || message.includes("429")) {
|
|
70
|
-
return new RateLimitError("Perplexity rate limit exceeded. Back off and retry.", "perplexity");
|
|
71
|
-
}
|
|
72
|
-
if (message.includes("model_not_found") || message.includes("404")) {
|
|
73
|
-
return new InvalidModelError(`Perplexity model '${this.modelName}' not found. Use sonar, sonar-pro, sonar-reasoning, sonar-reasoning-pro, or sonar-deep-research.`, "perplexity");
|
|
74
|
-
}
|
|
75
|
-
return new ProviderError(`Perplexity error: ${message}`, "perplexity");
|
|
57
|
+
const rules = [
|
|
58
|
+
{
|
|
59
|
+
match: (ctx) => ctx.statusCode === 401 ||
|
|
60
|
+
/Invalid API key|Authentication/i.test(ctx.message),
|
|
61
|
+
errorClass: AuthenticationError,
|
|
62
|
+
message: "Invalid Perplexity API key. Get one at https://www.perplexity.ai/settings/api",
|
|
63
|
+
},
|
|
64
|
+
...DEFAULT_ERROR_RULES,
|
|
65
|
+
];
|
|
66
|
+
return classifyProviderError(error, rules, "perplexity", this.modelName);
|
|
76
67
|
}
|
|
77
68
|
}
|
|
78
69
|
//# sourceMappingURL=perplexity.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { TogetherAIModels } from "../constants/enums.js";
|
|
2
|
-
import { AuthenticationError
|
|
2
|
+
import { AuthenticationError } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
4
|
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
5
|
+
import { classifyProviderError, DEFAULT_ERROR_RULES, } from "../utils/errorClassifier.js";
|
|
5
6
|
import { createTogetherAIConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
6
|
-
import { TimeoutError } from "../utils/timeout.js";
|
|
7
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
8
8
|
const TOGETHER_DEFAULT_BASE_URL = "https://api.together.xyz/v1";
|
|
9
9
|
const getTogetherApiKey = () => validateApiKey(createTogetherAIConfig());
|
|
@@ -58,25 +58,16 @@ export class TogetherAIProvider extends OpenAIChatCompletionsProvider {
|
|
|
58
58
|
];
|
|
59
59
|
}
|
|
60
60
|
formatProviderError(error) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return new AuthenticationError("Invalid Together AI API key. Get one at https://api.together.xyz/settings/api-keys", "together-ai");
|
|
72
|
-
}
|
|
73
|
-
if (message.includes("rate limit") || message.includes("429")) {
|
|
74
|
-
return new RateLimitError("Together AI rate limit exceeded. Back off and retry.", "together-ai");
|
|
75
|
-
}
|
|
76
|
-
if (message.includes("model_not_found") || message.includes("404")) {
|
|
77
|
-
return new InvalidModelError(`Together AI model '${this.modelName}' not found. Browse the catalog at https://api.together.xyz/models`, "together-ai");
|
|
78
|
-
}
|
|
79
|
-
return new ProviderError(`Together AI error: ${message}`, "together-ai");
|
|
61
|
+
const rules = [
|
|
62
|
+
{
|
|
63
|
+
match: (ctx) => ctx.statusCode === 401 ||
|
|
64
|
+
/Invalid API key|Authentication/i.test(ctx.message),
|
|
65
|
+
errorClass: AuthenticationError,
|
|
66
|
+
message: "Invalid Together AI API key. Get one at https://api.together.xyz/settings/api-keys",
|
|
67
|
+
},
|
|
68
|
+
...DEFAULT_ERROR_RULES,
|
|
69
|
+
];
|
|
70
|
+
return classifyProviderError(error, rules, "together-ai", this.modelName);
|
|
80
71
|
}
|
|
81
72
|
}
|
|
82
73
|
//# sourceMappingURL=togetherAi.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { XaiModels } from "../constants/enums.js";
|
|
2
|
-
import { AuthenticationError,
|
|
2
|
+
import { AuthenticationError, ProviderError } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
4
|
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
5
|
+
import { classifyProviderError, DEFAULT_ERROR_RULES, } from "../utils/errorClassifier.js";
|
|
5
6
|
import { createXaiConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
6
|
-
import { TimeoutError } from "../utils/timeout.js";
|
|
7
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
8
8
|
const XAI_DEFAULT_BASE_URL = "https://api.x.ai/v1";
|
|
9
9
|
const getXaiApiKey = () => validateApiKey(createXaiConfig());
|
|
@@ -57,30 +57,21 @@ export class XaiProvider extends OpenAIChatCompletionsProvider {
|
|
|
57
57
|
];
|
|
58
58
|
}
|
|
59
59
|
formatProviderError(error) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
if (message.includes("model_not_found") || message.includes("404")) {
|
|
77
|
-
return new InvalidModelError(`xAI model '${this.modelName}' not found. Use grok-2-latest, grok-3, grok-3-mini, grok-2-vision-latest, or grok-beta.`, "xai");
|
|
78
|
-
}
|
|
79
|
-
if (message.includes("insufficient_quota") ||
|
|
80
|
-
message.includes("quota exceeded")) {
|
|
81
|
-
return new ProviderError("xAI account has insufficient quota. Top up at https://console.x.ai/", "xai");
|
|
82
|
-
}
|
|
83
|
-
return new ProviderError(`xAI error: ${message}`, "xai");
|
|
60
|
+
const rules = [
|
|
61
|
+
{
|
|
62
|
+
match: (ctx) => ctx.statusCode === 401 ||
|
|
63
|
+
/Invalid API key|Authentication|invalid_api_key/i.test(ctx.message),
|
|
64
|
+
errorClass: AuthenticationError,
|
|
65
|
+
message: "Invalid xAI API key. Please check your XAI_API_KEY environment variable. Get one at https://console.x.ai/",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
match: (ctx) => /insufficient_quota|quota exceeded/i.test(ctx.message),
|
|
69
|
+
errorClass: ProviderError,
|
|
70
|
+
message: "xAI account has insufficient quota. Top up at https://console.x.ai/",
|
|
71
|
+
},
|
|
72
|
+
...DEFAULT_ERROR_RULES,
|
|
73
|
+
];
|
|
74
|
+
return classifyProviderError(error, rules, "xai", this.modelName);
|
|
84
75
|
}
|
|
85
76
|
}
|
|
86
77
|
//# sourceMappingURL=xai.js.map
|
|
@@ -88,7 +88,7 @@ export declare class RateLimitError extends ServerAdapterError {
|
|
|
88
88
|
/**
|
|
89
89
|
* Timeout error
|
|
90
90
|
*/
|
|
91
|
-
export declare class
|
|
91
|
+
export declare class ServerTimeoutError extends ServerAdapterError {
|
|
92
92
|
constructor(timeoutMs: number, operation?: string, requestId?: string);
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
@@ -206,7 +206,7 @@ export class RateLimitError extends ServerAdapterError {
|
|
|
206
206
|
/**
|
|
207
207
|
* Timeout error
|
|
208
208
|
*/
|
|
209
|
-
export class
|
|
209
|
+
export class ServerTimeoutError extends ServerAdapterError {
|
|
210
210
|
constructor(timeoutMs, operation, requestId) {
|
|
211
211
|
super(`Operation timed out after ${timeoutMs}ms${operation ? `: ${operation}` : ""}`, ServerAdapterErrorCode.TIMEOUT, {
|
|
212
212
|
category: ErrorCategory.EXECUTION,
|
|
@@ -215,7 +215,7 @@ export class TimeoutError extends ServerAdapterError {
|
|
|
215
215
|
requestId,
|
|
216
216
|
details: { timeoutMs, operation },
|
|
217
217
|
});
|
|
218
|
-
this.name = "
|
|
218
|
+
this.name = "ServerTimeoutError";
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
/**
|
|
@@ -27,7 +27,7 @@ export { ExpressServerAdapter } from "./adapters/expressAdapter.js";
|
|
|
27
27
|
export { FastifyServerAdapter } from "./adapters/fastifyAdapter.js";
|
|
28
28
|
export { HonoServerAdapter } from "./adapters/honoAdapter.js";
|
|
29
29
|
export { KoaServerAdapter } from "./adapters/koaAdapter.js";
|
|
30
|
-
export { AlreadyRunningError, AuthenticationError, AuthorizationError, ConfigurationError, ErrorRecoveryStrategies, HandlerError, InvalidAuthenticationError, MissingDependencyError, NotRunningError, RateLimitError as ServerRateLimitError, RouteConflictError, RouteNotFoundError, ServerAdapterError, ServerStartError, ServerStopError, StreamAbortedError, StreamingError,
|
|
30
|
+
export { AlreadyRunningError, AuthenticationError as ServerAuthenticationError, AuthorizationError as ServerAuthorizationError, ConfigurationError, ErrorRecoveryStrategies, HandlerError, InvalidAuthenticationError, MissingDependencyError, NotRunningError, RateLimitError as ServerRateLimitError, RouteConflictError, RouteNotFoundError, ServerAdapterError, ServerStartError, ServerStopError, StreamAbortedError, StreamingError, ServerTimeoutError, ValidationError as ServerValidationError, WebSocketConnectionError, WebSocketError, wrapError, } from "./errors.js";
|
|
31
31
|
export { createServer, ServerAdapterFactory, } from "./factory/serverAdapterFactory.js";
|
|
32
32
|
export { createAbortSignalMiddleware, createExpressAbortMiddleware, } from "./middleware/abortSignal.js";
|
|
33
33
|
export { createAuthMiddleware, createRoleMiddleware, } from "./middleware/auth.js";
|
|
@@ -35,7 +35,7 @@ export { createCacheInvalidator, createCacheMiddleware, InMemoryCacheStore, } fr
|
|
|
35
35
|
export { createCompressionMiddleware, createErrorHandlingMiddleware, createLoggingMiddleware, createRequestIdMiddleware, createSecurityHeadersMiddleware, createTimingMiddleware, } from "./middleware/common.js";
|
|
36
36
|
export { createDeprecationMiddleware } from "./middleware/deprecation.js";
|
|
37
37
|
export { createMCPBodyAttachmentMiddleware, fastifyMCPBodyHook, } from "./middleware/mcpBodyAttachment.js";
|
|
38
|
-
export { createRateLimitMiddleware, createSlidingWindowRateLimitMiddleware, InMemoryRateLimitStore,
|
|
38
|
+
export { createRateLimitMiddleware, createSlidingWindowRateLimitMiddleware, InMemoryRateLimitStore, } from "./middleware/rateLimit.js";
|
|
39
39
|
export { CommonSchemas, createFieldValidator, createRequestValidationMiddleware, ValidationError, } from "./middleware/validation.js";
|
|
40
40
|
export { AgentExecuteRequestSchema as OpenAPIAgentExecuteRequestSchema, AgentExecuteResponseSchema, AgentInputSchema, ApiKeySecurityScheme, BasicSecurityScheme, BearerSecurityScheme, CommonParameters, ConversationMessageSchema, createApiInfo, createDeleteOperation, createErrorResponse as createOpenAPIErrorResponse, createGetOperation, createHeaderParameter, createOpenAPIGenerator, createPathParameter, createPostOperation, createQueryParameter, createServer as createOpenAPIServer, createStreamingPostOperation, createStreamingResponse, createSuccessResponse, DefaultServers, ErrorResponseSchema, generateOpenAPIFromConfig, generateOpenAPISpec, HealthResponseSchema, MCPServerStatusSchema, MCPServersListResponseSchema, MCPServerToolSchema, MetricsResponseSchema, NeuroLinkApiInfo, OpenAPIGenerator, OpenAPISchemas, ProviderInfoSchema, ReadyResponseSchema, SessionSchema, SessionsListResponseSchema, StandardErrorResponses, StandardTags, TokenUsageSchema, ToolCallSchema, ToolDefinitionSchema, ToolExecuteRequestSchema as OpenAPIToolExecuteRequestSchema, ToolExecuteResponseSchema, ToolListResponseSchema, ToolParameterSchema, } from "./openapi/index.js";
|
|
41
41
|
export { createAgentRoutes, createAllRoutes, createHealthRoutes, createMCPRoutes, createMemoryRoutes, createOpenApiRoutes, createToolRoutes, registerAllRoutes, } from "./routes/index.js";
|
package/dist/lib/server/index.js
CHANGED
|
@@ -38,7 +38,9 @@ export { KoaServerAdapter } from "./adapters/koaAdapter.js";
|
|
|
38
38
|
// ============================================
|
|
39
39
|
export { AlreadyRunningError,
|
|
40
40
|
// Authentication/Authorization errors
|
|
41
|
-
|
|
41
|
+
// (aliased: the bare names resolve to the provider-error classes of the
|
|
42
|
+
// same name from types/ on the public @juspay/neurolink surface)
|
|
43
|
+
AuthenticationError as ServerAuthenticationError, AuthorizationError as ServerAuthorizationError,
|
|
42
44
|
// Configuration errors
|
|
43
45
|
ConfigurationError,
|
|
44
46
|
// Error recovery
|
|
@@ -56,7 +58,7 @@ ServerStartError, ServerStopError, StreamAbortedError,
|
|
|
56
58
|
// Streaming errors
|
|
57
59
|
StreamingError,
|
|
58
60
|
// Timeout errors
|
|
59
|
-
|
|
61
|
+
ServerTimeoutError,
|
|
60
62
|
// Validation errors
|
|
61
63
|
ValidationError as ServerValidationError, WebSocketConnectionError,
|
|
62
64
|
// WebSocket errors
|
|
@@ -76,7 +78,7 @@ export { createCacheInvalidator, createCacheMiddleware, InMemoryCacheStore, } fr
|
|
|
76
78
|
export { createCompressionMiddleware, createErrorHandlingMiddleware, createLoggingMiddleware, createRequestIdMiddleware, createSecurityHeadersMiddleware, createTimingMiddleware, } from "./middleware/common.js";
|
|
77
79
|
export { createDeprecationMiddleware } from "./middleware/deprecation.js";
|
|
78
80
|
export { createMCPBodyAttachmentMiddleware, fastifyMCPBodyHook, } from "./middleware/mcpBodyAttachment.js";
|
|
79
|
-
export { createRateLimitMiddleware, createSlidingWindowRateLimitMiddleware, InMemoryRateLimitStore,
|
|
81
|
+
export { createRateLimitMiddleware, createSlidingWindowRateLimitMiddleware, InMemoryRateLimitStore, } from "./middleware/rateLimit.js";
|
|
80
82
|
export { CommonSchemas, createFieldValidator, createRequestValidationMiddleware, ValidationError, } from "./middleware/validation.js";
|
|
81
83
|
// ============================================
|
|
82
84
|
// OpenAPI
|
|
@@ -40,10 +40,6 @@ export declare class InMemoryRateLimitStore implements RateLimitStore {
|
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
42
|
export declare function createRateLimitMiddleware(config: RateLimitMiddlewareConfig): MiddlewareDefinition;
|
|
43
|
-
/**
|
|
44
|
-
* Re-export RateLimitError from errors for convenience
|
|
45
|
-
*/
|
|
46
|
-
export { RateLimitError } from "../errors.js";
|
|
47
43
|
/**
|
|
48
44
|
* Create a sliding window rate limiter
|
|
49
45
|
* More accurate than fixed window but slightly more complex
|
|
@@ -114,10 +114,6 @@ function defaultKeyGenerator(ctx) {
|
|
|
114
114
|
ctx.headers["x-real-ip"] ||
|
|
115
115
|
"unknown");
|
|
116
116
|
}
|
|
117
|
-
/**
|
|
118
|
-
* Re-export RateLimitError from errors for convenience
|
|
119
|
-
*/
|
|
120
|
-
export { RateLimitError } from "../errors.js";
|
|
121
117
|
/**
|
|
122
118
|
* Create a sliding window rate limiter
|
|
123
119
|
* More accurate than fixed window but slightly more complex
|
|
@@ -47,6 +47,41 @@ export declare class RateLimitError extends ProviderError {
|
|
|
47
47
|
export declare class InvalidModelError extends ProviderError {
|
|
48
48
|
constructor(message: string, provider?: string);
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Everything a ProviderErrorRule's `match`/`message` functions can inspect
|
|
52
|
+
* about a raw thrown error, pre-extracted once so every rule doesn't
|
|
53
|
+
* re-derive the same duck-typed fields.
|
|
54
|
+
*/
|
|
55
|
+
export type ProviderErrorContext = {
|
|
56
|
+
/** The raw thrown value, for rules that need custom inspection beyond the extracted fields. */
|
|
57
|
+
error: unknown;
|
|
58
|
+
/** `.message` off the raw error, or "Unknown error" if absent/non-string. */
|
|
59
|
+
message: string;
|
|
60
|
+
/** HTTP status code, duck-typed from `.statusCode` / `.status`. */
|
|
61
|
+
statusCode: number | undefined;
|
|
62
|
+
/** `.name` off the raw error (e.g. AWS SDK exception names like "ThrottlingException"). */
|
|
63
|
+
errorName: string | undefined;
|
|
64
|
+
/** `.code` off the raw error (e.g. AWS SDK / Node network error codes). */
|
|
65
|
+
errorCode: string | undefined;
|
|
66
|
+
/** Provider key passed to classifyProviderError (e.g. "mistral", "vertex"). */
|
|
67
|
+
provider: string;
|
|
68
|
+
/** Model name in effect for this call, when the caller has one available. */
|
|
69
|
+
modelName: string | undefined;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* One row of a provider's error-classification table. Rules are tried in
|
|
73
|
+
* array order; the first `match` to return true wins. `errorClass` must be
|
|
74
|
+
* `ProviderError` or one of its subclasses (AuthenticationError,
|
|
75
|
+
* RateLimitError, InvalidModelError, NetworkError, ...) sharing its
|
|
76
|
+
* `(message, provider?)` constructor shape. `message` can be a static
|
|
77
|
+
* string or a function of the context, for providers that need to
|
|
78
|
+
* interpolate a model name, a scraped retry-delay, or an AWS error code.
|
|
79
|
+
*/
|
|
80
|
+
export type ProviderErrorRule = {
|
|
81
|
+
match: (ctx: ProviderErrorContext) => boolean;
|
|
82
|
+
errorClass: new (message: string, provider?: string) => ProviderError;
|
|
83
|
+
message: string | ((ctx: ProviderErrorContext) => string);
|
|
84
|
+
};
|
|
50
85
|
/**
|
|
51
86
|
* Base class for OAuth-specific errors
|
|
52
87
|
*/
|
|
@@ -96,6 +96,7 @@ export type NeurolinkCredentials = {
|
|
|
96
96
|
};
|
|
97
97
|
googleAiStudio?: {
|
|
98
98
|
apiKey?: string;
|
|
99
|
+
baseURL?: string;
|
|
99
100
|
};
|
|
100
101
|
vertex?: {
|
|
101
102
|
projectId?: string;
|
|
@@ -888,6 +889,8 @@ export type GenAIClient = {
|
|
|
888
889
|
export type GoogleGenAIHttpOptions = {
|
|
889
890
|
/** Custom fetch implementation for proxy support */
|
|
890
891
|
fetch?: typeof fetch;
|
|
892
|
+
/** Override the API base URL (e.g. a corporate proxy or mock endpoint) */
|
|
893
|
+
baseUrl?: string;
|
|
891
894
|
};
|
|
892
895
|
/**
|
|
893
896
|
* Google GenAI constructor type
|
|
@@ -1677,6 +1680,67 @@ export type ProviderRegistration = {
|
|
|
1677
1680
|
constructor: ProviderConstructor;
|
|
1678
1681
|
defaultModel?: string;
|
|
1679
1682
|
aliases?: string[];
|
|
1683
|
+
descriptor?: ProviderDescriptor;
|
|
1684
|
+
};
|
|
1685
|
+
/**
|
|
1686
|
+
* Single source of truth for one AI provider's static identity: how it's
|
|
1687
|
+
* addressed (name/aliases), how it's authenticated (credentialsKey/envVars),
|
|
1688
|
+
* what it defaults to (defaultModel), and how the rest of the codebase
|
|
1689
|
+
* should treat it (toolSupport/localRuntime/healthCheck). Every consumer
|
|
1690
|
+
* that used to hand-maintain its own provider table (CLI choices,
|
|
1691
|
+
* CREDENTIAL_KEY_MAP, env-var checks, health-check dispatch, auto-select
|
|
1692
|
+
* priority, PROMPT_ONLY_TOOL_PROVIDERS) derives from PROVIDER_DESCRIPTORS
|
|
1693
|
+
* instead. See src/lib/factories/providerDescriptors.ts for the data.
|
|
1694
|
+
*/
|
|
1695
|
+
export type ProviderDescriptor = {
|
|
1696
|
+
/** Canonical identity — matches an AIProviderName enum member (never AUTO). */
|
|
1697
|
+
name: AIProviderName;
|
|
1698
|
+
/** Alternate spellings accepted by the CLI and the alias index (kebab-case, shorthand, legacy names). Does not include `name` itself. */
|
|
1699
|
+
aliases: readonly string[];
|
|
1700
|
+
/** Key into NeurolinkCredentials for per-call/per-instance credential overrides. */
|
|
1701
|
+
credentialsKey: keyof NeurolinkCredentials;
|
|
1702
|
+
/** Environment variables this provider reads at runtime. */
|
|
1703
|
+
envVars: {
|
|
1704
|
+
/** Primary identity/secret env var. Absent for providers with no required credential (Ollama, LM Studio, llama.cpp) or that use extraRequired instead of a single key (Vertex). */
|
|
1705
|
+
apiKey?: string;
|
|
1706
|
+
/** Alternate env vars accepted in place of apiKey, checked in order after apiKey. */
|
|
1707
|
+
fallbacks?: readonly string[];
|
|
1708
|
+
baseURL?: string;
|
|
1709
|
+
/** Alternate env vars accepted in place of baseURL. */
|
|
1710
|
+
baseURLFallbacks?: readonly string[];
|
|
1711
|
+
/** Env var that overrides the static defaultModel at runtime. */
|
|
1712
|
+
model?: string;
|
|
1713
|
+
/** Alternate env vars accepted in place of model, checked in order after model. */
|
|
1714
|
+
modelFallbacks?: readonly string[];
|
|
1715
|
+
/** Additional env vars required alongside apiKey (e.g. AWS secret key, Azure endpoint). */
|
|
1716
|
+
extraRequired?: readonly string[];
|
|
1717
|
+
/** Alternate ways to satisfy extraRequired when it isn't a plain env-var list (e.g. Vertex's file-path-OR-individual-fields auth). */
|
|
1718
|
+
extraRequiredFallbacks?: readonly string[];
|
|
1719
|
+
/** True when the provider is usable with zero configuration (local runtime with a documented default URL, or a documented non-secret default like LiteLLM's "sk-anything"). */
|
|
1720
|
+
optional?: boolean;
|
|
1721
|
+
};
|
|
1722
|
+
/**
|
|
1723
|
+
* Static fallback model. The empty string "" is a documented sentinel
|
|
1724
|
+
* meaning "no static default — resolved at runtime via envVars.model or
|
|
1725
|
+
* provider-side auto-discovery" (used by Bedrock, OpenAI-Compatible,
|
|
1726
|
+
* LM Studio, llama.cpp, matching how providerRegistry.ts already passes
|
|
1727
|
+
* `undefined` as their defaultModel argument today).
|
|
1728
|
+
*/
|
|
1729
|
+
defaultModel: string;
|
|
1730
|
+
toolSupport: "native" | "prompt-only" | "none" | "model-dependent";
|
|
1731
|
+
/** True only for providers that run entirely on the caller's machine with no cloud account (Ollama, LM Studio, llama.cpp). LiteLLM is a local proxy but commonly points at cloud models, so it is deliberately false. */
|
|
1732
|
+
localRuntime: boolean;
|
|
1733
|
+
/** How ProviderHealthChecker should verify this provider is reachable. */
|
|
1734
|
+
healthCheck: "env-only" | "models-probe" | "live-generate";
|
|
1735
|
+
setupUrl?: string;
|
|
1736
|
+
timeouts?: {
|
|
1737
|
+
generateMs?: number;
|
|
1738
|
+
streamMs?: number;
|
|
1739
|
+
};
|
|
1740
|
+
/** Ascending priority (1 = tried first) in the auto-select fallback chain used by getBestProvider(). Undefined = not part of the auto-select chain. */
|
|
1741
|
+
autoSelectPriority?: number;
|
|
1742
|
+
/** Format-validation regex sourced from providerConfig.ts's API_KEY_FORMATS, when one exists for this provider. */
|
|
1743
|
+
apiKeyFormatPattern?: RegExp;
|
|
1680
1744
|
};
|
|
1681
1745
|
/** Minimal NeuroLink-like instance accepted by the image generation service. */
|
|
1682
1746
|
export type NeuroLinkInstance = {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared provider-error classification. Every provider's
|
|
3
|
+
* `formatProviderError(error)` delegates here instead of hand-rolling its
|
|
4
|
+
* own TimeoutError-check → .includes()-chain → `new XError(...)` ladder.
|
|
5
|
+
*
|
|
6
|
+
* `classifyProviderError` picks the Error subclass + message; it does NOT
|
|
7
|
+
* stamp statusCode/isRetryable/retryAfterMs onto the result — that
|
|
8
|
+
* passthrough already happens generically in
|
|
9
|
+
* `BaseProvider.handleProviderError()` (src/lib/core/baseProvider.ts) for
|
|
10
|
+
* every provider's returned error, migrated or not, so duplicating it here
|
|
11
|
+
* would risk the two copies disagreeing.
|
|
12
|
+
*/
|
|
13
|
+
import { type ProviderErrorRule } from "../types/index.js";
|
|
14
|
+
/**
|
|
15
|
+
* Classify a raw provider error into a NeuroLink `ProviderError` subclass.
|
|
16
|
+
* `rules` are tried in order; the first match wins. `TimeoutError` is
|
|
17
|
+
* always handled first, ahead of any rule table — every provider treated
|
|
18
|
+
* it identically before this change, so it is not made overridable.
|
|
19
|
+
*/
|
|
20
|
+
export declare function classifyProviderError(error: unknown, rules: ProviderErrorRule[], provider: string, modelName?: string): Error;
|
|
21
|
+
/**
|
|
22
|
+
* Generic fallback rule table covering the five categories every
|
|
23
|
+
* OpenAI-compatible provider already hand-rolled near-identically:
|
|
24
|
+
* auth (401), rate limit (429), model-not-found (404), network/connection
|
|
25
|
+
* errors, and 5xx server errors. Providers with a provider-specific auth
|
|
26
|
+
* message (naming the exact env var) prepend one override rule and spread
|
|
27
|
+
* this table after it — see errorClassifier usage in any migrated
|
|
28
|
+
* provider's formatProviderError for the pattern.
|
|
29
|
+
*/
|
|
30
|
+
export declare const DEFAULT_ERROR_RULES: ProviderErrorRule[];
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared provider-error classification. Every provider's
|
|
3
|
+
* `formatProviderError(error)` delegates here instead of hand-rolling its
|
|
4
|
+
* own TimeoutError-check → .includes()-chain → `new XError(...)` ladder.
|
|
5
|
+
*
|
|
6
|
+
* `classifyProviderError` picks the Error subclass + message; it does NOT
|
|
7
|
+
* stamp statusCode/isRetryable/retryAfterMs onto the result — that
|
|
8
|
+
* passthrough already happens generically in
|
|
9
|
+
* `BaseProvider.handleProviderError()` (src/lib/core/baseProvider.ts) for
|
|
10
|
+
* every provider's returned error, migrated or not, so duplicating it here
|
|
11
|
+
* would risk the two copies disagreeing.
|
|
12
|
+
*/
|
|
13
|
+
import { ProviderError, AuthenticationError, RateLimitError, InvalidModelError, NetworkError, } from "../types/index.js";
|
|
14
|
+
import { TimeoutError } from "./timeout.js";
|
|
15
|
+
import { duckTypedStatusCode } from "./providerRetry.js";
|
|
16
|
+
function buildErrorContext(error, provider, modelName) {
|
|
17
|
+
const record = error && typeof error === "object"
|
|
18
|
+
? error
|
|
19
|
+
: undefined;
|
|
20
|
+
const message = typeof record?.message === "string"
|
|
21
|
+
? record.message
|
|
22
|
+
: error instanceof Error
|
|
23
|
+
? error.message
|
|
24
|
+
: "Unknown error";
|
|
25
|
+
return {
|
|
26
|
+
error,
|
|
27
|
+
message,
|
|
28
|
+
statusCode: duckTypedStatusCode(error),
|
|
29
|
+
errorName: typeof record?.name === "string" ? record.name : undefined,
|
|
30
|
+
errorCode: typeof record?.code === "string" ? record.code : undefined,
|
|
31
|
+
provider,
|
|
32
|
+
modelName,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Classify a raw provider error into a NeuroLink `ProviderError` subclass.
|
|
37
|
+
* `rules` are tried in order; the first match wins. `TimeoutError` is
|
|
38
|
+
* always handled first, ahead of any rule table — every provider treated
|
|
39
|
+
* it identically before this change, so it is not made overridable.
|
|
40
|
+
*/
|
|
41
|
+
export function classifyProviderError(error, rules, provider, modelName) {
|
|
42
|
+
if (error instanceof TimeoutError) {
|
|
43
|
+
return new NetworkError(`Request timed out: ${error.message}`, provider);
|
|
44
|
+
}
|
|
45
|
+
const ctx = buildErrorContext(error, provider, modelName);
|
|
46
|
+
const rule = rules.find((r) => r.match(ctx));
|
|
47
|
+
if (!rule) {
|
|
48
|
+
return new ProviderError(`${provider} error: ${ctx.message}`, provider);
|
|
49
|
+
}
|
|
50
|
+
const message = typeof rule.message === "function" ? rule.message(ctx) : rule.message;
|
|
51
|
+
return new rule.errorClass(message, provider);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Generic fallback rule table covering the five categories every
|
|
55
|
+
* OpenAI-compatible provider already hand-rolled near-identically:
|
|
56
|
+
* auth (401), rate limit (429), model-not-found (404), network/connection
|
|
57
|
+
* errors, and 5xx server errors. Providers with a provider-specific auth
|
|
58
|
+
* message (naming the exact env var) prepend one override rule and spread
|
|
59
|
+
* this table after it — see errorClassifier usage in any migrated
|
|
60
|
+
* provider's formatProviderError for the pattern.
|
|
61
|
+
*/
|
|
62
|
+
export const DEFAULT_ERROR_RULES = [
|
|
63
|
+
{
|
|
64
|
+
match: (ctx) => ctx.statusCode === 401 ||
|
|
65
|
+
/API_KEY_INVALID|Invalid API key|Unauthorized|invalid_api_key/i.test(ctx.message),
|
|
66
|
+
errorClass: AuthenticationError,
|
|
67
|
+
message: (ctx) => `Invalid ${ctx.provider} API key. Please check your credentials.`,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
match: (ctx) => ctx.statusCode === 429 || /rate limit/i.test(ctx.message),
|
|
71
|
+
errorClass: RateLimitError,
|
|
72
|
+
message: (ctx) => `${ctx.provider} rate limit exceeded. Please try again later.`,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
match: (ctx) => ctx.statusCode === 404 ||
|
|
76
|
+
/model_not_found|model not found/i.test(ctx.message),
|
|
77
|
+
errorClass: InvalidModelError,
|
|
78
|
+
message: (ctx) => ctx.modelName
|
|
79
|
+
? `${ctx.provider} model '${ctx.modelName}' not found.`
|
|
80
|
+
: `${ctx.provider} model not found.`,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
match: (ctx) => /ECONNRESET|ENOTFOUND|ECONNREFUSED|ETIMEDOUT|network|connection/i.test(ctx.message),
|
|
84
|
+
errorClass: NetworkError,
|
|
85
|
+
message: (ctx) => `Connection error: ${ctx.message}`,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
match: (ctx) => (ctx.statusCode !== undefined && ctx.statusCode >= 500) ||
|
|
89
|
+
/\b5\d\d\b|server error/i.test(ctx.message),
|
|
90
|
+
errorClass: ProviderError,
|
|
91
|
+
message: (ctx) => `${ctx.provider} server error: ${ctx.message}`,
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
//# sourceMappingURL=errorClassifier.js.map
|