@juspay/neurolink 11.2.1 → 11.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/browser/neurolink.min.js +392 -392
- package/dist/factories/providerRegistry.d.ts +16 -4
- package/dist/factories/providerRegistry.js +70 -48
- package/dist/lib/factories/providerRegistry.d.ts +16 -4
- package/dist/lib/factories/providerRegistry.js +70 -48
- package/dist/lib/providers/configuredOpenAICompat.js +10 -3
- package/dist/lib/providers/openaiChatCompletionsBase.js +26 -14
- package/dist/lib/providers/openaiCompatCatalog.js +9 -11
- package/dist/lib/types/providers.d.ts +15 -1
- package/dist/providers/configuredOpenAICompat.js +10 -3
- package/dist/providers/openaiChatCompletionsBase.js +26 -14
- package/dist/providers/openaiCompatCatalog.js +9 -11
- package/dist/types/providers.d.ts +15 -1
- package/package.json +3 -2
- package/dist/lib/providers/cloudflare.d.ts +0 -26
- package/dist/lib/providers/cloudflare.js +0 -83
- package/dist/lib/providers/fireworks.d.ts +0 -22
- package/dist/lib/providers/fireworks.js +0 -73
- package/dist/lib/providers/groq.d.ts +0 -24
- package/dist/lib/providers/groq.js +0 -83
- package/dist/lib/providers/mistral.d.ts +0 -25
- package/dist/lib/providers/mistral.js +0 -87
- package/dist/lib/providers/perplexity.d.ts +0 -24
- package/dist/lib/providers/perplexity.js +0 -69
- package/dist/lib/providers/togetherAi.d.ts +0 -23
- package/dist/lib/providers/togetherAi.js +0 -73
- package/dist/lib/providers/xai.d.ts +0 -22
- package/dist/lib/providers/xai.js +0 -77
- package/dist/providers/cloudflare.d.ts +0 -26
- package/dist/providers/cloudflare.js +0 -82
- package/dist/providers/fireworks.d.ts +0 -22
- package/dist/providers/fireworks.js +0 -72
- package/dist/providers/groq.d.ts +0 -24
- package/dist/providers/groq.js +0 -82
- package/dist/providers/mistral.d.ts +0 -25
- package/dist/providers/mistral.js +0 -86
- package/dist/providers/perplexity.d.ts +0 -24
- package/dist/providers/perplexity.js +0 -68
- package/dist/providers/togetherAi.d.ts +0 -23
- package/dist/providers/togetherAi.js +0 -72
- package/dist/providers/xai.d.ts +0 -22
- package/dist/providers/xai.js +0 -76
|
@@ -49,17 +49,15 @@ export const OPENAI_COMPAT_CATALOG = [
|
|
|
49
49
|
GroqModels.LLAMA_3_2_90B_VISION_PREVIEW,
|
|
50
50
|
GroqModels.LLAMA_3_2_11B_VISION_PREVIEW,
|
|
51
51
|
],
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
// shape; the TimeoutError special case is a structural gap in
|
|
62
|
-
// ConfiguredOpenAICompatProvider, not a data error here.
|
|
52
|
+
// Groq's pre-migration subclass intercepted TimeoutError itself and
|
|
53
|
+
// returned a plain ProviderError, ahead of classifyProviderError's own
|
|
54
|
+
// non-overridable TimeoutError -> NetworkError default. Expressed here
|
|
55
|
+
// as data — see OpenAICompatCatalogEntry.timeoutErrorClass and
|
|
56
|
+
// ConfiguredOpenAICompatProvider.formatProviderError, which consults
|
|
57
|
+
// this field before ever delegating to the shared classifier. No other
|
|
58
|
+
// entry in this catalog sets it, so every other provider still gets
|
|
59
|
+
// the classifier's unmodified default.
|
|
60
|
+
timeoutErrorClass: ProviderError,
|
|
63
61
|
errorRules: [
|
|
64
62
|
{
|
|
65
63
|
match: (ctx) => ctx.statusCode === 401 ||
|
|
@@ -8,7 +8,7 @@ import type { ValidationSchema } from "./aliases.js";
|
|
|
8
8
|
import type { EnhancedGenerateResult, GenerateResult, TextGenerationOptions } from "./generate.js";
|
|
9
9
|
import type { MultimodalAudioEntry } from "./file.js";
|
|
10
10
|
import type { StreamOptions, StreamResult } from "./stream.js";
|
|
11
|
-
import type { ProviderErrorRule } from "./errors.js";
|
|
11
|
+
import type { ProviderError, ProviderErrorRule } from "./errors.js";
|
|
12
12
|
import type { ExternalMCPToolInfo } from "./externalMcp.js";
|
|
13
13
|
import type { ClaudeSubscriptionTier, AnthropicAuthMethod, AnthropicAuthConfig, SubscriptionInfo, OAuthToken } from "./subscription.js";
|
|
14
14
|
import type { Tool } from "./tools.js";
|
|
@@ -671,6 +671,20 @@ export type OpenAICompatCatalogEntry = {
|
|
|
671
671
|
* Task 4, so nothing actually mutates it at runtime.
|
|
672
672
|
*/
|
|
673
673
|
errorRules: ProviderErrorRule[];
|
|
674
|
+
/**
|
|
675
|
+
* Optional override for the Error subclass a TimeoutError should produce
|
|
676
|
+
* for this entry. classifyProviderError() hard-codes
|
|
677
|
+
* TimeoutError -> NetworkError unconditionally, ahead of any rule table,
|
|
678
|
+
* and does not make that mapping overridable per-provider (see
|
|
679
|
+
* errorClassifier.ts). Groq's pre-migration subclass predates that
|
|
680
|
+
* shared classifier and intercepted TimeoutError itself, returning a
|
|
681
|
+
* plain ProviderError instead — this field lets
|
|
682
|
+
* ConfiguredOpenAICompatProvider reproduce that one documented
|
|
683
|
+
* divergence as data (see its formatProviderError), rather than adding a
|
|
684
|
+
* class-level hook back in. Omit for every entry whose timeout should use
|
|
685
|
+
* the classifier's default (six of the seven catalog entries).
|
|
686
|
+
*/
|
|
687
|
+
timeoutErrorClass?: new (message: string, provider?: string) => ProviderError;
|
|
674
688
|
};
|
|
675
689
|
/** The subset of OpenAICompatCatalogEntry that resolveOpenAICompatConfig()
|
|
676
690
|
* needs — lets call sites pass a minimal object without the full catalog
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "11.2.
|
|
3
|
+
"version": "11.2.3",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
5
|
"description": "TypeScript AI SDK with 24+ LLM providers behind one consistent API. MCP-native (connect any MCP server), voice TTS/STT/realtime, RAG, agents, memory, context compaction. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · DeepSeek · NVIDIA NIM and more.",
|
|
6
6
|
"author": {
|
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
"test:memory": "npx tsx test/continuous-test-suite-memory.ts",
|
|
83
83
|
"test:openai-compat-streaming-retry": "npx tsx test/continuous-test-suite-openai-compat-streaming-retry.ts",
|
|
84
84
|
"test:anthropic-streaming-retry": "npx tsx test/continuous-test-suite-anthropic-streaming-retry.ts",
|
|
85
|
+
"test:adjust-body-after-400": "npx tsx test/continuous-test-suite-adjust-body-after-400.ts",
|
|
85
86
|
"test:error-classification-e2e": "npx tsx test/continuous-test-suite-error-classification-e2e.ts",
|
|
86
87
|
"test:error-classifier-contract": "npx tsx test/continuous-test-suite-error-classifier-contract.ts",
|
|
87
88
|
"test:middleware": "npx tsx test/continuous-test-suite-middleware.ts",
|
|
@@ -124,7 +125,7 @@
|
|
|
124
125
|
"test:tool-dedup": "npx tsx test/continuous-test-suite-tool-dedup.ts",
|
|
125
126
|
"test:model-not-found-retryable": "npx tsx test/continuous-test-suite-model-not-found-retryable.ts",
|
|
126
127
|
"test:ci": "pnpm run test && pnpm run test:client && pnpm run test:hitl",
|
|
127
|
-
"// CI tier — fast, no live AI calls, safe for every commit (test:unit; also see the separate provider-safety-net CI job, which runs build + test:providers-mocked + test:provider-structure on every PR)": "",
|
|
128
|
+
"// CI tier — fast, no live AI calls, safe for every commit (test:unit; also see the separate provider-safety-net CI job, which runs build + test:providers-mocked + test:provider-structure + test:error-classifier-contract on every PR)": "",
|
|
128
129
|
"test:tool-routing": "npx tsx test/continuous-test-suite-tool-routing.ts",
|
|
129
130
|
"test:tool-routing-semantic": "npx tsx test/continuous-test-suite-tool-routing-semantic.ts",
|
|
130
131
|
"test:unit": "pnpm run test:bugfixes && pnpm run test:mcp:infra && pnpm run test:mcp:spans && pnpm run test:tool-routing && pnpm run test:tool-routing-cli && pnpm run test:tool-dedup && pnpm run test:model-pool && pnpm run test:tool-routing-semantic && pnpm run test:mcp-result-cache && pnpm run test:model-not-found-retryable && pnpm run test:archive:security && pnpm run test:office:security && pnpm run test:vector-chroma && pnpm run test:vector-pgvector && pnpm run test:vector-pinecone && pnpm run test:provider-wiring",
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import type { NeurolinkCredentials } from "../types/index.js";
|
|
3
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
4
|
-
/**
|
|
5
|
-
* Cloudflare Workers AI Provider — direct HTTP, no AI SDK.
|
|
6
|
-
*
|
|
7
|
-
* Edge-served open models (Llama / Mistral / Qwen / Gemma) at
|
|
8
|
-
* `https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/v1`
|
|
9
|
-
* (OpenAI-compatible). Cheapest tier for high-volume usage.
|
|
10
|
-
*
|
|
11
|
-
* Required env: `CLOUDFLARE_API_KEY` + `CLOUDFLARE_ACCOUNT_ID`.
|
|
12
|
-
*
|
|
13
|
-
* All request/stream/tool-loop orchestration lives in
|
|
14
|
-
* `OpenAIChatCompletionsProvider`; this class only declares configuration
|
|
15
|
-
* and provider-specific error mapping.
|
|
16
|
-
*
|
|
17
|
-
* @see https://developers.cloudflare.com/workers-ai/configuration/open-ai-compatibility/
|
|
18
|
-
*/
|
|
19
|
-
export declare class CloudflareProvider extends OpenAIChatCompletionsProvider {
|
|
20
|
-
constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["cloudflare"]);
|
|
21
|
-
protected getProviderName(): AIProviderName;
|
|
22
|
-
protected getDefaultModel(): string;
|
|
23
|
-
protected getFallbackModelName(): string;
|
|
24
|
-
protected getFallbackModels(): string[];
|
|
25
|
-
protected formatProviderError(error: unknown): Error;
|
|
26
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { CloudflareModels } from "../constants/enums.js";
|
|
2
|
-
import { AuthenticationError } from "../types/index.js";
|
|
3
|
-
import { logger } from "../utils/logger.js";
|
|
4
|
-
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
5
|
-
import { classifyProviderError, DEFAULT_ERROR_RULES, } from "../utils/errorClassifier.js";
|
|
6
|
-
import { createCloudflareConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
7
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
8
|
-
/**
|
|
9
|
-
* Cloudflare Workers AI exposes an OpenAI-compatible endpoint scoped per
|
|
10
|
-
* account: `https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/v1`.
|
|
11
|
-
* The account id is required — without it the URL would 404.
|
|
12
|
-
*/
|
|
13
|
-
const buildCloudflareBaseURL = (accountId) => `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1`;
|
|
14
|
-
const getCloudflareApiKey = () => validateApiKey(createCloudflareConfig());
|
|
15
|
-
const getDefaultCloudflareModel = () => getProviderModel("CLOUDFLARE_MODEL", CloudflareModels.LLAMA_3_3_70B_FAST);
|
|
16
|
-
/**
|
|
17
|
-
* Cloudflare Workers AI Provider — direct HTTP, no AI SDK.
|
|
18
|
-
*
|
|
19
|
-
* Edge-served open models (Llama / Mistral / Qwen / Gemma) at
|
|
20
|
-
* `https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/v1`
|
|
21
|
-
* (OpenAI-compatible). Cheapest tier for high-volume usage.
|
|
22
|
-
*
|
|
23
|
-
* Required env: `CLOUDFLARE_API_KEY` + `CLOUDFLARE_ACCOUNT_ID`.
|
|
24
|
-
*
|
|
25
|
-
* All request/stream/tool-loop orchestration lives in
|
|
26
|
-
* `OpenAIChatCompletionsProvider`; this class only declares configuration
|
|
27
|
-
* and provider-specific error mapping.
|
|
28
|
-
*
|
|
29
|
-
* @see https://developers.cloudflare.com/workers-ai/configuration/open-ai-compatibility/
|
|
30
|
-
*/
|
|
31
|
-
export class CloudflareProvider extends OpenAIChatCompletionsProvider {
|
|
32
|
-
constructor(modelName, sdk, _region, credentials) {
|
|
33
|
-
const overrideApiKey = credentials?.apiKey?.trim();
|
|
34
|
-
const apiKey = overrideApiKey && overrideApiKey.length > 0
|
|
35
|
-
? overrideApiKey
|
|
36
|
-
: getCloudflareApiKey();
|
|
37
|
-
const accountId = (credentials?.accountId ??
|
|
38
|
-
process.env.CLOUDFLARE_ACCOUNT_ID ??
|
|
39
|
-
"").trim();
|
|
40
|
-
if (!accountId) {
|
|
41
|
-
throw new Error("CLOUDFLARE_ACCOUNT_ID is required (or pass credentials.cloudflare.accountId). Get the account id from https://dash.cloudflare.com/");
|
|
42
|
-
}
|
|
43
|
-
const baseURL = credentials?.baseURL ?? buildCloudflareBaseURL(accountId);
|
|
44
|
-
super("cloudflare", modelName, sdk, { baseURL, apiKey });
|
|
45
|
-
logger.debug("Cloudflare Workers AI Provider initialized", {
|
|
46
|
-
modelName: this.modelName,
|
|
47
|
-
providerName: this.providerName,
|
|
48
|
-
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
getProviderName() {
|
|
52
|
-
return "cloudflare";
|
|
53
|
-
}
|
|
54
|
-
getDefaultModel() {
|
|
55
|
-
return getDefaultCloudflareModel();
|
|
56
|
-
}
|
|
57
|
-
getFallbackModelName() {
|
|
58
|
-
return CloudflareModels.LLAMA_3_1_8B_FAST;
|
|
59
|
-
}
|
|
60
|
-
getFallbackModels() {
|
|
61
|
-
return [
|
|
62
|
-
CloudflareModels.LLAMA_3_3_70B_FAST,
|
|
63
|
-
CloudflareModels.LLAMA_3_1_70B_INSTRUCT,
|
|
64
|
-
CloudflareModels.LLAMA_3_1_8B_FAST,
|
|
65
|
-
CloudflareModels.LLAMA_3_2_11B_VISION,
|
|
66
|
-
CloudflareModels.MISTRAL_7B_INSTRUCT_V0_2,
|
|
67
|
-
CloudflareModels.QWEN_1P5_14B_CHAT_AWQ,
|
|
68
|
-
];
|
|
69
|
-
}
|
|
70
|
-
formatProviderError(error) {
|
|
71
|
-
const rules = [
|
|
72
|
-
{
|
|
73
|
-
match: (ctx) => ctx.statusCode === 401 ||
|
|
74
|
-
/Invalid API key|Authentication/i.test(ctx.message),
|
|
75
|
-
errorClass: AuthenticationError,
|
|
76
|
-
message: "Invalid Cloudflare API key. Use a token with Workers AI Read+Write scope. Get one at https://dash.cloudflare.com/profile/api-tokens",
|
|
77
|
-
},
|
|
78
|
-
...DEFAULT_ERROR_RULES,
|
|
79
|
-
];
|
|
80
|
-
return classifyProviderError(error, rules, "cloudflare", this.modelName);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
//# sourceMappingURL=cloudflare.js.map
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import type { NeurolinkCredentials } from "../types/index.js";
|
|
3
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
4
|
-
/**
|
|
5
|
-
* Fireworks AI Provider — direct HTTP, no AI SDK.
|
|
6
|
-
*
|
|
7
|
-
* Hosted open-model serving at api.fireworks.ai/inference/v1
|
|
8
|
-
* (OpenAI-compatible). Best for low-latency at scale on Llama / Mixtral /
|
|
9
|
-
* Qwen / DeepSeek. All request/stream/tool-loop orchestration lives in
|
|
10
|
-
* `OpenAIChatCompletionsProvider`; this class only declares configuration
|
|
11
|
-
* and provider-specific error mapping.
|
|
12
|
-
*
|
|
13
|
-
* @see https://docs.fireworks.ai/api-reference/introduction
|
|
14
|
-
*/
|
|
15
|
-
export declare class FireworksProvider extends OpenAIChatCompletionsProvider {
|
|
16
|
-
constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["fireworks"]);
|
|
17
|
-
protected getProviderName(): AIProviderName;
|
|
18
|
-
protected getDefaultModel(): string;
|
|
19
|
-
protected getFallbackModelName(): string;
|
|
20
|
-
protected getFallbackModels(): string[];
|
|
21
|
-
protected formatProviderError(error: unknown): Error;
|
|
22
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { FireworksModels } from "../constants/enums.js";
|
|
2
|
-
import { AuthenticationError } from "../types/index.js";
|
|
3
|
-
import { logger } from "../utils/logger.js";
|
|
4
|
-
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
5
|
-
import { classifyProviderError, DEFAULT_ERROR_RULES, } from "../utils/errorClassifier.js";
|
|
6
|
-
import { createFireworksConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
7
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
8
|
-
const FIREWORKS_DEFAULT_BASE_URL = "https://api.fireworks.ai/inference/v1";
|
|
9
|
-
const getFireworksApiKey = () => validateApiKey(createFireworksConfig());
|
|
10
|
-
const getDefaultFireworksModel = () => getProviderModel("FIREWORKS_MODEL", FireworksModels.DEEPSEEK_V4_PRO);
|
|
11
|
-
/**
|
|
12
|
-
* Fireworks AI Provider — direct HTTP, no AI SDK.
|
|
13
|
-
*
|
|
14
|
-
* Hosted open-model serving at api.fireworks.ai/inference/v1
|
|
15
|
-
* (OpenAI-compatible). Best for low-latency at scale on Llama / Mixtral /
|
|
16
|
-
* Qwen / DeepSeek. All request/stream/tool-loop orchestration lives in
|
|
17
|
-
* `OpenAIChatCompletionsProvider`; this class only declares configuration
|
|
18
|
-
* and provider-specific error mapping.
|
|
19
|
-
*
|
|
20
|
-
* @see https://docs.fireworks.ai/api-reference/introduction
|
|
21
|
-
*/
|
|
22
|
-
export class FireworksProvider extends OpenAIChatCompletionsProvider {
|
|
23
|
-
constructor(modelName, sdk, _region, credentials) {
|
|
24
|
-
// Trim the override before applying precedence. A blank/whitespace
|
|
25
|
-
// `credentials.apiKey` must NOT bypass the env key — that would build a
|
|
26
|
-
// client with an unusable bearer token and fail at request time.
|
|
27
|
-
const overrideApiKey = credentials?.apiKey?.trim();
|
|
28
|
-
const apiKey = overrideApiKey && overrideApiKey.length > 0
|
|
29
|
-
? overrideApiKey
|
|
30
|
-
: getFireworksApiKey();
|
|
31
|
-
const baseURL = credentials?.baseURL?.trim() ||
|
|
32
|
-
process.env.FIREWORKS_BASE_URL?.trim() ||
|
|
33
|
-
FIREWORKS_DEFAULT_BASE_URL;
|
|
34
|
-
super("fireworks", modelName, sdk, { baseURL, apiKey });
|
|
35
|
-
logger.debug("Fireworks Provider initialized", {
|
|
36
|
-
modelName: this.modelName,
|
|
37
|
-
providerName: this.providerName,
|
|
38
|
-
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
getProviderName() {
|
|
42
|
-
return "fireworks";
|
|
43
|
-
}
|
|
44
|
-
getDefaultModel() {
|
|
45
|
-
return getDefaultFireworksModel();
|
|
46
|
-
}
|
|
47
|
-
getFallbackModelName() {
|
|
48
|
-
return FireworksModels.DEEPSEEK_V4_PRO;
|
|
49
|
-
}
|
|
50
|
-
getFallbackModels() {
|
|
51
|
-
return [
|
|
52
|
-
FireworksModels.DEEPSEEK_V4_PRO,
|
|
53
|
-
FireworksModels.GLM_5P1,
|
|
54
|
-
FireworksModels.GLM_5,
|
|
55
|
-
FireworksModels.KIMI_K2P6,
|
|
56
|
-
FireworksModels.KIMI_K2P5,
|
|
57
|
-
FireworksModels.GPT_OSS_120B,
|
|
58
|
-
];
|
|
59
|
-
}
|
|
60
|
-
formatProviderError(error) {
|
|
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 Fireworks API key. Get one at https://fireworks.ai/account/api-keys",
|
|
67
|
-
},
|
|
68
|
-
...DEFAULT_ERROR_RULES,
|
|
69
|
-
];
|
|
70
|
-
return classifyProviderError(error, rules, "fireworks", this.modelName);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=fireworks.js.map
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import type { NeurolinkCredentials } from "../types/index.js";
|
|
3
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
4
|
-
/**
|
|
5
|
-
* Groq Provider — direct HTTP, no AI SDK.
|
|
6
|
-
*
|
|
7
|
-
* Sub-100ms inference of Llama / Mistral / Gemma at api.groq.com/openai/v1
|
|
8
|
-
* (OpenAI-compatible). Best for low-latency tier; trade-off vs other open
|
|
9
|
-
* model hosts is throughput latency, not quality.
|
|
10
|
-
*
|
|
11
|
-
* All request/stream/tool-loop orchestration lives in
|
|
12
|
-
* `OpenAIChatCompletionsProvider`; this class only declares configuration
|
|
13
|
-
* and provider-specific error mapping.
|
|
14
|
-
*
|
|
15
|
-
* @see https://console.groq.com/docs/quickstart
|
|
16
|
-
*/
|
|
17
|
-
export declare class GroqProvider extends OpenAIChatCompletionsProvider {
|
|
18
|
-
constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["groq"]);
|
|
19
|
-
protected getProviderName(): AIProviderName;
|
|
20
|
-
protected getDefaultModel(): string;
|
|
21
|
-
protected getFallbackModelName(): string;
|
|
22
|
-
protected getFallbackModels(): string[];
|
|
23
|
-
protected formatProviderError(error: unknown): Error;
|
|
24
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { GroqModels } from "../constants/enums.js";
|
|
2
|
-
import { AuthenticationError, InvalidModelError, ProviderError, } from "../types/index.js";
|
|
3
|
-
import { logger } from "../utils/logger.js";
|
|
4
|
-
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
5
|
-
import { classifyProviderError, DEFAULT_ERROR_RULES, } from "../utils/errorClassifier.js";
|
|
6
|
-
import { createGroqConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
7
|
-
import { TimeoutError } from "../utils/timeout.js";
|
|
8
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
9
|
-
const GROQ_DEFAULT_BASE_URL = "https://api.groq.com/openai/v1";
|
|
10
|
-
const getGroqApiKey = () => validateApiKey(createGroqConfig());
|
|
11
|
-
const getDefaultGroqModel = () => getProviderModel("GROQ_MODEL", GroqModels.LLAMA_3_3_70B_VERSATILE);
|
|
12
|
-
/**
|
|
13
|
-
* Groq Provider — direct HTTP, no AI SDK.
|
|
14
|
-
*
|
|
15
|
-
* Sub-100ms inference of Llama / Mistral / Gemma at api.groq.com/openai/v1
|
|
16
|
-
* (OpenAI-compatible). Best for low-latency tier; trade-off vs other open
|
|
17
|
-
* model hosts is throughput latency, not quality.
|
|
18
|
-
*
|
|
19
|
-
* All request/stream/tool-loop orchestration lives in
|
|
20
|
-
* `OpenAIChatCompletionsProvider`; this class only declares configuration
|
|
21
|
-
* and provider-specific error mapping.
|
|
22
|
-
*
|
|
23
|
-
* @see https://console.groq.com/docs/quickstart
|
|
24
|
-
*/
|
|
25
|
-
export class GroqProvider extends OpenAIChatCompletionsProvider {
|
|
26
|
-
constructor(modelName, sdk, _region, credentials) {
|
|
27
|
-
const overrideApiKey = credentials?.apiKey?.trim();
|
|
28
|
-
const apiKey = overrideApiKey && overrideApiKey.length > 0
|
|
29
|
-
? overrideApiKey
|
|
30
|
-
: getGroqApiKey();
|
|
31
|
-
const baseURL = credentials?.baseURL?.trim() ||
|
|
32
|
-
process.env.GROQ_BASE_URL?.trim() ||
|
|
33
|
-
GROQ_DEFAULT_BASE_URL;
|
|
34
|
-
super("groq", modelName, sdk, { baseURL, apiKey });
|
|
35
|
-
logger.debug("Groq Provider initialized", {
|
|
36
|
-
modelName: this.modelName,
|
|
37
|
-
providerName: this.providerName,
|
|
38
|
-
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
getProviderName() {
|
|
42
|
-
return "groq";
|
|
43
|
-
}
|
|
44
|
-
getDefaultModel() {
|
|
45
|
-
return getDefaultGroqModel();
|
|
46
|
-
}
|
|
47
|
-
getFallbackModelName() {
|
|
48
|
-
return GroqModels.LLAMA_3_1_8B_INSTANT;
|
|
49
|
-
}
|
|
50
|
-
getFallbackModels() {
|
|
51
|
-
return [
|
|
52
|
-
GroqModels.LLAMA_3_3_70B_VERSATILE,
|
|
53
|
-
GroqModels.LLAMA_3_1_8B_INSTANT,
|
|
54
|
-
GroqModels.GEMMA_2_9B_IT,
|
|
55
|
-
GroqModels.MIXTRAL_8X7B_32768,
|
|
56
|
-
GroqModels.LLAMA_3_2_90B_VISION_PREVIEW,
|
|
57
|
-
GroqModels.LLAMA_3_2_11B_VISION_PREVIEW,
|
|
58
|
-
];
|
|
59
|
-
}
|
|
60
|
-
formatProviderError(error) {
|
|
61
|
-
// Groq's TimeoutError maps to plain ProviderError (not NetworkError, the
|
|
62
|
-
// classifier's built-in default) — intercept before delegating.
|
|
63
|
-
if (error instanceof TimeoutError) {
|
|
64
|
-
return new ProviderError(`Groq request timed out: ${error.message}`, "groq");
|
|
65
|
-
}
|
|
66
|
-
const rules = [
|
|
67
|
-
{
|
|
68
|
-
match: (ctx) => ctx.statusCode === 401 ||
|
|
69
|
-
/Invalid API key|Authentication|invalid_api_key/i.test(ctx.message),
|
|
70
|
-
errorClass: AuthenticationError,
|
|
71
|
-
message: "Invalid Groq API key. Check GROQ_API_KEY. Get one at https://console.groq.com/keys",
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
match: (ctx) => /model_decommissioned/i.test(ctx.message),
|
|
75
|
-
errorClass: InvalidModelError,
|
|
76
|
-
message: (ctx) => `Groq model '${ctx.modelName}' was decommissioned. Pick a current model from https://console.groq.com/docs/models.`,
|
|
77
|
-
},
|
|
78
|
-
...DEFAULT_ERROR_RULES,
|
|
79
|
-
];
|
|
80
|
-
return classifyProviderError(error, rules, "groq", this.modelName);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
//# sourceMappingURL=groq.js.map
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import type { NeurolinkCredentials } from "../types/index.js";
|
|
3
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
4
|
-
/**
|
|
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/
|
|
17
|
-
*/
|
|
18
|
-
export declare class MistralProvider extends OpenAIChatCompletionsProvider {
|
|
19
|
-
constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["mistral"]);
|
|
20
|
-
protected getProviderName(): AIProviderName;
|
|
21
|
-
protected getDefaultModel(): string;
|
|
22
|
-
protected formatProviderError(error: unknown): Error;
|
|
23
|
-
protected getFallbackModelName(): string;
|
|
24
|
-
protected getFallbackModels(): string[];
|
|
25
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { MistralModels } from "../constants/enums.js";
|
|
2
|
-
import { AuthenticationError } from "../types/index.js";
|
|
3
|
-
import { logger } from "../utils/logger.js";
|
|
4
|
-
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
5
|
-
import { classifyProviderError, DEFAULT_ERROR_RULES, } from "../utils/errorClassifier.js";
|
|
6
|
-
import { createMistralConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
7
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
8
|
-
const MISTRAL_DEFAULT_BASE_URL = "https://api.mistral.ai/v1";
|
|
9
|
-
const getMistralApiKey = () => {
|
|
10
|
-
return validateApiKey(createMistralConfig());
|
|
11
|
-
};
|
|
12
|
-
const getDefaultMistralModel = () => {
|
|
13
|
-
// Vision-capable Mistral Small (June 2025) with multimodal support.
|
|
14
|
-
return getProviderModel("MISTRAL_MODEL", MistralModels.MISTRAL_SMALL_2506);
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
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/
|
|
29
|
-
*/
|
|
30
|
-
export class MistralProvider extends OpenAIChatCompletionsProvider {
|
|
31
|
-
constructor(modelName, sdk, _region, credentials) {
|
|
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", {
|
|
48
|
-
modelName: this.modelName,
|
|
49
|
-
providerName: this.providerName,
|
|
50
|
-
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
// ===========================================================================
|
|
54
|
-
// Abstract hooks (required)
|
|
55
|
-
// ===========================================================================
|
|
56
|
-
getProviderName() {
|
|
57
|
-
return "mistral";
|
|
58
|
-
}
|
|
59
|
-
getDefaultModel() {
|
|
60
|
-
return getDefaultMistralModel();
|
|
61
|
-
}
|
|
62
|
-
formatProviderError(error) {
|
|
63
|
-
const rules = [
|
|
64
|
-
{
|
|
65
|
-
match: (ctx) => ctx.statusCode === 401 ||
|
|
66
|
-
/API_KEY_INVALID|Invalid API key|Unauthorized/i.test(ctx.message),
|
|
67
|
-
errorClass: AuthenticationError,
|
|
68
|
-
message: "Invalid Mistral API key. Please check your MISTRAL_API_KEY environment variable.",
|
|
69
|
-
},
|
|
70
|
-
...DEFAULT_ERROR_RULES,
|
|
71
|
-
];
|
|
72
|
-
return classifyProviderError(error, rules, "mistral", this.modelName);
|
|
73
|
-
}
|
|
74
|
-
// ===========================================================================
|
|
75
|
-
// Optional hooks
|
|
76
|
-
// ===========================================================================
|
|
77
|
-
getFallbackModelName() {
|
|
78
|
-
return MistralModels.MISTRAL_SMALL_2506;
|
|
79
|
-
}
|
|
80
|
-
getFallbackModels() {
|
|
81
|
-
return [
|
|
82
|
-
MistralModels.MISTRAL_SMALL_2506,
|
|
83
|
-
MistralModels.MISTRAL_LARGE_LATEST,
|
|
84
|
-
];
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
//# sourceMappingURL=mistral.js.map
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import type { NeurolinkCredentials } from "../types/index.js";
|
|
3
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
4
|
-
/**
|
|
5
|
-
* Perplexity Provider — direct HTTP, no AI SDK.
|
|
6
|
-
*
|
|
7
|
-
* Sonar models with built-in web grounding. OpenAI-compatible chat
|
|
8
|
-
* completions at api.perplexity.ai. Best for queries that need fresh
|
|
9
|
-
* web context (search-augmented answers). Citation data, if the API returns
|
|
10
|
-
* any, is not extracted or exposed by this provider.
|
|
11
|
-
*
|
|
12
|
-
* All request/stream/tool-loop orchestration lives in
|
|
13
|
-
* `OpenAIChatCompletionsProvider`; this class only declares configuration
|
|
14
|
-
* and provider-specific error mapping.
|
|
15
|
-
*
|
|
16
|
-
* @see https://docs.perplexity.ai/api-reference/chat-completions
|
|
17
|
-
*/
|
|
18
|
-
export declare class PerplexityProvider extends OpenAIChatCompletionsProvider {
|
|
19
|
-
constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["perplexity"]);
|
|
20
|
-
protected getProviderName(): AIProviderName;
|
|
21
|
-
protected getDefaultModel(): string;
|
|
22
|
-
protected getFallbackModels(): string[];
|
|
23
|
-
protected formatProviderError(error: unknown): Error;
|
|
24
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { PerplexityModels } from "../constants/enums.js";
|
|
2
|
-
import { AuthenticationError } from "../types/index.js";
|
|
3
|
-
import { logger } from "../utils/logger.js";
|
|
4
|
-
import { redactUrlCredentials } from "../utils/logSanitize.js";
|
|
5
|
-
import { classifyProviderError, DEFAULT_ERROR_RULES, } from "../utils/errorClassifier.js";
|
|
6
|
-
import { createPerplexityConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
|
|
7
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
8
|
-
const PERPLEXITY_DEFAULT_BASE_URL = "https://api.perplexity.ai";
|
|
9
|
-
const getPerplexityApiKey = () => validateApiKey(createPerplexityConfig());
|
|
10
|
-
const getDefaultPerplexityModel = () => getProviderModel("PERPLEXITY_MODEL", PerplexityModels.SONAR);
|
|
11
|
-
/**
|
|
12
|
-
* Perplexity Provider — direct HTTP, no AI SDK.
|
|
13
|
-
*
|
|
14
|
-
* Sonar models with built-in web grounding. OpenAI-compatible chat
|
|
15
|
-
* completions at api.perplexity.ai. Best for queries that need fresh
|
|
16
|
-
* web context (search-augmented answers). Citation data, if the API returns
|
|
17
|
-
* any, is not extracted or exposed by this provider.
|
|
18
|
-
*
|
|
19
|
-
* All request/stream/tool-loop orchestration lives in
|
|
20
|
-
* `OpenAIChatCompletionsProvider`; this class only declares configuration
|
|
21
|
-
* and provider-specific error mapping.
|
|
22
|
-
*
|
|
23
|
-
* @see https://docs.perplexity.ai/api-reference/chat-completions
|
|
24
|
-
*/
|
|
25
|
-
export class PerplexityProvider extends OpenAIChatCompletionsProvider {
|
|
26
|
-
constructor(modelName, sdk, _region, credentials) {
|
|
27
|
-
const overrideApiKey = credentials?.apiKey?.trim();
|
|
28
|
-
const apiKey = overrideApiKey && overrideApiKey.length > 0
|
|
29
|
-
? overrideApiKey
|
|
30
|
-
: getPerplexityApiKey();
|
|
31
|
-
const baseURL = credentials?.baseURL?.trim() ||
|
|
32
|
-
process.env.PERPLEXITY_BASE_URL?.trim() ||
|
|
33
|
-
PERPLEXITY_DEFAULT_BASE_URL;
|
|
34
|
-
super("perplexity", modelName, sdk, { baseURL, apiKey });
|
|
35
|
-
logger.debug("Perplexity Provider initialized", {
|
|
36
|
-
modelName: this.modelName,
|
|
37
|
-
providerName: this.providerName,
|
|
38
|
-
baseURL: redactUrlCredentials(this.config.baseURL),
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
getProviderName() {
|
|
42
|
-
return "perplexity";
|
|
43
|
-
}
|
|
44
|
-
getDefaultModel() {
|
|
45
|
-
return getDefaultPerplexityModel();
|
|
46
|
-
}
|
|
47
|
-
getFallbackModels() {
|
|
48
|
-
return [
|
|
49
|
-
PerplexityModels.SONAR,
|
|
50
|
-
PerplexityModels.SONAR_PRO,
|
|
51
|
-
PerplexityModels.SONAR_REASONING,
|
|
52
|
-
PerplexityModels.SONAR_REASONING_PRO,
|
|
53
|
-
PerplexityModels.SONAR_DEEP_RESEARCH,
|
|
54
|
-
];
|
|
55
|
-
}
|
|
56
|
-
formatProviderError(error) {
|
|
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);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
//# sourceMappingURL=perplexity.js.map
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import type { NeurolinkCredentials } from "../types/index.js";
|
|
3
|
-
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
4
|
-
/**
|
|
5
|
-
* Together AI Provider — direct HTTP, no AI SDK.
|
|
6
|
-
*
|
|
7
|
-
* Hosted open-model gateway at api.together.xyz/v1 (OpenAI-compatible).
|
|
8
|
-
* Llama / Mistral / Qwen / DeepSeek / Gemma / WizardLM available
|
|
9
|
-
* server-less; pass any catalog id via `--model`.
|
|
10
|
-
* All request/stream/tool-loop orchestration lives in
|
|
11
|
-
* `OpenAIChatCompletionsProvider`; this class only declares configuration
|
|
12
|
-
* and provider-specific error mapping.
|
|
13
|
-
*
|
|
14
|
-
* @see https://docs.together.ai/docs/openai-api-compatibility
|
|
15
|
-
*/
|
|
16
|
-
export declare class TogetherAIProvider extends OpenAIChatCompletionsProvider {
|
|
17
|
-
constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["together"]);
|
|
18
|
-
protected getProviderName(): AIProviderName;
|
|
19
|
-
protected getDefaultModel(): string;
|
|
20
|
-
protected getFallbackModelName(): string;
|
|
21
|
-
protected getFallbackModels(): string[];
|
|
22
|
-
protected formatProviderError(error: unknown): Error;
|
|
23
|
-
}
|