@juspay/neurolink 12.55.2 → 12.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -3
- package/dist/browser/neurolink.min.js +405 -405
- package/dist/cli/commands/setup.d.ts +3 -3
- package/dist/cli/commands/setup.js +4 -5
- package/dist/constants/enums.d.ts +4 -9
- package/dist/constants/enums.js +5 -10
- package/dist/factories/providerDescriptors.js +7 -48
- package/dist/factories/providerRegistry.js +1 -9
- package/dist/models/manifestRegistry.js +0 -2
- package/dist/providers/catalog/index.generated.d.ts +1 -1
- package/dist/providers/catalog/index.generated.js +6 -2
- package/dist/providers/catalog/provider-catalog.schema.json +54 -1
- package/dist/providers/catalog/schema.js +154 -8
- package/dist/providers/catalog/xor.json +86 -0
- package/dist/providers/configuredDecision.d.ts +2 -2
- package/dist/providers/configuredDecision.js +22 -5
- package/dist/providers/decide/baseUrl.d.ts +3 -1
- package/dist/providers/decide/baseUrl.js +43 -0
- package/dist/providers/decide/errors.js +42 -16
- package/dist/types/providerCatalog.d.ts +27 -1
- package/dist/types/providerCatalog.generated.d.ts +2 -2
- package/dist/types/providers.d.ts +4 -10
- package/dist/utils/modelChoices.js +1 -9
- package/dist/utils/providerConfig.d.ts +0 -5
- package/dist/utils/providerConfig.js +0 -17
- package/docs-site/static/search-index.json +7 -7
- package/package.json +6 -3
- package/dist/models/manifests/xor.d.ts +0 -12
- package/dist/models/manifests/xor.js +0 -30
- package/dist/providers/xor.d.ts +0 -48
- package/dist/providers/xor.js +0 -192
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./provider-catalog.schema.json",
|
|
3
|
+
"id": "xor",
|
|
4
|
+
"displayName": "XOR",
|
|
5
|
+
"aliases": [],
|
|
6
|
+
"inferenceKinds": ["decide"],
|
|
7
|
+
"wire": {},
|
|
8
|
+
"models": {
|
|
9
|
+
"default": "xor-1.1",
|
|
10
|
+
"topModels": ["xor-1.1"],
|
|
11
|
+
"catalog": {
|
|
12
|
+
"xor-1.1": {
|
|
13
|
+
"contextWindow": 250000,
|
|
14
|
+
"maxOutputTokens": 256,
|
|
15
|
+
"vision": false,
|
|
16
|
+
"status": "production",
|
|
17
|
+
"description": "Recommended - XOR 1.1, decision model that also reads images and video"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"timeouts": { "decideMs": 5000 },
|
|
22
|
+
"decisionLimits": {
|
|
23
|
+
"maxStateTokens": 200000,
|
|
24
|
+
"nonAsciiTokensPerChar": 1,
|
|
25
|
+
"media": { "maxImages": 8, "video": true, "maxRequestBytes": 8388608 }
|
|
26
|
+
},
|
|
27
|
+
"decide": {
|
|
28
|
+
"dialect": "system-one",
|
|
29
|
+
"order": 3,
|
|
30
|
+
"baseURLRequired": true,
|
|
31
|
+
"baseURLNormalize": ["strip-trailing-slash", "strip-v1-suffix"],
|
|
32
|
+
"baseURLShape": "origin",
|
|
33
|
+
"endpoint": "{baseURL}/v1/systemone",
|
|
34
|
+
"model": { "placement": "body" },
|
|
35
|
+
"media": { "imagesKey": "images", "videoKey": "video" },
|
|
36
|
+
"requestIdHeaders": [
|
|
37
|
+
"x-request-id",
|
|
38
|
+
"x-typesafe-request-id",
|
|
39
|
+
"x-litellm-call-id"
|
|
40
|
+
],
|
|
41
|
+
"errors": {
|
|
42
|
+
"rules": [
|
|
43
|
+
{ "status": 401, "kind": "authentication" },
|
|
44
|
+
{ "status": 413, "kind": "max_tokens_exceeded" },
|
|
45
|
+
{ "status": 429, "kind": "rate_limit" },
|
|
46
|
+
{ "status": 503, "kind": "overloaded" },
|
|
47
|
+
{
|
|
48
|
+
"statusMin": 500,
|
|
49
|
+
"messagePattern": "(context|prefill|prompt).{0,40}(length|limit|too long|exceed)|(too long|exceeds?).{0,40}(context|tokens)",
|
|
50
|
+
"kind": "max_tokens_exceeded"
|
|
51
|
+
},
|
|
52
|
+
{ "statusMin": 500, "kind": "server" }
|
|
53
|
+
],
|
|
54
|
+
"default": "invalid_request",
|
|
55
|
+
"bodyShapes": [
|
|
56
|
+
{ "path": "error.message" },
|
|
57
|
+
{ "path": "error" },
|
|
58
|
+
{
|
|
59
|
+
"path": "detail",
|
|
60
|
+
"isArray": true,
|
|
61
|
+
"formatter": "fastapi-validation"
|
|
62
|
+
},
|
|
63
|
+
{ "path": "detail" }
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"setup": {
|
|
68
|
+
"url": "https://huggingface.co/juspay/xor",
|
|
69
|
+
"apiKeyFormat": null,
|
|
70
|
+
"billingPolicy": "free-tier",
|
|
71
|
+
"description": "API key for your XOR endpoint",
|
|
72
|
+
"instructions": [
|
|
73
|
+
"1. Reach an XOR deployment, or use a LiteLLM proxy with a pass-through route to one",
|
|
74
|
+
"2. Set XOR_BASE_URL to its origin (NeuroLink calls <XOR_BASE_URL>/v1/systemone)",
|
|
75
|
+
"3. Set {apiKeyEnvVar} to the key it accepts (on LiteLLM, a virtual key whose team allows xor-1.1)"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
"evidence": {
|
|
79
|
+
"rosterVerified": {
|
|
80
|
+
"date": "2026-09-29",
|
|
81
|
+
"method": "The single model id xor-1.1 is the roster the hand-written XOR descriptor shipped; 2026-09-29 is the date it was added, not a date it was checked. The roster was never verified against a live XOR endpoint, and no live probe was run in this change"
|
|
82
|
+
},
|
|
83
|
+
"liveMatrix": null,
|
|
84
|
+
"addedInPR": "https://github.com/juspay/neurolink/pull/1984"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DecideCatalogJson, DecisionDialect, DecisionError, DecisionState, UnknownRecord } from "../types/index.js";
|
|
1
|
+
import type { DecideCatalogJson, DecisionDialect, DecisionError, DecisionPreparedMedia, DecisionState, UnknownRecord } from "../types/index.js";
|
|
2
2
|
import { SystemOneDecisionProvider } from "./systemOneDecision.js";
|
|
3
3
|
/** A `decide` provider described entirely by its catalog entry. */
|
|
4
4
|
export declare class ConfiguredDecisionProvider extends SystemOneDecisionProvider {
|
|
@@ -15,7 +15,7 @@ export declare class ConfiguredDecisionProvider extends SystemOneDecisionProvide
|
|
|
15
15
|
protected missingConfigMessage(): string | undefined;
|
|
16
16
|
protected decisionEndpoint(): string;
|
|
17
17
|
protected decisionHeaders(): Record<string, string>;
|
|
18
|
-
protected buildDecisionBody(state: DecisionState, questions: Record<string, Record<string, unknown>>, model: string): Record<string, unknown>;
|
|
18
|
+
protected buildDecisionBody(state: DecisionState, questions: Record<string, Record<string, unknown>>, model: string, media?: DecisionPreparedMedia): Record<string, unknown>;
|
|
19
19
|
protected parseDecisionError(status: number, payload: unknown, requestId: string | undefined): DecisionError;
|
|
20
20
|
protected readRequestId(headers: Headers): string | undefined;
|
|
21
21
|
protected resolveResponseModel(payload: Record<string, unknown>, requestedModel: string): string;
|
|
@@ -2,7 +2,7 @@ import { logger } from "../utils/logger.js";
|
|
|
2
2
|
import { redactUrlForError } from "../utils/logSanitize.js";
|
|
3
3
|
import { getProviderModel } from "../utils/providerConfig.js";
|
|
4
4
|
import { catalogCredentialsKey, catalogEnvVar } from "./catalog/loader.js";
|
|
5
|
-
import { normalizeBaseURL } from "./decide/baseUrl.js";
|
|
5
|
+
import { baseURLShapeProblem, normalizeBaseURL } from "./decide/baseUrl.js";
|
|
6
6
|
import { getDecisionDialect } from "./decide/dialects/index.js";
|
|
7
7
|
import { classifyDecisionError } from "./decide/errors.js";
|
|
8
8
|
import { isRecord } from "./decide/guards.js";
|
|
@@ -54,8 +54,14 @@ export class ConfiguredDecisionProvider extends SystemOneDecisionProvider {
|
|
|
54
54
|
return `${this.entry.displayName} requires an API key. Set ${catalogEnvVar(this.entry, "apiKey")} or pass credentials.${catalogCredentialsKey(this.entry)}.apiKey.`;
|
|
55
55
|
}
|
|
56
56
|
missingConfigMessage() {
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
const { baseURLRequired, baseURLShape } = this.entry.decide;
|
|
58
|
+
if (!this.baseURL) {
|
|
59
|
+
return baseURLRequired
|
|
60
|
+
? `${this.entry.displayName} requires a base URL. Set ${catalogEnvVar(this.entry, "baseURL")} or pass credentials.${catalogCredentialsKey(this.entry)}.baseURL.`
|
|
61
|
+
: undefined;
|
|
62
|
+
}
|
|
63
|
+
return baseURLShape
|
|
64
|
+
? baseURLShapeProblem(baseURLShape, this.baseURL, this.entry.displayName, `Set ${catalogEnvVar(this.entry, "baseURL")} or pass credentials.${catalogCredentialsKey(this.entry)}.baseURL to the origin, and give the key through ${catalogEnvVar(this.entry, "apiKey")} or credentials.${catalogCredentialsKey(this.entry)}.apiKey.`)
|
|
59
65
|
: undefined;
|
|
60
66
|
}
|
|
61
67
|
decisionEndpoint() {
|
|
@@ -67,11 +73,22 @@ export class ConfiguredDecisionProvider extends SystemOneDecisionProvider {
|
|
|
67
73
|
"Content-Type": "application/json",
|
|
68
74
|
};
|
|
69
75
|
}
|
|
70
|
-
buildDecisionBody(state, questions, model) {
|
|
76
|
+
buildDecisionBody(state, questions, model, media) {
|
|
71
77
|
const { placement, alias } = this.entry.decide.model;
|
|
72
|
-
|
|
78
|
+
const body = placement === "body-unless-alias" && model === alias
|
|
73
79
|
? { state, questions }
|
|
74
80
|
: { model, state, questions };
|
|
81
|
+
const keys = this.entry.decide.media;
|
|
82
|
+
if (!keys || !media) {
|
|
83
|
+
return body;
|
|
84
|
+
}
|
|
85
|
+
// A key is written only for media the request carries: a server may refuse
|
|
86
|
+
// an empty `images`.
|
|
87
|
+
return {
|
|
88
|
+
...body,
|
|
89
|
+
...(media.images.length > 0 ? { [keys.imagesKey]: media.images } : {}),
|
|
90
|
+
...(media.video && keys.videoKey ? { [keys.videoKey]: media.video } : {}),
|
|
91
|
+
};
|
|
75
92
|
}
|
|
76
93
|
parseDecisionError(status, payload, requestId) {
|
|
77
94
|
return classifyDecisionError(this.entry.decide.errors, {
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
import type { DecideBaseURLTransform } from "../../types/index.js";
|
|
1
|
+
import type { DecideBaseURLShape, DecideBaseURLTransform } from "../../types/index.js";
|
|
2
2
|
export declare function normalizeBaseURL(raw: string, transforms: readonly DecideBaseURLTransform[]): string;
|
|
3
|
+
/** Why a normalised base URL fails the shape, or undefined when it passes. */
|
|
4
|
+
export declare function baseURLShapeProblem(shape: DecideBaseURLShape, baseURL: string, displayName: string, fix: string): string | undefined;
|
|
@@ -8,7 +8,50 @@ const TRANSFORMS = {
|
|
|
8
8
|
}
|
|
9
9
|
return value.slice(0, end);
|
|
10
10
|
},
|
|
11
|
+
// A fixed-width tail check, not a pattern: nothing here can backtrack.
|
|
12
|
+
"strip-v1-suffix": (value) => {
|
|
13
|
+
const start = value.length - 3;
|
|
14
|
+
return start >= 0 &&
|
|
15
|
+
value[start] === "/" &&
|
|
16
|
+
(value[start + 1] === "v" || value[start + 1] === "V") &&
|
|
17
|
+
value[start + 2] === "1"
|
|
18
|
+
? value.slice(0, start)
|
|
19
|
+
: value;
|
|
20
|
+
},
|
|
11
21
|
};
|
|
12
22
|
export function normalizeBaseURL(raw, transforms) {
|
|
13
23
|
return transforms.reduce((value, name) => TRANSFORMS[name](value), raw);
|
|
14
24
|
}
|
|
25
|
+
const SHAPE_CHECKS = {
|
|
26
|
+
// None of these messages repeats the base URL: it can hold a credential,
|
|
27
|
+
// `fetch` rejects userinfo and echoes it, and a route appended after a query
|
|
28
|
+
// string or fragment ends up inside it.
|
|
29
|
+
origin: (baseURL, displayName, fix) => {
|
|
30
|
+
try {
|
|
31
|
+
const url = new URL(baseURL);
|
|
32
|
+
// `new URL()` accepts any scheme, so a host:port with no scheme parses as
|
|
33
|
+
// one (`xor.internal:8080` has the scheme `xor.internal:`) and would reach
|
|
34
|
+
// `fetch` as a network error instead of this message.
|
|
35
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
36
|
+
return `The ${displayName} base URL must start with https:// or http://. ${fix}`;
|
|
37
|
+
}
|
|
38
|
+
// The raw text is checked as well: `search` and `hash` are empty for a
|
|
39
|
+
// lone "?" or "#", which still swallows the route appended after it.
|
|
40
|
+
return url.username ||
|
|
41
|
+
url.password ||
|
|
42
|
+
url.search ||
|
|
43
|
+
url.hash ||
|
|
44
|
+
baseURL.includes("?") ||
|
|
45
|
+
baseURL.includes("#")
|
|
46
|
+
? `The ${displayName} base URL must not carry credentials, a query string or a fragment. ${fix}`
|
|
47
|
+
: undefined;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return `The ${displayName} base URL is not a valid absolute URL. ${fix}`;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
/** Why a normalised base URL fails the shape, or undefined when it passes. */
|
|
55
|
+
export function baseURLShapeProblem(shape, baseURL, displayName, fix) {
|
|
56
|
+
return SHAPE_CHECKS[shape](baseURL, displayName, fix);
|
|
57
|
+
}
|
|
@@ -7,14 +7,29 @@ const RETRYABLE_BY_DEFAULT = new Set([
|
|
|
7
7
|
"server",
|
|
8
8
|
]);
|
|
9
9
|
const isRetryableByDefault = (kind) => RETRYABLE_BY_DEFAULT.has(kind);
|
|
10
|
-
|
|
10
|
+
// The window a messagePattern is searched in: an error body can be arbitrarily
|
|
11
|
+
// long, and a pattern only needs the start of it.
|
|
12
|
+
const MESSAGE_MATCH_LIMIT = 2000;
|
|
13
|
+
const COMPILED_PATTERNS = new Map();
|
|
14
|
+
function compilePattern(source) {
|
|
15
|
+
const cached = COMPILED_PATTERNS.get(source);
|
|
16
|
+
if (cached) {
|
|
17
|
+
return cached;
|
|
18
|
+
}
|
|
19
|
+
const compiled = new RegExp(source, "i");
|
|
20
|
+
COMPILED_PATTERNS.set(source, compiled);
|
|
21
|
+
return compiled;
|
|
22
|
+
}
|
|
23
|
+
function ruleMatches(rule, status, message) {
|
|
11
24
|
const statuses = rule.status === undefined
|
|
12
25
|
? []
|
|
13
26
|
: typeof rule.status === "number"
|
|
14
27
|
? [rule.status]
|
|
15
28
|
: rule.status;
|
|
16
|
-
return (statuses.includes(status) ||
|
|
17
|
-
(rule.statusMin !== undefined && status >= rule.statusMin))
|
|
29
|
+
return ((statuses.includes(status) ||
|
|
30
|
+
(rule.statusMin !== undefined && status >= rule.statusMin)) &&
|
|
31
|
+
(rule.messagePattern === undefined ||
|
|
32
|
+
compilePattern(rule.messagePattern).test(message.slice(0, MESSAGE_MATCH_LIMIT))));
|
|
18
33
|
}
|
|
19
34
|
function messageFromShape(shape, value) {
|
|
20
35
|
if (shape.isArray) {
|
|
@@ -27,31 +42,42 @@ function messageFromShape(shape, value) {
|
|
|
27
42
|
}
|
|
28
43
|
return shape.formatter ? DECIDE_FORMATTERS[shape.formatter](value) : value;
|
|
29
44
|
}
|
|
45
|
+
function firstShapeText(shapes, payload) {
|
|
46
|
+
for (const shape of shapes) {
|
|
47
|
+
const text = messageFromShape(shape, readPath(payload, shape.path));
|
|
48
|
+
if (text !== undefined) {
|
|
49
|
+
return { shape, text };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
30
54
|
export function classifyDecisionError(spec, input) {
|
|
31
55
|
const { status, payload, requestId, label, apiKey } = input;
|
|
32
|
-
const rule = spec.rules.find((candidate) => ruleMatches(candidate, status));
|
|
33
|
-
const ruleKind = rule?.kind ?? spec.default;
|
|
34
|
-
const ruleRetryable = rule?.retryable ?? isRetryableByDefault(ruleKind);
|
|
35
56
|
// Redacted once, here: it stands in for a shape's text that redaction
|
|
36
57
|
// empties, and the label is catalog data a key can match. Redaction is not
|
|
37
58
|
// idempotent for a key such as "e" (it matches inside "[redacted]"), so the
|
|
38
59
|
// fallback is never passed through it a second time.
|
|
39
60
|
const fallback = redactCredentials(`${label} request failed with HTTP ${status}`, apiKey);
|
|
40
|
-
const
|
|
61
|
+
const found = firstShapeText(spec.bodyShapes, payload);
|
|
62
|
+
// The message comes first because a rule may match on it: the key is gone
|
|
63
|
+
// from the text a pattern sees.
|
|
64
|
+
const message = (found?.text && redactCredentials(found.text, apiKey)) || fallback;
|
|
65
|
+
const rule = spec.rules.find((candidate) => ruleMatches(candidate, status, message));
|
|
66
|
+
const ruleKind = rule?.kind ?? spec.default;
|
|
67
|
+
const ruleRetryable = rule?.retryable ?? isRetryableByDefault(ruleKind);
|
|
68
|
+
const build = (kind, retryable) => ({
|
|
41
69
|
kind,
|
|
42
|
-
message
|
|
70
|
+
message,
|
|
43
71
|
status,
|
|
44
72
|
requestId,
|
|
45
73
|
retryable,
|
|
46
74
|
});
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
: isRetryableByDefault(shape.kind)), text);
|
|
54
|
-
}
|
|
75
|
+
if (found) {
|
|
76
|
+
const { shape } = found;
|
|
77
|
+
return build(shape.kind ?? ruleKind, shape.retryable ??
|
|
78
|
+
(shape.kind === undefined
|
|
79
|
+
? ruleRetryable
|
|
80
|
+
: isRetryableByDefault(shape.kind)));
|
|
55
81
|
}
|
|
56
82
|
return build(ruleKind, ruleRetryable);
|
|
57
83
|
}
|
|
@@ -262,12 +262,23 @@ export type ProviderCatalogJson = {
|
|
|
262
262
|
evidence: CatalogEvidence;
|
|
263
263
|
};
|
|
264
264
|
export type DecideFormatterName = "fastapi-validation";
|
|
265
|
-
export type DecideBaseURLTransform = "strip-trailing-slash";
|
|
265
|
+
export type DecideBaseURLTransform = "strip-trailing-slash" | "strip-v1-suffix";
|
|
266
|
+
/** A check a base URL must pass once normalised; `origin` allows only an http(s) URL with no userinfo, query string or fragment. */
|
|
267
|
+
export type DecideBaseURLShape = "origin";
|
|
266
268
|
export type DecideErrorRule = {
|
|
267
269
|
/** One status or a list of them. A rule sets this or `statusMin`, never both. */
|
|
268
270
|
status?: number | readonly number[];
|
|
269
271
|
/** Matches every status at or above this value. */
|
|
270
272
|
statusMin?: number;
|
|
273
|
+
/**
|
|
274
|
+
* With a status, the rule also needs the error message to match this regular
|
|
275
|
+
* expression (case-insensitive, searched in the first 2,000 characters of the
|
|
276
|
+
* message after the key is removed). Bounded: no unescaped `*`, `+` or
|
|
277
|
+
* `{n,}`, no quantifier on a group, no count above 255, and the counts side
|
|
278
|
+
* by side multiply to at most 4,096 ways (each `?` is 2, each `{n,m}` is
|
|
279
|
+
* m-n+1).
|
|
280
|
+
*/
|
|
281
|
+
messagePattern?: string;
|
|
271
282
|
kind: DecisionErrorKind;
|
|
272
283
|
retryable?: boolean;
|
|
273
284
|
};
|
|
@@ -289,16 +300,31 @@ export type DecideModel = {
|
|
|
289
300
|
/** With `body-unless-alias`: the model name that means "send no model". */
|
|
290
301
|
alias?: string;
|
|
291
302
|
};
|
|
303
|
+
/**
|
|
304
|
+
* The request body keys prepared media is written under. Set together with
|
|
305
|
+
* `decisionLimits.media`, which says how much of it a request may carry.
|
|
306
|
+
*/
|
|
307
|
+
export type DecideMedia = {
|
|
308
|
+
/** Written only when the request carries at least one image. */
|
|
309
|
+
imagesKey: string;
|
|
310
|
+
/** Written only when the request carries a video; required exactly when `decisionLimits.media.video` is true. */
|
|
311
|
+
videoKey?: string;
|
|
312
|
+
};
|
|
292
313
|
export type DecideBlock = {
|
|
293
314
|
dialect: DecideDialectName;
|
|
294
315
|
/** Decision order, lower runs first; unique across decide providers. */
|
|
295
316
|
order: number;
|
|
296
317
|
/** True when the provider has no built-in endpoint and the caller must supply one. */
|
|
297
318
|
baseURLRequired?: boolean;
|
|
319
|
+
/** Applied to the base URL in list order. */
|
|
298
320
|
baseURLNormalize?: readonly DecideBaseURLTransform[];
|
|
321
|
+
/** Refuses a base URL of another shape before any request. Omitted means no check. */
|
|
322
|
+
baseURLShape?: DecideBaseURLShape;
|
|
299
323
|
/** Request URL; `{baseURL}` is the only placeholder. */
|
|
300
324
|
endpoint: string;
|
|
301
325
|
model: DecideModel;
|
|
326
|
+
/** Body keys for images and video, after `model`, `state` and `questions`. Omitted means the body never carries media. */
|
|
327
|
+
media?: DecideMedia;
|
|
302
328
|
requestIdHeaders?: readonly string[];
|
|
303
329
|
response?: {
|
|
304
330
|
modelPaths?: readonly string[];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type CatalogProviderName = "a2agent" | "abliteration" | "above-dev" | "ai21" | "aiand" | "aihubmix" | "aionlabs" | "ambient" | "api-route" | "arcee" | "atlas-cloud" | "avian-io" | "baidu-qianfan" | "baseten" | "bee-heossi" | "byteplus-modelark" | "bytez" | "cerebras" | "charm-hyper" | "chutes" | "cloudflare" | "crusoe" | "dashscope" | "deepinfra" | "deepseek" | "empiriolabs" | "featherless-ai" | "fireworks" | "friendli" | "gmicloud" | "gradientai" | "groq" | "hetzner-inference" | "huggingface" | "inception-labs" | "inceptron" | "inco" | "inference-net" | "io-intelligence" | "koscompute" | "laya" | "lemonfox-ai" | "lilac" | "llmtech" | "longcat" | "mancer" | "meta-model-api" | "minimax" | "mistral" | "moark" | "modelscope" | "moonshot-ai" | "morph" | "naver-clova-studio" | "nebius" | "neuralwatt" | "novita" | "ovhcloud" | "parasail" | "pareto-inference" | "perplexity" | "poolside" | "prime-intellect" | "reka" | "runinfra" | "sakana-ai" | "sambanova" | "sarvam" | "scaleway" | "siliconflow" | "stackit" | "stepfun" | "subconscious" | "synthetic" | "telnyx" | "thinking-machines" | "tinfoil" | "together-ai" | "umans-ai" | "upstage" | "venice-ai" | "vispark" | "vultr-inference" | "wafer" | "wandb-inference" | "xai" | "xiaomi-mimo" | "z-ai";
|
|
2
|
-
export type CatalogCredentialKey = "a2agent" | "abliteration" | "aboveDev" | "ai21" | "aiand" | "aihubmix" | "aionlabs" | "ambient" | "apiRoute" | "arcee" | "atlasCloud" | "avianIo" | "baiduQianfan" | "baseten" | "beeHeossi" | "byteplusModelark" | "bytez" | "cerebras" | "charmHyper" | "chutes" | "cloudflare" | "crusoe" | "dashscope" | "deepinfra" | "deepseek" | "empiriolabs" | "featherlessAi" | "fireworks" | "friendli" | "gmicloud" | "gradientai" | "groq" | "hetznerInference" | "huggingFace" | "inceptionLabs" | "inceptron" | "inco" | "inferenceNet" | "ioIntelligence" | "koscompute" | "laya" | "lemonfoxAi" | "lilac" | "llmtech" | "longcat" | "mancer" | "metaModelApi" | "minimax" | "mistral" | "moark" | "modelscope" | "moonshotAi" | "morph" | "naverClovaStudio" | "nebius" | "neuralwatt" | "novita" | "ovhcloud" | "parasail" | "paretoInference" | "perplexity" | "poolside" | "primeIntellect" | "reka" | "runinfra" | "sakanaAi" | "sambanova" | "sarvam" | "scaleway" | "siliconflow" | "stackit" | "stepfun" | "subconscious" | "synthetic" | "telnyx" | "thinkingMachines" | "tinfoil" | "together" | "umansAi" | "upstage" | "veniceAi" | "vispark" | "vultrInference" | "wafer" | "wandbInference" | "xai" | "xiaomiMimo" | "zAi";
|
|
1
|
+
export type CatalogProviderName = "a2agent" | "abliteration" | "above-dev" | "ai21" | "aiand" | "aihubmix" | "aionlabs" | "ambient" | "api-route" | "arcee" | "atlas-cloud" | "avian-io" | "baidu-qianfan" | "baseten" | "bee-heossi" | "byteplus-modelark" | "bytez" | "cerebras" | "charm-hyper" | "chutes" | "cloudflare" | "crusoe" | "dashscope" | "deepinfra" | "deepseek" | "empiriolabs" | "featherless-ai" | "fireworks" | "friendli" | "gmicloud" | "gradientai" | "groq" | "hetzner-inference" | "huggingface" | "inception-labs" | "inceptron" | "inco" | "inference-net" | "io-intelligence" | "koscompute" | "laya" | "lemonfox-ai" | "lilac" | "llmtech" | "longcat" | "mancer" | "meta-model-api" | "minimax" | "mistral" | "moark" | "modelscope" | "moonshot-ai" | "morph" | "naver-clova-studio" | "nebius" | "neuralwatt" | "novita" | "ovhcloud" | "parasail" | "pareto-inference" | "perplexity" | "poolside" | "prime-intellect" | "reka" | "runinfra" | "sakana-ai" | "sambanova" | "sarvam" | "scaleway" | "siliconflow" | "stackit" | "stepfun" | "subconscious" | "synthetic" | "telnyx" | "thinking-machines" | "tinfoil" | "together-ai" | "umans-ai" | "upstage" | "venice-ai" | "vispark" | "vultr-inference" | "wafer" | "wandb-inference" | "xai" | "xiaomi-mimo" | "xor" | "z-ai";
|
|
2
|
+
export type CatalogCredentialKey = "a2agent" | "abliteration" | "aboveDev" | "ai21" | "aiand" | "aihubmix" | "aionlabs" | "ambient" | "apiRoute" | "arcee" | "atlasCloud" | "avianIo" | "baiduQianfan" | "baseten" | "beeHeossi" | "byteplusModelark" | "bytez" | "cerebras" | "charmHyper" | "chutes" | "cloudflare" | "crusoe" | "dashscope" | "deepinfra" | "deepseek" | "empiriolabs" | "featherlessAi" | "fireworks" | "friendli" | "gmicloud" | "gradientai" | "groq" | "hetznerInference" | "huggingFace" | "inceptionLabs" | "inceptron" | "inco" | "inferenceNet" | "ioIntelligence" | "koscompute" | "laya" | "lemonfoxAi" | "lilac" | "llmtech" | "longcat" | "mancer" | "metaModelApi" | "minimax" | "mistral" | "moark" | "modelscope" | "moonshotAi" | "morph" | "naverClovaStudio" | "nebius" | "neuralwatt" | "novita" | "ovhcloud" | "parasail" | "paretoInference" | "perplexity" | "poolside" | "primeIntellect" | "reka" | "runinfra" | "sakanaAi" | "sambanova" | "sarvam" | "scaleway" | "siliconflow" | "stackit" | "stepfun" | "subconscious" | "synthetic" | "telnyx" | "thinkingMachines" | "tinfoil" | "together" | "umansAi" | "upstage" | "veniceAi" | "vispark" | "vultrInference" | "wafer" | "wandbInference" | "xai" | "xiaomiMimo" | "xor" | "zAi";
|
|
@@ -541,6 +541,10 @@ export type NeurolinkCredentials = {
|
|
|
541
541
|
apiKey?: string;
|
|
542
542
|
baseURL?: string;
|
|
543
543
|
};
|
|
544
|
+
xor?: {
|
|
545
|
+
apiKey?: string;
|
|
546
|
+
baseURL?: string;
|
|
547
|
+
};
|
|
544
548
|
zAi?: {
|
|
545
549
|
apiKey?: string;
|
|
546
550
|
baseURL?: string;
|
|
@@ -601,16 +605,6 @@ export type NeurolinkCredentials = {
|
|
|
601
605
|
*/
|
|
602
606
|
gatewayURL?: string;
|
|
603
607
|
};
|
|
604
|
-
/**
|
|
605
|
-
* XOR (Juspay, open weights) — the `decide` inference type. There is no
|
|
606
|
-
* built-in endpoint: `baseURL` (or XOR_BASE_URL) is required, pointing at the
|
|
607
|
-
* origin of an XOR deployment or a proxy route to one; requests go to
|
|
608
|
-
* `<baseURL>/v1/systemone`.
|
|
609
|
-
*/
|
|
610
|
-
xor?: {
|
|
611
|
-
apiKey?: string;
|
|
612
|
-
baseURL?: string;
|
|
613
|
-
};
|
|
614
608
|
/**
|
|
615
609
|
* Perplexity Decisions API — the `decide` inference type. The key is the same
|
|
616
610
|
* `PERPLEXITY_API_KEY` the `perplexity` text provider reads, but this slice
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Centralized model choices for CLI commands
|
|
3
3
|
* Derives choices from model enums to ensure consistency
|
|
4
4
|
*/
|
|
5
|
-
import { AIProviderName, OpenAIModels, AnthropicModels, GoogleAIModels, BedrockModels, VertexModels, OllamaModels, AzureOpenAIModels, LiteLLMModels, SageMakerModels, OpenRouterModels, NvidiaNimModels, CohereModels, VoyageModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, TypeSafeModels,
|
|
5
|
+
import { AIProviderName, OpenAIModels, AnthropicModels, GoogleAIModels, BedrockModels, VertexModels, OllamaModels, AzureOpenAIModels, LiteLLMModels, SageMakerModels, OpenRouterModels, NvidiaNimModels, CohereModels, VoyageModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, TypeSafeModels, PerplexityDeciderModels, CloudflareClefModels, ReplicateModels, } from "../constants/enums.js";
|
|
6
6
|
import { getCatalogJsonEntries, getDecideCatalogEntries, } from "../providers/catalog/loader.js";
|
|
7
7
|
/**
|
|
8
8
|
* Looks up the JSON catalog entry for a provider, if it is one of the 11
|
|
@@ -377,12 +377,6 @@ const TOP_MODELS_CONFIG = {
|
|
|
377
377
|
description: "Preview build of Jev",
|
|
378
378
|
},
|
|
379
379
|
],
|
|
380
|
-
[AIProviderName.XOR]: [
|
|
381
|
-
{
|
|
382
|
-
model: XorModels.XOR_1_1,
|
|
383
|
-
description: "Recommended - XOR 1.1, decision model that also reads images and video",
|
|
384
|
-
},
|
|
385
|
-
],
|
|
386
380
|
[AIProviderName.PERPLEXITY_DECIDER]: [
|
|
387
381
|
{
|
|
388
382
|
model: PerplexityDeciderModels.PPLX_DECIDER_V1_27B,
|
|
@@ -445,7 +439,6 @@ export const DEFAULT_MODELS = {
|
|
|
445
439
|
[AIProviderName.IDEOGRAM]: IdeogramModels.IDEOGRAM_V3,
|
|
446
440
|
[AIProviderName.RECRAFT]: RecraftModels.RECRAFT_V3,
|
|
447
441
|
[AIProviderName.TYPESAFE]: TypeSafeModels.JEV_LATEST,
|
|
448
|
-
[AIProviderName.XOR]: XorModels.XOR_1_1,
|
|
449
442
|
[AIProviderName.PERPLEXITY_DECIDER]: PerplexityDeciderModels.PPLX_DECIDER_V1_27B,
|
|
450
443
|
[AIProviderName.CLOUDFLARE_CLEF]: CloudflareClefModels.CLEF,
|
|
451
444
|
};
|
|
@@ -480,7 +473,6 @@ const MODEL_ENUMS = {
|
|
|
480
473
|
[AIProviderName.IDEOGRAM]: IdeogramModels,
|
|
481
474
|
[AIProviderName.RECRAFT]: RecraftModels,
|
|
482
475
|
[AIProviderName.TYPESAFE]: TypeSafeModels,
|
|
483
|
-
[AIProviderName.XOR]: XorModels,
|
|
484
476
|
[AIProviderName.PERPLEXITY_DECIDER]: PerplexityDeciderModels,
|
|
485
477
|
[AIProviderName.CLOUDFLARE_CLEF]: CloudflareClefModels,
|
|
486
478
|
[AIProviderName.AUTO]: null,
|
|
@@ -400,11 +400,6 @@ export declare function resolveOpenAICompatConfig(entry: OpenAICompatConfigInput
|
|
|
400
400
|
* TypeSafe (Jev) — the `decide` inference type. Not a text provider.
|
|
401
401
|
*/
|
|
402
402
|
export declare function createTypeSafeConfig(): ProviderConfigOptions;
|
|
403
|
-
/**
|
|
404
|
-
* XOR — the `decide` inference type. Not a text provider, and it has no
|
|
405
|
-
* built-in endpoint: XOR_BASE_URL is required alongside the key.
|
|
406
|
-
*/
|
|
407
|
-
export declare function createXorConfig(): ProviderConfigOptions;
|
|
408
403
|
/**
|
|
409
404
|
* Perplexity Decisions API — the `decide` inference type, not the Sonar text
|
|
410
405
|
* models. It reads the same PERPLEXITY_API_KEY as the `perplexity` text
|
|
@@ -1324,23 +1324,6 @@ export function createTypeSafeConfig() {
|
|
|
1324
1324
|
],
|
|
1325
1325
|
};
|
|
1326
1326
|
}
|
|
1327
|
-
/**
|
|
1328
|
-
* XOR — the `decide` inference type. Not a text provider, and it has no
|
|
1329
|
-
* built-in endpoint: XOR_BASE_URL is required alongside the key.
|
|
1330
|
-
*/
|
|
1331
|
-
export function createXorConfig() {
|
|
1332
|
-
return {
|
|
1333
|
-
providerName: "XOR",
|
|
1334
|
-
envVarName: "XOR_API_KEY",
|
|
1335
|
-
setupUrl: "https://huggingface.co/juspay/xor",
|
|
1336
|
-
description: "API key for your XOR endpoint",
|
|
1337
|
-
instructions: [
|
|
1338
|
-
"1. Reach an XOR deployment, or use a LiteLLM proxy with a pass-through route to one",
|
|
1339
|
-
"2. Set XOR_BASE_URL to its origin (NeuroLink calls <XOR_BASE_URL>/v1/systemone)",
|
|
1340
|
-
"3. Set XOR_API_KEY to the key it accepts (on LiteLLM, a virtual key whose team allows xor-1.1)",
|
|
1341
|
-
],
|
|
1342
|
-
};
|
|
1343
|
-
}
|
|
1344
1327
|
/**
|
|
1345
1328
|
* Perplexity Decisions API — the `decide` inference type, not the Sonar text
|
|
1346
1329
|
* models. It reads the same PERPLEXITY_API_KEY as the `perplexity` text
|