@juspay/neurolink 12.23.2 → 12.24.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 +367 -367
- package/dist/constants/enums.d.ts +61 -69
- package/dist/constants/enums.js +63 -96
- package/dist/core/nativeGenerateLoop.js +11 -1
- package/dist/factories/providerDescriptors.d.ts +1 -1
- package/dist/factories/providerDescriptors.js +50 -83
- package/dist/factories/providerRegistry.js +9 -16
- package/dist/models/manifestRegistry.js +11 -2
- package/dist/providers/anthropic/client.js +7 -1
- package/dist/providers/catalog/deepseek.json +84 -0
- package/dist/providers/catalog/huggingface.json +405 -0
- package/dist/providers/catalog/index.generated.d.ts +1 -1
- package/dist/providers/catalog/index.generated.js +6 -0
- package/dist/providers/catalog/loader.js +20 -5
- package/dist/providers/catalog/mistral.json +8 -3
- package/dist/providers/catalog/provider-catalog.schema.json +31 -1
- package/dist/providers/catalog/schema.d.ts +8 -1
- package/dist/providers/catalog/schema.js +9 -1
- package/dist/providers/configuredOpenAICompat.d.ts +14 -5
- package/dist/providers/configuredOpenAICompat.js +19 -4
- package/dist/providers/embeddingResponseParsing.d.ts +1 -0
- package/dist/providers/embeddingResponseParsing.js +47 -0
- package/dist/providers/ideogram.js +7 -1
- package/dist/providers/jina.js +6 -15
- package/dist/providers/llamaCpp.js +4 -15
- package/dist/providers/lmStudio.js +4 -15
- package/dist/providers/localRuntimeOpenAICompat.d.ts +16 -0
- package/dist/providers/localRuntimeOpenAICompat.js +26 -0
- package/dist/providers/ollama/client.js +3 -9
- package/dist/providers/openaiChatCompletionsBase.d.ts +3 -3
- package/dist/providers/openaiChatCompletionsBase.js +20 -5
- package/dist/providers/openaiCompatCatalog.d.ts +16 -12
- package/dist/providers/openaiCompatCatalog.js +16 -12
- package/dist/providers/voyage.js +5 -18
- package/dist/types/providerCatalog.d.ts +46 -1
- package/dist/types/providerCatalog.generated.d.ts +2 -2
- package/dist/types/providers.d.ts +12 -8
- package/dist/utils/modelChoices.d.ts +2 -2
- package/dist/utils/modelChoices.js +10 -38
- package/dist/utils/sizeGuard.d.ts +8 -5
- package/dist/utils/sizeGuard.js +32 -9
- package/docs-site/static/search-index.json +1 -1
- package/package.json +2 -1
- package/dist/providers/deepseek.d.ts +0 -47
- package/dist/providers/deepseek.js +0 -120
- package/dist/providers/huggingFace/client.d.ts +0 -54
- package/dist/providers/huggingFace/client.js +0 -120
- package/dist/providers/huggingFace/index.d.ts +0 -1
- package/dist/providers/huggingFace/index.js +0 -1
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
import type { OpenAICompatCatalogEntry } from "../types/index.js";
|
|
2
2
|
/**
|
|
3
|
-
* Config-driven catalog of the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
3
|
+
* Config-driven catalog of the 10 OpenAI-compatible providers whose only
|
|
4
|
+
* differences from each other are expressible as named, closed catalog
|
|
5
|
+
* quirks (messageContentFormat, timeoutErrorClass, responseFormatDowngrade)
|
|
6
|
+
* rather than real code. Each entry fully replaces what used to be a
|
|
7
|
+
* hand-written OpenAIChatCompletionsProvider subclass — see
|
|
8
|
+
* ConfiguredOpenAICompatProvider for the class that reads these entries,
|
|
9
|
+
* and providerRegistry.ts for the registration loop that consumes this
|
|
10
|
+
* array.
|
|
8
11
|
*
|
|
9
12
|
* The entries themselves are derived from the JSON catalog
|
|
10
13
|
* (src/lib/providers/catalog/<id>.json) via buildCatalogEntries() — that
|
|
11
|
-
* JSON is now the single source of truth for these
|
|
14
|
+
* JSON is now the single source of truth for these 10 providers' identity,
|
|
12
15
|
* models, error rules and wire config. See
|
|
13
16
|
* src/lib/providers/catalog/loader.ts for the derivation logic and
|
|
14
17
|
* docs/superpowers/plans/2026-08-28-provider-json-catalog-spec.md for the
|
|
15
18
|
* authoring format.
|
|
16
19
|
*
|
|
17
|
-
* To add a new
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* (getProviderName/getDefaultModel/formatProviderError)
|
|
22
|
-
* dedicated subclass instead (see
|
|
20
|
+
* To add a new OpenAI-compatible provider: add one JSON file under
|
|
21
|
+
* src/lib/providers/catalog/ (see provider-catalog.schema.json) and run
|
|
22
|
+
* `pnpm run codegen:catalog`. Do NOT add a provider here if it needs a real
|
|
23
|
+
* hook override beyond the 3 mandatory ones
|
|
24
|
+
* (getProviderName/getDefaultModel/formatProviderError) and the named
|
|
25
|
+
* catalog quirks above — write a dedicated subclass instead (see
|
|
26
|
+
* azureOpenai.ts).
|
|
23
27
|
*/
|
|
24
28
|
export declare const OPENAI_COMPAT_CATALOG: readonly OpenAICompatCatalogEntry[];
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
import { buildCatalogEntries } from "./catalog/loader.js";
|
|
2
2
|
/**
|
|
3
|
-
* Config-driven catalog of the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
3
|
+
* Config-driven catalog of the 10 OpenAI-compatible providers whose only
|
|
4
|
+
* differences from each other are expressible as named, closed catalog
|
|
5
|
+
* quirks (messageContentFormat, timeoutErrorClass, responseFormatDowngrade)
|
|
6
|
+
* rather than real code. Each entry fully replaces what used to be a
|
|
7
|
+
* hand-written OpenAIChatCompletionsProvider subclass — see
|
|
8
|
+
* ConfiguredOpenAICompatProvider for the class that reads these entries,
|
|
9
|
+
* and providerRegistry.ts for the registration loop that consumes this
|
|
10
|
+
* array.
|
|
8
11
|
*
|
|
9
12
|
* The entries themselves are derived from the JSON catalog
|
|
10
13
|
* (src/lib/providers/catalog/<id>.json) via buildCatalogEntries() — that
|
|
11
|
-
* JSON is now the single source of truth for these
|
|
14
|
+
* JSON is now the single source of truth for these 10 providers' identity,
|
|
12
15
|
* models, error rules and wire config. See
|
|
13
16
|
* src/lib/providers/catalog/loader.ts for the derivation logic and
|
|
14
17
|
* docs/superpowers/plans/2026-08-28-provider-json-catalog-spec.md for the
|
|
15
18
|
* authoring format.
|
|
16
19
|
*
|
|
17
|
-
* To add a new
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* (getProviderName/getDefaultModel/formatProviderError)
|
|
22
|
-
* dedicated subclass instead (see
|
|
20
|
+
* To add a new OpenAI-compatible provider: add one JSON file under
|
|
21
|
+
* src/lib/providers/catalog/ (see provider-catalog.schema.json) and run
|
|
22
|
+
* `pnpm run codegen:catalog`. Do NOT add a provider here if it needs a real
|
|
23
|
+
* hook override beyond the 3 mandatory ones
|
|
24
|
+
* (getProviderName/getDefaultModel/formatProviderError) and the named
|
|
25
|
+
* catalog quirks above — write a dedicated subclass instead (see
|
|
26
|
+
* azureOpenai.ts).
|
|
23
27
|
*/
|
|
24
28
|
export const OPENAI_COMPAT_CATALOG = buildCatalogEntries();
|
package/dist/providers/voyage.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { VoyageModels } from "../constants/enums.js";
|
|
2
2
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
3
3
|
import { isNeuroLink } from "../neurolink.js";
|
|
4
|
+
import { parseIndexedEmbeddingsResponse } from "./embeddingResponseParsing.js";
|
|
4
5
|
import { createProxyFetch } from "../proxy/proxyFetch.js";
|
|
5
6
|
import { AuthenticationError, InvalidModelError, ProviderError, RateLimitError, } from "../types/index.js";
|
|
6
7
|
import { withTimeout } from "../utils/errorHandling.js";
|
|
@@ -146,24 +147,10 @@ export class VoyageProvider extends BaseProvider {
|
|
|
146
147
|
throw this.formatProviderError(new Error(`Voyage embeddings failed: ${response.status} — ${text}`));
|
|
147
148
|
}
|
|
148
149
|
const data = (await response.json());
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
// Voyage may return partial results in edge-case error scenarios.
|
|
154
|
-
if (data.data.length !== inputs.length) {
|
|
155
|
-
throw new ProviderError(`Voyage embeddings response count mismatch: expected ${inputs.length}, got ${data.data.length}`, "voyage");
|
|
156
|
-
}
|
|
157
|
-
// Sort by index (Voyage returns out-of-order under some conditions)
|
|
158
|
-
// and drop to a flat number[][] result.
|
|
159
|
-
const sorted = data.data.slice().sort((a, b) => a.index - b.index);
|
|
160
|
-
// Verify that index coverage is complete (0 … n-1).
|
|
161
|
-
for (let i = 0; i < sorted.length; i++) {
|
|
162
|
-
if (sorted[i].index !== i) {
|
|
163
|
-
throw new ProviderError(`Voyage embeddings response has unexpected index ordering: position ${i} has index ${sorted[i].index}`, "voyage");
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
return sorted.map((d) => d.embedding);
|
|
150
|
+
// Sorts by index (Voyage returns out-of-order under some conditions) and
|
|
151
|
+
// verifies complete 0..n-1 coverage (Voyage may return partial results
|
|
152
|
+
// in edge-case error scenarios).
|
|
153
|
+
return parseIndexedEmbeddingsResponse(data, inputs.length, "Voyage", (message) => new ProviderError(message, "voyage"));
|
|
167
154
|
}
|
|
168
155
|
async validateConfiguration() {
|
|
169
156
|
return typeof this.apiKey === "string" && this.apiKey.trim().length > 0;
|
|
@@ -10,6 +10,18 @@ export type CatalogPricingPerMTok = {
|
|
|
10
10
|
cachedInput?: number;
|
|
11
11
|
};
|
|
12
12
|
export type CatalogModelStatus = "production" | "preview" | "retired";
|
|
13
|
+
/**
|
|
14
|
+
* Descriptor-only per-provider turn-budget override — mirrors
|
|
15
|
+
* ProviderDescriptor.timeouts field-for-field (src/lib/types/providers.ts).
|
|
16
|
+
* Consumed only by buildCatalogDescriptor() (providerDescriptors.ts), never
|
|
17
|
+
* by the OpenAI-compat runtime path (loader.ts's buildCatalogEntries()).
|
|
18
|
+
* Optional and absent for every catalog provider except mistral, whose
|
|
19
|
+
* value preserves its pre-migration hand-typed descriptor exactly.
|
|
20
|
+
*/
|
|
21
|
+
export type CatalogTimeouts = {
|
|
22
|
+
generateMs?: number;
|
|
23
|
+
streamMs?: number;
|
|
24
|
+
};
|
|
13
25
|
export type CatalogModelSpec = {
|
|
14
26
|
contextWindow?: number;
|
|
15
27
|
maxOutputTokens?: number;
|
|
@@ -34,6 +46,11 @@ export type CatalogWire = {
|
|
|
34
46
|
baseURL?: string;
|
|
35
47
|
model?: string;
|
|
36
48
|
};
|
|
49
|
+
/** Additional env vars validateApiKey() tries, in order, when the primary
|
|
50
|
+
* apiKeyEnvVar is unset (e.g. HuggingFace's HF_TOKEN alongside
|
|
51
|
+
* HUGGINGFACE_API_KEY). Consumed by buildCatalogConfigOptions() via
|
|
52
|
+
* ProviderConfigOptions.fallbackEnvVars. */
|
|
53
|
+
apiKeyFallbackEnvVars?: string[];
|
|
37
54
|
};
|
|
38
55
|
export type CatalogErrorRuleClass = "authentication" | "rate-limit" | "invalid-model" | "network" | "provider";
|
|
39
56
|
export type CatalogErrorRuleJson = {
|
|
@@ -51,6 +68,11 @@ export type CatalogQuirks = {
|
|
|
51
68
|
* ConfiguredOpenAICompatProvider so tool round-trips work. */
|
|
52
69
|
messageContentFormat?: "string";
|
|
53
70
|
registryDefaultIgnoresModelEnvVar?: boolean;
|
|
71
|
+
/** Vendor rejects `response_format: { type: "json_schema" }` outright but
|
|
72
|
+
* accepts `{ type: "json_object" }`. Normalized by
|
|
73
|
+
* ConfiguredOpenAICompatProvider so `generate({ schema })` keeps working
|
|
74
|
+
* (mirrors the pre-catalog `supportsStructuredOutputs: false` behavior). */
|
|
75
|
+
responseFormatDowngrade?: "json-schema-to-json-object";
|
|
54
76
|
};
|
|
55
77
|
export type CatalogBillingPolicy = "free-tier" | "free-with-card" | "no-free-tier";
|
|
56
78
|
export type CatalogSetup = {
|
|
@@ -85,7 +107,14 @@ export type CatalogEvidence = {
|
|
|
85
107
|
export type CatalogCapabilities = {
|
|
86
108
|
text: boolean;
|
|
87
109
|
streaming: boolean;
|
|
88
|
-
|
|
110
|
+
/** "model-dependent" when tool support varies per served model and the
|
|
111
|
+
* vendor doesn't reject `tools` for unsupported ones (the model just
|
|
112
|
+
* never emits tool_calls) — e.g. HuggingFace's router. Maps to
|
|
113
|
+
* ProviderDescriptor.toolSupport's own "model-dependent" member and
|
|
114
|
+
* leaves OpenAICompatCatalogEntry.supportsTools unset so
|
|
115
|
+
* ConfiguredOpenAICompatProvider falls through to the model-registry
|
|
116
|
+
* default, exactly like an entry that never set supportsTools at all. */
|
|
117
|
+
tools: boolean | "model-dependent";
|
|
89
118
|
toolsWithStreaming: boolean;
|
|
90
119
|
structuredOutput: boolean;
|
|
91
120
|
structuredOutputWithTools: boolean;
|
|
@@ -150,6 +179,22 @@ export type ProviderCatalogJson = {
|
|
|
150
179
|
capabilities: CatalogCapabilities;
|
|
151
180
|
errorRules: CatalogErrorRuleJson[];
|
|
152
181
|
quirks?: CatalogQuirks;
|
|
182
|
+
/**
|
|
183
|
+
* Descriptor-only generate/stream turn-budget override — see
|
|
184
|
+
* CatalogTimeouts. Absent = buildCatalogDescriptor() omits
|
|
185
|
+
* ProviderDescriptor.timeouts entirely, matching every catalog provider's
|
|
186
|
+
* behavior before this field existed.
|
|
187
|
+
*/
|
|
188
|
+
timeouts?: CatalogTimeouts;
|
|
189
|
+
/**
|
|
190
|
+
* Descriptor-only ascending auto-select priority override — mirrors
|
|
191
|
+
* ProviderDescriptor.autoSelectPriority field-for-field (lower = tried
|
|
192
|
+
* first in getBestProvider()'s fallback chain). Absent = not part of the
|
|
193
|
+
* auto-select chain, matching every catalog provider's behavior before
|
|
194
|
+
* this field existed (only mistral sets it today, preserving its
|
|
195
|
+
* pre-migration hand-typed value).
|
|
196
|
+
*/
|
|
197
|
+
autoSelectPriority?: number;
|
|
153
198
|
setup: CatalogSetup;
|
|
154
199
|
evidence: CatalogEvidence;
|
|
155
200
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type CatalogProviderName = "api-route" | "baseten" | "cerebras" | "cloudflare" | "fireworks" | "friendli" | "gmicloud" | "groq" | "inception-labs" | "io-intelligence" | "mancer" | "mistral" | "perplexity" | "sambanova" | "together-ai" | "upstage" | "xai";
|
|
2
|
-
export type CatalogCredentialKey = "apiRoute" | "baseten" | "cerebras" | "cloudflare" | "fireworks" | "friendli" | "gmicloud" | "groq" | "inceptionLabs" | "ioIntelligence" | "mancer" | "mistral" | "perplexity" | "sambanova" | "together" | "upstage" | "xai";
|
|
1
|
+
export type CatalogProviderName = "api-route" | "baseten" | "cerebras" | "cloudflare" | "deepseek" | "fireworks" | "friendli" | "gmicloud" | "groq" | "huggingface" | "inception-labs" | "io-intelligence" | "mancer" | "mistral" | "perplexity" | "sambanova" | "together-ai" | "upstage" | "xai";
|
|
2
|
+
export type CatalogCredentialKey = "apiRoute" | "baseten" | "cerebras" | "cloudflare" | "deepseek" | "fireworks" | "friendli" | "gmicloud" | "groq" | "huggingFace" | "inceptionLabs" | "ioIntelligence" | "mancer" | "mistral" | "perplexity" | "sambanova" | "together" | "upstage" | "xai";
|
|
@@ -143,10 +143,6 @@ export type NeurolinkCredentials = {
|
|
|
143
143
|
apiVersion?: string;
|
|
144
144
|
useMaxCompletionTokens?: boolean;
|
|
145
145
|
};
|
|
146
|
-
huggingFace?: {
|
|
147
|
-
apiKey?: string;
|
|
148
|
-
baseURL?: string;
|
|
149
|
-
};
|
|
150
146
|
openrouter?: {
|
|
151
147
|
apiKey?: string;
|
|
152
148
|
baseURL?: string;
|
|
@@ -163,10 +159,6 @@ export type NeurolinkCredentials = {
|
|
|
163
159
|
baseURL?: string;
|
|
164
160
|
apiKey?: string;
|
|
165
161
|
};
|
|
166
|
-
deepseek?: {
|
|
167
|
-
apiKey?: string;
|
|
168
|
-
baseURL?: string;
|
|
169
|
-
};
|
|
170
162
|
nvidiaNim?: {
|
|
171
163
|
apiKey?: string;
|
|
172
164
|
baseURL?: string;
|
|
@@ -196,6 +188,10 @@ export type NeurolinkCredentials = {
|
|
|
196
188
|
baseURL?: string;
|
|
197
189
|
accountId?: string;
|
|
198
190
|
};
|
|
191
|
+
deepseek?: {
|
|
192
|
+
apiKey?: string;
|
|
193
|
+
baseURL?: string;
|
|
194
|
+
};
|
|
199
195
|
fireworks?: {
|
|
200
196
|
apiKey?: string;
|
|
201
197
|
baseURL?: string;
|
|
@@ -212,6 +208,10 @@ export type NeurolinkCredentials = {
|
|
|
212
208
|
apiKey?: string;
|
|
213
209
|
baseURL?: string;
|
|
214
210
|
};
|
|
211
|
+
huggingFace?: {
|
|
212
|
+
apiKey?: string;
|
|
213
|
+
baseURL?: string;
|
|
214
|
+
};
|
|
215
215
|
inceptionLabs?: {
|
|
216
216
|
apiKey?: string;
|
|
217
217
|
baseURL?: string;
|
|
@@ -771,6 +771,10 @@ export type OpenAICompatCatalogEntry = {
|
|
|
771
771
|
/** See CatalogQuirks.messageContentFormat — a vendor that accepts
|
|
772
772
|
* `messages[].content` only as a plain string. */
|
|
773
773
|
messageContentFormat?: "string";
|
|
774
|
+
/** See CatalogQuirks.responseFormatDowngrade — a vendor that rejects
|
|
775
|
+
* `response_format: { type: "json_schema" }` but accepts
|
|
776
|
+
* `{ type: "json_object" }`. */
|
|
777
|
+
responseFormatDowngrade?: "json-schema-to-json-object";
|
|
774
778
|
};
|
|
775
779
|
/** The subset of OpenAICompatCatalogEntry that resolveOpenAICompatConfig()
|
|
776
780
|
* needs — lets call sites pass a minimal object without the full catalog
|
|
@@ -7,9 +7,9 @@ import type { CatalogProviderName, ModelChoice } from "../types/index.js";
|
|
|
7
7
|
/**
|
|
8
8
|
* Default models per provider (first choice/recommended).
|
|
9
9
|
*
|
|
10
|
-
* Covers every provider EXCEPT the
|
|
10
|
+
* Covers every provider EXCEPT the 11 JSON-catalog providers — those default
|
|
11
11
|
* models come from `models.default` in the catalog JSON, read directly by
|
|
12
|
-
* `getDefaultModel()` below. (Two of the
|
|
12
|
+
* `getDefaultModel()` below. (Two of the 11 — cerebras, sambanova — never had
|
|
13
13
|
* a hand entry here at all; `getDefaultModel()` now resolves them too.)
|
|
14
14
|
*
|
|
15
15
|
* AUTO is also excluded — it never had an entry here either (matches
|
|
@@ -2,10 +2,10 @@
|
|
|
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,
|
|
5
|
+
import { AIProviderName, OpenAIModels, AnthropicModels, GoogleAIModels, BedrockModels, VertexModels, OllamaModels, AzureOpenAIModels, LiteLLMModels, SageMakerModels, OpenRouterModels, NvidiaNimModels, CohereModels, VoyageModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, TypeSafeModels, ReplicateModels, } from "../constants/enums.js";
|
|
6
6
|
import { getCatalogJsonEntries } from "../providers/catalog/loader.js";
|
|
7
7
|
/**
|
|
8
|
-
* Looks up the JSON catalog entry for a provider, if it is one of the
|
|
8
|
+
* Looks up the JSON catalog entry for a provider, if it is one of the 11
|
|
9
9
|
* JSON-catalog providers. Used to short-circuit the hand tables below so a
|
|
10
10
|
* catalog provider's models are always sourced from its catalog JSON, never
|
|
11
11
|
* from stale hand-written duplicates.
|
|
@@ -36,11 +36,11 @@ function catalogTopModels(entry) {
|
|
|
36
36
|
* Top models per provider with descriptions for CLI prompts
|
|
37
37
|
* These are curated lists of the most commonly used/recommended models
|
|
38
38
|
*
|
|
39
|
-
* Covers every provider EXCEPT the
|
|
40
|
-
* cloudflare, fireworks, groq, mistral, perplexity,
|
|
41
|
-
* xai) — their entries are derived from
|
|
42
|
-
* `catalogTopModels()` and merged in at
|
|
43
|
-
* never hand-duplicated here.
|
|
39
|
+
* Covers every provider EXCEPT the 11 JSON-catalog providers (cerebras,
|
|
40
|
+
* cloudflare, deepseek, fireworks, groq, huggingface, mistral, perplexity,
|
|
41
|
+
* sambanova, together-ai, xai) — their entries are derived from
|
|
42
|
+
* `models.catalog[*].description` by `catalogTopModels()` and merged in at
|
|
43
|
+
* the accessor-function level below, never hand-duplicated here.
|
|
44
44
|
*/
|
|
45
45
|
const TOP_MODELS_CONFIG = {
|
|
46
46
|
[AIProviderName.OPENAI]: [
|
|
@@ -194,23 +194,6 @@ const TOP_MODELS_CONFIG = {
|
|
|
194
194
|
description: "Vertex via LiteLLM",
|
|
195
195
|
},
|
|
196
196
|
],
|
|
197
|
-
[AIProviderName.HUGGINGFACE]: [
|
|
198
|
-
{
|
|
199
|
-
model: HuggingFaceModels.LLAMA_3_3_70B_INSTRUCT,
|
|
200
|
-
description: "Recommended - Latest Llama",
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
model: HuggingFaceModels.MISTRAL_LARGE_3_675B,
|
|
204
|
-
description: "Mistral Large",
|
|
205
|
-
},
|
|
206
|
-
{ model: HuggingFaceModels.DEEPSEEK_R1, description: "Advanced reasoning" },
|
|
207
|
-
{
|
|
208
|
-
model: HuggingFaceModels.QWEN_2_5_72B_INSTRUCT,
|
|
209
|
-
description: "Qwen flagship",
|
|
210
|
-
},
|
|
211
|
-
{ model: HuggingFaceModels.PHI_4, description: "Microsoft Phi-4" },
|
|
212
|
-
{ model: HuggingFaceModels.GEMMA_3_27B_IT, description: "Google Gemma 3" },
|
|
213
|
-
],
|
|
214
197
|
[AIProviderName.SAGEMAKER]: [
|
|
215
198
|
{
|
|
216
199
|
model: SageMakerModels.LLAMA_4_MAVERICK_17B_128E,
|
|
@@ -245,13 +228,6 @@ const TOP_MODELS_CONFIG = {
|
|
|
245
228
|
{ model: "gpt-4-turbo", description: "Turbo compatible model" },
|
|
246
229
|
{ model: "gpt-3.5-turbo", description: "Legacy compatible model" },
|
|
247
230
|
],
|
|
248
|
-
[AIProviderName.DEEPSEEK]: [
|
|
249
|
-
{ model: "deepseek-chat", description: "DeepSeek-V3 general chat" },
|
|
250
|
-
{
|
|
251
|
-
model: "deepseek-reasoner",
|
|
252
|
-
description: "DeepSeek-R1 reasoning (slower, deeper)",
|
|
253
|
-
},
|
|
254
|
-
],
|
|
255
231
|
[AIProviderName.NVIDIA_NIM]: [
|
|
256
232
|
{
|
|
257
233
|
model: "meta/llama-3.3-70b-instruct",
|
|
@@ -408,9 +384,9 @@ const TOP_MODELS_CONFIG = {
|
|
|
408
384
|
/**
|
|
409
385
|
* Default models per provider (first choice/recommended).
|
|
410
386
|
*
|
|
411
|
-
* Covers every provider EXCEPT the
|
|
387
|
+
* Covers every provider EXCEPT the 11 JSON-catalog providers — those default
|
|
412
388
|
* models come from `models.default` in the catalog JSON, read directly by
|
|
413
|
-
* `getDefaultModel()` below. (Two of the
|
|
389
|
+
* `getDefaultModel()` below. (Two of the 11 — cerebras, sambanova — never had
|
|
414
390
|
* a hand entry here at all; `getDefaultModel()` now resolves them too.)
|
|
415
391
|
*
|
|
416
392
|
* AUTO is also excluded — it never had an entry here either (matches
|
|
@@ -425,11 +401,9 @@ export const DEFAULT_MODELS = {
|
|
|
425
401
|
[AIProviderName.AZURE]: AzureOpenAIModels.GPT_4O,
|
|
426
402
|
[AIProviderName.OLLAMA]: OllamaModels.LLAMA4_LATEST,
|
|
427
403
|
[AIProviderName.LITELLM]: LiteLLMModels.OPENAI_GPT_4O,
|
|
428
|
-
[AIProviderName.HUGGINGFACE]: HuggingFaceModels.LLAMA_3_3_70B_INSTRUCT,
|
|
429
404
|
[AIProviderName.SAGEMAKER]: SageMakerModels.LLAMA_4_MAVERICK_17B_128E,
|
|
430
405
|
[AIProviderName.OPENROUTER]: OpenRouterModels.CLAUDE_SONNET_4_5,
|
|
431
406
|
[AIProviderName.OPENAI_COMPATIBLE]: "gpt-4o",
|
|
432
|
-
[AIProviderName.DEEPSEEK]: DeepSeekModels.DEEPSEEK_CHAT,
|
|
433
407
|
[AIProviderName.NVIDIA_NIM]: NvidiaNimModels.GPT_OSS_20B,
|
|
434
408
|
// LM Studio + llama.cpp auto-discover their loaded model from /v1/models;
|
|
435
409
|
// an empty default is the documented signal to use that path.
|
|
@@ -447,7 +421,7 @@ export const DEFAULT_MODELS = {
|
|
|
447
421
|
/**
|
|
448
422
|
* Model enum mappings for getAllModels.
|
|
449
423
|
*
|
|
450
|
-
* Covers every provider EXCEPT the
|
|
424
|
+
* Covers every provider EXCEPT the 11 JSON-catalog providers — those model
|
|
451
425
|
* lists come from `Object.keys(models.catalog)` in the catalog JSON, read
|
|
452
426
|
* directly by `getAllModels()` below.
|
|
453
427
|
*/
|
|
@@ -460,11 +434,9 @@ const MODEL_ENUMS = {
|
|
|
460
434
|
[AIProviderName.AZURE]: AzureOpenAIModels,
|
|
461
435
|
[AIProviderName.OLLAMA]: OllamaModels,
|
|
462
436
|
[AIProviderName.LITELLM]: LiteLLMModels,
|
|
463
|
-
[AIProviderName.HUGGINGFACE]: HuggingFaceModels,
|
|
464
437
|
[AIProviderName.SAGEMAKER]: SageMakerModels,
|
|
465
438
|
[AIProviderName.OPENROUTER]: OpenRouterModels,
|
|
466
439
|
[AIProviderName.OPENAI_COMPATIBLE]: null,
|
|
467
|
-
[AIProviderName.DEEPSEEK]: DeepSeekModels,
|
|
468
440
|
[AIProviderName.NVIDIA_NIM]: NvidiaNimModels,
|
|
469
441
|
[AIProviderName.LM_STUDIO]: null,
|
|
470
442
|
[AIProviderName.LLAMACPP]: null,
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Size Guard Utility
|
|
3
3
|
*
|
|
4
4
|
* Provides bounded binary downloads to prevent OOM when fetching generated
|
|
5
|
-
* media from external providers. Applies a Content-Length pre-check and
|
|
6
|
-
*
|
|
7
|
-
* materialise in process memory.
|
|
5
|
+
* media from external providers. Applies a Content-Length pre-check and
|
|
6
|
+
* counts bytes while streaming, so multi-GB responses are rejected before
|
|
7
|
+
* they fully materialise in process memory.
|
|
8
8
|
*
|
|
9
9
|
* @module utils/sizeGuard
|
|
10
10
|
*/
|
|
@@ -21,8 +21,11 @@ export declare const MAX_IMAGE_BYTES: number;
|
|
|
21
21
|
* Two checks are performed:
|
|
22
22
|
* 1. If the response includes a `Content-Length` header that exceeds
|
|
23
23
|
* `maxBytes`, the download is rejected immediately (no data is read).
|
|
24
|
-
* 2.
|
|
25
|
-
* This catches chunked transfers where no
|
|
24
|
+
* 2. The body is read as a stream and the reader is cancelled as soon as
|
|
25
|
+
* more than `maxBytes` arrive. This catches chunked transfers where no
|
|
26
|
+
* `Content-Length` was provided (or it understated the body) without
|
|
27
|
+
* buffering the excess. A response without a readable stream falls back
|
|
28
|
+
* to buffering and checking afterwards.
|
|
26
29
|
*
|
|
27
30
|
* @param response The fetch {@link Response} to drain.
|
|
28
31
|
* @param maxBytes Maximum number of bytes allowed.
|
package/dist/utils/sizeGuard.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Size Guard Utility
|
|
3
3
|
*
|
|
4
4
|
* Provides bounded binary downloads to prevent OOM when fetching generated
|
|
5
|
-
* media from external providers. Applies a Content-Length pre-check and
|
|
6
|
-
*
|
|
7
|
-
* materialise in process memory.
|
|
5
|
+
* media from external providers. Applies a Content-Length pre-check and
|
|
6
|
+
* counts bytes while streaming, so multi-GB responses are rejected before
|
|
7
|
+
* they fully materialise in process memory.
|
|
8
8
|
*
|
|
9
9
|
* @module utils/sizeGuard
|
|
10
10
|
*/
|
|
@@ -21,8 +21,11 @@ export const MAX_IMAGE_BYTES = 25 * 1024 * 1024;
|
|
|
21
21
|
* Two checks are performed:
|
|
22
22
|
* 1. If the response includes a `Content-Length` header that exceeds
|
|
23
23
|
* `maxBytes`, the download is rejected immediately (no data is read).
|
|
24
|
-
* 2.
|
|
25
|
-
* This catches chunked transfers where no
|
|
24
|
+
* 2. The body is read as a stream and the reader is cancelled as soon as
|
|
25
|
+
* more than `maxBytes` arrive. This catches chunked transfers where no
|
|
26
|
+
* `Content-Length` was provided (or it understated the body) without
|
|
27
|
+
* buffering the excess. A response without a readable stream falls back
|
|
28
|
+
* to buffering and checking afterwards.
|
|
26
29
|
*
|
|
27
30
|
* @param response The fetch {@link Response} to drain.
|
|
28
31
|
* @param maxBytes Maximum number of bytes allowed.
|
|
@@ -36,9 +39,29 @@ export async function readBoundedBuffer(response, maxBytes, label) {
|
|
|
36
39
|
if (contentLength > 0 && contentLength > maxBytes) {
|
|
37
40
|
throw new Error(`${label} download too large: ${contentLength} bytes (max ${maxBytes})`);
|
|
38
41
|
}
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
const exceeded = (bytes) => new Error(`${label} download exceeded size cap after fetch: ${bytes} bytes (max ${maxBytes})`);
|
|
43
|
+
const body = response.body;
|
|
44
|
+
if (!body || typeof body.getReader !== "function") {
|
|
45
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
46
|
+
if (buffer.length > maxBytes) {
|
|
47
|
+
throw exceeded(buffer.length);
|
|
48
|
+
}
|
|
49
|
+
return buffer;
|
|
42
50
|
}
|
|
43
|
-
|
|
51
|
+
const reader = body.getReader();
|
|
52
|
+
const chunks = [];
|
|
53
|
+
let received = 0;
|
|
54
|
+
for (;;) {
|
|
55
|
+
const { done, value } = await reader.read();
|
|
56
|
+
if (done) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
received += value.byteLength;
|
|
60
|
+
if (received > maxBytes) {
|
|
61
|
+
await reader.cancel().catch(() => undefined);
|
|
62
|
+
throw exceeded(received);
|
|
63
|
+
}
|
|
64
|
+
chunks.push(value);
|
|
65
|
+
}
|
|
66
|
+
return Buffer.concat(chunks, received);
|
|
44
67
|
}
|