@juspay/neurolink 9.68.16 → 9.68.18
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/browser/neurolink.min.js +561 -561
- package/dist/lib/providers/cloudflare.js +2 -1
- package/dist/lib/providers/cohere.js +2 -1
- package/dist/lib/providers/deepseek.js +2 -1
- package/dist/lib/providers/fireworks.js +2 -1
- package/dist/lib/providers/groq.js +2 -1
- package/dist/lib/providers/huggingFace.js +2 -1
- package/dist/lib/providers/litellm.js +2 -1
- package/dist/lib/providers/llamaCpp.js +1 -6
- package/dist/lib/providers/lmStudio.js +3 -2
- package/dist/lib/providers/mistral.d.ts +20 -28
- package/dist/lib/providers/mistral.js +61 -136
- package/dist/lib/providers/nvidiaNim.js +2 -1
- package/dist/lib/providers/openAI.js +2 -1
- package/dist/lib/providers/openaiCompatible.js +3 -2
- package/dist/lib/providers/perplexity.js +2 -1
- package/dist/lib/providers/togetherAi.js +2 -1
- package/dist/lib/providers/xai.js +2 -1
- package/dist/lib/types/providers.d.ts +1 -0
- package/dist/lib/utils/logSanitize.d.ts +14 -0
- package/dist/lib/utils/logSanitize.js +16 -0
- package/dist/providers/cloudflare.js +2 -1
- package/dist/providers/cohere.js +2 -1
- package/dist/providers/deepseek.js +2 -1
- package/dist/providers/fireworks.js +2 -1
- package/dist/providers/groq.js +2 -1
- package/dist/providers/huggingFace.js +2 -1
- package/dist/providers/litellm.js +2 -1
- package/dist/providers/llamaCpp.js +1 -6
- package/dist/providers/lmStudio.js +3 -2
- package/dist/providers/mistral.d.ts +20 -28
- package/dist/providers/mistral.js +61 -136
- package/dist/providers/nvidiaNim.js +2 -1
- package/dist/providers/openAI.js +2 -1
- package/dist/providers/openaiCompatible.js +3 -2
- package/dist/providers/perplexity.js +2 -1
- package/dist/providers/togetherAi.js +2 -1
- package/dist/providers/xai.js +2 -1
- package/dist/types/providers.d.ts +1 -0
- package/dist/utils/logSanitize.d.ts +14 -0
- package/dist/utils/logSanitize.js +16 -0
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CloudflareModels } from "../constants/enums.js";
|
|
2
2
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
4
5
|
import { createCloudflareConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
5
6
|
import { TimeoutError } from "../utils/timeout.js";
|
|
6
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
@@ -44,7 +45,7 @@ export class CloudflareProvider extends OpenAIChatCompletionsProvider {
|
|
|
44
45
|
logger.debug("Cloudflare Workers AI Provider initialized", {
|
|
45
46
|
modelName: this.modelName,
|
|
46
47
|
providerName: this.providerName,
|
|
47
|
-
baseURL: this.config.baseURL,
|
|
48
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
48
49
|
});
|
|
49
50
|
}
|
|
50
51
|
getProviderName() {
|
package/dist/providers/cohere.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CohereModels } from "../constants/enums.js";
|
|
2
2
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
4
5
|
import { createProxyFetch } from "../proxy/proxyFetch.js";
|
|
5
6
|
import { createCohereConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
6
7
|
import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
|
|
@@ -36,7 +37,7 @@ export class CohereProvider extends OpenAIChatCompletionsProvider {
|
|
|
36
37
|
logger.debug("Cohere Provider initialized", {
|
|
37
38
|
modelName: this.modelName,
|
|
38
39
|
providerName: this.providerName,
|
|
39
|
-
baseURL: this.config.baseURL,
|
|
40
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
40
41
|
});
|
|
41
42
|
}
|
|
42
43
|
getProviderName() {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DeepSeekModels } from "../constants/enums.js";
|
|
2
2
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
4
5
|
import { createDeepSeekConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
5
6
|
import { TimeoutError } from "../utils/timeout.js";
|
|
6
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
@@ -55,7 +56,7 @@ export class DeepSeekProvider extends OpenAIChatCompletionsProvider {
|
|
|
55
56
|
logger.debug("DeepSeek Provider initialized", {
|
|
56
57
|
modelName: this.modelName,
|
|
57
58
|
providerName: this.providerName,
|
|
58
|
-
baseURL: this.config.baseURL,
|
|
59
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
59
60
|
});
|
|
60
61
|
}
|
|
61
62
|
// ===========================================================================
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FireworksModels } from "../constants/enums.js";
|
|
2
2
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
4
5
|
import { createFireworksConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
5
6
|
import { TimeoutError } from "../utils/timeout.js";
|
|
6
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
@@ -34,7 +35,7 @@ export class FireworksProvider extends OpenAIChatCompletionsProvider {
|
|
|
34
35
|
logger.debug("Fireworks Provider initialized", {
|
|
35
36
|
modelName: this.modelName,
|
|
36
37
|
providerName: this.providerName,
|
|
37
|
-
baseURL: this.config.baseURL,
|
|
38
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
getProviderName() {
|
package/dist/providers/groq.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { GroqModels } from "../constants/enums.js";
|
|
2
2
|
import { AuthenticationError, InvalidModelError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
4
5
|
import { createGroqConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
5
6
|
import { TimeoutError } from "../utils/timeout.js";
|
|
6
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
@@ -33,7 +34,7 @@ export class GroqProvider extends OpenAIChatCompletionsProvider {
|
|
|
33
34
|
logger.debug("Groq Provider initialized", {
|
|
34
35
|
modelName: this.modelName,
|
|
35
36
|
providerName: this.providerName,
|
|
36
|
-
baseURL: this.config.baseURL,
|
|
37
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
getProviderName() {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
2
2
|
import { logger } from "../utils/logger.js";
|
|
3
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
3
4
|
import { createHuggingFaceConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
4
5
|
import { TimeoutError } from "../utils/timeout.js";
|
|
5
6
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
@@ -33,7 +34,7 @@ export class HuggingFaceProvider extends OpenAIChatCompletionsProvider {
|
|
|
33
34
|
logger.debug("HuggingFaceProvider initialized", {
|
|
34
35
|
modelName: this.modelName,
|
|
35
36
|
providerName: this.providerName,
|
|
36
|
-
baseURL: this.config.baseURL,
|
|
37
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
getProviderName() {
|
|
@@ -3,6 +3,7 @@ import { createProxyFetch } from "../proxy/proxyFetch.js";
|
|
|
3
3
|
import { AuthenticationError, InvalidModelError, ModelAccessDeniedError, NetworkError, ProviderError, RateLimitError, isModelAccessDeniedMessage, parseAllowedModels, } from "../types/index.js";
|
|
4
4
|
import { isAbortError } from "../utils/errorHandling.js";
|
|
5
5
|
import { logger } from "../utils/logger.js";
|
|
6
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
6
7
|
import { isGemini25Model as isCanonicalGemini25Model } from "../utils/modelDetection.js";
|
|
7
8
|
import { calculateCost } from "../utils/pricing.js";
|
|
8
9
|
import { getProviderModel } from "../utils/providerConfig.js";
|
|
@@ -53,7 +54,7 @@ export class LiteLLMProvider extends OpenAIChatCompletionsProvider {
|
|
|
53
54
|
logger.debug("LiteLLM Provider initialized", {
|
|
54
55
|
modelName: this.modelName,
|
|
55
56
|
provider: this.providerName,
|
|
56
|
-
baseURL: this.config.baseURL,
|
|
57
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
getProviderName() {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NetworkError, ProviderError } from "../types/index.js";
|
|
2
2
|
import { logger } from "../utils/logger.js";
|
|
3
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
3
4
|
import { TimeoutError } from "../utils/timeout.js";
|
|
4
5
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
5
6
|
const LLAMACPP_DEFAULT_BASE_URL = "http://localhost:8080/v1";
|
|
@@ -7,12 +8,6 @@ const LLAMACPP_PLACEHOLDER_KEY = "llamacpp";
|
|
|
7
8
|
const getLlamaCppBaseURL = () => {
|
|
8
9
|
return process.env.LLAMACPP_BASE_URL || LLAMACPP_DEFAULT_BASE_URL;
|
|
9
10
|
};
|
|
10
|
-
/**
|
|
11
|
-
* Strip embedded `user:pass@` credentials from a URL before logging it or
|
|
12
|
-
* surfacing it in a user-facing error. Preserves host/port/path so the URL
|
|
13
|
-
* stays useful for diagnostics.
|
|
14
|
-
*/
|
|
15
|
-
const redactUrlCredentials = (url) => url.replace(/\/\/[^/@]+@/, "//***@");
|
|
16
11
|
/**
|
|
17
12
|
* llama.cpp Provider — direct HTTP, no AI SDK.
|
|
18
13
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createProxyFetch } from "../proxy/proxyFetch.js";
|
|
2
2
|
import { InvalidModelError, NetworkError, ProviderError, } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
4
5
|
import { TimeoutError } from "../utils/timeout.js";
|
|
5
6
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
6
7
|
const LM_STUDIO_DEFAULT_BASE_URL = "http://localhost:1234/v1";
|
|
@@ -34,7 +35,7 @@ export class LMStudioProvider extends OpenAIChatCompletionsProvider {
|
|
|
34
35
|
logger.debug("LM Studio Provider initialized", {
|
|
35
36
|
modelName: this.modelName,
|
|
36
37
|
providerName: this.providerName,
|
|
37
|
-
baseURL: this.config.baseURL,
|
|
38
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
getProviderName() {
|
|
@@ -60,7 +61,7 @@ export class LMStudioProvider extends OpenAIChatCompletionsProvider {
|
|
|
60
61
|
message.includes("ECONNREFUSED") ||
|
|
61
62
|
message.includes("Failed to fetch") ||
|
|
62
63
|
message.includes("fetch failed")) {
|
|
63
|
-
return new NetworkError(`LM Studio server not reachable at ${this.config.baseURL}. ` +
|
|
64
|
+
return new NetworkError(`LM Studio server not reachable at ${redactUrlCredentials(this.config.baseURL)}. ` +
|
|
64
65
|
`Open the LM Studio app, load a model, and click "Start Server".`, "lm-studio");
|
|
65
66
|
}
|
|
66
67
|
if (message.includes("model_not_found") || message.includes("404")) {
|
|
@@ -1,33 +1,25 @@
|
|
|
1
1
|
import type { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import type { LanguageModel } from "../types/index.js";
|
|
2
|
+
import type { NeurolinkCredentials } from "../types/index.js";
|
|
3
|
+
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
5
4
|
/**
|
|
6
|
-
* Mistral AI Provider
|
|
7
|
-
*
|
|
5
|
+
* Mistral AI Provider — direct HTTP, no AI SDK.
|
|
6
|
+
*
|
|
7
|
+
* OpenAI-compatible chat completions at api.mistral.ai/v1. All request/stream/
|
|
8
|
+
* tool-loop orchestration lives in `OpenAIChatCompletionsProvider`; this class
|
|
9
|
+
* only declares configuration and the provider-specific error mapping.
|
|
10
|
+
*
|
|
11
|
+
* Mistral's `/chat/completions` accepts `response_format: { type:
|
|
12
|
+
* "json_schema" }` on current models (mistral-small-2506 and newer), so no
|
|
13
|
+
* structured-output downgrade is needed — the base client's default
|
|
14
|
+
* pass-through is correct.
|
|
15
|
+
*
|
|
16
|
+
* @see https://docs.mistral.ai/api/
|
|
8
17
|
*/
|
|
9
|
-
export declare class MistralProvider extends
|
|
10
|
-
private model;
|
|
18
|
+
export declare class MistralProvider extends OpenAIChatCompletionsProvider {
|
|
11
19
|
constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["mistral"]);
|
|
12
|
-
protected
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
*/
|
|
18
|
-
getAISDKModel(): LanguageModel;
|
|
19
|
-
formatProviderError(error: unknown): Error;
|
|
20
|
-
/**
|
|
21
|
-
* Validate provider configuration
|
|
22
|
-
*/
|
|
23
|
-
validateConfiguration(): Promise<boolean>;
|
|
24
|
-
/**
|
|
25
|
-
* Get provider-specific configuration
|
|
26
|
-
*/
|
|
27
|
-
getConfiguration(): {
|
|
28
|
-
provider: AIProviderName;
|
|
29
|
-
model: string;
|
|
30
|
-
defaultModel: string;
|
|
31
|
-
};
|
|
20
|
+
protected getProviderName(): AIProviderName;
|
|
21
|
+
protected getDefaultModel(): string;
|
|
22
|
+
protected formatProviderError(error: unknown): Error;
|
|
23
|
+
protected getFallbackModelName(): string;
|
|
24
|
+
protected getFallbackModels(): string[];
|
|
32
25
|
}
|
|
33
|
-
export default MistralProvider;
|
|
@@ -1,135 +1,64 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { DEFAULT_MAX_STEPS } from "../core/constants.js";
|
|
4
|
-
import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
|
|
5
|
-
import { isNeuroLink } from "../neurolink.js";
|
|
6
|
-
import { createProxyFetch } from "../proxy/proxyFetch.js";
|
|
7
|
-
import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
8
|
-
import { emitToolEndFromStepFinish } from "../utils/toolEndEmitter.js";
|
|
1
|
+
import { MistralModels } from "../constants/enums.js";
|
|
2
|
+
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
9
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
10
5
|
import { createMistralConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
import { stepCountIs } from "../utils/tool.js";
|
|
15
|
-
import { streamText } from "../utils/generation.js";
|
|
16
|
-
// Configuration helpers - now using consolidated utility
|
|
6
|
+
import { TimeoutError } from "../utils/timeout.js";
|
|
7
|
+
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
8
|
+
const MISTRAL_DEFAULT_BASE_URL = "https://api.mistral.ai/v1";
|
|
17
9
|
const getMistralApiKey = () => {
|
|
18
10
|
return validateApiKey(createMistralConfig());
|
|
19
11
|
};
|
|
20
12
|
const getDefaultMistralModel = () => {
|
|
21
|
-
//
|
|
22
|
-
return getProviderModel("MISTRAL_MODEL",
|
|
13
|
+
// Vision-capable Mistral Small (June 2025) with multimodal support.
|
|
14
|
+
return getProviderModel("MISTRAL_MODEL", MistralModels.MISTRAL_SMALL_2506);
|
|
23
15
|
};
|
|
24
16
|
/**
|
|
25
|
-
* Mistral AI Provider
|
|
26
|
-
*
|
|
17
|
+
* Mistral AI Provider — direct HTTP, no AI SDK.
|
|
18
|
+
*
|
|
19
|
+
* OpenAI-compatible chat completions at api.mistral.ai/v1. All request/stream/
|
|
20
|
+
* tool-loop orchestration lives in `OpenAIChatCompletionsProvider`; this class
|
|
21
|
+
* only declares configuration and the provider-specific error mapping.
|
|
22
|
+
*
|
|
23
|
+
* Mistral's `/chat/completions` accepts `response_format: { type:
|
|
24
|
+
* "json_schema" }` on current models (mistral-small-2506 and newer), so no
|
|
25
|
+
* structured-output downgrade is needed — the base client's default
|
|
26
|
+
* pass-through is correct.
|
|
27
|
+
*
|
|
28
|
+
* @see https://docs.mistral.ai/api/
|
|
27
29
|
*/
|
|
28
|
-
export class MistralProvider extends
|
|
29
|
-
model;
|
|
30
|
+
export class MistralProvider extends OpenAIChatCompletionsProvider {
|
|
30
31
|
constructor(modelName, sdk, _region, credentials) {
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
// Trim the override before applying precedence. A blank/whitespace
|
|
33
|
+
// `credentials.apiKey` must NOT bypass `getMistralApiKey()` — that would
|
|
34
|
+
// build a client with an unusable bearer token and fail at request time
|
|
35
|
+
// with a confusing 401 instead of at construction time.
|
|
36
|
+
const overrideApiKey = credentials?.apiKey?.trim();
|
|
37
|
+
const apiKey = overrideApiKey && overrideApiKey.length > 0
|
|
38
|
+
? overrideApiKey
|
|
39
|
+
: getMistralApiKey();
|
|
40
|
+
// Treat blank/whitespace overrides as unset so an empty
|
|
41
|
+
// `credentials.baseURL` or `MISTRAL_BASE_URL=` cannot silently override
|
|
42
|
+
// the default with "" (mirrors the apiKey precedence above).
|
|
43
|
+
const baseURL = credentials?.baseURL?.trim() ||
|
|
44
|
+
process.env.MISTRAL_BASE_URL?.trim() ||
|
|
45
|
+
MISTRAL_DEFAULT_BASE_URL;
|
|
46
|
+
super("mistral", modelName, sdk, { baseURL, apiKey });
|
|
47
|
+
logger.debug("Mistral Provider initialized", {
|
|
42
48
|
modelName: this.modelName,
|
|
43
49
|
providerName: this.providerName,
|
|
50
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
44
51
|
});
|
|
45
52
|
}
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const startTime = Date.now();
|
|
50
|
-
const timeout = this.getTimeout(options);
|
|
51
|
-
const timeoutController = createTimeoutController(timeout, this.providerName, "stream");
|
|
52
|
-
try {
|
|
53
|
-
// Get tools - options.tools is pre-merged by BaseProvider.stream()
|
|
54
|
-
const shouldUseTools = !options.disableTools && this.supportsTools();
|
|
55
|
-
const tools = shouldUseTools
|
|
56
|
-
? options.tools || (await this.getAllTools())
|
|
57
|
-
: {};
|
|
58
|
-
// Build message array from options with multimodal support
|
|
59
|
-
// Using protected helper from BaseProvider to eliminate code duplication
|
|
60
|
-
const messages = await this.buildMessagesForStream(options);
|
|
61
|
-
const model = await this.getAISDKModelWithMiddleware(options); // This is where network connection happens!
|
|
62
|
-
// Reviewer follow-up: capture upstream provider errors via onError
|
|
63
|
-
// so the post-stream NoOutput sentinel carries the real cause.
|
|
64
|
-
let capturedProviderError;
|
|
65
|
-
const result = await streamText({
|
|
66
|
-
model,
|
|
67
|
-
messages: messages,
|
|
68
|
-
temperature: options.temperature,
|
|
69
|
-
maxOutputTokens: options.maxTokens, // No default limit - unlimited unless specified
|
|
70
|
-
tools,
|
|
71
|
-
stopWhen: stepCountIs(options.maxSteps || DEFAULT_MAX_STEPS),
|
|
72
|
-
toolChoice: resolveToolChoice(options, tools, shouldUseTools),
|
|
73
|
-
abortSignal: composeAbortSignals(options.abortSignal, timeoutController?.controller.signal),
|
|
74
|
-
experimental_telemetry: this.telemetryHandler.getTelemetryConfig(options),
|
|
75
|
-
experimental_repairToolCall: this.getToolCallRepairFn(options),
|
|
76
|
-
onError: (event) => {
|
|
77
|
-
capturedProviderError = event.error;
|
|
78
|
-
logger.error("Mistral: Stream error", {
|
|
79
|
-
error: event.error instanceof Error
|
|
80
|
-
? event.error.message
|
|
81
|
-
: String(event.error),
|
|
82
|
-
});
|
|
83
|
-
},
|
|
84
|
-
onStepFinish: ({ toolCalls, toolResults }) => {
|
|
85
|
-
emitToolEndFromStepFinish(this.neurolink?.getEventEmitter(), toolResults);
|
|
86
|
-
this.handleToolExecutionStorage(toolCalls, toolResults, options, new Date()).catch((error) => {
|
|
87
|
-
logger.warn("[MistralProvider] Failed to store tool executions", {
|
|
88
|
-
provider: this.providerName,
|
|
89
|
-
error: error instanceof Error ? error.message : String(error),
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
timeoutController?.cleanup();
|
|
95
|
-
// Transform string stream to content object stream using BaseProvider method
|
|
96
|
-
const transformedStream = this.createTextStream(result, () => capturedProviderError);
|
|
97
|
-
// Create analytics promise that resolves after stream completion
|
|
98
|
-
const analyticsPromise = streamAnalyticsCollector.createAnalytics(this.providerName, this.modelName, toAnalyticsStreamResult(result), Date.now() - startTime, {
|
|
99
|
-
requestId: `mistral-stream-${Date.now()}`,
|
|
100
|
-
streamingMode: true,
|
|
101
|
-
});
|
|
102
|
-
return {
|
|
103
|
-
stream: transformedStream,
|
|
104
|
-
provider: this.providerName,
|
|
105
|
-
model: this.modelName,
|
|
106
|
-
analytics: analyticsPromise,
|
|
107
|
-
metadata: {
|
|
108
|
-
startTime,
|
|
109
|
-
streamId: `mistral-${Date.now()}`,
|
|
110
|
-
},
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
timeoutController?.cleanup();
|
|
115
|
-
throw this.handleProviderError(error);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// ===================
|
|
119
|
-
// ABSTRACT METHOD IMPLEMENTATIONS
|
|
120
|
-
// ===================
|
|
53
|
+
// ===========================================================================
|
|
54
|
+
// Abstract hooks (required)
|
|
55
|
+
// ===========================================================================
|
|
121
56
|
getProviderName() {
|
|
122
|
-
return
|
|
57
|
+
return "mistral";
|
|
123
58
|
}
|
|
124
59
|
getDefaultModel() {
|
|
125
60
|
return getDefaultMistralModel();
|
|
126
61
|
}
|
|
127
|
-
/**
|
|
128
|
-
* Returns the Vercel AI SDK model instance for Mistral
|
|
129
|
-
*/
|
|
130
|
-
getAISDKModel() {
|
|
131
|
-
return this.model;
|
|
132
|
-
}
|
|
133
62
|
formatProviderError(error) {
|
|
134
63
|
if (error instanceof TimeoutError) {
|
|
135
64
|
return new NetworkError(`Request timed out: ${error.message}`, "mistral");
|
|
@@ -139,35 +68,31 @@ export class MistralProvider extends BaseProvider {
|
|
|
139
68
|
? errorRecord.message
|
|
140
69
|
: "Unknown error";
|
|
141
70
|
if (message.includes("API_KEY_INVALID") ||
|
|
142
|
-
message.includes("Invalid API key")
|
|
71
|
+
message.includes("Invalid API key") ||
|
|
72
|
+
message.includes("Unauthorized") ||
|
|
73
|
+
message.includes("401")) {
|
|
143
74
|
return new AuthenticationError("Invalid Mistral API key. Please check your MISTRAL_API_KEY environment variable.", "mistral");
|
|
144
75
|
}
|
|
145
|
-
if (message.includes("
|
|
76
|
+
if (message.includes("rate limit") ||
|
|
77
|
+
message.includes("Rate limit") ||
|
|
78
|
+
message.includes("429")) {
|
|
146
79
|
return new RateLimitError("Mistral rate limit exceeded", "mistral");
|
|
147
80
|
}
|
|
81
|
+
if (message.includes("model_not_found") || message.includes("404")) {
|
|
82
|
+
return new InvalidModelError(`Mistral model '${this.modelName}' not found.`, "mistral");
|
|
83
|
+
}
|
|
148
84
|
return new ProviderError(`Mistral error: ${message}`, "mistral");
|
|
149
85
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
getMistralApiKey();
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
catch {
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
86
|
+
// ===========================================================================
|
|
87
|
+
// Optional hooks
|
|
88
|
+
// ===========================================================================
|
|
89
|
+
getFallbackModelName() {
|
|
90
|
+
return MistralModels.MISTRAL_SMALL_2506;
|
|
161
91
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
provider: this.providerName,
|
|
168
|
-
model: this.modelName,
|
|
169
|
-
defaultModel: getDefaultMistralModel(),
|
|
170
|
-
};
|
|
92
|
+
getFallbackModels() {
|
|
93
|
+
return [
|
|
94
|
+
MistralModels.MISTRAL_SMALL_2506,
|
|
95
|
+
MistralModels.MISTRAL_LARGE_LATEST,
|
|
96
|
+
];
|
|
171
97
|
}
|
|
172
98
|
}
|
|
173
|
-
export default MistralProvider;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NvidiaNimModels } from "../constants/enums.js";
|
|
2
2
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
4
5
|
import { createNvidiaNimConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
5
6
|
import { TimeoutError } from "../utils/timeout.js";
|
|
6
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
@@ -164,7 +165,7 @@ export class NvidiaNimProvider extends OpenAIChatCompletionsProvider {
|
|
|
164
165
|
logger.debug("NVIDIA NIM Provider initialized", {
|
|
165
166
|
modelName: this.modelName,
|
|
166
167
|
providerName: this.providerName,
|
|
167
|
-
baseURL: this.config.baseURL,
|
|
168
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
168
169
|
});
|
|
169
170
|
}
|
|
170
171
|
getProviderName() {
|
package/dist/providers/openAI.js
CHANGED
|
@@ -3,6 +3,7 @@ import { AIProviderName as AIProviderNameEnum } from "../constants/enums.js";
|
|
|
3
3
|
import { createProxyFetch } from "../proxy/proxyFetch.js";
|
|
4
4
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
5
5
|
import { logger } from "../utils/logger.js";
|
|
6
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
6
7
|
import { calculateCost } from "../utils/pricing.js";
|
|
7
8
|
import { createOpenAIConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
8
9
|
import { MAX_IMAGE_BYTES, readBoundedBuffer } from "../utils/sizeGuard.js";
|
|
@@ -67,7 +68,7 @@ export class OpenAIProvider extends OpenAIChatCompletionsProvider {
|
|
|
67
68
|
logger.debug("OpenAIProvider initialized", {
|
|
68
69
|
model: this.modelName,
|
|
69
70
|
providerName: this.providerName,
|
|
70
|
-
baseURL: this.config.baseURL,
|
|
71
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
71
72
|
});
|
|
72
73
|
}
|
|
73
74
|
// ===========================================================================
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
2
2
|
import { logger } from "../utils/logger.js";
|
|
3
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
3
4
|
import { TimeoutError } from "../utils/timeout.js";
|
|
4
5
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
5
6
|
const FALLBACK_OPENAI_COMPATIBLE_MODEL = "gpt-3.5-turbo";
|
|
@@ -42,7 +43,7 @@ export class OpenAICompatibleProvider extends OpenAIChatCompletionsProvider {
|
|
|
42
43
|
logger.debug("OpenAI Compatible Provider initialized", {
|
|
43
44
|
modelName: this.modelName,
|
|
44
45
|
provider: this.providerName,
|
|
45
|
-
baseURL: this.config.baseURL,
|
|
46
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
46
47
|
});
|
|
47
48
|
}
|
|
48
49
|
getProviderName() {
|
|
@@ -78,7 +79,7 @@ export class OpenAICompatibleProvider extends OpenAIChatCompletionsProvider {
|
|
|
78
79
|
if (typeof errorRecord?.message === "string") {
|
|
79
80
|
if (errorRecord.message.includes("ECONNREFUSED") ||
|
|
80
81
|
errorRecord.message.includes("Failed to fetch")) {
|
|
81
|
-
return new NetworkError(`OpenAI Compatible endpoint not available. Please check your OPENAI_COMPATIBLE_BASE_URL: ${this.config.baseURL}`, "openai-compatible");
|
|
82
|
+
return new NetworkError(`OpenAI Compatible endpoint not available. Please check your OPENAI_COMPATIBLE_BASE_URL: ${redactUrlCredentials(this.config.baseURL)}`, "openai-compatible");
|
|
82
83
|
}
|
|
83
84
|
if (errorRecord.message.includes("API_KEY_INVALID") ||
|
|
84
85
|
errorRecord.message.includes("Invalid API key") ||
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PerplexityModels } from "../constants/enums.js";
|
|
2
2
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
4
5
|
import { createPerplexityConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
5
6
|
import { TimeoutError } from "../utils/timeout.js";
|
|
6
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
@@ -33,7 +34,7 @@ export class PerplexityProvider extends OpenAIChatCompletionsProvider {
|
|
|
33
34
|
logger.debug("Perplexity Provider initialized", {
|
|
34
35
|
modelName: this.modelName,
|
|
35
36
|
providerName: this.providerName,
|
|
36
|
-
baseURL: this.config.baseURL,
|
|
37
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
getProviderName() {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TogetherAIModels } from "../constants/enums.js";
|
|
2
2
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
4
5
|
import { createTogetherAIConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
5
6
|
import { TimeoutError } from "../utils/timeout.js";
|
|
6
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
@@ -32,7 +33,7 @@ export class TogetherAIProvider extends OpenAIChatCompletionsProvider {
|
|
|
32
33
|
logger.debug("Together AI Provider initialized", {
|
|
33
34
|
modelName: this.modelName,
|
|
34
35
|
providerName: this.providerName,
|
|
35
|
-
baseURL: this.config.baseURL,
|
|
36
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
getProviderName() {
|
package/dist/providers/xai.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { XaiModels } from "../constants/enums.js";
|
|
2
2
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
4
5
|
import { createXaiConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
5
6
|
import { TimeoutError } from "../utils/timeout.js";
|
|
6
7
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
@@ -34,7 +35,7 @@ export class XaiProvider extends OpenAIChatCompletionsProvider {
|
|
|
34
35
|
logger.debug("xAI Provider initialized", {
|
|
35
36
|
modelName: this.modelName,
|
|
36
37
|
providerName: this.providerName,
|
|
37
|
-
baseURL: this.config.baseURL,
|
|
38
|
+
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
getProviderName() {
|
|
@@ -26,6 +26,20 @@
|
|
|
26
26
|
* @param maxLen - Maximum number of characters to keep (default 500).
|
|
27
27
|
*/
|
|
28
28
|
export declare function sanitizeForLog(text: string, maxLen?: number): string;
|
|
29
|
+
/**
|
|
30
|
+
* Strip embedded `user:pass@` credentials from a URL's authority component
|
|
31
|
+
* before logging it or surfacing it in a user-facing error.
|
|
32
|
+
*
|
|
33
|
+
* Turns `https://user:secret@host/path` into `https://***@host/path` while
|
|
34
|
+
* leaving credential-free URLs untouched, so the host/port/path stay useful
|
|
35
|
+
* for diagnostics. Use this for any `baseURL`/endpoint a caller may have
|
|
36
|
+
* supplied with inline credentials. The match is global, so every `//…@`
|
|
37
|
+
* authority in the string is redacted (e.g. a proxy chain or a URL embedded
|
|
38
|
+
* in a query parameter), not just the first.
|
|
39
|
+
*
|
|
40
|
+
* @param url - The URL (or URL-shaped string) to redact.
|
|
41
|
+
*/
|
|
42
|
+
export declare function redactUrlCredentials(url: string): string;
|
|
29
43
|
/**
|
|
30
44
|
* Recursively sanitize a record/array, returning a structurally identical
|
|
31
45
|
* value with sensitive keys redacted and string values run through
|
|
@@ -91,6 +91,22 @@ export function sanitizeForLog(text, maxLen = 500) {
|
|
|
91
91
|
}
|
|
92
92
|
return text.slice(0, maxLen).replace(SECRET_PATTERN, "***");
|
|
93
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Strip embedded `user:pass@` credentials from a URL's authority component
|
|
96
|
+
* before logging it or surfacing it in a user-facing error.
|
|
97
|
+
*
|
|
98
|
+
* Turns `https://user:secret@host/path` into `https://***@host/path` while
|
|
99
|
+
* leaving credential-free URLs untouched, so the host/port/path stay useful
|
|
100
|
+
* for diagnostics. Use this for any `baseURL`/endpoint a caller may have
|
|
101
|
+
* supplied with inline credentials. The match is global, so every `//…@`
|
|
102
|
+
* authority in the string is redacted (e.g. a proxy chain or a URL embedded
|
|
103
|
+
* in a query parameter), not just the first.
|
|
104
|
+
*
|
|
105
|
+
* @param url - The URL (or URL-shaped string) to redact.
|
|
106
|
+
*/
|
|
107
|
+
export function redactUrlCredentials(url) {
|
|
108
|
+
return url.replace(/\/\/[^/@]+@/g, "//***@");
|
|
109
|
+
}
|
|
94
110
|
/**
|
|
95
111
|
* Recursively sanitize a record/array, returning a structurally identical
|
|
96
112
|
* value with sensitive keys redacted and string values run through
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "9.68.
|
|
3
|
+
"version": "9.68.18",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
5
|
"description": "Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applications with 21+ providers: OpenAI, Anthropic, Google AI Studio, Google Vertex, AWS Bedrock, Azure OpenAI, Mistral, LiteLLM, SageMaker, Hugging Face, Ollama, OpenAI-compatible, OpenRouter, DeepSeek, NVIDIA NIM, LM Studio, llama.cpp, plus voice (OpenAI TTS, ElevenLabs, Deepgram, Azure Speech).",
|
|
6
6
|
"author": {
|