llm-models 1.2.2 → 1.2.4

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/build/cache.d.ts CHANGED
@@ -6,6 +6,7 @@ export declare function readSnapshot<T>(key: string): {
6
6
  timestamp: number;
7
7
  data: T;
8
8
  } | null;
9
+ export declare function readFallbackCache<T>(key: string): T | null;
9
10
  export declare function clearCache(): void;
10
11
  export declare function getCacheInfo(): {
11
12
  files: number;
@@ -1,7 +1,7 @@
1
1
  export { compareModels } from "./compare";
2
2
  export { cheapestModels, estimateCost } from "./cost";
3
3
  export { diffModels } from "./diff";
4
- export { fetchUnifiedModels } from "./normalize";
4
+ export { fetchUnifiedData, fetchUnifiedModels } from "./normalize";
5
5
  export { getProvider, listProviders } from "./provider";
6
6
  export { QueryBuilder, query } from "./query";
7
7
  export { listUseCases, recommendModels } from "./recommend";
@@ -1,5 +1,9 @@
1
- import type { ModelsDevModel, OpenRouterModel, UnifiedModel } from "../types";
1
+ import type { ModelsDevModel, ModelsDevResponse, OpenRouterModel, UnifiedModel } from "../types";
2
2
  export declare function openRouterPriceToPerMillion(perToken: string): number;
3
3
  export declare function normalizeOpenRouterModel(model: OpenRouterModel): UnifiedModel;
4
4
  export declare function normalizeModelsDevModel(model: ModelsDevModel, providerId: string): UnifiedModel;
5
+ export declare function fetchUnifiedData(): Promise<{
6
+ models: UnifiedModel[];
7
+ modelsDevData: ModelsDevResponse;
8
+ }>;
5
9
  export declare function fetchUnifiedModels(): Promise<UnifiedModel[]>;
package/build/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { clearCache, setCacheEnabled } from "./cache";
3
3
  export { fetchModelsDevModels } from "./clients/models-dev";
4
4
  export { fetchOpenRouterModels } from "./clients/openrouter";
5
5
  export { getProfile, listProfiles, loadConfig } from "./config";
6
- export { cheapestModels, compareModels, diffModels, estimateCost, fetchUnifiedModels, filterModels, findModels, getProvider, getStats, listProviders, listUseCases, QueryBuilder, query, recommendModels, sortModels, } from "./functions/index";
6
+ export { cheapestModels, compareModels, diffModels, estimateCost, fetchUnifiedData, fetchUnifiedModels, filterModels, findModels, getProvider, getStats, listProviders, listUseCases, QueryBuilder, query, recommendModels, sortModels, } from "./functions/index";
7
7
  export { CapabilitiesSchema, CostEstimateSchema, ModelComparisonSchema, ModelFilterSchema, ModelSortFieldSchema, NormalizedCostSchema, ProviderInfoSchema, UnifiedModelSchema, } from "./schemas/functions";
8
8
  export { ModelsDevCostSchema, ModelsDevLimitSchema, ModelsDevModalitiesSchema, ModelsDevModelSchema, ModelsDevProviderSchema, ModelsDevResponseSchema, } from "./schemas/models-dev";
9
9
  export { OpenRouterArchitectureSchema, OpenRouterDefaultParametersSchema, OpenRouterLinksSchema, OpenRouterModelSchema, OpenRouterPricingSchema, OpenRouterResponseSchema, OpenRouterTopProviderSchema, } from "./schemas/openrouter";
package/build/index.js CHANGED
@@ -4,7 +4,6 @@ var __create = Object.create;
4
4
  var __getProtoOf = Object.getPrototypeOf;
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
8
  function __accessProp(key) {
10
9
  return this[key];
@@ -31,23 +30,6 @@ var __toESM = (mod, isNodeMode, target) => {
31
30
  cache.set(mod, to);
32
31
  return to;
33
32
  };
34
- var __toCommonJS = (from) => {
35
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
36
- if (entry)
37
- return entry;
38
- entry = __defProp({}, "__esModule", { value: true });
39
- if (from && typeof from === "object" || typeof from === "function") {
40
- for (var key of __getOwnPropNames(from))
41
- if (!__hasOwnProp.call(entry, key))
42
- __defProp(entry, key, {
43
- get: __accessProp.bind(from, key),
44
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
45
- });
46
- }
47
- __moduleCache.set(from, entry);
48
- return entry;
49
- };
50
- var __moduleCache;
51
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
52
34
  var __returnValue = (v) => v;
53
35
  function __exportSetter(name, newValue) {
@@ -66,25 +48,20 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
66
48
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
67
49
 
68
50
  // src/cache.ts
69
- var exports_cache = {};
70
- __export(exports_cache, {
71
- writeCache: () => writeCache,
72
- setCacheEnabled: () => setCacheEnabled,
73
- readSnapshot: () => readSnapshot,
74
- readCache: () => readCache,
75
- isCacheEnabled: () => isCacheEnabled,
76
- getCacheInfo: () => getCacheInfo,
77
- clearCache: () => clearCache
78
- });
79
- import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
51
+ import {
52
+ existsSync,
53
+ mkdirSync,
54
+ readdirSync,
55
+ readFileSync,
56
+ rmSync,
57
+ statSync,
58
+ writeFileSync
59
+ } from "node:fs";
80
60
  import { homedir } from "node:os";
81
61
  import { join } from "node:path";
82
62
  function setCacheEnabled(enabled) {
83
63
  cacheEnabled = enabled;
84
64
  }
85
- function isCacheEnabled() {
86
- return cacheEnabled;
87
- }
88
65
  function ensureCacheDir() {
89
66
  if (!existsSync(CACHE_DIR)) {
90
67
  mkdirSync(CACHE_DIR, { recursive: true });
@@ -124,6 +101,18 @@ function readSnapshot(key) {
124
101
  return null;
125
102
  }
126
103
  }
104
+ function readFallbackCache(key) {
105
+ const filePath = join(CACHE_DIR, `${key}.json`);
106
+ try {
107
+ if (!existsSync(filePath))
108
+ return null;
109
+ const raw = readFileSync(filePath, "utf-8");
110
+ const cached = JSON.parse(raw);
111
+ return cached.data;
112
+ } catch {
113
+ return null;
114
+ }
115
+ }
127
116
  function clearCache() {
128
117
  if (existsSync(CACHE_DIR)) {
129
118
  rmSync(CACHE_DIR, { recursive: true });
@@ -139,8 +128,7 @@ function getCacheInfo() {
139
128
  let sizeBytes = 0;
140
129
  for (const file of files) {
141
130
  try {
142
- const stat = Bun.file(join(CACHE_DIR, file));
143
- sizeBytes += stat.size;
131
+ sizeBytes += statSync(join(CACHE_DIR, file)).size;
144
132
  } catch {}
145
133
  }
146
134
  return { files: files.length, sizeBytes };
@@ -14210,7 +14198,11 @@ function normalizeOpenRouterModel(model) {
14210
14198
  input: model.architecture.input_modalities,
14211
14199
  output: model.architecture.output_modalities
14212
14200
  },
14213
- capabilities: {},
14201
+ capabilities: {
14202
+ tool_call: model.supported_parameters.includes("tools") ? true : undefined,
14203
+ structured_output: model.supported_parameters.includes("response_format") ? true : undefined,
14204
+ reasoning: model.pricing.internal_reasoning && Number.parseFloat(model.pricing.internal_reasoning) > 0 ? true : undefined
14205
+ },
14214
14206
  knowledge_cutoff: model.knowledge_cutoff ?? null,
14215
14207
  release_date: undefined,
14216
14208
  status: undefined,
@@ -14261,7 +14253,9 @@ function mergeModels(openrouter, modelsDev) {
14261
14253
  if (cost && openrouter.cost && modelsDev.cost) {
14262
14254
  cost = {
14263
14255
  ...modelsDev.cost,
14264
- reasoning: modelsDev.cost.reasoning ?? openrouter.cost.reasoning
14256
+ reasoning: modelsDev.cost.reasoning ?? openrouter.cost.reasoning,
14257
+ cache_read: modelsDev.cost.cache_read ?? openrouter.cost.cache_read,
14258
+ cache_write: modelsDev.cost.cache_write ?? openrouter.cost.cache_write
14265
14259
  };
14266
14260
  }
14267
14261
  return {
@@ -14279,27 +14273,45 @@ function mergeModels(openrouter, modelsDev) {
14279
14273
  sources: { openrouter: true, models_dev: true }
14280
14274
  };
14281
14275
  }
14282
- async function fetchUnifiedModels() {
14283
- const [openRouterData, modelsDevData] = await Promise.all([
14284
- fetchOpenRouterModels(),
14285
- fetchModelsDevModels()
14286
- ]);
14276
+ async function fetchUnifiedData() {
14277
+ const results = await Promise.allSettled([fetchOpenRouterModels(), fetchModelsDevModels()]);
14278
+ let openRouterData = results[0].status === "fulfilled" ? results[0].value : null;
14279
+ let modelsDevData = results[1].status === "fulfilled" ? results[1].value : null;
14280
+ if (!openRouterData) {
14281
+ openRouterData = readFallbackCache("openrouter");
14282
+ if (openRouterData) {
14283
+ console.error("Warning: OpenRouter API unavailable, using expired cache");
14284
+ }
14285
+ }
14286
+ if (!modelsDevData) {
14287
+ modelsDevData = readFallbackCache("models-dev");
14288
+ if (modelsDevData) {
14289
+ console.error("Warning: models.dev API unavailable, using expired cache");
14290
+ }
14291
+ }
14292
+ if (!openRouterData && !modelsDevData) {
14293
+ throw new Error("Both APIs are unavailable and no cached data exists");
14294
+ }
14287
14295
  const modelsDevMap = new Map;
14288
- for (const [providerId, provider] of Object.entries(modelsDevData)) {
14289
- for (const model of Object.values(provider.models)) {
14290
- const unified2 = normalizeModelsDevModel(model, providerId);
14291
- modelsDevMap.set(unified2.id, unified2);
14296
+ if (modelsDevData) {
14297
+ for (const [providerId, provider] of Object.entries(modelsDevData)) {
14298
+ for (const model of Object.values(provider.models)) {
14299
+ const unified2 = normalizeModelsDevModel(model, providerId);
14300
+ modelsDevMap.set(unified2.id, unified2);
14301
+ }
14292
14302
  }
14293
14303
  }
14294
14304
  const result = new Map;
14295
- for (const orModel of openRouterData.data) {
14296
- const normalized = normalizeOpenRouterModel(orModel);
14297
- const modelsDevMatch = modelsDevMap.get(normalized.id);
14298
- if (modelsDevMatch) {
14299
- result.set(normalized.id, mergeModels(normalized, modelsDevMatch));
14300
- modelsDevMap.delete(normalized.id);
14301
- } else {
14302
- result.set(normalized.id, normalized);
14305
+ if (openRouterData) {
14306
+ for (const orModel of openRouterData.data) {
14307
+ const normalized = normalizeOpenRouterModel(orModel);
14308
+ const modelsDevMatch = modelsDevMap.get(normalized.id);
14309
+ if (modelsDevMatch) {
14310
+ result.set(normalized.id, mergeModels(normalized, modelsDevMatch));
14311
+ modelsDevMap.delete(normalized.id);
14312
+ } else {
14313
+ result.set(normalized.id, normalized);
14314
+ }
14303
14315
  }
14304
14316
  }
14305
14317
  for (const [id, model] of modelsDevMap) {
@@ -14307,7 +14319,10 @@ async function fetchUnifiedModels() {
14307
14319
  }
14308
14320
  const unified = Array.from(result.values());
14309
14321
  writeCache("unified", unified);
14310
- return unified;
14322
+ return { models: unified, modelsDevData: modelsDevData ?? {} };
14323
+ }
14324
+ async function fetchUnifiedModels() {
14325
+ return (await fetchUnifiedData()).models;
14311
14326
  }
14312
14327
  var init_normalize = __esm(() => {
14313
14328
  init_cache();
@@ -14415,7 +14430,7 @@ function filterModels(models, filter) {
14415
14430
  }
14416
14431
  if (filter.modality) {
14417
14432
  const mod = filter.modality.toLowerCase();
14418
- result = result.filter((m) => m.modalities.input.some((i) => i.toLowerCase() === mod));
14433
+ result = result.filter((m) => m.modalities.input.some((i) => i.toLowerCase() === mod) || m.modalities.output.some((o) => o.toLowerCase() === mod));
14419
14434
  }
14420
14435
  if (filter.maxCostInput != null) {
14421
14436
  const max = filter.maxCostInput;
@@ -14562,10 +14577,7 @@ var init_cost = __esm(() => {
14562
14577
 
14563
14578
  // src/functions/provider.ts
14564
14579
  async function getProvider(providerId) {
14565
- const [allModels, modelsDevData] = await Promise.all([
14566
- fetchUnifiedModels(),
14567
- fetchModelsDevModels()
14568
- ]);
14580
+ const { models: allModels, modelsDevData } = await fetchUnifiedData();
14569
14581
  const providerModels = allModels.filter((m) => m.provider.toLowerCase() === providerId.toLowerCase());
14570
14582
  if (providerModels.length === 0) {
14571
14583
  throw new Error(`Provider "${providerId}" not found`);
@@ -14583,10 +14595,7 @@ async function getProvider(providerId) {
14583
14595
  };
14584
14596
  }
14585
14597
  async function listProviders() {
14586
- const [allModels, modelsDevData] = await Promise.all([
14587
- fetchUnifiedModels(),
14588
- fetchModelsDevModels()
14589
- ]);
14598
+ const { models: allModels, modelsDevData } = await fetchUnifiedData();
14590
14599
  const providerMap = new Map;
14591
14600
  for (const model of allModels) {
14592
14601
  const existing = providerMap.get(model.provider) ?? [];
@@ -14610,7 +14619,6 @@ async function listProviders() {
14610
14619
  return providers.sort((a, b) => b.model_count - a.model_count);
14611
14620
  }
14612
14621
  var init_provider = __esm(() => {
14613
- init_models_dev2();
14614
14622
  init_normalize();
14615
14623
  });
14616
14624
 
@@ -14737,6 +14745,7 @@ async function getStats() {
14737
14745
  release_date: m.release_date
14738
14746
  }));
14739
14747
  const contexts = models.map((m) => m.context_length).sort((a, b) => a - b);
14748
+ const contextStats = contexts.length > 0 ? { min: contexts[0], max: contexts[contexts.length - 1], median: percentile(contexts, 50) } : { min: 0, max: 0, median: 0 };
14740
14749
  return {
14741
14750
  total_models: models.length,
14742
14751
  total_providers: providerMap.size,
@@ -14745,11 +14754,7 @@ async function getStats() {
14745
14754
  by_modality: byModality,
14746
14755
  cost: inputDist && outputDist ? { input: inputDist, output: outputDist } : null,
14747
14756
  newest_models: newest,
14748
- context_length: {
14749
- min: contexts[0],
14750
- max: contexts[contexts.length - 1],
14751
- median: percentile(contexts, 50)
14752
- }
14757
+ context_length: contextStats
14753
14758
  };
14754
14759
  }
14755
14760
  var init_stats = __esm(() => {
@@ -16849,82 +16854,6 @@ var require_commander = __commonJS((exports) => {
16849
16854
  exports.InvalidOptionArgumentError = InvalidArgumentError;
16850
16855
  });
16851
16856
 
16852
- // package.json
16853
- var require_package = __commonJS((exports, module) => {
16854
- module.exports = {
16855
- name: "llm-models",
16856
- version: "1.2.1",
16857
- author: "maxgfr",
16858
- license: "MIT",
16859
- type: "module",
16860
- main: "./build/index.js",
16861
- types: "./build/index.d.ts",
16862
- description: "Fetch latest LLM models from OpenRouter and models.dev APIs",
16863
- repository: {
16864
- type: "git",
16865
- url: "https://github.com/maxgfr/llm-models.git"
16866
- },
16867
- bugs: {
16868
- url: "https://github.com/maxgfr/llm-models/issues"
16869
- },
16870
- homepage: "https://github.com/maxgfr/llm-models#readme",
16871
- files: [
16872
- "build"
16873
- ],
16874
- bin: {
16875
- "llm-models": "./build/index.js"
16876
- },
16877
- publishConfig: {
16878
- access: "public",
16879
- provenance: true
16880
- },
16881
- keywords: [
16882
- "llm",
16883
- "models",
16884
- "openrouter",
16885
- "ai",
16886
- "machine-learning",
16887
- "api",
16888
- "cli",
16889
- "zod"
16890
- ],
16891
- scripts: {
16892
- start: "bun run src/index.ts",
16893
- dev: "bun run --watch src/index.ts",
16894
- build: "bun build src/index.ts --outdir build --target node",
16895
- "build:types": "tsc --emitDeclarationOnly",
16896
- "build:all": "bun run build && bun run build:types",
16897
- test: "bun test",
16898
- "test:watch": "bun test --watch",
16899
- lint: "biome check src/",
16900
- "lint:fix": "biome check --write src/",
16901
- format: "biome format --write src/",
16902
- release: "semantic-release",
16903
- "build:binary:linux-x64": "bun build src/index.ts --compile --target=bun-linux-x64 --outfile dist/llm-models-linux-x64",
16904
- "build:binary:linux-arm64": "bun build src/index.ts --compile --target=bun-linux-arm64 --outfile dist/llm-models-linux-arm64",
16905
- "build:binary:macos-x64": "bun build src/index.ts --compile --target=bun-darwin-x64 --outfile dist/llm-models-macos-x64",
16906
- "build:binary:macos-arm64": "bun build src/index.ts --compile --target=bun-darwin-arm64 --outfile dist/llm-models-macos-arm64",
16907
- "build:binary:win-x64": "bun build src/index.ts --compile --target=bun-windows-x64 --outfile dist/llm-models-win-x64.exe"
16908
- },
16909
- dependencies: {
16910
- "@modelcontextprotocol/sdk": "^1.29.0",
16911
- commander: "^14.0.3",
16912
- zod: "^4.3.6"
16913
- },
16914
- devDependencies: {
16915
- "@biomejs/biome": "^2.4.10",
16916
- "@semantic-release/commit-analyzer": "^13.0.1",
16917
- "@semantic-release/git": "^10.0.1",
16918
- "@semantic-release/github": "^12.0.6",
16919
- "@semantic-release/npm": "^13.1.5",
16920
- "@semantic-release/release-notes-generator": "^14.1.0",
16921
- "bun-types": "^1.3.11",
16922
- "semantic-release": "^25.0.3",
16923
- typescript: "^6.0.2"
16924
- }
16925
- };
16926
- });
16927
-
16928
16857
  // node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/helpers/util.js
16929
16858
  var util, objectUtil, ZodParsedType, getParsedType2 = (data) => {
16930
16859
  const t = typeof data;
@@ -41005,6 +40934,79 @@ var {
41005
40934
  Option,
41006
40935
  Help
41007
40936
  } = import__.default;
40937
+ // package.json
40938
+ var package_default = {
40939
+ name: "llm-models",
40940
+ version: "1.2.3",
40941
+ author: "maxgfr",
40942
+ license: "MIT",
40943
+ type: "module",
40944
+ main: "./build/index.js",
40945
+ types: "./build/index.d.ts",
40946
+ description: "Fetch latest LLM models from OpenRouter and models.dev APIs",
40947
+ repository: {
40948
+ type: "git",
40949
+ url: "https://github.com/maxgfr/llm-models.git"
40950
+ },
40951
+ bugs: {
40952
+ url: "https://github.com/maxgfr/llm-models/issues"
40953
+ },
40954
+ homepage: "https://github.com/maxgfr/llm-models#readme",
40955
+ files: [
40956
+ "build"
40957
+ ],
40958
+ bin: {
40959
+ "llm-models": "./build/index.js"
40960
+ },
40961
+ publishConfig: {
40962
+ access: "public",
40963
+ provenance: true
40964
+ },
40965
+ keywords: [
40966
+ "llm",
40967
+ "models",
40968
+ "openrouter",
40969
+ "ai",
40970
+ "machine-learning",
40971
+ "api",
40972
+ "cli",
40973
+ "zod"
40974
+ ],
40975
+ scripts: {
40976
+ start: "bun run src/index.ts",
40977
+ dev: "bun run --watch src/index.ts",
40978
+ build: "bun build src/index.ts --outdir build --target node",
40979
+ "build:types": "tsc --emitDeclarationOnly",
40980
+ "build:all": "bun run build && bun run build:types",
40981
+ test: "bun test",
40982
+ "test:watch": "bun test --watch",
40983
+ lint: "biome check src/",
40984
+ "lint:fix": "biome check --write src/",
40985
+ format: "biome format --write src/",
40986
+ release: "semantic-release",
40987
+ "build:binary:linux-x64": "bun build src/index.ts --compile --target=bun-linux-x64 --outfile dist/llm-models-linux-x64",
40988
+ "build:binary:linux-arm64": "bun build src/index.ts --compile --target=bun-linux-arm64 --outfile dist/llm-models-linux-arm64",
40989
+ "build:binary:macos-x64": "bun build src/index.ts --compile --target=bun-darwin-x64 --outfile dist/llm-models-macos-x64",
40990
+ "build:binary:macos-arm64": "bun build src/index.ts --compile --target=bun-darwin-arm64 --outfile dist/llm-models-macos-arm64",
40991
+ "build:binary:win-x64": "bun build src/index.ts --compile --target=bun-windows-x64 --outfile dist/llm-models-win-x64.exe"
40992
+ },
40993
+ dependencies: {
40994
+ "@modelcontextprotocol/sdk": "^1.29.0",
40995
+ commander: "^14.0.3",
40996
+ zod: "^4.3.6"
40997
+ },
40998
+ devDependencies: {
40999
+ "@biomejs/biome": "^2.4.10",
41000
+ "@semantic-release/commit-analyzer": "^13.0.1",
41001
+ "@semantic-release/git": "^10.0.1",
41002
+ "@semantic-release/github": "^12.0.6",
41003
+ "@semantic-release/npm": "^13.1.5",
41004
+ "@semantic-release/release-notes-generator": "^14.1.0",
41005
+ "bun-types": "^1.3.11",
41006
+ "semantic-release": "^25.0.3",
41007
+ typescript: "^6.0.2"
41008
+ }
41009
+ };
41008
41010
 
41009
41011
  // src/cli.ts
41010
41012
  init_cache();
@@ -41309,7 +41311,6 @@ init_provider();
41309
41311
  init_recommend();
41310
41312
  init_search();
41311
41313
  init_stats();
41312
- var pkg = require_package();
41313
41314
  function resolveFormat(options) {
41314
41315
  if (options.json)
41315
41316
  return "json";
@@ -41320,7 +41321,7 @@ function resolveFormat(options) {
41320
41321
  }
41321
41322
  function runCommand() {
41322
41323
  const program2 = new Command;
41323
- program2.name("llm-models").description("Fetch latest LLM models from OpenRouter and models.dev").version(pkg.version).option("--no-cache", "Disable cache for this request").option("--quiet", "Suppress informational messages").option("--verbose", "Show debug info (timing, cache status)").hook("preAction", (_thisCommand, _actionCommand) => {
41324
+ program2.name("llm-models").description("Fetch latest LLM models from OpenRouter and models.dev").version(package_default.version).option("--no-cache", "Disable cache for this request").option("--quiet", "Suppress informational messages").option("--verbose", "Show debug info (timing, cache status)").hook("preAction", (_thisCommand, _actionCommand) => {
41324
41325
  const opts = program2.opts();
41325
41326
  if (opts.cache === false) {
41326
41327
  setCacheEnabled(false);
@@ -41382,7 +41383,7 @@ function runCommand() {
41382
41383
  }
41383
41384
  console.log(JSON.stringify(data, null, 2));
41384
41385
  });
41385
- program2.command("find").description("Discover models across both APIs with smart filtering").option("-p, --provider <id>", "Filter by provider").option("-C, --capability <cap>", "Filter by capability: reasoning, tool_call, structured_output, open_weights, attachment").option("-m, --modality <mod>", "Filter by input modality (e.g. image, audio, video, pdf)").option("--max-cost <n>", "Max input cost ($/million tokens)", Number.parseFloat).option("--max-cost-output <n>", "Max output cost ($/million tokens)", Number.parseFloat).option("--min-context <n>", "Min context window size", Number.parseInt).option("-s, --search <term>", "Search by name or ID").option("--status <status>", "Filter by status: active, beta, deprecated").option("-f, --family <name>", "Filter by model family (e.g. gpt, claude, gemini)").option("--sort <field>", "Sort by: cost_input, cost_output, context_length, release_date, name, knowledge_cutoff, value").option("--desc", "Sort descending").option("-n, --limit <n>", "Max results (default: 20)", Number.parseInt, 20).option("-c, --count", "Show model count only").option("--ids-only", "Output model IDs only, one per line").option("--json", "Output raw JSON").option("--format <fmt>", "Output format: table, json, csv, markdown").action(async (options) => {
41386
+ program2.command("find").description("Discover models across both APIs with smart filtering").option("-p, --provider <id>", "Filter by provider").option("-C, --capability <cap>", "Filter by capability: reasoning, tool_call, structured_output, open_weights, attachment").option("-m, --modality <mod>", "Filter by input modality (e.g. image, audio, video, pdf)").option("--max-cost <n>", "Max input cost ($/million tokens)", Number.parseFloat).option("--max-cost-output <n>", "Max output cost ($/million tokens)", Number.parseFloat).option("--min-context <n>", "Min context window size", Number.parseInt).option("-s, --search <term>", "Search by name or ID").option("--status <status>", "Filter by status: active, beta, deprecated").option("-f, --family <name>", "Filter by model family (e.g. gpt, claude, gemini)").option("--sort <field>", "Sort by: cost_input, cost_output, context_length, release_date, name, knowledge_cutoff, value").option("--desc", "Sort descending").option("-n, --limit <n>", "Max results (default: 20)", (v) => Number.parseInt(v, 10), 20).option("-c, --count", "Show model count only").option("--ids-only", "Output model IDs only, one per line").option("--json", "Output raw JSON").option("--format <fmt>", "Output format: table, json, csv, markdown").action(async (options) => {
41386
41387
  const start = Date.now();
41387
41388
  const filter = {
41388
41389
  provider: options.provider,
@@ -41579,7 +41580,7 @@ ${bold("Models")} (${provider.model_count}):`);
41579
41580
  });
41580
41581
  outputFormatted(fmt, headers, rows, estimates);
41581
41582
  });
41582
- program2.command("cheapest").description("Find the cheapest models matching your criteria").option("-C, --capability <cap>", "Filter by capability: reasoning, tool_call, structured_output, open_weights, attachment").option("--min-context <n>", "Min context window size", Number.parseInt).option("-n, --limit <n>", "Max results (default: 10)", Number.parseInt, 10).option("--json", "Output raw JSON").option("--format <fmt>", "Output format: table, json, csv, markdown").action(async (options) => {
41583
+ program2.command("cheapest").description("Find the cheapest models matching your criteria").option("-C, --capability <cap>", "Filter by capability: reasoning, tool_call, structured_output, open_weights, attachment").option("--min-context <n>", "Min context window size", Number.parseInt).option("-n, --limit <n>", "Max results (default: 10)", (v) => Number.parseInt(v, 10), 10).option("--json", "Output raw JSON").option("--format <fmt>", "Output format: table, json, csv, markdown").action(async (options) => {
41583
41584
  const models = await cheapestModels({
41584
41585
  capability: options.capability,
41585
41586
  minContext: options.minContext,
@@ -41691,7 +41692,7 @@ ${ids.map((id) => ` - ${id}`).join(`
41691
41692
  console.log();
41692
41693
  console.log(dim(`Sources: ${[model.sources.openrouter ? "OpenRouter" : "", model.sources.models_dev ? "models.dev" : ""].filter(Boolean).join(", ")}`));
41693
41694
  });
41694
- program2.command("recommend").description("Get model recommendations for a use case").argument("[use-case]", "Use case: code-gen, vision, cheap-chatbot, reasoning, long-context, open-source, audio, tool-use").option("--max-cost <n>", "Max input cost budget ($/M tokens)", Number.parseFloat).option("--min-context <n>", "Min context window", Number.parseInt).option("-n, --limit <n>", "Max results (default: 10)", Number.parseInt, 10).option("--list", "List available use cases").option("--json", "Output raw JSON").option("--format <fmt>", "Output format: table, json, csv, markdown").action(async (useCase, options) => {
41695
+ program2.command("recommend").description("Get model recommendations for a use case").argument("[use-case]", "Use case: code-gen, vision, cheap-chatbot, reasoning, long-context, open-source, audio, tool-use").option("--max-cost <n>", "Max input cost budget ($/M tokens)", Number.parseFloat).option("--min-context <n>", "Min context window", Number.parseInt).option("-n, --limit <n>", "Max results (default: 10)", (v) => Number.parseInt(v, 10), 10).option("--list", "List available use cases").option("--json", "Output raw JSON").option("--format <fmt>", "Output format: table, json, csv, markdown").action(async (useCase, options) => {
41695
41696
  if (options.list || !useCase) {
41696
41697
  const useCases = listUseCases();
41697
41698
  console.log(bold(`Available use cases:
@@ -41832,7 +41833,7 @@ No changes detected.`);
41832
41833
  if (action === "clear") {
41833
41834
  clearCache();
41834
41835
  } else {
41835
- const info = (init_cache(), __toCommonJS(exports_cache)).getCacheInfo();
41836
+ const info = getCacheInfo();
41836
41837
  console.log("Cache directory: ~/.cache/llm-models/");
41837
41838
  console.log(`Files: ${info.files}`);
41838
41839
  console.log(`Size: ${(info.sizeBytes / 1024).toFixed(1)} KB`);
@@ -41907,6 +41908,7 @@ export {
41907
41908
  findModels,
41908
41909
  filterModels,
41909
41910
  fetchUnifiedModels,
41911
+ fetchUnifiedData,
41910
41912
  fetchOpenRouterModels,
41911
41913
  fetchModelsDevModels,
41912
41914
  estimateCost,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-models",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "author": "maxgfr",
5
5
  "license": "MIT",
6
6
  "type": "module",