@juspay/neurolink 13.1.0 → 13.2.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 -7
- package/README.md +71 -52
- package/dist/browser/neurolink.min.js +374 -374
- package/dist/cli/commands/decide.d.ts +2 -1
- package/dist/cli/commands/decide.js +2 -1
- package/dist/cli/commands/setup.d.ts +1 -1
- package/dist/cli/commands/setup.js +1 -1
- package/dist/cli/factories/commandFactory.js +14 -5
- package/dist/constants/contextWindows.d.ts +7 -0
- package/dist/constants/contextWindows.js +48 -0
- package/dist/constants/enums.d.ts +5 -0
- package/dist/constants/enums.js +6 -0
- package/dist/factories/providerDescriptors.js +13 -9
- package/dist/neurolink.d.ts +4 -0
- package/dist/neurolink.js +24 -1
- package/dist/providers/catalog/charm-hyper.json +6 -10
- package/dist/providers/catalog/index.generated.d.ts +1 -1
- package/dist/providers/catalog/index.generated.js +3 -0
- package/dist/providers/catalog/openai-decisions.json +1 -1
- package/dist/providers/catalog/provider-catalog.schema.json +8 -0
- package/dist/providers/catalog/scaledown.json +68 -0
- package/dist/providers/catalog/schema.js +2 -0
- package/dist/providers/configuredDecision.d.ts +5 -0
- package/dist/providers/configuredDecision.js +27 -5
- package/dist/types/classifierRouter.d.ts +10 -9
- package/dist/types/cli.d.ts +2 -2
- package/dist/types/providerCatalog.d.ts +22 -0
- package/dist/types/providerCatalog.generated.d.ts +2 -2
- package/dist/types/providers.d.ts +4 -0
- package/dist/utils/pricing.js +12 -0
- package/dist/utils/tokenLimits.js +20 -1
- package/docs-site/static/search-index.json +92 -67
- package/package.json +4 -2
|
@@ -24,16 +24,16 @@ export type ClassifierDifficulty = "trivial" | "simple" | "moderate" | "hard" |
|
|
|
24
24
|
* - `heuristic` — keyword/length scoring. Deterministic, zero latency.
|
|
25
25
|
* - `llm` — a cheap classifier model via the injected `generate`.
|
|
26
26
|
* - `jev` — a decision model, whichever decision provider is configured
|
|
27
|
-
* (TypeSafe's Jev, Laya, XOR, SubQ, Perplexity, Cloudflare Clef
|
|
28
|
-
* Decisions); one round trip that returns the confidence the provider
|
|
27
|
+
* (TypeSafe's Jev, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI
|
|
28
|
+
* Decisions or ScaleDown); one round trip that returns the confidence the provider
|
|
29
29
|
* reports (*calibrated* on TypeSafe's Jev, ~400ms there) rather than a
|
|
30
30
|
* self-reported one.
|
|
31
31
|
* - `auto` — `jev` when a decision provider is configured, in the environment
|
|
32
32
|
* or in SDK credentials (`TYPESAFE_API_KEY`, `LAYA_API_KEY` with
|
|
33
33
|
* `LAYA_BASE_URL`, `XOR_API_KEY` with `XOR_BASE_URL`, `SUBQ_API_KEY`, `PERPLEXITY_API_KEY`,
|
|
34
|
-
* `CLOUDFLARE_API_KEY` with `CLOUDFLARE_ACCOUNT_ID`,
|
|
34
|
+
* `CLOUDFLARE_API_KEY` with `CLOUDFLARE_ACCOUNT_ID`, `OPENAI_API_KEY`,
|
|
35
35
|
* which does not count while `OPENAI_BASE_URL`, `OPENAI_API_BASE` or `credentials.openai.baseURL` names a
|
|
36
|
-
* host other than `https://api.openai.com`), otherwise `heuristic`.
|
|
36
|
+
* host other than `https://api.openai.com`, or `SCALEDOWN_API_KEY`), otherwise `heuristic`.
|
|
37
37
|
*/
|
|
38
38
|
export type ClassifierStrategyKind = "heuristic" | "llm" | "jev" | "auto";
|
|
39
39
|
/**
|
|
@@ -195,15 +195,16 @@ export type ClassifierRouterConfig = {
|
|
|
195
195
|
* decision provider is configured, in the environment or in SDK credentials
|
|
196
196
|
* (`TYPESAFE_API_KEY`, `LAYA_API_KEY` with `LAYA_BASE_URL`,
|
|
197
197
|
* `XOR_API_KEY` with `XOR_BASE_URL`, `SUBQ_API_KEY`, `PERPLEXITY_API_KEY`,
|
|
198
|
-
* `CLOUDFLARE_API_KEY` with `CLOUDFLARE_ACCOUNT_ID`,
|
|
199
|
-
* "heuristic" otherwise, so configuring one upgrades routing without any code
|
|
198
|
+
* `CLOUDFLARE_API_KEY` with `CLOUDFLARE_ACCOUNT_ID`, `OPENAI_API_KEY` or
|
|
199
|
+
* `SCALEDOWN_API_KEY`) and "heuristic" otherwise, so configuring one upgrades routing without any code
|
|
200
200
|
* change. Behaviour for a caller with none of these is unchanged. Three of them
|
|
201
201
|
* are shared with a text provider and count here too: `PERPLEXITY_API_KEY`
|
|
202
202
|
* (Perplexity's), the Cloudflare pair (Workers AI's) and `OPENAI_API_KEY` (the
|
|
203
203
|
* OpenAI chat provider's). A caller whose only key is `OPENAI_API_KEY` now
|
|
204
|
-
* resolves to "jev", answered by OpenAI Decisions
|
|
205
|
-
* provider
|
|
206
|
-
*
|
|
204
|
+
* resolves to "jev", answered by OpenAI Decisions (the default decision
|
|
205
|
+
* provider whenever none ahead of it in the order is configured); each
|
|
206
|
+
* classification is then a paid call that still falls back to the heuristic
|
|
207
|
+
* on any failure. The exception is a key that sits beside an
|
|
207
208
|
* `OPENAI_BASE_URL`, `OPENAI_API_BASE` or `credentials.openai.baseURL` naming a host other than
|
|
208
209
|
* `https://api.openai.com`: that key is a gateway's and does not count.
|
|
209
210
|
*/
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -1770,9 +1770,9 @@ export type CliClassifierRouterFlags = {
|
|
|
1770
1770
|
* (--classifier-strategy). "auto" resolves to "jev" when a decision
|
|
1771
1771
|
* provider is configured (TYPESAFE_API_KEY, LAYA_API_KEY with
|
|
1772
1772
|
* LAYA_BASE_URL, XOR_API_KEY with XOR_BASE_URL, SUBQ_API_KEY, PERPLEXITY_API_KEY,
|
|
1773
|
-
* CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID,
|
|
1773
|
+
* CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID, OPENAI_API_KEY, which does
|
|
1774
1774
|
* not count beside an OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL naming a host other
|
|
1775
|
-
* than https://api.openai.com) and "heuristic" otherwise.
|
|
1775
|
+
* than https://api.openai.com, or SCALEDOWN_API_KEY) and "heuristic" otherwise.
|
|
1776
1776
|
*/
|
|
1777
1777
|
classifierStrategy?: string;
|
|
1778
1778
|
/**
|
|
@@ -25,6 +25,14 @@ export type CatalogTimeouts = {
|
|
|
25
25
|
};
|
|
26
26
|
export type CatalogModelSpec = {
|
|
27
27
|
contextWindow?: number;
|
|
28
|
+
/**
|
|
29
|
+
* The model's own output-token limit. Enforced at runtime: for a provider
|
|
30
|
+
* with no PROVIDER_MAX_TOKENS row, getSafeMaxTokens clamps a larger
|
|
31
|
+
* requested maxTokens to this value. Record only a number the vendor states
|
|
32
|
+
* as a hard limit; omit it when the source is a roster field that looks
|
|
33
|
+
* derived from the context window, because an omitted value leaves the
|
|
34
|
+
* model uncapped while a wrong one silently truncates callers.
|
|
35
|
+
*/
|
|
28
36
|
maxOutputTokens?: number;
|
|
29
37
|
pricingPerMTok?: CatalogPricingPerMTok;
|
|
30
38
|
vision: boolean;
|
|
@@ -314,6 +322,20 @@ export type DecideBlock = {
|
|
|
314
322
|
/** Request URL; `{baseURL}` is the only placeholder. */
|
|
315
323
|
endpoint: string;
|
|
316
324
|
model: DecideModel;
|
|
325
|
+
/**
|
|
326
|
+
* How the API key is sent. `bearer`, the default when omitted, sends
|
|
327
|
+
* `Authorization: Bearer <key>`. `x-api-key` sends `x-api-key: <key>` and no
|
|
328
|
+
* `Authorization` header at all. This is the decide request's own setting;
|
|
329
|
+
* `quirks.authHeaderStyle` belongs to the chat path and is not read here.
|
|
330
|
+
*/
|
|
331
|
+
authHeader?: "bearer" | "x-api-key";
|
|
332
|
+
/**
|
|
333
|
+
* `text` makes the state that goes out always a string: a string is sent
|
|
334
|
+
* unchanged (not trimmed), any other value is sent as its JSON text, and a
|
|
335
|
+
* state that is blank after trimming is refused before any request, as an
|
|
336
|
+
* `invalid_request`. Omitted means the state goes out as given.
|
|
337
|
+
*/
|
|
338
|
+
stateEncoding?: "text";
|
|
317
339
|
/** Body keys for images and video, after `model`, `state` and `questions`. Omitted means the body never carries media. */
|
|
318
340
|
media?: DecideMedia;
|
|
319
341
|
/**
|
|
@@ -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" | "openai-decisions" | "ovhcloud" | "parasail" | "pareto-inference" | "perplexity" | "poolside" | "prime-intellect" | "reka" | "runinfra" | "sakana-ai" | "sambanova" | "sarvam" | "scaleway" | "siliconflow" | "stackit" | "stepfun" | "subconscious" | "subq" | "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" | "openaiDecisions" | "ovhcloud" | "parasail" | "paretoInference" | "perplexity" | "poolside" | "primeIntellect" | "reka" | "runinfra" | "sakanaAi" | "sambanova" | "sarvam" | "scaleway" | "siliconflow" | "stackit" | "stepfun" | "subconscious" | "subq" | "synthetic" | "telnyx" | "thinkingMachines" | "tinfoil" | "together" | "umansAi" | "upstage" | "veniceAi" | "vispark" | "vultrInference" | "wafer" | "wandbInference" | "xai" | "xiaomiMimo" | "xor" | "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" | "openai-decisions" | "ovhcloud" | "parasail" | "pareto-inference" | "perplexity" | "poolside" | "prime-intellect" | "reka" | "runinfra" | "sakana-ai" | "sambanova" | "sarvam" | "scaledown" | "scaleway" | "siliconflow" | "stackit" | "stepfun" | "subconscious" | "subq" | "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" | "openaiDecisions" | "ovhcloud" | "parasail" | "paretoInference" | "perplexity" | "poolside" | "primeIntellect" | "reka" | "runinfra" | "sakanaAi" | "sambanova" | "sarvam" | "scaledown" | "scaleway" | "siliconflow" | "stackit" | "stepfun" | "subconscious" | "subq" | "synthetic" | "telnyx" | "thinkingMachines" | "tinfoil" | "together" | "umansAi" | "upstage" | "veniceAi" | "vispark" | "vultrInference" | "wafer" | "wandbInference" | "xai" | "xiaomiMimo" | "xor" | "zAi";
|
package/dist/utils/pricing.js
CHANGED
|
@@ -812,6 +812,18 @@ const PRICING = {
|
|
|
812
812
|
// name, so a `"gpt-6-luna"` key would price that chat model at this rate.
|
|
813
813
|
_default: { input: 0.1 / 1_000_000, output: 0 },
|
|
814
814
|
},
|
|
815
|
+
scaledown: {
|
|
816
|
+
// $0.05 per million input tokens, output free: `output: 0` is a price, not
|
|
817
|
+
// a token count, so do not "correct" it from `usage.output_tokens`. A list
|
|
818
|
+
// price from ScaleDown's launch post and from `usage.cost` in a response,
|
|
819
|
+
// both as reported to this project on 2026-10-15; this project has not
|
|
820
|
+
// priced a call itself. Per ScaleDown's docs each choice option is a
|
|
821
|
+
// separate internal call, so input tokens grow with options times state
|
|
822
|
+
// length (not measured here). Only `_default`: LiteLLM, OpenRouter and
|
|
823
|
+
// openai-compatible search every table by model name, so a `"classify"` key
|
|
824
|
+
// would price an unrelated model at this rate.
|
|
825
|
+
_default: { input: 0.05 / 1_000_000, output: 0 },
|
|
826
|
+
},
|
|
815
827
|
"cloudflare-clef": {
|
|
816
828
|
// Workers AI bills Clef per million INPUT tokens ($0.24 for clef, $0.09 for
|
|
817
829
|
// clef-flash); no output price is listed. `output: 0` is a price, not a token
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Provider-specific token limit utilities
|
|
3
3
|
* Provides safe maxTokens values based on provider and model capabilities
|
|
4
4
|
*/
|
|
5
|
-
import { getRuntimeOutputCeiling } from "../constants/contextWindows.js";
|
|
5
|
+
import { getCatalogOutputCeiling, getRuntimeOutputCeiling, } from "../constants/contextWindows.js";
|
|
6
6
|
import { bedrockModelIdForLookup, stripBedrockGeoPrefix, } from "../constants/bedrockIdentifiers.js";
|
|
7
7
|
import { PROVIDER_MAX_TOKENS } from "../core/constants.js";
|
|
8
8
|
import { logger } from "./logger.js";
|
|
@@ -68,6 +68,25 @@ export function getSafeMaxTokens(provider, model, requestedMaxTokens) {
|
|
|
68
68
|
// Get provider-specific limits
|
|
69
69
|
const providerLimits = PROVIDER_MAX_TOKENS[canonicalProvider];
|
|
70
70
|
if (!providerLimits) {
|
|
71
|
+
// A JSON-catalog provider has no PROVIDER_MAX_TOKENS row, but its catalog
|
|
72
|
+
// entry can declare the model's own output ceiling. Only that per-model
|
|
73
|
+
// value counts: the provider-wide default is a 4096 placeholder for many
|
|
74
|
+
// providers. An over-large request is clamped. Unlike the runtime ceiling
|
|
75
|
+
// above, this ceiling is not injected as a default: an unset request stays
|
|
76
|
+
// unset, because a ceiling-sized default would shrink usable input on
|
|
77
|
+
// total-context backends.
|
|
78
|
+
const catalogCeiling = getCatalogOutputCeiling(provider, model);
|
|
79
|
+
if (catalogCeiling !== undefined) {
|
|
80
|
+
if (requestedMaxTokens === undefined || requestedMaxTokens === null) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
if (requestedMaxTokens > catalogCeiling) {
|
|
84
|
+
logger.warn(`Requested maxTokens ${requestedMaxTokens} exceeds the catalog output ceiling ` +
|
|
85
|
+
`of ${catalogCeiling} for ${provider}/${model}. Using ${catalogCeiling} instead.`);
|
|
86
|
+
return catalogCeiling;
|
|
87
|
+
}
|
|
88
|
+
return requestedMaxTokens;
|
|
89
|
+
}
|
|
71
90
|
logger.warn(`Unknown provider ${provider}, no token limits enforced`);
|
|
72
91
|
// Explicit undefined/null check so a caller-supplied 0 is preserved
|
|
73
92
|
// (truthy guard would silently drop 0 here as it does in the restricted branch).
|