@x12i/ai-tools 1.0.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +146 -204
  3. package/dist/AiModelsCatalogClient-B5FMI9gj.d.cts +58 -0
  4. package/dist/AiModelsCatalogClient-CPPNI6Ry.d.ts +58 -0
  5. package/dist/aliases/index.cjs +4 -3
  6. package/dist/aliases/index.cjs.map +1 -1
  7. package/dist/aliases/index.d.cts +3 -5
  8. package/dist/aliases/index.d.ts +3 -5
  9. package/dist/aliases/index.js +2 -2
  10. package/dist/catalog/index.cjs +18 -9
  11. package/dist/catalog/index.cjs.map +1 -1
  12. package/dist/catalog/index.d.cts +13 -100
  13. package/dist/catalog/index.d.ts +13 -100
  14. package/dist/catalog/index.js +31 -23
  15. package/dist/{chunk-AJEKEWWB.js → chunk-2PTCWPHV.js} +17 -3
  16. package/dist/chunk-2PTCWPHV.js.map +1 -0
  17. package/dist/chunk-56R4XA2S.js +1 -0
  18. package/dist/chunk-5GUKLOEK.cjs +1 -0
  19. package/dist/chunk-5GUKLOEK.cjs.map +1 -0
  20. package/dist/chunk-5XAAMBDO.cjs +1988 -0
  21. package/dist/chunk-5XAAMBDO.cjs.map +1 -0
  22. package/dist/chunk-6BQBKROR.js +95 -0
  23. package/dist/chunk-6BQBKROR.js.map +1 -0
  24. package/dist/chunk-AB5GNXJ4.js +46 -0
  25. package/dist/chunk-AB5GNXJ4.js.map +1 -0
  26. package/dist/{chunk-O2A6OVEH.js → chunk-ANVONYJF.js} +2 -2
  27. package/dist/{chunk-O2A6OVEH.js.map → chunk-ANVONYJF.js.map} +1 -1
  28. package/dist/chunk-B3V2EHRY.js +225 -0
  29. package/dist/chunk-B3V2EHRY.js.map +1 -0
  30. package/dist/{chunk-QWAX7VQO.cjs → chunk-BAHBDADJ.cjs} +11 -11
  31. package/dist/{chunk-QWAX7VQO.cjs.map → chunk-BAHBDADJ.cjs.map} +1 -1
  32. package/dist/{chunk-TF4L2NEC.cjs → chunk-DXZOL3VN.cjs} +62 -313
  33. package/dist/chunk-DXZOL3VN.cjs.map +1 -0
  34. package/dist/chunk-EDMCKHO6.cjs +225 -0
  35. package/dist/chunk-EDMCKHO6.cjs.map +1 -0
  36. package/dist/{chunk-DJ5SWJDY.js → chunk-EYHMQVAL.js} +48 -299
  37. package/dist/chunk-EYHMQVAL.js.map +1 -0
  38. package/dist/chunk-GS7T56RP.cjs +8 -0
  39. package/dist/chunk-GS7T56RP.cjs.map +1 -0
  40. package/dist/chunk-NF2SKQR7.cjs +973 -0
  41. package/dist/chunk-NF2SKQR7.cjs.map +1 -0
  42. package/dist/chunk-OPN6BGNH.js +1985 -0
  43. package/dist/chunk-OPN6BGNH.js.map +1 -0
  44. package/dist/{chunk-7Q742NI3.cjs → chunk-PADNCGZB.cjs} +17 -3
  45. package/dist/chunk-PADNCGZB.cjs.map +1 -0
  46. package/dist/chunk-PRCICORG.cjs +95 -0
  47. package/dist/chunk-PRCICORG.cjs.map +1 -0
  48. package/dist/{chunk-6QGDZTGH.js → chunk-SIH4GPV4.js} +4 -29
  49. package/dist/chunk-SIH4GPV4.js.map +1 -0
  50. package/dist/chunk-U2YDDUVP.js +970 -0
  51. package/dist/chunk-U2YDDUVP.js.map +1 -0
  52. package/dist/{chunk-4NAY6HRP.js → chunk-VJHLO2R3.js} +7 -58
  53. package/dist/chunk-VJHLO2R3.js.map +1 -0
  54. package/dist/chunk-XAWBTX3N.cjs +46 -0
  55. package/dist/chunk-XAWBTX3N.cjs.map +1 -0
  56. package/dist/{chunk-AV6OE2YQ.cjs → chunk-XOKUDUUI.cjs} +14 -39
  57. package/dist/chunk-XOKUDUUI.cjs.map +1 -0
  58. package/dist/chunk-YQDSN6R6.cjs +86 -0
  59. package/dist/chunk-YQDSN6R6.cjs.map +1 -0
  60. package/dist/cli/index.cjs +59 -201
  61. package/dist/cli/index.cjs.map +1 -1
  62. package/dist/cli/index.js +53 -198
  63. package/dist/cli/index.js.map +1 -1
  64. package/dist/cost/index.cjs +19 -3
  65. package/dist/cost/index.cjs.map +1 -1
  66. package/dist/cost/index.d.cts +10 -50
  67. package/dist/cost/index.d.ts +10 -50
  68. package/dist/cost/index.js +18 -3
  69. package/dist/index.cjs +24 -16
  70. package/dist/index.cjs.map +1 -1
  71. package/dist/index.d.cts +13 -13
  72. package/dist/index.d.ts +13 -13
  73. package/dist/index.js +44 -37
  74. package/dist/modelCache-BzRn6t_C.d.ts +113 -0
  75. package/dist/modelCache-CJftI-Ko.d.cts +113 -0
  76. package/dist/{modelNameResolver-DqFt7g6W.d.ts → modelNameResolver-5XkBMctP.d.ts} +2 -6
  77. package/dist/{modelNameResolver-D9V_GfUK.d.cts → modelNameResolver-C5CSTGFF.d.cts} +2 -6
  78. package/dist/models/index.cjs +9 -6
  79. package/dist/models/index.cjs.map +1 -1
  80. package/dist/models/index.d.cts +9 -31
  81. package/dist/models/index.d.ts +9 -31
  82. package/dist/models/index.js +9 -7
  83. package/dist/resolveUsageModel-BFwf80Hz.d.ts +140 -0
  84. package/dist/resolveUsageModel-C_YmGR1M.d.cts +140 -0
  85. package/dist/sync/index.cjs +7 -9
  86. package/dist/sync/index.cjs.map +1 -1
  87. package/dist/sync/index.d.cts +3 -8
  88. package/dist/sync/index.d.ts +3 -8
  89. package/dist/sync/index.js +8 -11
  90. package/dist/toolbox/index.cjs +1 -0
  91. package/dist/toolbox/index.cjs.map +1 -1
  92. package/dist/types-BrzJWsTU.d.cts +277 -0
  93. package/dist/types-BrzJWsTU.d.ts +277 -0
  94. package/package.json +9 -20
  95. package/src/data/models-catalog.json +670 -0
  96. package/src/data/openrouter-models-catalog.json +857 -0
  97. package/dist/AiModelsCatalogClient-4RF5BCDL.cjs +0 -9
  98. package/dist/AiModelsCatalogClient-4RF5BCDL.cjs.map +0 -1
  99. package/dist/AiModelsCatalogClient-CNeqFiFs.d.cts +0 -30
  100. package/dist/AiModelsCatalogClient-NUF3CBLW.js +0 -9
  101. package/dist/AiModelsCatalogClient-nwFoEaqL.d.ts +0 -30
  102. package/dist/catalox/index.cjs +0 -21
  103. package/dist/catalox/index.cjs.map +0 -1
  104. package/dist/catalox/index.d.cts +0 -11
  105. package/dist/catalox/index.d.ts +0 -11
  106. package/dist/catalox/index.js +0 -21
  107. package/dist/catalox/index.js.map +0 -1
  108. package/dist/chunk-4NAY6HRP.js.map +0 -1
  109. package/dist/chunk-6QGDZTGH.js.map +0 -1
  110. package/dist/chunk-7Q742NI3.cjs.map +0 -1
  111. package/dist/chunk-AJEKEWWB.js.map +0 -1
  112. package/dist/chunk-AV6OE2YQ.cjs.map +0 -1
  113. package/dist/chunk-C3H7RTFR.cjs +0 -1
  114. package/dist/chunk-C3H7RTFR.cjs.map +0 -1
  115. package/dist/chunk-DJ5SWJDY.js.map +0 -1
  116. package/dist/chunk-DKHGWHXP.cjs +0 -169
  117. package/dist/chunk-DKHGWHXP.cjs.map +0 -1
  118. package/dist/chunk-F2F4UEFD.cjs +0 -75
  119. package/dist/chunk-F2F4UEFD.cjs.map +0 -1
  120. package/dist/chunk-FGP3QXWL.cjs +0 -163
  121. package/dist/chunk-FGP3QXWL.cjs.map +0 -1
  122. package/dist/chunk-G2G4KSC5.js +0 -30
  123. package/dist/chunk-G2G4KSC5.js.map +0 -1
  124. package/dist/chunk-HN6UAQAE.cjs +0 -83
  125. package/dist/chunk-HN6UAQAE.cjs.map +0 -1
  126. package/dist/chunk-HS74X2OJ.cjs +0 -172
  127. package/dist/chunk-HS74X2OJ.cjs.map +0 -1
  128. package/dist/chunk-HYGXZY25.js +0 -163
  129. package/dist/chunk-HYGXZY25.js.map +0 -1
  130. package/dist/chunk-KQOALKKX.js +0 -75
  131. package/dist/chunk-KQOALKKX.js.map +0 -1
  132. package/dist/chunk-LYOU7CA2.cjs +0 -30
  133. package/dist/chunk-LYOU7CA2.cjs.map +0 -1
  134. package/dist/chunk-M5TMA73F.js +0 -1
  135. package/dist/chunk-M5TMA73F.js.map +0 -1
  136. package/dist/chunk-MX3AMQFC.js +0 -172
  137. package/dist/chunk-MX3AMQFC.js.map +0 -1
  138. package/dist/chunk-QCRLKVB3.cjs +0 -137
  139. package/dist/chunk-QCRLKVB3.cjs.map +0 -1
  140. package/dist/chunk-TF4L2NEC.cjs.map +0 -1
  141. package/dist/chunk-VRFVF5RH.js +0 -169
  142. package/dist/chunk-VRFVF5RH.js.map +0 -1
  143. package/dist/chunk-YHO57D2V.js +0 -83
  144. package/dist/chunk-YHO57D2V.js.map +0 -1
  145. package/dist/syncAiModelsCatalog-CnXRLm2c.d.cts +0 -32
  146. package/dist/syncAiModelsCatalog-DpkN_w7S.d.ts +0 -32
  147. package/dist/types-BYXnCvKx.d.cts +0 -137
  148. package/dist/types-BYXnCvKx.d.ts +0 -137
  149. package/dist/types-CX6QFNNy.d.cts +0 -144
  150. package/dist/types-CuiPDcVs.d.ts +0 -144
  151. package/dist/upsertAiModelRecord-C831wOIF.d.ts +0 -35
  152. package/dist/upsertAiModelRecord-CjY-sny0.d.cts +0 -35
  153. /package/dist/{AiModelsCatalogClient-NUF3CBLW.js.map → chunk-56R4XA2S.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../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"],"sourcesContent":["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"],"mappings":"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","names":[]}
@@ -13,7 +13,7 @@ var ModelNotFoundError = class extends AiToolsError {
13
13
  constructor(modelId) {
14
14
  super(
15
15
  "MODEL_NOT_FOUND",
16
- `Model not found: "${modelId}". Run "ai-tools sync" to populate the catalog.`
16
+ `Model not found: "${modelId}". Run "npx ai-tools catalog refresh" or verify the model id against the catalog.`
17
17
  );
18
18
  this.name = "ModelNotFoundError";
19
19
  }
@@ -90,6 +90,20 @@ var CostCalculationError = class extends AiToolsError {
90
90
  this.name = "CostCalculationError";
91
91
  }
92
92
  };
93
+ var UnknownModelCostError = class extends AiToolsError {
94
+ constructor(model, provider) {
95
+ super(
96
+ "COST_UNKNOWN_MODEL",
97
+ `Cannot price unknown model "${model}" (provider: "${provider}"). Refresh catalogs with "npx ai-tools catalog refresh", use a known ai-profile name, or set throwOnUnknownModel: false.`
98
+ );
99
+ this.model = model;
100
+ this.provider = provider;
101
+ this.name = "UnknownModelCostError";
102
+ }
103
+
104
+
105
+ };
106
+
93
107
 
94
108
 
95
109
 
@@ -102,5 +116,5 @@ var CostCalculationError = class extends AiToolsError {
102
116
 
103
117
 
104
118
 
105
- exports.AiToolsError = AiToolsError; exports.ModelNotFoundError = ModelNotFoundError; exports.ModelResolutionError = ModelResolutionError; exports.AliasNotFoundError = AliasNotFoundError; exports.AliasInvalidNameError = AliasInvalidNameError; exports.AliasConflictError = AliasConflictError; exports.AliasFileParseError = AliasFileParseError; exports.AliasFileWriteError = AliasFileWriteError; exports.SyncError = SyncError; exports.CostCalculationError = CostCalculationError;
106
- //# sourceMappingURL=chunk-7Q742NI3.cjs.map
119
+ exports.AiToolsError = AiToolsError; exports.ModelNotFoundError = ModelNotFoundError; exports.ModelResolutionError = ModelResolutionError; exports.AliasNotFoundError = AliasNotFoundError; exports.AliasInvalidNameError = AliasInvalidNameError; exports.AliasConflictError = AliasConflictError; exports.AliasFileParseError = AliasFileParseError; exports.AliasFileWriteError = AliasFileWriteError; exports.SyncError = SyncError; exports.CostCalculationError = CostCalculationError; exports.UnknownModelCostError = UnknownModelCostError;
120
+ //# sourceMappingURL=chunk-PADNCGZB.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-PADNCGZB.cjs","../src/errors.ts"],"names":[],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-PADNCGZB.cjs","sourcesContent":[null,"import type {\n ModelResolutionInput,\n ModelResolutionNotFound,\n} from \"./sync/modelNameResolver/types.js\";\n\nexport type AiToolsErrorCode =\n | \"MODEL_NOT_FOUND\"\n | \"SYNC_FETCH_FAILED\"\n | \"SYNC_UPSERT_FAILED\"\n | \"COST_CALCULATION_FAILED\"\n | \"COST_UNKNOWN_MODEL\"\n | \"INVALID_USAGE_INPUT\"\n | \"OPENROUTER_AUTH_FAILED\"\n | \"OPENROUTER_MODELS_FETCH_FAILED\"\n | \"CACHE_READ_ERROR\"\n | \"ALIAS_NOT_FOUND\"\n | \"ALIAS_INVALID_NAME\"\n | \"ALIAS_CONFLICT\"\n | \"ALIAS_FILE_PARSE_ERROR\"\n | \"ALIAS_FILE_WRITE_ERROR\";\n\nexport class AiToolsError extends Error {\n constructor(\n public readonly code: AiToolsErrorCode,\n message: string,\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = \"AiToolsError\";\n }\n}\n\nexport class ModelNotFoundError extends AiToolsError {\n constructor(modelId: string) {\n super(\n \"MODEL_NOT_FOUND\",\n `Model not found: \"${modelId}\". Run \"npx ai-tools catalog refresh\" or verify the model id against the catalog.`,\n );\n this.name = \"ModelNotFoundError\";\n }\n}\n\nexport class ModelResolutionError extends AiToolsError {\n constructor(\n public readonly input: ModelResolutionInput,\n public readonly result: ModelResolutionNotFound,\n ) {\n super(\n \"MODEL_NOT_FOUND\",\n `Could not resolve model \"${input.model}\" (provider: \"${input.provider ?? \"unspecified\"}\"). ` +\n result.reason +\n (result.bestRejectedCandidate\n ? ` Best candidate was \"${result.bestRejectedCandidate.modelId}\" (confidence ${result.bestRejectedCandidate.confidence.toFixed(2)}).`\n : \"\"),\n );\n this.name = \"ModelResolutionError\";\n }\n}\n\nexport class AliasNotFoundError extends AiToolsError {\n constructor(aliasName: string) {\n super(\n \"ALIAS_NOT_FOUND\",\n `Alias not found: \"${aliasName}\". Run \"ai-tools alias list\" to see defined aliases.`,\n );\n this.name = \"AliasNotFoundError\";\n }\n}\n\nexport class AliasInvalidNameError extends AiToolsError {\n constructor(aliasName: string) {\n super(\n \"ALIAS_INVALID_NAME\",\n `Invalid alias name: \"${aliasName}\". Names must match /^[a-z0-9][a-z0-9-]*$/`,\n );\n this.name = \"AliasInvalidNameError\";\n }\n}\n\nexport class AliasConflictError extends AiToolsError {\n constructor(aliasName: string) {\n super(\n \"ALIAS_CONFLICT\",\n `Alias \"${aliasName}\" already exists. Use --force to overwrite.`,\n );\n this.name = \"AliasConflictError\";\n }\n}\n\nexport class AliasFileParseError extends AiToolsError {\n constructor(path: string, cause?: unknown) {\n super(\n \"ALIAS_FILE_PARSE_ERROR\",\n `Failed to parse aliases file at \"${path}\". Check JSON syntax.`,\n cause,\n );\n this.name = \"AliasFileParseError\";\n }\n}\n\nexport class AliasFileWriteError extends AiToolsError {\n constructor(path: string, cause?: unknown) {\n super(\n \"ALIAS_FILE_WRITE_ERROR\",\n `Failed to write aliases file at \"${path}\".`,\n cause,\n );\n this.name = \"AliasFileWriteError\";\n }\n}\n\nexport class SyncError extends AiToolsError {\n constructor(code: Extract<AiToolsErrorCode, \"SYNC_FETCH_FAILED\" | \"SYNC_UPSERT_FAILED\" | \"OPENROUTER_AUTH_FAILED\" | \"OPENROUTER_MODELS_FETCH_FAILED\">, message: string, cause?: unknown) {\n super(code, message, cause);\n this.name = \"SyncError\";\n }\n}\n\nexport class CostCalculationError extends AiToolsError {\n constructor(message: string, cause?: unknown) {\n super(\"COST_CALCULATION_FAILED\", message, cause);\n this.name = \"CostCalculationError\";\n }\n}\n\nexport class UnknownModelCostError extends AiToolsError {\n constructor(\n public readonly model: string,\n public readonly provider: string,\n ) {\n super(\n \"COST_UNKNOWN_MODEL\",\n `Cannot price unknown model \"${model}\" (provider: \"${provider}\"). ` +\n 'Refresh catalogs with \"npx ai-tools catalog refresh\", use a known ai-profile name, or set throwOnUnknownModel: false.',\n );\n this.name = \"UnknownModelCostError\";\n }\n}\n"]}
@@ -0,0 +1,95 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+ var _chunkXOKUDUUIcjs = require('./chunk-XOKUDUUI.cjs');
4
+
5
+
6
+ var _chunkDXZOL3VNcjs = require('./chunk-DXZOL3VN.cjs');
7
+
8
+
9
+ var _chunkPADNCGZBcjs = require('./chunk-PADNCGZB.cjs');
10
+
11
+ // src/sync/OpenRouterSyncProvider.ts
12
+ function buildFetchHeaders(apiKey) {
13
+ const headers = { Accept: "application/json" };
14
+ if (_optionalChain([apiKey, 'optionalAccess', _ => _.trim, 'call', _2 => _2()])) headers.Authorization = `Bearer ${apiKey.trim()}`;
15
+ return headers;
16
+ }
17
+ function buildModelsUrl(baseUrl, query) {
18
+ const url = new URL(`${baseUrl.replace(/\/$/, "")}/models`);
19
+ const q = { output_modalities: "all", ...query };
20
+ for (const [key, value] of Object.entries(q)) {
21
+ if (value !== void 0 && value !== "") url.searchParams.set(key, value);
22
+ }
23
+ return url.toString();
24
+ }
25
+ var OpenRouterSyncProvider = class {
26
+
27
+
28
+
29
+ constructor(options = {}) {
30
+ this.apiKey = options.apiKey;
31
+ this.baseUrl = _nullishCoalesce(options.baseUrl, () => ( "https://openrouter.ai/api/v1"));
32
+ this.query = _nullishCoalesce(options.query, () => ( { output_modalities: "all" }));
33
+ }
34
+ /**
35
+ * Fetches the full OpenRouter model catalog (public, no API key required).
36
+ * @see https://openrouter.ai/api/v1/models
37
+ */
38
+ async fetchModels() {
39
+ const url = buildModelsUrl(this.baseUrl, this.query);
40
+ let response;
41
+ try {
42
+ response = await fetch(url, { headers: buildFetchHeaders(this.apiKey) });
43
+ } catch (cause) {
44
+ throw new (0, _chunkPADNCGZBcjs.SyncError)("OPENROUTER_MODELS_FETCH_FAILED", `Failed to fetch OpenRouter models from ${url}`, cause);
45
+ }
46
+ if (response.status === 401 || response.status === 403) {
47
+ throw new (0, _chunkPADNCGZBcjs.SyncError)(
48
+ "OPENROUTER_AUTH_FAILED",
49
+ this.apiKey ? "OpenRouter API key is invalid or unauthorized." : "OpenRouter returned unauthorized \u2014 remove OPENROUTER_API_KEY to use the public models endpoint."
50
+ );
51
+ }
52
+ if (!response.ok) {
53
+ const body = await response.text().catch(() => "");
54
+ throw new (0, _chunkPADNCGZBcjs.SyncError)(
55
+ "OPENROUTER_MODELS_FETCH_FAILED",
56
+ `OpenRouter models fetch failed (${response.status}): ${body.slice(0, 200)}`
57
+ );
58
+ }
59
+ const json = await response.json();
60
+ const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
61
+ return (_nullishCoalesce(json.data, () => ( []))).map((row) => _chunkXOKUDUUIcjs.normalizeOpenRouterModel.call(void 0, row, syncedAt));
62
+ }
63
+ /** Build the URL used for the last fetch pattern (for debugging). */
64
+ getModelsUrl() {
65
+ return buildModelsUrl(this.baseUrl, this.query);
66
+ }
67
+ };
68
+
69
+ // src/sync/modelNameResolver.ts
70
+ function createModelNameResolver(catalog, options) {
71
+ return new (0, _chunkDXZOL3VNcjs.ModelNameResolver)(catalog, options);
72
+ }
73
+ function resolveModel(input, models, aliasRegistry, provider) {
74
+ const resolver = new (0, _chunkDXZOL3VNcjs.ModelNameResolver)(models, { aliasRegistry });
75
+ const result = resolver.resolve({ model: input, provider });
76
+ if (!result.found || !result.record) return null;
77
+ return {
78
+ catalogModel: result.record,
79
+ matchedAlias: result.modelId,
80
+ routedViaOpenRouter: result.routedViaOpenRouter
81
+ };
82
+ }
83
+ function isRoutedViaOpenRouter(provider, model, matchedKey) {
84
+ if (provider === "openrouter") return true;
85
+ if (provider && provider !== "openrouter") return false;
86
+ return model.modelId.includes("/") && matchedKey.includes("/");
87
+ }
88
+
89
+
90
+
91
+
92
+
93
+
94
+ exports.OpenRouterSyncProvider = OpenRouterSyncProvider; exports.createModelNameResolver = createModelNameResolver; exports.resolveModel = resolveModel; exports.isRoutedViaOpenRouter = isRoutedViaOpenRouter;
95
+ //# sourceMappingURL=chunk-PRCICORG.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-PRCICORG.cjs","../src/sync/OpenRouterSyncProvider.ts","../src/sync/modelNameResolver.ts"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACMA,SAAS,iBAAA,CAAkB,MAAA,EAAyC;AAClE,EAAA,MAAM,QAAA,EAAkC,EAAE,MAAA,EAAQ,mBAAmB,CAAA;AACrE,EAAA,GAAA,iBAAI,MAAA,2BAAQ,IAAA,mBAAK,GAAA,EAAG,OAAA,CAAQ,cAAA,EAAgB,CAAA,OAAA,EAAU,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,CAAA;AAC5D,EAAA;AACT;AAEgF;AACpB,EAAA;AACX,EAAA;AACD,EAAA;AACuB,IAAA;AACrE,EAAA;AACoB,EAAA;AACtB;AAEoC;AACjB,EAAA;AACA,EAAA;AACA,EAAA;AAEwC,EAAA;AACjC,IAAA;AACY,IAAA;AACuB,IAAA;AAC3D,EAAA;AAAA;AAAA;AAAA;AAAA;AAM8C,EAAA;AACO,IAAA;AAC/C,IAAA;AAEA,IAAA;AAC4D,MAAA;AAChD,IAAA;AACwC,MAAA;AACxD,IAAA;AAEwD,IAAA;AAC5C,MAAA;AACR,QAAA;AAEI,QAAA;AAEN,MAAA;AACF,IAAA;AAEkB,IAAA;AACiC,MAAA;AACvC,MAAA;AACR,QAAA;AAC6D,QAAA;AAC/D,MAAA;AACF,IAAA;AAEkC,IAAA;AACM,IAAA;AACuB,IAAA;AACjE,EAAA;AAAA;AAGuB,EAAA;AACyB,IAAA;AAChD,EAAA;AACF;ADfsE;AACA;AE1CjD;AAC0B,EAAA;AAC/C;AAQwB;AAC0C,EAAA;AACN,EAAA;AACd,EAAA;AACrC,EAAA;AACgB,IAAA;AACA,IAAA;AACO,IAAA;AAC9B,EAAA;AACF;AAMW;AAC6B,EAAA;AACY,EAAA;AACW,EAAA;AAC/D;AFgCsE;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-PRCICORG.cjs","sourcesContent":[null,"import { SyncError } from \"../errors.js\";\nimport { normalizeOpenRouterModel } from \"../models/normalizeOpenRouterModel.js\";\nimport type { AiModelRecord } from \"../models/types.js\";\nimport type {\n OpenRouterModelsQuery,\n OpenRouterModelsResponse,\n} from \"../models/openrouter.types.js\";\n\nexport type OpenRouterSyncProviderOptions = {\n /** Optional — public GET /models needs no key. */\n apiKey?: string;\n baseUrl?: string;\n /** Query params passed to OpenRouter (default: all modalities). */\n query?: OpenRouterModelsQuery;\n};\n\nfunction buildFetchHeaders(apiKey?: string): Record<string, string> {\n const headers: Record<string, string> = { Accept: \"application/json\" };\n if (apiKey?.trim()) headers.Authorization = `Bearer ${apiKey.trim()}`;\n return headers;\n}\n\nfunction buildModelsUrl(baseUrl: string, query?: OpenRouterModelsQuery): string {\n const url = new URL(`${baseUrl.replace(/\\/$/, \"\")}/models`);\n const q = { output_modalities: \"all\", ...query };\n for (const [key, value] of Object.entries(q)) {\n if (value !== undefined && value !== \"\") url.searchParams.set(key, value);\n }\n return url.toString();\n}\n\nexport class OpenRouterSyncProvider {\n private readonly apiKey?: string;\n private readonly baseUrl: string;\n private readonly query?: OpenRouterModelsQuery;\n\n constructor(options: OpenRouterSyncProviderOptions = {}) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl ?? \"https://openrouter.ai/api/v1\";\n this.query = options.query ?? { output_modalities: \"all\" };\n }\n\n /**\n * Fetches the full OpenRouter model catalog (public, no API key required).\n * @see https://openrouter.ai/api/v1/models\n */\n async fetchModels(): Promise<AiModelRecord[]> {\n const url = buildModelsUrl(this.baseUrl, this.query);\n let response: Response;\n\n try {\n response = await fetch(url, { headers: buildFetchHeaders(this.apiKey) });\n } catch (cause) {\n throw new SyncError(\"OPENROUTER_MODELS_FETCH_FAILED\", `Failed to fetch OpenRouter models from ${url}`, cause);\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new SyncError(\n \"OPENROUTER_AUTH_FAILED\",\n this.apiKey\n ? \"OpenRouter API key is invalid or unauthorized.\"\n : \"OpenRouter returned unauthorized — remove OPENROUTER_API_KEY to use the public models endpoint.\",\n );\n }\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new SyncError(\n \"OPENROUTER_MODELS_FETCH_FAILED\",\n `OpenRouter models fetch failed (${response.status}): ${body.slice(0, 200)}`,\n );\n }\n\n const json = (await response.json()) as OpenRouterModelsResponse;\n const syncedAt = new Date().toISOString();\n return (json.data ?? []).map((row) => normalizeOpenRouterModel(row, syncedAt));\n }\n\n /** Build the URL used for the last fetch pattern (for debugging). */\n getModelsUrl(): string {\n return buildModelsUrl(this.baseUrl, this.query);\n }\n}\n","import type { AliasRegistry } from \"../aliases/AliasRegistry.js\";\nimport type { AiModelRecord } from \"../models/types.js\";\nimport { ModelNameResolver } from \"./modelNameResolver/ModelNameResolver.js\";\nimport type {\n ModelResolutionInput,\n ModelResolutionResult,\n ModelResolutionSuccess,\n ModelResolverOptions,\n ResolvedModel,\n} from \"./modelNameResolver/types.js\";\n\nexport { ModelNameResolver } from \"./modelNameResolver/ModelNameResolver.js\";\nexport { buildCatalogIndexes } from \"./modelNameResolver/catalogIndexes.js\";\nexport * from \"./modelNameResolver/types.js\";\nexport {\n loadOpenRouterRoutingEnv,\n shouldDefaultRouteViaOpenRouter,\n providerIdToEnvKeyPrefix,\n vendorApiKeyEnvName,\n} from \"./openRouterRoutingEnv.js\";\nexport type { OpenRouterRoutingConfig } from \"./openRouterRoutingEnv.js\";\nexport { normalizeString, normalizeProvider } from \"./modelNameResolver/normalize.js\";\n\nexport function createModelNameResolver(\n catalog: Map<string, AiModelRecord>,\n options?: ModelResolverOptions,\n): ModelNameResolver {\n return new ModelNameResolver(catalog, options);\n}\n\n/** Resolve a model string; returns catalog record only (no resolution metadata). */\nexport function resolveModel(\n input: string,\n models: Map<string, AiModelRecord>,\n aliasRegistry?: AliasRegistry,\n provider?: string,\n): ResolvedModel | null {\n const resolver = new ModelNameResolver(models, { aliasRegistry });\n const result = resolver.resolve({ model: input, provider });\n if (!result.found || !result.record) return null;\n return {\n catalogModel: result.record,\n matchedAlias: result.modelId,\n routedViaOpenRouter: result.routedViaOpenRouter,\n };\n}\n\nexport function isRoutedViaOpenRouter(\n provider: string | undefined,\n model: AiModelRecord,\n matchedKey: string,\n): boolean {\n if (provider === \"openrouter\") return true;\n if (provider && provider !== \"openrouter\") return false;\n return model.modelId.includes(\"/\") && matchedKey.includes(\"/\");\n}\n\nexport type {\n ModelResolutionInput,\n ModelResolutionResult,\n ModelResolutionSuccess,\n ModelResolverOptions,\n};\n"]}
@@ -1,26 +1,6 @@
1
- // src/models/reasoningModel.ts
2
- var REASONING_SUPPORTED_PARAMETERS = ["reasoning", "include_reasoning"];
3
- function supportsReasoningParameter(model) {
4
- return model.supportedParameters.some(
5
- (p) => REASONING_SUPPORTED_PARAMETERS.includes(p)
6
- );
7
- }
8
- function hasReasoningPricing(model) {
9
- const raw = model.openRouterPricing?.internal_reasoning;
10
- if (raw !== void 0 && raw !== null && String(raw).trim() !== "") {
11
- return true;
12
- }
13
- return model.pricing.reasoningUsdPerToken !== void 0;
14
- }
15
- function computeSupportsReasoning(model) {
16
- return supportsReasoningParameter(model) || hasReasoningPricing(model);
17
- }
18
- function isReasoningModel(model) {
19
- if (model.supportsReasoning !== void 0) {
20
- return model.supportsReasoning;
21
- }
22
- return computeSupportsReasoning(model);
23
- }
1
+ import {
2
+ computeSupportsReasoning
3
+ } from "./chunk-EYHMQVAL.js";
24
4
 
25
5
  // src/models/normalizeOpenRouterModel.ts
26
6
  function parsePrice(value) {
@@ -116,12 +96,7 @@ function normalizeOpenRouterModel(row, syncedAt) {
116
96
  }
117
97
 
118
98
  export {
119
- REASONING_SUPPORTED_PARAMETERS,
120
- supportsReasoningParameter,
121
- hasReasoningPricing,
122
- computeSupportsReasoning,
123
- isReasoningModel,
124
99
  extractProviderId,
125
100
  normalizeOpenRouterModel
126
101
  };
127
- //# sourceMappingURL=chunk-6QGDZTGH.js.map
102
+ //# sourceMappingURL=chunk-SIH4GPV4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/models/normalizeOpenRouterModel.ts"],"sourcesContent":["import { computeSupportsReasoning } from \"./reasoningModel.js\";\nimport type { AiModelPricing, AiModelRecord } from \"./types.js\";\nimport type { OpenRouterModelApi } from \"./openrouter.types.js\";\n\nfunction parsePrice(value: string | number | undefined): number {\n if (value === undefined || value === null || value === \"\") return 0;\n const n = typeof value === \"number\" ? value : Number.parseFloat(String(value));\n return Number.isFinite(n) ? n : 0;\n}\n\nexport function extractProviderId(modelId: string): string {\n const slash = modelId.indexOf(\"/\");\n if (slash > 0) return modelId.slice(0, slash);\n return \"other\";\n}\n\nfunction buildAliases(modelId: string, name?: string): string[] {\n const aliases = new Set<string>();\n if (name) aliases.add(name);\n const slash = modelId.indexOf(\"/\");\n if (slash > 0) {\n const direct = modelId.slice(slash + 1);\n aliases.add(direct);\n const base = direct.replace(/-\\d{4}-\\d{2}-\\d{2}$/, \"\").replace(/-\\d{8}$/, \"\");\n if (base !== direct) aliases.add(base);\n }\n return [...aliases];\n}\n\nfunction normalizePricing(raw: OpenRouterModelApi[\"pricing\"]): AiModelPricing {\n return {\n promptUsdPerToken: parsePrice(raw.prompt),\n completionUsdPerToken: parsePrice(raw.completion),\n imageUsdPerUnit: parsePrice(raw.image),\n requestUsdPerRequest: parsePrice(raw.request),\n cacheReadUsdPerToken: raw.input_cache_read\n ? parsePrice(raw.input_cache_read)\n : undefined,\n cacheWriteUsdPerToken: raw.input_cache_write\n ? parsePrice(raw.input_cache_write)\n : undefined,\n reasoningUsdPerToken: raw.internal_reasoning\n ? parsePrice(raw.internal_reasoning)\n : undefined,\n webSearchUsdPerRequest: raw.web_search ? parsePrice(raw.web_search) : undefined,\n openRouterMarkupUsdPerInputToken: 0,\n openRouterMarkupUsdPerOutputToken: 0,\n pricedAt: new Date().toISOString(),\n source: \"openrouter\",\n };\n}\n\nfunction resolveStatus(row: OpenRouterModelApi): AiModelRecord[\"status\"] {\n if (row.expiration_date) {\n const exp = Date.parse(row.expiration_date);\n if (!Number.isNaN(exp) && exp < Date.now()) return \"deprecated\";\n }\n return \"active\";\n}\n\nexport function normalizeOpenRouterModel(row: OpenRouterModelApi, syncedAt: string): AiModelRecord {\n const outputModalities = row.architecture?.output_modalities ?? [\"text\"];\n const inputModalities = row.architecture?.input_modalities ?? [\"text\"];\n const supportedParameters = row.supported_parameters ?? [];\n const pricing = normalizePricing(row.pricing);\n const openRouterPricing = row.pricing;\n const supportsReasoning = computeSupportsReasoning({\n supportedParameters,\n pricing,\n openRouterPricing,\n });\n\n return {\n modelId: row.id,\n name: row.name ?? row.id,\n providerId: extractProviderId(row.id),\n canonicalSlug: row.canonical_slug ?? row.id,\n status: resolveStatus(row),\n description: row.description ?? \"\",\n created: row.created ?? 0,\n expirationDate: row.expiration_date ?? null,\n contextLength: row.context_length ?? row.top_provider?.context_length ?? 0,\n maxCompletionTokens: row.top_provider?.max_completion_tokens ?? null,\n isModerated: row.top_provider?.is_moderated ?? false,\n modality: row.architecture?.modality ?? \"\",\n inputModalities,\n outputModalities,\n tokenizer: row.architecture?.tokenizer ?? \"\",\n instructType: row.architecture?.instruct_type ?? null,\n supportedParameters,\n defaultParameters: row.default_parameters ?? null,\n perRequestLimits: row.per_request_limits ?? null,\n pricing,\n openRouterPricing,\n architecture: row.architecture,\n topProvider: row.top_provider,\n openRouter: row,\n aliases: buildAliases(row.id, row.name),\n availableOnOpenRouter: true,\n supportsStreaming: outputModalities.includes(\"text\"),\n supportsTools: supportedParameters.includes(\"tools\"),\n supportsReasoning,\n primaryOutputModality: outputModalities[0] ?? \"text\",\n syncedAt,\n syncSource: \"openrouter\",\n };\n}\n"],"mappings":"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","names":[]}