@x12i/ai-tools 1.0.4 → 2.0.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 +23 -0
- package/README.md +146 -204
- package/dist/AiModelsCatalogClient-B5FMI9gj.d.cts +58 -0
- package/dist/AiModelsCatalogClient-CPPNI6Ry.d.ts +58 -0
- package/dist/aliases/index.cjs +4 -3
- package/dist/aliases/index.cjs.map +1 -1
- package/dist/aliases/index.d.cts +3 -5
- package/dist/aliases/index.d.ts +3 -5
- package/dist/aliases/index.js +2 -2
- package/dist/catalog/index.cjs +18 -9
- package/dist/catalog/index.cjs.map +1 -1
- package/dist/catalog/index.d.cts +13 -100
- package/dist/catalog/index.d.ts +13 -100
- package/dist/catalog/index.js +31 -23
- package/dist/{chunk-AJEKEWWB.js → chunk-2PTCWPHV.js} +17 -3
- package/dist/chunk-2PTCWPHV.js.map +1 -0
- package/dist/chunk-56R4XA2S.js +1 -0
- package/dist/chunk-5GUKLOEK.cjs +1 -0
- package/dist/chunk-5GUKLOEK.cjs.map +1 -0
- package/dist/chunk-5XAAMBDO.cjs +1988 -0
- package/dist/chunk-5XAAMBDO.cjs.map +1 -0
- package/dist/chunk-6BQBKROR.js +95 -0
- package/dist/chunk-6BQBKROR.js.map +1 -0
- package/dist/chunk-AB5GNXJ4.js +46 -0
- package/dist/chunk-AB5GNXJ4.js.map +1 -0
- package/dist/{chunk-O2A6OVEH.js → chunk-ANVONYJF.js} +2 -2
- package/dist/{chunk-O2A6OVEH.js.map → chunk-ANVONYJF.js.map} +1 -1
- package/dist/chunk-B3V2EHRY.js +225 -0
- package/dist/chunk-B3V2EHRY.js.map +1 -0
- package/dist/{chunk-QWAX7VQO.cjs → chunk-BAHBDADJ.cjs} +11 -11
- package/dist/{chunk-QWAX7VQO.cjs.map → chunk-BAHBDADJ.cjs.map} +1 -1
- package/dist/{chunk-TF4L2NEC.cjs → chunk-DXZOL3VN.cjs} +62 -313
- package/dist/chunk-DXZOL3VN.cjs.map +1 -0
- package/dist/chunk-EDMCKHO6.cjs +225 -0
- package/dist/chunk-EDMCKHO6.cjs.map +1 -0
- package/dist/{chunk-DJ5SWJDY.js → chunk-EYHMQVAL.js} +48 -299
- package/dist/chunk-EYHMQVAL.js.map +1 -0
- package/dist/chunk-GS7T56RP.cjs +8 -0
- package/dist/chunk-GS7T56RP.cjs.map +1 -0
- package/dist/chunk-NF2SKQR7.cjs +973 -0
- package/dist/chunk-NF2SKQR7.cjs.map +1 -0
- package/dist/chunk-OPN6BGNH.js +1985 -0
- package/dist/chunk-OPN6BGNH.js.map +1 -0
- package/dist/{chunk-7Q742NI3.cjs → chunk-PADNCGZB.cjs} +17 -3
- package/dist/chunk-PADNCGZB.cjs.map +1 -0
- package/dist/chunk-PRCICORG.cjs +95 -0
- package/dist/chunk-PRCICORG.cjs.map +1 -0
- package/dist/{chunk-6QGDZTGH.js → chunk-SIH4GPV4.js} +4 -29
- package/dist/chunk-SIH4GPV4.js.map +1 -0
- package/dist/chunk-U2YDDUVP.js +970 -0
- package/dist/chunk-U2YDDUVP.js.map +1 -0
- package/dist/{chunk-4NAY6HRP.js → chunk-VJHLO2R3.js} +7 -58
- package/dist/chunk-VJHLO2R3.js.map +1 -0
- package/dist/chunk-XAWBTX3N.cjs +46 -0
- package/dist/chunk-XAWBTX3N.cjs.map +1 -0
- package/dist/{chunk-AV6OE2YQ.cjs → chunk-XOKUDUUI.cjs} +14 -39
- package/dist/chunk-XOKUDUUI.cjs.map +1 -0
- package/dist/chunk-YQDSN6R6.cjs +86 -0
- package/dist/chunk-YQDSN6R6.cjs.map +1 -0
- package/dist/cli/index.cjs +59 -201
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +53 -198
- package/dist/cli/index.js.map +1 -1
- package/dist/cost/index.cjs +19 -3
- package/dist/cost/index.cjs.map +1 -1
- package/dist/cost/index.d.cts +10 -50
- package/dist/cost/index.d.ts +10 -50
- package/dist/cost/index.js +18 -3
- package/dist/index.cjs +24 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -13
- package/dist/index.d.ts +13 -13
- package/dist/index.js +44 -37
- package/dist/modelCache-BzRn6t_C.d.ts +113 -0
- package/dist/modelCache-CJftI-Ko.d.cts +113 -0
- package/dist/{modelNameResolver-DqFt7g6W.d.ts → modelNameResolver-5XkBMctP.d.ts} +2 -6
- package/dist/{modelNameResolver-D9V_GfUK.d.cts → modelNameResolver-C5CSTGFF.d.cts} +2 -6
- package/dist/models/index.cjs +9 -6
- package/dist/models/index.cjs.map +1 -1
- package/dist/models/index.d.cts +9 -31
- package/dist/models/index.d.ts +9 -31
- package/dist/models/index.js +9 -7
- package/dist/resolveUsageModel-BFwf80Hz.d.ts +140 -0
- package/dist/resolveUsageModel-C_YmGR1M.d.cts +140 -0
- package/dist/sync/index.cjs +7 -9
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +3 -8
- package/dist/sync/index.d.ts +3 -8
- package/dist/sync/index.js +8 -11
- package/dist/toolbox/index.cjs +1 -0
- package/dist/toolbox/index.cjs.map +1 -1
- package/dist/types-BrzJWsTU.d.cts +277 -0
- package/dist/types-BrzJWsTU.d.ts +277 -0
- package/package.json +9 -20
- package/src/data/models-catalog.json +670 -0
- package/src/data/openrouter-models-catalog.json +857 -0
- package/dist/AiModelsCatalogClient-4RF5BCDL.cjs +0 -9
- package/dist/AiModelsCatalogClient-4RF5BCDL.cjs.map +0 -1
- package/dist/AiModelsCatalogClient-CNeqFiFs.d.cts +0 -30
- package/dist/AiModelsCatalogClient-NUF3CBLW.js +0 -9
- package/dist/AiModelsCatalogClient-nwFoEaqL.d.ts +0 -30
- package/dist/catalox/index.cjs +0 -21
- package/dist/catalox/index.cjs.map +0 -1
- package/dist/catalox/index.d.cts +0 -11
- package/dist/catalox/index.d.ts +0 -11
- package/dist/catalox/index.js +0 -21
- package/dist/catalox/index.js.map +0 -1
- package/dist/chunk-4NAY6HRP.js.map +0 -1
- package/dist/chunk-6QGDZTGH.js.map +0 -1
- package/dist/chunk-7Q742NI3.cjs.map +0 -1
- package/dist/chunk-AJEKEWWB.js.map +0 -1
- package/dist/chunk-AV6OE2YQ.cjs.map +0 -1
- package/dist/chunk-C3H7RTFR.cjs +0 -1
- package/dist/chunk-C3H7RTFR.cjs.map +0 -1
- package/dist/chunk-DJ5SWJDY.js.map +0 -1
- package/dist/chunk-DKHGWHXP.cjs +0 -169
- package/dist/chunk-DKHGWHXP.cjs.map +0 -1
- package/dist/chunk-F2F4UEFD.cjs +0 -75
- package/dist/chunk-F2F4UEFD.cjs.map +0 -1
- package/dist/chunk-FGP3QXWL.cjs +0 -163
- package/dist/chunk-FGP3QXWL.cjs.map +0 -1
- package/dist/chunk-G2G4KSC5.js +0 -30
- package/dist/chunk-G2G4KSC5.js.map +0 -1
- package/dist/chunk-HN6UAQAE.cjs +0 -83
- package/dist/chunk-HN6UAQAE.cjs.map +0 -1
- package/dist/chunk-HS74X2OJ.cjs +0 -172
- package/dist/chunk-HS74X2OJ.cjs.map +0 -1
- package/dist/chunk-HYGXZY25.js +0 -163
- package/dist/chunk-HYGXZY25.js.map +0 -1
- package/dist/chunk-KQOALKKX.js +0 -75
- package/dist/chunk-KQOALKKX.js.map +0 -1
- package/dist/chunk-LYOU7CA2.cjs +0 -30
- package/dist/chunk-LYOU7CA2.cjs.map +0 -1
- package/dist/chunk-M5TMA73F.js +0 -1
- package/dist/chunk-M5TMA73F.js.map +0 -1
- package/dist/chunk-MX3AMQFC.js +0 -172
- package/dist/chunk-MX3AMQFC.js.map +0 -1
- package/dist/chunk-QCRLKVB3.cjs +0 -137
- package/dist/chunk-QCRLKVB3.cjs.map +0 -1
- package/dist/chunk-TF4L2NEC.cjs.map +0 -1
- package/dist/chunk-VRFVF5RH.js +0 -169
- package/dist/chunk-VRFVF5RH.js.map +0 -1
- package/dist/chunk-YHO57D2V.js +0 -83
- package/dist/chunk-YHO57D2V.js.map +0 -1
- package/dist/syncAiModelsCatalog-CnXRLm2c.d.cts +0 -32
- package/dist/syncAiModelsCatalog-DpkN_w7S.d.ts +0 -32
- package/dist/types-BYXnCvKx.d.cts +0 -137
- package/dist/types-BYXnCvKx.d.ts +0 -137
- package/dist/types-CX6QFNNy.d.cts +0 -144
- package/dist/types-CuiPDcVs.d.ts +0 -144
- package/dist/upsertAiModelRecord-C831wOIF.d.ts +0 -35
- package/dist/upsertAiModelRecord-CjY-sny0.d.cts +0 -35
- /package/dist/{AiModelsCatalogClient-NUF3CBLW.js.map → chunk-56R4XA2S.js.map} +0 -0
|
@@ -1,270 +1,20 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
-
var _chunk7Q742NI3cjs = require('./chunk-7Q742NI3.cjs');
|
|
4
3
|
|
|
5
|
-
// src/cache/modelCache.ts
|
|
6
|
-
var _nxcache = require('nx-cache');
|
|
7
|
-
var cache = _nxcache.createNxCache.call(void 0, );
|
|
8
|
-
var DEFAULT_MODEL_CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
9
|
-
function readCachedModels(appId, ttlMs = DEFAULT_MODEL_CACHE_TTL_MS) {
|
|
10
|
-
const res = cache.read("ai-models", { appId });
|
|
11
|
-
if (!res.found) return null;
|
|
12
|
-
const cachedAt = _optionalChain([res, 'access', _ => _.metadata, 'optionalAccess', _2 => _2.cachedAt]);
|
|
13
|
-
if (cachedAt) {
|
|
14
|
-
const age = Date.now() - new Date(cachedAt).getTime();
|
|
15
|
-
if (age > ttlMs) return null;
|
|
16
|
-
} else if (res.meta.isExpired) {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
return res.value;
|
|
20
|
-
}
|
|
21
|
-
function writeCachedModels(appId, models, ttlMs = DEFAULT_MODEL_CACHE_TTL_MS) {
|
|
22
|
-
cache.write("ai-models", models, {
|
|
23
|
-
scope: { appId },
|
|
24
|
-
ttlMs,
|
|
25
|
-
metadata: { cachedAt: (/* @__PURE__ */ new Date()).toISOString(), count: models.size }
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
function invalidateModelsCache(appId) {
|
|
29
|
-
cache.resetKey("ai-models", { appId });
|
|
30
|
-
}
|
|
31
4
|
|
|
32
|
-
// src/catalog/aiModelsCatalogDescriptor.ts
|
|
33
|
-
var AI_MODELS_CATALOG_ID = "ai-models";
|
|
34
|
-
var AI_TOOLS_APP_ID = "ai-tools";
|
|
35
|
-
var AI_MODELS_DESCRIPTOR = {
|
|
36
|
-
catalogId: AI_MODELS_CATALOG_ID,
|
|
37
|
-
label: "AI Models",
|
|
38
|
-
description: "Full mirror of OpenRouter Models API metadata and pricing, synced on a schedule.",
|
|
39
|
-
itemLabel: "Model",
|
|
40
|
-
sourceMode: "native",
|
|
41
|
-
status: "active",
|
|
42
|
-
visibility: "visible",
|
|
43
|
-
capabilities: {
|
|
44
|
-
canList: true,
|
|
45
|
-
canGet: true,
|
|
46
|
-
canCreate: false,
|
|
47
|
-
canEdit: false,
|
|
48
|
-
canDelete: false,
|
|
49
|
-
canExport: true,
|
|
50
|
-
canValidate: true
|
|
51
|
-
},
|
|
52
|
-
identity: {
|
|
53
|
-
itemIdStrategy: "natural",
|
|
54
|
-
itemIdField: "modelId",
|
|
55
|
-
titleField: "name",
|
|
56
|
-
subtitleField: "providerId",
|
|
57
|
-
statusField: "status",
|
|
58
|
-
updatedAtField: "syncedAt"
|
|
59
|
-
},
|
|
60
|
-
queryableFields: [
|
|
61
|
-
{ key: "modelId", label: "Model ID", type: "string", indexed: true, filterable: true },
|
|
62
|
-
{ key: "providerId", label: "Provider", type: "string", indexed: true, filterable: true },
|
|
63
|
-
{ key: "name", label: "Name", type: "string", filterable: true },
|
|
64
|
-
{ key: "canonicalSlug", label: "Canonical Slug", type: "string", indexed: true, filterable: true },
|
|
65
|
-
{ key: "contextLength", label: "Context Length", type: "number", sortable: true },
|
|
66
|
-
{
|
|
67
|
-
key: "status",
|
|
68
|
-
label: "Status",
|
|
69
|
-
type: "enum",
|
|
70
|
-
indexed: true,
|
|
71
|
-
filterable: true,
|
|
72
|
-
enumValues: ["active", "deprecated", "unknown"]
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
key: "primaryOutputModality",
|
|
76
|
-
label: "Primary Output",
|
|
77
|
-
type: "string",
|
|
78
|
-
indexed: true,
|
|
79
|
-
filterable: true
|
|
80
|
-
},
|
|
81
|
-
{ key: "supportsTools", label: "Tools", type: "boolean", indexed: true, filterable: true },
|
|
82
|
-
{
|
|
83
|
-
key: "supportsReasoning",
|
|
84
|
-
label: "Reasoning",
|
|
85
|
-
type: "boolean",
|
|
86
|
-
indexed: true,
|
|
87
|
-
filterable: true
|
|
88
|
-
},
|
|
89
|
-
{ key: "supportsStreaming", label: "Streams", type: "boolean", filterable: true },
|
|
90
|
-
{ key: "isModerated", label: "Moderated", type: "boolean", filterable: true },
|
|
91
|
-
{ key: "syncedAt", label: "Synced At", type: "datetime", sortable: true }
|
|
92
|
-
],
|
|
93
|
-
defaultSort: { field: "syncedAt", direction: "desc" }
|
|
94
|
-
};
|
|
95
5
|
|
|
96
|
-
// src/sync/openRouterRoutingEnv.ts
|
|
97
|
-
var _env = require('@x12i/env');
|
|
98
|
-
function providerIdToEnvKeyPrefix(providerId) {
|
|
99
|
-
return providerId.trim().toLowerCase().replace(/-/g, "_").toUpperCase();
|
|
100
|
-
}
|
|
101
|
-
function vendorApiKeyEnvName(providerId) {
|
|
102
|
-
return `${providerIdToEnvKeyPrefix(providerId)}_API_KEY`;
|
|
103
|
-
}
|
|
104
|
-
function loadOpenRouterRoutingEnv(env = process.env) {
|
|
105
|
-
const dotenv = _env.loadDotenv.call(void 0, );
|
|
106
|
-
const merged = {};
|
|
107
|
-
for (const [k, v] of Object.entries(dotenv)) {
|
|
108
|
-
if (v !== void 0) merged[k] = v;
|
|
109
|
-
}
|
|
110
|
-
for (const [k, v] of Object.entries(env)) {
|
|
111
|
-
if (v !== void 0) merged[k] = v;
|
|
112
|
-
}
|
|
113
|
-
const openRouterKey = _optionalChain([merged, 'access', _3 => _3.OPENROUTER_API_KEY, 'optionalAccess', _4 => _4.trim, 'call', _5 => _5()]);
|
|
114
|
-
const useRaw = _optionalChain([merged, 'access', _6 => _6.USE_OPENROUTER, 'optionalAccess', _7 => _7.trim, 'call', _8 => _8(), 'access', _9 => _9.toLowerCase, 'call', _10 => _10()]);
|
|
115
|
-
const useOpenRouterExplicit = useRaw === "true" || useRaw === "1";
|
|
116
|
-
return {
|
|
117
|
-
hasOpenRouterKey: Boolean(openRouterKey),
|
|
118
|
-
useOpenRouterExplicit,
|
|
119
|
-
getVendorApiKey(providerId) {
|
|
120
|
-
const name = vendorApiKeyEnvName(providerId);
|
|
121
|
-
const val = _optionalChain([merged, 'access', _11 => _11[name], 'optionalAccess', _12 => _12.trim, 'call', _13 => _13()]);
|
|
122
|
-
return val || void 0;
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
function shouldDefaultRouteViaOpenRouter(providerId, config) {
|
|
127
|
-
if (!config.hasOpenRouterKey) return false;
|
|
128
|
-
if (config.useOpenRouterExplicit) return true;
|
|
129
|
-
if (providerId && providerId !== "openrouter") {
|
|
130
|
-
return !config.getVendorApiKey(providerId);
|
|
131
|
-
}
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
6
|
|
|
135
|
-
// src/sync/modelNameResolver/constants.ts
|
|
136
|
-
var DEFAULT_CONFIDENCE_THRESHOLD = 0.6;
|
|
137
|
-
var PROVIDER_NORMALISATION_MAP = {
|
|
138
|
-
"open-router": "openrouter",
|
|
139
|
-
or: "openrouter",
|
|
140
|
-
oai: "openai",
|
|
141
|
-
"open-ai": "openai",
|
|
142
|
-
claude: "anthropic",
|
|
143
|
-
ant: "anthropic",
|
|
144
|
-
gemini: "google",
|
|
145
|
-
gcp: "google",
|
|
146
|
-
"google-ai": "google",
|
|
147
|
-
vertex: "google",
|
|
148
|
-
meta: "meta-llama",
|
|
149
|
-
llama: "meta-llama",
|
|
150
|
-
"mistral-ai": "mistral",
|
|
151
|
-
"cohere-ai": "cohere"
|
|
152
|
-
};
|
|
153
|
-
var LOCAL_PROVIDERS = /* @__PURE__ */ new Set([
|
|
154
|
-
"ollama",
|
|
155
|
-
"lmstudio",
|
|
156
|
-
"lm-studio",
|
|
157
|
-
"localai",
|
|
158
|
-
"local-ai",
|
|
159
|
-
"llamacpp",
|
|
160
|
-
"llama.cpp",
|
|
161
|
-
"llamafile",
|
|
162
|
-
"jan",
|
|
163
|
-
"koboldcpp"
|
|
164
|
-
]);
|
|
165
|
-
var PROVIDER_INFERENCE_MAP = [
|
|
166
|
-
{ pattern: /^gpt-/, provider: "openai" },
|
|
167
|
-
{ pattern: /^o1($|-)/, provider: "openai" },
|
|
168
|
-
{ pattern: /^o3($|-)/, provider: "openai" },
|
|
169
|
-
{ pattern: /^o4($|-)/, provider: "openai" },
|
|
170
|
-
{ pattern: /^chatgpt-/, provider: "openai" },
|
|
171
|
-
{ pattern: /^text-davinci/, provider: "openai" },
|
|
172
|
-
{ pattern: /^dall-e/, provider: "openai" },
|
|
173
|
-
{ pattern: /^whisper/, provider: "openai" },
|
|
174
|
-
{ pattern: /^tts-/, provider: "openai" },
|
|
175
|
-
{ pattern: /^claude-/, provider: "anthropic" },
|
|
176
|
-
{ pattern: /^gemini-/, provider: "google" },
|
|
177
|
-
{ pattern: /^palm-/, provider: "google" },
|
|
178
|
-
{ pattern: /^bison/, provider: "google" },
|
|
179
|
-
{ pattern: /^llama-?[23]/, provider: "meta-llama" },
|
|
180
|
-
{ pattern: /^llama/, provider: "meta-llama" },
|
|
181
|
-
{ pattern: /^codellama/, provider: "meta-llama" },
|
|
182
|
-
{ pattern: /^mistral-/, provider: "mistral" },
|
|
183
|
-
{ pattern: /^mixtral-/, provider: "mistral" },
|
|
184
|
-
{ pattern: /^codestral/, provider: "mistral" },
|
|
185
|
-
{ pattern: /^ministral/, provider: "mistral" },
|
|
186
|
-
{ pattern: /^command-/, provider: "cohere" },
|
|
187
|
-
{ pattern: /^c4ai-/, provider: "cohere" },
|
|
188
|
-
{ pattern: /^deepseek-/, provider: "deepseek" },
|
|
189
|
-
{ pattern: /^grok-/, provider: "x-ai" },
|
|
190
|
-
{ pattern: /^qwen/, provider: "qwen" },
|
|
191
|
-
{ pattern: /^yi-/, provider: "01-ai" },
|
|
192
|
-
{ pattern: /^sonar/, provider: "perplexity" },
|
|
193
|
-
{ pattern: /^pplx-/, provider: "perplexity" },
|
|
194
|
-
{ pattern: /^titan-/, provider: "amazon" },
|
|
195
|
-
{ pattern: /^nova-/, provider: "amazon" }
|
|
196
|
-
];
|
|
197
|
-
var SHORTHAND_MAP = {
|
|
198
|
-
gpt4: "openai/gpt-4",
|
|
199
|
-
gpt4o: "openai/gpt-4o",
|
|
200
|
-
"gpt-4-omni": "openai/gpt-4o",
|
|
201
|
-
gpt4omni: "openai/gpt-4o",
|
|
202
|
-
"gpt4-turbo": "openai/gpt-4-turbo",
|
|
203
|
-
gpt4turbo: "openai/gpt-4-turbo",
|
|
204
|
-
"gpt4-mini": "openai/gpt-4o-mini",
|
|
205
|
-
"gpt-4o-mini": "openai/gpt-4o-mini",
|
|
206
|
-
o1: "openai/o1",
|
|
207
|
-
"o1-mini": "openai/o1-mini",
|
|
208
|
-
o3: "openai/o3",
|
|
209
|
-
"o3-mini": "openai/o3-mini",
|
|
210
|
-
"o4-mini": "openai/o4-mini",
|
|
211
|
-
"3.5-turbo": "openai/gpt-3.5-turbo",
|
|
212
|
-
gpt35: "openai/gpt-3.5-turbo",
|
|
213
|
-
gpt3: "openai/gpt-3.5-turbo",
|
|
214
|
-
claude3: "anthropic/claude-3-5-sonnet-20241022",
|
|
215
|
-
"claude-3": "anthropic/claude-3-5-sonnet-20241022",
|
|
216
|
-
"claude3-sonnet": "anthropic/claude-3-5-sonnet-20241022",
|
|
217
|
-
"claude-sonnet": "anthropic/claude-3-5-sonnet-20241022",
|
|
218
|
-
"claude-haiku": "anthropic/claude-3-5-haiku-20241022",
|
|
219
|
-
"claude3-haiku": "anthropic/claude-3-5-haiku-20241022",
|
|
220
|
-
"claude-opus": "anthropic/claude-opus-4",
|
|
221
|
-
"claude3-opus": "anthropic/claude-3-opus-20240229",
|
|
222
|
-
claude4: "anthropic/claude-opus-4",
|
|
223
|
-
"claude4-sonnet": "anthropic/claude-sonnet-4",
|
|
224
|
-
"claude4-opus": "anthropic/claude-opus-4",
|
|
225
|
-
sonnet: "anthropic/claude-3-5-sonnet-20241022",
|
|
226
|
-
haiku: "anthropic/claude-3-5-haiku-20241022",
|
|
227
|
-
opus: "anthropic/claude-opus-4",
|
|
228
|
-
gemini: "google/gemini-pro",
|
|
229
|
-
"gemini-pro": "google/gemini-pro",
|
|
230
|
-
"gemini-flash": "google/gemini-flash-1.5",
|
|
231
|
-
gemini2: "google/gemini-2.0-flash-001",
|
|
232
|
-
"gemini-2": "google/gemini-2.0-flash-001",
|
|
233
|
-
llama3: "meta-llama/llama-3.1-8b-instruct",
|
|
234
|
-
"llama-3": "meta-llama/llama-3.1-8b-instruct",
|
|
235
|
-
llama2: "meta-llama/llama-2-13b-chat",
|
|
236
|
-
"llama-2": "meta-llama/llama-2-13b-chat",
|
|
237
|
-
mistral: "mistral/mistral-7b-instruct",
|
|
238
|
-
"mistral-large": "mistral/mistral-large-latest",
|
|
239
|
-
mixtral: "mistral/mixtral-8x7b-instruct",
|
|
240
|
-
deepseek: "deepseek/deepseek-chat",
|
|
241
|
-
"deepseek-r1": "deepseek/deepseek-r1"
|
|
242
|
-
};
|
|
243
7
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return s;
|
|
255
|
-
}
|
|
256
|
-
function normalizeProvider(provider) {
|
|
257
|
-
if (provider === void 0 || provider === "") return void 0;
|
|
258
|
-
const n = normalizeString(provider);
|
|
259
|
-
return _nullishCoalesce(PROVIDER_NORMALISATION_MAP[n], () => ( n));
|
|
260
|
-
}
|
|
261
|
-
function tokenise(s) {
|
|
262
|
-
return s.split(/[-_./]+/).filter(Boolean);
|
|
263
|
-
}
|
|
264
|
-
function modelSlug(modelId) {
|
|
265
|
-
const slash = modelId.indexOf("/");
|
|
266
|
-
return slash >= 0 ? modelId.slice(slash + 1) : modelId;
|
|
267
|
-
}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
var _chunkEDMCKHO6cjs = require('./chunk-EDMCKHO6.cjs');
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
var _chunkPADNCGZBcjs = require('./chunk-PADNCGZB.cjs');
|
|
268
18
|
|
|
269
19
|
// src/sync/modelNameResolver/catalogIndexes.ts
|
|
270
20
|
function buildCatalogIndexes(catalog) {
|
|
@@ -273,10 +23,10 @@ function buildCatalogIndexes(catalog) {
|
|
|
273
23
|
const prefixCounts = /* @__PURE__ */ new Map();
|
|
274
24
|
for (const record of catalog.values()) {
|
|
275
25
|
for (const alias of record.aliases) {
|
|
276
|
-
aliasIndex.set(normalizeString(alias), record.modelId);
|
|
26
|
+
aliasIndex.set(_chunkEDMCKHO6cjs.normalizeString.call(void 0, alias), record.modelId);
|
|
277
27
|
}
|
|
278
28
|
if (record.canonicalSlug) {
|
|
279
|
-
slugIndex.set(normalizeString(record.canonicalSlug), record.modelId);
|
|
29
|
+
slugIndex.set(_chunkEDMCKHO6cjs.normalizeString.call(void 0, record.canonicalSlug), record.modelId);
|
|
280
30
|
}
|
|
281
31
|
const pid = record.providerId;
|
|
282
32
|
prefixCounts.set(pid, (_nullishCoalesce(prefixCounts.get(pid), () => ( 0))) + 1);
|
|
@@ -286,15 +36,6 @@ function buildCatalogIndexes(catalog) {
|
|
|
286
36
|
}
|
|
287
37
|
|
|
288
38
|
// src/sync/modelNameResolver/ModelNameResolver.ts
|
|
289
|
-
var VERSION_STRIP_PATTERNS = [
|
|
290
|
-
{ re: /-\d{4}-\d{2}-\d{2}$/, label: "date YYYY-MM-DD" },
|
|
291
|
-
{ re: /-\d{8}$/, label: "date YYYYMMDD" },
|
|
292
|
-
{ re: /-v\d+$/, label: "version -vN" },
|
|
293
|
-
{ re: /-\d+\.\d+\.\d+$/, label: "semver" },
|
|
294
|
-
{ re: /:\d+[a-z]?$/i, label: "colon version" },
|
|
295
|
-
{ re: /-\d{4,}$/, label: "build number" },
|
|
296
|
-
{ re: /@\d+$/, label: "epoch @NNNN" }
|
|
297
|
-
];
|
|
298
39
|
var ModelNameResolver = class {
|
|
299
40
|
|
|
300
41
|
|
|
@@ -306,40 +47,40 @@ var ModelNameResolver = class {
|
|
|
306
47
|
catalog,
|
|
307
48
|
indexes: this.indexes,
|
|
308
49
|
options: {
|
|
309
|
-
confidenceThreshold: _nullishCoalesce(options.confidenceThreshold, () => ( DEFAULT_CONFIDENCE_THRESHOLD)),
|
|
50
|
+
confidenceThreshold: _nullishCoalesce(options.confidenceThreshold, () => ( _chunkEDMCKHO6cjs.DEFAULT_CONFIDENCE_THRESHOLD)),
|
|
310
51
|
aliasRegistry: options.aliasRegistry,
|
|
311
52
|
additionalShorthands: _nullishCoalesce(options.additionalShorthands, () => ( {})),
|
|
312
53
|
additionalProviderPatterns: _nullishCoalesce(options.additionalProviderPatterns, () => ( [])),
|
|
313
54
|
additionalLocalProviders: _nullishCoalesce(options.additionalLocalProviders, () => ( [])),
|
|
314
|
-
routingEnv: _nullishCoalesce(options.routingEnv, () => ( loadOpenRouterRoutingEnv()))
|
|
55
|
+
routingEnv: _nullishCoalesce(options.routingEnv, () => ( _chunkEDMCKHO6cjs.loadOpenRouterRoutingEnv.call(void 0, )))
|
|
315
56
|
}
|
|
316
57
|
};
|
|
317
58
|
}
|
|
318
59
|
resolve(input) {
|
|
319
60
|
const attempted = [];
|
|
320
61
|
const threshold = this.ctx.options.confidenceThreshold;
|
|
321
|
-
let provider = normalizeProvider(input.provider);
|
|
322
|
-
let model = normalizeString(input.model);
|
|
62
|
+
let provider = _chunkEDMCKHO6cjs.normalizeProvider.call(void 0, input.provider);
|
|
63
|
+
let model = _chunkEDMCKHO6cjs.normalizeString.call(void 0, input.model);
|
|
323
64
|
const normalisedInput = model;
|
|
324
65
|
if (this.ctx.options.aliasRegistry) {
|
|
325
66
|
attempted.push("alias-registry");
|
|
326
67
|
const entry = this.ctx.options.aliasRegistry.get(model);
|
|
327
68
|
if (entry) {
|
|
328
|
-
model = normalizeString(entry.modelId);
|
|
329
|
-
provider = _nullishCoalesce(normalizeProvider(entry.provider), () => ( provider));
|
|
69
|
+
model = _chunkEDMCKHO6cjs.normalizeString.call(void 0, entry.modelId);
|
|
70
|
+
provider = _nullishCoalesce(_chunkEDMCKHO6cjs.normalizeProvider.call(void 0, entry.provider), () => ( provider));
|
|
330
71
|
}
|
|
331
72
|
}
|
|
332
73
|
if (this.ctx.options.aliasRegistry && provider) {
|
|
333
74
|
const aliasAsProvider = this.ctx.options.aliasRegistry.get(provider);
|
|
334
75
|
if (aliasAsProvider) {
|
|
335
76
|
attempted.push("alias-as-provider-correction");
|
|
336
|
-
model = normalizeString(aliasAsProvider.modelId);
|
|
337
|
-
provider = _nullishCoalesce(normalizeProvider(aliasAsProvider.provider), () => ( provider));
|
|
77
|
+
model = _chunkEDMCKHO6cjs.normalizeString.call(void 0, aliasAsProvider.modelId);
|
|
78
|
+
provider = _nullishCoalesce(_chunkEDMCKHO6cjs.normalizeProvider.call(void 0, aliasAsProvider.provider), () => ( provider));
|
|
338
79
|
}
|
|
339
80
|
}
|
|
340
81
|
const localProviders = /* @__PURE__ */ new Set([
|
|
341
|
-
...LOCAL_PROVIDERS,
|
|
342
|
-
...this.ctx.options.additionalLocalProviders.map((p) => normalizeString(p))
|
|
82
|
+
..._chunkEDMCKHO6cjs.LOCAL_PROVIDERS,
|
|
83
|
+
...this.ctx.options.additionalLocalProviders.map((p) => _chunkEDMCKHO6cjs.normalizeString.call(void 0, p))
|
|
343
84
|
]);
|
|
344
85
|
if (provider && localProviders.has(provider)) {
|
|
345
86
|
attempted.push("local-provider-passthrough");
|
|
@@ -390,7 +131,7 @@ var ModelNameResolver = class {
|
|
|
390
131
|
resolveOrThrow(input) {
|
|
391
132
|
const result = this.resolve(input);
|
|
392
133
|
if (result.found) return result;
|
|
393
|
-
throw new (0,
|
|
134
|
+
throw new (0, _chunkPADNCGZBcjs.ModelResolutionError)(input, result);
|
|
394
135
|
}
|
|
395
136
|
runPipeline(model, provider, attempted, threshold, resolvedVia, depth = 0) {
|
|
396
137
|
if (depth > 12) return { match: null };
|
|
@@ -415,7 +156,7 @@ var ModelNameResolver = class {
|
|
|
415
156
|
if (hit) return { match: hit };
|
|
416
157
|
hit = tryMatch("cross-provider-correction", () => this.crossProviderCorrection(model));
|
|
417
158
|
if (hit) return { match: hit };
|
|
418
|
-
const stripped =
|
|
159
|
+
const stripped = _chunkEDMCKHO6cjs.stripModelVersionSuffix.call(void 0, model);
|
|
419
160
|
if (stripped && stripped !== model) {
|
|
420
161
|
if (!attempted.includes("version-suffix-strip")) attempted.push("version-suffix-strip");
|
|
421
162
|
const inner = this.runPipeline(
|
|
@@ -444,7 +185,7 @@ var ModelNameResolver = class {
|
|
|
444
185
|
if (shorthand) {
|
|
445
186
|
if (!attempted.includes("shorthand-expansion")) attempted.push("shorthand-expansion");
|
|
446
187
|
const inner = this.runPipeline(
|
|
447
|
-
normalizeString(shorthand),
|
|
188
|
+
_chunkEDMCKHO6cjs.normalizeString.call(void 0, shorthand),
|
|
448
189
|
provider,
|
|
449
190
|
attempted,
|
|
450
191
|
threshold,
|
|
@@ -522,7 +263,7 @@ var ModelNameResolver = class {
|
|
|
522
263
|
inferProviderFromSlug(slug) {
|
|
523
264
|
const patterns = [
|
|
524
265
|
...this.ctx.options.additionalProviderPatterns,
|
|
525
|
-
...PROVIDER_INFERENCE_MAP
|
|
266
|
+
..._chunkEDMCKHO6cjs.PROVIDER_INFERENCE_MAP
|
|
526
267
|
];
|
|
527
268
|
for (const { pattern, provider } of patterns) {
|
|
528
269
|
if (pattern.test(slug)) return provider;
|
|
@@ -587,18 +328,10 @@ var ModelNameResolver = class {
|
|
|
587
328
|
reason: `Corrected provider prefix from "${wrongPrefix}" to "${inferred}" based on model name pattern`
|
|
588
329
|
};
|
|
589
330
|
}
|
|
590
|
-
stripVersionSuffixes(model) {
|
|
591
|
-
for (const { re } of VERSION_STRIP_PATTERNS) {
|
|
592
|
-
if (re.test(model)) {
|
|
593
|
-
return model.replace(re, "");
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
return null;
|
|
597
|
-
}
|
|
598
331
|
dateSuffixMatch(model) {
|
|
599
332
|
if (model.includes("/")) {
|
|
600
333
|
const [prefix, slug] = model.split("/", 2);
|
|
601
|
-
const stripped =
|
|
334
|
+
const stripped = _chunkEDMCKHO6cjs.stripModelSlugSuffix.call(void 0, slug);
|
|
602
335
|
if (stripped && stripped !== slug) {
|
|
603
336
|
const candidate = `${prefix}/${stripped}`;
|
|
604
337
|
const record = this.catalog.get(candidate);
|
|
@@ -643,22 +376,22 @@ var ModelNameResolver = class {
|
|
|
643
376
|
return { modelId: best.modelId, record: best.record };
|
|
644
377
|
}
|
|
645
378
|
shorthandMap() {
|
|
646
|
-
return { ...SHORTHAND_MAP, ...this.ctx.options.additionalShorthands };
|
|
379
|
+
return { ..._chunkEDMCKHO6cjs.SHORTHAND_MAP, ...this.ctx.options.additionalShorthands };
|
|
647
380
|
}
|
|
648
381
|
partialMatch(model, provider) {
|
|
649
382
|
let best = null;
|
|
650
|
-
const inputTokens = tokenise(model);
|
|
383
|
+
const inputTokens = _chunkEDMCKHO6cjs.tokenise.call(void 0, model);
|
|
651
384
|
if (inputTokens.length === 0) return null;
|
|
652
385
|
for (const record of this.catalog.values()) {
|
|
653
386
|
const recordTokens = /* @__PURE__ */ new Set([
|
|
654
|
-
...tokenise(record.modelId),
|
|
655
|
-
...tokenise(_nullishCoalesce(record.name, () => ( "")))
|
|
387
|
+
..._chunkEDMCKHO6cjs.tokenise.call(void 0, record.modelId),
|
|
388
|
+
..._chunkEDMCKHO6cjs.tokenise.call(void 0, _nullishCoalesce(record.name, () => ( "")))
|
|
656
389
|
]);
|
|
657
390
|
const intersection = inputTokens.filter((t) => recordTokens.has(t));
|
|
658
391
|
const overlapRatio = intersection.length / inputTokens.length;
|
|
659
392
|
let score = overlapRatio * 0.6;
|
|
660
393
|
if (record.modelId.includes(model)) score += 0.3;
|
|
661
|
-
const slug = modelSlug(record.modelId);
|
|
394
|
+
const slug = _chunkEDMCKHO6cjs.modelSlug.call(void 0, record.modelId);
|
|
662
395
|
if (model.includes(slug)) score += 0.2;
|
|
663
396
|
if (provider && provider === record.providerId) score += 0.15;
|
|
664
397
|
const lenPenalty = Math.abs(model.length - slug.length) / Math.max(model.length, slug.length, 1) * 0.1;
|
|
@@ -677,17 +410,17 @@ var ModelNameResolver = class {
|
|
|
677
410
|
};
|
|
678
411
|
}
|
|
679
412
|
computeRoutedViaOpenRouter(modelId, record, provider, originalProvider) {
|
|
680
|
-
const norm = _nullishCoalesce(normalizeProvider(originalProvider), () => ( provider));
|
|
413
|
+
const norm = _nullishCoalesce(_chunkEDMCKHO6cjs.normalizeProvider.call(void 0, originalProvider), () => ( provider));
|
|
681
414
|
if (norm === "openrouter") return true;
|
|
682
415
|
if (norm && norm !== "openrouter") {
|
|
683
|
-
if (shouldDefaultRouteViaOpenRouter(norm, this.ctx.options.routingEnv)) return true;
|
|
416
|
+
if (_chunkEDMCKHO6cjs.shouldDefaultRouteViaOpenRouter.call(void 0, norm, this.ctx.options.routingEnv)) return true;
|
|
684
417
|
return false;
|
|
685
418
|
}
|
|
686
|
-
const recordProvider = _optionalChain([record, 'optionalAccess',
|
|
687
|
-
if (recordProvider && shouldDefaultRouteViaOpenRouter(recordProvider, this.ctx.options.routingEnv)) {
|
|
419
|
+
const recordProvider = _optionalChain([record, 'optionalAccess', _ => _.providerId]);
|
|
420
|
+
if (recordProvider && _chunkEDMCKHO6cjs.shouldDefaultRouteViaOpenRouter.call(void 0, recordProvider, this.ctx.options.routingEnv)) {
|
|
688
421
|
return true;
|
|
689
422
|
}
|
|
690
|
-
if (_optionalChain([record, 'optionalAccess',
|
|
423
|
+
if (_optionalChain([record, 'optionalAccess', _2 => _2.availableOnOpenRouter]) && modelId.includes("/")) return true;
|
|
691
424
|
return false;
|
|
692
425
|
}
|
|
693
426
|
success(args) {
|
|
@@ -709,6 +442,29 @@ var ModelNameResolver = class {
|
|
|
709
442
|
}
|
|
710
443
|
};
|
|
711
444
|
|
|
445
|
+
// src/models/reasoningModel.ts
|
|
446
|
+
var REASONING_SUPPORTED_PARAMETERS = ["reasoning", "include_reasoning"];
|
|
447
|
+
function supportsReasoningParameter(model) {
|
|
448
|
+
return model.supportedParameters.some(
|
|
449
|
+
(p) => REASONING_SUPPORTED_PARAMETERS.includes(p)
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
function hasReasoningPricing(model) {
|
|
453
|
+
const raw = _optionalChain([model, 'access', _3 => _3.openRouterPricing, 'optionalAccess', _4 => _4.internal_reasoning]);
|
|
454
|
+
if (raw !== void 0 && raw !== null && String(raw).trim() !== "") {
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
return model.pricing.reasoningUsdPerToken !== void 0;
|
|
458
|
+
}
|
|
459
|
+
function computeSupportsReasoning(model) {
|
|
460
|
+
return supportsReasoningParameter(model) || hasReasoningPricing(model);
|
|
461
|
+
}
|
|
462
|
+
function isReasoningModel(model) {
|
|
463
|
+
if (model.supportsReasoning !== void 0) {
|
|
464
|
+
return model.supportsReasoning;
|
|
465
|
+
}
|
|
466
|
+
return computeSupportsReasoning(model);
|
|
467
|
+
}
|
|
712
468
|
|
|
713
469
|
|
|
714
470
|
|
|
@@ -718,12 +474,5 @@ var ModelNameResolver = class {
|
|
|
718
474
|
|
|
719
475
|
|
|
720
476
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
exports.DEFAULT_MODEL_CACHE_TTL_MS = DEFAULT_MODEL_CACHE_TTL_MS; exports.readCachedModels = readCachedModels; exports.writeCachedModels = writeCachedModels; exports.invalidateModelsCache = invalidateModelsCache; exports.AI_MODELS_CATALOG_ID = AI_MODELS_CATALOG_ID; exports.AI_TOOLS_APP_ID = AI_TOOLS_APP_ID; exports.AI_MODELS_DESCRIPTOR = AI_MODELS_DESCRIPTOR; exports.providerIdToEnvKeyPrefix = providerIdToEnvKeyPrefix; exports.vendorApiKeyEnvName = vendorApiKeyEnvName; exports.loadOpenRouterRoutingEnv = loadOpenRouterRoutingEnv; exports.shouldDefaultRouteViaOpenRouter = shouldDefaultRouteViaOpenRouter; exports.normalizeString = normalizeString; exports.normalizeProvider = normalizeProvider; exports.buildCatalogIndexes = buildCatalogIndexes; exports.ModelNameResolver = ModelNameResolver;
|
|
729
|
-
//# sourceMappingURL=chunk-TF4L2NEC.cjs.map
|
|
477
|
+
exports.buildCatalogIndexes = buildCatalogIndexes; exports.ModelNameResolver = ModelNameResolver; exports.REASONING_SUPPORTED_PARAMETERS = REASONING_SUPPORTED_PARAMETERS; exports.supportsReasoningParameter = supportsReasoningParameter; exports.hasReasoningPricing = hasReasoningPricing; exports.computeSupportsReasoning = computeSupportsReasoning; exports.isReasoningModel = isReasoningModel;
|
|
478
|
+
//# sourceMappingURL=chunk-DXZOL3VN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-DXZOL3VN.cjs","../src/sync/modelNameResolver/catalogIndexes.ts","../src/sync/modelNameResolver/ModelNameResolver.ts","../src/models/reasoningModel.ts"],"names":[],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-DXZOL3VN.cjs","sourcesContent":[null,"import type { AiModelRecord } from \"../../models/types.js\";\nimport { normalizeString } from \"./normalize.js\";\nimport type { CatalogIndexes } from \"./types.js\";\n\nexport function buildCatalogIndexes(catalog: Map<string, AiModelRecord>): CatalogIndexes {\n const aliasIndex = new Map<string, string>();\n const slugIndex = new Map<string, string>();\n const prefixCounts = new Map<string, number>();\n\n for (const record of catalog.values()) {\n for (const alias of record.aliases) {\n aliasIndex.set(normalizeString(alias), record.modelId);\n }\n if (record.canonicalSlug) {\n slugIndex.set(normalizeString(record.canonicalSlug), record.modelId);\n }\n const pid = record.providerId;\n prefixCounts.set(pid, (prefixCounts.get(pid) ?? 0) + 1);\n }\n\n const providerPrefixesBySize = [...prefixCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([p]) => p);\n\n return { aliasIndex, slugIndex, providerPrefixesBySize };\n}\n","import { ModelResolutionError } from \"../../errors.js\";\nimport type { AiModelRecord } from \"../../models/types.js\";\nimport {\n loadOpenRouterRoutingEnv,\n shouldDefaultRouteViaOpenRouter,\n} from \"../openRouterRoutingEnv.js\";\nimport { buildCatalogIndexes } from \"./catalogIndexes.js\";\nimport {\n DEFAULT_CONFIDENCE_THRESHOLD,\n LOCAL_PROVIDERS,\n PROVIDER_INFERENCE_MAP,\n SHORTHAND_MAP,\n} from \"./constants.js\";\nimport { modelSlug, normalizeProvider, normalizeString, tokenise } from \"./normalize.js\";\nimport { stripModelSlugSuffix, stripModelVersionSuffix } from \"./stripVersionSuffix.js\";\nimport type {\n CatalogIndexes,\n ModelResolutionInput,\n ModelResolutionNotFound,\n ModelResolutionResult,\n ModelResolutionSuccess,\n ModelResolverOptions,\n ResolutionStrategy,\n ResolverContext,\n} from \"./types.js\";\n\ntype MatchCandidate = {\n modelId: string;\n record: AiModelRecord | null;\n confidence: number;\n strategy: ResolutionStrategy;\n reason: string;\n};\n\nexport class ModelNameResolver {\n private readonly catalog: Map<string, AiModelRecord>;\n private readonly indexes: CatalogIndexes;\n private readonly ctx: ResolverContext;\n\n constructor(\n catalog: Map<string, AiModelRecord>,\n options: ModelResolverOptions = {},\n ) {\n this.catalog = catalog;\n this.indexes = buildCatalogIndexes(catalog);\n this.ctx = {\n catalog,\n indexes: this.indexes,\n options: {\n confidenceThreshold: options.confidenceThreshold ?? DEFAULT_CONFIDENCE_THRESHOLD,\n aliasRegistry: options.aliasRegistry,\n additionalShorthands: options.additionalShorthands ?? {},\n additionalProviderPatterns: options.additionalProviderPatterns ?? [],\n additionalLocalProviders: options.additionalLocalProviders ?? [],\n routingEnv: options.routingEnv ?? loadOpenRouterRoutingEnv(),\n },\n };\n }\n\n resolve(input: ModelResolutionInput): ModelResolutionResult {\n const attempted: ResolutionStrategy[] = [];\n const threshold = this.ctx.options.confidenceThreshold;\n\n let provider = normalizeProvider(input.provider);\n let model = normalizeString(input.model);\n const normalisedInput = model;\n\n // S0 — alias registry on model string\n if (this.ctx.options.aliasRegistry) {\n attempted.push(\"alias-registry\");\n const entry = this.ctx.options.aliasRegistry.get(model);\n if (entry) {\n model = normalizeString(entry.modelId);\n provider = normalizeProvider(entry.provider) ?? provider;\n }\n }\n\n // Alias used as provider name (e.g. provider=\"best\")\n if (this.ctx.options.aliasRegistry && provider) {\n const aliasAsProvider = this.ctx.options.aliasRegistry.get(provider);\n if (aliasAsProvider) {\n attempted.push(\"alias-as-provider-correction\");\n model = normalizeString(aliasAsProvider.modelId);\n provider = normalizeProvider(aliasAsProvider.provider) ?? provider;\n }\n }\n\n // S10 — local provider (before catalog strategies)\n const localProviders = new Set([\n ...LOCAL_PROVIDERS,\n ...this.ctx.options.additionalLocalProviders.map((p) => normalizeString(p)),\n ]);\n if (provider && localProviders.has(provider)) {\n attempted.push(\"local-provider-passthrough\");\n return this.success({\n modelId: model,\n record: null,\n confidence: 0.99,\n strategy: \"local-provider-passthrough\",\n reason: `Local provider \"${provider}\" — model not looked up in catalog`,\n resolvedVia: attempted,\n normalisedInput,\n provider,\n originalProvider: input.provider,\n });\n }\n\n const preCorrection = [...attempted];\n\n const { match, rejected } = this.runPipeline(model, provider, attempted, threshold, []);\n if (match) {\n const via = [\n ...preCorrection.filter((s) => !match.resolvedVia.includes(s)),\n ...match.resolvedVia,\n ];\n return this.success({\n modelId: match.modelId,\n record: match.record,\n confidence: match.confidence,\n strategy: match.strategy,\n reason: match.reason,\n resolvedVia: via,\n normalisedInput,\n provider,\n originalProvider: input.provider,\n });\n }\n\n const notFound: ModelResolutionNotFound = {\n found: false,\n modelId: null,\n record: null,\n attemptedStrategies: attempted,\n reason: \"No catalog entry matched after all strategies.\",\n bestRejectedCandidate: rejected,\n };\n return notFound;\n }\n\n resolveMany(inputs: ModelResolutionInput[]): ModelResolutionResult[] {\n return inputs.map((i) => this.resolve(i));\n }\n\n resolveOrThrow(input: ModelResolutionInput): ModelResolutionSuccess {\n const result = this.resolve(input);\n if (result.found) return result;\n throw new ModelResolutionError(input, result);\n }\n\n private runPipeline(\n model: string,\n provider: string | undefined,\n attempted: ResolutionStrategy[],\n threshold: number,\n resolvedVia: ResolutionStrategy[],\n depth = 0,\n ): {\n match: (MatchCandidate & { resolvedVia: ResolutionStrategy[] }) | null;\n rejected?: ModelResolutionNotFound[\"bestRejectedCandidate\"];\n } {\n if (depth > 12) return { match: null };\n\n const tryMatch = (\n strategy: ResolutionStrategy,\n fn: () => MatchCandidate | null,\n ): (MatchCandidate & { resolvedVia: ResolutionStrategy[] }) | null => {\n if (!attempted.includes(strategy)) attempted.push(strategy);\n const m = fn();\n if (m && m.confidence >= threshold) {\n return { ...m, resolvedVia: [...resolvedVia, strategy] };\n }\n return null;\n };\n\n let hit = tryMatch(\"exact-match\", () => this.exactMatch(model));\n if (hit) return { match: hit };\n\n hit = tryMatch(\"catalog-alias-match\", () => this.catalogAliasMatch(model));\n if (hit) return { match: hit };\n\n hit = tryMatch(\"canonical-slug-match\", () => this.slugMatch(model));\n if (hit) return { match: hit };\n\n hit = tryMatch(\"provider-prefix-injection\", () =>\n this.providerPrefixInjection(model, provider),\n );\n if (hit) return { match: hit };\n\n hit = tryMatch(\"cross-provider-correction\", () => this.crossProviderCorrection(model));\n if (hit) return { match: hit };\n\n const stripped = stripModelVersionSuffix(model);\n if (stripped && stripped !== model) {\n if (!attempted.includes(\"version-suffix-strip\")) attempted.push(\"version-suffix-strip\");\n const inner = this.runPipeline(\n stripped,\n provider,\n attempted,\n threshold,\n [...resolvedVia, \"version-suffix-strip\"],\n depth + 1,\n );\n if (inner.match) {\n return {\n match: {\n ...inner.match,\n confidence: 0.85,\n strategy: \"version-suffix-strip\",\n reason: `Stripped version suffix from \"${model}\" → \"${stripped}\" then ${inner.match.reason}`,\n resolvedVia: [...resolvedVia, \"version-suffix-strip\", ...inner.match.resolvedVia],\n },\n };\n }\n }\n\n hit = tryMatch(\"date-suffix-strip\", () => this.dateSuffixMatch(model));\n if (hit) return { match: hit };\n\n const shorthand = this.shorthandMap()[model];\n if (shorthand) {\n if (!attempted.includes(\"shorthand-expansion\")) attempted.push(\"shorthand-expansion\");\n const inner = this.runPipeline(\n normalizeString(shorthand),\n provider,\n attempted,\n threshold,\n [...resolvedVia, \"shorthand-expansion\"],\n depth + 1,\n );\n if (inner.match) {\n return {\n match: {\n ...inner.match,\n confidence: 0.8,\n strategy: \"shorthand-expansion\",\n reason: `Expanded shorthand \"${model}\" → \"${shorthand}\" then ${inner.match.reason}`,\n resolvedVia: [...resolvedVia, \"shorthand-expansion\", ...inner.match.resolvedVia],\n },\n };\n }\n }\n\n const partial = this.partialMatch(model, provider);\n if (partial) {\n if (!attempted.includes(\"partial-name-match\")) attempted.push(\"partial-name-match\");\n if (partial.confidence >= threshold) {\n return {\n match: { ...partial, resolvedVia: [...resolvedVia, \"partial-name-match\"] },\n };\n }\n return {\n match: null,\n rejected: {\n modelId: partial.modelId,\n confidence: partial.confidence,\n reason: partial.reason,\n },\n };\n }\n\n return { match: null };\n }\n\n private exactMatch(model: string): MatchCandidate | null {\n const record = this.catalog.get(model);\n if (!record) return null;\n return {\n modelId: model,\n record,\n confidence: 1,\n strategy: \"exact-match\",\n reason: `Exact catalog match for \"${model}\"`,\n };\n }\n\n private catalogAliasMatch(model: string): MatchCandidate | null {\n const modelId = this.indexes.aliasIndex.get(model);\n if (!modelId) return null;\n const record = this.catalog.get(modelId);\n if (!record) return null;\n return {\n modelId,\n record,\n confidence: 1,\n strategy: \"catalog-alias-match\",\n reason: `Catalog alias \"${model}\" → \"${modelId}\"`,\n };\n }\n\n private slugMatch(model: string): MatchCandidate | null {\n const modelId = this.indexes.slugIndex.get(model);\n if (!modelId) return null;\n const record = this.catalog.get(modelId);\n if (!record) return null;\n return {\n modelId,\n record,\n confidence: 0.95,\n strategy: \"canonical-slug-match\",\n reason: `Canonical slug match \"${model}\" → \"${modelId}\"`,\n };\n }\n\n private inferProviderFromSlug(slug: string): string | undefined {\n const patterns = [\n ...this.ctx.options.additionalProviderPatterns,\n ...PROVIDER_INFERENCE_MAP,\n ];\n for (const { pattern, provider } of patterns) {\n if (pattern.test(slug)) return provider;\n }\n return undefined;\n }\n\n private providerPrefixInjection(\n model: string,\n provider: string | undefined,\n ): MatchCandidate | null {\n if (model.includes(\"/\")) return null;\n\n const prefixes: string[] = [];\n if (provider && provider !== \"openrouter\") {\n prefixes.push(provider);\n }\n const inferred = this.inferProviderFromSlug(model);\n if (inferred && !prefixes.includes(inferred)) prefixes.push(inferred);\n for (const p of this.indexes.providerPrefixesBySize) {\n if (!prefixes.includes(p)) prefixes.push(p);\n }\n\n for (const prefix of prefixes) {\n const candidate = `${prefix}/${model}`;\n let record = this.catalog.get(candidate);\n let modelId = candidate;\n if (!record) {\n const latest = this.findLatestVersioned(candidate);\n if (latest) {\n record = latest.record;\n modelId = latest.modelId;\n }\n }\n if (record) {\n const viaInference = inferred === prefix;\n return {\n modelId,\n record,\n confidence: 0.95,\n strategy: \"provider-prefix-injection\",\n reason: viaInference\n ? `Injected provider prefix \"${prefix}/\" inferred from model name pattern`\n : `Injected provider prefix \"${prefix}/\"`,\n };\n }\n }\n return null;\n }\n\n private crossProviderCorrection(model: string): MatchCandidate | null {\n if (!model.includes(\"/\")) return null;\n const [wrongPrefix, ...rest] = model.split(\"/\");\n const slug = rest.join(\"/\");\n const inferred = this.inferProviderFromSlug(slug);\n if (!inferred || inferred === wrongPrefix) return null;\n const candidate = `${inferred}/${slug}`;\n let record = this.catalog.get(candidate);\n let modelId = candidate;\n if (!record) {\n const latest = this.findLatestVersioned(candidate);\n if (!latest) return null;\n record = latest.record;\n modelId = latest.modelId;\n }\n return {\n modelId,\n record,\n confidence: 0.9,\n strategy: \"cross-provider-correction\",\n reason: `Corrected provider prefix from \"${wrongPrefix}\" to \"${inferred}\" based on model name pattern`,\n };\n }\n\n private dateSuffixMatch(model: string): MatchCandidate | null {\n if (model.includes(\"/\")) {\n const [prefix, slug] = model.split(\"/\", 2);\n const stripped = stripModelSlugSuffix(slug);\n if (stripped && stripped !== slug) {\n const candidate = `${prefix}/${stripped}`;\n const record = this.catalog.get(candidate);\n if (record) {\n return {\n modelId: candidate,\n record,\n confidence: 0.85,\n strategy: \"date-suffix-strip\",\n reason: `Stripped date from slug \"${slug}\" → \"${stripped}\"`,\n };\n }\n }\n }\n\n const latest = this.findLatestVersioned(model);\n if (latest) {\n return {\n modelId: latest.modelId,\n record: latest.record,\n confidence: 0.85,\n strategy: \"date-suffix-strip\",\n reason: `Matched \"${model}\" to versioned catalog entry \"${latest.modelId}\" (latest)`,\n };\n }\n return null;\n }\n\n private findLatestVersioned(\n baseModelId: string,\n ): { modelId: string; record: AiModelRecord } | null {\n const candidates: Array<{ modelId: string; record: AiModelRecord; suffix: string }> = [];\n for (const [modelId, record] of this.catalog) {\n if (modelId === baseModelId) continue;\n if (modelId.startsWith(`${baseModelId}-`)) {\n candidates.push({\n modelId,\n record,\n suffix: modelId.slice(baseModelId.length + 1),\n });\n }\n }\n if (candidates.length === 0) return null;\n candidates.sort((a, b) => b.suffix.localeCompare(a.suffix));\n const best = candidates[0]!;\n return { modelId: best.modelId, record: best.record };\n }\n\n private shorthandMap(): Record<string, string> {\n return { ...SHORTHAND_MAP, ...this.ctx.options.additionalShorthands };\n }\n\n private partialMatch(\n model: string,\n provider: string | undefined,\n ): (MatchCandidate & { resolvedVia?: ResolutionStrategy[] }) | null {\n let best: { modelId: string; record: AiModelRecord; score: number } | null = null;\n const inputTokens = tokenise(model);\n if (inputTokens.length === 0) return null;\n\n for (const record of this.catalog.values()) {\n const recordTokens = new Set([\n ...tokenise(record.modelId),\n ...tokenise(record.name ?? \"\"),\n ]);\n const intersection = inputTokens.filter((t) => recordTokens.has(t));\n const overlapRatio = intersection.length / inputTokens.length;\n let score = overlapRatio * 0.6;\n\n if (record.modelId.includes(model)) score += 0.3;\n const slug = modelSlug(record.modelId);\n if (model.includes(slug)) score += 0.2;\n\n if (provider && provider === record.providerId) score += 0.15;\n\n const lenPenalty =\n (Math.abs(model.length - slug.length) / Math.max(model.length, slug.length, 1)) * 0.1;\n score -= lenPenalty;\n\n if (!best || score > best.score) {\n best = { modelId: record.modelId, record, score };\n }\n }\n\n if (!best || best.score < 0.65) return null;\n return {\n modelId: best.modelId,\n record: best.record,\n confidence: 0.65,\n strategy: \"partial-name-match\",\n reason: `Partial token match (score ${best.score.toFixed(2)})`,\n };\n }\n\n private computeRoutedViaOpenRouter(\n modelId: string,\n record: AiModelRecord | null,\n provider: string | undefined,\n originalProvider: string | undefined,\n ): boolean {\n const norm = normalizeProvider(originalProvider) ?? provider;\n if (norm === \"openrouter\") return true;\n if (norm && norm !== \"openrouter\") {\n if (shouldDefaultRouteViaOpenRouter(norm, this.ctx.options.routingEnv)) return true;\n return false;\n }\n\n const recordProvider = record?.providerId;\n if (recordProvider && shouldDefaultRouteViaOpenRouter(recordProvider, this.ctx.options.routingEnv)) {\n return true;\n }\n\n if (record?.availableOnOpenRouter && modelId.includes(\"/\")) return true;\n return false;\n }\n\n private success(args: {\n modelId: string;\n record: AiModelRecord | null;\n confidence: number;\n strategy: ResolutionStrategy;\n reason: string;\n resolvedVia: ResolutionStrategy[];\n normalisedInput: string;\n provider?: string;\n originalProvider?: string;\n }): ModelResolutionSuccess {\n return {\n found: true,\n modelId: args.modelId,\n record: args.record,\n routedViaOpenRouter: this.computeRoutedViaOpenRouter(\n args.modelId,\n args.record,\n args.provider,\n args.originalProvider,\n ),\n confidence: args.confidence,\n resolvedVia: args.resolvedVia,\n resolvedReason: args.reason,\n normalisedInput: args.normalisedInput,\n };\n }\n}\n","import type { AiModelRecord } from \"./types.js\";\n\n/** OpenRouter `supported_parameters` values that indicate reasoning API support. */\nexport const REASONING_SUPPORTED_PARAMETERS = [\"reasoning\", \"include_reasoning\"] as const;\n\nexport type ReasoningModelInput = Pick<\n AiModelRecord,\n \"supportedParameters\" | \"pricing\" | \"openRouterPricing\"\n> & {\n supportsReasoning?: boolean;\n};\n\n/**\n * Whether the model accepts OpenRouter's `reasoning` request parameter\n * (effort, max_tokens, exclude, enabled).\n */\nexport function supportsReasoningParameter(model: Pick<AiModelRecord, \"supportedParameters\">): boolean {\n return model.supportedParameters.some((p) =>\n (REASONING_SUPPORTED_PARAMETERS as readonly string[]).includes(p),\n );\n}\n\n/**\n * Whether the model bills separate reasoning / thinking tokens\n * (`internal_reasoning` in OpenRouter pricing).\n */\nexport function hasReasoningPricing(\n model: Pick<AiModelRecord, \"pricing\" | \"openRouterPricing\">,\n): boolean {\n const raw = model.openRouterPricing?.internal_reasoning;\n if (raw !== undefined && raw !== null && String(raw).trim() !== \"\") {\n return true;\n }\n return model.pricing.reasoningUsdPerToken !== undefined;\n}\n\n/**\n * Compute `supportsReasoning` from catalog fields (used when normalizing catalog entries).\n */\nexport function computeSupportsReasoning(model: ReasoningModelInput): boolean {\n return supportsReasoningParameter(model) || hasReasoningPricing(model);\n}\n\n/**\n * True when the model supports reasoning tokens (API param and/or separate reasoning pricing).\n *\n * Prefer `model.supportsReasoning` on {@link AiModelRecord} after catalog load;\n * this helper also works when only partial fields are available.\n */\nexport function isReasoningModel(model: ReasoningModelInput): boolean {\n if (model.supportsReasoning !== undefined) {\n return model.supportsReasoning;\n }\n return computeSupportsReasoning(model);\n}\n"]}
|