@x12i/ai-tools 2.0.0 → 2.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 (94) hide show
  1. package/dist/{AiModelsCatalogClient-B5FMI9gj.d.cts → AiModelsCatalogClient-C9ZJHhv3.d.ts} +4 -1
  2. package/dist/{AiModelsCatalogClient-CPPNI6Ry.d.ts → AiModelsCatalogClient-DgBdVFk-.d.cts} +4 -1
  3. package/dist/aliases/index.d.cts +3 -3
  4. package/dist/aliases/index.d.ts +3 -3
  5. package/dist/catalog/index.cjs +6 -5
  6. package/dist/catalog/index.cjs.map +1 -1
  7. package/dist/catalog/index.d.cts +4 -4
  8. package/dist/catalog/index.d.ts +4 -4
  9. package/dist/catalog/index.js +5 -4
  10. package/dist/{chunk-EYHMQVAL.js → chunk-54GKLIDW.js} +22 -10
  11. package/dist/chunk-54GKLIDW.js.map +1 -0
  12. package/dist/chunk-5IZ7PLY2.cjs +51 -0
  13. package/dist/chunk-5IZ7PLY2.cjs.map +1 -0
  14. package/dist/{chunk-XAWBTX3N.cjs → chunk-75ZVXZAV.cjs} +7 -7
  15. package/dist/{chunk-XAWBTX3N.cjs.map → chunk-75ZVXZAV.cjs.map} +1 -1
  16. package/dist/{chunk-YQDSN6R6.cjs → chunk-76FHWQH3.cjs} +3 -3
  17. package/dist/{chunk-YQDSN6R6.cjs.map → chunk-76FHWQH3.cjs.map} +1 -1
  18. package/dist/{chunk-EDMCKHO6.cjs → chunk-BCX5CLJJ.cjs} +15 -2
  19. package/dist/chunk-BCX5CLJJ.cjs.map +1 -0
  20. package/dist/{chunk-OPN6BGNH.js → chunk-D6OIUYNC.js} +117 -5
  21. package/dist/{chunk-OPN6BGNH.js.map → chunk-D6OIUYNC.js.map} +1 -1
  22. package/dist/{chunk-NF2SKQR7.cjs → chunk-DDRWORUU.cjs} +30 -298
  23. package/dist/chunk-DDRWORUU.cjs.map +1 -0
  24. package/dist/{chunk-5XAAMBDO.cjs → chunk-HBNYVRLZ.cjs} +123 -11
  25. package/dist/chunk-HBNYVRLZ.cjs.map +1 -0
  26. package/dist/chunk-HEB73GKJ.js +263 -0
  27. package/dist/chunk-HEB73GKJ.js.map +1 -0
  28. package/dist/{chunk-VJHLO2R3.js → chunk-KSJSLKYI.js} +2 -2
  29. package/dist/{chunk-SIH4GPV4.js → chunk-MOLWV5LV.js} +2 -2
  30. package/dist/{chunk-U2YDDUVP.js → chunk-PN4FF6YF.js} +10 -275
  31. package/dist/chunk-PN4FF6YF.js.map +1 -0
  32. package/dist/{chunk-DXZOL3VN.cjs → chunk-RSHI4OOY.cjs} +46 -34
  33. package/dist/chunk-RSHI4OOY.cjs.map +1 -0
  34. package/dist/{chunk-B3V2EHRY.js → chunk-SLSKQRMI.js} +15 -2
  35. package/dist/{chunk-B3V2EHRY.js.map → chunk-SLSKQRMI.js.map} +1 -1
  36. package/dist/{chunk-XOKUDUUI.cjs → chunk-TMA6QSNH.cjs} +3 -3
  37. package/dist/{chunk-XOKUDUUI.cjs.map → chunk-TMA6QSNH.cjs.map} +1 -1
  38. package/dist/{chunk-6BQBKROR.js → chunk-VBROBIVI.js} +3 -3
  39. package/dist/{chunk-6BQBKROR.js.map → chunk-VBROBIVI.js.map} +1 -1
  40. package/dist/chunk-WSUFQR3D.cjs +266 -0
  41. package/dist/chunk-WSUFQR3D.cjs.map +1 -0
  42. package/dist/{chunk-PRCICORG.cjs → chunk-X42KFOUO.cjs} +6 -6
  43. package/dist/{chunk-PRCICORG.cjs.map → chunk-X42KFOUO.cjs.map} +1 -1
  44. package/dist/chunk-YQVY7CWT.js +51 -0
  45. package/dist/chunk-YQVY7CWT.js.map +1 -0
  46. package/dist/{chunk-AB5GNXJ4.js → chunk-ZPUZ7DBO.js} +2 -2
  47. package/dist/cli/index.cjs +16 -15
  48. package/dist/cli/index.cjs.map +1 -1
  49. package/dist/cli/index.js +7 -6
  50. package/dist/cli/index.js.map +1 -1
  51. package/dist/cost/index.cjs +4 -3
  52. package/dist/cost/index.cjs.map +1 -1
  53. package/dist/cost/index.d.cts +4 -4
  54. package/dist/cost/index.d.ts +4 -4
  55. package/dist/cost/index.js +3 -2
  56. package/dist/index.cjs +28 -11
  57. package/dist/index.cjs.map +1 -1
  58. package/dist/index.d.cts +8 -6
  59. package/dist/index.d.ts +8 -6
  60. package/dist/index.js +33 -16
  61. package/dist/{modelCache-CJftI-Ko.d.cts → modelCache-sL3dBfRM.d.cts} +1 -1
  62. package/dist/{modelCache-BzRn6t_C.d.ts → modelCache-xzoTUue2.d.ts} +1 -1
  63. package/dist/{modelNameResolver-5XkBMctP.d.ts → modelNameResolver-2WroQlqt.d.ts} +2 -1
  64. package/dist/{modelNameResolver-C5CSTGFF.d.cts → modelNameResolver-Bxlehrbp.d.cts} +2 -1
  65. package/dist/models/index.cjs +7 -6
  66. package/dist/models/index.cjs.map +1 -1
  67. package/dist/models/index.d.cts +3 -3
  68. package/dist/models/index.d.ts +3 -3
  69. package/dist/models/index.js +9 -8
  70. package/dist/profiles/index.cjs +18 -0
  71. package/dist/profiles/index.cjs.map +1 -0
  72. package/dist/profiles/index.d.cts +40 -0
  73. package/dist/profiles/index.d.ts +40 -0
  74. package/dist/profiles/index.js +17 -0
  75. package/dist/profiles/index.js.map +1 -0
  76. package/dist/{resolveUsageModel-BFwf80Hz.d.ts → resolveUsageModel-DrFuiuIW.d.ts} +2 -2
  77. package/dist/{resolveUsageModel-C_YmGR1M.d.cts → resolveUsageModel-xKZ2QpHy.d.cts} +2 -2
  78. package/dist/sync/index.cjs +7 -5
  79. package/dist/sync/index.cjs.map +1 -1
  80. package/dist/sync/index.d.cts +3 -3
  81. package/dist/sync/index.d.ts +3 -3
  82. package/dist/sync/index.js +6 -4
  83. package/dist/{types-BrzJWsTU.d.ts → types-BZYGjN2O.d.cts} +21 -2
  84. package/dist/{types-BrzJWsTU.d.cts → types-BZYGjN2O.d.ts} +21 -2
  85. package/package.json +7 -2
  86. package/dist/chunk-5XAAMBDO.cjs.map +0 -1
  87. package/dist/chunk-DXZOL3VN.cjs.map +0 -1
  88. package/dist/chunk-EDMCKHO6.cjs.map +0 -1
  89. package/dist/chunk-EYHMQVAL.js.map +0 -1
  90. package/dist/chunk-NF2SKQR7.cjs.map +0 -1
  91. package/dist/chunk-U2YDDUVP.js.map +0 -1
  92. /package/dist/{chunk-VJHLO2R3.js.map → chunk-KSJSLKYI.js.map} +0 -0
  93. /package/dist/{chunk-SIH4GPV4.js.map → chunk-MOLWV5LV.js.map} +0 -0
  94. /package/dist/{chunk-AB5GNXJ4.js.map → chunk-ZPUZ7DBO.js.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x12i/ai-tools",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "AI model catalogs (open-assets JSON), cost calculation, and LLM utilities",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -45,6 +45,11 @@
45
45
  "types": "./dist/catalog/index.d.ts",
46
46
  "import": "./dist/catalog/index.js",
47
47
  "require": "./dist/catalog/index.cjs"
48
+ },
49
+ "./profiles": {
50
+ "types": "./dist/profiles/index.d.ts",
51
+ "import": "./dist/profiles/index.js",
52
+ "require": "./dist/profiles/index.cjs"
48
53
  }
49
54
  },
50
55
  "files": [
@@ -80,7 +85,7 @@
80
85
  }
81
86
  },
82
87
  "dependencies": {
83
- "@x12i/ai-profiles": "^1.1.0",
88
+ "@x12i/ai-profiles": "^1.2.0",
84
89
  "@x12i/env": "^4.0.1",
85
90
  "commander": "^12.1.0",
86
91
  "dotenv": "^16.4.7",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-5XAAMBDO.cjs","../src/cache/modelCache.ts","../src/catalog/catalogSources.ts","../src/catalog/normalizeX12iCatalogModel.ts","../src/catalog/loadCatalogSources.ts","../src/data/models-catalog.json","../src/data/openrouter-models-catalog.json","../src/catalog/catalogLoadCache.ts","../src/catalog/AiModelsCatalogClient.ts"],"names":[],"mappings":"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CA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAEA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAEA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAEA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAEA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAEA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAEA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACE,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACF,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAEA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAEA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAEA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AACF;AL2MU;AACA;AMz2BV;AACY,EAAA;AACV,EAAA;AACA,EAAA;AACA,EAAA;AACU,EAAA;AACR,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACF,EAAA;AACS,EAAA;AACP,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACF,EAAA;AACU,EAAA;AACR,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACF,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-5XAAMBDO.cjs","sourcesContent":[null,"import { createNxCache } from \"nx-cache\";\nimport type { AiModelRecord } from \"../cost/types.js\";\n\nconst cache = createNxCache<Map<string, AiModelRecord>, { cachedAt: string; count: number }>();\n\n/** Default in-memory catalog cache lifetime (24 hours). */\nexport const DEFAULT_CATALOG_CACHE_TTL_MS = 24 * 60 * 60 * 1000;\n\n/** @alias DEFAULT_CATALOG_CACHE_TTL_MS */\nexport const DEFAULT_MODEL_CACHE_TTL_MS = DEFAULT_CATALOG_CACHE_TTL_MS;\n\nexport function resolveCatalogCacheTtlMs(override?: number): number {\n if (override !== undefined) return override;\n const raw = process.env.AI_TOOLS_CACHE_TTL_MS;\n if (!raw) return DEFAULT_CATALOG_CACHE_TTL_MS;\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) && n > 0 ? n : DEFAULT_CATALOG_CACHE_TTL_MS;\n}\n\nexport type ModelCacheMetadata = { cachedAt: string; count: number };\n\nexport function readCachedModels(\n scopeKey: string,\n ttlMs = DEFAULT_CATALOG_CACHE_TTL_MS,\n): Map<string, AiModelRecord> | null {\n const res = cache.read(\"ai-models\", { appId: scopeKey });\n if (!res.found) return null;\n\n const cachedAt = res.metadata?.cachedAt;\n if (cachedAt) {\n const age = Date.now() - new Date(cachedAt).getTime();\n if (age > ttlMs) return null;\n } else if (res.meta.isExpired) {\n return null;\n }\n\n return res.value;\n}\n\nexport function writeCachedModels(\n scopeKey: string,\n models: Map<string, AiModelRecord>,\n ttlMs = DEFAULT_CATALOG_CACHE_TTL_MS,\n): void {\n cache.write(\"ai-models\", models, {\n scope: { appId: scopeKey },\n ttlMs,\n metadata: { cachedAt: new Date().toISOString(), count: models.size },\n });\n}\n\nexport function invalidateModelsCache(scopeKey: string): void {\n cache.resetKey(\"ai-models\", { appId: scopeKey });\n}\n","/** Remote catalog URLs (primary). */\nexport const DEFAULT_DIRECT_CATALOG_URL =\n \"https://open-assets.x12i.com/models-catalog.json\";\n\nexport const DEFAULT_OPENROUTER_CATALOG_URL =\n \"https://open-assets.x12i.com/openrouter-models-catalog.json\";\n\nexport type CatalogSourceKind = \"direct\" | \"openrouter\";\n\nexport type CatalogLoadSource = {\n kind: CatalogSourceKind;\n url: string;\n /** Bundled fallback (imported JSON). */\n bundled: X12iModelsCatalogFile;\n};\n\nexport type X12iCatalogPricing = {\n input?: number | null;\n output?: number | null;\n cachedInput?: number | null;\n cacheHit?: number | null;\n cacheWrite?: number | null;\n cacheWrite5m?: number | null;\n cacheWrite1h?: number | null;\n textInput?: number | null;\n textOutput?: number | null;\n audioInput?: number | null;\n imageInput?: number | null;\n internalReasoning?: number | null;\n webSearchPerRequest?: number | null;\n inputBelow200k?: number | null;\n inputAbove200k?: number | null;\n outputBelow200k?: number | null;\n outputAbove200k?: number | null;\n [key: string]: unknown;\n};\n\nexport type X12iCatalogModelEntry = {\n provider: string;\n modelId: string;\n displayName?: string;\n canonicalSlug?: string;\n family?: string;\n status?: string;\n modalities?: string[] | { input?: string[]; output?: string[] };\n contextWindow?: number;\n maxCompletionTokens?: number;\n pricing?: X12iCatalogPricing;\n capabilities?: {\n reasoning?: boolean | string;\n toolCalling?: boolean;\n structuredOutputs?: boolean;\n };\n aliases?: string[];\n sourceUrl?: string;\n};\n\n/**\n * Raw catalog JSON from open-assets.x12i.com (or bundled `src/data`).\n *\n * `schema` and `version` are publisher metadata only — this library never reads or\n * compares them. Remote catalogs are always treated as the latest pricing source.\n */\nexport type X12iModelsCatalogFile = {\n /** Publisher schema id (informational). */\n schema?: string;\n /** Publisher catalog revision (informational; not used for cache or compatibility). */\n version?: string;\n verifiedAt?: string;\n models: X12iCatalogModelEntry[];\n [key: string]: unknown;\n};\n","import { computeSupportsReasoning } from \"../models/reasoningModel.js\";\nimport type { AiModelPricing, AiModelRecord } from \"../models/types.js\";\nimport type { OpenRouterModelApi, OpenRouterPricingApi } from \"../models/openrouter.types.js\";\nimport { normalizeProvider, normalizeString } from \"../sync/modelNameResolver/normalize.js\";\nimport type { CatalogSourceKind, X12iCatalogModelEntry, X12iCatalogPricing } from \"./catalogSources.js\";\n\nconst TOKENS_PER_UNIT = 1_000_000;\n\nfunction usdPerToken(perMillion?: number | null): number {\n if (perMillion == null || !Number.isFinite(perMillion)) return 0;\n return perMillion / TOKENS_PER_UNIT;\n}\n\nfunction firstRate(\n raw: X12iCatalogPricing,\n ...keys: (keyof X12iCatalogPricing)[]\n): number | undefined {\n for (const key of keys) {\n const v = raw[key];\n if (typeof v === \"number\" && Number.isFinite(v)) return v;\n }\n return undefined;\n}\n\nexport function canonicalCatalogModelId(provider: string, modelId: string): string {\n const m = normalizeString(modelId);\n if (m.includes(\"/\")) return m;\n const p = normalizeProvider(provider) ?? normalizeString(provider);\n return `${p}/${m}`;\n}\n\nfunction mapStatus(status?: string): AiModelRecord[\"status\"] {\n if (!status) return \"active\";\n const s = status.toLowerCase();\n if (s === \"deprecated\" || s === \"legacy\") return \"deprecated\";\n if (s === \"active\" || s === \"preview\" || s === \"announced\") return \"active\";\n return \"unknown\";\n}\n\nfunction mapModalities(\n modalities?: X12iCatalogModelEntry[\"modalities\"],\n): { input: string[]; output: string[]; modality: string } {\n if (Array.isArray(modalities)) {\n return {\n input: modalities,\n output: modalities.includes(\"text\") ? [\"text\"] : modalities.slice(0, 1),\n modality: modalities.join(\"+\"),\n };\n }\n if (modalities && typeof modalities === \"object\") {\n const input = modalities.input ?? [\"text\"];\n const output = modalities.output ?? [\"text\"];\n return { input, output, modality: `${input.join(\"+\")}->${output.join(\"+\")}` };\n }\n return { input: [\"text\"], output: [\"text\"], modality: \"text->text\" };\n}\n\nfunction pricingToOpenRouterApi(\n raw: X12iCatalogPricing,\n perMillion = true,\n): OpenRouterPricingApi {\n const scale = perMillion ? (n?: number) => (n ?? 0) / TOKENS_PER_UNIT : (n?: number) => n ?? 0;\n return {\n prompt: String(scale(firstRate(raw, \"input\", \"textInput\"))),\n completion: String(scale(firstRate(raw, \"output\", \"textOutput\"))),\n request: \"0\",\n image: String(scale(firstRate(raw, \"imageInput\"))),\n input_cache_read: raw.cachedInput != null ? String(scale(raw.cachedInput)) : undefined,\n input_cache_write: raw.cacheWrite != null ? String(scale(raw.cacheWrite)) : undefined,\n internal_reasoning:\n raw.internalReasoning != null ? String(scale(raw.internalReasoning)) : undefined,\n web_search:\n raw.webSearchPerRequest != null ? String(raw.webSearchPerRequest) : undefined,\n };\n}\n\nfunction pricingFromX12i(\n raw: X12iCatalogPricing,\n pricedAt: string,\n source: AiModelPricing[\"source\"],\n): AiModelPricing {\n return {\n promptUsdPerToken: usdPerToken(firstRate(raw, \"input\", \"textInput\")),\n completionUsdPerToken: usdPerToken(firstRate(raw, \"output\", \"textOutput\")),\n imageUsdPerUnit: usdPerToken(firstRate(raw, \"imageInput\")),\n requestUsdPerRequest: usdPerToken(\n typeof raw.webSearchPerRequest === \"number\" ? raw.webSearchPerRequest * 1000 : 0,\n ),\n cacheReadUsdPerToken: usdPerToken(\n firstRate(raw, \"cachedInput\", \"cacheHit\"),\n ),\n cacheWriteUsdPerToken: usdPerToken(\n firstRate(raw, \"cacheWrite\", \"cacheWrite5m\", \"cacheWrite1h\"),\n ),\n reasoningUsdPerToken: usdPerToken(raw.internalReasoning),\n webSearchUsdPerRequest:\n typeof raw.webSearchPerRequest === \"number\" ? raw.webSearchPerRequest : undefined,\n pricedAt,\n source,\n };\n}\n\nfunction stubOpenRouterApi(\n modelId: string,\n entry: X12iCatalogModelEntry,\n modalities: ReturnType<typeof mapModalities>,\n pricing: OpenRouterPricingApi,\n): OpenRouterModelApi {\n return {\n id: modelId,\n canonical_slug: entry.canonicalSlug ?? modelId,\n name: entry.displayName ?? modelId,\n created: 0,\n description: entry.displayName ?? \"\",\n context_length: entry.contextWindow ?? 0,\n architecture: {\n modality: modalities.modality,\n input_modalities: modalities.input,\n output_modalities: modalities.output,\n tokenizer: \"\",\n instruct_type: null,\n },\n pricing,\n top_provider: {\n context_length: entry.contextWindow ?? 0,\n max_completion_tokens: entry.maxCompletionTokens ?? null,\n is_moderated: false,\n },\n per_request_limits: null,\n supported_parameters: entry.capabilities?.toolCalling ? [\"tools\"] : [],\n default_parameters: null,\n };\n}\n\nexport function normalizeX12iCatalogModel(\n entry: X12iCatalogModelEntry,\n kind: CatalogSourceKind,\n verifiedAt: string,\n): AiModelRecord | null {\n const pricingRaw = entry.pricing;\n if (!pricingRaw) return null;\n\n const inputRate = firstRate(pricingRaw, \"input\", \"textInput\", \"inputBelow200k\");\n const outputRate = firstRate(pricingRaw, \"output\", \"textOutput\", \"outputBelow200k\");\n if (inputRate == null && outputRate == null) return null;\n\n const modelId = canonicalCatalogModelId(entry.provider, entry.modelId);\n const providerId =\n kind === \"openrouter\" && modelId.includes(\"/\")\n ? modelId.split(\"/\")[0]!\n : normalizeProvider(entry.provider) ?? entry.provider;\n\n const modalities = mapModalities(entry.modalities);\n const pricedAt = verifiedAt || new Date().toISOString();\n const pricingSource: AiModelPricing[\"source\"] =\n kind === \"openrouter\" ? \"openrouter\" : \"direct\";\n const pricing = pricingFromX12i(pricingRaw, pricedAt, pricingSource);\n const openRouterPricing = pricingToOpenRouterApi(pricingRaw, true);\n const openRouter = stubOpenRouterApi(modelId, entry, modalities, openRouterPricing);\n\n const supportedParameters = openRouter.supported_parameters ?? [];\n const supportsReasoning =\n entry.capabilities?.reasoning === true ||\n computeSupportsReasoning({\n supportedParameters,\n pricing,\n openRouterPricing,\n });\n\n const aliases = new Set<string>(entry.aliases ?? []);\n aliases.add(entry.modelId);\n if (entry.displayName) aliases.add(entry.displayName);\n const slash = modelId.indexOf(\"/\");\n if (slash > 0) aliases.add(modelId.slice(slash + 1));\n\n return {\n modelId,\n name: entry.displayName ?? modelId,\n providerId,\n canonicalSlug: entry.canonicalSlug ?? modelId,\n status: mapStatus(entry.status),\n description: entry.displayName ?? \"\",\n created: 0,\n expirationDate: null,\n contextLength: entry.contextWindow ?? 0,\n maxCompletionTokens: entry.maxCompletionTokens ?? null,\n isModerated: false,\n modality: modalities.modality,\n inputModalities: modalities.input,\n outputModalities: modalities.output,\n tokenizer: \"\",\n instructType: null,\n supportedParameters,\n defaultParameters: null,\n perRequestLimits: null,\n pricing,\n openRouterPricing,\n architecture: openRouter.architecture,\n topProvider: openRouter.top_provider,\n openRouter,\n aliases: [...aliases],\n availableOnOpenRouter: kind === \"openrouter\",\n supportsStreaming: modalities.output.includes(\"text\"),\n supportsTools: entry.capabilities?.toolCalling === true,\n supportsReasoning,\n primaryOutputModality: modalities.output[0] ?? \"text\",\n syncedAt: pricedAt,\n syncSource: kind === \"openrouter\" ? \"openrouter\" : \"manual\",\n };\n}\n\nexport function modelsFromX12iCatalogFile(\n file: { models: X12iCatalogModelEntry[]; verifiedAt?: string },\n kind: CatalogSourceKind,\n): Map<string, AiModelRecord> {\n const map = new Map<string, AiModelRecord>();\n const verifiedAt = file.verifiedAt ?? new Date().toISOString().slice(0, 10);\n for (const entry of file.models) {\n const record = normalizeX12iCatalogModel(entry, kind, verifiedAt);\n if (record) map.set(record.modelId, record);\n }\n return map;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n DEFAULT_DIRECT_CATALOG_URL,\n DEFAULT_OPENROUTER_CATALOG_URL,\n type CatalogLoadSource,\n type X12iModelsCatalogFile,\n} from \"./catalogSources.js\";\n\nexport { DEFAULT_DIRECT_CATALOG_URL, DEFAULT_OPENROUTER_CATALOG_URL };\nimport { modelsFromX12iCatalogFile } from \"./normalizeX12iCatalogModel.js\";\nimport type { AiModelRecord } from \"../models/types.js\";\n\nimport bundledDirect from \"../data/models-catalog.json\" with { type: \"json\" };\nimport bundledOpenRouter from \"../data/openrouter-models-catalog.json\" with { type: \"json\" };\n\nconst dataDir = dirname(fileURLToPath(import.meta.url));\n\nexport type LoadCatalogOptions = {\n directCatalogUrl?: string;\n openRouterCatalogUrl?: string;\n /** When true, skip HTTP and use bundled `src/data` only. */\n bundledOnly?: boolean;\n fetchTimeoutMs?: number;\n};\n\nexport type LoadedCatalogs = {\n direct: Map<string, AiModelRecord>;\n openrouter: Map<string, AiModelRecord>;\n meta: {\n directSource: \"remote\" | \"bundled\";\n openRouterSource: \"remote\" | \"bundled\";\n directUrl: string;\n openRouterUrl: string;\n directCount: number;\n openRouterCount: number;\n };\n};\n\nasync function fetchCatalogJson(url: string, timeoutMs: number): Promise<X12iModelsCatalogFile> {\n const res = await fetch(url, {\n signal: AbortSignal.timeout(timeoutMs),\n headers: { accept: \"application/json\" },\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status} fetching ${url}`);\n }\n return (await res.json()) as X12iModelsCatalogFile;\n}\n\nasync function loadOneSource(\n source: CatalogLoadSource,\n options: LoadCatalogOptions,\n): Promise<{ file: X12iModelsCatalogFile; from: \"remote\" | \"bundled\" }> {\n if (options.bundledOnly) {\n return { file: source.bundled, from: \"bundled\" };\n }\n\n try {\n const file = await fetchCatalogJson(source.url, options.fetchTimeoutMs ?? 30_000);\n return { file, from: \"remote\" };\n } catch (err) {\n console.warn(\n `[ai-tools] Failed to load ${source.kind} catalog from ${source.url} (${err instanceof Error ? err.message : err}); using bundled fallback.`,\n );\n return { file: source.bundled, from: \"bundled\" };\n }\n}\n\n/** Load direct-provider and OpenRouter catalogs (remote with bundled fallback). */\nexport async function loadCatalogSources(\n options: LoadCatalogOptions = {},\n): Promise<LoadedCatalogs> {\n const directUrl = options.directCatalogUrl ?? DEFAULT_DIRECT_CATALOG_URL;\n const openRouterUrl = options.openRouterCatalogUrl ?? DEFAULT_OPENROUTER_CATALOG_URL;\n\n const sources: CatalogLoadSource[] = [\n {\n kind: \"direct\",\n url: directUrl,\n bundled: bundledDirect as X12iModelsCatalogFile,\n },\n {\n kind: \"openrouter\",\n url: openRouterUrl,\n bundled: bundledOpenRouter as X12iModelsCatalogFile,\n },\n ];\n\n const [directLoad, orLoad] = await Promise.all(\n sources.map((s) => loadOneSource(s, options)),\n );\n\n const direct = modelsFromX12iCatalogFile(directLoad.file, \"direct\");\n const openrouter = modelsFromX12iCatalogFile(orLoad.file, \"openrouter\");\n\n return {\n direct,\n openrouter,\n meta: {\n directSource: directLoad.from,\n openRouterSource: orLoad.from,\n directUrl,\n openRouterUrl,\n directCount: direct.size,\n openRouterCount: openrouter.size,\n },\n };\n}\n\n/** Read bundled JSON from disk (CLI / tests without import assertions). */\nexport async function readBundledCatalogFiles(): Promise<LoadedCatalogs> {\n const directPath = join(dataDir, \"../data/models-catalog.json\");\n const orPath = join(dataDir, \"../data/openrouter-models-catalog.json\");\n const [directRaw, orRaw] = await Promise.all([\n readFile(directPath, \"utf8\"),\n readFile(orPath, \"utf8\"),\n ]);\n const directFile = JSON.parse(directRaw) as X12iModelsCatalogFile;\n const orFile = JSON.parse(orRaw) as X12iModelsCatalogFile;\n return {\n direct: modelsFromX12iCatalogFile(directFile, \"direct\"),\n openrouter: modelsFromX12iCatalogFile(orFile, \"openrouter\"),\n meta: {\n directSource: \"bundled\",\n openRouterSource: \"bundled\",\n directUrl: DEFAULT_DIRECT_CATALOG_URL,\n openRouterUrl: DEFAULT_OPENROUTER_CATALOG_URL,\n directCount: directFile.models.length,\n openRouterCount: orFile.models.length,\n },\n };\n}\n","{\r\n \"schema\": \"x12i.ai-models.catalog\",\r\n \"version\": \"0.1.0\",\r\n \"currency\": \"USD\",\r\n \"pricingUnit\": \"1M_tokens\",\r\n \"verifiedAt\": \"2026-05-27\",\r\n \"notes\": [\r\n \"All token prices are listed per 1M tokens unless otherwise stated.\",\r\n \"Null means pricing was not found or not public in the checked official source.\",\r\n \"Some providers price audio, image, video, search, batch, cache, and regional processing separately.\",\r\n \"This catalog intentionally does not include OpenRouter pricing.\"\r\n ],\r\n \"models\": [\r\n {\r\n \"provider\": \"openai\",\r\n \"modelId\": \"gpt-5.5\",\r\n \"displayName\": \"GPT-5.5\",\r\n \"family\": \"gpt\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"vision\"],\r\n \"contextWindow\": 1000000,\r\n \"pricing\": {\r\n \"input\": 5,\r\n \"cachedInput\": 0.5,\r\n \"output\": 30,\r\n \"batchDiscount\": \"50%\",\r\n \"priorityMultiplier\": 2.5,\r\n \"dataResidencyMultiplier\": 1.1\r\n },\r\n \"sourceUrl\": \"https://openai.com/api/pricing/\"\r\n },\r\n {\r\n \"provider\": \"openai\",\r\n \"modelId\": \"gpt-5.5-pro\",\r\n \"displayName\": \"GPT-5.5 Pro\",\r\n \"family\": \"gpt\",\r\n \"status\": \"announced\",\r\n \"modalities\": [\"text\", \"vision\"],\r\n \"contextWindow\": 1000000,\r\n \"pricing\": {\r\n \"input\": 30,\r\n \"output\": 180\r\n },\r\n \"sourceUrl\": \"https://openai.com/index/introducing-gpt-5-5/\"\r\n },\r\n {\r\n \"provider\": \"openai\",\r\n \"modelId\": \"gpt-5.4\",\r\n \"displayName\": \"GPT-5.4\",\r\n \"family\": \"gpt\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"vision\"],\r\n \"pricing\": {\r\n \"input\": 2.5,\r\n \"cachedInput\": 0.25,\r\n \"output\": 15,\r\n \"batchDiscount\": \"50%\",\r\n \"dataResidencyMultiplier\": 1.1\r\n },\r\n \"sourceUrl\": \"https://openai.com/api/pricing/\"\r\n },\r\n {\r\n \"provider\": \"openai\",\r\n \"modelId\": \"gpt-5.4-mini\",\r\n \"displayName\": \"GPT-5.4 Mini\",\r\n \"family\": \"gpt\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"vision\"],\r\n \"pricing\": {\r\n \"input\": 0.75,\r\n \"cachedInput\": 0.075,\r\n \"output\": 4.5,\r\n \"batchDiscount\": \"50%\",\r\n \"dataResidencyMultiplier\": 1.1\r\n },\r\n \"sourceUrl\": \"https://openai.com/api/pricing/\"\r\n },\r\n {\r\n \"provider\": \"openai\",\r\n \"modelId\": \"gpt-realtime-2\",\r\n \"displayName\": \"GPT Realtime 2\",\r\n \"family\": \"gpt-realtime\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"audio\", \"image\"],\r\n \"pricing\": {\r\n \"textInput\": 4,\r\n \"textCachedInput\": 0.4,\r\n \"textOutput\": 24,\r\n \"audioInput\": 32,\r\n \"audioCachedInput\": 0.4,\r\n \"audioOutput\": 64,\r\n \"imageInput\": 5,\r\n \"imageCachedInput\": 0.5\r\n },\r\n \"sourceUrl\": \"https://openai.com/api/pricing/\"\r\n },\r\n {\r\n \"provider\": \"openai\",\r\n \"modelId\": \"gpt-image-2\",\r\n \"displayName\": \"GPT Image 2\",\r\n \"family\": \"gpt-image\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"image\", \"text\"],\r\n \"pricing\": {\r\n \"imageInput\": 8,\r\n \"imageCachedInput\": 2,\r\n \"imageOutput\": 30,\r\n \"textInput\": 5,\r\n \"textCachedInput\": 1.25\r\n },\r\n \"sourceUrl\": \"https://openai.com/api/pricing/\"\r\n },\r\n\r\n {\r\n \"provider\": \"anthropic\",\r\n \"modelId\": \"claude-opus-4-7\",\r\n \"displayName\": \"Claude Opus 4.7\",\r\n \"family\": \"claude\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"vision\"],\r\n \"contextWindow\": 1000000,\r\n \"pricing\": {\r\n \"input\": 5,\r\n \"cacheWrite5m\": 6.25,\r\n \"cacheWrite1h\": 10,\r\n \"cacheHit\": 0.5,\r\n \"output\": 25,\r\n \"batchInput\": 2.5,\r\n \"batchOutput\": 12.5,\r\n \"fastModeInput\": 30,\r\n \"fastModeOutput\": 150\r\n },\r\n \"sourceUrl\": \"https://platform.claude.com/docs/en/about-claude/pricing\"\r\n },\r\n {\r\n \"provider\": \"anthropic\",\r\n \"modelId\": \"claude-opus-4-6\",\r\n \"displayName\": \"Claude Opus 4.6\",\r\n \"family\": \"claude\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"vision\"],\r\n \"contextWindow\": 1000000,\r\n \"pricing\": {\r\n \"input\": 5,\r\n \"cacheWrite5m\": 6.25,\r\n \"cacheWrite1h\": 10,\r\n \"cacheHit\": 0.5,\r\n \"output\": 25,\r\n \"batchInput\": 2.5,\r\n \"batchOutput\": 12.5,\r\n \"fastModeInput\": 30,\r\n \"fastModeOutput\": 150\r\n },\r\n \"sourceUrl\": \"https://platform.claude.com/docs/en/about-claude/pricing\"\r\n },\r\n {\r\n \"provider\": \"anthropic\",\r\n \"modelId\": \"claude-opus-4-5\",\r\n \"displayName\": \"Claude Opus 4.5\",\r\n \"family\": \"claude\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"vision\"],\r\n \"pricing\": {\r\n \"input\": 5,\r\n \"cacheWrite5m\": 6.25,\r\n \"cacheWrite1h\": 10,\r\n \"cacheHit\": 0.5,\r\n \"output\": 25,\r\n \"batchInput\": 2.5,\r\n \"batchOutput\": 12.5\r\n },\r\n \"sourceUrl\": \"https://platform.claude.com/docs/en/about-claude/pricing\"\r\n },\r\n {\r\n \"provider\": \"anthropic\",\r\n \"modelId\": \"claude-sonnet-4-6\",\r\n \"displayName\": \"Claude Sonnet 4.6\",\r\n \"family\": \"claude\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"vision\"],\r\n \"contextWindow\": 1000000,\r\n \"pricing\": {\r\n \"input\": 3,\r\n \"cacheWrite5m\": 3.75,\r\n \"cacheWrite1h\": 6,\r\n \"cacheHit\": 0.3,\r\n \"output\": 15,\r\n \"batchInput\": 1.5,\r\n \"batchOutput\": 7.5\r\n },\r\n \"sourceUrl\": \"https://platform.claude.com/docs/en/about-claude/pricing\"\r\n },\r\n {\r\n \"provider\": \"anthropic\",\r\n \"modelId\": \"claude-sonnet-4-5\",\r\n \"displayName\": \"Claude Sonnet 4.5\",\r\n \"family\": \"claude\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"vision\"],\r\n \"pricing\": {\r\n \"input\": 3,\r\n \"cacheWrite5m\": 3.75,\r\n \"cacheWrite1h\": 6,\r\n \"cacheHit\": 0.3,\r\n \"output\": 15,\r\n \"batchInput\": 1.5,\r\n \"batchOutput\": 7.5\r\n },\r\n \"sourceUrl\": \"https://platform.claude.com/docs/en/about-claude/pricing\"\r\n },\r\n {\r\n \"provider\": \"anthropic\",\r\n \"modelId\": \"claude-haiku-4-5\",\r\n \"displayName\": \"Claude Haiku 4.5\",\r\n \"family\": \"claude\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"vision\"],\r\n \"pricing\": {\r\n \"input\": 1,\r\n \"cacheWrite5m\": 1.25,\r\n \"cacheWrite1h\": 2,\r\n \"cacheHit\": 0.1,\r\n \"output\": 5,\r\n \"batchInput\": 0.5,\r\n \"batchOutput\": 2.5\r\n },\r\n \"sourceUrl\": \"https://platform.claude.com/docs/en/about-claude/pricing\"\r\n },\r\n\r\n {\r\n \"provider\": \"google\",\r\n \"modelId\": \"gemini-3.5-flash\",\r\n \"displayName\": \"Gemini 3.5 Flash\",\r\n \"family\": \"gemini\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"image\", \"video\", \"audio\"],\r\n \"pricing\": {\r\n \"input\": 0.25,\r\n \"audioInput\": 0.5,\r\n \"output\": 1.5,\r\n \"cachedInput\": 0.025,\r\n \"audioCachedInput\": 0.05,\r\n \"cacheStoragePerHour\": 1,\r\n \"batchInput\": 0.125,\r\n \"batchAudioInput\": 0.25,\r\n \"batchOutput\": 0.75,\r\n \"googleSearchAfterFreePer1kQueries\": 14,\r\n \"googleMapsAfterFreePer1kQueries\": 14\r\n },\r\n \"sourceUrl\": \"https://ai.google.dev/gemini-api/docs/pricing\"\r\n },\r\n {\r\n \"provider\": \"google\",\r\n \"modelId\": \"gemini-3.1-pro-preview\",\r\n \"displayName\": \"Gemini 3.1 Pro Preview\",\r\n \"family\": \"gemini\",\r\n \"status\": \"preview\",\r\n \"modalities\": [\"text\", \"image\", \"video\", \"audio\"],\r\n \"pricing\": {\r\n \"input\": 0.45,\r\n \"audioInput\": 0.9,\r\n \"output\": 2.7,\r\n \"cachedInput\": 0.045,\r\n \"audioCachedInput\": 0.09,\r\n \"cacheStoragePerHour\": 1.8,\r\n \"googleSearchAfterFreePer1kQueries\": 14,\r\n \"googleMapsAfterFreePer1kQueries\": 14\r\n },\r\n \"sourceUrl\": \"https://ai.google.dev/gemini-api/docs/pricing\"\r\n },\r\n {\r\n \"provider\": \"google\",\r\n \"modelId\": \"gemini-3.1-flash-lite-preview\",\r\n \"displayName\": \"Gemini 3.1 Flash-Lite Preview\",\r\n \"family\": \"gemini\",\r\n \"status\": \"preview\",\r\n \"modalities\": [\"text\", \"image\", \"video\", \"audio\"],\r\n \"pricing\": {\r\n \"input\": 0.25,\r\n \"audioInput\": 0.5,\r\n \"output\": 1.5,\r\n \"cachedInput\": 0.025,\r\n \"audioCachedInput\": 0.05,\r\n \"cacheStoragePerHour\": 1,\r\n \"batchInput\": 0.125,\r\n \"batchAudioInput\": 0.25,\r\n \"batchOutput\": 0.75,\r\n \"googleSearchAfterFreePer1kQueries\": 14\r\n },\r\n \"sourceUrl\": \"https://ai.google.dev/gemini-api/docs/pricing\"\r\n },\r\n {\r\n \"provider\": \"google\",\r\n \"modelId\": \"gemini-2.5-flash\",\r\n \"displayName\": \"Gemini 2.5 Flash\",\r\n \"family\": \"gemini\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"image\", \"video\", \"audio\"],\r\n \"pricing\": {\r\n \"input\": 0.1,\r\n \"audioInput\": 0.7,\r\n \"output\": 0.4,\r\n \"cachedInput\": 0.025,\r\n \"audioCachedInput\": 0.175,\r\n \"cacheStoragePerHour\": 1\r\n },\r\n \"sourceUrl\": \"https://ai.google.dev/gemini-api/docs/pricing\"\r\n },\r\n {\r\n \"provider\": \"google\",\r\n \"modelId\": \"gemini-2.5-flash-lite\",\r\n \"displayName\": \"Gemini 2.5 Flash-Lite\",\r\n \"family\": \"gemini\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"image\", \"video\", \"audio\"],\r\n \"pricing\": {\r\n \"input\": 0.05,\r\n \"audioInput\": 0.35,\r\n \"output\": 0.2,\r\n \"cachedInput\": 0.025,\r\n \"audioCachedInput\": 0.175,\r\n \"cacheStoragePerHour\": 1\r\n },\r\n \"sourceUrl\": \"https://ai.google.dev/gemini-api/docs/pricing\"\r\n },\r\n {\r\n \"provider\": \"google\",\r\n \"modelId\": \"gemini-2.5-computer-use-preview-10-2025\",\r\n \"displayName\": \"Gemini 2.5 Computer Use Preview\",\r\n \"family\": \"gemini\",\r\n \"status\": \"preview\",\r\n \"modalities\": [\"text\", \"image\", \"browser-control\"],\r\n \"pricing\": {\r\n \"inputBelow200k\": 1.25,\r\n \"inputAbove200k\": 2.5,\r\n \"outputBelow200k\": 10,\r\n \"outputAbove200k\": 15\r\n },\r\n \"sourceUrl\": \"https://ai.google.dev/gemini-api/docs/pricing\"\r\n },\r\n {\r\n \"provider\": \"google\",\r\n \"modelId\": \"gemini-embedding-2\",\r\n \"displayName\": \"Gemini Embedding 2\",\r\n \"family\": \"gemini-embedding\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"image\", \"video\", \"audio\", \"pdf\"],\r\n \"pricing\": {\r\n \"textInput\": 0.2,\r\n \"imageInput\": 0.45,\r\n \"audioInput\": 6.5,\r\n \"videoInput\": 12\r\n },\r\n \"sourceUrl\": \"https://ai.google.dev/gemini-api/docs/pricing\"\r\n },\r\n {\r\n \"provider\": \"google\",\r\n \"modelId\": \"gemini-embedding-001\",\r\n \"displayName\": \"Gemini Embedding\",\r\n \"family\": \"gemini-embedding\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"pricing\": {\r\n \"input\": 0.15,\r\n \"batchInput\": 0.075\r\n },\r\n \"sourceUrl\": \"https://ai.google.dev/gemini-api/docs/pricing\"\r\n },\r\n\r\n {\r\n \"provider\": \"deepseek\",\r\n \"modelId\": \"deepseek-v4-flash\",\r\n \"displayName\": \"DeepSeek V4 Flash\",\r\n \"family\": \"deepseek-v4\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"contextWindow\": 1000000,\r\n \"maxOutputTokens\": 384000,\r\n \"pricing\": {\r\n \"inputCacheHit\": 0.0028,\r\n \"inputCacheMiss\": 0.14,\r\n \"output\": 0.28\r\n },\r\n \"capabilities\": {\r\n \"thinkingMode\": true,\r\n \"jsonOutput\": true,\r\n \"toolCalls\": true,\r\n \"fimCompletion\": true\r\n },\r\n \"sourceUrl\": \"https://api-docs.deepseek.com/quick_start/pricing\"\r\n },\r\n {\r\n \"provider\": \"deepseek\",\r\n \"modelId\": \"deepseek-v4-pro\",\r\n \"displayName\": \"DeepSeek V4 Pro\",\r\n \"family\": \"deepseek-v4\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"contextWindow\": 1000000,\r\n \"maxOutputTokens\": 384000,\r\n \"pricing\": {\r\n \"inputCacheHit\": 0.003625,\r\n \"inputCacheMiss\": 0.435,\r\n \"output\": 0.87,\r\n \"note\": \"DeepSeek states the 75% reduction becomes official pricing after the promotion ends on 2026-05-31 15:59 UTC.\"\r\n },\r\n \"capabilities\": {\r\n \"thinkingMode\": true,\r\n \"jsonOutput\": true,\r\n \"toolCalls\": true,\r\n \"fimCompletion\": true\r\n },\r\n \"sourceUrl\": \"https://api-docs.deepseek.com/quick_start/pricing\"\r\n },\r\n\r\n {\r\n \"provider\": \"xai\",\r\n \"modelId\": \"grok-4.3\",\r\n \"displayName\": \"Grok 4.3\",\r\n \"family\": \"grok\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"contextWindow\": 1000000,\r\n \"pricing\": {\r\n \"input\": 1.25,\r\n \"cachedInput\": 0.2,\r\n \"output\": 2.5\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": \"configurable\",\r\n \"toolCalling\": true\r\n },\r\n \"sourceUrl\": \"https://docs.x.ai/developers/pricing\"\r\n },\r\n {\r\n \"provider\": \"xai\",\r\n \"modelId\": \"grok-build-0.1\",\r\n \"displayName\": \"Grok Build 0.1\",\r\n \"family\": \"grok-build\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"code\"],\r\n \"contextWindow\": 256000,\r\n \"pricing\": {\r\n \"input\": 1,\r\n \"cachedInput\": 0.2,\r\n \"output\": 2\r\n },\r\n \"sourceUrl\": \"https://docs.x.ai/developers/pricing\"\r\n },\r\n {\r\n \"provider\": \"xai\",\r\n \"modelId\": \"grok-4.20-multi-agent-0309\",\r\n \"displayName\": \"Grok 4.20 Multi-Agent\",\r\n \"family\": \"grok\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"contextWindow\": 1000000,\r\n \"pricing\": {\r\n \"input\": 1.25,\r\n \"cachedInput\": 0.2,\r\n \"output\": 2.5\r\n },\r\n \"sourceUrl\": \"https://docs.x.ai/developers/pricing\"\r\n },\r\n {\r\n \"provider\": \"xai\",\r\n \"modelId\": \"grok-4.20-0309-reasoning\",\r\n \"displayName\": \"Grok 4.20 Reasoning\",\r\n \"family\": \"grok\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"contextWindow\": 1000000,\r\n \"pricing\": {\r\n \"input\": 1.25,\r\n \"cachedInput\": 0.2,\r\n \"output\": 2.5\r\n },\r\n \"sourceUrl\": \"https://docs.x.ai/developers/pricing\"\r\n },\r\n {\r\n \"provider\": \"xai\",\r\n \"modelId\": \"grok-4.20-0309-non-reasoning\",\r\n \"displayName\": \"Grok 4.20 Non-Reasoning\",\r\n \"family\": \"grok\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"contextWindow\": 1000000,\r\n \"pricing\": {\r\n \"input\": 1.25,\r\n \"cachedInput\": 0.2,\r\n \"output\": 2.5\r\n },\r\n \"sourceUrl\": \"https://docs.x.ai/developers/pricing\"\r\n },\r\n\r\n {\r\n \"provider\": \"cohere\",\r\n \"modelId\": \"command-a\",\r\n \"displayName\": \"Command A\",\r\n \"family\": \"command\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"pricing\": {\r\n \"input\": 1,\r\n \"output\": 2\r\n },\r\n \"sourceUrl\": \"https://cohere.com/pricing\"\r\n },\r\n {\r\n \"provider\": \"cohere\",\r\n \"modelId\": \"command\",\r\n \"displayName\": \"Command\",\r\n \"family\": \"command\",\r\n \"status\": \"legacy\",\r\n \"modalities\": [\"text\"],\r\n \"pricing\": {\r\n \"input\": 1,\r\n \"output\": 2\r\n },\r\n \"sourceUrl\": \"https://cohere.com/pricing\"\r\n },\r\n {\r\n \"provider\": \"cohere\",\r\n \"modelId\": \"command-light\",\r\n \"displayName\": \"Command Light\",\r\n \"family\": \"command\",\r\n \"status\": \"legacy\",\r\n \"modalities\": [\"text\"],\r\n \"pricing\": {\r\n \"input\": 0.3,\r\n \"output\": 0.6\r\n },\r\n \"sourceUrl\": \"https://cohere.com/pricing\"\r\n },\r\n {\r\n \"provider\": \"cohere\",\r\n \"modelId\": \"command-r-03-2024\",\r\n \"displayName\": \"Command R 03-2024\",\r\n \"family\": \"command-r\",\r\n \"status\": \"legacy\",\r\n \"modalities\": [\"text\"],\r\n \"pricing\": {\r\n \"input\": 0.5,\r\n \"output\": 1.5\r\n },\r\n \"sourceUrl\": \"https://cohere.com/pricing\"\r\n },\r\n {\r\n \"provider\": \"cohere\",\r\n \"modelId\": \"command-r-plus-08-2024\",\r\n \"displayName\": \"Command R+ 08-2024\",\r\n \"family\": \"command-r\",\r\n \"status\": \"legacy\",\r\n \"modalities\": [\"text\"],\r\n \"pricing\": {\r\n \"input\": 2.5,\r\n \"output\": 10\r\n },\r\n \"sourceUrl\": \"https://cohere.com/pricing\"\r\n },\r\n\r\n {\r\n \"provider\": \"perplexity\",\r\n \"modelId\": \"sonar-pro\",\r\n \"displayName\": \"Sonar Pro\",\r\n \"family\": \"sonar\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"search\"],\r\n \"pricing\": {\r\n \"input\": 3,\r\n \"output\": 15,\r\n \"searchRequestFeePer1k\": {\r\n \"fastLow\": 6,\r\n \"fastMedium\": 10,\r\n \"fastHigh\": 14,\r\n \"proLow\": 14,\r\n \"proMedium\": 18,\r\n \"proHigh\": 22\r\n }\r\n },\r\n \"sourceUrl\": \"https://docs.perplexity.ai/docs/getting-started/pricing\"\r\n },\r\n\r\n {\r\n \"provider\": \"groq\",\r\n \"modelId\": \"openai/gpt-oss-20b\",\r\n \"displayName\": \"GPT OSS 20B 128k\",\r\n \"family\": \"gpt-oss\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"contextWindow\": 128000,\r\n \"pricing\": {\r\n \"input\": 0.075,\r\n \"output\": 0.3\r\n },\r\n \"sourceUrl\": \"https://groq.com/pricing\"\r\n },\r\n {\r\n \"provider\": \"groq\",\r\n \"modelId\": \"openai/gpt-oss-120b\",\r\n \"displayName\": \"GPT OSS 120B 128k\",\r\n \"family\": \"gpt-oss\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"contextWindow\": 128000,\r\n \"pricing\": {\r\n \"input\": 0.15,\r\n \"output\": 0.6\r\n },\r\n \"sourceUrl\": \"https://groq.com/pricing\"\r\n },\r\n {\r\n \"provider\": \"groq\",\r\n \"modelId\": \"meta-llama/llama-4-scout-17b-16e-instruct\",\r\n \"displayName\": \"Llama 4 Scout 17Bx16E 128k\",\r\n \"family\": \"llama\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"contextWindow\": 128000,\r\n \"pricing\": {\r\n \"input\": 0.11,\r\n \"output\": 0.34\r\n },\r\n \"sourceUrl\": \"https://groq.com/pricing\"\r\n },\r\n {\r\n \"provider\": \"groq\",\r\n \"modelId\": \"qwen/qwen3-32b\",\r\n \"displayName\": \"Qwen3 32B 131k\",\r\n \"family\": \"qwen\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\"],\r\n \"contextWindow\": 131000,\r\n \"pricing\": {\r\n \"input\": 0.29,\r\n \"output\": 0.59\r\n },\r\n \"sourceUrl\": \"https://groq.com/pricing\"\r\n },\r\n\r\n {\r\n \"provider\": \"mistral\",\r\n \"modelId\": \"mistral-medium-3\",\r\n \"displayName\": \"Mistral Medium 3\",\r\n \"family\": \"mistral\",\r\n \"status\": \"active\",\r\n \"modalities\": [\"text\", \"vision\", \"tools\"],\r\n \"pricing\": {\r\n \"input\": 0.4,\r\n \"output\": 2\r\n },\r\n \"sourceUrl\": \"https://mistral.ai/news/mistral-medium-3\"\r\n },\r\n\r\n {\r\n \"provider\": \"ai21\",\r\n \"modelId\": \"jamba-large-1.7\",\r\n \"displayName\": \"Jamba Large 1.7\",\r\n \"family\": \"jamba\",\r\n \"status\": \"needs_verification\",\r\n \"modalities\": [\"text\"],\r\n \"pricing\": {\r\n \"input\": null,\r\n \"output\": null\r\n },\r\n \"notes\": \"AI21 docs say pricing depends on platform/endpoints and links to account/billing; public token prices were not exposed clearly in the checked official docs.\",\r\n \"sourceUrl\": \"https://docs.ai21.com/docs/usage-cost\"\r\n }\r\n ]\r\n}","{\r\n \"schema\": \"x12i.openrouter-models.catalog\",\r\n \"version\": \"0.1.0\",\r\n \"currency\": \"USD\",\r\n \"pricingUnit\": \"1M_tokens\",\r\n \"source\": {\r\n \"provider\": \"openrouter\",\r\n \"catalogUrl\": \"https://openrouter.ai/api/v1/models\",\r\n \"pricingUrl\": \"https://openrouter.ai/pricing\",\r\n \"verifiedAt\": \"2026-05-27\",\r\n \"normalization\": \"OpenRouter pricing fields are per-token decimal strings. Values below are normalized to USD per 1M tokens.\"\r\n },\r\n \"notes\": [\r\n \"This catalog is OpenRouter-specific and should not be merged with direct-provider pricing.\",\r\n \"Router models beginning with ~ are dynamic aliases that redirect to latest model families.\",\r\n \"Models ending with :free are free OpenRouter variants and may have rate limits or availability limits.\",\r\n \"webSearch is kept as a separate field because OpenRouter exposes it separately from token pricing.\",\r\n \"This is a seed catalog. In production, generate the full file from https://openrouter.ai/api/v1/models.\"\r\n ],\r\n \"models\": [\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"qwen/qwen3.7-max\",\r\n \"canonicalSlug\": \"qwen/qwen3.7-max-20260520\",\r\n \"displayName\": \"Qwen: Qwen3.7 Max\",\r\n \"family\": \"qwen\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1000000,\r\n \"maxCompletionTokens\": 65536,\r\n \"pricing\": {\r\n \"input\": 1.25,\r\n \"output\": 3.75,\r\n \"cachedInput\": 0.25,\r\n \"cacheWrite\": 1.5625\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"x-ai/grok-build-0.1\",\r\n \"canonicalSlug\": \"x-ai/grok-build-0.1-20260520\",\r\n \"displayName\": \"xAI: Grok Build 0.1\",\r\n \"family\": \"grok\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 256000,\r\n \"pricing\": {\r\n \"input\": 1,\r\n \"output\": 2,\r\n \"cachedInput\": 0.2,\r\n \"webSearchPerRequest\": 0.005\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"google/gemini-3.5-flash\",\r\n \"canonicalSlug\": \"google/gemini-3.5-flash-20260519\",\r\n \"displayName\": \"Google: Gemini 3.5 Flash\",\r\n \"family\": \"gemini\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"video\", \"file\", \"audio\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1048576,\r\n \"maxCompletionTokens\": 65536,\r\n \"knowledgeCutoff\": \"2025-01-01\",\r\n \"pricing\": {\r\n \"input\": 1.5,\r\n \"output\": 9,\r\n \"imageInput\": 1.5,\r\n \"audioInput\": 3,\r\n \"cachedInput\": 0.15,\r\n \"cacheWrite\": 0.08333333333333334,\r\n \"internalReasoning\": 9,\r\n \"webSearchPerRequest\": 0.014\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"anthropic/claude-opus-4.7-fast\",\r\n \"canonicalSlug\": \"anthropic/claude-4.7-opus-fast-20260512\",\r\n \"displayName\": \"Anthropic: Claude Opus 4.7 Fast\",\r\n \"family\": \"claude\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1000000,\r\n \"maxCompletionTokens\": 128000,\r\n \"pricing\": {\r\n \"input\": 30,\r\n \"output\": 150,\r\n \"cachedInput\": 3,\r\n \"cacheWrite\": 37.5,\r\n \"webSearchPerRequest\": 0.01\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"perceptron/perceptron-mk1\",\r\n \"canonicalSlug\": \"perceptron/perceptron-mk1-20260512\",\r\n \"displayName\": \"Perceptron: Perceptron Mk1\",\r\n \"family\": \"perceptron\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"video\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 32768,\r\n \"maxCompletionTokens\": 8192,\r\n \"pricing\": {\r\n \"input\": 0.15,\r\n \"output\": 1.5\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"inclusionai/ring-2.6-1t\",\r\n \"canonicalSlug\": \"inclusionai/ring-2.6-1t-20260508\",\r\n \"displayName\": \"inclusionAI: Ring-2.6-1T\",\r\n \"family\": \"ring\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 262144,\r\n \"maxCompletionTokens\": 65536,\r\n \"pricing\": {\r\n \"input\": 0.075,\r\n \"output\": 0.625,\r\n \"cachedInput\": 0.015\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"google/gemini-3.1-flash-lite\",\r\n \"canonicalSlug\": \"google/gemini-3.1-flash-lite-20260507\",\r\n \"displayName\": \"Google: Gemini 3.1 Flash Lite\",\r\n \"family\": \"gemini\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"video\", \"file\", \"audio\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1048576,\r\n \"maxCompletionTokens\": 65536,\r\n \"pricing\": {\r\n \"input\": 0.25,\r\n \"output\": 1.5,\r\n \"imageInput\": 0.25,\r\n \"audioInput\": 0.5,\r\n \"cachedInput\": 0.025,\r\n \"cacheWrite\": 0.08333333333333334,\r\n \"internalReasoning\": 1.5,\r\n \"webSearchPerRequest\": 0.014\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"openai/gpt-chat-latest\",\r\n \"canonicalSlug\": \"openai/gpt-chat-latest-20260505\",\r\n \"displayName\": \"OpenAI: GPT Chat Latest\",\r\n \"family\": \"gpt\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 400000,\r\n \"maxCompletionTokens\": 128000,\r\n \"pricing\": {\r\n \"input\": 5,\r\n \"output\": 30,\r\n \"cachedInput\": 0.5,\r\n \"webSearchPerRequest\": 0.01\r\n },\r\n \"capabilities\": {\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"x-ai/grok-4.3\",\r\n \"canonicalSlug\": \"x-ai/grok-4.3-20260430\",\r\n \"displayName\": \"xAI: Grok 4.3\",\r\n \"family\": \"grok\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1000000,\r\n \"pricing\": {\r\n \"input\": 1.25,\r\n \"output\": 2.5,\r\n \"cachedInput\": 0.2,\r\n \"webSearchPerRequest\": 0.005\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"ibm-granite/granite-4.1-8b\",\r\n \"canonicalSlug\": \"ibm-granite/granite-4.1-8b-20260429\",\r\n \"displayName\": \"IBM: Granite 4.1 8B\",\r\n \"family\": \"granite\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 131072,\r\n \"maxCompletionTokens\": 131072,\r\n \"pricing\": {\r\n \"input\": 0.05,\r\n \"output\": 0.1,\r\n \"cachedInput\": 0.05\r\n },\r\n \"capabilities\": {\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"mistralai/mistral-medium-3-5\",\r\n \"canonicalSlug\": \"mistralai/mistral-medium-3.5-20260430\",\r\n \"displayName\": \"Mistral: Mistral Medium 3.5\",\r\n \"family\": \"mistral\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 262144,\r\n \"pricing\": {\r\n \"input\": 1.5,\r\n \"output\": 7.5\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"openrouter/owl-alpha\",\r\n \"canonicalSlug\": \"openrouter/owl-alpha\",\r\n \"displayName\": \"Owl Alpha\",\r\n \"family\": \"owl\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1048756,\r\n \"maxCompletionTokens\": 262144,\r\n \"pricing\": {\r\n \"input\": 0,\r\n \"output\": 0\r\n },\r\n \"capabilities\": {\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"~anthropic/claude-haiku-latest\",\r\n \"canonicalSlug\": \"~anthropic/claude-haiku-latest\",\r\n \"displayName\": \"Anthropic Claude Haiku Latest\",\r\n \"family\": \"claude-router\",\r\n \"status\": \"router\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 200000,\r\n \"maxCompletionTokens\": 64000,\r\n \"pricing\": {\r\n \"input\": 1,\r\n \"output\": 5,\r\n \"cachedInput\": 0.1,\r\n \"cacheWrite\": 1.25,\r\n \"webSearchPerRequest\": 0.01\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"~openai/gpt-mini-latest\",\r\n \"canonicalSlug\": \"~openai/gpt-mini-latest\",\r\n \"displayName\": \"OpenAI GPT Mini Latest\",\r\n \"family\": \"gpt-router\",\r\n \"status\": \"router\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 400000,\r\n \"maxCompletionTokens\": 128000,\r\n \"knowledgeCutoff\": \"2025-08-31\",\r\n \"pricing\": {\r\n \"input\": 0.75,\r\n \"output\": 4.5,\r\n \"cachedInput\": 0.075,\r\n \"webSearchPerRequest\": 0.01\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"~google/gemini-pro-latest\",\r\n \"canonicalSlug\": \"~google/gemini-pro-latest\",\r\n \"displayName\": \"Google Gemini Pro Latest\",\r\n \"family\": \"gemini-router\",\r\n \"status\": \"router\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\", \"audio\", \"video\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1048576,\r\n \"maxCompletionTokens\": 65536,\r\n \"pricing\": {\r\n \"input\": 2,\r\n \"output\": 12,\r\n \"imageInput\": 2,\r\n \"audioInput\": 2,\r\n \"cachedInput\": 0.2,\r\n \"cacheWrite\": 0.375,\r\n \"internalReasoning\": 12,\r\n \"webSearchPerRequest\": 0.014\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"~moonshotai/kimi-latest\",\r\n \"canonicalSlug\": \"~moonshotai/kimi-latest\",\r\n \"displayName\": \"MoonshotAI Kimi Latest\",\r\n \"family\": \"kimi-router\",\r\n \"status\": \"router\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 262144,\r\n \"maxCompletionTokens\": 262142,\r\n \"pricing\": {\r\n \"input\": 0.73,\r\n \"output\": 3.49,\r\n \"cachedInput\": 0.25\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"~google/gemini-flash-latest\",\r\n \"canonicalSlug\": \"~google/gemini-flash-latest\",\r\n \"displayName\": \"Google Gemini Flash Latest\",\r\n \"family\": \"gemini-router\",\r\n \"status\": \"router\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"video\", \"file\", \"audio\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1048576,\r\n \"maxCompletionTokens\": 65536,\r\n \"knowledgeCutoff\": \"2025-01-01\",\r\n \"pricing\": {\r\n \"input\": 1.5,\r\n \"output\": 9,\r\n \"imageInput\": 1.5,\r\n \"audioInput\": 3,\r\n \"cachedInput\": 0.15,\r\n \"cacheWrite\": 0.08333333333333334,\r\n \"internalReasoning\": 9,\r\n \"webSearchPerRequest\": 0.014\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"~anthropic/claude-sonnet-latest\",\r\n \"canonicalSlug\": \"~anthropic/claude-sonnet-latest\",\r\n \"displayName\": \"Anthropic Claude Sonnet Latest\",\r\n \"family\": \"claude-router\",\r\n \"status\": \"router\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1000000,\r\n \"maxCompletionTokens\": 128000,\r\n \"pricing\": {\r\n \"input\": 3,\r\n \"output\": 15,\r\n \"cachedInput\": 0.3,\r\n \"cacheWrite\": 3.75,\r\n \"webSearchPerRequest\": 0.01\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"~openai/gpt-latest\",\r\n \"canonicalSlug\": \"~openai/gpt-latest\",\r\n \"displayName\": \"OpenAI GPT Latest\",\r\n \"family\": \"gpt-router\",\r\n \"status\": \"router\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1050000,\r\n \"maxCompletionTokens\": 128000,\r\n \"knowledgeCutoff\": \"2025-12-01\",\r\n \"pricing\": {\r\n \"input\": 5,\r\n \"output\": 30,\r\n \"cachedInput\": 0.5,\r\n \"webSearchPerRequest\": 0.01\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"qwen/qwen3.5-plus-20260420\",\r\n \"canonicalSlug\": \"qwen/qwen3.5-plus-20260420\",\r\n \"displayName\": \"Qwen: Qwen3.5 Plus 2026-04-20\",\r\n \"family\": \"qwen\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"video\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1000000,\r\n \"maxCompletionTokens\": 65536,\r\n \"pricing\": {\r\n \"input\": 0.3,\r\n \"output\": 1.8,\r\n \"cacheWrite\": 0.375\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"qwen/qwen3.6-flash\",\r\n \"canonicalSlug\": \"qwen/qwen3.6-flash\",\r\n \"displayName\": \"Qwen: Qwen3.6 Flash\",\r\n \"family\": \"qwen\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"video\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1000000,\r\n \"maxCompletionTokens\": 65536,\r\n \"pricing\": {\r\n \"input\": 0.1875,\r\n \"output\": 1.125,\r\n \"cacheWrite\": 0.234375\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"qwen/qwen3.6-35b-a3b\",\r\n \"canonicalSlug\": \"qwen/qwen3.6-35b-a3b-20260415\",\r\n \"displayName\": \"Qwen: Qwen3.6 35B A3B\",\r\n \"family\": \"qwen\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"video\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 262144,\r\n \"maxCompletionTokens\": 262140,\r\n \"pricing\": {\r\n \"input\": 0.14,\r\n \"output\": 1\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"qwen/qwen3.6-max-preview\",\r\n \"canonicalSlug\": \"qwen/qwen3.6-max-preview-20260420\",\r\n \"displayName\": \"Qwen: Qwen3.6 Max Preview\",\r\n \"family\": \"qwen\",\r\n \"status\": \"preview\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 262144,\r\n \"maxCompletionTokens\": 65536,\r\n \"pricing\": {\r\n \"input\": 1.04,\r\n \"output\": 6.24,\r\n \"cacheWrite\": 1.3\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"qwen/qwen3.6-27b\",\r\n \"canonicalSlug\": \"qwen/qwen3.6-27b-20260422\",\r\n \"displayName\": \"Qwen: Qwen3.6 27B\",\r\n \"family\": \"qwen\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"video\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 262144,\r\n \"maxCompletionTokens\": 262140,\r\n \"pricing\": {\r\n \"input\": 0.29,\r\n \"output\": 3.2\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"openai/gpt-5.5-pro\",\r\n \"canonicalSlug\": \"openai/gpt-5.5-pro-20260423\",\r\n \"displayName\": \"OpenAI: GPT-5.5 Pro\",\r\n \"family\": \"gpt\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1050000,\r\n \"maxCompletionTokens\": 128000,\r\n \"knowledgeCutoff\": \"2025-12-01\",\r\n \"pricing\": {\r\n \"input\": 30,\r\n \"output\": 180,\r\n \"webSearchPerRequest\": 0.01\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"openai/gpt-5.5\",\r\n \"canonicalSlug\": \"openai/gpt-5.5-20260423\",\r\n \"displayName\": \"OpenAI: GPT-5.5\",\r\n \"family\": \"gpt\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1050000,\r\n \"maxCompletionTokens\": 128000,\r\n \"knowledgeCutoff\": \"2025-12-01\",\r\n \"pricing\": {\r\n \"input\": 5,\r\n \"output\": 30,\r\n \"cachedInput\": 0.5,\r\n \"webSearchPerRequest\": 0.01\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"deepseek/deepseek-v4-pro\",\r\n \"canonicalSlug\": \"deepseek/deepseek-v4-pro-20260423\",\r\n \"displayName\": \"DeepSeek: DeepSeek V4 Pro\",\r\n \"family\": \"deepseek\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1048576,\r\n \"maxCompletionTokens\": 384000,\r\n \"pricing\": {\r\n \"input\": 0.435,\r\n \"output\": 0.87,\r\n \"cachedInput\": 0.003625\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"deepseek/deepseek-v4-flash\",\r\n \"canonicalSlug\": \"deepseek/deepseek-v4-flash-20260423\",\r\n \"displayName\": \"DeepSeek: DeepSeek V4 Flash\",\r\n \"family\": \"deepseek\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1048576,\r\n \"maxCompletionTokens\": 16384,\r\n \"pricing\": {\r\n \"input\": 0.1,\r\n \"output\": 0.2,\r\n \"cachedInput\": 0.02\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"deepseek/deepseek-v4-flash:free\",\r\n \"canonicalSlug\": \"deepseek/deepseek-v4-flash-20260423\",\r\n \"displayName\": \"DeepSeek: DeepSeek V4 Flash Free\",\r\n \"family\": \"deepseek\",\r\n \"status\": \"free\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1048576,\r\n \"maxCompletionTokens\": 384000,\r\n \"pricing\": {\r\n \"input\": 0,\r\n \"output\": 0\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"inclusionai/ling-2.6-1t\",\r\n \"canonicalSlug\": \"inclusionai/ling-2.6-1t-20260423\",\r\n \"displayName\": \"inclusionAI: Ling-2.6-1T\",\r\n \"family\": \"ling\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 262144,\r\n \"maxCompletionTokens\": 32768,\r\n \"pricing\": {\r\n \"input\": 0.075,\r\n \"output\": 0.625,\r\n \"cachedInput\": 0.015\r\n },\r\n \"capabilities\": {\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"tencent/hy3-preview\",\r\n \"canonicalSlug\": \"tencent/hy3-preview-20260421\",\r\n \"displayName\": \"Tencent: Hy3 Preview\",\r\n \"family\": \"hy3\",\r\n \"status\": \"preview\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 262144,\r\n \"maxCompletionTokens\": 262144,\r\n \"pricing\": {\r\n \"input\": 0.066,\r\n \"output\": 0.26,\r\n \"cachedInput\": 0.029\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"xiaomi/mimo-v2.5-pro\",\r\n \"canonicalSlug\": \"xiaomi/mimo-v2.5-pro-20260422\",\r\n \"displayName\": \"Xiaomi: MiMo-V2.5-Pro\",\r\n \"family\": \"mimo\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1048576,\r\n \"maxCompletionTokens\": 131072,\r\n \"pricing\": {\r\n \"input\": 0.435,\r\n \"output\": 0.87,\r\n \"cachedInput\": 0.0036\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true,\r\n \"structuredOutputs\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"xiaomi/mimo-v2.5\",\r\n \"canonicalSlug\": \"xiaomi/mimo-v2.5-20260422\",\r\n \"displayName\": \"Xiaomi: MiMo-V2.5\",\r\n \"family\": \"mimo\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"audio\", \"video\"],\r\n \"output\": [\"text\"]\r\n },\r\n \"contextWindow\": 1048576,\r\n \"maxCompletionTokens\": 131072,\r\n \"pricing\": {\r\n \"input\": 0.14,\r\n \"output\": 0.28,\r\n \"cachedInput\": 0.0028\r\n },\r\n \"capabilities\": {\r\n \"reasoning\": true,\r\n \"toolCalling\": true\r\n }\r\n },\r\n {\r\n \"provider\": \"openrouter\",\r\n \"modelId\": \"openai/gpt-5.4-image-2\",\r\n \"canonicalSlug\": \"openai/gpt-5.4-image-2-20260421\",\r\n \"displayName\": \"OpenAI: GPT-5.4 Image 2\",\r\n \"family\": \"gpt-image\",\r\n \"status\": \"active\",\r\n \"modalities\": {\r\n \"input\": [\"text\", \"image\", \"file\"],\r\n \"output\": [\"text\", \"image\"]\r\n },\r\n \"contextWindow\": 272000,\r\n \"pricing\": {\r\n \"input\": 8,\r\n \"output\": 15\r\n },\r\n \"capabilities\": {\r\n \"imageGeneration\": true,\r\n \"structuredOutputs\": true\r\n }\r\n }\r\n ]\r\n}","import { resolveCatalogCacheTtlMs } from \"../cache/modelCache.js\";\nimport { loadCatalogSources, type LoadCatalogOptions, type LoadedCatalogs } from \"./loadCatalogSources.js\";\n\ntype CacheSlot = {\n loadedAt: number;\n data: LoadedCatalogs;\n};\n\nconst slots = new Map<string, CacheSlot>();\nconst inflight = new Map<string, Promise<LoadedCatalogs>>();\n\nfunction slotKey(options: LoadCatalogOptions, cacheKey: string): string {\n return [\n cacheKey,\n options.bundledOnly ? \"bundled\" : \"remote\",\n options.directCatalogUrl ?? \"\",\n options.openRouterCatalogUrl ?? \"\",\n ].join(\"\\0\");\n}\n\nexport function invalidateCatalogLoadCache(cacheKey = \"default\"): void {\n for (const key of [...slots.keys()]) {\n if (key.startsWith(`${cacheKey}\\0`)) slots.delete(key);\n }\n for (const key of [...inflight.keys()]) {\n if (key.startsWith(`${cacheKey}\\0`)) inflight.delete(key);\n }\n}\n\nexport type LoadCatalogCachedOptions = {\n cacheKey?: string;\n ttlMs?: number;\n /** Bypass cache and fetch again (e.g. `catalog refresh`). */\n forceRefresh?: boolean;\n};\n\n/**\n * Load catalogs with a process-wide in-memory cache.\n * Remote fetches run at most once per TTL window (default 24h); concurrent callers share one in-flight request.\n */\nexport async function loadCatalogSourcesCached(\n options: LoadCatalogOptions = {},\n cacheOptions: LoadCatalogCachedOptions = {},\n): Promise<LoadedCatalogs> {\n if (options.bundledOnly) {\n return loadCatalogSources(options);\n }\n\n const ttlMs = resolveCatalogCacheTtlMs(cacheOptions.ttlMs);\n const key = slotKey(options, cacheOptions.cacheKey ?? \"default\");\n\n if (!cacheOptions.forceRefresh) {\n const slot = slots.get(key);\n if (slot && Date.now() - slot.loadedAt < ttlMs) {\n return slot.data;\n }\n } else {\n slots.delete(key);\n inflight.delete(key);\n }\n\n const pending = inflight.get(key);\n if (pending) return pending;\n\n const promise = loadCatalogSources(options)\n .then((data) => {\n slots.set(key, { loadedAt: Date.now(), data });\n inflight.delete(key);\n return data;\n })\n .catch((err) => {\n inflight.delete(key);\n throw err;\n });\n\n inflight.set(key, promise);\n return promise;\n}\n","import { resolveCatalogCacheTtlMs, writeCachedModels } from \"../cache/modelCache.js\";\nimport type { AiModelRecord } from \"../models/types.js\";\nimport { ModelNameResolver } from \"../sync/modelNameResolver/ModelNameResolver.js\";\nimport { normalizeProvider } from \"../sync/modelNameResolver/normalize.js\";\nimport type {\n ModelResolutionInput,\n ModelResolutionResult,\n ModelResolverOptions,\n} from \"../sync/modelNameResolver/types.js\";\nimport {\n invalidateCatalogLoadCache,\n loadCatalogSourcesCached,\n} from \"./catalogLoadCache.js\";\nimport type { LoadCatalogOptions } from \"./loadCatalogSources.js\";\n\nexport type AiModelsCatalogClientOptions = LoadCatalogOptions & {\n cacheTtlMs?: number;\n /** Cache scope key (default: `default`). */\n cacheKey?: string;\n resolverOptions?: Omit<ModelResolverOptions, \"aliasRegistry\">;\n};\n\nfunction isOpenRouterProvider(provider?: string): boolean {\n return normalizeProvider(provider) === \"openrouter\";\n}\n\nexport class AiModelsCatalogClient {\n private readonly cacheTtlMs: number;\n private readonly cacheKey: string;\n private readonly loadOptions: LoadCatalogOptions;\n private readonly resolverOptions?: ModelResolverOptions;\n\n private directModels: Map<string, AiModelRecord> | null = null;\n private openRouterModels: Map<string, AiModelRecord> | null = null;\n private loadedAt = 0;\n private loadPromise: Promise<void> | null = null;\n\n constructor(options: AiModelsCatalogClientOptions = {}) {\n this.cacheTtlMs = resolveCatalogCacheTtlMs(options.cacheTtlMs);\n this.cacheKey = options.cacheKey ?? \"default\";\n this.loadOptions = {\n directCatalogUrl: options.directCatalogUrl,\n openRouterCatalogUrl: options.openRouterCatalogUrl,\n bundledOnly: options.bundledOnly,\n fetchTimeoutMs: options.fetchTimeoutMs,\n };\n this.resolverOptions = options.resolverOptions;\n }\n\n private isInstanceCacheValid(): boolean {\n return (\n this.directModels !== null &&\n this.openRouterModels !== null &&\n Date.now() - this.loadedAt < this.cacheTtlMs\n );\n }\n\n private applyLoaded(\n direct: Map<string, AiModelRecord>,\n openrouter: Map<string, AiModelRecord>,\n ): void {\n this.directModels = direct;\n this.openRouterModels = openrouter;\n this.loadedAt = Date.now();\n writeCachedModels(`${this.cacheKey}:direct`, direct, this.cacheTtlMs);\n writeCachedModels(`${this.cacheKey}:openrouter`, openrouter, this.cacheTtlMs);\n }\n\n private async ensureLoaded(forceRefresh = false): Promise<void> {\n if (!forceRefresh && this.isInstanceCacheValid()) return;\n\n if (this.loadPromise) return this.loadPromise;\n\n this.loadPromise = (async () => {\n const loaded = await loadCatalogSourcesCached(this.loadOptions, {\n cacheKey: this.cacheKey,\n ttlMs: this.cacheTtlMs,\n forceRefresh,\n });\n this.applyLoaded(loaded.direct, loaded.openrouter);\n })().finally(() => {\n this.loadPromise = null;\n });\n\n await this.loadPromise;\n }\n\n mergedModels(): Map<string, AiModelRecord> {\n const map = new Map<string, AiModelRecord>();\n for (const r of this.directModels?.values() ?? []) {\n map.set(r.modelId, r);\n }\n for (const r of this.openRouterModels?.values() ?? []) {\n map.set(r.modelId, r);\n }\n return map;\n }\n\n private catalogForProvider(provider?: string): Map<string, AiModelRecord> {\n if (isOpenRouterProvider(provider)) {\n return this.openRouterModels ?? new Map();\n }\n return this.directModels ?? new Map();\n }\n\n private resolver(\n models: Map<string, AiModelRecord>,\n options?: ModelResolverOptions,\n ): ModelNameResolver {\n return new ModelNameResolver(models, { ...this.resolverOptions, ...options });\n }\n\n async getAllModels(): Promise<Map<string, AiModelRecord>> {\n await this.ensureLoaded();\n return this.mergedModels();\n }\n\n async getDirectModels(): Promise<Map<string, AiModelRecord>> {\n await this.ensureLoaded();\n return new Map(this.directModels);\n }\n\n async getOpenRouterModels(): Promise<Map<string, AiModelRecord>> {\n await this.ensureLoaded();\n return new Map(this.openRouterModels);\n }\n\n async resolveModel(\n input: ModelResolutionInput,\n options?: ModelResolverOptions,\n ): Promise<ModelResolutionResult> {\n await this.ensureLoaded();\n\n const primary = this.catalogForProvider(input.provider);\n const secondary = isOpenRouterProvider(input.provider)\n ? (this.directModels ?? new Map())\n : (this.openRouterModels ?? new Map());\n\n let result = this.resolver(primary, options).resolve(input);\n if (result.found && result.record) return result;\n\n if (secondary.size > 0) {\n const fallback = this.resolver(secondary, options).resolve(input);\n if (fallback.found && fallback.record) return fallback;\n if (!result.found && fallback.found) result = fallback;\n }\n\n if (!result.found) {\n result = this.resolver(this.mergedModels(), options).resolve(input);\n }\n\n return result;\n }\n\n async getModel(\n modelId: string,\n provider?: string,\n options?: ModelResolverOptions,\n ): Promise<AiModelRecord | null> {\n const result = await this.resolveModel({ model: modelId, provider }, options);\n return result.found ? result.record : null;\n }\n\n /** Clear caches and fetch catalogs again immediately. */\n async refresh(): Promise<void> {\n invalidateCatalogLoadCache(this.cacheKey);\n this.directModels = null;\n this.openRouterModels = null;\n this.loadedAt = 0;\n this.loadPromise = null;\n await this.ensureLoaded(true);\n }\n}\n"]}
@@ -1 +0,0 @@
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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-EDMCKHO6.cjs","../src/sync/modelNameResolver/constants.ts","../src/sync/modelNameResolver/normalize.ts","../src/sync/openRouterRoutingEnv.ts","../src/sync/modelNameResolver/stripVersionSuffix.ts"],"names":["stripped"],"mappings":"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AA;AACjB;AAEO,SAAS,mBAAA,CAAoB,UAAA,EAA4B;AAC9D,EAAA,OAAO,CAAA,EAAA;AACT;AAcgB;AAGR,EAAA;AACA,EAAA;AACN,EAAA;AACM,IAAA;AACN,EAAA;AACA,EAAA;AACM,IAAA;AACN,EAAA;AAEM,EAAA;AACA,EAAA;AACA,EAAA;AAEC,EAAA;AACL,IAAA;AACA,IAAA;AACA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AACF;AAOgB;AAIT,EAAA;AACD,EAAA;AACA,EAAA;AACF,IAAA;AACF,EAAA;AACO,EAAA;AACT;AHkGU;AACA;AI1KG;AACL,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACR;AAGgB;AACd,EAAA;AACM,IAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AACO,EAAA;AACT;AAMgB;AACR,EAAA;AACD,EAAA;AAED,EAAA;AACI,IAAA;AACA,IAAA;AACA,IAAA;AACAA,IAAAA;AACFA,IAAAA;AACF,MAAA;AACF,IAAA;AACA,IAAA;AACF,EAAA;AAEM,EAAA;AACC,EAAA;AACT;AJmKU;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-EDMCKHO6.cjs","sourcesContent":[null,"export const DEFAULT_CONFIDENCE_THRESHOLD = 0.6;\n\nexport const PROVIDER_NORMALISATION_MAP: Record<string, string> = {\n \"open-router\": \"openrouter\",\n or: \"openrouter\",\n oai: \"openai\",\n \"open-ai\": \"openai\",\n claude: \"anthropic\",\n ant: \"anthropic\",\n gemini: \"google\",\n gcp: \"google\",\n \"google-ai\": \"google\",\n vertex: \"google\",\n meta: \"meta-llama\",\n llama: \"meta-llama\",\n \"mistral-ai\": \"mistral\",\n \"cohere-ai\": \"cohere\",\n};\n\nexport const LOCAL_PROVIDERS = new Set([\n \"ollama\",\n \"lmstudio\",\n \"lm-studio\",\n \"localai\",\n \"local-ai\",\n \"llamacpp\",\n \"llama.cpp\",\n \"llamafile\",\n \"jan\",\n \"koboldcpp\",\n]);\n\nexport const PROVIDER_INFERENCE_MAP: Array<{\n pattern: RegExp;\n provider: string;\n notes?: string;\n}> = [\n { pattern: /^gpt-/, provider: \"openai\" },\n { pattern: /^o1($|-)/, provider: \"openai\" },\n { pattern: /^o3($|-)/, provider: \"openai\" },\n { pattern: /^o4($|-)/, provider: \"openai\" },\n { pattern: /^chatgpt-/, provider: \"openai\" },\n { pattern: /^text-davinci/, provider: \"openai\" },\n { pattern: /^dall-e/, provider: \"openai\" },\n { pattern: /^whisper/, provider: \"openai\" },\n { pattern: /^tts-/, provider: \"openai\" },\n { pattern: /^claude-/, provider: \"anthropic\" },\n { pattern: /^gemini-/, provider: \"google\" },\n { pattern: /^palm-/, provider: \"google\" },\n { pattern: /^bison/, provider: \"google\" },\n { pattern: /^llama-?[23]/, provider: \"meta-llama\" },\n { pattern: /^llama/, provider: \"meta-llama\" },\n { pattern: /^codellama/, provider: \"meta-llama\" },\n { pattern: /^mistral-/, provider: \"mistral\" },\n { pattern: /^mixtral-/, provider: \"mistral\" },\n { pattern: /^codestral/, provider: \"mistral\" },\n { pattern: /^ministral/, provider: \"mistral\" },\n { pattern: /^command-/, provider: \"cohere\" },\n { pattern: /^c4ai-/, provider: \"cohere\" },\n { pattern: /^deepseek-/, provider: \"deepseek\" },\n { pattern: /^grok-/, provider: \"x-ai\" },\n { pattern: /^qwen/, provider: \"qwen\" },\n { pattern: /^yi-/, provider: \"01-ai\" },\n { pattern: /^sonar/, provider: \"perplexity\" },\n { pattern: /^pplx-/, provider: \"perplexity\" },\n { pattern: /^titan-/, provider: \"amazon\" },\n { pattern: /^nova-/, provider: \"amazon\" },\n];\n\nexport const SHORTHAND_MAP: Record<string, string> = {\n gpt4: \"openai/gpt-4\",\n gpt4o: \"openai/gpt-4o\",\n \"gpt-4-omni\": \"openai/gpt-4o\",\n gpt4omni: \"openai/gpt-4o\",\n \"gpt4-turbo\": \"openai/gpt-4-turbo\",\n gpt4turbo: \"openai/gpt-4-turbo\",\n \"gpt4-mini\": \"openai/gpt-4o-mini\",\n \"gpt-4o-mini\": \"openai/gpt-4o-mini\",\n o1: \"openai/o1\",\n \"o1-mini\": \"openai/o1-mini\",\n o3: \"openai/o3\",\n \"o3-mini\": \"openai/o3-mini\",\n \"o4-mini\": \"openai/o4-mini\",\n \"3.5-turbo\": \"openai/gpt-3.5-turbo\",\n gpt35: \"openai/gpt-3.5-turbo\",\n gpt3: \"openai/gpt-3.5-turbo\",\n claude3: \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude-3\": \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude3-sonnet\": \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude-sonnet\": \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude-haiku\": \"anthropic/claude-3-5-haiku-20241022\",\n \"claude3-haiku\": \"anthropic/claude-3-5-haiku-20241022\",\n \"claude-opus\": \"anthropic/claude-opus-4\",\n \"claude3-opus\": \"anthropic/claude-3-opus-20240229\",\n claude4: \"anthropic/claude-opus-4\",\n \"claude4-sonnet\": \"anthropic/claude-sonnet-4\",\n \"claude4-opus\": \"anthropic/claude-opus-4\",\n sonnet: \"anthropic/claude-3-5-sonnet-20241022\",\n haiku: \"anthropic/claude-3-5-haiku-20241022\",\n opus: \"anthropic/claude-opus-4\",\n gemini: \"google/gemini-pro\",\n \"gemini-pro\": \"google/gemini-pro\",\n \"gemini-flash\": \"google/gemini-flash-1.5\",\n gemini2: \"google/gemini-2.0-flash-001\",\n \"gemini-2\": \"google/gemini-2.0-flash-001\",\n llama3: \"meta-llama/llama-3.1-8b-instruct\",\n \"llama-3\": \"meta-llama/llama-3.1-8b-instruct\",\n llama2: \"meta-llama/llama-2-13b-chat\",\n \"llama-2\": \"meta-llama/llama-2-13b-chat\",\n mistral: \"mistral/mistral-7b-instruct\",\n \"mistral-large\": \"mistral/mistral-large-latest\",\n mixtral: \"mistral/mixtral-8x7b-instruct\",\n deepseek: \"deepseek/deepseek-chat\",\n \"deepseek-r1\": \"deepseek/deepseek-r1\",\n};\n","import { PROVIDER_NORMALISATION_MAP } from \"./constants.js\";\n\nexport function normalizeString(input: string): string {\n let s = input.trim();\n s = s.replace(/\\s+/g, \" \").replace(/ /g, \"-\");\n s = s.toLowerCase();\n s = s.replace(/^\\/+|\\/+$/g, \"\");\n s = s.replace(/\\/+/g, \"/\");\n if (\n (s.startsWith('\"') && s.endsWith('\"')) ||\n (s.startsWith(\"'\") && s.endsWith(\"'\"))\n ) {\n s = s.slice(1, -1);\n }\n return s;\n}\n\nexport function normalizeProvider(provider: string | undefined): string | undefined {\n if (provider === undefined || provider === \"\") return undefined;\n const n = normalizeString(provider);\n return PROVIDER_NORMALISATION_MAP[n] ?? n;\n}\n\nexport function tokenise(s: string): string[] {\n return s.split(/[-_./]+/).filter(Boolean);\n}\n\nexport function modelSlug(modelId: string): string {\n const slash = modelId.indexOf(\"/\");\n return slash >= 0 ? modelId.slice(slash + 1) : modelId;\n}\n","import { loadDotenv } from \"@x12i/env\";\n\n/**\n * Env naming for vendor direct API keys: `{VENDOR}_API_KEY`\n * where VENDOR is the provider id in UPPER_SNAKE (hyphens → underscores).\n *\n * Examples: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `META_LLAMA_API_KEY`, `X_AI_API_KEY`\n */\nexport function providerIdToEnvKeyPrefix(providerId: string): string {\n return providerId\n .trim()\n .toLowerCase()\n .replace(/-/g, \"_\")\n .toUpperCase();\n}\n\nexport function vendorApiKeyEnvName(providerId: string): string {\n return `${providerIdToEnvKeyPrefix(providerId)}_API_KEY`;\n}\n\nexport type OpenRouterRoutingConfig = {\n /** OPENROUTER_API_KEY is set and non-empty */\n hasOpenRouterKey: boolean;\n /** USE_OPENROUTER=true or USE_OPENROUTER=1 */\n useOpenRouterExplicit: boolean;\n /** Read `{PROVIDER}_API_KEY` for a catalog provider id */\n getVendorApiKey(providerId: string): string | undefined;\n};\n\n/**\n * Load routing hints from process env and optional `.env` (via @x12/env).\n */\nexport function loadOpenRouterRoutingEnv(\n env: Record<string, string | undefined> = process.env,\n): OpenRouterRoutingConfig {\n const dotenv = loadDotenv();\n const merged: Record<string, string> = {};\n for (const [k, v] of Object.entries(dotenv)) {\n if (v !== undefined) merged[k] = v;\n }\n for (const [k, v] of Object.entries(env)) {\n if (v !== undefined) merged[k] = v;\n }\n\n const openRouterKey = merged.OPENROUTER_API_KEY?.trim();\n const useRaw = merged.USE_OPENROUTER?.trim().toLowerCase();\n const useOpenRouterExplicit = useRaw === \"true\" || useRaw === \"1\";\n\n return {\n hasOpenRouterKey: Boolean(openRouterKey),\n useOpenRouterExplicit,\n getVendorApiKey(providerId: string) {\n const name = vendorApiKeyEnvName(providerId);\n const val = merged[name]?.trim();\n return val || undefined;\n },\n };\n}\n\n/**\n * Default route via OpenRouter when:\n * 1. OPENROUTER_API_KEY is set AND USE_OPENROUTER=true|1, or\n * 2. OPENROUTER_API_KEY is set AND the vendor's `{VENDOR}_API_KEY` is missing.\n */\nexport function shouldDefaultRouteViaOpenRouter(\n providerId: string | undefined,\n config: OpenRouterRoutingConfig,\n): boolean {\n if (!config.hasOpenRouterKey) return false;\n if (config.useOpenRouterExplicit) return true;\n if (providerId && providerId !== \"openrouter\") {\n return !config.getVendorApiKey(providerId);\n }\n return false;\n}\n","import { normalizeString } from \"./normalize.js\";\n\n/** Patterns stripped when resolving versioned runtime model ids to catalog entries. */\nexport const VERSION_STRIP_PATTERNS: ReadonlyArray<{ re: RegExp; label: string }> = [\n { re: /-\\d{4}-\\d{2}-\\d{2}$/, label: \"date YYYY-MM-DD\" },\n { re: /-\\d{8}$/, label: \"date YYYYMMDD\" },\n { re: /-v\\d+$/, label: \"version -vN\" },\n { re: /-\\d+\\.\\d+\\.\\d+$/, label: \"semver\" },\n { re: /:\\d+[a-z]?$/i, label: \"colon version\" },\n { re: /-\\d{4,}$/, label: \"build number\" },\n { re: /@\\d+$/, label: \"epoch @NNNN\" },\n];\n\n/** Strip version/date suffix from a bare slug (no `provider/` prefix). */\nexport function stripModelSlugSuffix(slug: string): string | null {\n for (const { re } of VERSION_STRIP_PATTERNS) {\n if (re.test(slug)) {\n return slug.replace(re, \"\");\n }\n }\n return null;\n}\n\n/**\n * Strip a version/date suffix from a model id (`gpt-5.5-2026-04-23` → `gpt-5.5`,\n * `openai/gpt-4o-2024-08-06` → `openai/gpt-4o`). Returns null when nothing was stripped.\n */\nexport function stripModelVersionSuffix(model: string): string | null {\n const normalized = normalizeString(model);\n if (!normalized) return null;\n\n if (normalized.includes(\"/\")) {\n const slash = normalized.indexOf(\"/\");\n const prefix = normalized.slice(0, slash);\n const slug = normalized.slice(slash + 1);\n const stripped = stripModelSlugSuffix(slug);\n if (stripped && stripped !== slug) {\n return `${prefix}/${stripped}`;\n }\n return null;\n }\n\n const stripped = stripModelSlugSuffix(normalized);\n return stripped && stripped !== normalized ? stripped : null;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sync/modelNameResolver/catalogIndexes.ts","../src/sync/modelNameResolver/ModelNameResolver.ts","../src/models/reasoningModel.ts"],"sourcesContent":["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"],"mappings":"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","names":[]}