@dexto/core 1.8.0 → 1.8.2
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/dist/agent/DextoAgent.cjs +10 -16
- package/dist/agent/DextoAgent.d.ts +2 -2
- package/dist/agent/DextoAgent.d.ts.map +1 -1
- package/dist/agent/DextoAgent.js +8 -5
- package/dist/agent/types.d.ts +1 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/context/compaction/overflow.d.ts +1 -1
- package/dist/context/compaction/overflow.d.ts.map +1 -1
- package/dist/context/manager.cjs +8 -8
- package/dist/context/manager.d.ts +1 -1
- package/dist/context/manager.d.ts.map +1 -1
- package/dist/context/manager.js +1 -1
- package/dist/context/types.d.ts +1 -1
- package/dist/context/types.d.ts.map +1 -1
- package/dist/context/utils.cjs +3 -3
- package/dist/context/utils.d.ts +1 -1
- package/dist/context/utils.d.ts.map +1 -1
- package/dist/context/utils.js +1 -1
- package/dist/events/index.d.ts +2 -2
- package/dist/events/index.d.ts.map +1 -1
- package/dist/index.browser.cjs +9 -9
- package/dist/index.browser.d.ts +4 -4
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/llm/auth/index.cjs +16 -0
- package/dist/llm/auth/index.d.ts +2 -0
- package/dist/llm/auth/index.d.ts.map +1 -0
- package/dist/llm/auth/index.js +0 -0
- package/dist/llm/auth/types.cjs +16 -0
- package/dist/llm/auth/types.d.ts +25 -0
- package/dist/llm/auth/types.d.ts.map +1 -0
- package/dist/llm/auth/types.js +0 -0
- package/dist/llm/curation-config.cjs +3 -3
- package/dist/llm/curation-config.d.ts +1 -1
- package/dist/llm/curation-config.js +3 -3
- package/dist/llm/curation.cjs +2 -2
- package/dist/llm/curation.d.ts +2 -2
- package/dist/llm/curation.d.ts.map +1 -1
- package/dist/llm/curation.js +1 -1
- package/dist/llm/errors.cjs +3 -3
- package/dist/llm/errors.d.ts +1 -1
- package/dist/llm/errors.d.ts.map +1 -1
- package/dist/llm/errors.js +1 -1
- package/dist/llm/executor/provider-options.cjs +22 -25
- package/dist/llm/executor/provider-options.d.ts +1 -1
- package/dist/llm/executor/provider-options.d.ts.map +1 -1
- package/dist/llm/executor/provider-options.js +17 -16
- package/dist/llm/executor/stream-processor.d.ts +1 -1
- package/dist/llm/executor/stream-processor.d.ts.map +1 -1
- package/dist/llm/executor/turn-executor.d.ts +1 -1
- package/dist/llm/executor/turn-executor.d.ts.map +1 -1
- package/dist/llm/executor/types.d.ts +1 -1
- package/dist/llm/executor/types.d.ts.map +1 -1
- package/dist/llm/formatters/vercel.cjs +2 -2
- package/dist/llm/formatters/vercel.d.ts +1 -1
- package/dist/llm/formatters/vercel.d.ts.map +1 -1
- package/dist/llm/index.cjs +0 -4
- package/dist/llm/index.d.ts +1 -2
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +0 -2
- package/dist/llm/registry/auto-update.cjs +5 -5
- package/dist/llm/registry/auto-update.d.ts.map +1 -1
- package/dist/llm/registry/auto-update.js +2 -2
- package/dist/llm/registry/index.cjs +96 -789
- package/dist/llm/registry/index.d.ts +4 -323
- package/dist/llm/registry/index.d.ts.map +1 -1
- package/dist/llm/registry/index.js +99 -762
- package/dist/llm/registry/sync.d.ts +2 -2
- package/dist/llm/registry/sync.d.ts.map +1 -1
- package/dist/llm/resolver.cjs +7 -6
- package/dist/llm/resolver.d.ts +1 -1
- package/dist/llm/resolver.js +4 -4
- package/dist/llm/schemas.cjs +14 -14
- package/dist/llm/schemas.d.ts +1 -1
- package/dist/llm/schemas.d.ts.map +1 -1
- package/dist/llm/schemas.js +5 -4
- package/dist/llm/services/factory.cjs +124 -33
- package/dist/llm/services/factory.d.ts.map +1 -1
- package/dist/llm/services/factory.js +128 -35
- package/dist/llm/services/types.d.ts +8 -1
- package/dist/llm/services/types.d.ts.map +1 -1
- package/dist/llm/usage-metadata.cjs +3 -3
- package/dist/llm/usage-metadata.d.ts +2 -2
- package/dist/llm/usage-metadata.d.ts.map +1 -1
- package/dist/llm/usage-metadata.js +1 -4
- package/dist/llm/usage-summary.d.ts +1 -1
- package/dist/llm/validation.cjs +4 -4
- package/dist/llm/validation.d.ts +1 -1
- package/dist/llm/validation.js +1 -1
- package/dist/session/chat-session.cjs +2 -12
- package/dist/session/chat-session.d.ts +2 -0
- package/dist/session/chat-session.d.ts.map +1 -1
- package/dist/session/chat-session.js +2 -13
- package/dist/session/session-manager.cjs +4 -1
- package/dist/session/session-manager.d.ts +5 -1
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +4 -1
- package/dist/utils/api-key-resolver.d.ts +1 -1
- package/dist/utils/api-key-resolver.d.ts.map +1 -1
- package/dist/utils/result.cjs +1 -1
- package/dist/utils/result.js +1 -1
- package/dist/utils/service-initializer.cjs +3 -0
- package/dist/utils/service-initializer.d.ts +2 -0
- package/dist/utils/service-initializer.d.ts.map +1 -1
- package/dist/utils/service-initializer.js +3 -0
- package/package.json +3 -2
- package/dist/llm/reasoning/anthropic-betas.cjs +0 -31
- package/dist/llm/reasoning/anthropic-betas.d.ts +0 -3
- package/dist/llm/reasoning/anthropic-betas.d.ts.map +0 -1
- package/dist/llm/reasoning/anthropic-betas.js +0 -7
- package/dist/llm/reasoning/anthropic-thinking.cjs +0 -79
- package/dist/llm/reasoning/anthropic-thinking.d.ts +0 -15
- package/dist/llm/reasoning/anthropic-thinking.d.ts.map +0 -1
- package/dist/llm/reasoning/anthropic-thinking.js +0 -52
- package/dist/llm/reasoning/openai-reasoning-effort.cjs +0 -86
- package/dist/llm/reasoning/openai-reasoning-effort.d.ts +0 -5
- package/dist/llm/reasoning/openai-reasoning-effort.d.ts.map +0 -1
- package/dist/llm/reasoning/openai-reasoning-effort.js +0 -61
- package/dist/llm/reasoning/profile.cjs +0 -113
- package/dist/llm/reasoning/profile.d.ts +0 -13
- package/dist/llm/reasoning/profile.d.ts.map +0 -1
- package/dist/llm/reasoning/profile.js +0 -92
- package/dist/llm/reasoning/profiles/anthropic.cjs +0 -61
- package/dist/llm/reasoning/profiles/anthropic.d.ts +0 -8
- package/dist/llm/reasoning/profiles/anthropic.d.ts.map +0 -1
- package/dist/llm/reasoning/profiles/anthropic.js +0 -45
- package/dist/llm/reasoning/profiles/bedrock.cjs +0 -54
- package/dist/llm/reasoning/profiles/bedrock.d.ts +0 -3
- package/dist/llm/reasoning/profiles/bedrock.d.ts.map +0 -1
- package/dist/llm/reasoning/profiles/bedrock.js +0 -36
- package/dist/llm/reasoning/profiles/google.cjs +0 -45
- package/dist/llm/reasoning/profiles/google.d.ts +0 -9
- package/dist/llm/reasoning/profiles/google.d.ts.map +0 -1
- package/dist/llm/reasoning/profiles/google.js +0 -21
- package/dist/llm/reasoning/profiles/openai-compatible.cjs +0 -39
- package/dist/llm/reasoning/profiles/openai-compatible.d.ts +0 -3
- package/dist/llm/reasoning/profiles/openai-compatible.d.ts.map +0 -1
- package/dist/llm/reasoning/profiles/openai-compatible.js +0 -16
- package/dist/llm/reasoning/profiles/openai.cjs +0 -41
- package/dist/llm/reasoning/profiles/openai.d.ts +0 -3
- package/dist/llm/reasoning/profiles/openai.d.ts.map +0 -1
- package/dist/llm/reasoning/profiles/openai.js +0 -18
- package/dist/llm/reasoning/profiles/openrouter.cjs +0 -83
- package/dist/llm/reasoning/profiles/openrouter.d.ts +0 -10
- package/dist/llm/reasoning/profiles/openrouter.d.ts.map +0 -1
- package/dist/llm/reasoning/profiles/openrouter.js +0 -59
- package/dist/llm/reasoning/profiles/shared.cjs +0 -80
- package/dist/llm/reasoning/profiles/shared.d.ts +0 -25
- package/dist/llm/reasoning/profiles/shared.d.ts.map +0 -1
- package/dist/llm/reasoning/profiles/shared.js +0 -53
- package/dist/llm/reasoning/profiles/vertex.cjs +0 -46
- package/dist/llm/reasoning/profiles/vertex.d.ts +0 -3
- package/dist/llm/reasoning/profiles/vertex.d.ts.map +0 -1
- package/dist/llm/reasoning/profiles/vertex.js +0 -23
- package/dist/llm/registry/models.generated.cjs +0 -10741
- package/dist/llm/registry/models.generated.d.ts +0 -2945
- package/dist/llm/registry/models.generated.d.ts.map +0 -1
- package/dist/llm/registry/models.generated.js +0 -10717
- package/dist/llm/registry/models.manual.cjs +0 -44
- package/dist/llm/registry/models.manual.d.ts +0 -22
- package/dist/llm/registry/models.manual.d.ts.map +0 -1
- package/dist/llm/registry/models.manual.js +0 -21
- package/dist/llm/types.cjs +0 -55
- package/dist/llm/types.d.ts +0 -39
- package/dist/llm/types.d.ts.map +0 -1
- package/dist/llm/types.js +0 -30
|
@@ -18,584 +18,60 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var registry_exports = {};
|
|
20
20
|
__export(registry_exports, {
|
|
21
|
-
DEFAULT_MAX_INPUT_TOKENS: () => DEFAULT_MAX_INPUT_TOKENS,
|
|
22
|
-
LLM_REGISTRY: () => LLM_REGISTRY,
|
|
23
|
-
MIME_TYPE_TO_FILE_TYPE: () => MIME_TYPE_TO_FILE_TYPE,
|
|
24
|
-
acceptsAnyModel: () => acceptsAnyModel,
|
|
25
|
-
calculateCost: () => calculateCost,
|
|
26
|
-
calculateCostBreakdown: () => calculateCostBreakdown,
|
|
27
21
|
getAllModelsForProvider: () => getAllModelsForProvider,
|
|
28
|
-
getAllSupportedModels: () => getAllSupportedModels,
|
|
29
|
-
getAllowedMimeTypes: () => getAllowedMimeTypes,
|
|
30
|
-
getDefaultModelForProvider: () => getDefaultModelForProvider,
|
|
31
22
|
getEffectiveMaxInputTokens: () => getEffectiveMaxInputTokens,
|
|
32
23
|
getMaxInputTokensForModel: () => getMaxInputTokensForModel,
|
|
33
|
-
getModelDisplayName: () => getModelDisplayName,
|
|
34
|
-
getModelPricing: () => getModelPricing,
|
|
35
|
-
getOpenRouterCandidateModelIds: () => getOpenRouterCandidateModelIds,
|
|
36
24
|
getProviderFromModel: () => getProviderFromModel,
|
|
37
25
|
getSupportedFileTypesForModel: () => getSupportedFileTypesForModel,
|
|
38
|
-
|
|
39
|
-
getSupportedProviders: () => getSupportedProviders,
|
|
40
|
-
hasAllRegistryModelsSupport: () => hasAllRegistryModelsSupport,
|
|
41
|
-
isModelValidForProvider: () => isModelValidForProvider,
|
|
42
|
-
isReasoningCapableModel: () => isReasoningCapableModel,
|
|
43
|
-
isValidProviderModel: () => isValidProviderModel,
|
|
44
|
-
modelSupportsFileType: () => modelSupportsFileType,
|
|
45
|
-
requiresApiKey: () => requiresApiKey,
|
|
46
|
-
requiresBaseURL: () => requiresBaseURL,
|
|
47
|
-
stripBedrockRegionPrefix: () => stripBedrockRegionPrefix,
|
|
48
|
-
supportsBaseURL: () => supportsBaseURL,
|
|
49
|
-
supportsCustomModels: () => supportsCustomModels,
|
|
50
|
-
transformModelNameForProvider: () => transformModelNameForProvider,
|
|
51
|
-
validateModelFileSupport: () => validateModelFileSupport
|
|
26
|
+
modelSupportsFileType: () => modelSupportsFileType
|
|
52
27
|
});
|
|
53
28
|
module.exports = __toCommonJS(registry_exports);
|
|
29
|
+
var import_llm = require("@dexto/llm");
|
|
54
30
|
var import_errors = require("../errors.js");
|
|
55
31
|
var import_error_codes = require("../error-codes.js");
|
|
56
32
|
var import_DextoRuntimeError = require("../../errors/DextoRuntimeError.js");
|
|
57
|
-
var import_types = require("../types.js");
|
|
58
33
|
var import_openrouter_model_registry = require("../providers/openrouter-model-registry.js");
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const LEGACY_MODEL_ID_ALIASES = {
|
|
62
|
-
anthropic: {
|
|
63
|
-
// Older Dexto configs/tests used "claude-4-{tier}-{date}".
|
|
64
|
-
// models.dev (and our generated snapshot) use "claude-{tier}-4-{date}".
|
|
65
|
-
"claude-4-sonnet-20250514": "claude-sonnet-4-20250514",
|
|
66
|
-
"claude-4-opus-20250514": "claude-opus-4-20250514"
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
function getNormalizedModelIdForLookup(provider, model) {
|
|
70
|
-
const stripped = stripBedrockRegionPrefix(model);
|
|
71
|
-
const lower = stripped.toLowerCase();
|
|
72
|
-
const aliases = LEGACY_MODEL_ID_ALIASES[provider];
|
|
73
|
-
return aliases?.[lower] ?? lower;
|
|
74
|
-
}
|
|
75
|
-
function mergeModels(base, extra) {
|
|
76
|
-
if (!extra || extra.length === 0) return base;
|
|
77
|
-
const merged = [...base];
|
|
78
|
-
const indexByName = /* @__PURE__ */ new Map();
|
|
79
|
-
for (let i = 0; i < merged.length; i++) {
|
|
80
|
-
indexByName.set(merged[i].name.toLowerCase(), i);
|
|
81
|
-
}
|
|
82
|
-
for (const m of extra) {
|
|
83
|
-
const key = m.name.toLowerCase();
|
|
84
|
-
const existingIndex = indexByName.get(key);
|
|
85
|
-
if (existingIndex != null) {
|
|
86
|
-
merged[existingIndex] = m;
|
|
87
|
-
} else {
|
|
88
|
-
indexByName.set(key, merged.length);
|
|
89
|
-
merged.push(m);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return merged;
|
|
93
|
-
}
|
|
94
|
-
const MIME_TYPE_TO_FILE_TYPE = {
|
|
95
|
-
"application/pdf": "pdf",
|
|
96
|
-
"audio/mp3": "audio",
|
|
97
|
-
"audio/mpeg": "audio",
|
|
98
|
-
"audio/wav": "audio",
|
|
99
|
-
"audio/x-wav": "audio",
|
|
100
|
-
"audio/wave": "audio",
|
|
101
|
-
"audio/webm": "audio",
|
|
102
|
-
"audio/ogg": "audio",
|
|
103
|
-
"audio/m4a": "audio",
|
|
104
|
-
"audio/aac": "audio",
|
|
105
|
-
"video/mp4": "video",
|
|
106
|
-
"video/webm": "video",
|
|
107
|
-
"video/ogg": "video",
|
|
108
|
-
"video/quicktime": "video",
|
|
109
|
-
"video/x-msvideo": "video",
|
|
110
|
-
"video/x-matroska": "video",
|
|
111
|
-
// Common image MIME types
|
|
112
|
-
"image/jpeg": "image",
|
|
113
|
-
"image/jpg": "image",
|
|
114
|
-
"image/png": "image",
|
|
115
|
-
"image/webp": "image",
|
|
116
|
-
"image/gif": "image",
|
|
117
|
-
// Common document, presentation, and spreadsheet MIME types
|
|
118
|
-
"text/plain": "document",
|
|
119
|
-
"text/markdown": "document",
|
|
120
|
-
"text/html": "document",
|
|
121
|
-
"text/xml": "document",
|
|
122
|
-
"text/csv": "document",
|
|
123
|
-
"text/tab-separated-values": "document",
|
|
124
|
-
"application/json": "document",
|
|
125
|
-
"application/xml": "document",
|
|
126
|
-
"application/msword": "document",
|
|
127
|
-
"application/rtf": "document",
|
|
128
|
-
"text/rtf": "document",
|
|
129
|
-
"application/vnd.oasis.opendocument.text": "document",
|
|
130
|
-
"application/vnd.ms-powerpoint": "document",
|
|
131
|
-
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "document",
|
|
132
|
-
"application/vnd.ms-excel": "document",
|
|
133
|
-
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "document",
|
|
134
|
-
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "document"
|
|
135
|
-
};
|
|
136
|
-
const GENERIC_UPLOAD_FILE_TYPES = [
|
|
137
|
-
"pdf",
|
|
138
|
-
"image",
|
|
139
|
-
"audio",
|
|
140
|
-
"video",
|
|
141
|
-
"document"
|
|
142
|
-
];
|
|
143
|
-
function getAllowedMimeTypes() {
|
|
144
|
-
return Object.keys(MIME_TYPE_TO_FILE_TYPE);
|
|
34
|
+
function isUnknownCatalogModelError(error) {
|
|
35
|
+
return error instanceof import_llm.LlmCatalogError && error.code === "MODEL_UNKNOWN";
|
|
145
36
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
},
|
|
155
|
-
"openai-compatible": {
|
|
156
|
-
models: [],
|
|
157
|
-
// Empty - accepts any model name for custom endpoints
|
|
158
|
-
baseURLSupport: "required",
|
|
159
|
-
supportedFileTypes: GENERIC_UPLOAD_FILE_TYPES,
|
|
160
|
-
// Allow all generic file categories for custom endpoints
|
|
161
|
-
supportsCustomModels: true
|
|
162
|
-
},
|
|
163
|
-
anthropic: {
|
|
164
|
-
models: import_models_generated.MODELS_BY_PROVIDER.anthropic,
|
|
165
|
-
baseURLSupport: "none",
|
|
166
|
-
supportedFileTypes: [],
|
|
167
|
-
// No defaults - models must explicitly specify support
|
|
168
|
-
modelsDev: import_models_generated.MODELS_DEV_PROVIDER_METADATA_BY_PROVIDER.anthropic
|
|
169
|
-
},
|
|
170
|
-
google: {
|
|
171
|
-
models: import_models_generated.MODELS_BY_PROVIDER.google,
|
|
172
|
-
baseURLSupport: "none",
|
|
173
|
-
supportedFileTypes: [],
|
|
174
|
-
// No defaults - models must explicitly specify support
|
|
175
|
-
modelsDev: import_models_generated.MODELS_DEV_PROVIDER_METADATA_BY_PROVIDER.google
|
|
176
|
-
},
|
|
177
|
-
// https://console.groq.com/docs/models
|
|
178
|
-
groq: {
|
|
179
|
-
models: import_models_generated.MODELS_BY_PROVIDER.groq,
|
|
180
|
-
baseURLSupport: "none",
|
|
181
|
-
supportedFileTypes: [],
|
|
182
|
-
// Groq currently doesn't support file uploads
|
|
183
|
-
modelsDev: import_models_generated.MODELS_DEV_PROVIDER_METADATA_BY_PROVIDER.groq
|
|
184
|
-
},
|
|
185
|
-
// https://docs.x.ai/docs/models
|
|
186
|
-
// Note: XAI API only supports image uploads (JPG/PNG up to 20MB), not PDFs
|
|
187
|
-
xai: {
|
|
188
|
-
models: import_models_generated.MODELS_BY_PROVIDER.xai,
|
|
189
|
-
baseURLSupport: "none",
|
|
190
|
-
supportedFileTypes: [],
|
|
191
|
-
// No defaults - models must explicitly specify support
|
|
192
|
-
modelsDev: import_models_generated.MODELS_DEV_PROVIDER_METADATA_BY_PROVIDER.xai
|
|
193
|
-
},
|
|
194
|
-
// https://docs.cohere.com/reference/models
|
|
195
|
-
cohere: {
|
|
196
|
-
models: import_models_generated.MODELS_BY_PROVIDER.cohere,
|
|
197
|
-
baseURLSupport: "none",
|
|
198
|
-
supportedFileTypes: [],
|
|
199
|
-
// No defaults - models must explicitly specify support
|
|
200
|
-
modelsDev: import_models_generated.MODELS_DEV_PROVIDER_METADATA_BY_PROVIDER.cohere
|
|
201
|
-
},
|
|
202
|
-
// https://platform.minimax.io/docs/api-reference/text-openai-api
|
|
203
|
-
// MiniMax provides an OpenAI-compatible endpoint at https://api.minimax.chat/v1
|
|
204
|
-
minimax: {
|
|
205
|
-
models: import_models_generated.MODELS_BY_PROVIDER.minimax,
|
|
206
|
-
baseURLSupport: "none",
|
|
207
|
-
supportedFileTypes: [],
|
|
208
|
-
// No defaults - models must explicitly specify support
|
|
209
|
-
modelsDev: import_models_generated.MODELS_DEV_PROVIDER_METADATA_BY_PROVIDER.minimax
|
|
210
|
-
},
|
|
211
|
-
// https://open.bigmodel.cn/dev/api/normal-model/glm-4
|
|
212
|
-
// GLM (Zhipu AI) provides an OpenAI-compatible endpoint
|
|
213
|
-
glm: {
|
|
214
|
-
models: import_models_generated.MODELS_BY_PROVIDER.glm,
|
|
215
|
-
baseURLSupport: "none",
|
|
216
|
-
supportedFileTypes: [],
|
|
217
|
-
// No defaults - models must explicitly specify support
|
|
218
|
-
modelsDev: import_models_generated.MODELS_DEV_PROVIDER_METADATA_BY_PROVIDER.glm
|
|
219
|
-
},
|
|
220
|
-
// https://openrouter.ai/docs
|
|
221
|
-
// OpenRouter is a unified API gateway providing access to 100+ models from various providers.
|
|
222
|
-
// Model validation is handled dynamically via openrouter-model-registry.ts
|
|
223
|
-
openrouter: {
|
|
224
|
-
models: import_models_generated.MODELS_BY_PROVIDER.openrouter,
|
|
225
|
-
baseURLSupport: "none",
|
|
226
|
-
// Fixed endpoint - baseURL auto-injected in resolver, no user override allowed
|
|
227
|
-
supportedFileTypes: GENERIC_UPLOAD_FILE_TYPES,
|
|
228
|
-
// Allow all generic file categories - user assumes responsibility
|
|
229
|
-
supportsCustomModels: true,
|
|
230
|
-
supportsAllRegistryModels: true,
|
|
231
|
-
// Can serve models from all other providers
|
|
232
|
-
modelsDev: import_models_generated.MODELS_DEV_PROVIDER_METADATA_BY_PROVIDER.openrouter
|
|
233
|
-
},
|
|
234
|
-
// https://docs.litellm.ai/
|
|
235
|
-
// LiteLLM is an OpenAI-compatible proxy that unifies 100+ LLM providers.
|
|
236
|
-
// User must host their own LiteLLM proxy and provide the baseURL.
|
|
237
|
-
litellm: {
|
|
238
|
-
models: [],
|
|
239
|
-
baseURLSupport: "required",
|
|
240
|
-
supportedFileTypes: GENERIC_UPLOAD_FILE_TYPES,
|
|
241
|
-
supportsCustomModels: true
|
|
242
|
-
},
|
|
243
|
-
// https://glama.ai/
|
|
244
|
-
// Glama is an OpenAI-compatible gateway providing unified access to multiple LLM providers.
|
|
245
|
-
// Fixed endpoint: https://glama.ai/api/gateway/openai/v1
|
|
246
|
-
glama: {
|
|
247
|
-
models: [],
|
|
248
|
-
baseURLSupport: "none",
|
|
249
|
-
supportedFileTypes: GENERIC_UPLOAD_FILE_TYPES,
|
|
250
|
-
supportsCustomModels: true
|
|
251
|
-
},
|
|
252
|
-
// https://cloud.google.com/vertex-ai
|
|
253
|
-
vertex: {
|
|
254
|
-
models: import_models_generated.MODELS_BY_PROVIDER.vertex,
|
|
255
|
-
baseURLSupport: "none",
|
|
256
|
-
supportedFileTypes: [],
|
|
257
|
-
// No defaults - models must explicitly specify support
|
|
258
|
-
modelsDev: import_models_generated.MODELS_DEV_PROVIDER_METADATA_BY_PROVIDER.vertex
|
|
259
|
-
},
|
|
260
|
-
// https://docs.aws.amazon.com/bedrock/latest/userguide/models.html
|
|
261
|
-
bedrock: {
|
|
262
|
-
models: import_models_generated.MODELS_BY_PROVIDER.bedrock,
|
|
263
|
-
baseURLSupport: "none",
|
|
264
|
-
supportedFileTypes: [],
|
|
265
|
-
// No defaults - models must explicitly specify support
|
|
266
|
-
supportsCustomModels: true,
|
|
267
|
-
modelsDev: import_models_generated.MODELS_DEV_PROVIDER_METADATA_BY_PROVIDER.bedrock
|
|
268
|
-
},
|
|
269
|
-
// Native local model execution via node-llama-cpp
|
|
270
|
-
local: {
|
|
271
|
-
models: [],
|
|
272
|
-
// Populated dynamically from local model registry
|
|
273
|
-
baseURLSupport: "none",
|
|
274
|
-
supportedFileTypes: ["image"],
|
|
275
|
-
supportsCustomModels: true
|
|
276
|
-
},
|
|
277
|
-
// Ollama server integration
|
|
278
|
-
ollama: {
|
|
279
|
-
models: [],
|
|
280
|
-
// Populated dynamically from Ollama API
|
|
281
|
-
baseURLSupport: "optional",
|
|
282
|
-
supportedFileTypes: ["image"],
|
|
283
|
-
supportsCustomModels: true
|
|
284
|
-
},
|
|
285
|
-
// Dexto Gateway - OpenAI-compatible proxy through api.dexto.ai
|
|
286
|
-
// Routes to OpenRouter with per-request billing (balance decrement)
|
|
287
|
-
// Requires DEXTO_API_KEY from dexto login
|
|
288
|
-
//
|
|
289
|
-
// Model IDs are in OpenRouter format (e.g., 'anthropic/claude-sonnet-4.5')
|
|
290
|
-
"dexto-nova": {
|
|
291
|
-
models: [
|
|
292
|
-
// Claude models (Anthropic via OpenRouter)
|
|
293
|
-
{
|
|
294
|
-
name: "anthropic/claude-haiku-4.5",
|
|
295
|
-
displayName: "Claude Haiku 4.5",
|
|
296
|
-
maxInputTokens: 2e5,
|
|
297
|
-
default: true,
|
|
298
|
-
supportedFileTypes: ["pdf", "image"],
|
|
299
|
-
pricing: {
|
|
300
|
-
inputPerM: 1,
|
|
301
|
-
outputPerM: 5,
|
|
302
|
-
cacheWritePerM: 1.25,
|
|
303
|
-
cacheReadPerM: 0.1,
|
|
304
|
-
currency: "USD",
|
|
305
|
-
unit: "per_million_tokens"
|
|
306
|
-
}
|
|
307
|
-
},
|
|
308
|
-
{
|
|
309
|
-
name: "anthropic/claude-sonnet-4.5",
|
|
310
|
-
displayName: "Claude Sonnet 4.5",
|
|
311
|
-
maxInputTokens: 2e5,
|
|
312
|
-
supportedFileTypes: ["pdf", "image"],
|
|
313
|
-
pricing: {
|
|
314
|
-
inputPerM: 3,
|
|
315
|
-
outputPerM: 15,
|
|
316
|
-
cacheWritePerM: 3.75,
|
|
317
|
-
cacheReadPerM: 0.3,
|
|
318
|
-
currency: "USD",
|
|
319
|
-
unit: "per_million_tokens"
|
|
320
|
-
}
|
|
321
|
-
},
|
|
322
|
-
{
|
|
323
|
-
name: "anthropic/claude-opus-4.5",
|
|
324
|
-
displayName: "Claude Opus 4.5",
|
|
325
|
-
maxInputTokens: 2e5,
|
|
326
|
-
supportedFileTypes: ["pdf", "image"],
|
|
327
|
-
pricing: {
|
|
328
|
-
inputPerM: 5,
|
|
329
|
-
outputPerM: 25,
|
|
330
|
-
cacheWritePerM: 6.25,
|
|
331
|
-
cacheReadPerM: 0.5,
|
|
332
|
-
currency: "USD",
|
|
333
|
-
unit: "per_million_tokens"
|
|
334
|
-
}
|
|
335
|
-
},
|
|
336
|
-
// OpenAI models (via OpenRouter)
|
|
337
|
-
{
|
|
338
|
-
name: "openai/gpt-5.2",
|
|
339
|
-
displayName: "GPT-5.2",
|
|
340
|
-
maxInputTokens: 4e5,
|
|
341
|
-
supportedFileTypes: ["pdf", "image", "document"],
|
|
342
|
-
pricing: {
|
|
343
|
-
inputPerM: 1.75,
|
|
344
|
-
outputPerM: 14,
|
|
345
|
-
cacheReadPerM: 0.175,
|
|
346
|
-
currency: "USD",
|
|
347
|
-
unit: "per_million_tokens"
|
|
348
|
-
}
|
|
349
|
-
},
|
|
350
|
-
{
|
|
351
|
-
name: "openai/gpt-5.2-codex",
|
|
352
|
-
displayName: "GPT-5.2 Codex",
|
|
353
|
-
maxInputTokens: 4e5,
|
|
354
|
-
supportedFileTypes: ["pdf", "image", "document"],
|
|
355
|
-
pricing: {
|
|
356
|
-
inputPerM: 1.75,
|
|
357
|
-
outputPerM: 14,
|
|
358
|
-
cacheReadPerM: 0.175,
|
|
359
|
-
currency: "USD",
|
|
360
|
-
unit: "per_million_tokens"
|
|
361
|
-
}
|
|
362
|
-
},
|
|
363
|
-
// Google models (via OpenRouter)
|
|
364
|
-
{
|
|
365
|
-
name: "google/gemini-3-pro-preview",
|
|
366
|
-
displayName: "Gemini 3 Pro",
|
|
367
|
-
maxInputTokens: 1048576,
|
|
368
|
-
supportedFileTypes: ["pdf", "image", "audio", "video", "document"]
|
|
369
|
-
},
|
|
370
|
-
{
|
|
371
|
-
name: "google/gemini-3-flash-preview",
|
|
372
|
-
displayName: "Gemini 3 Flash",
|
|
373
|
-
maxInputTokens: 1048576,
|
|
374
|
-
supportedFileTypes: ["pdf", "image", "audio", "video", "document"]
|
|
375
|
-
},
|
|
376
|
-
// Free models (via OpenRouter)
|
|
377
|
-
{
|
|
378
|
-
name: "qwen/qwen3-coder:free",
|
|
379
|
-
displayName: "Qwen3 Coder (Free)",
|
|
380
|
-
maxInputTokens: 262e3,
|
|
381
|
-
supportedFileTypes: []
|
|
382
|
-
},
|
|
383
|
-
{
|
|
384
|
-
name: "deepseek/deepseek-r1-0528:free",
|
|
385
|
-
displayName: "DeepSeek R1 (Free)",
|
|
386
|
-
maxInputTokens: 163840,
|
|
387
|
-
supportedFileTypes: []
|
|
388
|
-
},
|
|
389
|
-
// Other models (via OpenRouter)
|
|
390
|
-
{
|
|
391
|
-
name: "z-ai/glm-4.7",
|
|
392
|
-
displayName: "GLM 4.7",
|
|
393
|
-
maxInputTokens: 202752,
|
|
394
|
-
supportedFileTypes: [],
|
|
395
|
-
pricing: {
|
|
396
|
-
inputPerM: 0.27,
|
|
397
|
-
outputPerM: 1.1,
|
|
398
|
-
currency: "USD",
|
|
399
|
-
unit: "per_million_tokens"
|
|
400
|
-
}
|
|
401
|
-
},
|
|
402
|
-
{
|
|
403
|
-
name: "minimax/minimax-m2.5",
|
|
404
|
-
displayName: "MiniMax M2.5",
|
|
405
|
-
maxInputTokens: 204800,
|
|
406
|
-
supportedFileTypes: [],
|
|
407
|
-
pricing: {
|
|
408
|
-
inputPerM: 0.3,
|
|
409
|
-
outputPerM: 1.2,
|
|
410
|
-
currency: "USD",
|
|
411
|
-
unit: "per_million_tokens"
|
|
412
|
-
}
|
|
413
|
-
},
|
|
414
|
-
{
|
|
415
|
-
name: "moonshotai/kimi-k2.5",
|
|
416
|
-
displayName: "Kimi K2.5",
|
|
417
|
-
maxInputTokens: 262144,
|
|
418
|
-
supportedFileTypes: ["image"],
|
|
419
|
-
pricing: {
|
|
420
|
-
inputPerM: 0.5,
|
|
421
|
-
outputPerM: 2.5,
|
|
422
|
-
currency: "USD",
|
|
423
|
-
unit: "per_million_tokens"
|
|
424
|
-
}
|
|
37
|
+
function cloneModel(model) {
|
|
38
|
+
return {
|
|
39
|
+
...model,
|
|
40
|
+
supportedFileTypes: [...model.supportedFileTypes],
|
|
41
|
+
...model.modalities ? {
|
|
42
|
+
modalities: {
|
|
43
|
+
input: [...model.modalities.input],
|
|
44
|
+
output: [...model.modalities.output]
|
|
425
45
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
432
|
-
};
|
|
433
|
-
function stripBedrockRegionPrefix(model) {
|
|
434
|
-
if (model.startsWith("eu.") || model.startsWith("us.")) {
|
|
435
|
-
return model.slice(3);
|
|
436
|
-
}
|
|
437
|
-
if (model.startsWith("global.")) {
|
|
438
|
-
return model.slice(7);
|
|
439
|
-
}
|
|
440
|
-
return model;
|
|
441
|
-
}
|
|
442
|
-
function getDefaultModelForProvider(provider) {
|
|
443
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
444
|
-
const explicit = providerInfo.models.find((m) => m.default)?.name;
|
|
445
|
-
if (explicit) return explicit;
|
|
446
|
-
if (providerInfo.models.length === 0) return null;
|
|
447
|
-
const sorted = [...providerInfo.models].sort((a, b) => a.name.localeCompare(b.name));
|
|
448
|
-
return sorted[0]?.name ?? null;
|
|
449
|
-
}
|
|
450
|
-
function getSupportedProviders() {
|
|
451
|
-
return [...import_types.LLM_PROVIDERS];
|
|
452
|
-
}
|
|
453
|
-
function getSupportedModels(provider) {
|
|
454
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
455
|
-
return providerInfo.models.map((m) => m.name);
|
|
456
|
-
}
|
|
457
|
-
function getMaxInputTokensForModel(provider, model, logger) {
|
|
458
|
-
const modelInfo = findModelInfo(provider, model);
|
|
459
|
-
if (!modelInfo) {
|
|
460
|
-
if ((provider === "openrouter" || provider === "dexto-nova") && model.includes("/")) {
|
|
461
|
-
const contextLength = (0, import_openrouter_model_registry.getOpenRouterModelContextLength)(model);
|
|
462
|
-
if (typeof contextLength === "number") {
|
|
463
|
-
logger?.debug(
|
|
464
|
-
`Using max tokens from OpenRouter cache for ${provider}/${model}: ${contextLength}`
|
|
465
|
-
);
|
|
466
|
-
return contextLength;
|
|
46
|
+
} : {},
|
|
47
|
+
...model.pricing ? {
|
|
48
|
+
pricing: {
|
|
49
|
+
...model.pricing,
|
|
50
|
+
...model.pricing.contextOver200kPerM ? { contextOver200kPerM: { ...model.pricing.contextOver200kPerM } } : {}
|
|
467
51
|
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
);
|
|
473
|
-
throw import_errors.LLMError.unknownModel(provider, model);
|
|
474
|
-
}
|
|
475
|
-
logger?.debug(`Found max tokens for ${provider}/${model}: ${modelInfo.maxInputTokens}`);
|
|
476
|
-
return modelInfo.maxInputTokens;
|
|
477
|
-
}
|
|
478
|
-
function isValidProviderModel(provider, model) {
|
|
479
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
480
|
-
const normalizedModel = getNormalizedModelIdForLookup(provider, model);
|
|
481
|
-
return providerInfo.models.some((m) => m.name.toLowerCase() === normalizedModel);
|
|
482
|
-
}
|
|
483
|
-
function getProviderFromModel(model) {
|
|
484
|
-
if (model.includes("/")) {
|
|
485
|
-
throw import_errors.LLMError.modelProviderUnknown(model);
|
|
486
|
-
}
|
|
487
|
-
for (const provider of import_types.LLM_PROVIDERS) {
|
|
488
|
-
const info = LLM_REGISTRY[provider];
|
|
489
|
-
const normalizedModel = getNormalizedModelIdForLookup(provider, model);
|
|
490
|
-
if (info.models.some((m) => m.name.toLowerCase() === normalizedModel)) {
|
|
491
|
-
return provider;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
throw import_errors.LLMError.modelProviderUnknown(model);
|
|
495
|
-
}
|
|
496
|
-
function getAllSupportedModels() {
|
|
497
|
-
return Object.values(LLM_REGISTRY).flatMap((info) => info.models.map((m) => m.name));
|
|
498
|
-
}
|
|
499
|
-
function supportsBaseURL(provider) {
|
|
500
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
501
|
-
return providerInfo.baseURLSupport !== "none";
|
|
502
|
-
}
|
|
503
|
-
function requiresBaseURL(provider) {
|
|
504
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
505
|
-
return providerInfo.baseURLSupport === "required";
|
|
506
|
-
}
|
|
507
|
-
function acceptsAnyModel(provider) {
|
|
508
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
509
|
-
return providerInfo.models.length === 0;
|
|
510
|
-
}
|
|
511
|
-
function supportsCustomModels(provider) {
|
|
512
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
513
|
-
return providerInfo.supportsCustomModels === true;
|
|
514
|
-
}
|
|
515
|
-
function hasAllRegistryModelsSupport(provider) {
|
|
516
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
517
|
-
return providerInfo.supportsAllRegistryModels === true;
|
|
518
|
-
}
|
|
519
|
-
const OPENROUTER_PREFIX_BY_PROVIDER = {
|
|
520
|
-
openai: "openai",
|
|
521
|
-
anthropic: "anthropic",
|
|
522
|
-
google: "google",
|
|
523
|
-
xai: "x-ai",
|
|
524
|
-
cohere: "cohere",
|
|
525
|
-
minimax: "minimax",
|
|
526
|
-
glm: "z-ai"
|
|
527
|
-
};
|
|
528
|
-
function getOpenRouterModelIdSet() {
|
|
529
|
-
return new Set(LLM_REGISTRY.openrouter.models.map((m) => m.name.toLowerCase()));
|
|
530
|
-
}
|
|
531
|
-
function getOpenRouterCandidateModelIds(model, originalProvider) {
|
|
532
|
-
if (model.includes("/")) return [model];
|
|
533
|
-
const prefix = OPENROUTER_PREFIX_BY_PROVIDER[originalProvider];
|
|
534
|
-
if (!prefix) return [];
|
|
535
|
-
if (originalProvider === "anthropic") {
|
|
536
|
-
const noDate = model.replace(/-\d{8}.*$/i, "");
|
|
537
|
-
const dotted = noDate.replace(/-(\d)-(\d)\b/g, "-$1.$2");
|
|
538
|
-
return [`${prefix}/${dotted}`, `${prefix}/${noDate}`, `${prefix}/${model}`];
|
|
539
|
-
}
|
|
540
|
-
if (originalProvider === "google") {
|
|
541
|
-
if (!/^gemini-/i.test(model)) {
|
|
542
|
-
return [`${prefix}/${model}`];
|
|
543
|
-
}
|
|
544
|
-
return [`${prefix}/${model}`, `${prefix}/${model}-001`];
|
|
545
|
-
}
|
|
546
|
-
return [`${prefix}/${model}`];
|
|
547
|
-
}
|
|
548
|
-
function pickExistingOpenRouterModelId(candidates) {
|
|
549
|
-
const openrouterSet = getOpenRouterModelIdSet();
|
|
550
|
-
for (const candidate of candidates) {
|
|
551
|
-
if (openrouterSet.has(candidate.toLowerCase())) {
|
|
552
|
-
return candidate;
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
return null;
|
|
556
|
-
}
|
|
557
|
-
function findModelInfo(provider, model) {
|
|
558
|
-
if (provider === "openrouter" && model.includes("/")) {
|
|
559
|
-
const dynamicOpenRouterModel = getOpenRouterGatewayModelById(model);
|
|
560
|
-
if (dynamicOpenRouterModel) return dynamicOpenRouterModel;
|
|
561
|
-
}
|
|
562
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
563
|
-
const normalizedModel = getNormalizedModelIdForLookup(provider, model);
|
|
564
|
-
const direct = providerInfo.models.find((m) => m.name.toLowerCase() === normalizedModel);
|
|
565
|
-
if (direct) return direct;
|
|
566
|
-
if (provider !== "openrouter" && hasAllRegistryModelsSupport(provider) && model.includes("/")) {
|
|
567
|
-
const openrouterModel = getOpenRouterGatewayModelById(model);
|
|
568
|
-
if (openrouterModel) return openrouterModel;
|
|
569
|
-
}
|
|
570
|
-
return null;
|
|
571
|
-
}
|
|
572
|
-
function ensureOpenRouterCatalogRefreshScheduled() {
|
|
573
|
-
const cacheInfo = (0, import_openrouter_model_registry.getOpenRouterModelCacheInfo)();
|
|
574
|
-
if (cacheInfo.modelCount === 0) {
|
|
575
|
-
(0, import_openrouter_model_registry.scheduleOpenRouterModelRefresh)({ force: true });
|
|
576
|
-
} else if (!cacheInfo.isFresh) {
|
|
577
|
-
(0, import_openrouter_model_registry.scheduleOpenRouterModelRefresh)();
|
|
578
|
-
}
|
|
52
|
+
} : {},
|
|
53
|
+
...model.providerMetadata ? { providerMetadata: { ...model.providerMetadata } } : {},
|
|
54
|
+
...model.interleaved && model.interleaved !== true ? { interleaved: { ...model.interleaved } } : {}
|
|
55
|
+
};
|
|
579
56
|
}
|
|
580
57
|
function findOpenRouterSnapshotModelById(modelId) {
|
|
581
58
|
const normalized = modelId.toLowerCase();
|
|
582
|
-
return LLM_REGISTRY.openrouter.models.find((m) => m.name.toLowerCase() === normalized) ?? null;
|
|
59
|
+
return import_llm.LLM_REGISTRY.openrouter.models.find((m) => m.name.toLowerCase() === normalized) ?? null;
|
|
583
60
|
}
|
|
584
61
|
function buildOpenRouterGatewayModelInfo(cachedModel, snapshot) {
|
|
585
|
-
const providerDefaults = LLM_REGISTRY.openrouter.supportedFileTypes;
|
|
586
62
|
const displayName = snapshot?.displayName ?? cachedModel.displayName;
|
|
587
|
-
const supportedFileTypes = snapshot?.supportedFileTypes ??
|
|
588
|
-
const maxInputTokens =
|
|
589
|
-
const inferredReasoning = cachedModel.supportedParameters?.includes("reasoning")
|
|
590
|
-
const inferredSupportsTemperature = cachedModel.supportedParameters?.includes("temperature")
|
|
591
|
-
return {
|
|
63
|
+
const supportedFileTypes = snapshot?.supportedFileTypes ?? import_llm.LLM_REGISTRY.openrouter.supportedFileTypes;
|
|
64
|
+
const maxInputTokens = cachedModel.contextLength > 0 ? cachedModel.contextLength : snapshot?.maxInputTokens ?? import_llm.DEFAULT_MAX_INPUT_TOKENS;
|
|
65
|
+
const inferredReasoning = cachedModel.supportedParameters?.includes("reasoning");
|
|
66
|
+
const inferredSupportsTemperature = cachedModel.supportedParameters?.includes("temperature");
|
|
67
|
+
return cloneModel({
|
|
592
68
|
name: snapshot?.name ?? cachedModel.id,
|
|
593
69
|
maxInputTokens,
|
|
594
70
|
supportedFileTypes,
|
|
595
71
|
...snapshot?.default ? { default: true } : {},
|
|
596
72
|
...displayName ? { displayName } : {},
|
|
597
|
-
...typeof snapshot?.reasoning === "boolean" ? { reasoning: snapshot.reasoning } :
|
|
598
|
-
...typeof snapshot?.supportsTemperature === "boolean" ? { supportsTemperature: snapshot.supportsTemperature } :
|
|
73
|
+
...typeof snapshot?.reasoning === "boolean" ? { reasoning: snapshot.reasoning } : inferredReasoning === true ? { reasoning: true } : {},
|
|
74
|
+
...typeof snapshot?.supportsTemperature === "boolean" ? { supportsTemperature: snapshot.supportsTemperature } : inferredSupportsTemperature === true ? { supportsTemperature: true } : {},
|
|
599
75
|
...typeof snapshot?.supportsInterleaved === "boolean" ? { supportsInterleaved: snapshot.supportsInterleaved } : {},
|
|
600
76
|
...snapshot?.releaseDate ? { releaseDate: snapshot.releaseDate } : {},
|
|
601
77
|
...typeof snapshot?.supportsToolCall === "boolean" ? { supportsToolCall: snapshot.supportsToolCall } : {},
|
|
@@ -604,155 +80,89 @@ function buildOpenRouterGatewayModelInfo(cachedModel, snapshot) {
|
|
|
604
80
|
...snapshot?.providerMetadata ? { providerMetadata: snapshot.providerMetadata } : {},
|
|
605
81
|
...snapshot?.interleaved ? { interleaved: snapshot.interleaved } : {},
|
|
606
82
|
...snapshot?.pricing ? { pricing: snapshot.pricing } : {}
|
|
607
|
-
};
|
|
608
|
-
}
|
|
609
|
-
function getOpenRouterGatewayModelById(modelId) {
|
|
610
|
-
ensureOpenRouterCatalogRefreshScheduled();
|
|
611
|
-
const snapshot = findOpenRouterSnapshotModelById(modelId);
|
|
612
|
-
const cached = (0, import_openrouter_model_registry.getCachedOpenRouterModelsWithInfo)();
|
|
613
|
-
if (!cached || cached.length === 0) {
|
|
614
|
-
return snapshot ? { ...snapshot } : null;
|
|
615
|
-
}
|
|
616
|
-
const normalized = modelId.toLowerCase();
|
|
617
|
-
const cachedModel = cached.find((m) => m.id.toLowerCase() === normalized);
|
|
618
|
-
if (!cachedModel) return snapshot ? { ...snapshot } : null;
|
|
619
|
-
return buildOpenRouterGatewayModelInfo(cachedModel, snapshot);
|
|
83
|
+
});
|
|
620
84
|
}
|
|
621
85
|
function getOpenRouterGatewayCatalogModels() {
|
|
622
|
-
ensureOpenRouterCatalogRefreshScheduled();
|
|
623
86
|
const cached = (0, import_openrouter_model_registry.getCachedOpenRouterModelsWithInfo)();
|
|
624
87
|
if (!cached || cached.length === 0) {
|
|
625
|
-
return LLM_REGISTRY.openrouter.models.map(
|
|
88
|
+
return import_llm.LLM_REGISTRY.openrouter.models.map(cloneModel);
|
|
626
89
|
}
|
|
627
|
-
|
|
90
|
+
return cached.map(
|
|
628
91
|
(cachedModel) => buildOpenRouterGatewayModelInfo(
|
|
629
92
|
cachedModel,
|
|
630
93
|
findOpenRouterSnapshotModelById(cachedModel.id)
|
|
631
94
|
)
|
|
632
95
|
).sort((a, b) => a.name.localeCompare(b.name));
|
|
633
|
-
return models;
|
|
634
96
|
}
|
|
635
97
|
function getAllModelsForProvider(provider) {
|
|
636
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
637
98
|
if (provider === "openrouter") {
|
|
638
|
-
return getOpenRouterGatewayCatalogModels().map((
|
|
639
|
-
...
|
|
99
|
+
return getOpenRouterGatewayCatalogModels().map((model) => ({
|
|
100
|
+
...model,
|
|
640
101
|
originalProvider: "openrouter"
|
|
641
102
|
}));
|
|
642
103
|
}
|
|
643
|
-
if (!
|
|
644
|
-
return
|
|
104
|
+
if (!(0, import_llm.hasAllRegistryModelsSupport)(provider)) {
|
|
105
|
+
return (0, import_llm.getAllModelsForProvider)(provider);
|
|
645
106
|
}
|
|
646
107
|
const allModels = [];
|
|
647
108
|
const seen = /* @__PURE__ */ new Set();
|
|
648
|
-
for (const model of
|
|
109
|
+
for (const model of import_llm.LLM_REGISTRY[provider].models) {
|
|
649
110
|
const key = model.name.toLowerCase();
|
|
650
111
|
if (seen.has(key)) continue;
|
|
651
112
|
seen.add(key);
|
|
652
|
-
allModels.push({ ...model, originalProvider: provider });
|
|
113
|
+
allModels.push({ ...cloneModel(model), originalProvider: provider });
|
|
653
114
|
}
|
|
654
115
|
for (const model of getOpenRouterGatewayCatalogModels()) {
|
|
655
116
|
const key = model.name.toLowerCase();
|
|
656
117
|
if (seen.has(key)) continue;
|
|
657
118
|
seen.add(key);
|
|
658
|
-
allModels.push({ ...model, originalProvider: "openrouter" });
|
|
119
|
+
allModels.push({ ...cloneModel(model), originalProvider: "openrouter" });
|
|
659
120
|
}
|
|
660
121
|
return allModels;
|
|
661
122
|
}
|
|
662
|
-
function
|
|
663
|
-
|
|
664
|
-
return model;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
return model;
|
|
671
|
-
}
|
|
672
|
-
const candidates = getOpenRouterCandidateModelIds(model, originalProvider);
|
|
673
|
-
if (candidates.length === 0) return model;
|
|
674
|
-
return pickExistingOpenRouterModelId(candidates) ?? candidates[0];
|
|
675
|
-
}
|
|
676
|
-
function isModelValidForProvider(provider, model) {
|
|
677
|
-
const providerInfo = LLM_REGISTRY[provider];
|
|
678
|
-
const normalizedModel = getNormalizedModelIdForLookup(provider, model);
|
|
679
|
-
if (providerInfo.models.some((m) => m.name.toLowerCase() === normalizedModel)) {
|
|
680
|
-
return true;
|
|
681
|
-
}
|
|
682
|
-
if (providerInfo.supportsAllRegistryModels && !model.includes("/")) {
|
|
683
|
-
return false;
|
|
684
|
-
}
|
|
685
|
-
if (providerInfo.supportsCustomModels) {
|
|
686
|
-
return true;
|
|
687
|
-
}
|
|
688
|
-
if (providerInfo.supportsAllRegistryModels) {
|
|
689
|
-
return findModelInfo(provider, model) !== null;
|
|
123
|
+
function getProviderFromModel(model) {
|
|
124
|
+
try {
|
|
125
|
+
return (0, import_llm.getProviderFromModel)(model);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (isUnknownCatalogModelError(error)) {
|
|
128
|
+
throw import_errors.LLMError.modelProviderUnknown(model);
|
|
129
|
+
}
|
|
130
|
+
throw error;
|
|
690
131
|
}
|
|
691
|
-
return false;
|
|
692
|
-
}
|
|
693
|
-
const API_KEY_OPTIONAL_PROVIDERS = /* @__PURE__ */ new Set([
|
|
694
|
-
"local",
|
|
695
|
-
// Native node-llama-cpp execution - no auth needed
|
|
696
|
-
"ollama",
|
|
697
|
-
// Ollama server - no auth needed by default
|
|
698
|
-
"openai-compatible",
|
|
699
|
-
// vLLM, LocalAI - often no auth needed
|
|
700
|
-
"litellm",
|
|
701
|
-
// Self-hosted proxy - handles auth internally
|
|
702
|
-
"vertex",
|
|
703
|
-
// Uses Google Cloud ADC (Application Default Credentials)
|
|
704
|
-
"bedrock"
|
|
705
|
-
// Uses AWS credentials (access key + secret or IAM role)
|
|
706
|
-
]);
|
|
707
|
-
function requiresApiKey(provider) {
|
|
708
|
-
return !API_KEY_OPTIONAL_PROVIDERS.has(provider);
|
|
709
132
|
}
|
|
710
133
|
function getSupportedFileTypesForModel(provider, model) {
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
}
|
|
719
|
-
if (supportsCustomModels(provider)) {
|
|
720
|
-
return providerInfo.supportedFileTypes;
|
|
134
|
+
try {
|
|
135
|
+
return (0, import_llm.getSupportedFileTypesForModel)(provider, model);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (isUnknownCatalogModelError(error)) {
|
|
138
|
+
throw import_errors.LLMError.unknownModel(provider, model);
|
|
139
|
+
}
|
|
140
|
+
throw error;
|
|
721
141
|
}
|
|
722
|
-
throw import_errors.LLMError.unknownModel(provider, model);
|
|
723
142
|
}
|
|
724
143
|
function modelSupportsFileType(provider, model, fileType) {
|
|
725
|
-
|
|
726
|
-
return supportedTypes.includes(fileType);
|
|
144
|
+
return getSupportedFileTypesForModel(provider, model).includes(fileType);
|
|
727
145
|
}
|
|
728
|
-
function
|
|
729
|
-
const
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
return
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
fileType,
|
|
742
|
-
error: `Model '${model}' (${provider}) does not support ${fileType} files`
|
|
743
|
-
};
|
|
146
|
+
function getMaxInputTokensForModel(provider, model, logger) {
|
|
147
|
+
const modelInfo = (0, import_llm.getModel)(provider, model);
|
|
148
|
+
if (modelInfo !== null) {
|
|
149
|
+
logger?.debug(`Found max tokens for ${provider}/${model}: ${modelInfo.maxInputTokens}`);
|
|
150
|
+
return modelInfo.maxInputTokens;
|
|
151
|
+
}
|
|
152
|
+
if ((provider === "openrouter" || provider === "dexto-nova") && model.includes("/")) {
|
|
153
|
+
const contextLength = (0, import_openrouter_model_registry.getOpenRouterModelContextLength)(model);
|
|
154
|
+
if (typeof contextLength === "number") {
|
|
155
|
+
logger?.debug(
|
|
156
|
+
`Using max tokens from OpenRouter cache for ${provider}/${model}: ${contextLength}`
|
|
157
|
+
);
|
|
158
|
+
return contextLength;
|
|
744
159
|
}
|
|
745
|
-
return {
|
|
746
|
-
isSupported: true,
|
|
747
|
-
fileType
|
|
748
|
-
};
|
|
749
|
-
} catch (error) {
|
|
750
|
-
return {
|
|
751
|
-
isSupported: false,
|
|
752
|
-
fileType,
|
|
753
|
-
error: error instanceof Error ? error.message : "Unknown error validating model file support"
|
|
754
|
-
};
|
|
755
160
|
}
|
|
161
|
+
const supportedModels = (0, import_llm.getSupportedModels)(provider).join(", ");
|
|
162
|
+
logger?.error(
|
|
163
|
+
`Model '${model}' not found for provider '${provider}' in LLM registry. Supported models: ${supportedModels}`
|
|
164
|
+
);
|
|
165
|
+
throw import_errors.LLMError.unknownModel(provider, model);
|
|
756
166
|
}
|
|
757
167
|
function getEffectiveMaxInputTokens(config, logger) {
|
|
758
168
|
const configuredMaxInputTokens = config.maxInputTokens;
|
|
@@ -774,38 +184,36 @@ function getEffectiveMaxInputTokens(config, logger) {
|
|
|
774
184
|
`Provided maxInputTokens (${configuredMaxInputTokens}) for ${config.provider}/${config.model} exceeds the known limit (${registryMaxInputTokens}) for model ${config.model}. Capping to registry limit.`
|
|
775
185
|
);
|
|
776
186
|
return registryMaxInputTokens;
|
|
777
|
-
} else {
|
|
778
|
-
logger.debug(
|
|
779
|
-
`Using valid maxInputTokens override from configuration: ${configuredMaxInputTokens} (Registry limit: ${registryMaxInputTokens})`
|
|
780
|
-
);
|
|
781
|
-
return configuredMaxInputTokens;
|
|
782
187
|
}
|
|
188
|
+
logger.debug(
|
|
189
|
+
`Using valid maxInputTokens override from configuration: ${configuredMaxInputTokens} (Registry limit: ${registryMaxInputTokens})`
|
|
190
|
+
);
|
|
191
|
+
return configuredMaxInputTokens;
|
|
783
192
|
} catch (error) {
|
|
784
193
|
if (error instanceof import_DextoRuntimeError.DextoRuntimeError && error.code === import_error_codes.LLMErrorCode.MODEL_UNKNOWN) {
|
|
785
194
|
logger.warn(
|
|
786
195
|
`Registry lookup failed during maxInputTokens override check for ${config.provider}/${config.model}: ${error.message}. Proceeding with the provided maxInputTokens value (${configuredMaxInputTokens}), but it might be invalid.`
|
|
787
196
|
);
|
|
788
197
|
return configuredMaxInputTokens;
|
|
789
|
-
} else {
|
|
790
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
791
|
-
logger.error(
|
|
792
|
-
`getEffectiveMaxInputTokens: unexpected error during maxInputTokens override check: ${errorMessage}`
|
|
793
|
-
);
|
|
794
|
-
throw error;
|
|
795
198
|
}
|
|
199
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
200
|
+
logger.error(
|
|
201
|
+
`getEffectiveMaxInputTokens: unexpected error during maxInputTokens override check: ${errorMessage}`
|
|
202
|
+
);
|
|
203
|
+
throw error;
|
|
796
204
|
}
|
|
797
205
|
}
|
|
798
206
|
if (config.baseURL) {
|
|
799
207
|
logger.warn(
|
|
800
|
-
`baseURL is set but maxInputTokens is missing. Defaulting to ${DEFAULT_MAX_INPUT_TOKENS}. Provide 'maxInputTokens' in configuration to avoid default fallback.`
|
|
208
|
+
`baseURL is set but maxInputTokens is missing. Defaulting to ${import_llm.DEFAULT_MAX_INPUT_TOKENS}. Provide 'maxInputTokens' in configuration to avoid default fallback.`
|
|
801
209
|
);
|
|
802
|
-
return DEFAULT_MAX_INPUT_TOKENS;
|
|
210
|
+
return import_llm.DEFAULT_MAX_INPUT_TOKENS;
|
|
803
211
|
}
|
|
804
|
-
if (acceptsAnyModel(config.provider)) {
|
|
212
|
+
if ((0, import_llm.acceptsAnyModel)(config.provider)) {
|
|
805
213
|
logger.debug(
|
|
806
|
-
`Provider ${config.provider} accepts any model, defaulting to ${DEFAULT_MAX_INPUT_TOKENS} tokens`
|
|
214
|
+
`Provider ${config.provider} accepts any model, defaulting to ${import_llm.DEFAULT_MAX_INPUT_TOKENS} tokens`
|
|
807
215
|
);
|
|
808
|
-
return DEFAULT_MAX_INPUT_TOKENS;
|
|
216
|
+
return import_llm.DEFAULT_MAX_INPUT_TOKENS;
|
|
809
217
|
}
|
|
810
218
|
try {
|
|
811
219
|
const registryMaxInputTokens = getMaxInputTokensForModel(
|
|
@@ -819,131 +227,30 @@ function getEffectiveMaxInputTokens(config, logger) {
|
|
|
819
227
|
return registryMaxInputTokens;
|
|
820
228
|
} catch (error) {
|
|
821
229
|
if (error instanceof import_DextoRuntimeError.DextoRuntimeError && error.code === import_error_codes.LLMErrorCode.MODEL_UNKNOWN) {
|
|
822
|
-
if (supportsCustomModels(config.provider)) {
|
|
230
|
+
if ((0, import_llm.supportsCustomModels)(config.provider)) {
|
|
823
231
|
logger.debug(
|
|
824
|
-
`Custom model ${config.model} not in ${config.provider} registry, defaulting to ${DEFAULT_MAX_INPUT_TOKENS} tokens`
|
|
232
|
+
`Custom model ${config.model} not in ${config.provider} registry, defaulting to ${import_llm.DEFAULT_MAX_INPUT_TOKENS} tokens`
|
|
825
233
|
);
|
|
826
|
-
return DEFAULT_MAX_INPUT_TOKENS;
|
|
234
|
+
return import_llm.DEFAULT_MAX_INPUT_TOKENS;
|
|
827
235
|
}
|
|
828
236
|
logger.error(
|
|
829
237
|
`Registry lookup failed for ${config.provider}/${config.model}: ${error.message}. Effective maxInputTokens cannot be determined.`
|
|
830
238
|
);
|
|
831
239
|
throw import_errors.LLMError.unknownModel(config.provider, config.model);
|
|
832
|
-
} else {
|
|
833
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
834
|
-
logger.error(
|
|
835
|
-
`getEffectiveMaxInputTokens: unexpected error during registry lookup for maxInputTokens: ${errorMessage}`
|
|
836
|
-
);
|
|
837
|
-
throw error;
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
function getModelPricing(provider, model) {
|
|
842
|
-
if (acceptsAnyModel(provider)) {
|
|
843
|
-
return void 0;
|
|
844
|
-
}
|
|
845
|
-
const modelInfo = findModelInfo(provider, model);
|
|
846
|
-
return modelInfo?.pricing;
|
|
847
|
-
}
|
|
848
|
-
function getModelDisplayName(model, provider) {
|
|
849
|
-
if (provider) {
|
|
850
|
-
const modelInfo = findModelInfo(provider, model);
|
|
851
|
-
return modelInfo?.displayName ?? model;
|
|
852
|
-
}
|
|
853
|
-
if (model.includes("/")) {
|
|
854
|
-
const modelInfo = findModelInfo("openrouter", model);
|
|
855
|
-
return modelInfo?.displayName ?? model;
|
|
856
|
-
}
|
|
857
|
-
try {
|
|
858
|
-
const inferredProvider = getProviderFromModel(model);
|
|
859
|
-
const modelInfo = findModelInfo(inferredProvider, model);
|
|
860
|
-
return modelInfo?.displayName ?? model;
|
|
861
|
-
} catch {
|
|
862
|
-
return model;
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
function isReasoningCapableModel(model, provider) {
|
|
866
|
-
const registryProvider = (() => {
|
|
867
|
-
if (model.includes("/")) return "openrouter";
|
|
868
|
-
if (provider) return provider;
|
|
869
|
-
try {
|
|
870
|
-
return getProviderFromModel(model);
|
|
871
|
-
} catch {
|
|
872
|
-
return void 0;
|
|
873
240
|
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
}
|
|
880
|
-
if (registryProvider) {
|
|
881
|
-
const modelInfo = findModelInfo(registryProvider, model);
|
|
882
|
-
if (modelInfo?.reasoning === true) return true;
|
|
883
|
-
if (modelInfo?.reasoning === false) return false;
|
|
884
|
-
}
|
|
885
|
-
const modelIdForHeuristics = model.includes("/") ? model.split("/").pop() ?? model : model;
|
|
886
|
-
const modelLower = modelIdForHeuristics.toLowerCase();
|
|
887
|
-
if (modelLower.includes("codex")) {
|
|
888
|
-
return true;
|
|
889
|
-
}
|
|
890
|
-
if (modelLower.startsWith("o1") || modelLower.startsWith("o3") || modelLower.startsWith("o4")) {
|
|
891
|
-
return true;
|
|
892
|
-
}
|
|
893
|
-
if (modelLower.includes("gpt-5") || modelLower.includes("gpt-5.1") || modelLower.includes("gpt-5.2")) {
|
|
894
|
-
return true;
|
|
241
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
242
|
+
logger.error(
|
|
243
|
+
`getEffectiveMaxInputTokens: unexpected error during registry lookup for maxInputTokens: ${errorMessage}`
|
|
244
|
+
);
|
|
245
|
+
throw error;
|
|
895
246
|
}
|
|
896
|
-
return false;
|
|
897
|
-
}
|
|
898
|
-
function calculateCost(usage, pricing) {
|
|
899
|
-
return calculateCostBreakdown(usage, pricing).totalUsd;
|
|
900
|
-
}
|
|
901
|
-
function calculateCostBreakdown(usage, pricing) {
|
|
902
|
-
const inputUsd = (usage.inputTokens ?? 0) * pricing.inputPerM / 1e6;
|
|
903
|
-
const outputUsd = (usage.outputTokens ?? 0) * pricing.outputPerM / 1e6;
|
|
904
|
-
const cacheReadUsd = (usage.cacheReadTokens ?? 0) * (pricing.cacheReadPerM ?? 0) / 1e6;
|
|
905
|
-
const cacheWriteUsd = (usage.cacheWriteTokens ?? 0) * (pricing.cacheWritePerM ?? 0) / 1e6;
|
|
906
|
-
const reasoningUsd = (usage.reasoningTokens ?? 0) * (pricing.reasoningPerM ?? pricing.outputPerM) / 1e6;
|
|
907
|
-
return {
|
|
908
|
-
inputUsd,
|
|
909
|
-
outputUsd,
|
|
910
|
-
reasoningUsd,
|
|
911
|
-
cacheReadUsd,
|
|
912
|
-
cacheWriteUsd,
|
|
913
|
-
totalUsd: inputUsd + outputUsd + cacheReadUsd + cacheWriteUsd + reasoningUsd
|
|
914
|
-
};
|
|
915
247
|
}
|
|
916
248
|
// Annotate the CommonJS export names for ESM import in node:
|
|
917
249
|
0 && (module.exports = {
|
|
918
|
-
DEFAULT_MAX_INPUT_TOKENS,
|
|
919
|
-
LLM_REGISTRY,
|
|
920
|
-
MIME_TYPE_TO_FILE_TYPE,
|
|
921
|
-
acceptsAnyModel,
|
|
922
|
-
calculateCost,
|
|
923
|
-
calculateCostBreakdown,
|
|
924
250
|
getAllModelsForProvider,
|
|
925
|
-
getAllSupportedModels,
|
|
926
|
-
getAllowedMimeTypes,
|
|
927
|
-
getDefaultModelForProvider,
|
|
928
251
|
getEffectiveMaxInputTokens,
|
|
929
252
|
getMaxInputTokensForModel,
|
|
930
|
-
getModelDisplayName,
|
|
931
|
-
getModelPricing,
|
|
932
|
-
getOpenRouterCandidateModelIds,
|
|
933
253
|
getProviderFromModel,
|
|
934
254
|
getSupportedFileTypesForModel,
|
|
935
|
-
|
|
936
|
-
getSupportedProviders,
|
|
937
|
-
hasAllRegistryModelsSupport,
|
|
938
|
-
isModelValidForProvider,
|
|
939
|
-
isReasoningCapableModel,
|
|
940
|
-
isValidProviderModel,
|
|
941
|
-
modelSupportsFileType,
|
|
942
|
-
requiresApiKey,
|
|
943
|
-
requiresBaseURL,
|
|
944
|
-
stripBedrockRegionPrefix,
|
|
945
|
-
supportsBaseURL,
|
|
946
|
-
supportsCustomModels,
|
|
947
|
-
transformModelNameForProvider,
|
|
948
|
-
validateModelFileSupport
|
|
255
|
+
modelSupportsFileType
|
|
949
256
|
});
|