@juspay/neurolink 12.5.0 → 12.5.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 +3 -3
- package/dist/adapters/providerImageAdapter.js +43 -19
- package/dist/browser/neurolink.min.js +414 -414
- package/dist/cli/commands/setup.d.ts +12 -7
- package/dist/cli/commands/setup.js +17 -16
- package/dist/cli/proxy-clients/openCode.js +16 -3
- package/dist/constants/contextWindows.js +23 -95
- package/dist/constants/enums.d.ts +111 -216
- package/dist/constants/enums.js +124 -240
- package/dist/factories/providerDescriptors.d.ts +2 -4
- package/dist/factories/providerDescriptors.js +83 -127
- package/dist/models/manifestRegistry.js +53 -4
- package/dist/providers/catalog/cerebras.json +75 -0
- package/dist/providers/catalog/cloudflare.json +121 -0
- package/dist/providers/catalog/fireworks.json +124 -0
- package/dist/providers/catalog/groq.json +127 -0
- package/dist/providers/catalog/index.generated.d.ts +3 -0
- package/dist/providers/catalog/index.generated.js +33 -0
- package/dist/providers/catalog/loader.d.ts +6 -0
- package/dist/providers/catalog/loader.js +115 -0
- package/dist/providers/catalog/mistral.json +244 -0
- package/dist/providers/catalog/perplexity.json +103 -0
- package/dist/providers/catalog/provider-catalog.schema.json +351 -0
- package/dist/providers/catalog/sambanova.json +129 -0
- package/dist/providers/catalog/schema.d.ts +123 -0
- package/dist/providers/catalog/schema.js +310 -0
- package/dist/providers/catalog/together-ai.json +172 -0
- package/dist/providers/catalog/xai.json +108 -0
- package/dist/providers/openaiCompatCatalog.d.ts +13 -13
- package/dist/providers/openaiCompatCatalog.js +15 -326
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/providerCatalog.d.ts +149 -0
- package/dist/types/providerCatalog.generated.d.ts +2 -0
- package/dist/types/providerCatalog.generated.js +1 -0
- package/dist/types/providerCatalog.js +7 -0
- package/dist/types/providers.d.ts +14 -14
- package/dist/utils/modelChoices.d.ts +11 -3
- package/dist/utils/modelChoices.js +84 -190
- package/dist/utils/pricing.js +92 -127
- package/dist/utils/providerConfig.d.ts +1 -1
- package/dist/utils/providerConfig.js +24 -108
- package/package.json +2 -1
- package/dist/models/manifests/cerebras.d.ts +0 -9
- package/dist/models/manifests/cerebras.js +0 -19
- package/dist/models/manifests/sambanova.d.ts +0 -11
- package/dist/models/manifests/sambanova.js +0 -42
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zod validator for the single-JSON provider catalog authoring format.
|
|
3
|
+
* Mirrors src/lib/types/providerCatalog.ts field-for-field with
|
|
4
|
+
* z.strictObject (unknown keys are authoring mistakes) plus the
|
|
5
|
+
* cross-field refinements the plain types cannot express. See
|
|
6
|
+
* docs/superpowers/plans/2026-08-28-provider-json-catalog-spec.md.
|
|
7
|
+
*
|
|
8
|
+
* provider-catalog.schema.json is a hand-kept JSON Schema mirror for
|
|
9
|
+
* editor validation only — this file is the authoritative validator.
|
|
10
|
+
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
const IDENTIFIER_PATTERN = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
13
|
+
const KEBAB_ID_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
14
|
+
const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
15
|
+
const catalogPricingPerMTokSchema = z.strictObject({
|
|
16
|
+
input: z.number(),
|
|
17
|
+
output: z.number(),
|
|
18
|
+
cachedInput: z.number().optional(),
|
|
19
|
+
});
|
|
20
|
+
const catalogModelStatusSchema = z.enum(["production", "preview", "retired"]);
|
|
21
|
+
const catalogModelSpecSchema = z.strictObject({
|
|
22
|
+
contextWindow: z.number().optional(),
|
|
23
|
+
maxOutputTokens: z.number().optional(),
|
|
24
|
+
pricingPerMTok: catalogPricingPerMTokSchema.optional(),
|
|
25
|
+
vision: z.boolean(),
|
|
26
|
+
status: catalogModelStatusSchema,
|
|
27
|
+
description: z.string(),
|
|
28
|
+
enumMember: z
|
|
29
|
+
.string()
|
|
30
|
+
.regex(IDENTIFIER_PATTERN, "enumMember must be a valid identifier")
|
|
31
|
+
.optional(),
|
|
32
|
+
});
|
|
33
|
+
const catalogWireSchema = z
|
|
34
|
+
.strictObject({
|
|
35
|
+
baseURL: z.string().optional(),
|
|
36
|
+
baseURLTemplate: z.string().optional(),
|
|
37
|
+
extraCredentials: z.array(z.string()).optional(),
|
|
38
|
+
missingCredentialMessage: z.string().optional(),
|
|
39
|
+
envOverrides: z
|
|
40
|
+
.strictObject({
|
|
41
|
+
apiKey: z.string().optional(),
|
|
42
|
+
baseURL: z.string().optional(),
|
|
43
|
+
model: z.string().optional(),
|
|
44
|
+
})
|
|
45
|
+
.optional(),
|
|
46
|
+
})
|
|
47
|
+
.superRefine((wire, ctx) => {
|
|
48
|
+
const hasBaseURL = wire.baseURL !== undefined;
|
|
49
|
+
const hasTemplate = wire.baseURLTemplate !== undefined;
|
|
50
|
+
if (hasBaseURL === hasTemplate) {
|
|
51
|
+
ctx.addIssue({
|
|
52
|
+
code: "custom",
|
|
53
|
+
path: ["baseURL"],
|
|
54
|
+
message: "wire requires exactly one of baseURL or baseURLTemplate",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (wire.extraCredentials !== undefined) {
|
|
58
|
+
if (wire.extraCredentials.length !== 1) {
|
|
59
|
+
ctx.addIssue({
|
|
60
|
+
code: "custom",
|
|
61
|
+
path: ["extraCredentials"],
|
|
62
|
+
message: "wire.extraCredentials must have exactly one entry",
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else if (!IDENTIFIER_PATTERN.test(wire.extraCredentials[0])) {
|
|
66
|
+
// Embedded verbatim in generated credential typing — a non-identifier
|
|
67
|
+
// value would emit invalid TypeScript.
|
|
68
|
+
ctx.addIssue({
|
|
69
|
+
code: "custom",
|
|
70
|
+
path: ["extraCredentials", 0],
|
|
71
|
+
message: "wire.extraCredentials entry must be a valid identifier",
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (!hasTemplate) {
|
|
75
|
+
ctx.addIssue({
|
|
76
|
+
code: "custom",
|
|
77
|
+
path: ["extraCredentials"],
|
|
78
|
+
message: "wire.extraCredentials is only valid with baseURLTemplate",
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (wire.missingCredentialMessage !== undefined && !hasTemplate) {
|
|
83
|
+
ctx.addIssue({
|
|
84
|
+
code: "custom",
|
|
85
|
+
path: ["missingCredentialMessage"],
|
|
86
|
+
message: "wire.missingCredentialMessage is only valid with baseURLTemplate",
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (hasTemplate &&
|
|
90
|
+
wire.extraCredentials !== undefined &&
|
|
91
|
+
wire.extraCredentials.length === 1) {
|
|
92
|
+
const placeholder = `{${wire.extraCredentials[0]}}`;
|
|
93
|
+
if (!wire.baseURLTemplate?.includes(placeholder)) {
|
|
94
|
+
ctx.addIssue({
|
|
95
|
+
code: "custom",
|
|
96
|
+
path: ["baseURLTemplate"],
|
|
97
|
+
message: "wire.baseURLTemplate must contain the extraCredentials[0] placeholder",
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
const catalogErrorRuleClassSchema = z.enum([
|
|
103
|
+
"authentication",
|
|
104
|
+
"rate-limit",
|
|
105
|
+
"invalid-model",
|
|
106
|
+
"network",
|
|
107
|
+
"provider",
|
|
108
|
+
]);
|
|
109
|
+
const catalogErrorRuleJsonSchema = z
|
|
110
|
+
.strictObject({
|
|
111
|
+
status: z.number().optional(),
|
|
112
|
+
pattern: z.string().optional(),
|
|
113
|
+
class: catalogErrorRuleClassSchema,
|
|
114
|
+
message: z.string(),
|
|
115
|
+
})
|
|
116
|
+
.superRefine((rule, ctx) => {
|
|
117
|
+
if (rule.status === undefined && rule.pattern === undefined) {
|
|
118
|
+
ctx.addIssue({
|
|
119
|
+
code: "custom",
|
|
120
|
+
path: [],
|
|
121
|
+
message: "errorRules entry requires status or pattern",
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (rule.pattern !== undefined) {
|
|
125
|
+
try {
|
|
126
|
+
new RegExp(rule.pattern, "i");
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
ctx.addIssue({
|
|
130
|
+
code: "custom",
|
|
131
|
+
path: ["pattern"],
|
|
132
|
+
message: "errorRules pattern must compile as a regular expression",
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
const catalogQuirksSchema = z.strictObject({
|
|
138
|
+
timeoutErrorClass: z.literal("provider").optional(),
|
|
139
|
+
registryDefaultIgnoresModelEnvVar: z.boolean().optional(),
|
|
140
|
+
});
|
|
141
|
+
const catalogBillingPolicySchema = z.enum([
|
|
142
|
+
"free-tier",
|
|
143
|
+
"free-with-card",
|
|
144
|
+
"no-free-tier",
|
|
145
|
+
]);
|
|
146
|
+
const catalogSetupSchema = z.strictObject({
|
|
147
|
+
url: z.string(),
|
|
148
|
+
apiKeyFormat: z.string().nullable(),
|
|
149
|
+
billingPolicy: catalogBillingPolicySchema,
|
|
150
|
+
instructions: z.array(z.string()),
|
|
151
|
+
description: z.string().optional(),
|
|
152
|
+
});
|
|
153
|
+
const catalogProbeEvidenceSchema = z.strictObject({
|
|
154
|
+
date: z.string().regex(DATE_PATTERN, "date must match YYYY-MM-DD"),
|
|
155
|
+
status: z.number().optional(),
|
|
156
|
+
code: z.string().optional(),
|
|
157
|
+
method: z.string().optional(),
|
|
158
|
+
});
|
|
159
|
+
const catalogEvidenceSchema = z.strictObject({
|
|
160
|
+
rosterVerified: catalogProbeEvidenceSchema,
|
|
161
|
+
authProbe: catalogProbeEvidenceSchema.optional(),
|
|
162
|
+
billingProbe: catalogProbeEvidenceSchema.optional(),
|
|
163
|
+
liveMatrix: z
|
|
164
|
+
.strictObject({
|
|
165
|
+
date: z.string().regex(DATE_PATTERN, "date must match YYYY-MM-DD"),
|
|
166
|
+
result: z.string(),
|
|
167
|
+
})
|
|
168
|
+
.nullable(),
|
|
169
|
+
addedInPR: z.string(),
|
|
170
|
+
});
|
|
171
|
+
const catalogCapabilitiesSchema = z.strictObject({
|
|
172
|
+
text: z.boolean(),
|
|
173
|
+
streaming: z.boolean(),
|
|
174
|
+
tools: z.boolean(),
|
|
175
|
+
toolsWithStreaming: z.boolean(),
|
|
176
|
+
structuredOutput: z.boolean(),
|
|
177
|
+
structuredOutputWithTools: z.boolean(),
|
|
178
|
+
embeddings: z.boolean(),
|
|
179
|
+
thinking: z.boolean(),
|
|
180
|
+
});
|
|
181
|
+
const catalogModelsSchema = z
|
|
182
|
+
.strictObject({
|
|
183
|
+
default: z.string(),
|
|
184
|
+
fallbacks: z.array(z.string()),
|
|
185
|
+
fallbackModelName: z.string().optional(),
|
|
186
|
+
registryDefaultModel: z.string().optional(),
|
|
187
|
+
defaultContextWindow: z.number(),
|
|
188
|
+
defaultMaxOutputTokens: z.number(),
|
|
189
|
+
catalog: z.record(z.string(), catalogModelSpecSchema),
|
|
190
|
+
topModels: z.array(z.string()).min(1).optional(),
|
|
191
|
+
visionModel: z.string().optional(),
|
|
192
|
+
// Deliberately NOT constrained to catalog keys: testModel captures what
|
|
193
|
+
// the testing account can actually reach today, which may be a model
|
|
194
|
+
// the transcribed catalog predates.
|
|
195
|
+
testModel: z.string().min(1).optional(),
|
|
196
|
+
})
|
|
197
|
+
.superRefine((models, ctx) => {
|
|
198
|
+
const catalogKeys = new Set(Object.keys(models.catalog));
|
|
199
|
+
if (models.fallbacks.length === 0) {
|
|
200
|
+
// The loader's fallbackModelName default is fallbacks[1] ?? fallbacks[0],
|
|
201
|
+
// which depends on fallbacks[0] existing.
|
|
202
|
+
ctx.addIssue({
|
|
203
|
+
code: "custom",
|
|
204
|
+
path: ["fallbacks"],
|
|
205
|
+
message: "models.fallbacks must have at least one entry",
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (!catalogKeys.has(models.default)) {
|
|
209
|
+
ctx.addIssue({
|
|
210
|
+
code: "custom",
|
|
211
|
+
path: ["default"],
|
|
212
|
+
message: "models.default must be a key of models.catalog",
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
models.fallbacks.forEach((fallback, index) => {
|
|
216
|
+
if (!catalogKeys.has(fallback)) {
|
|
217
|
+
ctx.addIssue({
|
|
218
|
+
code: "custom",
|
|
219
|
+
path: ["fallbacks", index],
|
|
220
|
+
message: "models.fallbacks entry must be a key of models.catalog",
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
if (models.fallbackModelName !== undefined &&
|
|
225
|
+
!catalogKeys.has(models.fallbackModelName)) {
|
|
226
|
+
ctx.addIssue({
|
|
227
|
+
code: "custom",
|
|
228
|
+
path: ["fallbackModelName"],
|
|
229
|
+
message: "models.fallbackModelName must be a key of models.catalog",
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
if (models.registryDefaultModel !== undefined &&
|
|
233
|
+
!catalogKeys.has(models.registryDefaultModel)) {
|
|
234
|
+
ctx.addIssue({
|
|
235
|
+
code: "custom",
|
|
236
|
+
path: ["registryDefaultModel"],
|
|
237
|
+
message: "models.registryDefaultModel must be a key of models.catalog",
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
if (models.topModels !== undefined) {
|
|
241
|
+
models.topModels.forEach((modelId, index) => {
|
|
242
|
+
if (!catalogKeys.has(modelId)) {
|
|
243
|
+
ctx.addIssue({
|
|
244
|
+
code: "custom",
|
|
245
|
+
path: ["topModels", index],
|
|
246
|
+
message: "models.topModels entry must be a key of models.catalog",
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
const seen = new Set();
|
|
251
|
+
models.topModels.forEach((modelId, index) => {
|
|
252
|
+
if (seen.has(modelId)) {
|
|
253
|
+
ctx.addIssue({
|
|
254
|
+
code: "custom",
|
|
255
|
+
path: ["topModels", index],
|
|
256
|
+
message: "models.topModels must not contain duplicate entries",
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
seen.add(modelId);
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
if (models.visionModel !== undefined) {
|
|
263
|
+
const spec = models.catalog[models.visionModel];
|
|
264
|
+
if (!spec) {
|
|
265
|
+
ctx.addIssue({
|
|
266
|
+
code: "custom",
|
|
267
|
+
path: ["visionModel"],
|
|
268
|
+
message: "models.visionModel must be a key of models.catalog",
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
else if (!spec.vision) {
|
|
272
|
+
ctx.addIssue({
|
|
273
|
+
code: "custom",
|
|
274
|
+
path: ["visionModel"],
|
|
275
|
+
message: "models.visionModel entry must have vision: true",
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
export const providerCatalogJsonSchema = z.strictObject({
|
|
281
|
+
$schema: z.string().optional(),
|
|
282
|
+
id: z.string().regex(KEBAB_ID_PATTERN, "id must be kebab-case"),
|
|
283
|
+
displayName: z.string(),
|
|
284
|
+
enumTypeName: z
|
|
285
|
+
.string()
|
|
286
|
+
.regex(IDENTIFIER_PATTERN, "enumTypeName must be a valid identifier")
|
|
287
|
+
.optional(),
|
|
288
|
+
credentialsKey: z
|
|
289
|
+
.string()
|
|
290
|
+
.regex(IDENTIFIER_PATTERN, "credentialsKey must be a valid identifier")
|
|
291
|
+
.optional(),
|
|
292
|
+
aliases: z.array(z.string()),
|
|
293
|
+
tier: z.literal(2),
|
|
294
|
+
wire: catalogWireSchema,
|
|
295
|
+
models: catalogModelsSchema,
|
|
296
|
+
capabilities: catalogCapabilitiesSchema,
|
|
297
|
+
errorRules: z.array(catalogErrorRuleJsonSchema),
|
|
298
|
+
quirks: catalogQuirksSchema.optional(),
|
|
299
|
+
setup: catalogSetupSchema,
|
|
300
|
+
evidence: catalogEvidenceSchema,
|
|
301
|
+
});
|
|
302
|
+
export function parseProviderCatalogJson(raw, sourcePath) {
|
|
303
|
+
const result = providerCatalogJsonSchema.safeParse(raw);
|
|
304
|
+
if (!result.success) {
|
|
305
|
+
throw new Error(`Invalid provider catalog file ${sourcePath}: ${result.error.issues
|
|
306
|
+
.map((i) => `${i.path.join(".")}: ${i.message}`)
|
|
307
|
+
.join("; ")}`);
|
|
308
|
+
}
|
|
309
|
+
return result.data;
|
|
310
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./provider-catalog.schema.json",
|
|
3
|
+
"id": "together-ai",
|
|
4
|
+
"displayName": "Together AI",
|
|
5
|
+
"enumTypeName": "TogetherAIModels",
|
|
6
|
+
"credentialsKey": "together",
|
|
7
|
+
"aliases": ["together"],
|
|
8
|
+
"tier": 2,
|
|
9
|
+
"wire": {
|
|
10
|
+
"baseURL": "https://api.together.xyz/v1",
|
|
11
|
+
"envOverrides": {
|
|
12
|
+
"apiKey": "TOGETHER_API_KEY",
|
|
13
|
+
"baseURL": "TOGETHER_BASE_URL",
|
|
14
|
+
"model": "TOGETHER_MODEL"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"models": {
|
|
18
|
+
"default": "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
19
|
+
"fallbackModelName": "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
|
|
20
|
+
"fallbacks": [
|
|
21
|
+
"meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
22
|
+
"meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo",
|
|
23
|
+
"meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
|
|
24
|
+
"meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
|
|
25
|
+
"mistralai/Mixtral-8x22B-Instruct-v0.1",
|
|
26
|
+
"Qwen/Qwen2.5-72B-Instruct-Turbo",
|
|
27
|
+
"deepseek-ai/DeepSeek-R1",
|
|
28
|
+
"deepseek-ai/DeepSeek-V3"
|
|
29
|
+
],
|
|
30
|
+
"defaultContextWindow": 128000,
|
|
31
|
+
"defaultMaxOutputTokens": 4096,
|
|
32
|
+
"catalog": {
|
|
33
|
+
"meta-llama/Llama-3.3-70B-Instruct-Turbo": {
|
|
34
|
+
"enumMember": "LLAMA_3_3_70B_INSTRUCT_TURBO",
|
|
35
|
+
"contextWindow": 128000,
|
|
36
|
+
"pricingPerMTok": { "input": 0.88, "output": 0.88 },
|
|
37
|
+
"vision": false,
|
|
38
|
+
"status": "production",
|
|
39
|
+
"description": "Recommended - Llama 3.3 70B Turbo"
|
|
40
|
+
},
|
|
41
|
+
"meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo": {
|
|
42
|
+
"enumMember": "LLAMA_3_1_405B_INSTRUCT_TURBO",
|
|
43
|
+
"contextWindow": 128000,
|
|
44
|
+
"pricingPerMTok": { "input": 3.5, "output": 3.5 },
|
|
45
|
+
"vision": false,
|
|
46
|
+
"status": "production",
|
|
47
|
+
"description": "Flagship 405B"
|
|
48
|
+
},
|
|
49
|
+
"meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo": {
|
|
50
|
+
"enumMember": "LLAMA_3_1_70B_INSTRUCT_TURBO",
|
|
51
|
+
"contextWindow": 128000,
|
|
52
|
+
"pricingPerMTok": { "input": 0.88, "output": 0.88 },
|
|
53
|
+
"vision": false,
|
|
54
|
+
"status": "production",
|
|
55
|
+
"description": "Llama 3.1 70B Instruct Turbo"
|
|
56
|
+
},
|
|
57
|
+
"meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo": {
|
|
58
|
+
"enumMember": "LLAMA_3_1_8B_INSTRUCT_TURBO",
|
|
59
|
+
"contextWindow": 128000,
|
|
60
|
+
"pricingPerMTok": { "input": 0.18, "output": 0.18 },
|
|
61
|
+
"vision": false,
|
|
62
|
+
"status": "production",
|
|
63
|
+
"description": "Llama 3.1 8B Instruct Turbo — fastest"
|
|
64
|
+
},
|
|
65
|
+
"mistralai/Mixtral-8x22B-Instruct-v0.1": {
|
|
66
|
+
"enumMember": "MIXTRAL_8X22B_INSTRUCT",
|
|
67
|
+
"contextWindow": 65536,
|
|
68
|
+
"pricingPerMTok": { "input": 1.2, "output": 1.2 },
|
|
69
|
+
"vision": false,
|
|
70
|
+
"status": "production",
|
|
71
|
+
"description": "Mistral 8x22B MoE"
|
|
72
|
+
},
|
|
73
|
+
"mistralai/Mixtral-8x7B-Instruct-v0.1": {
|
|
74
|
+
"enumMember": "MIXTRAL_8X7B_INSTRUCT",
|
|
75
|
+
"contextWindow": 32768,
|
|
76
|
+
"pricingPerMTok": { "input": 0.6, "output": 0.6 },
|
|
77
|
+
"vision": false,
|
|
78
|
+
"status": "production",
|
|
79
|
+
"description": "Mixtral 8x7B Instruct"
|
|
80
|
+
},
|
|
81
|
+
"Qwen/Qwen2.5-72B-Instruct-Turbo": {
|
|
82
|
+
"enumMember": "QWEN_2_5_72B_INSTRUCT_TURBO",
|
|
83
|
+
"contextWindow": 32768,
|
|
84
|
+
"pricingPerMTok": { "input": 1.2, "output": 1.2 },
|
|
85
|
+
"vision": false,
|
|
86
|
+
"status": "production",
|
|
87
|
+
"description": "Qwen 2.5 72B Turbo"
|
|
88
|
+
},
|
|
89
|
+
"Qwen/Qwen2.5-Coder-32B-Instruct": {
|
|
90
|
+
"enumMember": "QWEN_2_5_CODER_32B",
|
|
91
|
+
"contextWindow": 32768,
|
|
92
|
+
"vision": false,
|
|
93
|
+
"status": "production",
|
|
94
|
+
"description": "Qwen 2.5 Coder 32B Instruct"
|
|
95
|
+
},
|
|
96
|
+
"deepseek-ai/DeepSeek-R1": {
|
|
97
|
+
"enumMember": "DEEPSEEK_R1",
|
|
98
|
+
"contextWindow": 64000,
|
|
99
|
+
"pricingPerMTok": { "input": 7.0, "output": 7.0 },
|
|
100
|
+
"vision": false,
|
|
101
|
+
"status": "production",
|
|
102
|
+
"description": "DeepSeek R1 reasoning"
|
|
103
|
+
},
|
|
104
|
+
"deepseek-ai/DeepSeek-V3": {
|
|
105
|
+
"enumMember": "DEEPSEEK_V3",
|
|
106
|
+
"contextWindow": 64000,
|
|
107
|
+
"pricingPerMTok": { "input": 1.25, "output": 1.25 },
|
|
108
|
+
"vision": false,
|
|
109
|
+
"status": "production",
|
|
110
|
+
"description": "DeepSeek V3"
|
|
111
|
+
},
|
|
112
|
+
"google/gemma-2-27b-it": {
|
|
113
|
+
"enumMember": "GEMMA_2_27B_IT",
|
|
114
|
+
"contextWindow": 8192,
|
|
115
|
+
"vision": false,
|
|
116
|
+
"status": "production",
|
|
117
|
+
"description": "Google Gemma 2 27B IT"
|
|
118
|
+
},
|
|
119
|
+
"microsoft/WizardLM-2-8x22B": {
|
|
120
|
+
"enumMember": "WIZARDLM_2_8X22B",
|
|
121
|
+
"contextWindow": 65536,
|
|
122
|
+
"vision": false,
|
|
123
|
+
"status": "production",
|
|
124
|
+
"description": "WizardLM 2 8x22B"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"topModels": [
|
|
128
|
+
"meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
129
|
+
"meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo",
|
|
130
|
+
"Qwen/Qwen2.5-72B-Instruct-Turbo",
|
|
131
|
+
"deepseek-ai/DeepSeek-R1",
|
|
132
|
+
"mistralai/Mixtral-8x22B-Instruct-v0.1"
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
"capabilities": {
|
|
136
|
+
"text": true,
|
|
137
|
+
"streaming": true,
|
|
138
|
+
"tools": true,
|
|
139
|
+
"toolsWithStreaming": true,
|
|
140
|
+
"structuredOutput": true,
|
|
141
|
+
"structuredOutputWithTools": true,
|
|
142
|
+
"embeddings": false,
|
|
143
|
+
"thinking": false
|
|
144
|
+
},
|
|
145
|
+
"errorRules": [
|
|
146
|
+
{
|
|
147
|
+
"status": 401,
|
|
148
|
+
"pattern": "Invalid API key|Authentication",
|
|
149
|
+
"class": "authentication",
|
|
150
|
+
"message": "Invalid Together AI API key. Get one at https://api.together.xyz/settings/api-keys"
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
"setup": {
|
|
154
|
+
"url": "https://api.together.xyz/settings/api-keys",
|
|
155
|
+
"apiKeyFormat": null,
|
|
156
|
+
"billingPolicy": "free-with-card",
|
|
157
|
+
"instructions": [
|
|
158
|
+
"1. Visit: https://api.together.xyz/settings/api-keys",
|
|
159
|
+
"2. Sign in to your Together AI account",
|
|
160
|
+
"3. Create a new API key",
|
|
161
|
+
"4. Set {apiKeyEnvVar} in your .env file"
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
"evidence": {
|
|
165
|
+
"rosterVerified": {
|
|
166
|
+
"date": "2026-08-28",
|
|
167
|
+
"method": "transcribed from pre-migration TS catalog"
|
|
168
|
+
},
|
|
169
|
+
"liveMatrix": null,
|
|
170
|
+
"addedInPR": "https://github.com/juspay/neurolink/pull/1587"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./provider-catalog.schema.json",
|
|
3
|
+
"id": "xai",
|
|
4
|
+
"displayName": "xAI",
|
|
5
|
+
"aliases": ["grok"],
|
|
6
|
+
"tier": 2,
|
|
7
|
+
"wire": {
|
|
8
|
+
"baseURL": "https://api.x.ai/v1"
|
|
9
|
+
},
|
|
10
|
+
"models": {
|
|
11
|
+
"default": "grok-3",
|
|
12
|
+
"fallbacks": [
|
|
13
|
+
"grok-3",
|
|
14
|
+
"grok-3-mini",
|
|
15
|
+
"grok-2-latest",
|
|
16
|
+
"grok-2-vision-latest",
|
|
17
|
+
"grok-beta"
|
|
18
|
+
],
|
|
19
|
+
"defaultContextWindow": 131072,
|
|
20
|
+
"defaultMaxOutputTokens": 4096,
|
|
21
|
+
"catalog": {
|
|
22
|
+
"grok-3": {
|
|
23
|
+
"contextWindow": 131072,
|
|
24
|
+
"pricingPerMTok": { "input": 3.0, "output": 15.0 },
|
|
25
|
+
"vision": false,
|
|
26
|
+
"status": "production",
|
|
27
|
+
"description": "Recommended - Latest flagship Grok"
|
|
28
|
+
},
|
|
29
|
+
"grok-3-mini": {
|
|
30
|
+
"contextWindow": 131072,
|
|
31
|
+
"pricingPerMTok": { "input": 0.3, "output": 0.5 },
|
|
32
|
+
"vision": false,
|
|
33
|
+
"status": "production",
|
|
34
|
+
"description": "Faster + cheaper Grok 3"
|
|
35
|
+
},
|
|
36
|
+
"grok-2-latest": {
|
|
37
|
+
"contextWindow": 131072,
|
|
38
|
+
"pricingPerMTok": { "input": 2.0, "output": 10.0 },
|
|
39
|
+
"vision": false,
|
|
40
|
+
"status": "production",
|
|
41
|
+
"description": "Previous flagship"
|
|
42
|
+
},
|
|
43
|
+
"grok-2-vision-latest": {
|
|
44
|
+
"contextWindow": 32768,
|
|
45
|
+
"pricingPerMTok": { "input": 2.0, "output": 10.0 },
|
|
46
|
+
"vision": true,
|
|
47
|
+
"status": "production",
|
|
48
|
+
"description": "Multimodal (text + images)"
|
|
49
|
+
},
|
|
50
|
+
"grok-beta": {
|
|
51
|
+
"contextWindow": 131072,
|
|
52
|
+
"pricingPerMTok": { "input": 5.0, "output": 15.0 },
|
|
53
|
+
"vision": false,
|
|
54
|
+
"status": "preview",
|
|
55
|
+
"description": "Pre-release / experimental"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"topModels": [
|
|
59
|
+
"grok-3",
|
|
60
|
+
"grok-3-mini",
|
|
61
|
+
"grok-2-vision-latest",
|
|
62
|
+
"grok-2-latest",
|
|
63
|
+
"grok-beta"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
"capabilities": {
|
|
67
|
+
"text": true,
|
|
68
|
+
"streaming": true,
|
|
69
|
+
"tools": true,
|
|
70
|
+
"toolsWithStreaming": true,
|
|
71
|
+
"structuredOutput": true,
|
|
72
|
+
"structuredOutputWithTools": true,
|
|
73
|
+
"embeddings": false,
|
|
74
|
+
"thinking": false
|
|
75
|
+
},
|
|
76
|
+
"errorRules": [
|
|
77
|
+
{
|
|
78
|
+
"status": 401,
|
|
79
|
+
"pattern": "Invalid API key|Authentication|invalid_api_key",
|
|
80
|
+
"class": "authentication",
|
|
81
|
+
"message": "Invalid xAI API key. Please check your {apiKeyEnvVar} environment variable. Get one at https://console.x.ai/"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"pattern": "insufficient_quota|quota exceeded",
|
|
85
|
+
"class": "provider",
|
|
86
|
+
"message": "xAI account has insufficient quota. Top up at https://console.x.ai/"
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"setup": {
|
|
90
|
+
"url": "https://console.x.ai/",
|
|
91
|
+
"apiKeyFormat": null,
|
|
92
|
+
"billingPolicy": "no-free-tier",
|
|
93
|
+
"instructions": [
|
|
94
|
+
"1. Visit: https://console.x.ai/",
|
|
95
|
+
"2. Sign in with your xAI account",
|
|
96
|
+
"3. Create an API key",
|
|
97
|
+
"4. Set {apiKeyEnvVar} in your .env file"
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
"evidence": {
|
|
101
|
+
"rosterVerified": {
|
|
102
|
+
"date": "2026-08-28",
|
|
103
|
+
"method": "transcribed from pre-migration TS catalog"
|
|
104
|
+
},
|
|
105
|
+
"liveMatrix": null,
|
|
106
|
+
"addedInPR": "https://github.com/juspay/neurolink/pull/1587"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -6,19 +6,19 @@ import type { OpenAICompatCatalogEntry } from "../types/index.js";
|
|
|
6
6
|
* for the class that reads these entries, and providerRegistry.ts for the
|
|
7
7
|
* registration loop that consumes this array.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* (
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* See plan-05/progress.md Ruling R4 for the full rationale.
|
|
9
|
+
* The entries themselves are derived from the JSON catalog
|
|
10
|
+
* (src/lib/providers/catalog/<id>.json) via buildCatalogEntries() — that
|
|
11
|
+
* JSON is now the single source of truth for these 9 providers' identity,
|
|
12
|
+
* models, error rules and wire config. See
|
|
13
|
+
* src/lib/providers/catalog/loader.ts for the derivation logic and
|
|
14
|
+
* docs/superpowers/plans/2026-08-28-provider-json-catalog-spec.md for the
|
|
15
|
+
* authoring format.
|
|
17
16
|
*
|
|
18
|
-
* To add a new zero-quirk OpenAI-compatible provider: add one
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
17
|
+
* To add a new zero-quirk OpenAI-compatible provider: add one JSON file
|
|
18
|
+
* under src/lib/providers/catalog/ (see provider-catalog.schema.json) and
|
|
19
|
+
* run `pnpm run codegen:catalog`. Do NOT add a provider here if it needs
|
|
20
|
+
* any hook override beyond the 3 mandatory ones
|
|
21
|
+
* (getProviderName/getDefaultModel/formatProviderError) — write a
|
|
22
|
+
* dedicated subclass instead (see deepseek.ts, azureOpenai.ts).
|
|
23
23
|
*/
|
|
24
24
|
export declare const OPENAI_COMPAT_CATALOG: readonly OpenAICompatCatalogEntry[];
|