@x12i/ai-tools 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/{AiModelsCatalogClient-B5FMI9gj.d.cts → AiModelsCatalogClient-C9ZJHhv3.d.ts} +4 -1
  2. package/dist/{AiModelsCatalogClient-CPPNI6Ry.d.ts → AiModelsCatalogClient-DgBdVFk-.d.cts} +4 -1
  3. package/dist/aliases/index.d.cts +3 -3
  4. package/dist/aliases/index.d.ts +3 -3
  5. package/dist/catalog/index.cjs +6 -5
  6. package/dist/catalog/index.cjs.map +1 -1
  7. package/dist/catalog/index.d.cts +4 -4
  8. package/dist/catalog/index.d.ts +4 -4
  9. package/dist/catalog/index.js +5 -4
  10. package/dist/{chunk-EYHMQVAL.js → chunk-54GKLIDW.js} +22 -10
  11. package/dist/chunk-54GKLIDW.js.map +1 -0
  12. package/dist/chunk-5IZ7PLY2.cjs +51 -0
  13. package/dist/chunk-5IZ7PLY2.cjs.map +1 -0
  14. package/dist/{chunk-XAWBTX3N.cjs → chunk-75ZVXZAV.cjs} +7 -7
  15. package/dist/{chunk-XAWBTX3N.cjs.map → chunk-75ZVXZAV.cjs.map} +1 -1
  16. package/dist/{chunk-YQDSN6R6.cjs → chunk-76FHWQH3.cjs} +3 -3
  17. package/dist/{chunk-YQDSN6R6.cjs.map → chunk-76FHWQH3.cjs.map} +1 -1
  18. package/dist/{chunk-EDMCKHO6.cjs → chunk-BCX5CLJJ.cjs} +15 -2
  19. package/dist/chunk-BCX5CLJJ.cjs.map +1 -0
  20. package/dist/{chunk-OPN6BGNH.js → chunk-D6OIUYNC.js} +117 -5
  21. package/dist/{chunk-OPN6BGNH.js.map → chunk-D6OIUYNC.js.map} +1 -1
  22. package/dist/{chunk-NF2SKQR7.cjs → chunk-DDRWORUU.cjs} +30 -298
  23. package/dist/chunk-DDRWORUU.cjs.map +1 -0
  24. package/dist/{chunk-5XAAMBDO.cjs → chunk-HBNYVRLZ.cjs} +123 -11
  25. package/dist/chunk-HBNYVRLZ.cjs.map +1 -0
  26. package/dist/chunk-HEB73GKJ.js +263 -0
  27. package/dist/chunk-HEB73GKJ.js.map +1 -0
  28. package/dist/{chunk-VJHLO2R3.js → chunk-KSJSLKYI.js} +2 -2
  29. package/dist/{chunk-SIH4GPV4.js → chunk-MOLWV5LV.js} +2 -2
  30. package/dist/{chunk-U2YDDUVP.js → chunk-PN4FF6YF.js} +10 -275
  31. package/dist/chunk-PN4FF6YF.js.map +1 -0
  32. package/dist/{chunk-DXZOL3VN.cjs → chunk-RSHI4OOY.cjs} +46 -34
  33. package/dist/chunk-RSHI4OOY.cjs.map +1 -0
  34. package/dist/{chunk-B3V2EHRY.js → chunk-SLSKQRMI.js} +15 -2
  35. package/dist/{chunk-B3V2EHRY.js.map → chunk-SLSKQRMI.js.map} +1 -1
  36. package/dist/{chunk-XOKUDUUI.cjs → chunk-TMA6QSNH.cjs} +3 -3
  37. package/dist/{chunk-XOKUDUUI.cjs.map → chunk-TMA6QSNH.cjs.map} +1 -1
  38. package/dist/{chunk-6BQBKROR.js → chunk-VBROBIVI.js} +3 -3
  39. package/dist/{chunk-6BQBKROR.js.map → chunk-VBROBIVI.js.map} +1 -1
  40. package/dist/chunk-WSUFQR3D.cjs +266 -0
  41. package/dist/chunk-WSUFQR3D.cjs.map +1 -0
  42. package/dist/{chunk-PRCICORG.cjs → chunk-X42KFOUO.cjs} +6 -6
  43. package/dist/{chunk-PRCICORG.cjs.map → chunk-X42KFOUO.cjs.map} +1 -1
  44. package/dist/chunk-YQVY7CWT.js +51 -0
  45. package/dist/chunk-YQVY7CWT.js.map +1 -0
  46. package/dist/{chunk-AB5GNXJ4.js → chunk-ZPUZ7DBO.js} +2 -2
  47. package/dist/cli/index.cjs +16 -15
  48. package/dist/cli/index.cjs.map +1 -1
  49. package/dist/cli/index.js +7 -6
  50. package/dist/cli/index.js.map +1 -1
  51. package/dist/cost/index.cjs +4 -3
  52. package/dist/cost/index.cjs.map +1 -1
  53. package/dist/cost/index.d.cts +4 -4
  54. package/dist/cost/index.d.ts +4 -4
  55. package/dist/cost/index.js +3 -2
  56. package/dist/index.cjs +28 -11
  57. package/dist/index.cjs.map +1 -1
  58. package/dist/index.d.cts +8 -6
  59. package/dist/index.d.ts +8 -6
  60. package/dist/index.js +33 -16
  61. package/dist/{modelCache-CJftI-Ko.d.cts → modelCache-sL3dBfRM.d.cts} +1 -1
  62. package/dist/{modelCache-BzRn6t_C.d.ts → modelCache-xzoTUue2.d.ts} +1 -1
  63. package/dist/{modelNameResolver-5XkBMctP.d.ts → modelNameResolver-2WroQlqt.d.ts} +2 -1
  64. package/dist/{modelNameResolver-C5CSTGFF.d.cts → modelNameResolver-Bxlehrbp.d.cts} +2 -1
  65. package/dist/models/index.cjs +7 -6
  66. package/dist/models/index.cjs.map +1 -1
  67. package/dist/models/index.d.cts +3 -3
  68. package/dist/models/index.d.ts +3 -3
  69. package/dist/models/index.js +9 -8
  70. package/dist/profiles/index.cjs +18 -0
  71. package/dist/profiles/index.cjs.map +1 -0
  72. package/dist/profiles/index.d.cts +40 -0
  73. package/dist/profiles/index.d.ts +40 -0
  74. package/dist/profiles/index.js +17 -0
  75. package/dist/profiles/index.js.map +1 -0
  76. package/dist/{resolveUsageModel-BFwf80Hz.d.ts → resolveUsageModel-DrFuiuIW.d.ts} +2 -2
  77. package/dist/{resolveUsageModel-C_YmGR1M.d.cts → resolveUsageModel-xKZ2QpHy.d.cts} +2 -2
  78. package/dist/sync/index.cjs +7 -5
  79. package/dist/sync/index.cjs.map +1 -1
  80. package/dist/sync/index.d.cts +3 -3
  81. package/dist/sync/index.d.ts +3 -3
  82. package/dist/sync/index.js +6 -4
  83. package/dist/{types-BrzJWsTU.d.ts → types-BZYGjN2O.d.cts} +21 -2
  84. package/dist/{types-BrzJWsTU.d.cts → types-BZYGjN2O.d.ts} +21 -2
  85. package/package.json +7 -2
  86. package/dist/chunk-5XAAMBDO.cjs.map +0 -1
  87. package/dist/chunk-DXZOL3VN.cjs.map +0 -1
  88. package/dist/chunk-EDMCKHO6.cjs.map +0 -1
  89. package/dist/chunk-EYHMQVAL.js.map +0 -1
  90. package/dist/chunk-NF2SKQR7.cjs.map +0 -1
  91. package/dist/chunk-U2YDDUVP.js.map +0 -1
  92. /package/dist/{chunk-VJHLO2R3.js.map → chunk-KSJSLKYI.js.map} +0 -0
  93. /package/dist/{chunk-SIH4GPV4.js.map → chunk-MOLWV5LV.js.map} +0 -0
  94. /package/dist/{chunk-AB5GNXJ4.js.map → chunk-ZPUZ7DBO.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cost/constants.ts","../src/cost/enrichCostResult.ts","../src/cost/extractUsageInput.ts","../src/cost/resolveUsageModel.ts","../src/cost/profilePricing.ts","../src/cost/CostCalculator.ts"],"sourcesContent":["/** Default OpenRouter platform surcharge when catalog markup fields are absent (5%). */\nexport const DEFAULT_OPENROUTER_MARKUP_RATE = 0.05;\n\n/** ai-profiles tiered pricing threshold (tokens). */\nexport const PROFILE_TIERED_CONTEXT_THRESHOLD = 200_000;\n","import type { ExtractUsageInputResult } from \"./extractUsageInput.js\";\nimport type { AiCostExtraction, AiCostResult, AiUsageInput } from \"./types.js\";\n\nexport function toCostExtraction(\n provenance: ExtractUsageInputResult[\"provenance\"],\n): AiCostExtraction {\n return {\n model: { field: provenance.model.field, path: provenance.model.path },\n tokens: {\n source: provenance.tokens.source,\n path: provenance.tokens.path,\n estimated: provenance.tokens.estimated,\n },\n ...(provenance.modelUsed\n ? {\n modelUsed: {\n field: provenance.modelUsed.field,\n path: provenance.modelUsed.path,\n },\n }\n : {}),\n ...(provenance.provider\n ? {\n provider: {\n field: provenance.provider.field,\n path: provenance.provider.path,\n },\n }\n : {}),\n };\n}\n\n/** Attach usage, provider, and model fields callers expect on every cost response. */\nexport function enrichCostResult(\n result: Omit<\n AiCostResult,\n \"usage\" | \"provider\" | \"usedModel\" | \"model\" | \"extraction\"\n >,\n input: AiUsageInput,\n extraction?: AiCostExtraction,\n): AiCostResult {\n /** Original model id from the caller — never replaced by catalog resolution. */\n const receivedModelId = input.usedModel ?? input.modelUsed ?? input.model;\n\n return {\n ...result,\n provider: input.provider,\n usage: { ...input.tokens },\n ...(receivedModelId ? { usedModel: receivedModelId } : {}),\n ...(input.model && input.model !== receivedModelId ? { model: input.model } : {}),\n ...(extraction ? { extraction } : {}),\n };\n}\n","import type { AiUsageInput } from \"./types.js\";\n\n/** Model id field priority (higher wins). Runtime ids beat request/config aliases. */\nexport const MODEL_FIELD_PRIORITY: readonly { key: string; score: number }[] = [\n { key: \"usedModel\", score: 1000 },\n { key: \"modelUsed\", score: 990 },\n { key: \"resolvedModel\", score: 980 },\n { key: \"model\", score: 500 },\n { key: \"xynthesisModel\", score: 120 },\n { key: \"skillModel\", score: 110 },\n] as const;\n\n/** Path segments that boost or penalize a model candidate. */\nconst MODEL_PATH_BONUS: readonly { pattern: RegExp; bonus: number }[] = [\n { pattern: /(^|\\.)response(\\.|$)/i, bonus: 40 },\n { pattern: /(^|\\.)outer\\.input(\\.|$)/i, bonus: 35 },\n { pattern: /(^|\\.)config(?!\\.rawConfig)(\\.|$)/i, bonus: 30 },\n { pattern: /(^|\\.)outer\\.input\\.config(\\.|$)/i, bonus: 28 },\n { pattern: /(^|\\.)usage(\\.|$)/i, bonus: 15 },\n { pattern: /(^|\\.)rawConfig(\\.|$)/i, bonus: -40 },\n { pattern: /workingMemory/i, bonus: -50 },\n { pattern: /requestExample/i, bonus: -80 },\n { pattern: /graphsStudio/i, bonus: -80 },\n];\n\nconst PROVIDER_FIELD_PRIORITY: readonly { key: string; score: number }[] = [\n { key: \"provider\", score: 500 },\n { key: \"providerId\", score: 480 },\n] as const;\n\nconst PROVIDER_PATH_BONUS: readonly { pattern: RegExp; bonus: number }[] = [\n { pattern: /(^|\\.)config(?!\\.rawConfig)(\\.|$)/i, bonus: 30 },\n { pattern: /(^|\\.)outer\\.input(\\.|$)/i, bonus: 20 },\n { pattern: /(^|\\.)rawConfig(\\.|$)/i, bonus: -20 },\n];\n\nconst PROMPT_TOKEN_KEYS = new Set([\n \"prompt\",\n \"prompt_tokens\",\n \"promptTokens\",\n \"input_tokens\",\n \"inputTokens\",\n \"estimatedInputTokens\",\n \"input\",\n]);\n\nconst COMPLETION_TOKEN_KEYS = new Set([\n \"completion\",\n \"completion_tokens\",\n \"completionTokens\",\n \"output_tokens\",\n \"outputTokens\",\n \"estimatedOutputTokens\",\n \"output\",\n]);\n\nconst OPTIONAL_TOKEN_KEYS: Record<string, keyof AiUsageInput[\"tokens\"]> = {\n total: \"total\",\n total_tokens: \"total\",\n totalTokens: \"total\",\n cached: \"cached\",\n cached_tokens: \"cached\",\n cache_read_tokens: \"cached\",\n cacheReadTokens: \"cached\",\n cacheWrite: \"cacheWrite\",\n cache_write_tokens: \"cacheWrite\",\n cacheWriteTokens: \"cacheWrite\",\n reasoning: \"reasoning\",\n reasoning_tokens: \"reasoning\",\n reasoningTokens: \"reasoning\",\n audio: \"audio\",\n audio_tokens: \"audio\",\n image: \"image\",\n image_tokens: \"image\",\n};\n\nexport type FieldProvenance = {\n field: string;\n path: string;\n score: number;\n};\n\nexport type TokenExtractionProvenance = {\n source: \"usage\" | \"tokens\" | \"diagnostics\" | \"estimated\";\n path: string;\n estimated?: boolean;\n};\n\nexport type ExtractUsageInputResult = {\n input: AiUsageInput;\n provenance: {\n model: FieldProvenance;\n modelUsed?: FieldProvenance;\n provider?: FieldProvenance;\n tokens: TokenExtractionProvenance;\n };\n};\n\nexport type ExtractUsageInputOptions = {\n /** Default when no provider field is found (default: `openrouter`). */\n defaultProvider?: string;\n};\n\ntype ModelCandidate = FieldProvenance & { value: string };\ntype ProviderCandidate = FieldProvenance & { value: string };\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === \"object\" && !Array.isArray(v);\n}\n\nfunction modelKeyScore(key: string): number {\n return MODEL_FIELD_PRIORITY.find((e) => e.key === key)?.score ?? 0;\n}\n\nfunction providerKeyScore(key: string): number {\n return PROVIDER_FIELD_PRIORITY.find((e) => e.key === key)?.score ?? 0;\n}\n\nfunction pathBonus(path: string, rules: readonly { pattern: RegExp; bonus: number }[]): number {\n let bonus = 0;\n for (const { pattern, bonus: b } of rules) {\n if (pattern.test(path)) bonus += b;\n }\n return bonus;\n}\n\nfunction normalizeModelValue(v: unknown): string | undefined {\n if (typeof v !== \"string\") return undefined;\n const t = v.trim();\n return t.length > 0 ? t : undefined;\n}\n\nfunction normalizeProviderValue(v: unknown): string | undefined {\n if (typeof v !== \"string\") return undefined;\n const t = v.trim().toLowerCase();\n if (!t || t === \"null\") return undefined;\n return t;\n}\n\nfunction collectModelCandidates(\n node: unknown,\n path: string,\n out: ModelCandidate[],\n depth: number,\n maxDepth: number,\n): void {\n if (depth > maxDepth || node === null || node === undefined) return;\n\n if (isPlainObject(node)) {\n for (const [key, value] of Object.entries(node)) {\n const childPath = path ? `${path}.${key}` : key;\n const base = modelKeyScore(key);\n if (base > 0) {\n const model = normalizeModelValue(value);\n if (model) {\n out.push({\n field: key,\n path: childPath,\n value: model,\n score: base + pathBonus(childPath, MODEL_PATH_BONUS),\n });\n }\n }\n collectModelCandidates(value, childPath, out, depth + 1, maxDepth);\n }\n return;\n }\n\n if (Array.isArray(node)) {\n for (let i = 0; i < node.length; i++) {\n collectModelCandidates(node[i], `${path}[${i}]`, out, depth + 1, maxDepth);\n }\n }\n}\n\nfunction collectProviderCandidates(\n node: unknown,\n path: string,\n out: ProviderCandidate[],\n depth: number,\n maxDepth: number,\n): void {\n if (depth > maxDepth || node === null || node === undefined) return;\n\n if (isPlainObject(node)) {\n for (const [key, value] of Object.entries(node)) {\n const childPath = path ? `${path}.${key}` : key;\n const base = providerKeyScore(key);\n if (base > 0) {\n const provider = normalizeProviderValue(value);\n if (provider) {\n out.push({\n field: key,\n path: childPath,\n value: provider,\n score: base + pathBonus(childPath, PROVIDER_PATH_BONUS),\n });\n }\n }\n collectProviderCandidates(value, childPath, out, depth + 1, maxDepth);\n }\n return;\n }\n\n if (Array.isArray(node)) {\n for (let i = 0; i < node.length; i++) {\n collectProviderCandidates(node[i], `${path}[${i}]`, out, depth + 1, maxDepth);\n }\n }\n}\n\nfunction readNumber(obj: Record<string, unknown>, keys: Set<string>): number | undefined {\n for (const [k, v] of Object.entries(obj)) {\n if (!keys.has(k)) continue;\n if (typeof v === \"number\" && Number.isFinite(v) && v >= 0) return v;\n }\n return undefined;\n}\n\nfunction readOptionalNumbers(\n obj: Record<string, unknown>,\n): Partial<AiUsageInput[\"tokens\"]> {\n const extra: Partial<AiUsageInput[\"tokens\"]> = {};\n for (const [k, v] of Object.entries(obj)) {\n const target = OPTIONAL_TOKEN_KEYS[k];\n if (!target || typeof v !== \"number\" || !Number.isFinite(v) || v < 0) continue;\n extra[target] = v;\n }\n return extra;\n}\n\nfunction looksLikeUsageObject(obj: Record<string, unknown>): boolean {\n const hasPrompt = readNumber(obj, PROMPT_TOKEN_KEYS) !== undefined;\n const hasCompletion = readNumber(obj, COMPLETION_TOKEN_KEYS) !== undefined;\n return hasPrompt && hasCompletion;\n}\n\nfunction looksLikeDiagnosticsObject(obj: Record<string, unknown>): boolean {\n return (\n typeof obj.estimatedInputTokens === \"number\" &&\n typeof obj.estimatedOutputTokens === \"number\"\n );\n}\n\ntype TokenCandidate = {\n tokens: AiUsageInput[\"tokens\"];\n provenance: TokenExtractionProvenance;\n score: number;\n};\n\nfunction tokensFromObject(\n obj: Record<string, unknown>,\n source: TokenExtractionProvenance[\"source\"],\n path: string,\n estimated: boolean,\n score: number,\n): TokenCandidate | null {\n const prompt = readNumber(obj, PROMPT_TOKEN_KEYS);\n const completion = readNumber(obj, COMPLETION_TOKEN_KEYS);\n if (prompt === undefined || completion === undefined) return null;\n\n const extra = readOptionalNumbers(obj);\n const total =\n typeof extra.total === \"number\" ? extra.total : prompt + completion;\n\n return {\n tokens: {\n prompt,\n completion,\n total,\n ...extra,\n },\n provenance: { source, path, estimated },\n score,\n };\n}\n\nfunction collectTokenCandidates(\n node: unknown,\n path: string,\n out: TokenCandidate[],\n depth: number,\n maxDepth: number,\n): void {\n if (depth > maxDepth || node === null || node === undefined) return;\n\n if (isPlainObject(node)) {\n if (path.endsWith(\"diagnostics\") || looksLikeDiagnosticsObject(node)) {\n const cand = tokensFromObject(node, \"diagnostics\", path, true, 200);\n if (cand) out.push(cand);\n } else if (path.endsWith(\"usage\") || path.endsWith(\"tokens\") || looksLikeUsageObject(node)) {\n const source = path.endsWith(\"tokens\") ? \"tokens\" : \"usage\";\n const estimated = false;\n const score = path.endsWith(\"usage\") ? 500 : 450;\n const cand = tokensFromObject(node, source, path, estimated, score);\n if (cand) out.push(cand);\n }\n\n for (const [key, value] of Object.entries(node)) {\n const childPath = path ? `${path}.${key}` : key;\n if (key === \"usage\" || key === \"tokens\" || key === \"diagnostics\") {\n if (isPlainObject(value)) {\n collectTokenCandidates(value, childPath, out, depth + 1, maxDepth);\n }\n } else {\n collectTokenCandidates(value, childPath, out, depth + 1, maxDepth);\n }\n }\n return;\n }\n\n if (Array.isArray(node)) {\n for (let i = 0; i < node.length; i++) {\n collectTokenCandidates(node[i], `${path}[${i}]`, out, depth + 1, maxDepth);\n }\n }\n}\n\nfunction pickBestModel(candidates: ModelCandidate[]): ModelCandidate | null {\n if (candidates.length === 0) return null;\n return [...candidates].sort((a, b) => b.score - a.score)[0]!;\n}\n\nfunction pickBestProvider(candidates: ProviderCandidate[]): ProviderCandidate | null {\n if (candidates.length === 0) return null;\n return [...candidates].sort((a, b) => b.score - a.score)[0]!;\n}\n\nfunction pickBestTokens(candidates: TokenCandidate[]): TokenCandidate | null {\n if (candidates.length === 0) return null;\n return [...candidates].sort((a, b) => b.score - a.score)[0]!;\n}\n\nfunction inferProviderFromModel(model: string, fallback: string): string {\n const slash = model.indexOf(\"/\");\n if (slash > 0) {\n const prefix = model.slice(0, slash).toLowerCase();\n if (prefix !== \"openrouter\") return prefix;\n }\n return fallback;\n}\n\n/**\n * Extract {@link AiUsageInput} from activity logs, gateway records, MongoDB exports,\n * or any nested JSON shape (e.g. `outer.input`, `config`, `metadata.diagnostics`).\n */\nexport function extractUsageInput(\n record: unknown,\n options: ExtractUsageInputOptions = {},\n): ExtractUsageInputResult {\n const defaultProvider = options.defaultProvider ?? \"openrouter\";\n const maxDepth = 24;\n\n const modelCandidates: ModelCandidate[] = [];\n const providerCandidates: ProviderCandidate[] = [];\n const tokenCandidates: TokenCandidate[] = [];\n\n collectModelCandidates(record, \"\", modelCandidates, 0, maxDepth);\n collectProviderCandidates(record, \"\", providerCandidates, 0, maxDepth);\n collectTokenCandidates(record, \"\", tokenCandidates, 0, maxDepth);\n\n const bestModel = pickBestModel(modelCandidates);\n if (!bestModel) {\n throw new Error(\n \"[ai-tools] Could not extract a model from the record (looked for usedModel, modelUsed, model, …).\",\n );\n }\n\n const runtimeFields = new Set([\"usedModel\", \"modelUsed\", \"resolvedModel\"]);\n const isRuntimeModel = runtimeFields.has(bestModel.field);\n const requestModel = modelCandidates.find(\n (c) => c.field === \"model\" && c.path !== bestModel.path,\n );\n\n const bestProvider = pickBestProvider(providerCandidates);\n const provider =\n bestProvider?.value ??\n inferProviderFromModel(bestModel.value, defaultProvider);\n\n const bestTokens = pickBestTokens(tokenCandidates);\n if (!bestTokens) {\n throw new Error(\n \"[ai-tools] Could not extract token usage from the record (usage, tokens, or metadata.diagnostics).\",\n );\n }\n\n const input: AiUsageInput = {\n tokens: bestTokens.tokens,\n provider,\n ...(isRuntimeModel\n ? { modelUsed: bestModel.value, model: requestModel?.value }\n : { model: bestModel.value }),\n };\n\n const provenance: ExtractUsageInputResult[\"provenance\"] = {\n model: {\n field: bestModel.field,\n path: bestModel.path,\n score: bestModel.score,\n },\n tokens: bestTokens.provenance,\n };\n\n if (bestProvider) {\n provenance.provider = {\n field: bestProvider.field,\n path: bestProvider.path,\n score: bestProvider.score,\n };\n }\n\n if (isRuntimeModel && requestModel) {\n provenance.modelUsed = {\n field: bestModel.field,\n path: bestModel.path,\n score: bestModel.score,\n };\n } else if (input.modelUsed) {\n provenance.modelUsed = provenance.model;\n }\n\n return { input, provenance };\n}\n","import type { AiUsageInput } from \"./types.js\";\n\n/** Prefer runtime id (`usedModel` / `modelUsed`); fall back to `model`. */\nexport function resolveUsageModel(input: AiUsageInput): string {\n const value = input.usedModel ?? input.modelUsed ?? input.model;\n if (!value?.trim()) {\n throw new Error(\n \"[ai-tools] Cost calculation requires `usedModel`, `modelUsed`, or `model` on usage input.\",\n );\n }\n return value.trim();\n}\n","import type { AIModelPricing } from \"@x12i/ai-profiles\";\nimport {\n DEFAULT_OPENROUTER_MARKUP_RATE,\n PROFILE_TIERED_CONTEXT_THRESHOLD,\n} from \"./constants.js\";\nimport type { AiModelPricing, AiUsageInput } from \"./types.js\";\n\nconst TOKENS_PER_UNIT = 1_000_000;\n\nfunction usdPerToken(perMillion?: number): number {\n return (perMillion ?? 0) / TOKENS_PER_UNIT;\n}\n\nfunction pickInputRatePerMillion(\n pricing: AIModelPricing,\n promptTokens: number,\n): number | undefined {\n if (\n pricing.inputBelow200k !== undefined &&\n pricing.inputAbove200k !== undefined\n ) {\n return promptTokens <= PROFILE_TIERED_CONTEXT_THRESHOLD\n ? pricing.inputBelow200k\n : pricing.inputAbove200k;\n }\n return pricing.input ?? pricing.inputBelow200k ?? pricing.inputAbove200k;\n}\n\nfunction pickOutputRatePerMillion(\n pricing: AIModelPricing,\n promptTokens: number,\n): number | undefined {\n if (\n pricing.outputBelow200k !== undefined &&\n pricing.outputAbove200k !== undefined\n ) {\n return promptTokens <= PROFILE_TIERED_CONTEXT_THRESHOLD\n ? pricing.outputBelow200k\n : pricing.outputAbove200k;\n }\n return pricing.output ?? pricing.outputBelow200k ?? pricing.outputAbove200k;\n}\n\nexport type AiProfilesPricingOptions = {\n promptTokens?: number;\n routedViaOpenRouter?: boolean;\n};\n\nexport function aiProfilesPricingToCatalogPricing(\n pricing: AIModelPricing,\n pricedAt: string,\n options: AiProfilesPricingOptions = {},\n): AiModelPricing {\n const promptTokens = options.promptTokens ?? 0;\n const promptUsdPerToken = usdPerToken(pickInputRatePerMillion(pricing, promptTokens));\n const completionUsdPerToken = usdPerToken(\n pickOutputRatePerMillion(pricing, promptTokens),\n );\n\n const snapshot: AiModelPricing = {\n promptUsdPerToken,\n completionUsdPerToken,\n cacheReadUsdPerToken: usdPerToken(pricing.cachedInput ?? pricing.cacheHit),\n cacheWriteUsdPerToken: usdPerToken(pricing.cacheWrite5m ?? pricing.cacheWrite1h),\n imageUsdPerUnit: 0,\n requestUsdPerRequest: 0,\n pricedAt,\n source: \"manual\",\n };\n\n if (options.routedViaOpenRouter) {\n snapshot.openRouterMarkupUsdPerInputToken =\n promptUsdPerToken * DEFAULT_OPENROUTER_MARKUP_RATE;\n snapshot.openRouterMarkupUsdPerOutputToken =\n completionUsdPerToken * DEFAULT_OPENROUTER_MARKUP_RATE;\n }\n\n return snapshot;\n}\n\nexport function computeCostFromPricing(\n input: AiUsageInput,\n pricing: AiModelPricing,\n routedViaOpenRouter: boolean,\n includeBreakdown: boolean,\n): { cost: number; breakdown?: import(\"./types.js\").AiCostResult[\"breakdown\"] } {\n const { tokens } = input;\n\n let promptCost = tokens.prompt * pricing.promptUsdPerToken;\n let completionCost = tokens.completion * pricing.completionUsdPerToken;\n\n const cachingCost =\n (tokens.cacheWrite ?? 0) * (pricing.cacheWriteUsdPerToken ?? 0) +\n (tokens.cached ?? 0) * (pricing.cacheReadUsdPerToken ?? 0);\n\n const reasoningCost =\n (tokens.reasoning ?? 0) *\n (pricing.reasoningUsdPerToken ?? pricing.promptUsdPerToken);\n\n const audioCost = (tokens.audio ?? 0) * pricing.promptUsdPerToken;\n const imageCost = (tokens.image ?? 0) * (pricing.imageUsdPerUnit ?? 0);\n const requestFlat = pricing.requestUsdPerRequest;\n\n if (routedViaOpenRouter) {\n promptCost +=\n tokens.prompt * (pricing.openRouterMarkupUsdPerInputToken ?? 0);\n completionCost +=\n tokens.completion * (pricing.openRouterMarkupUsdPerOutputToken ?? 0);\n }\n\n const cost =\n promptCost +\n completionCost +\n cachingCost +\n reasoningCost +\n audioCost +\n imageCost +\n requestFlat;\n\n if (!includeBreakdown) {\n return { cost };\n }\n\n return {\n cost,\n breakdown: {\n promptCostUsd: promptCost,\n completionCostUsd: completionCost,\n cachingCostUsd: cachingCost || undefined,\n reasoningCostUsd: reasoningCost || undefined,\n audioCostUsd: audioCost || undefined,\n imageCostUsd: imageCost || undefined,\n requestFlatCostUsd: requestFlat || undefined,\n },\n };\n}\n","import type { AliasRegistry } from \"../aliases/AliasRegistry.js\";\nimport type { AiModelsCatalogClient } from \"../catalog/AiModelsCatalogClient.js\";\nimport { UnknownModelCostError } from \"../errors.js\";\nimport { normalizeString } from \"../sync/modelNameResolver/normalize.js\";\nimport { stripModelVersionSuffix } from \"../sync/modelNameResolver/stripVersionSuffix.js\";\nimport type {\n ModelResolutionResult,\n ModelResolverOptions,\n} from \"../sync/modelNameResolver/types.js\";\nimport { matchModelInAiProfiles } from \"./aiProfilesMatch.js\";\nimport {\n buildCatalogResolveAttempts,\n isLocalProvider,\n isLocalProviderResolution,\n resolveFromCatalogAttempts,\n resolveRoutedViaOpenRouter,\n} from \"./costModelResolution.js\";\nimport {\n aiProfilesPricingToCatalogPricing,\n computeCostFromPricing,\n} from \"./profilePricing.js\";\nimport { enrichCostResult, toCostExtraction } from \"./enrichCostResult.js\";\nimport {\n extractUsageInput,\n type ExtractUsageInputOptions,\n} from \"./extractUsageInput.js\";\nimport { resolveUsageModel } from \"./resolveUsageModel.js\";\nimport type { AiCostResult, AiCostWarning, AiModelPricing, AiUsageInput } from \"./types.js\";\n\nexport type CostCalculatorOptions = {\n aliasRegistry?: AliasRegistry;\n includeBreakdown?: boolean;\n resolverOptions?: ModelResolverOptions;\n /** When true, throw {@link UnknownModelCostError} instead of zero-cost fallback. */\n throwOnUnknownModel?: boolean;\n};\n\nfunction emptyPricing(): AiModelPricing {\n return {\n promptUsdPerToken: 0,\n completionUsdPerToken: 0,\n imageUsdPerUnit: 0,\n requestUsdPerRequest: 0,\n pricedAt: new Date().toISOString(),\n source: \"manual\",\n };\n}\n\nfunction mergeAttempts(\n ...groups: ReturnType<typeof buildCatalogResolveAttempts>[]\n): ReturnType<typeof buildCatalogResolveAttempts> {\n const seen = new Set<string>();\n const out: ReturnType<typeof buildCatalogResolveAttempts> = [];\n for (const group of groups) {\n for (const a of group) {\n const key = `${a.provider ?? \"\"}\\0${a.model}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(a);\n }\n }\n return out;\n}\n\nexport class CostCalculator {\n private readonly aliasRegistry?: AliasRegistry;\n private readonly includeBreakdown: boolean;\n private readonly resolverOptions?: ModelResolverOptions;\n private readonly throwOnUnknownModel: boolean;\n\n constructor(\n private readonly catalog: AiModelsCatalogClient,\n options: CostCalculatorOptions = {},\n ) {\n this.aliasRegistry = options.aliasRegistry;\n this.includeBreakdown = options.includeBreakdown ?? true;\n this.resolverOptions = options.resolverOptions;\n this.throwOnUnknownModel = options.throwOnUnknownModel ?? false;\n }\n\n /**\n * Extract model, provider, and token usage from an activity / gateway record\n * (MongoDB export, nested `outer`, `config`, `metadata.diagnostics`, etc.)\n * then run {@link calculate}.\n */\n async calculateFromRecord(\n record: unknown,\n extractOptions?: ExtractUsageInputOptions,\n ): Promise<AiCostResult> {\n const { input, provenance } = extractUsageInput(record, extractOptions);\n const warnings: AiCostWarning[] = [];\n if (provenance.tokens.estimated) {\n warnings.push({\n code: \"ESTIMATED_TOKEN_USAGE\",\n message: `Token counts are estimates from ${provenance.tokens.path} (not billed usage).`,\n });\n }\n const result = await this.calculate(input);\n const enriched = enrichCostResult(result, input, toCostExtraction(provenance));\n if (warnings.length > 0) {\n enriched.warnings = [...(enriched.warnings ?? []), ...warnings];\n }\n return enriched;\n }\n\n async calculate(input: AiUsageInput): Promise<AiCostResult> {\n const modelInput = resolveUsageModel(input);\n const resolverOpts = {\n ...this.resolverOptions,\n aliasRegistry: this.aliasRegistry ?? this.resolverOptions?.aliasRegistry,\n };\n\n let resolved = await resolveFromCatalogAttempts(\n this.catalog,\n buildCatalogResolveAttempts(modelInput, input.provider),\n resolverOpts,\n );\n\n if (isLocalProviderResolution(resolved, input.provider)) {\n return this.localProviderResult(modelInput, input, resolved);\n }\n\n let profileMatch = null as Awaited<ReturnType<typeof matchModelInAiProfiles>>;\n const warnings: AiCostWarning[] = [];\n\n if (!resolved?.found || !resolved.record) {\n if (!isLocalProvider(input.provider)) {\n profileMatch = await matchModelInAiProfiles(modelInput, input.provider);\n }\n if (profileMatch) {\n resolved = await resolveFromCatalogAttempts(\n this.catalog,\n mergeAttempts(\n buildCatalogResolveAttempts(\n profileMatch.canonicalModelId,\n input.provider ?? profileMatch.provider,\n ),\n buildCatalogResolveAttempts(\n profileMatch.canonicalModelId,\n profileMatch.provider,\n ),\n ),\n resolverOpts,\n );\n }\n\n if (isLocalProviderResolution(resolved, input.provider)) {\n return this.localProviderResult(modelInput, input, resolved);\n }\n\n if ((!resolved?.found || !resolved.record) && profileMatch?.pricing) {\n const routedViaOpenRouter = resolveRoutedViaOpenRouter(\n input.provider,\n resolved,\n profileMatch.canonicalModelId,\n resolverOpts?.routingEnv,\n );\n const pricing = aiProfilesPricingToCatalogPricing(\n profileMatch.pricing,\n new Date().toISOString(),\n {\n promptTokens: input.tokens.prompt,\n routedViaOpenRouter,\n },\n );\n const { cost, breakdown } = computeCostFromPricing(\n input,\n pricing,\n routedViaOpenRouter,\n this.includeBreakdown,\n );\n\n warnings.push({\n code: \"AI_PROFILES_ESTIMATE\",\n message: `Catalog has no pricing for \"${modelInput}\"; estimated from ai-profiles (${profileMatch.matchedVia} → ${profileMatch.canonicalModelId}).`,\n });\n if (\n routedViaOpenRouter &&\n pricing.openRouterMarkupUsdPerInputToken !== undefined\n ) {\n warnings.push({\n code: \"OPENROUTER_MARKUP_ESTIMATED\",\n message:\n \"OpenRouter markup estimated at 5% of base token rates (catalog markup fields absent).\",\n });\n }\n\n console.warn(`[ai-tools] ${warnings.map((w) => w.message).join(\" \")}`);\n\n return this.finish(\n {\n cost,\n breakdown,\n resolvedModelId: profileMatch.canonicalModelId,\n routedViaOpenRouter,\n isAuthoritative: false,\n pricingSnapshot: pricing,\n source: \"ai-profiles\",\n warnings,\n },\n input,\n resolved,\n );\n }\n }\n\n if (!resolved?.found || !resolved.record) {\n return this.unknownModelResult(modelInput, input, resolved);\n }\n\n const { record, modelId } = resolved;\n const routedViaOpenRouter = resolveRoutedViaOpenRouter(\n input.provider,\n resolved,\n modelId,\n resolverOpts?.routingEnv,\n );\n const pricing = record.pricing;\n const { cost, breakdown } = computeCostFromPricing(\n input,\n pricing,\n routedViaOpenRouter,\n this.includeBreakdown,\n );\n\n return this.finish(\n {\n cost,\n breakdown,\n resolvedModelId: modelId,\n routedViaOpenRouter,\n isAuthoritative: true,\n pricingSnapshot: pricing,\n source: \"catalog\",\n },\n input,\n resolved,\n );\n }\n\n private versionSuffixWarnings(\n input: AiUsageInput,\n pricedModelId: string,\n resolved?: ModelResolutionResult | null,\n ): AiCostWarning[] {\n const received = input.usedModel ?? input.modelUsed ?? input.model;\n if (!received) return [];\n\n const normalizedReceived = normalizeString(received);\n const normalizedPriced = normalizeString(pricedModelId);\n if (normalizedReceived === normalizedPriced) return [];\n\n const stripped = stripModelVersionSuffix(received);\n const viaResolver =\n resolved?.found === true &&\n resolved.resolvedVia.some(\n (s) => s === \"version-suffix-strip\" || s === \"date-suffix-strip\",\n );\n const pricedViaStrip =\n stripped !== null && normalizeString(stripped) === normalizedPriced;\n\n if (!viaResolver && !pricedViaStrip) return [];\n\n return [\n {\n code: \"VERSION_SUFFIX_PRICING\",\n message: `Priced using catalog model \"${pricedModelId}\" (no exact pricing for \"${received}\").`,\n },\n ];\n }\n\n private finish(\n partial: Omit<\n AiCostResult,\n \"usage\" | \"provider\" | \"usedModel\" | \"model\" | \"extraction\"\n >,\n input: AiUsageInput,\n resolved?: ModelResolutionResult | null,\n ): AiCostResult {\n const enriched = enrichCostResult(partial, input);\n const suffixWarnings = this.versionSuffixWarnings(\n input,\n partial.resolvedModelId,\n resolved,\n );\n if (suffixWarnings.length > 0) {\n enriched.warnings = [...(enriched.warnings ?? []), ...suffixWarnings];\n }\n return enriched;\n }\n\n private localProviderResult(\n modelInput: string,\n input: AiUsageInput,\n resolved: Awaited<ReturnType<typeof resolveFromCatalogAttempts>>,\n ): AiCostResult {\n const warnings: AiCostWarning[] = [\n {\n code: \"LOCAL_PROVIDER_NO_PRICING\",\n message: `Local provider \"${input.provider}\" has no catalog pricing for \"${modelInput}\".`,\n },\n ];\n console.warn(`[ai-tools] ${warnings[0]!.message}`);\n return this.finish(\n {\n cost: 0,\n resolvedModelId: resolved?.found ? resolved.modelId : modelInput,\n routedViaOpenRouter: false,\n isAuthoritative: false,\n pricingSnapshot: emptyPricing(),\n source: \"local\",\n warnings,\n },\n input,\n );\n }\n\n private unknownModelResult(\n modelInput: string,\n input: AiUsageInput,\n resolved: Awaited<ReturnType<typeof resolveFromCatalogAttempts>>,\n ): AiCostResult {\n if (this.throwOnUnknownModel) {\n throw new UnknownModelCostError(modelInput, input.provider);\n }\n\n const warnings: AiCostWarning[] = [\n {\n code: \"UNKNOWN_MODEL\",\n message: `Unknown model \"${modelInput}\" (provider: \"${input.provider}\") — returning zero-cost fallback.`,\n },\n ];\n console.warn(`[ai-tools] ${warnings[0]!.message}`);\n\n return this.finish(\n {\n cost: 0,\n resolvedModelId: modelInput,\n routedViaOpenRouter: resolveRoutedViaOpenRouter(\n input.provider,\n resolved,\n modelInput,\n this.resolverOptions?.routingEnv,\n ),\n isAuthoritative: false,\n pricingSnapshot: emptyPricing(),\n source: \"estimate-fallback\",\n unknownModel: true,\n warnings,\n },\n input,\n );\n }\n}\n"],"mappings":"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","names":["routedViaOpenRouter","pricing","cost","breakdown"]}
@@ -11,7 +11,7 @@
11
11
 
12
12
 
13
13
 
14
- var _chunkEDMCKHO6cjs = require('./chunk-EDMCKHO6.cjs');
14
+ var _chunkBCX5CLJJcjs = require('./chunk-BCX5CLJJ.cjs');
15
15
 
16
16
 
17
17
  var _chunkPADNCGZBcjs = require('./chunk-PADNCGZB.cjs');
@@ -23,10 +23,10 @@ function buildCatalogIndexes(catalog) {
23
23
  const prefixCounts = /* @__PURE__ */ new Map();
24
24
  for (const record of catalog.values()) {
25
25
  for (const alias of record.aliases) {
26
- aliasIndex.set(_chunkEDMCKHO6cjs.normalizeString.call(void 0, alias), record.modelId);
26
+ aliasIndex.set(_chunkBCX5CLJJcjs.normalizeString.call(void 0, alias), record.modelId);
27
27
  }
28
28
  if (record.canonicalSlug) {
29
- slugIndex.set(_chunkEDMCKHO6cjs.normalizeString.call(void 0, record.canonicalSlug), record.modelId);
29
+ slugIndex.set(_chunkBCX5CLJJcjs.normalizeString.call(void 0, record.canonicalSlug), record.modelId);
30
30
  }
31
31
  const pid = record.providerId;
32
32
  prefixCounts.set(pid, (_nullishCoalesce(prefixCounts.get(pid), () => ( 0))) + 1);
@@ -47,40 +47,41 @@ var ModelNameResolver = class {
47
47
  catalog,
48
48
  indexes: this.indexes,
49
49
  options: {
50
- confidenceThreshold: _nullishCoalesce(options.confidenceThreshold, () => ( _chunkEDMCKHO6cjs.DEFAULT_CONFIDENCE_THRESHOLD)),
50
+ confidenceThreshold: _nullishCoalesce(options.confidenceThreshold, () => ( _chunkBCX5CLJJcjs.DEFAULT_CONFIDENCE_THRESHOLD)),
51
51
  aliasRegistry: options.aliasRegistry,
52
52
  additionalShorthands: _nullishCoalesce(options.additionalShorthands, () => ( {})),
53
53
  additionalProviderPatterns: _nullishCoalesce(options.additionalProviderPatterns, () => ( [])),
54
54
  additionalLocalProviders: _nullishCoalesce(options.additionalLocalProviders, () => ( [])),
55
- routingEnv: _nullishCoalesce(options.routingEnv, () => ( _chunkEDMCKHO6cjs.loadOpenRouterRoutingEnv.call(void 0, )))
55
+ routingEnv: _nullishCoalesce(options.routingEnv, () => ( _chunkBCX5CLJJcjs.loadOpenRouterRoutingEnv.call(void 0, ))),
56
+ routeViaOpenRouter: options.routeViaOpenRouter
56
57
  }
57
58
  };
58
59
  }
59
60
  resolve(input) {
60
61
  const attempted = [];
61
62
  const threshold = this.ctx.options.confidenceThreshold;
62
- let provider = _chunkEDMCKHO6cjs.normalizeProvider.call(void 0, input.provider);
63
- let model = _chunkEDMCKHO6cjs.normalizeString.call(void 0, input.model);
63
+ let provider = _chunkBCX5CLJJcjs.normalizeProvider.call(void 0, input.provider);
64
+ let model = _chunkBCX5CLJJcjs.normalizeString.call(void 0, input.model);
64
65
  const normalisedInput = model;
65
66
  if (this.ctx.options.aliasRegistry) {
66
67
  attempted.push("alias-registry");
67
68
  const entry = this.ctx.options.aliasRegistry.get(model);
68
69
  if (entry) {
69
- model = _chunkEDMCKHO6cjs.normalizeString.call(void 0, entry.modelId);
70
- provider = _nullishCoalesce(_chunkEDMCKHO6cjs.normalizeProvider.call(void 0, entry.provider), () => ( provider));
70
+ model = _chunkBCX5CLJJcjs.normalizeString.call(void 0, entry.modelId);
71
+ provider = _nullishCoalesce(_chunkBCX5CLJJcjs.normalizeProvider.call(void 0, entry.provider), () => ( provider));
71
72
  }
72
73
  }
73
74
  if (this.ctx.options.aliasRegistry && provider) {
74
75
  const aliasAsProvider = this.ctx.options.aliasRegistry.get(provider);
75
76
  if (aliasAsProvider) {
76
77
  attempted.push("alias-as-provider-correction");
77
- model = _chunkEDMCKHO6cjs.normalizeString.call(void 0, aliasAsProvider.modelId);
78
- provider = _nullishCoalesce(_chunkEDMCKHO6cjs.normalizeProvider.call(void 0, aliasAsProvider.provider), () => ( provider));
78
+ model = _chunkBCX5CLJJcjs.normalizeString.call(void 0, aliasAsProvider.modelId);
79
+ provider = _nullishCoalesce(_chunkBCX5CLJJcjs.normalizeProvider.call(void 0, aliasAsProvider.provider), () => ( provider));
79
80
  }
80
81
  }
81
82
  const localProviders = /* @__PURE__ */ new Set([
82
- ..._chunkEDMCKHO6cjs.LOCAL_PROVIDERS,
83
- ...this.ctx.options.additionalLocalProviders.map((p) => _chunkEDMCKHO6cjs.normalizeString.call(void 0, p))
83
+ ..._chunkBCX5CLJJcjs.LOCAL_PROVIDERS,
84
+ ...this.ctx.options.additionalLocalProviders.map((p) => _chunkBCX5CLJJcjs.normalizeString.call(void 0, p))
84
85
  ]);
85
86
  if (provider && localProviders.has(provider)) {
86
87
  attempted.push("local-provider-passthrough");
@@ -156,7 +157,7 @@ var ModelNameResolver = class {
156
157
  if (hit) return { match: hit };
157
158
  hit = tryMatch("cross-provider-correction", () => this.crossProviderCorrection(model));
158
159
  if (hit) return { match: hit };
159
- const stripped = _chunkEDMCKHO6cjs.stripModelVersionSuffix.call(void 0, model);
160
+ const stripped = _chunkBCX5CLJJcjs.stripModelVersionSuffix.call(void 0, model);
160
161
  if (stripped && stripped !== model) {
161
162
  if (!attempted.includes("version-suffix-strip")) attempted.push("version-suffix-strip");
162
163
  const inner = this.runPipeline(
@@ -185,7 +186,7 @@ var ModelNameResolver = class {
185
186
  if (shorthand) {
186
187
  if (!attempted.includes("shorthand-expansion")) attempted.push("shorthand-expansion");
187
188
  const inner = this.runPipeline(
188
- _chunkEDMCKHO6cjs.normalizeString.call(void 0, shorthand),
189
+ _chunkBCX5CLJJcjs.normalizeString.call(void 0, shorthand),
189
190
  provider,
190
191
  attempted,
191
192
  threshold,
@@ -263,7 +264,7 @@ var ModelNameResolver = class {
263
264
  inferProviderFromSlug(slug) {
264
265
  const patterns = [
265
266
  ...this.ctx.options.additionalProviderPatterns,
266
- ..._chunkEDMCKHO6cjs.PROVIDER_INFERENCE_MAP
267
+ ..._chunkBCX5CLJJcjs.PROVIDER_INFERENCE_MAP
267
268
  ];
268
269
  for (const { pattern, provider } of patterns) {
269
270
  if (pattern.test(slug)) return provider;
@@ -331,7 +332,7 @@ var ModelNameResolver = class {
331
332
  dateSuffixMatch(model) {
332
333
  if (model.includes("/")) {
333
334
  const [prefix, slug] = model.split("/", 2);
334
- const stripped = _chunkEDMCKHO6cjs.stripModelSlugSuffix.call(void 0, slug);
335
+ const stripped = _chunkBCX5CLJJcjs.stripModelSlugSuffix.call(void 0, slug);
335
336
  if (stripped && stripped !== slug) {
336
337
  const candidate = `${prefix}/${stripped}`;
337
338
  const record = this.catalog.get(candidate);
@@ -376,22 +377,22 @@ var ModelNameResolver = class {
376
377
  return { modelId: best.modelId, record: best.record };
377
378
  }
378
379
  shorthandMap() {
379
- return { ..._chunkEDMCKHO6cjs.SHORTHAND_MAP, ...this.ctx.options.additionalShorthands };
380
+ return { ..._chunkBCX5CLJJcjs.SHORTHAND_MAP, ...this.ctx.options.additionalShorthands };
380
381
  }
381
382
  partialMatch(model, provider) {
382
383
  let best = null;
383
- const inputTokens = _chunkEDMCKHO6cjs.tokenise.call(void 0, model);
384
+ const inputTokens = _chunkBCX5CLJJcjs.tokenise.call(void 0, model);
384
385
  if (inputTokens.length === 0) return null;
385
386
  for (const record of this.catalog.values()) {
386
387
  const recordTokens = /* @__PURE__ */ new Set([
387
- ..._chunkEDMCKHO6cjs.tokenise.call(void 0, record.modelId),
388
- ..._chunkEDMCKHO6cjs.tokenise.call(void 0, _nullishCoalesce(record.name, () => ( "")))
388
+ ..._chunkBCX5CLJJcjs.tokenise.call(void 0, record.modelId),
389
+ ..._chunkBCX5CLJJcjs.tokenise.call(void 0, _nullishCoalesce(record.name, () => ( "")))
389
390
  ]);
390
391
  const intersection = inputTokens.filter((t) => recordTokens.has(t));
391
392
  const overlapRatio = intersection.length / inputTokens.length;
392
393
  let score = overlapRatio * 0.6;
393
394
  if (record.modelId.includes(model)) score += 0.3;
394
- const slug = _chunkEDMCKHO6cjs.modelSlug.call(void 0, record.modelId);
395
+ const slug = _chunkBCX5CLJJcjs.modelSlug.call(void 0, record.modelId);
395
396
  if (model.includes(slug)) score += 0.2;
396
397
  if (provider && provider === record.providerId) score += 0.15;
397
398
  const lenPenalty = Math.abs(model.length - slug.length) / Math.max(model.length, slug.length, 1) * 0.1;
@@ -410,30 +411,41 @@ var ModelNameResolver = class {
410
411
  };
411
412
  }
412
413
  computeRoutedViaOpenRouter(modelId, record, provider, originalProvider) {
413
- const norm = _nullishCoalesce(_chunkEDMCKHO6cjs.normalizeProvider.call(void 0, originalProvider), () => ( provider));
414
+ const override = this.ctx.options.routeViaOpenRouter;
415
+ if (override === true) return true;
416
+ if (override === false) return false;
417
+ const norm = _nullishCoalesce(_chunkBCX5CLJJcjs.normalizeProvider.call(void 0, originalProvider), () => ( provider));
414
418
  if (norm === "openrouter") return true;
415
419
  if (norm && norm !== "openrouter") {
416
- if (_chunkEDMCKHO6cjs.shouldDefaultRouteViaOpenRouter.call(void 0, norm, this.ctx.options.routingEnv)) return true;
420
+ if (_chunkBCX5CLJJcjs.shouldDefaultRouteViaOpenRouter.call(void 0, norm, this.ctx.options.routingEnv)) return true;
417
421
  return false;
418
422
  }
419
423
  const recordProvider = _optionalChain([record, 'optionalAccess', _ => _.providerId]);
420
- if (recordProvider && _chunkEDMCKHO6cjs.shouldDefaultRouteViaOpenRouter.call(void 0, recordProvider, this.ctx.options.routingEnv)) {
424
+ if (recordProvider && _chunkBCX5CLJJcjs.shouldDefaultRouteViaOpenRouter.call(void 0, recordProvider, this.ctx.options.routingEnv)) {
421
425
  return true;
422
426
  }
423
427
  if (_optionalChain([record, 'optionalAccess', _2 => _2.availableOnOpenRouter]) && modelId.includes("/")) return true;
424
428
  return false;
425
429
  }
430
+ toOpenRouterSlug(modelId, provider, record) {
431
+ if (modelId.includes("/")) return modelId;
432
+ const vendor = _nullishCoalesce(_optionalChain([record, 'optionalAccess', _3 => _3.providerId]), () => ( (provider && provider !== "openrouter" ? provider : void 0)));
433
+ if (!vendor || vendor === "openrouter") return modelId;
434
+ return `${vendor}/${modelId}`;
435
+ }
426
436
  success(args) {
437
+ const routedViaOpenRouter = this.computeRoutedViaOpenRouter(
438
+ args.modelId,
439
+ args.record,
440
+ args.provider,
441
+ args.originalProvider
442
+ );
443
+ const modelId = routedViaOpenRouter ? this.toOpenRouterSlug(args.modelId, args.provider, args.record) : args.modelId;
427
444
  return {
428
445
  found: true,
429
- modelId: args.modelId,
446
+ modelId,
430
447
  record: args.record,
431
- routedViaOpenRouter: this.computeRoutedViaOpenRouter(
432
- args.modelId,
433
- args.record,
434
- args.provider,
435
- args.originalProvider
436
- ),
448
+ routedViaOpenRouter,
437
449
  confidence: args.confidence,
438
450
  resolvedVia: args.resolvedVia,
439
451
  resolvedReason: args.reason,
@@ -450,7 +462,7 @@ function supportsReasoningParameter(model) {
450
462
  );
451
463
  }
452
464
  function hasReasoningPricing(model) {
453
- const raw = _optionalChain([model, 'access', _3 => _3.openRouterPricing, 'optionalAccess', _4 => _4.internal_reasoning]);
465
+ const raw = _optionalChain([model, 'access', _4 => _4.openRouterPricing, 'optionalAccess', _5 => _5.internal_reasoning]);
454
466
  if (raw !== void 0 && raw !== null && String(raw).trim() !== "") {
455
467
  return true;
456
468
  }
@@ -475,4 +487,4 @@ function isReasoningModel(model) {
475
487
 
476
488
 
477
489
  exports.buildCatalogIndexes = buildCatalogIndexes; exports.ModelNameResolver = ModelNameResolver; exports.REASONING_SUPPORTED_PARAMETERS = REASONING_SUPPORTED_PARAMETERS; exports.supportsReasoningParameter = supportsReasoningParameter; exports.hasReasoningPricing = hasReasoningPricing; exports.computeSupportsReasoning = computeSupportsReasoning; exports.isReasoningModel = isReasoningModel;
478
- //# sourceMappingURL=chunk-DXZOL3VN.cjs.map
490
+ //# sourceMappingURL=chunk-RSHI4OOY.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-RSHI4OOY.cjs","../src/sync/modelNameResolver/catalogIndexes.ts","../src/sync/modelNameResolver/ModelNameResolver.ts","../src/models/reasoningModel.ts"],"names":[],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-RSHI4OOY.cjs","sourcesContent":[null,"import type { AiModelRecord } from \"../../models/types.js\";\nimport { normalizeString } from \"./normalize.js\";\nimport type { CatalogIndexes } from \"./types.js\";\n\nexport function buildCatalogIndexes(catalog: Map<string, AiModelRecord>): CatalogIndexes {\n const aliasIndex = new Map<string, string>();\n const slugIndex = new Map<string, string>();\n const prefixCounts = new Map<string, number>();\n\n for (const record of catalog.values()) {\n for (const alias of record.aliases) {\n aliasIndex.set(normalizeString(alias), record.modelId);\n }\n if (record.canonicalSlug) {\n slugIndex.set(normalizeString(record.canonicalSlug), record.modelId);\n }\n const pid = record.providerId;\n prefixCounts.set(pid, (prefixCounts.get(pid) ?? 0) + 1);\n }\n\n const providerPrefixesBySize = [...prefixCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([p]) => p);\n\n return { aliasIndex, slugIndex, providerPrefixesBySize };\n}\n","import { ModelResolutionError } from \"../../errors.js\";\nimport type { AiModelRecord } from \"../../models/types.js\";\nimport {\n loadOpenRouterRoutingEnv,\n shouldDefaultRouteViaOpenRouter,\n} from \"../openRouterRoutingEnv.js\";\nimport { buildCatalogIndexes } from \"./catalogIndexes.js\";\nimport {\n DEFAULT_CONFIDENCE_THRESHOLD,\n LOCAL_PROVIDERS,\n PROVIDER_INFERENCE_MAP,\n SHORTHAND_MAP,\n} from \"./constants.js\";\nimport { modelSlug, normalizeProvider, normalizeString, tokenise } from \"./normalize.js\";\nimport { stripModelSlugSuffix, stripModelVersionSuffix } from \"./stripVersionSuffix.js\";\nimport type {\n CatalogIndexes,\n ModelResolutionInput,\n ModelResolutionNotFound,\n ModelResolutionResult,\n ModelResolutionSuccess,\n ModelResolverOptions,\n ResolutionStrategy,\n ResolverContext,\n} from \"./types.js\";\n\ntype MatchCandidate = {\n modelId: string;\n record: AiModelRecord | null;\n confidence: number;\n strategy: ResolutionStrategy;\n reason: string;\n};\n\nexport class ModelNameResolver {\n private readonly catalog: Map<string, AiModelRecord>;\n private readonly indexes: CatalogIndexes;\n private readonly ctx: ResolverContext;\n\n constructor(\n catalog: Map<string, AiModelRecord>,\n options: ModelResolverOptions = {},\n ) {\n this.catalog = catalog;\n this.indexes = buildCatalogIndexes(catalog);\n this.ctx = {\n catalog,\n indexes: this.indexes,\n options: {\n confidenceThreshold: options.confidenceThreshold ?? DEFAULT_CONFIDENCE_THRESHOLD,\n aliasRegistry: options.aliasRegistry,\n additionalShorthands: options.additionalShorthands ?? {},\n additionalProviderPatterns: options.additionalProviderPatterns ?? [],\n additionalLocalProviders: options.additionalLocalProviders ?? [],\n routingEnv: options.routingEnv ?? loadOpenRouterRoutingEnv(),\n routeViaOpenRouter: options.routeViaOpenRouter,\n },\n };\n }\n\n resolve(input: ModelResolutionInput): ModelResolutionResult {\n const attempted: ResolutionStrategy[] = [];\n const threshold = this.ctx.options.confidenceThreshold;\n\n let provider = normalizeProvider(input.provider);\n let model = normalizeString(input.model);\n const normalisedInput = model;\n\n // S0 — alias registry on model string\n if (this.ctx.options.aliasRegistry) {\n attempted.push(\"alias-registry\");\n const entry = this.ctx.options.aliasRegistry.get(model);\n if (entry) {\n model = normalizeString(entry.modelId);\n provider = normalizeProvider(entry.provider) ?? provider;\n }\n }\n\n // Alias used as provider name (e.g. provider=\"best\")\n if (this.ctx.options.aliasRegistry && provider) {\n const aliasAsProvider = this.ctx.options.aliasRegistry.get(provider);\n if (aliasAsProvider) {\n attempted.push(\"alias-as-provider-correction\");\n model = normalizeString(aliasAsProvider.modelId);\n provider = normalizeProvider(aliasAsProvider.provider) ?? provider;\n }\n }\n\n // S10 — local provider (before catalog strategies)\n const localProviders = new Set([\n ...LOCAL_PROVIDERS,\n ...this.ctx.options.additionalLocalProviders.map((p) => normalizeString(p)),\n ]);\n if (provider && localProviders.has(provider)) {\n attempted.push(\"local-provider-passthrough\");\n return this.success({\n modelId: model,\n record: null,\n confidence: 0.99,\n strategy: \"local-provider-passthrough\",\n reason: `Local provider \"${provider}\" — model not looked up in catalog`,\n resolvedVia: attempted,\n normalisedInput,\n provider,\n originalProvider: input.provider,\n });\n }\n\n const preCorrection = [...attempted];\n\n const { match, rejected } = this.runPipeline(model, provider, attempted, threshold, []);\n if (match) {\n const via = [\n ...preCorrection.filter((s) => !match.resolvedVia.includes(s)),\n ...match.resolvedVia,\n ];\n return this.success({\n modelId: match.modelId,\n record: match.record,\n confidence: match.confidence,\n strategy: match.strategy,\n reason: match.reason,\n resolvedVia: via,\n normalisedInput,\n provider,\n originalProvider: input.provider,\n });\n }\n\n const notFound: ModelResolutionNotFound = {\n found: false,\n modelId: null,\n record: null,\n attemptedStrategies: attempted,\n reason: \"No catalog entry matched after all strategies.\",\n bestRejectedCandidate: rejected,\n };\n return notFound;\n }\n\n resolveMany(inputs: ModelResolutionInput[]): ModelResolutionResult[] {\n return inputs.map((i) => this.resolve(i));\n }\n\n resolveOrThrow(input: ModelResolutionInput): ModelResolutionSuccess {\n const result = this.resolve(input);\n if (result.found) return result;\n throw new ModelResolutionError(input, result);\n }\n\n private runPipeline(\n model: string,\n provider: string | undefined,\n attempted: ResolutionStrategy[],\n threshold: number,\n resolvedVia: ResolutionStrategy[],\n depth = 0,\n ): {\n match: (MatchCandidate & { resolvedVia: ResolutionStrategy[] }) | null;\n rejected?: ModelResolutionNotFound[\"bestRejectedCandidate\"];\n } {\n if (depth > 12) return { match: null };\n\n const tryMatch = (\n strategy: ResolutionStrategy,\n fn: () => MatchCandidate | null,\n ): (MatchCandidate & { resolvedVia: ResolutionStrategy[] }) | null => {\n if (!attempted.includes(strategy)) attempted.push(strategy);\n const m = fn();\n if (m && m.confidence >= threshold) {\n return { ...m, resolvedVia: [...resolvedVia, strategy] };\n }\n return null;\n };\n\n let hit = tryMatch(\"exact-match\", () => this.exactMatch(model));\n if (hit) return { match: hit };\n\n hit = tryMatch(\"catalog-alias-match\", () => this.catalogAliasMatch(model));\n if (hit) return { match: hit };\n\n hit = tryMatch(\"canonical-slug-match\", () => this.slugMatch(model));\n if (hit) return { match: hit };\n\n hit = tryMatch(\"provider-prefix-injection\", () =>\n this.providerPrefixInjection(model, provider),\n );\n if (hit) return { match: hit };\n\n hit = tryMatch(\"cross-provider-correction\", () => this.crossProviderCorrection(model));\n if (hit) return { match: hit };\n\n const stripped = stripModelVersionSuffix(model);\n if (stripped && stripped !== model) {\n if (!attempted.includes(\"version-suffix-strip\")) attempted.push(\"version-suffix-strip\");\n const inner = this.runPipeline(\n stripped,\n provider,\n attempted,\n threshold,\n [...resolvedVia, \"version-suffix-strip\"],\n depth + 1,\n );\n if (inner.match) {\n return {\n match: {\n ...inner.match,\n confidence: 0.85,\n strategy: \"version-suffix-strip\",\n reason: `Stripped version suffix from \"${model}\" → \"${stripped}\" then ${inner.match.reason}`,\n resolvedVia: [...resolvedVia, \"version-suffix-strip\", ...inner.match.resolvedVia],\n },\n };\n }\n }\n\n hit = tryMatch(\"date-suffix-strip\", () => this.dateSuffixMatch(model));\n if (hit) return { match: hit };\n\n const shorthand = this.shorthandMap()[model];\n if (shorthand) {\n if (!attempted.includes(\"shorthand-expansion\")) attempted.push(\"shorthand-expansion\");\n const inner = this.runPipeline(\n normalizeString(shorthand),\n provider,\n attempted,\n threshold,\n [...resolvedVia, \"shorthand-expansion\"],\n depth + 1,\n );\n if (inner.match) {\n return {\n match: {\n ...inner.match,\n confidence: 0.8,\n strategy: \"shorthand-expansion\",\n reason: `Expanded shorthand \"${model}\" → \"${shorthand}\" then ${inner.match.reason}`,\n resolvedVia: [...resolvedVia, \"shorthand-expansion\", ...inner.match.resolvedVia],\n },\n };\n }\n }\n\n const partial = this.partialMatch(model, provider);\n if (partial) {\n if (!attempted.includes(\"partial-name-match\")) attempted.push(\"partial-name-match\");\n if (partial.confidence >= threshold) {\n return {\n match: { ...partial, resolvedVia: [...resolvedVia, \"partial-name-match\"] },\n };\n }\n return {\n match: null,\n rejected: {\n modelId: partial.modelId,\n confidence: partial.confidence,\n reason: partial.reason,\n },\n };\n }\n\n return { match: null };\n }\n\n private exactMatch(model: string): MatchCandidate | null {\n const record = this.catalog.get(model);\n if (!record) return null;\n return {\n modelId: model,\n record,\n confidence: 1,\n strategy: \"exact-match\",\n reason: `Exact catalog match for \"${model}\"`,\n };\n }\n\n private catalogAliasMatch(model: string): MatchCandidate | null {\n const modelId = this.indexes.aliasIndex.get(model);\n if (!modelId) return null;\n const record = this.catalog.get(modelId);\n if (!record) return null;\n return {\n modelId,\n record,\n confidence: 1,\n strategy: \"catalog-alias-match\",\n reason: `Catalog alias \"${model}\" → \"${modelId}\"`,\n };\n }\n\n private slugMatch(model: string): MatchCandidate | null {\n const modelId = this.indexes.slugIndex.get(model);\n if (!modelId) return null;\n const record = this.catalog.get(modelId);\n if (!record) return null;\n return {\n modelId,\n record,\n confidence: 0.95,\n strategy: \"canonical-slug-match\",\n reason: `Canonical slug match \"${model}\" → \"${modelId}\"`,\n };\n }\n\n private inferProviderFromSlug(slug: string): string | undefined {\n const patterns = [\n ...this.ctx.options.additionalProviderPatterns,\n ...PROVIDER_INFERENCE_MAP,\n ];\n for (const { pattern, provider } of patterns) {\n if (pattern.test(slug)) return provider;\n }\n return undefined;\n }\n\n private providerPrefixInjection(\n model: string,\n provider: string | undefined,\n ): MatchCandidate | null {\n if (model.includes(\"/\")) return null;\n\n const prefixes: string[] = [];\n if (provider && provider !== \"openrouter\") {\n prefixes.push(provider);\n }\n const inferred = this.inferProviderFromSlug(model);\n if (inferred && !prefixes.includes(inferred)) prefixes.push(inferred);\n for (const p of this.indexes.providerPrefixesBySize) {\n if (!prefixes.includes(p)) prefixes.push(p);\n }\n\n for (const prefix of prefixes) {\n const candidate = `${prefix}/${model}`;\n let record = this.catalog.get(candidate);\n let modelId = candidate;\n if (!record) {\n const latest = this.findLatestVersioned(candidate);\n if (latest) {\n record = latest.record;\n modelId = latest.modelId;\n }\n }\n if (record) {\n const viaInference = inferred === prefix;\n return {\n modelId,\n record,\n confidence: 0.95,\n strategy: \"provider-prefix-injection\",\n reason: viaInference\n ? `Injected provider prefix \"${prefix}/\" inferred from model name pattern`\n : `Injected provider prefix \"${prefix}/\"`,\n };\n }\n }\n return null;\n }\n\n private crossProviderCorrection(model: string): MatchCandidate | null {\n if (!model.includes(\"/\")) return null;\n const [wrongPrefix, ...rest] = model.split(\"/\");\n const slug = rest.join(\"/\");\n const inferred = this.inferProviderFromSlug(slug);\n if (!inferred || inferred === wrongPrefix) return null;\n const candidate = `${inferred}/${slug}`;\n let record = this.catalog.get(candidate);\n let modelId = candidate;\n if (!record) {\n const latest = this.findLatestVersioned(candidate);\n if (!latest) return null;\n record = latest.record;\n modelId = latest.modelId;\n }\n return {\n modelId,\n record,\n confidence: 0.9,\n strategy: \"cross-provider-correction\",\n reason: `Corrected provider prefix from \"${wrongPrefix}\" to \"${inferred}\" based on model name pattern`,\n };\n }\n\n private dateSuffixMatch(model: string): MatchCandidate | null {\n if (model.includes(\"/\")) {\n const [prefix, slug] = model.split(\"/\", 2);\n const stripped = stripModelSlugSuffix(slug);\n if (stripped && stripped !== slug) {\n const candidate = `${prefix}/${stripped}`;\n const record = this.catalog.get(candidate);\n if (record) {\n return {\n modelId: candidate,\n record,\n confidence: 0.85,\n strategy: \"date-suffix-strip\",\n reason: `Stripped date from slug \"${slug}\" → \"${stripped}\"`,\n };\n }\n }\n }\n\n const latest = this.findLatestVersioned(model);\n if (latest) {\n return {\n modelId: latest.modelId,\n record: latest.record,\n confidence: 0.85,\n strategy: \"date-suffix-strip\",\n reason: `Matched \"${model}\" to versioned catalog entry \"${latest.modelId}\" (latest)`,\n };\n }\n return null;\n }\n\n private findLatestVersioned(\n baseModelId: string,\n ): { modelId: string; record: AiModelRecord } | null {\n const candidates: Array<{ modelId: string; record: AiModelRecord; suffix: string }> = [];\n for (const [modelId, record] of this.catalog) {\n if (modelId === baseModelId) continue;\n if (modelId.startsWith(`${baseModelId}-`)) {\n candidates.push({\n modelId,\n record,\n suffix: modelId.slice(baseModelId.length + 1),\n });\n }\n }\n if (candidates.length === 0) return null;\n candidates.sort((a, b) => b.suffix.localeCompare(a.suffix));\n const best = candidates[0]!;\n return { modelId: best.modelId, record: best.record };\n }\n\n private shorthandMap(): Record<string, string> {\n return { ...SHORTHAND_MAP, ...this.ctx.options.additionalShorthands };\n }\n\n private partialMatch(\n model: string,\n provider: string | undefined,\n ): (MatchCandidate & { resolvedVia?: ResolutionStrategy[] }) | null {\n let best: { modelId: string; record: AiModelRecord; score: number } | null = null;\n const inputTokens = tokenise(model);\n if (inputTokens.length === 0) return null;\n\n for (const record of this.catalog.values()) {\n const recordTokens = new Set([\n ...tokenise(record.modelId),\n ...tokenise(record.name ?? \"\"),\n ]);\n const intersection = inputTokens.filter((t) => recordTokens.has(t));\n const overlapRatio = intersection.length / inputTokens.length;\n let score = overlapRatio * 0.6;\n\n if (record.modelId.includes(model)) score += 0.3;\n const slug = modelSlug(record.modelId);\n if (model.includes(slug)) score += 0.2;\n\n if (provider && provider === record.providerId) score += 0.15;\n\n const lenPenalty =\n (Math.abs(model.length - slug.length) / Math.max(model.length, slug.length, 1)) * 0.1;\n score -= lenPenalty;\n\n if (!best || score > best.score) {\n best = { modelId: record.modelId, record, score };\n }\n }\n\n if (!best || best.score < 0.65) return null;\n return {\n modelId: best.modelId,\n record: best.record,\n confidence: 0.65,\n strategy: \"partial-name-match\",\n reason: `Partial token match (score ${best.score.toFixed(2)})`,\n };\n }\n\n private computeRoutedViaOpenRouter(\n modelId: string,\n record: AiModelRecord | null,\n provider: string | undefined,\n originalProvider: string | undefined,\n ): boolean {\n const override = this.ctx.options.routeViaOpenRouter;\n if (override === true) return true;\n if (override === false) return false;\n\n const norm = normalizeProvider(originalProvider) ?? provider;\n if (norm === \"openrouter\") return true;\n if (norm && norm !== \"openrouter\") {\n if (shouldDefaultRouteViaOpenRouter(norm, this.ctx.options.routingEnv)) return true;\n return false;\n }\n\n const recordProvider = record?.providerId;\n if (recordProvider && shouldDefaultRouteViaOpenRouter(recordProvider, this.ctx.options.routingEnv)) {\n return true;\n }\n\n if (record?.availableOnOpenRouter && modelId.includes(\"/\")) return true;\n return false;\n }\n\n private toOpenRouterSlug(\n modelId: string,\n provider: string | undefined,\n record: AiModelRecord | null,\n ): string {\n if (modelId.includes(\"/\")) return modelId;\n const vendor =\n record?.providerId ??\n (provider && provider !== \"openrouter\" ? provider : undefined);\n if (!vendor || vendor === \"openrouter\") return modelId;\n return `${vendor}/${modelId}`;\n }\n\n private success(args: {\n modelId: string;\n record: AiModelRecord | null;\n confidence: number;\n strategy: ResolutionStrategy;\n reason: string;\n resolvedVia: ResolutionStrategy[];\n normalisedInput: string;\n provider?: string;\n originalProvider?: string;\n }): ModelResolutionSuccess {\n const routedViaOpenRouter = this.computeRoutedViaOpenRouter(\n args.modelId,\n args.record,\n args.provider,\n args.originalProvider,\n );\n const modelId = routedViaOpenRouter\n ? this.toOpenRouterSlug(args.modelId, args.provider, args.record)\n : args.modelId;\n\n return {\n found: true,\n modelId,\n record: args.record,\n routedViaOpenRouter,\n confidence: args.confidence,\n resolvedVia: args.resolvedVia,\n resolvedReason: args.reason,\n normalisedInput: args.normalisedInput,\n };\n }\n}\n","import type { AiModelRecord } from \"./types.js\";\n\n/** OpenRouter `supported_parameters` values that indicate reasoning API support. */\nexport const REASONING_SUPPORTED_PARAMETERS = [\"reasoning\", \"include_reasoning\"] as const;\n\nexport type ReasoningModelInput = Pick<\n AiModelRecord,\n \"supportedParameters\" | \"pricing\" | \"openRouterPricing\"\n> & {\n supportsReasoning?: boolean;\n};\n\n/**\n * Whether the model accepts OpenRouter's `reasoning` request parameter\n * (effort, max_tokens, exclude, enabled).\n */\nexport function supportsReasoningParameter(model: Pick<AiModelRecord, \"supportedParameters\">): boolean {\n return model.supportedParameters.some((p) =>\n (REASONING_SUPPORTED_PARAMETERS as readonly string[]).includes(p),\n );\n}\n\n/**\n * Whether the model bills separate reasoning / thinking tokens\n * (`internal_reasoning` in OpenRouter pricing).\n */\nexport function hasReasoningPricing(\n model: Pick<AiModelRecord, \"pricing\" | \"openRouterPricing\">,\n): boolean {\n const raw = model.openRouterPricing?.internal_reasoning;\n if (raw !== undefined && raw !== null && String(raw).trim() !== \"\") {\n return true;\n }\n return model.pricing.reasoningUsdPerToken !== undefined;\n}\n\n/**\n * Compute `supportsReasoning` from catalog fields (used when normalizing catalog entries).\n */\nexport function computeSupportsReasoning(model: ReasoningModelInput): boolean {\n return supportsReasoningParameter(model) || hasReasoningPricing(model);\n}\n\n/**\n * True when the model supports reasoning tokens (API param and/or separate reasoning pricing).\n *\n * Prefer `model.supportsReasoning` on {@link AiModelRecord} after catalog load;\n * this helper also works when only partial fields are available.\n */\nexport function isReasoningModel(model: ReasoningModelInput): boolean {\n if (model.supportsReasoning !== undefined) {\n return model.supportsReasoning;\n }\n return computeSupportsReasoning(model);\n}\n"]}
@@ -170,6 +170,18 @@ function shouldDefaultRouteViaOpenRouter(providerId, config) {
170
170
  }
171
171
  return false;
172
172
  }
173
+ function isEffectiveOpenRouterTransport(config, input = {}) {
174
+ if (input.routeViaOpenRouter === true) return true;
175
+ if (input.routeViaOpenRouter === false) return false;
176
+ const provider = input.provider?.trim().toLowerCase();
177
+ if (provider === "openrouter") return true;
178
+ const vendor = input.modelId?.includes("/") === true ? input.modelId.split("/")[0].trim().toLowerCase() : provider;
179
+ if (vendor && vendor !== "openrouter") {
180
+ return shouldDefaultRouteViaOpenRouter(vendor, config);
181
+ }
182
+ if (config.hasOpenRouterKey && config.useOpenRouterExplicit) return true;
183
+ return false;
184
+ }
173
185
 
174
186
  // src/sync/modelNameResolver/stripVersionSuffix.ts
175
187
  var VERSION_STRIP_PATTERNS = [
@@ -220,6 +232,7 @@ export {
220
232
  providerIdToEnvKeyPrefix,
221
233
  vendorApiKeyEnvName,
222
234
  loadOpenRouterRoutingEnv,
223
- shouldDefaultRouteViaOpenRouter
235
+ shouldDefaultRouteViaOpenRouter,
236
+ isEffectiveOpenRouterTransport
224
237
  };
225
- //# sourceMappingURL=chunk-B3V2EHRY.js.map
238
+ //# sourceMappingURL=chunk-SLSKQRMI.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sync/modelNameResolver/constants.ts","../src/sync/modelNameResolver/normalize.ts","../src/sync/openRouterRoutingEnv.ts","../src/sync/modelNameResolver/stripVersionSuffix.ts"],"sourcesContent":["export const DEFAULT_CONFIDENCE_THRESHOLD = 0.6;\n\nexport const PROVIDER_NORMALISATION_MAP: Record<string, string> = {\n \"open-router\": \"openrouter\",\n or: \"openrouter\",\n oai: \"openai\",\n \"open-ai\": \"openai\",\n claude: \"anthropic\",\n ant: \"anthropic\",\n gemini: \"google\",\n gcp: \"google\",\n \"google-ai\": \"google\",\n vertex: \"google\",\n meta: \"meta-llama\",\n llama: \"meta-llama\",\n \"mistral-ai\": \"mistral\",\n \"cohere-ai\": \"cohere\",\n};\n\nexport const LOCAL_PROVIDERS = new Set([\n \"ollama\",\n \"lmstudio\",\n \"lm-studio\",\n \"localai\",\n \"local-ai\",\n \"llamacpp\",\n \"llama.cpp\",\n \"llamafile\",\n \"jan\",\n \"koboldcpp\",\n]);\n\nexport const PROVIDER_INFERENCE_MAP: Array<{\n pattern: RegExp;\n provider: string;\n notes?: string;\n}> = [\n { pattern: /^gpt-/, provider: \"openai\" },\n { pattern: /^o1($|-)/, provider: \"openai\" },\n { pattern: /^o3($|-)/, provider: \"openai\" },\n { pattern: /^o4($|-)/, provider: \"openai\" },\n { pattern: /^chatgpt-/, provider: \"openai\" },\n { pattern: /^text-davinci/, provider: \"openai\" },\n { pattern: /^dall-e/, provider: \"openai\" },\n { pattern: /^whisper/, provider: \"openai\" },\n { pattern: /^tts-/, provider: \"openai\" },\n { pattern: /^claude-/, provider: \"anthropic\" },\n { pattern: /^gemini-/, provider: \"google\" },\n { pattern: /^palm-/, provider: \"google\" },\n { pattern: /^bison/, provider: \"google\" },\n { pattern: /^llama-?[23]/, provider: \"meta-llama\" },\n { pattern: /^llama/, provider: \"meta-llama\" },\n { pattern: /^codellama/, provider: \"meta-llama\" },\n { pattern: /^mistral-/, provider: \"mistral\" },\n { pattern: /^mixtral-/, provider: \"mistral\" },\n { pattern: /^codestral/, provider: \"mistral\" },\n { pattern: /^ministral/, provider: \"mistral\" },\n { pattern: /^command-/, provider: \"cohere\" },\n { pattern: /^c4ai-/, provider: \"cohere\" },\n { pattern: /^deepseek-/, provider: \"deepseek\" },\n { pattern: /^grok-/, provider: \"x-ai\" },\n { pattern: /^qwen/, provider: \"qwen\" },\n { pattern: /^yi-/, provider: \"01-ai\" },\n { pattern: /^sonar/, provider: \"perplexity\" },\n { pattern: /^pplx-/, provider: \"perplexity\" },\n { pattern: /^titan-/, provider: \"amazon\" },\n { pattern: /^nova-/, provider: \"amazon\" },\n];\n\nexport const SHORTHAND_MAP: Record<string, string> = {\n gpt4: \"openai/gpt-4\",\n gpt4o: \"openai/gpt-4o\",\n \"gpt-4-omni\": \"openai/gpt-4o\",\n gpt4omni: \"openai/gpt-4o\",\n \"gpt4-turbo\": \"openai/gpt-4-turbo\",\n gpt4turbo: \"openai/gpt-4-turbo\",\n \"gpt4-mini\": \"openai/gpt-4o-mini\",\n \"gpt-4o-mini\": \"openai/gpt-4o-mini\",\n o1: \"openai/o1\",\n \"o1-mini\": \"openai/o1-mini\",\n o3: \"openai/o3\",\n \"o3-mini\": \"openai/o3-mini\",\n \"o4-mini\": \"openai/o4-mini\",\n \"3.5-turbo\": \"openai/gpt-3.5-turbo\",\n gpt35: \"openai/gpt-3.5-turbo\",\n gpt3: \"openai/gpt-3.5-turbo\",\n claude3: \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude-3\": \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude3-sonnet\": \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude-sonnet\": \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude-haiku\": \"anthropic/claude-3-5-haiku-20241022\",\n \"claude3-haiku\": \"anthropic/claude-3-5-haiku-20241022\",\n \"claude-opus\": \"anthropic/claude-opus-4\",\n \"claude3-opus\": \"anthropic/claude-3-opus-20240229\",\n claude4: \"anthropic/claude-opus-4\",\n \"claude4-sonnet\": \"anthropic/claude-sonnet-4\",\n \"claude4-opus\": \"anthropic/claude-opus-4\",\n sonnet: \"anthropic/claude-3-5-sonnet-20241022\",\n haiku: \"anthropic/claude-3-5-haiku-20241022\",\n opus: \"anthropic/claude-opus-4\",\n gemini: \"google/gemini-pro\",\n \"gemini-pro\": \"google/gemini-pro\",\n \"gemini-flash\": \"google/gemini-flash-1.5\",\n gemini2: \"google/gemini-2.0-flash-001\",\n \"gemini-2\": \"google/gemini-2.0-flash-001\",\n llama3: \"meta-llama/llama-3.1-8b-instruct\",\n \"llama-3\": \"meta-llama/llama-3.1-8b-instruct\",\n llama2: \"meta-llama/llama-2-13b-chat\",\n \"llama-2\": \"meta-llama/llama-2-13b-chat\",\n mistral: \"mistral/mistral-7b-instruct\",\n \"mistral-large\": \"mistral/mistral-large-latest\",\n mixtral: \"mistral/mixtral-8x7b-instruct\",\n deepseek: \"deepseek/deepseek-chat\",\n \"deepseek-r1\": \"deepseek/deepseek-r1\",\n};\n","import { PROVIDER_NORMALISATION_MAP } from \"./constants.js\";\n\nexport function normalizeString(input: string): string {\n let s = input.trim();\n s = s.replace(/\\s+/g, \" \").replace(/ /g, \"-\");\n s = s.toLowerCase();\n s = s.replace(/^\\/+|\\/+$/g, \"\");\n s = s.replace(/\\/+/g, \"/\");\n if (\n (s.startsWith('\"') && s.endsWith('\"')) ||\n (s.startsWith(\"'\") && s.endsWith(\"'\"))\n ) {\n s = s.slice(1, -1);\n }\n return s;\n}\n\nexport function normalizeProvider(provider: string | undefined): string | undefined {\n if (provider === undefined || provider === \"\") return undefined;\n const n = normalizeString(provider);\n return PROVIDER_NORMALISATION_MAP[n] ?? n;\n}\n\nexport function tokenise(s: string): string[] {\n return s.split(/[-_./]+/).filter(Boolean);\n}\n\nexport function modelSlug(modelId: string): string {\n const slash = modelId.indexOf(\"/\");\n return slash >= 0 ? modelId.slice(slash + 1) : modelId;\n}\n","import { loadDotenv } from \"@x12i/env\";\n\n/**\n * Env naming for vendor direct API keys: `{VENDOR}_API_KEY`\n * where VENDOR is the provider id in UPPER_SNAKE (hyphens → underscores).\n *\n * Examples: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `META_LLAMA_API_KEY`, `X_AI_API_KEY`\n */\nexport function providerIdToEnvKeyPrefix(providerId: string): string {\n return providerId\n .trim()\n .toLowerCase()\n .replace(/-/g, \"_\")\n .toUpperCase();\n}\n\nexport function vendorApiKeyEnvName(providerId: string): string {\n return `${providerIdToEnvKeyPrefix(providerId)}_API_KEY`;\n}\n\nexport type OpenRouterRoutingConfig = {\n /** OPENROUTER_API_KEY is set and non-empty */\n hasOpenRouterKey: boolean;\n /** USE_OPENROUTER=true or USE_OPENROUTER=1 */\n useOpenRouterExplicit: boolean;\n /** Read `{PROVIDER}_API_KEY` for a catalog provider id */\n getVendorApiKey(providerId: string): string | undefined;\n};\n\n/**\n * Load routing hints from process env and optional `.env` (via @x12/env).\n */\nexport function loadOpenRouterRoutingEnv(\n env: Record<string, string | undefined> = process.env,\n): OpenRouterRoutingConfig {\n const dotenv = loadDotenv();\n const merged: Record<string, string> = {};\n for (const [k, v] of Object.entries(dotenv)) {\n if (v !== undefined) merged[k] = v;\n }\n for (const [k, v] of Object.entries(env)) {\n if (v !== undefined) merged[k] = v;\n }\n\n const openRouterKey = merged.OPENROUTER_API_KEY?.trim();\n const useRaw = merged.USE_OPENROUTER?.trim().toLowerCase();\n const useOpenRouterExplicit = useRaw === \"true\" || useRaw === \"1\";\n\n return {\n hasOpenRouterKey: Boolean(openRouterKey),\n useOpenRouterExplicit,\n getVendorApiKey(providerId: string) {\n const name = vendorApiKeyEnvName(providerId);\n const val = merged[name]?.trim();\n return val || undefined;\n },\n };\n}\n\n/**\n * Default route via OpenRouter when:\n * 1. OPENROUTER_API_KEY is set AND USE_OPENROUTER=true|1, or\n * 2. OPENROUTER_API_KEY is set AND the vendor's `{VENDOR}_API_KEY` is missing.\n */\nexport function shouldDefaultRouteViaOpenRouter(\n providerId: string | undefined,\n config: OpenRouterRoutingConfig,\n): boolean {\n if (!config.hasOpenRouterKey) return false;\n if (config.useOpenRouterExplicit) return true;\n if (providerId && providerId !== \"openrouter\") {\n return !config.getVendorApiKey(providerId);\n }\n return false;\n}\n","import { normalizeString } from \"./normalize.js\";\n\n/** Patterns stripped when resolving versioned runtime model ids to catalog entries. */\nexport const VERSION_STRIP_PATTERNS: ReadonlyArray<{ re: RegExp; label: string }> = [\n { re: /-\\d{4}-\\d{2}-\\d{2}$/, label: \"date YYYY-MM-DD\" },\n { re: /-\\d{8}$/, label: \"date YYYYMMDD\" },\n { re: /-v\\d+$/, label: \"version -vN\" },\n { re: /-\\d+\\.\\d+\\.\\d+$/, label: \"semver\" },\n { re: /:\\d+[a-z]?$/i, label: \"colon version\" },\n { re: /-\\d{4,}$/, label: \"build number\" },\n { re: /@\\d+$/, label: \"epoch @NNNN\" },\n];\n\n/** Strip version/date suffix from a bare slug (no `provider/` prefix). */\nexport function stripModelSlugSuffix(slug: string): string | null {\n for (const { re } of VERSION_STRIP_PATTERNS) {\n if (re.test(slug)) {\n return slug.replace(re, \"\");\n }\n }\n return null;\n}\n\n/**\n * Strip a version/date suffix from a model id (`gpt-5.5-2026-04-23` → `gpt-5.5`,\n * `openai/gpt-4o-2024-08-06` → `openai/gpt-4o`). Returns null when nothing was stripped.\n */\nexport function stripModelVersionSuffix(model: string): string | null {\n const normalized = normalizeString(model);\n if (!normalized) return null;\n\n if (normalized.includes(\"/\")) {\n const slash = normalized.indexOf(\"/\");\n const prefix = normalized.slice(0, slash);\n const slug = normalized.slice(slash + 1);\n const stripped = stripModelSlugSuffix(slug);\n if (stripped && stripped !== slug) {\n return `${prefix}/${stripped}`;\n }\n return null;\n }\n\n const stripped = stripModelSlugSuffix(normalized);\n return stripped && stripped !== normalized ? stripped : null;\n}\n"],"mappings":"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","names":["stripped"]}
1
+ {"version":3,"sources":["../src/sync/modelNameResolver/constants.ts","../src/sync/modelNameResolver/normalize.ts","../src/sync/openRouterRoutingEnv.ts","../src/sync/modelNameResolver/stripVersionSuffix.ts"],"sourcesContent":["export const DEFAULT_CONFIDENCE_THRESHOLD = 0.6;\n\nexport const PROVIDER_NORMALISATION_MAP: Record<string, string> = {\n \"open-router\": \"openrouter\",\n or: \"openrouter\",\n oai: \"openai\",\n \"open-ai\": \"openai\",\n claude: \"anthropic\",\n ant: \"anthropic\",\n gemini: \"google\",\n gcp: \"google\",\n \"google-ai\": \"google\",\n vertex: \"google\",\n meta: \"meta-llama\",\n llama: \"meta-llama\",\n \"mistral-ai\": \"mistral\",\n \"cohere-ai\": \"cohere\",\n};\n\nexport const LOCAL_PROVIDERS = new Set([\n \"ollama\",\n \"lmstudio\",\n \"lm-studio\",\n \"localai\",\n \"local-ai\",\n \"llamacpp\",\n \"llama.cpp\",\n \"llamafile\",\n \"jan\",\n \"koboldcpp\",\n]);\n\nexport const PROVIDER_INFERENCE_MAP: Array<{\n pattern: RegExp;\n provider: string;\n notes?: string;\n}> = [\n { pattern: /^gpt-/, provider: \"openai\" },\n { pattern: /^o1($|-)/, provider: \"openai\" },\n { pattern: /^o3($|-)/, provider: \"openai\" },\n { pattern: /^o4($|-)/, provider: \"openai\" },\n { pattern: /^chatgpt-/, provider: \"openai\" },\n { pattern: /^text-davinci/, provider: \"openai\" },\n { pattern: /^dall-e/, provider: \"openai\" },\n { pattern: /^whisper/, provider: \"openai\" },\n { pattern: /^tts-/, provider: \"openai\" },\n { pattern: /^claude-/, provider: \"anthropic\" },\n { pattern: /^gemini-/, provider: \"google\" },\n { pattern: /^palm-/, provider: \"google\" },\n { pattern: /^bison/, provider: \"google\" },\n { pattern: /^llama-?[23]/, provider: \"meta-llama\" },\n { pattern: /^llama/, provider: \"meta-llama\" },\n { pattern: /^codellama/, provider: \"meta-llama\" },\n { pattern: /^mistral-/, provider: \"mistral\" },\n { pattern: /^mixtral-/, provider: \"mistral\" },\n { pattern: /^codestral/, provider: \"mistral\" },\n { pattern: /^ministral/, provider: \"mistral\" },\n { pattern: /^command-/, provider: \"cohere\" },\n { pattern: /^c4ai-/, provider: \"cohere\" },\n { pattern: /^deepseek-/, provider: \"deepseek\" },\n { pattern: /^grok-/, provider: \"x-ai\" },\n { pattern: /^qwen/, provider: \"qwen\" },\n { pattern: /^yi-/, provider: \"01-ai\" },\n { pattern: /^sonar/, provider: \"perplexity\" },\n { pattern: /^pplx-/, provider: \"perplexity\" },\n { pattern: /^titan-/, provider: \"amazon\" },\n { pattern: /^nova-/, provider: \"amazon\" },\n];\n\nexport const SHORTHAND_MAP: Record<string, string> = {\n gpt4: \"openai/gpt-4\",\n gpt4o: \"openai/gpt-4o\",\n \"gpt-4-omni\": \"openai/gpt-4o\",\n gpt4omni: \"openai/gpt-4o\",\n \"gpt4-turbo\": \"openai/gpt-4-turbo\",\n gpt4turbo: \"openai/gpt-4-turbo\",\n \"gpt4-mini\": \"openai/gpt-4o-mini\",\n \"gpt-4o-mini\": \"openai/gpt-4o-mini\",\n o1: \"openai/o1\",\n \"o1-mini\": \"openai/o1-mini\",\n o3: \"openai/o3\",\n \"o3-mini\": \"openai/o3-mini\",\n \"o4-mini\": \"openai/o4-mini\",\n \"3.5-turbo\": \"openai/gpt-3.5-turbo\",\n gpt35: \"openai/gpt-3.5-turbo\",\n gpt3: \"openai/gpt-3.5-turbo\",\n claude3: \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude-3\": \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude3-sonnet\": \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude-sonnet\": \"anthropic/claude-3-5-sonnet-20241022\",\n \"claude-haiku\": \"anthropic/claude-3-5-haiku-20241022\",\n \"claude3-haiku\": \"anthropic/claude-3-5-haiku-20241022\",\n \"claude-opus\": \"anthropic/claude-opus-4\",\n \"claude3-opus\": \"anthropic/claude-3-opus-20240229\",\n claude4: \"anthropic/claude-opus-4\",\n \"claude4-sonnet\": \"anthropic/claude-sonnet-4\",\n \"claude4-opus\": \"anthropic/claude-opus-4\",\n sonnet: \"anthropic/claude-3-5-sonnet-20241022\",\n haiku: \"anthropic/claude-3-5-haiku-20241022\",\n opus: \"anthropic/claude-opus-4\",\n gemini: \"google/gemini-pro\",\n \"gemini-pro\": \"google/gemini-pro\",\n \"gemini-flash\": \"google/gemini-flash-1.5\",\n gemini2: \"google/gemini-2.0-flash-001\",\n \"gemini-2\": \"google/gemini-2.0-flash-001\",\n llama3: \"meta-llama/llama-3.1-8b-instruct\",\n \"llama-3\": \"meta-llama/llama-3.1-8b-instruct\",\n llama2: \"meta-llama/llama-2-13b-chat\",\n \"llama-2\": \"meta-llama/llama-2-13b-chat\",\n mistral: \"mistral/mistral-7b-instruct\",\n \"mistral-large\": \"mistral/mistral-large-latest\",\n mixtral: \"mistral/mixtral-8x7b-instruct\",\n deepseek: \"deepseek/deepseek-chat\",\n \"deepseek-r1\": \"deepseek/deepseek-r1\",\n};\n","import { PROVIDER_NORMALISATION_MAP } from \"./constants.js\";\n\nexport function normalizeString(input: string): string {\n let s = input.trim();\n s = s.replace(/\\s+/g, \" \").replace(/ /g, \"-\");\n s = s.toLowerCase();\n s = s.replace(/^\\/+|\\/+$/g, \"\");\n s = s.replace(/\\/+/g, \"/\");\n if (\n (s.startsWith('\"') && s.endsWith('\"')) ||\n (s.startsWith(\"'\") && s.endsWith(\"'\"))\n ) {\n s = s.slice(1, -1);\n }\n return s;\n}\n\nexport function normalizeProvider(provider: string | undefined): string | undefined {\n if (provider === undefined || provider === \"\") return undefined;\n const n = normalizeString(provider);\n return PROVIDER_NORMALISATION_MAP[n] ?? n;\n}\n\nexport function tokenise(s: string): string[] {\n return s.split(/[-_./]+/).filter(Boolean);\n}\n\nexport function modelSlug(modelId: string): string {\n const slash = modelId.indexOf(\"/\");\n return slash >= 0 ? modelId.slice(slash + 1) : modelId;\n}\n","import { loadDotenv } from \"@x12i/env\";\n\n/**\n * Env naming for vendor direct API keys: `{VENDOR}_API_KEY`\n * where VENDOR is the provider id in UPPER_SNAKE (hyphens → underscores).\n *\n * Examples: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `META_LLAMA_API_KEY`, `X_AI_API_KEY`\n */\nexport function providerIdToEnvKeyPrefix(providerId: string): string {\n return providerId\n .trim()\n .toLowerCase()\n .replace(/-/g, \"_\")\n .toUpperCase();\n}\n\nexport function vendorApiKeyEnvName(providerId: string): string {\n return `${providerIdToEnvKeyPrefix(providerId)}_API_KEY`;\n}\n\nexport type OpenRouterRoutingConfig = {\n /** OPENROUTER_API_KEY is set and non-empty */\n hasOpenRouterKey: boolean;\n /** USE_OPENROUTER=true or USE_OPENROUTER=1 */\n useOpenRouterExplicit: boolean;\n /** Read `{PROVIDER}_API_KEY` for a catalog provider id */\n getVendorApiKey(providerId: string): string | undefined;\n};\n\n/**\n * Load routing hints from process env and optional `.env` (via @x12/env).\n */\nexport function loadOpenRouterRoutingEnv(\n env: Record<string, string | undefined> = process.env,\n): OpenRouterRoutingConfig {\n const dotenv = loadDotenv();\n const merged: Record<string, string> = {};\n for (const [k, v] of Object.entries(dotenv)) {\n if (v !== undefined) merged[k] = v;\n }\n for (const [k, v] of Object.entries(env)) {\n if (v !== undefined) merged[k] = v;\n }\n\n const openRouterKey = merged.OPENROUTER_API_KEY?.trim();\n const useRaw = merged.USE_OPENROUTER?.trim().toLowerCase();\n const useOpenRouterExplicit = useRaw === \"true\" || useRaw === \"1\";\n\n return {\n hasOpenRouterKey: Boolean(openRouterKey),\n useOpenRouterExplicit,\n getVendorApiKey(providerId: string) {\n const name = vendorApiKeyEnvName(providerId);\n const val = merged[name]?.trim();\n return val || undefined;\n },\n };\n}\n\n/**\n * Default route via OpenRouter when:\n * 1. OPENROUTER_API_KEY is set AND USE_OPENROUTER=true|1, or\n * 2. OPENROUTER_API_KEY is set AND the vendor's `{VENDOR}_API_KEY` is missing.\n */\nexport function shouldDefaultRouteViaOpenRouter(\n providerId: string | undefined,\n config: OpenRouterRoutingConfig,\n): boolean {\n if (!config.hasOpenRouterKey) return false;\n if (config.useOpenRouterExplicit) return true;\n if (providerId && providerId !== \"openrouter\") {\n return !config.getVendorApiKey(providerId);\n }\n return false;\n}\n\nexport type EffectiveOpenRouterTransportInput = {\n provider?: string;\n modelId?: string;\n routeViaOpenRouter?: boolean;\n};\n\n/**\n * Whether the effective runtime transport is OpenRouter.\n * Honors explicit gateway override, then env defaults from {@link loadOpenRouterRoutingEnv}.\n */\nexport function isEffectiveOpenRouterTransport(\n config: OpenRouterRoutingConfig,\n input: EffectiveOpenRouterTransportInput = {},\n): boolean {\n if (input.routeViaOpenRouter === true) return true;\n if (input.routeViaOpenRouter === false) return false;\n\n const provider = input.provider?.trim().toLowerCase();\n if (provider === \"openrouter\") return true;\n\n const vendor =\n input.modelId?.includes(\"/\") === true\n ? input.modelId.split(\"/\")[0]!.trim().toLowerCase()\n : provider;\n\n if (vendor && vendor !== \"openrouter\") {\n return shouldDefaultRouteViaOpenRouter(vendor, config);\n }\n\n if (config.hasOpenRouterKey && config.useOpenRouterExplicit) return true;\n return false;\n}\n","import { normalizeString } from \"./normalize.js\";\n\n/** Patterns stripped when resolving versioned runtime model ids to catalog entries. */\nexport const VERSION_STRIP_PATTERNS: ReadonlyArray<{ re: RegExp; label: string }> = [\n { re: /-\\d{4}-\\d{2}-\\d{2}$/, label: \"date YYYY-MM-DD\" },\n { re: /-\\d{8}$/, label: \"date YYYYMMDD\" },\n { re: /-v\\d+$/, label: \"version -vN\" },\n { re: /-\\d+\\.\\d+\\.\\d+$/, label: \"semver\" },\n { re: /:\\d+[a-z]?$/i, label: \"colon version\" },\n { re: /-\\d{4,}$/, label: \"build number\" },\n { re: /@\\d+$/, label: \"epoch @NNNN\" },\n];\n\n/** Strip version/date suffix from a bare slug (no `provider/` prefix). */\nexport function stripModelSlugSuffix(slug: string): string | null {\n for (const { re } of VERSION_STRIP_PATTERNS) {\n if (re.test(slug)) {\n return slug.replace(re, \"\");\n }\n }\n return null;\n}\n\n/**\n * Strip a version/date suffix from a model id (`gpt-5.5-2026-04-23` → `gpt-5.5`,\n * `openai/gpt-4o-2024-08-06` → `openai/gpt-4o`). Returns null when nothing was stripped.\n */\nexport function stripModelVersionSuffix(model: string): string | null {\n const normalized = normalizeString(model);\n if (!normalized) return null;\n\n if (normalized.includes(\"/\")) {\n const slash = normalized.indexOf(\"/\");\n const prefix = normalized.slice(0, slash);\n const slug = normalized.slice(slash + 1);\n const stripped = stripModelSlugSuffix(slug);\n if (stripped && stripped !== slug) {\n return `${prefix}/${stripped}`;\n }\n return null;\n }\n\n const stripped = stripModelSlugSuffix(normalized);\n return stripped && stripped !== normalized ? stripped : null;\n}\n"],"mappings":"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","names":["stripped"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkDXZOL3VNcjs = require('./chunk-DXZOL3VN.cjs');
3
+ var _chunkRSHI4OOYcjs = require('./chunk-RSHI4OOY.cjs');
4
4
 
5
5
  // src/models/normalizeOpenRouterModel.ts
6
6
  function parsePrice(value) {
@@ -54,7 +54,7 @@ function normalizeOpenRouterModel(row, syncedAt) {
54
54
  const supportedParameters = _nullishCoalesce(row.supported_parameters, () => ( []));
55
55
  const pricing = normalizePricing(row.pricing);
56
56
  const openRouterPricing = row.pricing;
57
- const supportsReasoning = _chunkDXZOL3VNcjs.computeSupportsReasoning.call(void 0, {
57
+ const supportsReasoning = _chunkRSHI4OOYcjs.computeSupportsReasoning.call(void 0, {
58
58
  supportedParameters,
59
59
  pricing,
60
60
  openRouterPricing
@@ -99,4 +99,4 @@ function normalizeOpenRouterModel(row, syncedAt) {
99
99
 
100
100
 
101
101
  exports.extractProviderId = extractProviderId; exports.normalizeOpenRouterModel = normalizeOpenRouterModel;
102
- //# sourceMappingURL=chunk-XOKUDUUI.cjs.map
102
+ //# sourceMappingURL=chunk-TMA6QSNH.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-XOKUDUUI.cjs","../src/models/normalizeOpenRouterModel.ts"],"names":[],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-XOKUDUUI.cjs","sourcesContent":[null,"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"]}
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-TMA6QSNH.cjs","../src/models/normalizeOpenRouterModel.ts"],"names":[],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-TMA6QSNH.cjs","sourcesContent":[null,"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"]}
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  normalizeOpenRouterModel
3
- } from "./chunk-SIH4GPV4.js";
3
+ } from "./chunk-MOLWV5LV.js";
4
4
  import {
5
5
  ModelNameResolver
6
- } from "./chunk-EYHMQVAL.js";
6
+ } from "./chunk-54GKLIDW.js";
7
7
  import {
8
8
  SyncError
9
9
  } from "./chunk-2PTCWPHV.js";
@@ -92,4 +92,4 @@ export {
92
92
  resolveModel,
93
93
  isRoutedViaOpenRouter
94
94
  };
95
- //# sourceMappingURL=chunk-6BQBKROR.js.map
95
+ //# sourceMappingURL=chunk-VBROBIVI.js.map