@juspay/neurolink 12.50.0 → 12.51.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 +2 -2
- package/dist/browser/neurolink.min.js +666 -666
- package/dist/cli/commands/setup.d.ts +7 -5
- package/dist/cli/commands/setup.js +10 -8
- package/dist/constants/enums.d.ts +7 -15
- package/dist/constants/enums.js +8 -16
- package/dist/factories/providerDescriptors.d.ts +17 -3
- package/dist/factories/providerDescriptors.js +81 -56
- package/dist/factories/providerRegistry.d.ts +9 -1
- package/dist/factories/providerRegistry.js +19 -9
- package/dist/models/manifestRegistry.js +40 -3
- package/dist/providers/catalog/index.generated.d.ts +3 -1
- package/dist/providers/catalog/index.generated.js +11 -0
- package/dist/providers/catalog/laya.json +107 -0
- package/dist/providers/catalog/loader.d.ts +7 -4
- package/dist/providers/catalog/loader.js +10 -3
- package/dist/providers/catalog/provider-catalog.schema.json +218 -11
- package/dist/providers/catalog/schema.d.ts +11 -9
- package/dist/providers/catalog/schema.js +333 -59
- package/dist/providers/configuredDecision.d.ts +23 -0
- package/dist/providers/configuredDecision.js +111 -0
- package/dist/providers/decide/baseUrl.d.ts +2 -0
- package/dist/providers/decide/baseUrl.js +14 -0
- package/dist/providers/decide/errors.d.ts +8 -0
- package/dist/providers/decide/errors.js +57 -0
- package/dist/providers/decide/formatters.d.ts +2 -0
- package/dist/providers/decide/formatters.js +4 -0
- package/dist/providers/decide/paths.d.ts +1 -0
- package/dist/providers/decide/paths.js +21 -0
- package/dist/providers/decide/template.d.ts +3 -0
- package/dist/providers/decide/template.js +13 -0
- package/dist/types/providerCatalog.d.ts +74 -1
- package/dist/types/providerCatalog.generated.d.ts +2 -2
- package/dist/types/providers.d.ts +12 -9
- package/dist/utils/modelChoices.js +11 -25
- 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 -2
- package/dist/models/manifests/laya.d.ts +0 -12
- package/dist/models/manifests/laya.js +0 -54
- package/dist/providers/laya.d.ts +0 -40
- package/dist/providers/laya.js +0 -152
|
@@ -7,16 +7,18 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { ProviderConfigOptions, SetupArgs } from "../../types/index.js";
|
|
9
9
|
/**
|
|
10
|
-
* ProviderConfigOptions for the
|
|
10
|
+
* ProviderConfigOptions for the canonical AIProviderName values the
|
|
11
11
|
* interactive wizard above doesn't have a bespoke handleXSetup() for. 8 are
|
|
12
12
|
* the JSON-catalog providers (cerebras, cloudflare, fireworks, groq,
|
|
13
13
|
* perplexity, sambanova, together-ai, xai — mistral is the 9th catalog
|
|
14
14
|
* provider but keeps its own handleMistralSetup() flow above, so it's
|
|
15
15
|
* excluded here), spread directly from the catalog JSON via
|
|
16
|
-
* buildCatalogConfigOptions()
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* buildCatalogConfigOptions(); decide-kind catalog entries (laya) are spread
|
|
17
|
+
* the same way from getDecideCatalogEntries(). The hand rows listed first
|
|
18
|
+
* reuse the existing createXConfig() factories in providerConfig.ts; the
|
|
19
|
+
* remaining 5 (ollama, litellm, sagemaker, lm-studio, llamacpp) don't have a
|
|
20
|
+
* factory and are defined inline using their real env var names. lm-studio
|
|
21
|
+
* and llamacpp previously
|
|
20
22
|
* had createLmStudioConfig()/createLlamaCppConfig() factories, but those
|
|
21
23
|
* were removed as dead code in a later cleanup — this mirrors that removal
|
|
22
24
|
* rather than re-adding them.
|
|
@@ -21,8 +21,8 @@ import { handleHuggingFaceSetup } from "./setup-huggingface.js";
|
|
|
21
21
|
import { handleMistralSetup } from "./setup-mistral.js";
|
|
22
22
|
import { OpenRouterModels, } from "../../constants/enums.js";
|
|
23
23
|
import { PROVIDER_DESCRIPTORS_BY_NAME } from "../../factories/providerDescriptors.js";
|
|
24
|
-
import { createCohereConfig, createDeepSeekConfig, createIdeogramConfig, createJinaConfig, createNvidiaNimConfig, createOpenAICompatibleConfig, createRecraftConfig, createReplicateConfig, createStabilityConfig, createVoyageConfig, createTypeSafeConfig,
|
|
25
|
-
import { getCatalogJsonEntries, buildCatalogConfigOptions, } from "../../providers/catalog/loader.js";
|
|
24
|
+
import { createCohereConfig, createDeepSeekConfig, createIdeogramConfig, createJinaConfig, createNvidiaNimConfig, createOpenAICompatibleConfig, createRecraftConfig, createReplicateConfig, createStabilityConfig, createVoyageConfig, createTypeSafeConfig, createXorConfig, createPerplexityDeciderConfig, createCloudflareClefConfig, satisfiesFallbacks, } from "../../utils/providerConfig.js";
|
|
25
|
+
import { getCatalogJsonEntries, getDecideCatalogEntries, buildCatalogConfigOptions, } from "../../providers/catalog/loader.js";
|
|
26
26
|
// Provider information database
|
|
27
27
|
const PROVIDERS = [
|
|
28
28
|
{
|
|
@@ -144,16 +144,18 @@ const PROVIDERS = [
|
|
|
144
144
|
},
|
|
145
145
|
];
|
|
146
146
|
/**
|
|
147
|
-
* ProviderConfigOptions for the
|
|
147
|
+
* ProviderConfigOptions for the canonical AIProviderName values the
|
|
148
148
|
* interactive wizard above doesn't have a bespoke handleXSetup() for. 8 are
|
|
149
149
|
* the JSON-catalog providers (cerebras, cloudflare, fireworks, groq,
|
|
150
150
|
* perplexity, sambanova, together-ai, xai — mistral is the 9th catalog
|
|
151
151
|
* provider but keeps its own handleMistralSetup() flow above, so it's
|
|
152
152
|
* excluded here), spread directly from the catalog JSON via
|
|
153
|
-
* buildCatalogConfigOptions()
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
153
|
+
* buildCatalogConfigOptions(); decide-kind catalog entries (laya) are spread
|
|
154
|
+
* the same way from getDecideCatalogEntries(). The hand rows listed first
|
|
155
|
+
* reuse the existing createXConfig() factories in providerConfig.ts; the
|
|
156
|
+
* remaining 5 (ollama, litellm, sagemaker, lm-studio, llamacpp) don't have a
|
|
157
|
+
* factory and are defined inline using their real env var names. lm-studio
|
|
158
|
+
* and llamacpp previously
|
|
157
159
|
* had createLmStudioConfig()/createLlamaCppConfig() factories, but those
|
|
158
160
|
* were removed as dead code in a later cleanup — this mirrors that removal
|
|
159
161
|
* rather than re-adding them.
|
|
@@ -170,10 +172,10 @@ export const EXTRA_PROVIDER_CONFIGS = {
|
|
|
170
172
|
ideogram: createIdeogramConfig(),
|
|
171
173
|
recraft: createRecraftConfig(),
|
|
172
174
|
typesafe: createTypeSafeConfig(),
|
|
173
|
-
laya: createLayaConfig(),
|
|
174
175
|
xor: createXorConfig(),
|
|
175
176
|
"perplexity-decider": createPerplexityDeciderConfig(),
|
|
176
177
|
"cloudflare-clef": createCloudflareClefConfig(),
|
|
178
|
+
...Object.fromEntries(getDecideCatalogEntries().map((e) => [e.id, buildCatalogConfigOptions(e)])),
|
|
177
179
|
...Object.fromEntries(getCatalogJsonEntries()
|
|
178
180
|
.filter((e) => e.id !== "mistral")
|
|
179
181
|
.map((e) => [e.id, buildCatalogConfigOptions(e)])),
|
|
@@ -56,6 +56,7 @@ export declare enum AIProviderName {
|
|
|
56
56
|
INFERENCE_NET = "inference-net",
|
|
57
57
|
IO_INTELLIGENCE = "io-intelligence",
|
|
58
58
|
KOSCOMPUTE = "koscompute",
|
|
59
|
+
LAYA = "laya",
|
|
59
60
|
LEMONFOX_AI = "lemonfox-ai",
|
|
60
61
|
LILAC = "lilac",
|
|
61
62
|
LLMTECH = "llmtech",
|
|
@@ -109,8 +110,6 @@ export declare enum AIProviderName {
|
|
|
109
110
|
RECRAFT = "recraft",
|
|
110
111
|
/** TypeSafe (Jev) — serves the `decide` inference type only. */
|
|
111
112
|
TYPESAFE = "typesafe",
|
|
112
|
-
/** Laya (Convai, open weights) — serves the `decide` inference type only. */
|
|
113
|
-
LAYA = "laya",
|
|
114
113
|
/** XOR (Juspay, open weights) — serves the `decide` inference type only. */
|
|
115
114
|
XOR = "xor",
|
|
116
115
|
/**
|
|
@@ -1327,6 +1326,12 @@ export declare enum IoIntelligenceModels {
|
|
|
1327
1326
|
export declare enum KoscomputeModels {
|
|
1328
1327
|
QWEN_QWEN3_8_27B = "qwen/qwen3.8-27b"
|
|
1329
1328
|
}
|
|
1329
|
+
export declare enum LayaModels {
|
|
1330
|
+
TYPED_DECISIONS = "typed-decisions",
|
|
1331
|
+
ENGLISH = "english",
|
|
1332
|
+
MULTILINGUAL = "multilingual",
|
|
1333
|
+
AUTO = "auto"
|
|
1334
|
+
}
|
|
1330
1335
|
export declare enum LemonfoxAiModels {
|
|
1331
1336
|
DEEPSEEK_V4_FLASH = "deepseek-v4-flash",
|
|
1332
1337
|
MIMO_V2_5_PRO = "mimo-v2.5-pro"
|
|
@@ -1771,19 +1776,6 @@ export declare enum TypeSafeModels {
|
|
|
1771
1776
|
JEV_LATEST = "jev-latest",
|
|
1772
1777
|
JEV_PREVIEW = "jev-preview"
|
|
1773
1778
|
}
|
|
1774
|
-
/**
|
|
1775
|
-
* Laya checkpoints. Hand-written: Laya is a Tier-3 provider, so it is not in
|
|
1776
|
-
* the provider catalog and codegen never touches this.
|
|
1777
|
-
*
|
|
1778
|
-
* `auto` sends no model, which lets Laya's own router pick a checkpoint by
|
|
1779
|
-
* the detected language of the state.
|
|
1780
|
-
*/
|
|
1781
|
-
export declare enum LayaModels {
|
|
1782
|
-
TYPED_DECISIONS = "typed-decisions",
|
|
1783
|
-
ENGLISH = "english",
|
|
1784
|
-
MULTILINGUAL = "multilingual",
|
|
1785
|
-
AUTO = "auto"
|
|
1786
|
-
}
|
|
1787
1779
|
/**
|
|
1788
1780
|
* XOR decision models. Hand-written: XOR is a Tier-3 provider, so it is not in
|
|
1789
1781
|
* the provider catalog and codegen never touches this.
|
package/dist/constants/enums.js
CHANGED
|
@@ -61,6 +61,7 @@ export var AIProviderName;
|
|
|
61
61
|
AIProviderName["INFERENCE_NET"] = "inference-net";
|
|
62
62
|
AIProviderName["IO_INTELLIGENCE"] = "io-intelligence";
|
|
63
63
|
AIProviderName["KOSCOMPUTE"] = "koscompute";
|
|
64
|
+
AIProviderName["LAYA"] = "laya";
|
|
64
65
|
AIProviderName["LEMONFOX_AI"] = "lemonfox-ai";
|
|
65
66
|
AIProviderName["LILAC"] = "lilac";
|
|
66
67
|
AIProviderName["LLMTECH"] = "llmtech";
|
|
@@ -115,8 +116,6 @@ export var AIProviderName;
|
|
|
115
116
|
AIProviderName["RECRAFT"] = "recraft";
|
|
116
117
|
/** TypeSafe (Jev) — serves the `decide` inference type only. */
|
|
117
118
|
AIProviderName["TYPESAFE"] = "typesafe";
|
|
118
|
-
/** Laya (Convai, open weights) — serves the `decide` inference type only. */
|
|
119
|
-
AIProviderName["LAYA"] = "laya";
|
|
120
119
|
/** XOR (Juspay, open weights) — serves the `decide` inference type only. */
|
|
121
120
|
AIProviderName["XOR"] = "xor";
|
|
122
121
|
/**
|
|
@@ -1603,6 +1602,13 @@ export var KoscomputeModels;
|
|
|
1603
1602
|
(function (KoscomputeModels) {
|
|
1604
1603
|
KoscomputeModels["QWEN_QWEN3_8_27B"] = "qwen/qwen3.8-27b";
|
|
1605
1604
|
})(KoscomputeModels || (KoscomputeModels = {}));
|
|
1605
|
+
export var LayaModels;
|
|
1606
|
+
(function (LayaModels) {
|
|
1607
|
+
LayaModels["TYPED_DECISIONS"] = "typed-decisions";
|
|
1608
|
+
LayaModels["ENGLISH"] = "english";
|
|
1609
|
+
LayaModels["MULTILINGUAL"] = "multilingual";
|
|
1610
|
+
LayaModels["AUTO"] = "auto";
|
|
1611
|
+
})(LayaModels || (LayaModels = {}));
|
|
1606
1612
|
export var LemonfoxAiModels;
|
|
1607
1613
|
(function (LemonfoxAiModels) {
|
|
1608
1614
|
LemonfoxAiModels["DEEPSEEK_V4_FLASH"] = "deepseek-v4-flash";
|
|
@@ -2093,20 +2099,6 @@ export var TypeSafeModels;
|
|
|
2093
2099
|
TypeSafeModels["JEV_LATEST"] = "jev-latest";
|
|
2094
2100
|
TypeSafeModels["JEV_PREVIEW"] = "jev-preview";
|
|
2095
2101
|
})(TypeSafeModels || (TypeSafeModels = {}));
|
|
2096
|
-
/**
|
|
2097
|
-
* Laya checkpoints. Hand-written: Laya is a Tier-3 provider, so it is not in
|
|
2098
|
-
* the provider catalog and codegen never touches this.
|
|
2099
|
-
*
|
|
2100
|
-
* `auto` sends no model, which lets Laya's own router pick a checkpoint by
|
|
2101
|
-
* the detected language of the state.
|
|
2102
|
-
*/
|
|
2103
|
-
export var LayaModels;
|
|
2104
|
-
(function (LayaModels) {
|
|
2105
|
-
LayaModels["TYPED_DECISIONS"] = "typed-decisions";
|
|
2106
|
-
LayaModels["ENGLISH"] = "english";
|
|
2107
|
-
LayaModels["MULTILINGUAL"] = "multilingual";
|
|
2108
|
-
LayaModels["AUTO"] = "auto";
|
|
2109
|
-
})(LayaModels || (LayaModels = {}));
|
|
2110
2102
|
/**
|
|
2111
2103
|
* XOR decision models. Hand-written: XOR is a Tier-3 provider, so it is not in
|
|
2112
2104
|
* the provider catalog and codegen never touches this.
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import type { NeurolinkCredentials, ProviderDescriptor } from "../types/index.js";
|
|
2
|
+
import type { DecideCatalogJson, NeurolinkCredentials, ProviderDescriptor } from "../types/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Builds the ProviderDescriptor of a JSON `decide` provider. It serves only
|
|
5
|
+
* `decide`, so it declares no auto-select, preference or health-sweep rank:
|
|
6
|
+
* those feed generation fallback chains a text-less provider must never join.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildDecideDescriptor(entry: DecideCatalogJson): ProviderDescriptor;
|
|
3
9
|
/**
|
|
4
10
|
* Single source of truth for provider identity, credentials, defaults, and
|
|
5
11
|
* runtime behavior classification — the hand-maintained providers plus the
|
|
@@ -14,10 +20,18 @@ export declare const PROVIDER_DESCRIPTORS_BY_NAME: ReadonlyMap<AIProviderName, P
|
|
|
14
20
|
* ProviderFactory.normalizeProviderName().
|
|
15
21
|
*/
|
|
16
22
|
export declare const PROVIDER_ALIAS_INDEX: ReadonlyMap<string, AIProviderName>;
|
|
23
|
+
/**
|
|
24
|
+
* Throws unless every descriptor that serves `decide` has its own finite
|
|
25
|
+
* `decideOrder`. The order is the precedence of resolveDefaultDecisionProvider(),
|
|
26
|
+
* so a missing or repeated number would make that choice depend on array position.
|
|
27
|
+
*/
|
|
28
|
+
export declare function assertUniqueDecideOrder(descriptors: readonly ProviderDescriptor[]): void;
|
|
29
|
+
/** The descriptors that serve `decide`, lowest `decideOrder` first. */
|
|
30
|
+
export declare function orderDecisionProviders(descriptors: readonly ProviderDescriptor[]): readonly ProviderDescriptor[];
|
|
17
31
|
/**
|
|
18
32
|
* Providers that serve the `decide` inference type, derived from each
|
|
19
|
-
* descriptor's `inferenceKinds
|
|
20
|
-
* provider, so it is not here.
|
|
33
|
+
* descriptor's `inferenceKinds` and sorted by `decideOrder`, lowest first. A
|
|
34
|
+
* provider that declares nothing is a text provider, so it is not here.
|
|
21
35
|
*/
|
|
22
36
|
export declare const DECISION_PROVIDERS: readonly ProviderDescriptor[];
|
|
23
37
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import { GoogleAIModels, OpenAIModels, AnthropicModels, VertexModels, OllamaModels, LiteLLMModels, NvidiaNimModels, OpenRouterModels, CohereModels, VoyageModels, TypeSafeModels,
|
|
2
|
+
import { GoogleAIModels, OpenAIModels, AnthropicModels, VertexModels, OllamaModels, LiteLLMModels, NvidiaNimModels, OpenRouterModels, CohereModels, VoyageModels, TypeSafeModels, XorModels, PerplexityDeciderModels, CloudflareClefModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, ReplicateModels, } from "../constants/enums.js";
|
|
3
3
|
import { API_KEY_FORMATS } from "../utils/providerConfig.js";
|
|
4
|
-
import { getCatalogJsonEntries, catalogCredentialsKey, catalogEnvVar, } from "../providers/catalog/loader.js";
|
|
4
|
+
import { getCatalogJsonEntries, getDecideCatalogEntries, catalogCredentialsKey, catalogEnvVar, } from "../providers/catalog/loader.js";
|
|
5
5
|
import { DEFAULT_INFERENCE_KINDS } from "../types/index.js";
|
|
6
6
|
/**
|
|
7
7
|
* Hand-maintained provider identity, credentials, defaults, and runtime
|
|
@@ -440,6 +440,7 @@ const HAND_DESCRIPTORS = [
|
|
|
440
440
|
// what keeps it out of every generation code path, rather than each of
|
|
441
441
|
// those having to special-case the provider name.
|
|
442
442
|
inferenceKinds: ["decide"],
|
|
443
|
+
decideOrder: 1,
|
|
443
444
|
// It emits no text, so it cannot call tools and cannot answer a
|
|
444
445
|
// "live-generate" health probe.
|
|
445
446
|
toolSupport: "none",
|
|
@@ -466,58 +467,13 @@ const HAND_DESCRIPTORS = [
|
|
|
466
467
|
},
|
|
467
468
|
setupUrl: "https://console.typesafe.ai/keys",
|
|
468
469
|
},
|
|
469
|
-
//
|
|
470
|
-
//
|
|
470
|
+
// Decision precedence is decideOrder, not position: typesafe 1, laya 2 (from
|
|
471
|
+
// catalog/laya.json), xor 3, perplexity-decider 4, cloudflare-clef 5.
|
|
471
472
|
// resolveDefaultDecisionProvider() returns the first configured
|
|
472
|
-
// DECISION_PROVIDERS entry
|
|
473
|
+
// DECISION_PROVIDERS entry in that order, so a host configured for several
|
|
473
474
|
// keeps Jev for every built-in consumer and reaches the others only by
|
|
474
|
-
// naming them.
|
|
475
|
-
//
|
|
476
|
-
{
|
|
477
|
-
name: AIProviderName.LAYA,
|
|
478
|
-
aliases: [],
|
|
479
|
-
credentialsKey: "laya",
|
|
480
|
-
envVars: {
|
|
481
|
-
apiKey: "LAYA_API_KEY",
|
|
482
|
-
baseURL: "LAYA_BASE_URL",
|
|
483
|
-
// Laya has no built-in endpoint (it is self-hosted or behind a proxy),
|
|
484
|
-
// so a key is useless without a base URL. Both are required for it to
|
|
485
|
-
// count as configured, from the environment or credentials.laya.
|
|
486
|
-
extraRequired: ["LAYA_BASE_URL"],
|
|
487
|
-
model: "LAYA_MODEL",
|
|
488
|
-
},
|
|
489
|
-
defaultModel: LayaModels.TYPED_DECISIONS,
|
|
490
|
-
// Serves only `decide`, like TypeSafe — the one declaration that keeps it
|
|
491
|
-
// out of every generation code path.
|
|
492
|
-
inferenceKinds: ["decide"],
|
|
493
|
-
toolSupport: "none",
|
|
494
|
-
localRuntime: false,
|
|
495
|
-
healthCheck: "env-only",
|
|
496
|
-
// Deliberately NO autoSelectPriority / autoSelectPreference /
|
|
497
|
-
// defaultHealthSweepPriority, for the same reason as TypeSafe above.
|
|
498
|
-
timeouts: { decideMs: 5000 },
|
|
499
|
-
// Laya's encoders cut the state off silently past their window (measured
|
|
500
|
-
// live: a 60,000-character state answered 200 on 1,024 tokens). 768 is
|
|
501
|
-
// the 1,024-token window minus the 256-token budget Laya reserves for a
|
|
502
|
-
// question and its options; 320 is the English checkpoint's 512 minus
|
|
503
|
-
// 192. `auto` may route to English, and an unlisted name (Laya's server
|
|
504
|
-
// accepts aliases such as `en`) could be any checkpoint, so both get 320.
|
|
505
|
-
// 64 is the question cap in Laya's own server. Non-ASCII rates were
|
|
506
|
-
// measured live: Chinese is ~1.4 tokens per character on the English
|
|
507
|
-
// tokenizer (typed-decisions, english) and ~0.56 on multilingual.
|
|
508
|
-
decisionLimits: {
|
|
509
|
-
maxStateTokens: 320,
|
|
510
|
-
maxQuestions: 64,
|
|
511
|
-
nonAsciiTokensPerChar: 1.5,
|
|
512
|
-
models: {
|
|
513
|
-
"typed-decisions": { maxStateTokens: 768 },
|
|
514
|
-
multilingual: { maxStateTokens: 768, nonAsciiTokensPerChar: 0.6 },
|
|
515
|
-
english: { maxStateTokens: 320 },
|
|
516
|
-
auto: { maxStateTokens: 320 },
|
|
517
|
-
},
|
|
518
|
-
},
|
|
519
|
-
setupUrl: "https://github.com/NandhaKishorM/laya",
|
|
520
|
-
},
|
|
475
|
+
// naming them. Renumbering silently changes which model routes, compacts
|
|
476
|
+
// and plans for every such host.
|
|
521
477
|
{
|
|
522
478
|
name: AIProviderName.XOR,
|
|
523
479
|
aliases: [],
|
|
@@ -535,6 +491,7 @@ const HAND_DESCRIPTORS = [
|
|
|
535
491
|
// Serves only `decide`, like TypeSafe and Laya — the one declaration that
|
|
536
492
|
// keeps it out of every generation code path.
|
|
537
493
|
inferenceKinds: ["decide"],
|
|
494
|
+
decideOrder: 3,
|
|
538
495
|
toolSupport: "none",
|
|
539
496
|
localRuntime: false,
|
|
540
497
|
healthCheck: "env-only",
|
|
@@ -579,6 +536,7 @@ const HAND_DESCRIPTORS = [
|
|
|
579
536
|
// declaration that keeps it out of every generation code path, and out of
|
|
580
537
|
// the way of the `perplexity` text provider.
|
|
581
538
|
inferenceKinds: ["decide"],
|
|
539
|
+
decideOrder: 4,
|
|
582
540
|
toolSupport: "none",
|
|
583
541
|
localRuntime: false,
|
|
584
542
|
healthCheck: "env-only",
|
|
@@ -646,6 +604,7 @@ const HAND_DESCRIPTORS = [
|
|
|
646
604
|
// declaration that keeps it out of every generation code path, and out of
|
|
647
605
|
// the way of the `cloudflare` text provider.
|
|
648
606
|
inferenceKinds: ["decide"],
|
|
607
|
+
decideOrder: 5,
|
|
649
608
|
toolSupport: "none",
|
|
650
609
|
localRuntime: false,
|
|
651
610
|
healthCheck: "env-only",
|
|
@@ -778,8 +737,48 @@ function buildCatalogDescriptor(entry) {
|
|
|
778
737
|
: {}),
|
|
779
738
|
};
|
|
780
739
|
}
|
|
740
|
+
/**
|
|
741
|
+
* Builds the ProviderDescriptor of a JSON `decide` provider. It serves only
|
|
742
|
+
* `decide`, so it declares no auto-select, preference or health-sweep rank:
|
|
743
|
+
* those feed generation fallback chains a text-less provider must never join.
|
|
744
|
+
*/
|
|
745
|
+
export function buildDecideDescriptor(entry) {
|
|
746
|
+
const fallbacks = entry.wire.apiKeyFallbackEnvVars?.length
|
|
747
|
+
? { fallbacks: [...entry.wire.apiKeyFallbackEnvVars] }
|
|
748
|
+
: {};
|
|
749
|
+
return {
|
|
750
|
+
name: entry.id,
|
|
751
|
+
aliases: entry.aliases,
|
|
752
|
+
credentialsKey: catalogCredentialsKey(entry),
|
|
753
|
+
envVars: {
|
|
754
|
+
apiKey: catalogEnvVar(entry, "apiKey"),
|
|
755
|
+
...fallbacks,
|
|
756
|
+
baseURL: catalogEnvVar(entry, "baseURL"),
|
|
757
|
+
// A key is useless without an endpoint when the provider has no built-in one.
|
|
758
|
+
...(entry.decide.baseURLRequired
|
|
759
|
+
? { extraRequired: [catalogEnvVar(entry, "baseURL")] }
|
|
760
|
+
: {}),
|
|
761
|
+
model: catalogEnvVar(entry, "model"),
|
|
762
|
+
},
|
|
763
|
+
defaultModel: entry.models.default,
|
|
764
|
+
inferenceKinds: ["decide"],
|
|
765
|
+
decideOrder: entry.decide.order,
|
|
766
|
+
toolSupport: "none",
|
|
767
|
+
localRuntime: false,
|
|
768
|
+
healthCheck: "env-only",
|
|
769
|
+
setupUrl: entry.setup.url,
|
|
770
|
+
...(entry.setup.apiKeyFormat
|
|
771
|
+
? { apiKeyFormatPattern: new RegExp(entry.setup.apiKeyFormat) }
|
|
772
|
+
: {}),
|
|
773
|
+
...(entry.timeouts ? { timeouts: { ...entry.timeouts } } : {}),
|
|
774
|
+
...(entry.decisionLimits ? { decisionLimits: entry.decisionLimits } : {}),
|
|
775
|
+
};
|
|
776
|
+
}
|
|
781
777
|
function buildCatalogDescriptors() {
|
|
782
|
-
return
|
|
778
|
+
return [
|
|
779
|
+
...getCatalogJsonEntries().map(buildCatalogDescriptor),
|
|
780
|
+
...getDecideCatalogEntries().map(buildDecideDescriptor),
|
|
781
|
+
];
|
|
783
782
|
}
|
|
784
783
|
/**
|
|
785
784
|
* Single source of truth for provider identity, credentials, defaults, and
|
|
@@ -801,12 +800,38 @@ export const PROVIDER_ALIAS_INDEX = new Map(PROVIDER_DESCRIPTORS.flatMap((d) =>
|
|
|
801
800
|
[d.name.toLowerCase(), d.name],
|
|
802
801
|
...d.aliases.map((alias) => [alias.toLowerCase(), d.name]),
|
|
803
802
|
]));
|
|
803
|
+
const servesDecide = (descriptor) => (descriptor.inferenceKinds ?? DEFAULT_INFERENCE_KINDS).includes("decide");
|
|
804
|
+
/**
|
|
805
|
+
* Throws unless every descriptor that serves `decide` has its own finite
|
|
806
|
+
* `decideOrder`. The order is the precedence of resolveDefaultDecisionProvider(),
|
|
807
|
+
* so a missing or repeated number would make that choice depend on array position.
|
|
808
|
+
*/
|
|
809
|
+
export function assertUniqueDecideOrder(descriptors) {
|
|
810
|
+
const owners = new Map();
|
|
811
|
+
for (const descriptor of descriptors.filter(servesDecide)) {
|
|
812
|
+
const order = descriptor.decideOrder;
|
|
813
|
+
if (order === undefined || !Number.isFinite(order)) {
|
|
814
|
+
throw new Error(`decision provider "${descriptor.name}" has no usable decideOrder`);
|
|
815
|
+
}
|
|
816
|
+
const clash = owners.get(order);
|
|
817
|
+
if (clash !== undefined) {
|
|
818
|
+
throw new Error(`decideOrder ${order} is used by both "${clash}" and "${descriptor.name}"`);
|
|
819
|
+
}
|
|
820
|
+
owners.set(order, descriptor.name);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
/** The descriptors that serve `decide`, lowest `decideOrder` first. */
|
|
824
|
+
export function orderDecisionProviders(descriptors) {
|
|
825
|
+
const rank = (d) => d.decideOrder ?? Number.MAX_SAFE_INTEGER;
|
|
826
|
+
return descriptors.filter(servesDecide).sort((a, b) => rank(a) - rank(b));
|
|
827
|
+
}
|
|
828
|
+
assertUniqueDecideOrder(PROVIDER_DESCRIPTORS);
|
|
804
829
|
/**
|
|
805
830
|
* Providers that serve the `decide` inference type, derived from each
|
|
806
|
-
* descriptor's `inferenceKinds
|
|
807
|
-
* provider, so it is not here.
|
|
831
|
+
* descriptor's `inferenceKinds` and sorted by `decideOrder`, lowest first. A
|
|
832
|
+
* provider that declares nothing is a text provider, so it is not here.
|
|
808
833
|
*/
|
|
809
|
-
export const DECISION_PROVIDERS = PROVIDER_DESCRIPTORS
|
|
834
|
+
export const DECISION_PROVIDERS = orderDecisionProviders(PROVIDER_DESCRIPTORS);
|
|
810
835
|
/**
|
|
811
836
|
* Whether a decision provider is fully configured: its key and every
|
|
812
837
|
* extraRequired variable are set, each either in the environment or in
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import type { ProviderRegistryOptions } from "../types/index.js";
|
|
1
|
+
import type { DecideCatalogJson, ProviderRegistryOptions } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Registers the config-driven `decide` providers described by catalog JSON
|
|
4
|
+
* (inferenceKinds ["decide"]). Each one is built by ConfiguredDecisionProvider,
|
|
5
|
+
* loaded lazily like every other provider; its descriptor declares
|
|
6
|
+
* inferenceKinds ["decide"], so nothing in the generation fallback chain can
|
|
7
|
+
* reach it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function registerDecideCatalogProviders(entries: readonly DecideCatalogJson[]): void;
|
|
2
10
|
/**
|
|
3
11
|
* Provider Registry - registers all providers with the factory
|
|
4
12
|
* This is where we migrate providers one by one to the new pattern
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
import { ProviderFactory } from "./providerFactory.js";
|
|
2
2
|
import { logger } from "../utils/logger.js";
|
|
3
|
-
import { AIProviderName, GoogleAIModels, OpenAIModels, AnthropicModels, VertexModels, OllamaModels, LiteLLMModels, NvidiaNimModels, OpenRouterModels, CohereModels, VoyageModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, TypeSafeModels,
|
|
3
|
+
import { AIProviderName, GoogleAIModels, OpenAIModels, AnthropicModels, VertexModels, OllamaModels, LiteLLMModels, NvidiaNimModels, OpenRouterModels, CohereModels, VoyageModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, TypeSafeModels, XorModels, PerplexityDeciderModels, CloudflareClefModels, ReplicateModels, } from "../constants/enums.js";
|
|
4
4
|
import { PROVIDER_DESCRIPTORS_BY_NAME } from "./providerDescriptors.js";
|
|
5
5
|
import { OPENAI_COMPAT_CATALOG } from "../providers/openaiCompatCatalog.js";
|
|
6
6
|
import { providerChoicesFor } from "./mediaHandlerCatalog.js";
|
|
7
|
+
import { catalogEnvVar, getDecideCatalogEntries, } from "../providers/catalog/loader.js";
|
|
8
|
+
/**
|
|
9
|
+
* Registers the config-driven `decide` providers described by catalog JSON
|
|
10
|
+
* (inferenceKinds ["decide"]). Each one is built by ConfiguredDecisionProvider,
|
|
11
|
+
* loaded lazily like every other provider; its descriptor declares
|
|
12
|
+
* inferenceKinds ["decide"], so nothing in the generation fallback chain can
|
|
13
|
+
* reach it.
|
|
14
|
+
*/
|
|
15
|
+
export function registerDecideCatalogProviders(entries) {
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
ProviderFactory.registerProvider(entry.id, async (modelName, _providerName, sdk, _region, credentials) => {
|
|
18
|
+
const { ConfiguredDecisionProvider } = await import("../providers/configuredDecision.js");
|
|
19
|
+
return new ConfiguredDecisionProvider(entry, modelName, sdk, credentials);
|
|
20
|
+
}, process.env[catalogEnvVar(entry, "model")] || entry.models.default, [...entry.aliases], PROVIDER_DESCRIPTORS_BY_NAME.get(entry.id));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
7
23
|
/**
|
|
8
24
|
* Provider Registry - registers all providers with the factory
|
|
9
25
|
* This is where we migrate providers one by one to the new pattern
|
|
@@ -234,14 +250,6 @@ export class ProviderRegistry {
|
|
|
234
250
|
const { TypeSafeProvider } = await import("../providers/typesafe.js");
|
|
235
251
|
return new TypeSafeProvider(modelName, sdk, undefined, typesafeCreds);
|
|
236
252
|
}, process.env.TYPESAFE_MODEL || TypeSafeModels.JEV_LATEST, ["jev", "typesafe-ai"], PROVIDER_DESCRIPTORS_BY_NAME.get(AIProviderName.TYPESAFE));
|
|
237
|
-
// Register Laya — the second `decide` provider, reached at whatever base
|
|
238
|
-
// URL its config names. Its descriptor declares inferenceKinds:
|
|
239
|
-
// ["decide"], so nothing in the generation fallback chain can reach it.
|
|
240
|
-
ProviderFactory.registerProvider(AIProviderName.LAYA, async (modelName, _providerName, sdk, _region, credentials) => {
|
|
241
|
-
const layaCreds = credentials;
|
|
242
|
-
const { LayaProvider } = await import("../providers/laya.js");
|
|
243
|
-
return new LayaProvider(modelName, sdk, undefined, layaCreds);
|
|
244
|
-
}, process.env.LAYA_MODEL || LayaModels.TYPED_DECISIONS, [], PROVIDER_DESCRIPTORS_BY_NAME.get(AIProviderName.LAYA));
|
|
245
253
|
// Register XOR — the third `decide` provider, reached at whatever base
|
|
246
254
|
// URL its config names. Its descriptor declares inferenceKinds:
|
|
247
255
|
// ["decide"], so nothing in the generation fallback chain can reach it.
|
|
@@ -269,6 +277,8 @@ export class ProviderRegistry {
|
|
|
269
277
|
const { CloudflareClefProvider } = await import("../providers/cloudflareClef.js");
|
|
270
278
|
return new CloudflareClefProvider(modelName, sdk, undefined, cloudflareClefCreds);
|
|
271
279
|
}, process.env.CLOUDFLARE_CLEF_MODEL || CloudflareClefModels.CLEF, [], PROVIDER_DESCRIPTORS_BY_NAME.get(AIProviderName.CLOUDFLARE_CLEF));
|
|
280
|
+
// The decide providers described by catalog JSON (laya.json and later).
|
|
281
|
+
registerDecideCatalogProviders(getDecideCatalogEntries());
|
|
272
282
|
logger.debug("All AI providers registered successfully");
|
|
273
283
|
// ===== MEDIA HANDLER REGISTRATION =====
|
|
274
284
|
// Single registration path (Task 11): each ecosystem barrel (voice,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PROVIDER_MAX_TOKENS } from "../core/constants.js";
|
|
2
|
-
import { getCatalogJsonEntries } from "../providers/catalog/loader.js";
|
|
2
|
+
import { getCatalogJsonEntries, getDecideCatalogEntries, } from "../providers/catalog/loader.js";
|
|
3
3
|
import { anthropicManifest } from "./manifests/anthropic.js";
|
|
4
4
|
import { openaiManifest } from "./manifests/openai.js";
|
|
5
5
|
import { azureManifest } from "./manifests/azure.js";
|
|
@@ -20,7 +20,6 @@ import { llamacppManifest } from "./manifests/llamacpp.js";
|
|
|
20
20
|
import { xaiManifest } from "./manifests/xai.js";
|
|
21
21
|
import { groqManifest } from "./manifests/groq.js";
|
|
22
22
|
import { typesafeManifest } from "./manifests/typesafe.js";
|
|
23
|
-
import { layaManifest } from "./manifests/laya.js";
|
|
24
23
|
import { xorManifest } from "./manifests/xor.js";
|
|
25
24
|
import { perplexityDeciderManifest } from "./manifests/perplexityDecider.js";
|
|
26
25
|
import { cloudflareClefManifest } from "./manifests/cloudflareClef.js";
|
|
@@ -94,6 +93,44 @@ const catalogManifest = (id) => {
|
|
|
94
93
|
}
|
|
95
94
|
return buildCatalogManifest(entry);
|
|
96
95
|
};
|
|
96
|
+
/**
|
|
97
|
+
* Builds a manifest for a decide catalog provider from its catalog entry.
|
|
98
|
+
*
|
|
99
|
+
* A decide model emits no text, but the manifest type requires a
|
|
100
|
+
* `maxOutputTokens`, so the figure a decide entry declares is carried over
|
|
101
|
+
* as is. A model that omits `contextWindow` or `maxOutputTokens` takes the
|
|
102
|
+
* default model's, and `_default` is the default model's own row.
|
|
103
|
+
* `functionCalling` is always false: a decide model has no tool calling.
|
|
104
|
+
* No row gets a `displayName`: the decide catalog has no field for one and
|
|
105
|
+
* no reader shows a decide model's manifest name.
|
|
106
|
+
*/
|
|
107
|
+
function buildDecideManifest(entry) {
|
|
108
|
+
const base = entry.models.catalog[entry.models.default];
|
|
109
|
+
if (base === undefined ||
|
|
110
|
+
base.contextWindow === undefined ||
|
|
111
|
+
base.maxOutputTokens === undefined) {
|
|
112
|
+
throw new Error(`Decide catalog entry "${entry.id}": models.default needs contextWindow and maxOutputTokens for its manifest`);
|
|
113
|
+
}
|
|
114
|
+
const baseWindow = base.contextWindow;
|
|
115
|
+
const baseMaxOutput = base.maxOutputTokens;
|
|
116
|
+
const toEntry = (spec) => ({
|
|
117
|
+
aliases: [],
|
|
118
|
+
contextWindow: spec.contextWindow ?? baseWindow,
|
|
119
|
+
maxOutputTokens: spec.maxOutputTokens ?? baseMaxOutput,
|
|
120
|
+
vision: spec.vision,
|
|
121
|
+
functionCalling: false,
|
|
122
|
+
});
|
|
123
|
+
return {
|
|
124
|
+
defaultContextWindow: baseWindow,
|
|
125
|
+
models: {
|
|
126
|
+
_default: toEntry(base),
|
|
127
|
+
...Object.fromEntries(Object.entries(entry.models.catalog).map(([modelId, spec]) => [
|
|
128
|
+
modelId,
|
|
129
|
+
toEntry(spec),
|
|
130
|
+
])),
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
97
134
|
/**
|
|
98
135
|
* Every provider's model manifest, keyed by the exact AIProviderName enum
|
|
99
136
|
* value (kebab-case) — e.g. "google-ai", "nvidia-nim". Manifests are pure
|
|
@@ -122,7 +159,7 @@ export const MANIFEST_REGISTRY = {
|
|
|
122
159
|
xai: xaiManifest,
|
|
123
160
|
groq: groqManifest,
|
|
124
161
|
typesafe: typesafeManifest,
|
|
125
|
-
|
|
162
|
+
...Object.fromEntries(getDecideCatalogEntries().map((e) => [e.id, buildDecideManifest(e)])),
|
|
126
163
|
xor: xorManifest,
|
|
127
164
|
"perplexity-decider": perplexityDeciderManifest,
|
|
128
165
|
"cloudflare-clef": cloudflareClefManifest,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
import type { ProviderCatalogJson } from "../../types/index.js";
|
|
1
|
+
import type { DecideCatalogJson, ProviderCatalogJson } from "../../types/index.js";
|
|
2
2
|
export declare const CATALOG_JSON_ENTRIES: ProviderCatalogJson[];
|
|
3
3
|
export declare const CATALOG_PROVIDER_IDS: readonly ["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", "lemonfox-ai", "lilac", "llmtech", "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", "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", "z-ai"];
|
|
4
|
+
export declare const DECIDE_CATALOG_JSON_ENTRIES: DecideCatalogJson[];
|
|
5
|
+
export declare const DECIDE_CATALOG_PROVIDER_IDS: readonly ["laya"];
|
|
@@ -40,6 +40,7 @@ import incoJson from "./inco.json" with { type: "json" };
|
|
|
40
40
|
import inferenceNetJson from "./inference-net.json" with { type: "json" };
|
|
41
41
|
import ioIntelligenceJson from "./io-intelligence.json" with { type: "json" };
|
|
42
42
|
import koscomputeJson from "./koscompute.json" with { type: "json" };
|
|
43
|
+
import layaJson from "./laya.json" with { type: "json" };
|
|
43
44
|
import lemonfoxAiJson from "./lemonfox-ai.json" with { type: "json" };
|
|
44
45
|
import lilacJson from "./lilac.json" with { type: "json" };
|
|
45
46
|
import llmtechJson from "./llmtech.json" with { type: "json" };
|
|
@@ -84,6 +85,14 @@ import waferJson from "./wafer.json" with { type: "json" };
|
|
|
84
85
|
import wandbInferenceJson from "./wandb-inference.json" with { type: "json" };
|
|
85
86
|
import xaiJson from "./xai.json" with { type: "json" };
|
|
86
87
|
import zAiJson from "./z-ai.json" with { type: "json" };
|
|
88
|
+
import { isDecideCatalogEntry, parseCatalogEntry } from "./schema.js";
|
|
89
|
+
const asDecideEntry = (raw) => {
|
|
90
|
+
const entry = parseCatalogEntry(raw);
|
|
91
|
+
if (!isDecideCatalogEntry(entry)) {
|
|
92
|
+
throw new Error("a catalog file listed as a decide entry parsed as a chat entry");
|
|
93
|
+
}
|
|
94
|
+
return entry;
|
|
95
|
+
};
|
|
87
96
|
export const CATALOG_JSON_ENTRIES = [
|
|
88
97
|
a2agentJson,
|
|
89
98
|
abliterationJson,
|
|
@@ -256,3 +265,5 @@ export const CATALOG_PROVIDER_IDS = [
|
|
|
256
265
|
"xai",
|
|
257
266
|
"z-ai",
|
|
258
267
|
];
|
|
268
|
+
export const DECIDE_CATALOG_JSON_ENTRIES = [layaJson].map(asDecideEntry);
|
|
269
|
+
export const DECIDE_CATALOG_PROVIDER_IDS = ["laya"];
|