@juspay/neurolink 11.26.2 → 11.27.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/adapters/providerImageAdapter.js +20 -0
- package/dist/browser/neurolink.min.js +397 -397
- package/dist/constants/contextWindows.d.ts +18 -4
- package/dist/constants/contextWindows.js +35 -4
- package/dist/core/constants.js +59 -1
- package/dist/models/anthropicModels.d.ts +3 -6
- package/dist/models/anthropicModels.js +97 -123
- package/dist/models/manifestRegistry.d.ts +9 -0
- package/dist/models/manifestRegistry.js +23 -0
- package/dist/models/manifests/anthropic.js +5 -3
- package/dist/models/manifests/azure.js +6 -1
- package/dist/models/modelRegistry.d.ts +22 -2
- package/dist/models/modelRegistry.js +143 -8
- package/dist/providers/amazonSagemaker.d.ts +1 -1
- package/dist/providers/sagemaker/language-model.d.ts +2 -2
- package/dist/utils/pricing.js +51 -0
- package/package.json +1 -1
|
@@ -63,10 +63,24 @@ export declare function clearRuntimeOutputCeilings(): void;
|
|
|
63
63
|
* 0.5 Runtime-discovered windows (registerRuntimeContextWindow) — real
|
|
64
64
|
* per-model limits fetched from the serving infrastructure (LiteLLM
|
|
65
65
|
* `/model/info`)
|
|
66
|
-
* 1.
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
66
|
+
* 1. Manifest exact/alias match ONLY (resolveManifestEntryStrict — no prefix, see
|
|
67
|
+
* src/lib/models/manifestRegistry.ts) — the emerging single source of
|
|
68
|
+
* truth for per-model metadata. Deliberately consulted for a REAL match
|
|
69
|
+
* only (never the manifest's synthesized/generic default): most provider
|
|
70
|
+
* manifests are still "minimal" stubs holding nothing but a provider-wide
|
|
71
|
+
* default (e.g. vertex.ts, together-ai.ts) and none of the per-model
|
|
72
|
+
* overrides — including Vertex's Claude "claude-" prefix catch-all below,
|
|
73
|
+
* which exists specifically to stop an unlisted Claude-on-Vertex model
|
|
74
|
+
* from inheriting Gemini's 1,048,576 default — that still live only in
|
|
75
|
+
* MODEL_CONTEXT_WINDOWS. Falling back to a manifest-wide default here
|
|
76
|
+
* would silently drop that coverage. When a manifest DOES carry a real
|
|
77
|
+
* entry for this model, it wins even if it disagrees with the legacy
|
|
78
|
+
* table (e.g. Mistral's manifest supersedes the coarser, older
|
|
79
|
+
* MODEL_CONTEXT_WINDOWS.mistral values).
|
|
80
|
+
* 2. Exact model match under provider in static registry
|
|
81
|
+
* 3. Prefix match under provider in static registry
|
|
82
|
+
* 4. Provider's _default in static registry
|
|
83
|
+
* 5. Global DEFAULT_CONTEXT_WINDOW
|
|
70
84
|
*/
|
|
71
85
|
export declare function getContextWindowSize(provider: string, model?: string): number;
|
|
72
86
|
/**
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { DynamicModelProvider } from "../core/dynamicModels.js";
|
|
14
14
|
import { logger } from "../utils/logger.js";
|
|
15
|
+
import { resolveManifestEntryStrict } from "../models/manifestRegistry.js";
|
|
15
16
|
/** Default context window when provider/model is unknown */
|
|
16
17
|
export const DEFAULT_CONTEXT_WINDOW = 128_000;
|
|
17
18
|
/** Maximum output reserve when maxTokens not specified */
|
|
@@ -488,10 +489,24 @@ export function clearRuntimeOutputCeilings() {
|
|
|
488
489
|
* 0.5 Runtime-discovered windows (registerRuntimeContextWindow) — real
|
|
489
490
|
* per-model limits fetched from the serving infrastructure (LiteLLM
|
|
490
491
|
* `/model/info`)
|
|
491
|
-
* 1.
|
|
492
|
-
*
|
|
493
|
-
*
|
|
494
|
-
*
|
|
492
|
+
* 1. Manifest exact/alias match ONLY (resolveManifestEntryStrict — no prefix, see
|
|
493
|
+
* src/lib/models/manifestRegistry.ts) — the emerging single source of
|
|
494
|
+
* truth for per-model metadata. Deliberately consulted for a REAL match
|
|
495
|
+
* only (never the manifest's synthesized/generic default): most provider
|
|
496
|
+
* manifests are still "minimal" stubs holding nothing but a provider-wide
|
|
497
|
+
* default (e.g. vertex.ts, together-ai.ts) and none of the per-model
|
|
498
|
+
* overrides — including Vertex's Claude "claude-" prefix catch-all below,
|
|
499
|
+
* which exists specifically to stop an unlisted Claude-on-Vertex model
|
|
500
|
+
* from inheriting Gemini's 1,048,576 default — that still live only in
|
|
501
|
+
* MODEL_CONTEXT_WINDOWS. Falling back to a manifest-wide default here
|
|
502
|
+
* would silently drop that coverage. When a manifest DOES carry a real
|
|
503
|
+
* entry for this model, it wins even if it disagrees with the legacy
|
|
504
|
+
* table (e.g. Mistral's manifest supersedes the coarser, older
|
|
505
|
+
* MODEL_CONTEXT_WINDOWS.mistral values).
|
|
506
|
+
* 2. Exact model match under provider in static registry
|
|
507
|
+
* 3. Prefix match under provider in static registry
|
|
508
|
+
* 4. Provider's _default in static registry
|
|
509
|
+
* 5. Global DEFAULT_CONTEXT_WINDOW
|
|
495
510
|
*/
|
|
496
511
|
export function getContextWindowSize(provider, model) {
|
|
497
512
|
// Step 0: Check dynamic model registry first.
|
|
@@ -521,6 +536,22 @@ export function getContextWindowSize(provider, model) {
|
|
|
521
536
|
// Static fallback chain — normalize aliases first so "lmstudio" / "llama.cpp" /
|
|
522
537
|
// "nvidianim" find their canonical entries instead of falling back to default.
|
|
523
538
|
const canonical = normalizeProviderForLookup(provider);
|
|
539
|
+
// Step 1: Manifest real-entry lookup (exact id, alias, or longest-prefix —
|
|
540
|
+
// see resolveManifestEntryStrict's docblock). Tries the alias-normalized
|
|
541
|
+
// provider key first, then the raw provider string, mirroring the
|
|
542
|
+
// `MODEL_CONTEXT_WINDOWS[canonical] ?? MODEL_CONTEXT_WINDOWS[provider]`
|
|
543
|
+
// double-lookup below — MANIFEST_REGISTRY is keyed by the same hyphenated
|
|
544
|
+
// AIProviderName forms (e.g. "together-ai") that normalizeProviderForLookup
|
|
545
|
+
// strips and PROVIDER_ALIAS_MAP doesn't cover, so callers passing the raw
|
|
546
|
+
// enum value still resolve. Only a genuine match short-circuits; a miss
|
|
547
|
+
// falls straight through to the untouched legacy cascade below.
|
|
548
|
+
if (model) {
|
|
549
|
+
const manifestEntry = resolveManifestEntryStrict(canonical, model) ??
|
|
550
|
+
resolveManifestEntryStrict(provider, model);
|
|
551
|
+
if (manifestEntry) {
|
|
552
|
+
return manifestEntry.contextWindow;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
524
555
|
const providerWindows = MODEL_CONTEXT_WINDOWS[canonical] ?? MODEL_CONTEXT_WINDOWS[provider];
|
|
525
556
|
if (!providerWindows) {
|
|
526
557
|
return DEFAULT_CONTEXT_WINDOW;
|
package/dist/core/constants.js
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
* Central configuration constants for NeuroLink
|
|
3
3
|
* Single source of truth for all default values
|
|
4
4
|
*/
|
|
5
|
+
import { anthropicManifest } from "../models/manifests/anthropic.js";
|
|
6
|
+
import { openaiManifest } from "../models/manifests/openai.js";
|
|
7
|
+
import { googleAiManifest } from "../models/manifests/google-ai.js";
|
|
8
|
+
import { vertexManifest } from "../models/manifests/vertex.js";
|
|
9
|
+
import { bedrockManifest } from "../models/manifests/bedrock.js";
|
|
10
|
+
import { azureManifest } from "../models/manifests/azure.js";
|
|
11
|
+
import { mistralManifest } from "../models/manifests/mistral.js";
|
|
12
|
+
import { ollamaManifest } from "../models/manifests/ollama.js";
|
|
13
|
+
import { litellmManifest } from "../models/manifests/litellm.js";
|
|
5
14
|
// Image Generation Model Identifiers
|
|
6
15
|
// Used to detect if a model is an image generation model (not text generation).
|
|
7
16
|
// `isImageGenerationModel(name)` (below) does boundary-aware matching:
|
|
@@ -167,34 +176,83 @@ export const PROVIDER_CONFIG = {
|
|
|
167
176
|
temperature: 0.4,
|
|
168
177
|
},
|
|
169
178
|
};
|
|
170
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Per-model output-token overrides for a manifest, keyed by canonical model
|
|
181
|
+
* id. The manifest's synthetic "_default" entry is excluded — the
|
|
182
|
+
* provider-level `default` in PROVIDER_MAX_TOKENS already carries that role,
|
|
183
|
+
* and is left as the hand-authored value below rather than replaced with
|
|
184
|
+
* this data (a provider's `_default` entry, when present, is a minimal
|
|
185
|
+
* catch-all sized for an unlisted/gateway model id, not a considered
|
|
186
|
+
* provider-wide ceiling).
|
|
187
|
+
*/
|
|
188
|
+
function maxTokensOverridesFrom(manifest) {
|
|
189
|
+
const overrides = {};
|
|
190
|
+
for (const [id, entry] of Object.entries(manifest.models)) {
|
|
191
|
+
if (id === "_default") {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
overrides[id] = entry.maxOutputTokens;
|
|
195
|
+
}
|
|
196
|
+
return overrides;
|
|
197
|
+
}
|
|
198
|
+
// Provider-specific maxTokens limits. Each provider's `default` is the
|
|
199
|
+
// original hand-authored ceiling (unchanged); per-model keys are generated
|
|
200
|
+
// from that provider's manifest (src/lib/models/manifests/) so
|
|
201
|
+
// getSafeMaxTokens()'s existing per-model lookup (tokenLimits.ts) actually
|
|
202
|
+
// has data to find instead of always falling through to the coarse
|
|
203
|
+
// `default`. This resolves the historical disagreement between
|
|
204
|
+
// getSafeMaxTokens("anthropic", "claude-opus-4-6") (used to return the flat
|
|
205
|
+
// 64000) and resolveClaudeMaxTokens("claude-opus-4-6") (tokenLimits.ts's
|
|
206
|
+
// regex ladder, correctly 32000 for the Opus family) — the manifest's own
|
|
207
|
+
// per-model maxOutputTokens now wins for every listed model, on every
|
|
208
|
+
// provider below, not just Anthropic.
|
|
209
|
+
//
|
|
210
|
+
// Manifests are imported directly from src/lib/models/manifests/ rather
|
|
211
|
+
// than through manifestRegistry.ts's aggregator: manifestRegistry.ts
|
|
212
|
+
// imports PROVIDER_MAX_TOKENS from this file (to size the synthetic
|
|
213
|
+
// `_default` entry for manifests that don't declare their own), so
|
|
214
|
+
// importing the aggregator back here would form a constants.ts <->
|
|
215
|
+
// manifestRegistry.ts import cycle whose safety depends on which module a
|
|
216
|
+
// given entrypoint happens to reach first — an ES module TDZ hazard, not
|
|
217
|
+
// something a type-checker catches. The individual manifest files have no
|
|
218
|
+
// dependency on this module (only on the ProviderModelManifest type), so
|
|
219
|
+
// reaching past the aggregator avoids the cycle entirely.
|
|
171
220
|
export const PROVIDER_MAX_TOKENS = {
|
|
172
221
|
anthropic: {
|
|
173
222
|
default: 64000,
|
|
223
|
+
...maxTokensOverridesFrom(anthropicManifest),
|
|
174
224
|
},
|
|
175
225
|
openai: {
|
|
176
226
|
default: 128000,
|
|
227
|
+
...maxTokensOverridesFrom(openaiManifest),
|
|
177
228
|
},
|
|
178
229
|
"google-ai": {
|
|
179
230
|
default: 64000,
|
|
231
|
+
...maxTokensOverridesFrom(googleAiManifest),
|
|
180
232
|
},
|
|
181
233
|
vertex: {
|
|
182
234
|
default: 64000,
|
|
235
|
+
...maxTokensOverridesFrom(vertexManifest),
|
|
183
236
|
},
|
|
184
237
|
bedrock: {
|
|
185
238
|
default: 64000,
|
|
239
|
+
...maxTokensOverridesFrom(bedrockManifest),
|
|
186
240
|
},
|
|
187
241
|
azure: {
|
|
188
242
|
default: 128000,
|
|
243
|
+
...maxTokensOverridesFrom(azureManifest),
|
|
189
244
|
},
|
|
190
245
|
mistral: {
|
|
191
246
|
default: 128000,
|
|
247
|
+
...maxTokensOverridesFrom(mistralManifest),
|
|
192
248
|
},
|
|
193
249
|
ollama: {
|
|
194
250
|
default: 64000,
|
|
251
|
+
...maxTokensOverridesFrom(ollamaManifest),
|
|
195
252
|
},
|
|
196
253
|
litellm: {
|
|
197
254
|
default: 128000,
|
|
255
|
+
...maxTokensOverridesFrom(litellmManifest),
|
|
198
256
|
},
|
|
199
257
|
default: 64000,
|
|
200
258
|
};
|
|
@@ -20,6 +20,9 @@ export declare enum AnthropicModel {
|
|
|
20
20
|
CLAUDE_3_5_SONNET_V2 = "claude-3-5-sonnet-v2-20241022",
|
|
21
21
|
CLAUDE_SONNET_4 = "claude-sonnet-4-20250514",
|
|
22
22
|
CLAUDE_SONNET_4_6 = "claude-sonnet-4-6",
|
|
23
|
+
CLAUDE_OPUS_4_5 = "claude-opus-4-5-20251101",
|
|
24
|
+
CLAUDE_SONNET_4_5 = "claude-sonnet-4-5-20250929",
|
|
25
|
+
CLAUDE_HAIKU_4_5 = "claude-haiku-4-5-20251001",
|
|
23
26
|
CLAUDE_3_OPUS = "claude-3-opus-20240229",
|
|
24
27
|
CLAUDE_OPUS_4 = "claude-opus-4-20250514",
|
|
25
28
|
CLAUDE_OPUS_4_6 = "claude-opus-4-6"
|
|
@@ -34,12 +37,6 @@ export declare enum AnthropicModel {
|
|
|
34
37
|
* - api: Full API access to all models (based on API access)
|
|
35
38
|
*/
|
|
36
39
|
export declare const MODEL_TIER_ACCESS: Record<ClaudeSubscriptionTier, string[]>;
|
|
37
|
-
/**
|
|
38
|
-
* Model metadata by model ID
|
|
39
|
-
*
|
|
40
|
-
* Comprehensive mapping of each Anthropic model's metadata,
|
|
41
|
-
* including display names, context windows, vision support, and extended thinking.
|
|
42
|
-
*/
|
|
43
40
|
export declare const MODEL_METADATA: Record<string, AnthropicModelMetadata>;
|
|
44
41
|
/**
|
|
45
42
|
* Default model for each subscription tier
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* model capabilities, and provides helper functions for tier-based access control.
|
|
6
6
|
*/
|
|
7
7
|
import { ModelAccessError } from "../types/index.js";
|
|
8
|
+
import { anthropicManifest } from "./manifests/anthropic.js";
|
|
8
9
|
// Re-export runtime value for convenience
|
|
9
10
|
export { ModelAccessError };
|
|
10
11
|
// ============================================================================
|
|
@@ -30,6 +31,12 @@ export var AnthropicModel;
|
|
|
30
31
|
AnthropicModel["CLAUDE_SONNET_4"] = "claude-sonnet-4-20250514";
|
|
31
32
|
// Claude Sonnet 4.6
|
|
32
33
|
AnthropicModel["CLAUDE_SONNET_4_6"] = "claude-sonnet-4-6";
|
|
34
|
+
// Claude Opus 4.5
|
|
35
|
+
AnthropicModel["CLAUDE_OPUS_4_5"] = "claude-opus-4-5-20251101";
|
|
36
|
+
// Claude Sonnet 4.5
|
|
37
|
+
AnthropicModel["CLAUDE_SONNET_4_5"] = "claude-sonnet-4-5-20250929";
|
|
38
|
+
// Claude 4.5 Haiku
|
|
39
|
+
AnthropicModel["CLAUDE_HAIKU_4_5"] = "claude-haiku-4-5-20251001";
|
|
33
40
|
// Claude 3 Opus (Legacy flagship)
|
|
34
41
|
AnthropicModel["CLAUDE_3_OPUS"] = "claude-3-opus-20240229";
|
|
35
42
|
// Claude Opus 4 (Latest flagship)
|
|
@@ -76,130 +83,91 @@ export const MODEL_TIER_ACCESS = {
|
|
|
76
83
|
// MODEL METADATA
|
|
77
84
|
// ============================================================================
|
|
78
85
|
/**
|
|
79
|
-
* Model metadata by model ID
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
86
|
+
* Model metadata by model ID, derived from the anthropic manifest
|
|
87
|
+
* (src/lib/models/manifests/anthropic.ts) so this catalog can no longer
|
|
88
|
+
* silently drift from the canonical source. Family/description fields —
|
|
89
|
+
* not tracked by the manifest — are supplied by the small per-id lookups
|
|
90
|
+
* below, unchanged from their pre-migration values.
|
|
83
91
|
*/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
[AnthropicModel.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
},
|
|
98
|
-
// Claude 3.5 Haiku
|
|
99
|
-
[AnthropicModel.CLAUDE_3_5_HAIKU]: {
|
|
100
|
-
displayName: "Claude 3.5 Haiku",
|
|
101
|
-
contextWindow: 200000,
|
|
102
|
-
maxOutputTokens: 8192,
|
|
103
|
-
supportsVision: false,
|
|
104
|
-
supportsExtendedThinking: false,
|
|
105
|
-
supportsToolUse: true,
|
|
106
|
-
supportsStreaming: true,
|
|
107
|
-
deprecated: false,
|
|
108
|
-
family: "haiku",
|
|
109
|
-
description: "Improved fast model with better performance",
|
|
110
|
-
},
|
|
111
|
-
// Claude 3.5 Sonnet
|
|
112
|
-
[AnthropicModel.CLAUDE_3_5_SONNET]: {
|
|
113
|
-
displayName: "Claude 3.5 Sonnet",
|
|
114
|
-
contextWindow: 200000,
|
|
115
|
-
maxOutputTokens: 8192,
|
|
116
|
-
supportsVision: true,
|
|
117
|
-
supportsExtendedThinking: false,
|
|
118
|
-
supportsToolUse: true,
|
|
119
|
-
supportsStreaming: true,
|
|
120
|
-
deprecated: false,
|
|
121
|
-
family: "sonnet",
|
|
122
|
-
description: "Balanced model for most tasks",
|
|
123
|
-
},
|
|
124
|
-
// Claude 3.5 Sonnet V2
|
|
125
|
-
[AnthropicModel.CLAUDE_3_5_SONNET_V2]: {
|
|
126
|
-
displayName: "Claude 3.5 Sonnet V2",
|
|
127
|
-
contextWindow: 200000,
|
|
128
|
-
maxOutputTokens: 8192,
|
|
129
|
-
supportsVision: true,
|
|
130
|
-
supportsExtendedThinking: false,
|
|
131
|
-
supportsToolUse: true,
|
|
132
|
-
supportsStreaming: true,
|
|
133
|
-
deprecated: false,
|
|
134
|
-
family: "sonnet",
|
|
135
|
-
description: "Updated Sonnet with improved capabilities",
|
|
136
|
-
},
|
|
137
|
-
// Claude Sonnet 4
|
|
138
|
-
[AnthropicModel.CLAUDE_SONNET_4]: {
|
|
139
|
-
displayName: "Claude Sonnet 4",
|
|
140
|
-
contextWindow: 200000,
|
|
141
|
-
maxOutputTokens: 64000,
|
|
142
|
-
supportsVision: true,
|
|
143
|
-
supportsExtendedThinking: true,
|
|
144
|
-
supportsToolUse: true,
|
|
145
|
-
supportsStreaming: true,
|
|
146
|
-
deprecated: false,
|
|
147
|
-
family: "sonnet",
|
|
148
|
-
description: "Latest Sonnet with extended thinking support",
|
|
149
|
-
},
|
|
150
|
-
// Claude 3 Opus (Legacy)
|
|
151
|
-
[AnthropicModel.CLAUDE_3_OPUS]: {
|
|
152
|
-
displayName: "Claude 3 Opus",
|
|
153
|
-
contextWindow: 200000,
|
|
154
|
-
maxOutputTokens: 4096,
|
|
155
|
-
supportsVision: true,
|
|
156
|
-
supportsExtendedThinking: false,
|
|
157
|
-
supportsToolUse: true,
|
|
158
|
-
supportsStreaming: true,
|
|
159
|
-
deprecated: true,
|
|
160
|
-
family: "opus",
|
|
161
|
-
description: "Legacy flagship model for complex tasks",
|
|
162
|
-
},
|
|
163
|
-
// Claude Opus 4
|
|
164
|
-
[AnthropicModel.CLAUDE_OPUS_4]: {
|
|
165
|
-
displayName: "Claude Opus 4",
|
|
166
|
-
contextWindow: 200000,
|
|
167
|
-
maxOutputTokens: 64000,
|
|
168
|
-
supportsVision: true,
|
|
169
|
-
supportsExtendedThinking: true,
|
|
170
|
-
supportsToolUse: true,
|
|
171
|
-
supportsStreaming: true,
|
|
172
|
-
deprecated: false,
|
|
173
|
-
family: "opus",
|
|
174
|
-
description: "Latest flagship model with advanced reasoning",
|
|
175
|
-
},
|
|
176
|
-
// Claude Sonnet 4.6
|
|
177
|
-
[AnthropicModel.CLAUDE_SONNET_4_6]: {
|
|
178
|
-
displayName: "Claude Sonnet 4.6",
|
|
179
|
-
contextWindow: 1000000,
|
|
180
|
-
maxOutputTokens: 64000,
|
|
181
|
-
supportsVision: true,
|
|
182
|
-
supportsExtendedThinking: true,
|
|
183
|
-
supportsToolUse: true,
|
|
184
|
-
supportsStreaming: true,
|
|
185
|
-
deprecated: false,
|
|
186
|
-
family: "sonnet",
|
|
187
|
-
description: "Claude 4.6 Sonnet with 1M context window",
|
|
188
|
-
},
|
|
189
|
-
// Claude Opus 4.6
|
|
190
|
-
[AnthropicModel.CLAUDE_OPUS_4_6]: {
|
|
191
|
-
displayName: "Claude Opus 4.6",
|
|
192
|
-
contextWindow: 1000000,
|
|
193
|
-
maxOutputTokens: 64000,
|
|
194
|
-
supportsVision: true,
|
|
195
|
-
supportsExtendedThinking: true,
|
|
196
|
-
supportsToolUse: true,
|
|
197
|
-
supportsStreaming: true,
|
|
198
|
-
deprecated: false,
|
|
199
|
-
family: "opus",
|
|
200
|
-
description: "Claude 4.6 Opus flagship with 1M context window",
|
|
201
|
-
},
|
|
92
|
+
const FAMILY_BY_MODEL = {
|
|
93
|
+
[AnthropicModel.CLAUDE_3_HAIKU]: "haiku",
|
|
94
|
+
[AnthropicModel.CLAUDE_3_5_HAIKU]: "haiku",
|
|
95
|
+
[AnthropicModel.CLAUDE_3_5_SONNET]: "sonnet",
|
|
96
|
+
[AnthropicModel.CLAUDE_3_5_SONNET_V2]: "sonnet",
|
|
97
|
+
[AnthropicModel.CLAUDE_SONNET_4]: "sonnet",
|
|
98
|
+
[AnthropicModel.CLAUDE_SONNET_4_6]: "sonnet",
|
|
99
|
+
[AnthropicModel.CLAUDE_3_OPUS]: "opus",
|
|
100
|
+
[AnthropicModel.CLAUDE_OPUS_4]: "opus",
|
|
101
|
+
[AnthropicModel.CLAUDE_OPUS_4_6]: "opus",
|
|
102
|
+
[AnthropicModel.CLAUDE_OPUS_4_5]: "opus",
|
|
103
|
+
[AnthropicModel.CLAUDE_SONNET_4_5]: "sonnet",
|
|
104
|
+
[AnthropicModel.CLAUDE_HAIKU_4_5]: "haiku",
|
|
202
105
|
};
|
|
106
|
+
const DESCRIPTION_BY_MODEL = {
|
|
107
|
+
[AnthropicModel.CLAUDE_3_HAIKU]: "Fast and efficient model for simple tasks",
|
|
108
|
+
[AnthropicModel.CLAUDE_3_5_HAIKU]: "Improved fast model with better performance",
|
|
109
|
+
[AnthropicModel.CLAUDE_3_5_SONNET]: "Balanced model for most tasks",
|
|
110
|
+
[AnthropicModel.CLAUDE_3_5_SONNET_V2]: "Updated Sonnet with improved capabilities",
|
|
111
|
+
[AnthropicModel.CLAUDE_SONNET_4]: "Latest Sonnet with extended thinking support",
|
|
112
|
+
[AnthropicModel.CLAUDE_3_OPUS]: "Legacy flagship model for complex tasks",
|
|
113
|
+
[AnthropicModel.CLAUDE_OPUS_4]: "Latest flagship model with advanced reasoning",
|
|
114
|
+
[AnthropicModel.CLAUDE_SONNET_4_6]: "Claude 4.6 Sonnet with 1M context window",
|
|
115
|
+
[AnthropicModel.CLAUDE_OPUS_4_6]: "Claude 4.6 Opus flagship with 1M context window",
|
|
116
|
+
[AnthropicModel.CLAUDE_OPUS_4_5]: "Claude 4.5 Opus flagship model",
|
|
117
|
+
[AnthropicModel.CLAUDE_SONNET_4_5]: "Claude 4.5 Sonnet balanced model",
|
|
118
|
+
[AnthropicModel.CLAUDE_HAIKU_4_5]: "Claude 4.5 Haiku fast model",
|
|
119
|
+
};
|
|
120
|
+
const DEPRECATED_MODELS = new Set([
|
|
121
|
+
AnthropicModel.CLAUDE_3_HAIKU,
|
|
122
|
+
AnthropicModel.CLAUDE_3_OPUS,
|
|
123
|
+
]);
|
|
124
|
+
/**
|
|
125
|
+
* CLAUDE_3_5_SONNET_V2's enum value ("claude-3-5-sonnet-v2-20241022") is a
|
|
126
|
+
* synthetic id minted only inside this file, pre-dating the manifest — it
|
|
127
|
+
* never was a real Anthropic wire id and has no row anywhere else in the
|
|
128
|
+
* codebase (pricing.ts, contextWindows.ts, VISION_CAPABILITIES all key off
|
|
129
|
+
* "claude-3-5-sonnet-20241022" for both v1 and v2). Route the manifest
|
|
130
|
+
* lookup to the real entry instead of inventing a duplicate manifest row
|
|
131
|
+
* for the same model; the enum member's name and exported value are left
|
|
132
|
+
* untouched.
|
|
133
|
+
*/
|
|
134
|
+
const MANIFEST_ID_OVERRIDES = {
|
|
135
|
+
[AnthropicModel.CLAUDE_3_5_SONNET_V2]: AnthropicModel.CLAUDE_3_5_SONNET,
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* displayName override applied only where routing through
|
|
139
|
+
* MANIFEST_ID_OVERRIDES would otherwise silently rename a model the caller
|
|
140
|
+
* already knows by its pre-migration display name (avoids user-visible
|
|
141
|
+
* naming churn, same principle the manifest itself documents for its
|
|
142
|
+
* pre-existing MODEL_REGISTRY-derived ids).
|
|
143
|
+
*/
|
|
144
|
+
const DISPLAY_NAME_OVERRIDES = {
|
|
145
|
+
[AnthropicModel.CLAUDE_3_5_SONNET_V2]: "Claude 3.5 Sonnet V2",
|
|
146
|
+
};
|
|
147
|
+
function metadataFromManifest(model) {
|
|
148
|
+
const manifestId = MANIFEST_ID_OVERRIDES[model] ?? model;
|
|
149
|
+
const entry = anthropicManifest.models[manifestId];
|
|
150
|
+
if (!entry) {
|
|
151
|
+
throw new Error(`metadataFromManifest: no manifest entry for "${model}" — add it to ` +
|
|
152
|
+
`src/lib/models/manifests/anthropic.ts before referencing it here`);
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
displayName: DISPLAY_NAME_OVERRIDES[model] ?? entry.displayName ?? model,
|
|
156
|
+
contextWindow: entry.contextWindow,
|
|
157
|
+
maxOutputTokens: entry.maxOutputTokens,
|
|
158
|
+
supportsVision: entry.vision,
|
|
159
|
+
supportsExtendedThinking: entry.reasoning ?? false,
|
|
160
|
+
supportsToolUse: entry.functionCalling,
|
|
161
|
+
supportsStreaming: true,
|
|
162
|
+
deprecated: DEPRECATED_MODELS.has(model),
|
|
163
|
+
family: FAMILY_BY_MODEL[model] ?? "sonnet",
|
|
164
|
+
description: DESCRIPTION_BY_MODEL[model] ?? entry.displayName ?? model,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
export const MODEL_METADATA = Object.fromEntries(Object.values(AnthropicModel).map((model) => [
|
|
168
|
+
model,
|
|
169
|
+
metadataFromManifest(model),
|
|
170
|
+
]));
|
|
203
171
|
// ============================================================================
|
|
204
172
|
// DEFAULT MODELS BY TIER
|
|
205
173
|
// ============================================================================
|
|
@@ -447,15 +415,21 @@ export function getLatestModelsByFamily() {
|
|
|
447
415
|
};
|
|
448
416
|
// Priority order for each family (latest first based on model version)
|
|
449
417
|
const familyPriority = {
|
|
450
|
-
haiku: [
|
|
418
|
+
haiku: [
|
|
419
|
+
AnthropicModel.CLAUDE_HAIKU_4_5,
|
|
420
|
+
AnthropicModel.CLAUDE_3_5_HAIKU,
|
|
421
|
+
AnthropicModel.CLAUDE_3_HAIKU,
|
|
422
|
+
],
|
|
451
423
|
sonnet: [
|
|
452
424
|
AnthropicModel.CLAUDE_SONNET_4_6,
|
|
425
|
+
AnthropicModel.CLAUDE_SONNET_4_5,
|
|
453
426
|
AnthropicModel.CLAUDE_SONNET_4,
|
|
454
427
|
AnthropicModel.CLAUDE_3_5_SONNET_V2,
|
|
455
428
|
AnthropicModel.CLAUDE_3_5_SONNET,
|
|
456
429
|
],
|
|
457
430
|
opus: [
|
|
458
431
|
AnthropicModel.CLAUDE_OPUS_4_6,
|
|
432
|
+
AnthropicModel.CLAUDE_OPUS_4_5,
|
|
459
433
|
AnthropicModel.CLAUDE_OPUS_4,
|
|
460
434
|
AnthropicModel.CLAUDE_3_OPUS,
|
|
461
435
|
],
|
|
@@ -21,6 +21,15 @@ export declare function getAllManifestProviders(): string[];
|
|
|
21
21
|
* "llama3.2:latest" or OpenRouter's "openai/gpt-4o"), then undefined.
|
|
22
22
|
* Family rules are applied on top of whichever entry matched.
|
|
23
23
|
*/
|
|
24
|
+
/**
|
|
25
|
+
* Like resolveManifestEntryExact but WITHOUT the longest-prefix fallback:
|
|
26
|
+
* exact canonical id or declared alias only. For consumers where a prefix
|
|
27
|
+
* hit can steal precedence from a more-specific legacy row — boolean
|
|
28
|
+
* capability checks above all (a manifest "gpt-4" prefix match must never
|
|
29
|
+
* shadow the legacy table's explicit "gpt-4-vision-preview" vision row).
|
|
30
|
+
* Family rules still apply to a real match.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveManifestEntryStrict(provider: string, model: string): ProviderModelManifestEntry | undefined;
|
|
24
33
|
export declare function resolveManifestEntryExact(provider: string, model: string): ProviderModelManifestEntry | undefined;
|
|
25
34
|
/**
|
|
26
35
|
* Resolve a model against a provider's manifest, falling back to the
|
|
@@ -105,6 +105,29 @@ function applyFamilyRules(manifest, model, base) {
|
|
|
105
105
|
* "llama3.2:latest" or OpenRouter's "openai/gpt-4o"), then undefined.
|
|
106
106
|
* Family rules are applied on top of whichever entry matched.
|
|
107
107
|
*/
|
|
108
|
+
/**
|
|
109
|
+
* Like resolveManifestEntryExact but WITHOUT the longest-prefix fallback:
|
|
110
|
+
* exact canonical id or declared alias only. For consumers where a prefix
|
|
111
|
+
* hit can steal precedence from a more-specific legacy row — boolean
|
|
112
|
+
* capability checks above all (a manifest "gpt-4" prefix match must never
|
|
113
|
+
* shadow the legacy table's explicit "gpt-4-vision-preview" vision row).
|
|
114
|
+
* Family rules still apply to a real match.
|
|
115
|
+
*/
|
|
116
|
+
export function resolveManifestEntryStrict(provider, model) {
|
|
117
|
+
const manifest = MANIFEST_REGISTRY[provider];
|
|
118
|
+
if (!manifest) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
const exact = manifest.models[model];
|
|
122
|
+
if (exact) {
|
|
123
|
+
return applyFamilyRules(manifest, model, exact);
|
|
124
|
+
}
|
|
125
|
+
const aliasMatch = Object.entries(manifest.models).find(([canonicalId, entry]) => canonicalId !== "_default" && entry.aliases.includes(model));
|
|
126
|
+
if (aliasMatch) {
|
|
127
|
+
return applyFamilyRules(manifest, model, aliasMatch[1]);
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
108
131
|
export function resolveManifestEntryExact(provider, model) {
|
|
109
132
|
const manifest = MANIFEST_REGISTRY[provider];
|
|
110
133
|
if (!manifest) {
|
|
@@ -28,9 +28,11 @@ export const anthropicManifest = {
|
|
|
28
28
|
displayName: "Claude Sonnet 5",
|
|
29
29
|
contextWindow: 1_000_000,
|
|
30
30
|
maxOutputTokens: 64_000,
|
|
31
|
-
// No pricingPerMTok:
|
|
32
|
-
//
|
|
33
|
-
//
|
|
31
|
+
// No pricingPerMTok DELIBERATELY: PRICING.anthropic carries real
|
|
32
|
+
// rates for this id, and findRates() is manifest-first with a legacy
|
|
33
|
+
// fallback — omitting the rate here defers to that table instead of
|
|
34
|
+
// duplicating it, and keeps this entry out of the manifest-derived
|
|
35
|
+
// MODEL_REGISTRY rows (which only admit priced entries).
|
|
34
36
|
vision: true,
|
|
35
37
|
functionCalling: true,
|
|
36
38
|
reasoning: true,
|
|
@@ -77,7 +77,12 @@ export const azureManifest = {
|
|
|
77
77
|
contextWindow: 200000,
|
|
78
78
|
maxOutputTokens: 32768,
|
|
79
79
|
pricingPerMTok: { input: 1.25, output: 10 },
|
|
80
|
-
|
|
80
|
+
// Azure publishes no such model (the registry row is deprecated for
|
|
81
|
+
// exactly that reason, modelRegistry.ts ~2550), and vision was
|
|
82
|
+
// deliberately removed from VISION_CAPABILITIES for it — this entry
|
|
83
|
+
// was generated from the registry BEFORE that fix and must not
|
|
84
|
+
// re-advertise a capability an undeployable id cannot have.
|
|
85
|
+
vision: false,
|
|
81
86
|
functionCalling: true,
|
|
82
87
|
reasoning: true,
|
|
83
88
|
jsonMode: true,
|
|
@@ -6,7 +6,16 @@
|
|
|
6
6
|
import { AIProviderName } from "../constants/enums.js";
|
|
7
7
|
import type { JsonValue, ModelCapabilities, ModelInfo } from "../types/index.js";
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Public MODEL_REGISTRY: the manifest-derived entries merged over the
|
|
10
|
+
* hand-authored LEGACY_MODEL_REGISTRY base. Spread order matters — manifest
|
|
11
|
+
* entries are spread last, so a manifest-priced model wins outright
|
|
12
|
+
* (whole-entry replacement, not a per-field merge) over a legacy row with
|
|
13
|
+
* the same id. Any legacy id the manifest doesn't also price (no
|
|
14
|
+
* pricingPerMTok, or no manifest entry at all — e.g. AnthropicModels.
|
|
15
|
+
* CLAUDE_OPUS_5/CLAUDE_FABLE_5, which have no manifest counterpart yet)
|
|
16
|
+
* passes through unchanged, which is what keeps resolveSamplingParams/
|
|
17
|
+
* modelSupportsSamplingParams behaviour identical for those "non-manifest"
|
|
18
|
+
* models: their capabilities.samplingParams (or absence of it) is untouched.
|
|
10
19
|
*/
|
|
11
20
|
export declare const MODEL_REGISTRY: Record<string, ModelInfo>;
|
|
12
21
|
/**
|
|
@@ -61,7 +70,18 @@ export declare function resolveSamplingParams(provider: string, model: string |
|
|
|
61
70
|
*/
|
|
62
71
|
export declare function getModelsByProvider(provider: AIProviderName): ModelInfo[];
|
|
63
72
|
/**
|
|
64
|
-
* Get available providers
|
|
73
|
+
* Get available providers.
|
|
74
|
+
*
|
|
75
|
+
* Deliberately does NOT derive from MODEL_REGISTRY membership: a registry
|
|
76
|
+
* keyed only by "real, priced, named models" under-reports providers whose
|
|
77
|
+
* manifest carries only a `_default` entry (the minimal-tier providers —
|
|
78
|
+
* e.g. voyage, jina, stability — have no priced named model and so
|
|
79
|
+
* contribute zero MODEL_REGISTRY rows). Reading getAllManifestProviders()
|
|
80
|
+
* directly gives every provider NeuroLink actually knows a manifest for,
|
|
81
|
+
* decoupled from MODEL_REGISTRY membership entirely. Manifest keys are
|
|
82
|
+
* literally the AIProviderName enum's kebab-case values by construction
|
|
83
|
+
* (see manifestRegistry.ts), so the cast is a same-value relabel, not a
|
|
84
|
+
* narrowing assumption.
|
|
65
85
|
*/
|
|
66
86
|
export declare function getAvailableProviders(): AIProviderName[];
|
|
67
87
|
/**
|