@x12i/ai-tools 1.0.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.
Files changed (113) hide show
  1. package/README.md +214 -0
  2. package/dist/AiModelsCatalogClient-4RF5BCDL.cjs +9 -0
  3. package/dist/AiModelsCatalogClient-4RF5BCDL.cjs.map +1 -0
  4. package/dist/AiModelsCatalogClient-B-dNLXX0.d.ts +29 -0
  5. package/dist/AiModelsCatalogClient-CSVlKql5.d.cts +29 -0
  6. package/dist/AiModelsCatalogClient-NUF3CBLW.js +9 -0
  7. package/dist/AiModelsCatalogClient-NUF3CBLW.js.map +1 -0
  8. package/dist/aliases/index.cjs +11 -0
  9. package/dist/aliases/index.cjs.map +1 -0
  10. package/dist/aliases/index.d.cts +21 -0
  11. package/dist/aliases/index.d.ts +21 -0
  12. package/dist/aliases/index.js +11 -0
  13. package/dist/aliases/index.js.map +1 -0
  14. package/dist/catalox/index.cjs +21 -0
  15. package/dist/catalox/index.cjs.map +1 -0
  16. package/dist/catalox/index.d.cts +23 -0
  17. package/dist/catalox/index.d.ts +23 -0
  18. package/dist/catalox/index.js +21 -0
  19. package/dist/catalox/index.js.map +1 -0
  20. package/dist/chunk-2PYACSZ5.cjs +1 -0
  21. package/dist/chunk-2PYACSZ5.cjs.map +1 -0
  22. package/dist/chunk-3E67S427.cjs +1 -0
  23. package/dist/chunk-3E67S427.cjs.map +1 -0
  24. package/dist/chunk-4NAY6HRP.js +137 -0
  25. package/dist/chunk-4NAY6HRP.js.map +1 -0
  26. package/dist/chunk-5HNFAYTO.cjs +254 -0
  27. package/dist/chunk-5HNFAYTO.cjs.map +1 -0
  28. package/dist/chunk-6QGDZTGH.js +127 -0
  29. package/dist/chunk-6QGDZTGH.js.map +1 -0
  30. package/dist/chunk-7Q742NI3.cjs +106 -0
  31. package/dist/chunk-7Q742NI3.cjs.map +1 -0
  32. package/dist/chunk-AJEKEWWB.js +106 -0
  33. package/dist/chunk-AJEKEWWB.js.map +1 -0
  34. package/dist/chunk-AV6OE2YQ.cjs +127 -0
  35. package/dist/chunk-AV6OE2YQ.cjs.map +1 -0
  36. package/dist/chunk-COK34C6P.js +1 -0
  37. package/dist/chunk-COK34C6P.js.map +1 -0
  38. package/dist/chunk-DJ5SWJDY.js +729 -0
  39. package/dist/chunk-DJ5SWJDY.js.map +1 -0
  40. package/dist/chunk-F2F4UEFD.cjs +75 -0
  41. package/dist/chunk-F2F4UEFD.cjs.map +1 -0
  42. package/dist/chunk-G2G4KSC5.js +30 -0
  43. package/dist/chunk-G2G4KSC5.js.map +1 -0
  44. package/dist/chunk-HHNHWYTP.cjs +105 -0
  45. package/dist/chunk-HHNHWYTP.cjs.map +1 -0
  46. package/dist/chunk-HN6UAQAE.cjs +83 -0
  47. package/dist/chunk-HN6UAQAE.cjs.map +1 -0
  48. package/dist/chunk-KHODXGPV.js +1 -0
  49. package/dist/chunk-KHODXGPV.js.map +1 -0
  50. package/dist/chunk-KQOALKKX.js +75 -0
  51. package/dist/chunk-KQOALKKX.js.map +1 -0
  52. package/dist/chunk-LYOU7CA2.cjs +30 -0
  53. package/dist/chunk-LYOU7CA2.cjs.map +1 -0
  54. package/dist/chunk-ML2FRR4L.js +105 -0
  55. package/dist/chunk-ML2FRR4L.js.map +1 -0
  56. package/dist/chunk-MLRHYOCD.js +160 -0
  57. package/dist/chunk-MLRHYOCD.js.map +1 -0
  58. package/dist/chunk-O2A6OVEH.js +240 -0
  59. package/dist/chunk-O2A6OVEH.js.map +1 -0
  60. package/dist/chunk-ONA73BU6.cjs +160 -0
  61. package/dist/chunk-ONA73BU6.cjs.map +1 -0
  62. package/dist/chunk-QCRLKVB3.cjs +137 -0
  63. package/dist/chunk-QCRLKVB3.cjs.map +1 -0
  64. package/dist/chunk-QWAX7VQO.cjs +240 -0
  65. package/dist/chunk-QWAX7VQO.cjs.map +1 -0
  66. package/dist/chunk-TF4L2NEC.cjs +729 -0
  67. package/dist/chunk-TF4L2NEC.cjs.map +1 -0
  68. package/dist/chunk-XRBZQQQU.js +254 -0
  69. package/dist/chunk-XRBZQQQU.js.map +1 -0
  70. package/dist/chunk-YHO57D2V.js +83 -0
  71. package/dist/chunk-YHO57D2V.js.map +1 -0
  72. package/dist/cli/index.cjs +403 -0
  73. package/dist/cli/index.cjs.map +1 -0
  74. package/dist/cli/index.d.cts +1 -0
  75. package/dist/cli/index.d.ts +1 -0
  76. package/dist/cli/index.js +403 -0
  77. package/dist/cli/index.js.map +1 -0
  78. package/dist/cost/index.cjs +7 -0
  79. package/dist/cost/index.cjs.map +1 -0
  80. package/dist/cost/index.d.cts +52 -0
  81. package/dist/cost/index.d.ts +52 -0
  82. package/dist/cost/index.js +7 -0
  83. package/dist/cost/index.js.map +1 -0
  84. package/dist/index.cjs +104 -0
  85. package/dist/index.cjs.map +1 -0
  86. package/dist/index.d.cts +58 -0
  87. package/dist/index.d.ts +58 -0
  88. package/dist/index.js +104 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/modelNameResolver-Bn8QnkSj.d.ts +80 -0
  91. package/dist/modelNameResolver-bZD-eBSJ.d.cts +80 -0
  92. package/dist/models/index.cjs +33 -0
  93. package/dist/models/index.cjs.map +1 -0
  94. package/dist/models/index.d.cts +75 -0
  95. package/dist/models/index.d.ts +75 -0
  96. package/dist/models/index.js +33 -0
  97. package/dist/models/index.js.map +1 -0
  98. package/dist/sync/index.cjs +38 -0
  99. package/dist/sync/index.cjs.map +1 -0
  100. package/dist/sync/index.d.cts +12 -0
  101. package/dist/sync/index.d.ts +12 -0
  102. package/dist/sync/index.js +38 -0
  103. package/dist/sync/index.js.map +1 -0
  104. package/dist/toolbox/index.cjs +7 -0
  105. package/dist/toolbox/index.cjs.map +1 -0
  106. package/dist/toolbox/index.d.cts +72 -0
  107. package/dist/toolbox/index.d.ts +72 -0
  108. package/dist/toolbox/index.js +7 -0
  109. package/dist/toolbox/index.js.map +1 -0
  110. package/dist/types-DdGB3YaA.d.cts +278 -0
  111. package/dist/types-DdGB3YaA.d.ts +278 -0
  112. package/package.json +115 -0
  113. package/schemas/aliases.json +28 -0
@@ -0,0 +1,729 @@
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
+
3
+ var _chunk7Q742NI3cjs = require('./chunk-7Q742NI3.cjs');
4
+
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
+
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
+
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
+
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
+
244
+ // src/sync/modelNameResolver/normalize.ts
245
+ function normalizeString(input) {
246
+ let s = input.trim();
247
+ s = s.replace(/\s+/g, " ").replace(/ /g, "-");
248
+ s = s.toLowerCase();
249
+ s = s.replace(/^\/+|\/+$/g, "");
250
+ s = s.replace(/\/+/g, "/");
251
+ if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) {
252
+ s = s.slice(1, -1);
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
+ }
268
+
269
+ // src/sync/modelNameResolver/catalogIndexes.ts
270
+ function buildCatalogIndexes(catalog) {
271
+ const aliasIndex = /* @__PURE__ */ new Map();
272
+ const slugIndex = /* @__PURE__ */ new Map();
273
+ const prefixCounts = /* @__PURE__ */ new Map();
274
+ for (const record of catalog.values()) {
275
+ for (const alias of record.aliases) {
276
+ aliasIndex.set(normalizeString(alias), record.modelId);
277
+ }
278
+ if (record.canonicalSlug) {
279
+ slugIndex.set(normalizeString(record.canonicalSlug), record.modelId);
280
+ }
281
+ const pid = record.providerId;
282
+ prefixCounts.set(pid, (_nullishCoalesce(prefixCounts.get(pid), () => ( 0))) + 1);
283
+ }
284
+ const providerPrefixesBySize = [...prefixCounts.entries()].sort((a, b) => b[1] - a[1]).map(([p]) => p);
285
+ return { aliasIndex, slugIndex, providerPrefixesBySize };
286
+ }
287
+
288
+ // 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
+ var ModelNameResolver = class {
299
+
300
+
301
+
302
+ constructor(catalog, options = {}) {
303
+ this.catalog = catalog;
304
+ this.indexes = buildCatalogIndexes(catalog);
305
+ this.ctx = {
306
+ catalog,
307
+ indexes: this.indexes,
308
+ options: {
309
+ confidenceThreshold: _nullishCoalesce(options.confidenceThreshold, () => ( DEFAULT_CONFIDENCE_THRESHOLD)),
310
+ aliasRegistry: options.aliasRegistry,
311
+ additionalShorthands: _nullishCoalesce(options.additionalShorthands, () => ( {})),
312
+ additionalProviderPatterns: _nullishCoalesce(options.additionalProviderPatterns, () => ( [])),
313
+ additionalLocalProviders: _nullishCoalesce(options.additionalLocalProviders, () => ( [])),
314
+ routingEnv: _nullishCoalesce(options.routingEnv, () => ( loadOpenRouterRoutingEnv()))
315
+ }
316
+ };
317
+ }
318
+ resolve(input) {
319
+ const attempted = [];
320
+ const threshold = this.ctx.options.confidenceThreshold;
321
+ let provider = normalizeProvider(input.provider);
322
+ let model = normalizeString(input.model);
323
+ const normalisedInput = model;
324
+ if (this.ctx.options.aliasRegistry) {
325
+ attempted.push("alias-registry");
326
+ const entry = this.ctx.options.aliasRegistry.get(model);
327
+ if (entry) {
328
+ model = normalizeString(entry.modelId);
329
+ provider = _nullishCoalesce(normalizeProvider(entry.provider), () => ( provider));
330
+ }
331
+ }
332
+ if (this.ctx.options.aliasRegistry && provider) {
333
+ const aliasAsProvider = this.ctx.options.aliasRegistry.get(provider);
334
+ if (aliasAsProvider) {
335
+ attempted.push("alias-as-provider-correction");
336
+ model = normalizeString(aliasAsProvider.modelId);
337
+ provider = _nullishCoalesce(normalizeProvider(aliasAsProvider.provider), () => ( provider));
338
+ }
339
+ }
340
+ const localProviders = /* @__PURE__ */ new Set([
341
+ ...LOCAL_PROVIDERS,
342
+ ...this.ctx.options.additionalLocalProviders.map((p) => normalizeString(p))
343
+ ]);
344
+ if (provider && localProviders.has(provider)) {
345
+ attempted.push("local-provider-passthrough");
346
+ return this.success({
347
+ modelId: model,
348
+ record: null,
349
+ confidence: 0.99,
350
+ strategy: "local-provider-passthrough",
351
+ reason: `Local provider "${provider}" \u2014 model not looked up in catalog`,
352
+ resolvedVia: attempted,
353
+ normalisedInput,
354
+ provider,
355
+ originalProvider: input.provider
356
+ });
357
+ }
358
+ const preCorrection = [...attempted];
359
+ const { match, rejected } = this.runPipeline(model, provider, attempted, threshold, []);
360
+ if (match) {
361
+ const via = [
362
+ ...preCorrection.filter((s) => !match.resolvedVia.includes(s)),
363
+ ...match.resolvedVia
364
+ ];
365
+ return this.success({
366
+ modelId: match.modelId,
367
+ record: match.record,
368
+ confidence: match.confidence,
369
+ strategy: match.strategy,
370
+ reason: match.reason,
371
+ resolvedVia: via,
372
+ normalisedInput,
373
+ provider,
374
+ originalProvider: input.provider
375
+ });
376
+ }
377
+ const notFound = {
378
+ found: false,
379
+ modelId: null,
380
+ record: null,
381
+ attemptedStrategies: attempted,
382
+ reason: "No catalog entry matched after all strategies.",
383
+ bestRejectedCandidate: rejected
384
+ };
385
+ return notFound;
386
+ }
387
+ resolveMany(inputs) {
388
+ return inputs.map((i) => this.resolve(i));
389
+ }
390
+ resolveOrThrow(input) {
391
+ const result = this.resolve(input);
392
+ if (result.found) return result;
393
+ throw new (0, _chunk7Q742NI3cjs.ModelResolutionError)(input, result);
394
+ }
395
+ runPipeline(model, provider, attempted, threshold, resolvedVia, depth = 0) {
396
+ if (depth > 12) return { match: null };
397
+ const tryMatch = (strategy, fn) => {
398
+ if (!attempted.includes(strategy)) attempted.push(strategy);
399
+ const m = fn();
400
+ if (m && m.confidence >= threshold) {
401
+ return { ...m, resolvedVia: [...resolvedVia, strategy] };
402
+ }
403
+ return null;
404
+ };
405
+ let hit = tryMatch("exact-match", () => this.exactMatch(model));
406
+ if (hit) return { match: hit };
407
+ hit = tryMatch("catalog-alias-match", () => this.catalogAliasMatch(model));
408
+ if (hit) return { match: hit };
409
+ hit = tryMatch("canonical-slug-match", () => this.slugMatch(model));
410
+ if (hit) return { match: hit };
411
+ hit = tryMatch(
412
+ "provider-prefix-injection",
413
+ () => this.providerPrefixInjection(model, provider)
414
+ );
415
+ if (hit) return { match: hit };
416
+ hit = tryMatch("cross-provider-correction", () => this.crossProviderCorrection(model));
417
+ if (hit) return { match: hit };
418
+ const stripped = this.stripVersionSuffixes(model);
419
+ if (stripped && stripped !== model) {
420
+ if (!attempted.includes("version-suffix-strip")) attempted.push("version-suffix-strip");
421
+ const inner = this.runPipeline(
422
+ stripped,
423
+ provider,
424
+ attempted,
425
+ threshold,
426
+ [...resolvedVia, "version-suffix-strip"],
427
+ depth + 1
428
+ );
429
+ if (inner.match) {
430
+ return {
431
+ match: {
432
+ ...inner.match,
433
+ confidence: 0.85,
434
+ strategy: "version-suffix-strip",
435
+ reason: `Stripped version suffix from "${model}" \u2192 "${stripped}" then ${inner.match.reason}`,
436
+ resolvedVia: [...resolvedVia, "version-suffix-strip", ...inner.match.resolvedVia]
437
+ }
438
+ };
439
+ }
440
+ }
441
+ hit = tryMatch("date-suffix-strip", () => this.dateSuffixMatch(model));
442
+ if (hit) return { match: hit };
443
+ const shorthand = this.shorthandMap()[model];
444
+ if (shorthand) {
445
+ if (!attempted.includes("shorthand-expansion")) attempted.push("shorthand-expansion");
446
+ const inner = this.runPipeline(
447
+ normalizeString(shorthand),
448
+ provider,
449
+ attempted,
450
+ threshold,
451
+ [...resolvedVia, "shorthand-expansion"],
452
+ depth + 1
453
+ );
454
+ if (inner.match) {
455
+ return {
456
+ match: {
457
+ ...inner.match,
458
+ confidence: 0.8,
459
+ strategy: "shorthand-expansion",
460
+ reason: `Expanded shorthand "${model}" \u2192 "${shorthand}" then ${inner.match.reason}`,
461
+ resolvedVia: [...resolvedVia, "shorthand-expansion", ...inner.match.resolvedVia]
462
+ }
463
+ };
464
+ }
465
+ }
466
+ const partial = this.partialMatch(model, provider);
467
+ if (partial) {
468
+ if (!attempted.includes("partial-name-match")) attempted.push("partial-name-match");
469
+ if (partial.confidence >= threshold) {
470
+ return {
471
+ match: { ...partial, resolvedVia: [...resolvedVia, "partial-name-match"] }
472
+ };
473
+ }
474
+ return {
475
+ match: null,
476
+ rejected: {
477
+ modelId: partial.modelId,
478
+ confidence: partial.confidence,
479
+ reason: partial.reason
480
+ }
481
+ };
482
+ }
483
+ return { match: null };
484
+ }
485
+ exactMatch(model) {
486
+ const record = this.catalog.get(model);
487
+ if (!record) return null;
488
+ return {
489
+ modelId: model,
490
+ record,
491
+ confidence: 1,
492
+ strategy: "exact-match",
493
+ reason: `Exact catalog match for "${model}"`
494
+ };
495
+ }
496
+ catalogAliasMatch(model) {
497
+ const modelId = this.indexes.aliasIndex.get(model);
498
+ if (!modelId) return null;
499
+ const record = this.catalog.get(modelId);
500
+ if (!record) return null;
501
+ return {
502
+ modelId,
503
+ record,
504
+ confidence: 1,
505
+ strategy: "catalog-alias-match",
506
+ reason: `Catalog alias "${model}" \u2192 "${modelId}"`
507
+ };
508
+ }
509
+ slugMatch(model) {
510
+ const modelId = this.indexes.slugIndex.get(model);
511
+ if (!modelId) return null;
512
+ const record = this.catalog.get(modelId);
513
+ if (!record) return null;
514
+ return {
515
+ modelId,
516
+ record,
517
+ confidence: 0.95,
518
+ strategy: "canonical-slug-match",
519
+ reason: `Canonical slug match "${model}" \u2192 "${modelId}"`
520
+ };
521
+ }
522
+ inferProviderFromSlug(slug) {
523
+ const patterns = [
524
+ ...this.ctx.options.additionalProviderPatterns,
525
+ ...PROVIDER_INFERENCE_MAP
526
+ ];
527
+ for (const { pattern, provider } of patterns) {
528
+ if (pattern.test(slug)) return provider;
529
+ }
530
+ return void 0;
531
+ }
532
+ providerPrefixInjection(model, provider) {
533
+ if (model.includes("/")) return null;
534
+ const prefixes = [];
535
+ if (provider && provider !== "openrouter") {
536
+ prefixes.push(provider);
537
+ }
538
+ const inferred = this.inferProviderFromSlug(model);
539
+ if (inferred && !prefixes.includes(inferred)) prefixes.push(inferred);
540
+ for (const p of this.indexes.providerPrefixesBySize) {
541
+ if (!prefixes.includes(p)) prefixes.push(p);
542
+ }
543
+ for (const prefix of prefixes) {
544
+ const candidate = `${prefix}/${model}`;
545
+ let record = this.catalog.get(candidate);
546
+ let modelId = candidate;
547
+ if (!record) {
548
+ const latest = this.findLatestVersioned(candidate);
549
+ if (latest) {
550
+ record = latest.record;
551
+ modelId = latest.modelId;
552
+ }
553
+ }
554
+ if (record) {
555
+ const viaInference = inferred === prefix;
556
+ return {
557
+ modelId,
558
+ record,
559
+ confidence: 0.95,
560
+ strategy: "provider-prefix-injection",
561
+ reason: viaInference ? `Injected provider prefix "${prefix}/" inferred from model name pattern` : `Injected provider prefix "${prefix}/"`
562
+ };
563
+ }
564
+ }
565
+ return null;
566
+ }
567
+ crossProviderCorrection(model) {
568
+ if (!model.includes("/")) return null;
569
+ const [wrongPrefix, ...rest] = model.split("/");
570
+ const slug = rest.join("/");
571
+ const inferred = this.inferProviderFromSlug(slug);
572
+ if (!inferred || inferred === wrongPrefix) return null;
573
+ const candidate = `${inferred}/${slug}`;
574
+ let record = this.catalog.get(candidate);
575
+ let modelId = candidate;
576
+ if (!record) {
577
+ const latest = this.findLatestVersioned(candidate);
578
+ if (!latest) return null;
579
+ record = latest.record;
580
+ modelId = latest.modelId;
581
+ }
582
+ return {
583
+ modelId,
584
+ record,
585
+ confidence: 0.9,
586
+ strategy: "cross-provider-correction",
587
+ reason: `Corrected provider prefix from "${wrongPrefix}" to "${inferred}" based on model name pattern`
588
+ };
589
+ }
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
+ dateSuffixMatch(model) {
599
+ if (model.includes("/")) {
600
+ const [prefix, slug] = model.split("/", 2);
601
+ const stripped = this.stripVersionSuffixes(slug);
602
+ if (stripped && stripped !== slug) {
603
+ const candidate = `${prefix}/${stripped}`;
604
+ const record = this.catalog.get(candidate);
605
+ if (record) {
606
+ return {
607
+ modelId: candidate,
608
+ record,
609
+ confidence: 0.85,
610
+ strategy: "date-suffix-strip",
611
+ reason: `Stripped date from slug "${slug}" \u2192 "${stripped}"`
612
+ };
613
+ }
614
+ }
615
+ }
616
+ const latest = this.findLatestVersioned(model);
617
+ if (latest) {
618
+ return {
619
+ modelId: latest.modelId,
620
+ record: latest.record,
621
+ confidence: 0.85,
622
+ strategy: "date-suffix-strip",
623
+ reason: `Matched "${model}" to versioned catalog entry "${latest.modelId}" (latest)`
624
+ };
625
+ }
626
+ return null;
627
+ }
628
+ findLatestVersioned(baseModelId) {
629
+ const candidates = [];
630
+ for (const [modelId, record] of this.catalog) {
631
+ if (modelId === baseModelId) continue;
632
+ if (modelId.startsWith(`${baseModelId}-`)) {
633
+ candidates.push({
634
+ modelId,
635
+ record,
636
+ suffix: modelId.slice(baseModelId.length + 1)
637
+ });
638
+ }
639
+ }
640
+ if (candidates.length === 0) return null;
641
+ candidates.sort((a, b) => b.suffix.localeCompare(a.suffix));
642
+ const best = candidates[0];
643
+ return { modelId: best.modelId, record: best.record };
644
+ }
645
+ shorthandMap() {
646
+ return { ...SHORTHAND_MAP, ...this.ctx.options.additionalShorthands };
647
+ }
648
+ partialMatch(model, provider) {
649
+ let best = null;
650
+ const inputTokens = tokenise(model);
651
+ if (inputTokens.length === 0) return null;
652
+ for (const record of this.catalog.values()) {
653
+ const recordTokens = /* @__PURE__ */ new Set([
654
+ ...tokenise(record.modelId),
655
+ ...tokenise(_nullishCoalesce(record.name, () => ( "")))
656
+ ]);
657
+ const intersection = inputTokens.filter((t) => recordTokens.has(t));
658
+ const overlapRatio = intersection.length / inputTokens.length;
659
+ let score = overlapRatio * 0.6;
660
+ if (record.modelId.includes(model)) score += 0.3;
661
+ const slug = modelSlug(record.modelId);
662
+ if (model.includes(slug)) score += 0.2;
663
+ if (provider && provider === record.providerId) score += 0.15;
664
+ const lenPenalty = Math.abs(model.length - slug.length) / Math.max(model.length, slug.length, 1) * 0.1;
665
+ score -= lenPenalty;
666
+ if (!best || score > best.score) {
667
+ best = { modelId: record.modelId, record, score };
668
+ }
669
+ }
670
+ if (!best || best.score < 0.65) return null;
671
+ return {
672
+ modelId: best.modelId,
673
+ record: best.record,
674
+ confidence: 0.65,
675
+ strategy: "partial-name-match",
676
+ reason: `Partial token match (score ${best.score.toFixed(2)})`
677
+ };
678
+ }
679
+ computeRoutedViaOpenRouter(modelId, record, provider, originalProvider) {
680
+ const norm = _nullishCoalesce(normalizeProvider(originalProvider), () => ( provider));
681
+ if (norm === "openrouter") return true;
682
+ if (norm && norm !== "openrouter") {
683
+ if (shouldDefaultRouteViaOpenRouter(norm, this.ctx.options.routingEnv)) return true;
684
+ return false;
685
+ }
686
+ const recordProvider = _optionalChain([record, 'optionalAccess', _14 => _14.providerId]);
687
+ if (recordProvider && shouldDefaultRouteViaOpenRouter(recordProvider, this.ctx.options.routingEnv)) {
688
+ return true;
689
+ }
690
+ if (_optionalChain([record, 'optionalAccess', _15 => _15.availableOnOpenRouter]) && modelId.includes("/")) return true;
691
+ return false;
692
+ }
693
+ success(args) {
694
+ return {
695
+ found: true,
696
+ modelId: args.modelId,
697
+ record: args.record,
698
+ routedViaOpenRouter: this.computeRoutedViaOpenRouter(
699
+ args.modelId,
700
+ args.record,
701
+ args.provider,
702
+ args.originalProvider
703
+ ),
704
+ confidence: args.confidence,
705
+ resolvedVia: args.resolvedVia,
706
+ resolvedReason: args.reason,
707
+ normalisedInput: args.normalisedInput
708
+ };
709
+ }
710
+ };
711
+
712
+
713
+
714
+
715
+
716
+
717
+
718
+
719
+
720
+
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