@juspay/neurolink 12.9.1 → 12.9.2
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 +2 -2
- package/dist/browser/neurolink.min.js +359 -359
- package/dist/constants/enums.d.ts +17 -2
- package/dist/constants/enums.js +17 -2
- package/dist/core/baseProvider.d.ts +56 -0
- package/dist/core/baseProvider.js +308 -17
- package/dist/providers/catalog/cerebras.json +15 -5
- package/dist/providers/catalog/cloudflare.json +17 -13
- package/dist/providers/catalog/fireworks.json +74 -43
- package/dist/providers/catalog/groq.json +81 -32
- package/dist/providers/catalog/loader.js +3 -0
- package/dist/providers/catalog/mistral.json +27 -23
- package/dist/providers/catalog/provider-catalog.schema.json +5 -0
- package/dist/providers/catalog/sambanova.json +36 -11
- package/dist/providers/catalog/schema.d.ts +2 -1
- package/dist/providers/catalog/schema.js +1 -0
- package/dist/providers/catalog/xai.json +39 -26
- package/dist/providers/configuredOpenAICompat.d.ts +18 -1
- package/dist/providers/configuredOpenAICompat.js +48 -0
- package/dist/providers/openaiChatCompletionsBase.d.ts +15 -0
- package/dist/providers/openaiChatCompletionsBase.js +20 -0
- package/dist/types/providerCatalog.d.ts +6 -0
- package/dist/types/providers.d.ts +3 -0
- package/package.json +2 -1
|
@@ -8,23 +8,38 @@
|
|
|
8
8
|
"baseURL": "https://api.x.ai/v1"
|
|
9
9
|
},
|
|
10
10
|
"models": {
|
|
11
|
-
"default": "grok-
|
|
12
|
-
"fallbacks": [
|
|
13
|
-
"grok-3",
|
|
14
|
-
"grok-3-mini",
|
|
15
|
-
"grok-2-latest",
|
|
16
|
-
"grok-2-vision-latest",
|
|
17
|
-
"grok-beta"
|
|
18
|
-
],
|
|
11
|
+
"default": "grok-4.6",
|
|
12
|
+
"fallbacks": ["grok-4.6", "grok-4.5", "grok-4.3", "grok-3", "grok-3-mini"],
|
|
19
13
|
"defaultContextWindow": 131072,
|
|
20
14
|
"defaultMaxOutputTokens": 4096,
|
|
21
15
|
"catalog": {
|
|
16
|
+
"grok-4.6": {
|
|
17
|
+
"enumMember": "GROK_4_6",
|
|
18
|
+
"contextWindow": 131072,
|
|
19
|
+
"vision": true,
|
|
20
|
+
"status": "production",
|
|
21
|
+
"description": "Recommended - Grok 4.6, current flagship; vision-capable"
|
|
22
|
+
},
|
|
23
|
+
"grok-4.5": {
|
|
24
|
+
"enumMember": "GROK_4_5",
|
|
25
|
+
"contextWindow": 131072,
|
|
26
|
+
"vision": true,
|
|
27
|
+
"status": "production",
|
|
28
|
+
"description": "Grok 4.5 — vision-capable"
|
|
29
|
+
},
|
|
30
|
+
"grok-4.3": {
|
|
31
|
+
"enumMember": "GROK_4_3",
|
|
32
|
+
"contextWindow": 131072,
|
|
33
|
+
"vision": true,
|
|
34
|
+
"status": "production",
|
|
35
|
+
"description": "Grok 4.3 — vision-capable"
|
|
36
|
+
},
|
|
22
37
|
"grok-3": {
|
|
23
38
|
"contextWindow": 131072,
|
|
24
39
|
"pricingPerMTok": { "input": 3.0, "output": 15.0 },
|
|
25
40
|
"vision": false,
|
|
26
41
|
"status": "production",
|
|
27
|
-
"description": "
|
|
42
|
+
"description": "Grok 3 — still served, though absent from the /models roster"
|
|
28
43
|
},
|
|
29
44
|
"grok-3-mini": {
|
|
30
45
|
"contextWindow": 131072,
|
|
@@ -37,31 +52,26 @@
|
|
|
37
52
|
"contextWindow": 131072,
|
|
38
53
|
"pricingPerMTok": { "input": 2.0, "output": 10.0 },
|
|
39
54
|
"vision": false,
|
|
40
|
-
"status": "
|
|
41
|
-
"description": "
|
|
55
|
+
"status": "retired",
|
|
56
|
+
"description": "Retired 2026-08 — xAI rejects it as an invalid model"
|
|
42
57
|
},
|
|
43
58
|
"grok-2-vision-latest": {
|
|
44
59
|
"contextWindow": 32768,
|
|
45
60
|
"pricingPerMTok": { "input": 2.0, "output": 10.0 },
|
|
46
|
-
"vision":
|
|
47
|
-
"status": "
|
|
48
|
-
"description": "
|
|
61
|
+
"vision": false,
|
|
62
|
+
"status": "retired",
|
|
63
|
+
"description": "Retired 2026-08 — xAI rejects it as an invalid model; vision moved to the grok-4.x line"
|
|
49
64
|
},
|
|
50
65
|
"grok-beta": {
|
|
51
66
|
"contextWindow": 131072,
|
|
52
67
|
"pricingPerMTok": { "input": 5.0, "output": 15.0 },
|
|
53
68
|
"vision": false,
|
|
54
|
-
"status": "
|
|
55
|
-
"description": "
|
|
69
|
+
"status": "retired",
|
|
70
|
+
"description": "Retired 2026-08 — xAI rejects it as an invalid model"
|
|
56
71
|
}
|
|
57
72
|
},
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
"grok-3-mini",
|
|
61
|
-
"grok-2-vision-latest",
|
|
62
|
-
"grok-2-latest",
|
|
63
|
-
"grok-beta"
|
|
64
|
-
]
|
|
73
|
+
"visionModel": "grok-4.6",
|
|
74
|
+
"topModels": ["grok-4.6", "grok-4.5", "grok-4.3", "grok-3"]
|
|
65
75
|
},
|
|
66
76
|
"capabilities": {
|
|
67
77
|
"text": true,
|
|
@@ -99,10 +109,13 @@
|
|
|
99
109
|
},
|
|
100
110
|
"evidence": {
|
|
101
111
|
"rosterVerified": {
|
|
102
|
-
"date": "2026-08-
|
|
103
|
-
"method": "
|
|
112
|
+
"date": "2026-08-30",
|
|
113
|
+
"method": "GET /models against the live account, cross-checked with a real chat call per id"
|
|
114
|
+
},
|
|
115
|
+
"liveMatrix": {
|
|
116
|
+
"date": "2026-08-30",
|
|
117
|
+
"result": "grok-2-latest, grok-2-vision-latest and grok-beta are rejected as invalid models. The grok-4.x line replaces them: 4.3/4.5/4.6 all answer, and all three read a 64x64 PNG correctly, so vision moved there from the retired grok-2-vision-latest. An earlier probe with an 8x8 PNG reported no vision — that was xAI answering 'Invalid PNG image', a complaint about the file rather than the capability. grok-3 and grok-3-mini are kept because they still serve, even though xAI's /models roster omits them: roster absence is not evidence of death here."
|
|
104
118
|
},
|
|
105
|
-
"liveMatrix": null,
|
|
106
119
|
"addedInPR": "https://github.com/juspay/neurolink/pull/1587"
|
|
107
120
|
}
|
|
108
121
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import type { OpenAICompatCatalogEntry, OpenAICompatCredentials } from "../types/index.js";
|
|
2
|
+
import type { OpenAICompatCatalogEntry, OpenAICompatChatRequest, OpenAICompatCredentials } from "../types/index.js";
|
|
3
3
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
4
4
|
/**
|
|
5
5
|
* Generic OpenAI-compatible provider driven entirely by an
|
|
@@ -12,6 +12,22 @@ import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
|
12
12
|
* adjustBodyAfter400, getChatCompletionsURL, getAuthHeaders,
|
|
13
13
|
* suppressResponseFormatWithTools, ...) it does NOT belong in the catalog —
|
|
14
14
|
* write a dedicated subclass instead (see deepseek.ts, azureOpenai.ts).
|
|
15
|
+
*
|
|
16
|
+
* The exception is a WIRE DIALECT: a vendor that speaks OpenAI for ordinary
|
|
17
|
+
* chat but encodes one part of the request differently. Expressing that as
|
|
18
|
+
* data (the catalog's `messageContentFormat`) keeps the provider a
|
|
19
|
+
* one-JSON-file entry instead of promoting it to a hand-written subclass
|
|
20
|
+
* over a single incompatibility.
|
|
21
|
+
*
|
|
22
|
+
* Today that is Cloudflare Workers AI, whose OpenAI-compatible endpoint
|
|
23
|
+
* accepts `messages[].content` only as a plain string — never the
|
|
24
|
+
* content-parts array OpenAI allows, and never the `null` that OpenAI uses
|
|
25
|
+
* on an assistant message carrying tool_calls. Its schema rejects both with
|
|
26
|
+
* HTTP 400 ("Type mismatch of '/messages/N/content'"). That bites precisely
|
|
27
|
+
* on the second turn of a tool call, so single-turn chat looks healthy while
|
|
28
|
+
* every tool round-trip fails. Normalizing content to a string below is the
|
|
29
|
+
* whole fix: tools, tool_choice, the `tool` role and `tool_calls` are all
|
|
30
|
+
* accepted as-is.
|
|
15
31
|
*/
|
|
16
32
|
export declare class ConfiguredOpenAICompatProvider extends OpenAIChatCompletionsProvider {
|
|
17
33
|
private readonly entry;
|
|
@@ -20,5 +36,6 @@ export declare class ConfiguredOpenAICompatProvider extends OpenAIChatCompletion
|
|
|
20
36
|
protected getDefaultModel(): string;
|
|
21
37
|
protected getFallbackModelName(): string;
|
|
22
38
|
protected getFallbackModels(): string[];
|
|
39
|
+
protected adjustRequestBody(body: OpenAICompatChatRequest, modelId: string): OpenAICompatChatRequest;
|
|
23
40
|
protected formatProviderError(error: unknown): Error;
|
|
24
41
|
}
|
|
@@ -4,6 +4,25 @@ import { getProviderModel, resolveOpenAICompatConfig, } from "../utils/providerC
|
|
|
4
4
|
import { classifyProviderError } from "../utils/errorClassifier.js";
|
|
5
5
|
import { TimeoutError } from "../utils/timeout.js";
|
|
6
6
|
import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
7
|
+
/**
|
|
8
|
+
* Collapse OpenAI's `content` union down to the plain string that
|
|
9
|
+
* string-only vendors accept. Image parts carry no string representation and
|
|
10
|
+
* are dropped — a provider that cannot accept a content array cannot accept
|
|
11
|
+
* inline images either.
|
|
12
|
+
*/
|
|
13
|
+
const flattenMessageContent = (content) => {
|
|
14
|
+
if (typeof content === "string") {
|
|
15
|
+
return content;
|
|
16
|
+
}
|
|
17
|
+
// An assistant message with tool_calls legitimately has null content;
|
|
18
|
+
// the empty string is its string-only equivalent.
|
|
19
|
+
if (content === null || content === undefined) {
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
return content
|
|
23
|
+
.map((part) => (part.type === "text" ? part.text : ""))
|
|
24
|
+
.join("");
|
|
25
|
+
};
|
|
7
26
|
/**
|
|
8
27
|
* Generic OpenAI-compatible provider driven entirely by an
|
|
9
28
|
* OpenAICompatCatalogEntry. Replaces a hand-written subclass for any
|
|
@@ -15,6 +34,22 @@ import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
|
|
|
15
34
|
* adjustBodyAfter400, getChatCompletionsURL, getAuthHeaders,
|
|
16
35
|
* suppressResponseFormatWithTools, ...) it does NOT belong in the catalog —
|
|
17
36
|
* write a dedicated subclass instead (see deepseek.ts, azureOpenai.ts).
|
|
37
|
+
*
|
|
38
|
+
* The exception is a WIRE DIALECT: a vendor that speaks OpenAI for ordinary
|
|
39
|
+
* chat but encodes one part of the request differently. Expressing that as
|
|
40
|
+
* data (the catalog's `messageContentFormat`) keeps the provider a
|
|
41
|
+
* one-JSON-file entry instead of promoting it to a hand-written subclass
|
|
42
|
+
* over a single incompatibility.
|
|
43
|
+
*
|
|
44
|
+
* Today that is Cloudflare Workers AI, whose OpenAI-compatible endpoint
|
|
45
|
+
* accepts `messages[].content` only as a plain string — never the
|
|
46
|
+
* content-parts array OpenAI allows, and never the `null` that OpenAI uses
|
|
47
|
+
* on an assistant message carrying tool_calls. Its schema rejects both with
|
|
48
|
+
* HTTP 400 ("Type mismatch of '/messages/N/content'"). That bites precisely
|
|
49
|
+
* on the second turn of a tool call, so single-turn chat looks healthy while
|
|
50
|
+
* every tool round-trip fails. Normalizing content to a string below is the
|
|
51
|
+
* whole fix: tools, tool_choice, the `tool` role and `tool_calls` are all
|
|
52
|
+
* accepted as-is.
|
|
18
53
|
*/
|
|
19
54
|
export class ConfiguredOpenAICompatProvider extends OpenAIChatCompletionsProvider {
|
|
20
55
|
entry;
|
|
@@ -51,6 +86,19 @@ export class ConfiguredOpenAICompatProvider extends OpenAIChatCompletionsProvide
|
|
|
51
86
|
getFallbackModels() {
|
|
52
87
|
return this.entry.fallbackModels;
|
|
53
88
|
}
|
|
89
|
+
adjustRequestBody(body, modelId) {
|
|
90
|
+
const adjusted = super.adjustRequestBody(body, modelId);
|
|
91
|
+
if (this.entry.messageContentFormat !== "string") {
|
|
92
|
+
return adjusted;
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
...adjusted,
|
|
96
|
+
messages: adjusted.messages.map((message) => ({
|
|
97
|
+
...message,
|
|
98
|
+
content: flattenMessageContent(message.content),
|
|
99
|
+
})),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
54
102
|
formatProviderError(error) {
|
|
55
103
|
// classifyProviderError hard-codes TimeoutError -> NetworkError ahead
|
|
56
104
|
// of any rule table and does not allow a per-provider override. An
|
|
@@ -45,6 +45,21 @@ export declare abstract class OpenAIChatCompletionsProvider extends BaseProvider
|
|
|
45
45
|
* Hardcoded model names returned from `getAvailableModels()` when the
|
|
46
46
|
* remote `/models` endpoint can't be reached. Default empty.
|
|
47
47
|
*/
|
|
48
|
+
/**
|
|
49
|
+
* Feed the catalog's `fallbacks` to BaseProvider's invalid-model retry, so
|
|
50
|
+
* a default the vendor has retired degrades to the next live model in the
|
|
51
|
+
* entry instead of failing the call outright.
|
|
52
|
+
*/
|
|
53
|
+
protected getModelFallbacks(): string[];
|
|
54
|
+
/**
|
|
55
|
+
* `resolvedModel` memoizes the first id this provider resolved, and
|
|
56
|
+
* getAISDKModel() builds its wire model from that memo rather than from
|
|
57
|
+
* `modelName`. Leaving it stale here silently defeats the invalid-model
|
|
58
|
+
* fallback: modelName advances to the next candidate while every request
|
|
59
|
+
* still carries the retired id, so each retry fails for the same reason
|
|
60
|
+
* the first attempt did.
|
|
61
|
+
*/
|
|
62
|
+
protected refreshHandlersForModel(model: string): void;
|
|
48
63
|
protected getFallbackModels(): string[];
|
|
49
64
|
/**
|
|
50
65
|
* Hook to mutate the `buildBody` options before the wire body is
|
|
@@ -68,6 +68,26 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
68
68
|
* Hardcoded model names returned from `getAvailableModels()` when the
|
|
69
69
|
* remote `/models` endpoint can't be reached. Default empty.
|
|
70
70
|
*/
|
|
71
|
+
/**
|
|
72
|
+
* Feed the catalog's `fallbacks` to BaseProvider's invalid-model retry, so
|
|
73
|
+
* a default the vendor has retired degrades to the next live model in the
|
|
74
|
+
* entry instead of failing the call outright.
|
|
75
|
+
*/
|
|
76
|
+
getModelFallbacks() {
|
|
77
|
+
return this.getFallbackModels();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* `resolvedModel` memoizes the first id this provider resolved, and
|
|
81
|
+
* getAISDKModel() builds its wire model from that memo rather than from
|
|
82
|
+
* `modelName`. Leaving it stale here silently defeats the invalid-model
|
|
83
|
+
* fallback: modelName advances to the next candidate while every request
|
|
84
|
+
* still carries the retired id, so each retry fails for the same reason
|
|
85
|
+
* the first attempt did.
|
|
86
|
+
*/
|
|
87
|
+
refreshHandlersForModel(model) {
|
|
88
|
+
this.resolvedModel = model;
|
|
89
|
+
super.refreshHandlersForModel(model);
|
|
90
|
+
}
|
|
71
91
|
getFallbackModels() {
|
|
72
92
|
return [];
|
|
73
93
|
}
|
|
@@ -44,6 +44,12 @@ export type CatalogErrorRuleJson = {
|
|
|
44
44
|
};
|
|
45
45
|
export type CatalogQuirks = {
|
|
46
46
|
timeoutErrorClass?: "provider";
|
|
47
|
+
/** Vendor speaks OpenAI for chat but restricts how message content is
|
|
48
|
+
* encoded. "string": `messages[].content` must be a plain string —
|
|
49
|
+
* the content-parts array and the `null` OpenAI uses on an assistant
|
|
50
|
+
* message with tool_calls are both rejected with HTTP 400. Normalized by
|
|
51
|
+
* ConfiguredOpenAICompatProvider so tool round-trips work. */
|
|
52
|
+
messageContentFormat?: "string";
|
|
47
53
|
registryDefaultIgnoresModelEnvVar?: boolean;
|
|
48
54
|
};
|
|
49
55
|
export type CatalogBillingPolicy = "free-tier" | "free-with-card" | "no-free-tier";
|
|
@@ -693,6 +693,9 @@ export type OpenAICompatCatalogEntry = {
|
|
|
693
693
|
* the classifier's default (six of the seven catalog entries).
|
|
694
694
|
*/
|
|
695
695
|
timeoutErrorClass?: new (message: string, provider?: string) => ProviderError;
|
|
696
|
+
/** See CatalogQuirks.messageContentFormat — a vendor that accepts
|
|
697
|
+
* `messages[].content` only as a plain string. */
|
|
698
|
+
messageContentFormat?: "string";
|
|
696
699
|
};
|
|
697
700
|
/** The subset of OpenAICompatCatalogEntry that resolveOpenAICompatConfig()
|
|
698
701
|
* 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": "12.9.
|
|
3
|
+
"version": "12.9.2",
|
|
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": {
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"prepack": "svelte-kit sync && svelte-package && pnpm run build:react-hooks && pnpm run build:cli && pnpm run build:browser && publint",
|
|
42
42
|
"build:react-hooks": "pnpm exec tsc --jsx react-jsx --module nodenext --moduleResolution nodenext --target esnext --esModuleInterop --skipLibCheck --outDir dist --declaration false src/lib/client/reactHooks.tsx",
|
|
43
43
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && tsc --noEmit --strict",
|
|
44
|
+
"check:models": "tsx tools/check-model-liveness.ts",
|
|
44
45
|
"check:ci-scripts": "svelte-kit sync && tsc -p tsconfig.ci-scripts.json",
|
|
45
46
|
"check:test-parse": "node scripts/parse-check-tests.mjs",
|
|
46
47
|
"check:tools-tests": "svelte-kit sync && tsc -p tsconfig.tools-tests.json",
|