@x12i/ai-tools 2.0.7 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/catalog/index.cjs +6 -6
  2. package/dist/catalog/index.js +5 -5
  3. package/dist/{chunk-ZPUZ7DBO.js → chunk-25O27USJ.js} +2 -2
  4. package/dist/{chunk-DDRWORUU.cjs → chunk-2A6EUGR5.cjs} +19 -19
  5. package/dist/{chunk-DDRWORUU.cjs.map → chunk-2A6EUGR5.cjs.map} +1 -1
  6. package/dist/chunk-2KPWVOOT.cjs +32 -0
  7. package/dist/chunk-2KPWVOOT.cjs.map +1 -0
  8. package/dist/{chunk-PN4FF6YF.js → chunk-4AIEM4AE.js} +3 -3
  9. package/dist/{chunk-RSHI4OOY.cjs → chunk-5XBMNY7Q.cjs} +252 -64
  10. package/dist/chunk-5XBMNY7Q.cjs.map +1 -0
  11. package/dist/chunk-EBBJCLJQ.js +29 -0
  12. package/dist/chunk-EBBJCLJQ.js.map +1 -0
  13. package/dist/{chunk-D6OIUYNC.js → chunk-ET5LPVPT.js} +5 -5
  14. package/dist/chunk-FISSYP27.cjs +29 -0
  15. package/dist/chunk-FISSYP27.cjs.map +1 -0
  16. package/dist/{chunk-76FHWQH3.cjs → chunk-GVFL2LRG.cjs} +9 -3
  17. package/dist/chunk-GVFL2LRG.cjs.map +1 -0
  18. package/dist/{chunk-75ZVXZAV.cjs → chunk-I6CDT2NG.cjs} +7 -7
  19. package/dist/{chunk-75ZVXZAV.cjs.map → chunk-I6CDT2NG.cjs.map} +1 -1
  20. package/dist/{chunk-VBROBIVI.js → chunk-JCMLIXIX.js} +3 -3
  21. package/dist/{chunk-VBROBIVI.js.map → chunk-JCMLIXIX.js.map} +1 -1
  22. package/dist/chunk-LQLSD26Y.cjs +1 -0
  23. package/dist/chunk-LQLSD26Y.cjs.map +1 -0
  24. package/dist/{chunk-X42KFOUO.cjs → chunk-R6P4AWOM.cjs} +6 -6
  25. package/dist/{chunk-X42KFOUO.cjs.map → chunk-R6P4AWOM.cjs.map} +1 -1
  26. package/dist/{chunk-HBNYVRLZ.cjs → chunk-SIR4LDHD.cjs} +16 -16
  27. package/dist/{chunk-HBNYVRLZ.cjs.map → chunk-SIR4LDHD.cjs.map} +1 -1
  28. package/dist/chunk-SQ6NOF4Z.js +32 -0
  29. package/dist/chunk-SQ6NOF4Z.js.map +1 -0
  30. package/dist/{chunk-54GKLIDW.js → chunk-SYHLDADG.js} +233 -45
  31. package/dist/chunk-SYHLDADG.js.map +1 -0
  32. package/dist/{chunk-WSUFQR3D.cjs → chunk-TDO5SDQ3.cjs} +25 -25
  33. package/dist/{chunk-WSUFQR3D.cjs.map → chunk-TDO5SDQ3.cjs.map} +1 -1
  34. package/dist/chunk-TMDWPWKB.cjs +123 -0
  35. package/dist/chunk-TMDWPWKB.cjs.map +1 -0
  36. package/dist/{chunk-MOLWV5LV.js → chunk-VDNKQRDG.js} +2 -2
  37. package/dist/chunk-VYVX46VO.js +123 -0
  38. package/dist/chunk-VYVX46VO.js.map +1 -0
  39. package/dist/{chunk-KSJSLKYI.js → chunk-WFRS32EQ.js} +8 -2
  40. package/dist/chunk-WFRS32EQ.js.map +1 -0
  41. package/dist/{chunk-HEB73GKJ.js → chunk-XMOALOYU.js} +2 -2
  42. package/dist/chunk-XUUPJ7WO.js +1 -0
  43. package/dist/{chunk-TMA6QSNH.cjs → chunk-YO7AJ5Z3.cjs} +3 -3
  44. package/dist/{chunk-TMA6QSNH.cjs.map → chunk-YO7AJ5Z3.cjs.map} +1 -1
  45. package/dist/cli/index.cjs +36 -16
  46. package/dist/cli/index.cjs.map +1 -1
  47. package/dist/cli/index.js +27 -7
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/cost/index.cjs +15 -5
  50. package/dist/cost/index.cjs.map +1 -1
  51. package/dist/cost/index.d.cts +3 -2
  52. package/dist/cost/index.d.ts +3 -2
  53. package/dist/cost/index.js +14 -4
  54. package/dist/index.cjs +21 -11
  55. package/dist/index.cjs.map +1 -1
  56. package/dist/index.d.cts +2 -1
  57. package/dist/index.d.ts +2 -1
  58. package/dist/index.js +21 -11
  59. package/dist/models/index.cjs +9 -7
  60. package/dist/models/index.cjs.map +1 -1
  61. package/dist/models/index.d.cts +2 -0
  62. package/dist/models/index.d.ts +2 -0
  63. package/dist/models/index.js +8 -6
  64. package/dist/{resolveUsageModel-DrFuiuIW.d.ts → resolveModelVendor--2JdUZlR.d.ts} +5 -1
  65. package/dist/{resolveUsageModel-xKZ2QpHy.d.cts → resolveModelVendor-BPPvzxE8.d.cts} +5 -1
  66. package/dist/resolveModelVendor-Dd4N6Vds.d.cts +16 -0
  67. package/dist/resolveModelVendor-oKeiH9ig.d.ts +16 -0
  68. package/dist/sync/index.cjs +10 -5
  69. package/dist/sync/index.cjs.map +1 -1
  70. package/dist/sync/index.d.cts +1 -0
  71. package/dist/sync/index.d.ts +1 -0
  72. package/dist/sync/index.js +11 -6
  73. package/package.json +2 -2
  74. package/dist/chunk-54GKLIDW.js.map +0 -1
  75. package/dist/chunk-56R4XA2S.js +0 -1
  76. package/dist/chunk-5GUKLOEK.cjs +0 -1
  77. package/dist/chunk-5GUKLOEK.cjs.map +0 -1
  78. package/dist/chunk-76FHWQH3.cjs.map +0 -1
  79. package/dist/chunk-BCX5CLJJ.cjs +0 -238
  80. package/dist/chunk-BCX5CLJJ.cjs.map +0 -1
  81. package/dist/chunk-KSJSLKYI.js.map +0 -1
  82. package/dist/chunk-RSHI4OOY.cjs.map +0 -1
  83. package/dist/chunk-SLSKQRMI.js +0 -238
  84. package/dist/chunk-SLSKQRMI.js.map +0 -1
  85. /package/dist/{chunk-ZPUZ7DBO.js.map → chunk-25O27USJ.js.map} +0 -0
  86. /package/dist/{chunk-PN4FF6YF.js.map → chunk-4AIEM4AE.js.map} +0 -0
  87. /package/dist/{chunk-D6OIUYNC.js.map → chunk-ET5LPVPT.js.map} +0 -0
  88. /package/dist/{chunk-MOLWV5LV.js.map → chunk-VDNKQRDG.js.map} +0 -0
  89. /package/dist/{chunk-HEB73GKJ.js.map → chunk-XMOALOYU.js.map} +0 -0
  90. /package/dist/{chunk-56R4XA2S.js.map → chunk-XUUPJ7WO.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-WSUFQR3D.cjs","../src/cost/costModelResolution.ts","../src/cost/aiProfilesMatch.ts"],"names":["require"],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-WSUFQR3D.cjs","sourcesContent":[null,"import type { AiModelsCatalogClient } from \"../catalog/AiModelsCatalogClient.js\";\nimport { LOCAL_PROVIDERS } from \"../sync/modelNameResolver/constants.js\";\nimport {\n loadOpenRouterRoutingEnv,\n shouldDefaultRouteViaOpenRouter,\n} from \"../sync/openRouterRoutingEnv.js\";\nimport { normalizeProvider, normalizeString } from \"../sync/modelNameResolver/normalize.js\";\nimport type {\n ModelResolutionInput,\n ModelResolutionResult,\n ModelResolverOptions,\n} from \"../sync/modelNameResolver/types.js\";\nimport type { OpenRouterRoutingConfig } from \"../sync/openRouterRoutingEnv.js\";\n\nexport function isOpenRouterProvider(provider?: string): boolean {\n return normalizeProvider(provider) === \"openrouter\";\n}\n\nexport function isLocalProvider(provider?: string): boolean {\n const p = normalizeProvider(provider) ?? normalizeString(provider ?? \"\");\n return LOCAL_PROVIDERS.has(p);\n}\n\n/** Catalog resolver returned success without a priced record (Ollama, LM Studio, …). */\nexport function isLocalProviderResolution(\n resolved: ModelResolutionResult | null,\n inputProvider?: string,\n): boolean {\n if (!resolved?.found || resolved.record) return false;\n if (resolved.resolvedVia.includes(\"local-provider-passthrough\")) return true;\n return isLocalProvider(inputProvider);\n}\n\n/**\n * Vendor id for a model slug (`openai/gpt-4o` → `openai`).\n * Ignores `openrouter` as a provider hint — it is a routing layer, not the model owner.\n */\nexport function underlyingProviderFromModel(\n model: string,\n providerHint?: string,\n): string | undefined {\n const normalized = normalizeString(model);\n if (normalized.includes(\"/\")) {\n const prefix = normalized.split(\"/\")[0]!;\n if (!isOpenRouterProvider(prefix)) return prefix;\n }\n if (providerHint && !isOpenRouterProvider(providerHint)) {\n return normalizeProvider(providerHint);\n }\n return undefined;\n}\n\n/** Provider hint for ai-profiles index lookup (openrouter → underlying vendor). */\nexport function providerHintForProfiles(\n model: string,\n provider?: string,\n): string | undefined {\n if (isOpenRouterProvider(provider)) {\n return underlyingProviderFromModel(model, provider);\n }\n return normalizeProvider(provider);\n}\n\n/**\n * Catalog resolve attempts for direct API and OpenRouter usage.\n * Tries the caller hint, inferred vendor, no hint, and openrouter routing.\n */\nexport function buildCatalogResolveAttempts(\n model: string,\n provider?: string,\n): ModelResolutionInput[] {\n const attempts: ModelResolutionInput[] = [];\n const seen = new Set<string>();\n const add = (m: string, p?: string) => {\n const key = `${p ?? \"\"}\\0${normalizeString(m)}`;\n if (seen.has(key)) return;\n seen.add(key);\n attempts.push({ model: m, provider: p });\n };\n\n add(model, provider);\n\n const underlying = underlyingProviderFromModel(model, provider);\n if (provider) add(model, undefined);\n if (underlying) add(model, underlying);\n if (!isOpenRouterProvider(provider)) {\n add(model, \"openrouter\");\n }\n\n return attempts;\n}\n\nexport async function resolveFromCatalogAttempts(\n catalog: AiModelsCatalogClient,\n attempts: ModelResolutionInput[],\n options?: ModelResolverOptions,\n): Promise<ModelResolutionResult | null> {\n let last: ModelResolutionResult | null = null;\n let localPassthrough: ModelResolutionResult | null = null;\n\n for (const attempt of attempts) {\n const result = await catalog.resolveModel(attempt, options);\n last = result;\n if (result.found && result.record) return result;\n if (\n result.found &&\n !result.record &&\n isLocalProviderResolution(result, attempt.provider)\n ) {\n localPassthrough = result;\n }\n }\n\n return localPassthrough ?? last;\n}\n\nexport function resolveRoutedViaOpenRouter(\n inputProvider: string | undefined,\n resolved: ModelResolutionResult | null,\n modelId?: string,\n routingEnv?: OpenRouterRoutingConfig,\n): boolean {\n const env = routingEnv ?? loadOpenRouterRoutingEnv();\n\n if (isOpenRouterProvider(inputProvider)) return true;\n\n if (resolved?.found) {\n return resolved.routedViaOpenRouter;\n }\n\n const vendor = underlyingProviderFromModel(\n modelId ?? (resolved?.found ? resolved.modelId : \"\") ?? \"\",\n inputProvider,\n );\n if (vendor && shouldDefaultRouteViaOpenRouter(vendor, env)) {\n return true;\n }\n\n return false;\n}\n","import { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\nimport { AIProfilesError, resolveAIProfile } from \"@x12i/ai-profiles\";\nimport type {\n AIProfileBackend,\n AIProfileChoice,\n AIModelPricing,\n AIProfilesRegistry,\n InstructionTier,\n ResolvedAIProfile,\n} from \"@x12i/ai-profiles\";\nimport { providerHintForProfiles } from \"./costModelResolution.js\";\nimport { normalizeProvider, normalizeString } from \"../sync/modelNameResolver/normalize.js\";\nimport { stripModelVersionSuffix } from \"../sync/modelNameResolver/stripVersionSuffix.js\";\n\nconst require = createRequire(import.meta.url);\n\ntype LoadRegistryFn = (options?: {\n source?: \"auto\" | \"remote\" | \"bundled\";\n refresh?: boolean;\n}) => Promise<AIProfilesRegistry>;\n\nfunction loadProfilesRegistry(): Promise<AIProfilesRegistry> {\n const entry = dirname(require.resolve(\"@x12i/ai-profiles\"));\n const loader = require(join(entry, \"loader/loadAIProfilesRegistry.js\")) as {\n loadAIProfilesRegistry: LoadRegistryFn;\n };\n return loader.loadAIProfilesRegistry({ source: \"auto\" });\n}\n\nexport type AiProfilesModelMatch = {\n provider: string;\n modelId: string;\n canonicalModelId: string;\n pricing?: AIModelPricing;\n instructionTier: InstructionTier;\n backend: AIProfileBackend;\n matchedVia: \"profile\" | \"shortcut\" | \"profile-alias\" | \"model-id\";\n profile?: string;\n choice?: string;\n};\n\nfunction profileKey(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction canonicalModelId(provider: string, modelId: string): string {\n const normalized = normalizeString(modelId);\n if (normalized.includes(\"/\")) return normalized;\n const p = normalizeProvider(provider) ?? normalizeString(provider);\n return `${p}/${normalized}`;\n}\n\ntype IndexedChoice = {\n provider: string;\n modelId: string;\n canonicalModelId: string;\n pricing?: AIModelPricing;\n profile: string;\n choice: string;\n};\n\nlet cachedIndex: {\n cacheKey: string;\n byKey: Map<string, IndexedChoice[]>;\n} | null = null;\n\n/** Index bare model ids only — profile/shortcut names resolve via {@link resolveAIProfile}. */\nfunction indexRegistry(registry: AIProfilesRegistry): Map<string, IndexedChoice[]> {\n const byKey = new Map<string, IndexedChoice[]>();\n\n const add = (key: string, entry: IndexedChoice) => {\n const k = profileKey(key);\n if (!k) return;\n const list = byKey.get(k) ?? [];\n if (\n list.some(\n (e) =>\n e.canonicalModelId === entry.canonicalModelId &&\n e.choice === entry.choice &&\n e.profile === entry.profile,\n )\n ) {\n return;\n }\n list.push(entry);\n byKey.set(k, list);\n };\n\n for (const profile of Object.values(registry.profiles)) {\n for (const [choiceKey, choice] of Object.entries(profile.choices)) {\n const entry = choiceEntry(choice, profile.profile, choiceKey);\n add(choice.modelId, entry);\n add(canonicalModelId(choice.provider, choice.modelId), entry);\n }\n }\n\n return byKey;\n}\n\nfunction choiceEntry(\n choice: AIProfileChoice,\n profile: string,\n choiceKey: string,\n): IndexedChoice {\n const canonical = canonicalModelId(choice.provider, choice.modelId);\n return {\n provider: normalizeProvider(choice.provider) ?? choice.provider,\n modelId: normalizeString(choice.modelId),\n canonicalModelId: canonical,\n pricing: choice.pricing,\n profile,\n choice: choiceKey,\n };\n}\n\nasync function getProfileIndex(): Promise<Map<string, IndexedChoice[]>> {\n const registry = await loadProfilesRegistry();\n const cacheKey = `${registry.version}:${registry.generatedAt ?? \"\"}:${registry.source}`;\n if (cachedIndex?.cacheKey === cacheKey) {\n return cachedIndex.byKey;\n }\n const byKey = indexRegistry(registry);\n cachedIndex = { cacheKey, byKey };\n return byKey;\n}\n\nfunction scoreCandidate(\n entry: IndexedChoice,\n model: string,\n providerHint?: string,\n): number {\n const normalized = normalizeString(model);\n let score = 0;\n\n if (normalized === entry.canonicalModelId) score += 100;\n if (normalized === entry.modelId) score += 80;\n if (providerHint && entry.provider === providerHint) score += 50;\n if (entry.pricing) score += 2;\n\n return score;\n}\n\nfunction pickBest(\n candidates: IndexedChoice[],\n model: string,\n providerHint?: string,\n): IndexedChoice | null {\n if (candidates.length === 0) return null;\n if (candidates.length === 1) return candidates[0]!;\n\n let best = candidates[0]!;\n let bestScore = scoreCandidate(best, model, providerHint);\n for (let i = 1; i < candidates.length; i++) {\n const c = candidates[i]!;\n const s = scoreCandidate(c, model, providerHint);\n if (s > bestScore) {\n best = c;\n bestScore = s;\n }\n }\n return best;\n}\n\nfunction resolvedToMatch(resolved: ResolvedAIProfile): AiProfilesModelMatch {\n return {\n provider: normalizeProvider(resolved.provider) ?? resolved.provider,\n modelId: normalizeString(resolved.modelId),\n canonicalModelId: canonicalModelId(resolved.provider, resolved.modelId),\n pricing: resolved.pricing,\n instructionTier: resolved.instructionTier,\n backend: resolved.backend,\n matchedVia: resolved.shortcut ? \"shortcut\" : \"profile\",\n profile: resolved.profile,\n choice: resolved.choice,\n };\n}\n\nasync function fromIndexed(entry: IndexedChoice): Promise<AiProfilesModelMatch> {\n const resolved = await resolveAIProfile(entry.profile, { choice: entry.choice });\n return {\n provider: normalizeProvider(resolved.provider) ?? resolved.provider,\n modelId: normalizeString(resolved.modelId),\n canonicalModelId: canonicalModelId(resolved.provider, resolved.modelId),\n pricing: resolved.pricing ?? entry.pricing,\n instructionTier: resolved.instructionTier,\n backend: resolved.backend,\n matchedVia: \"model-id\",\n profile: resolved.profile,\n choice: resolved.choice,\n };\n}\n\nasync function lookupInIndex(\n index: Map<string, IndexedChoice[]>,\n model: string,\n provider?: string,\n): Promise<AiProfilesModelMatch | null> {\n const providerHint = provider ? normalizeProvider(provider) : undefined;\n const keys = [\n profileKey(model),\n profileKey(normalizeString(model)),\n ];\n if (providerHint) {\n keys.push(profileKey(canonicalModelId(providerHint, model)));\n }\n\n const pooled: IndexedChoice[] = [];\n for (const key of keys) {\n const hits = index.get(key);\n if (hits) pooled.push(...hits);\n }\n\n const bare = normalizeString(model);\n if (!bare.includes(\"/\")) {\n for (const list of index.values()) {\n for (const entry of list) {\n if (entry.modelId === bare) pooled.push(entry);\n }\n }\n }\n\n const unique = new Map<string, IndexedChoice>();\n for (const e of pooled) {\n unique.set(`${e.profile}:${e.choice}:${e.canonicalModelId}`, e);\n }\n\n const best = pickBest([...unique.values()], model, providerHint);\n return best ? fromIndexed(best) : null;\n}\n\n/**\n * Resolve a model string via @x12i/ai-profiles — profile/shortcut names, aliases,\n * or a concrete model id that appears on a profile choice.\n */\nexport async function matchModelInAiProfiles(\n model: string,\n provider?: string,\n): Promise<AiProfilesModelMatch | null> {\n try {\n const resolved = await resolveAIProfile(model);\n return resolvedToMatch(resolved);\n } catch (err) {\n if (!(err instanceof AIProfilesError) || err.code !== \"UNKNOWN_PROFILE\") {\n throw err;\n }\n }\n\n const index = await getProfileIndex();\n const hint = providerHintForProfiles(model, provider);\n const direct = await lookupInIndex(index, model, hint);\n if (direct) return direct;\n\n const stripped = stripModelVersionSuffix(model);\n if (stripped && stripped !== normalizeString(model)) {\n return lookupInIndex(\n index,\n stripped,\n providerHintForProfiles(stripped, provider),\n );\n }\n\n return null;\n}\n\n/** @internal Test-only — reset module cache between tests. */\nexport function resetAiProfilesMatchCacheForTests(): void {\n cachedIndex = null;\n}\n"]}
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-TDO5SDQ3.cjs","../src/cost/costModelResolution.ts","../src/cost/aiProfilesMatch.ts"],"names":["require"],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-TDO5SDQ3.cjs","sourcesContent":[null,"import type { AiModelsCatalogClient } from \"../catalog/AiModelsCatalogClient.js\";\nimport { LOCAL_PROVIDERS } from \"../sync/modelNameResolver/constants.js\";\nimport {\n loadOpenRouterRoutingEnv,\n shouldDefaultRouteViaOpenRouter,\n} from \"../sync/openRouterRoutingEnv.js\";\nimport { normalizeProvider, normalizeString } from \"../sync/modelNameResolver/normalize.js\";\nimport type {\n ModelResolutionInput,\n ModelResolutionResult,\n ModelResolverOptions,\n} from \"../sync/modelNameResolver/types.js\";\nimport type { OpenRouterRoutingConfig } from \"../sync/openRouterRoutingEnv.js\";\n\nexport function isOpenRouterProvider(provider?: string): boolean {\n return normalizeProvider(provider) === \"openrouter\";\n}\n\nexport function isLocalProvider(provider?: string): boolean {\n const p = normalizeProvider(provider) ?? normalizeString(provider ?? \"\");\n return LOCAL_PROVIDERS.has(p);\n}\n\n/** Catalog resolver returned success without a priced record (Ollama, LM Studio, …). */\nexport function isLocalProviderResolution(\n resolved: ModelResolutionResult | null,\n inputProvider?: string,\n): boolean {\n if (!resolved?.found || resolved.record) return false;\n if (resolved.resolvedVia.includes(\"local-provider-passthrough\")) return true;\n return isLocalProvider(inputProvider);\n}\n\n/**\n * Vendor id for a model slug (`openai/gpt-4o` → `openai`).\n * Ignores `openrouter` as a provider hint — it is a routing layer, not the model owner.\n */\nexport function underlyingProviderFromModel(\n model: string,\n providerHint?: string,\n): string | undefined {\n const normalized = normalizeString(model);\n if (normalized.includes(\"/\")) {\n const prefix = normalized.split(\"/\")[0]!;\n if (!isOpenRouterProvider(prefix)) return prefix;\n }\n if (providerHint && !isOpenRouterProvider(providerHint)) {\n return normalizeProvider(providerHint);\n }\n return undefined;\n}\n\n/** Provider hint for ai-profiles index lookup (openrouter → underlying vendor). */\nexport function providerHintForProfiles(\n model: string,\n provider?: string,\n): string | undefined {\n if (isOpenRouterProvider(provider)) {\n return underlyingProviderFromModel(model, provider);\n }\n return normalizeProvider(provider);\n}\n\n/**\n * Catalog resolve attempts for direct API and OpenRouter usage.\n * Tries the caller hint, inferred vendor, no hint, and openrouter routing.\n */\nexport function buildCatalogResolveAttempts(\n model: string,\n provider?: string,\n): ModelResolutionInput[] {\n const attempts: ModelResolutionInput[] = [];\n const seen = new Set<string>();\n const add = (m: string, p?: string) => {\n const key = `${p ?? \"\"}\\0${normalizeString(m)}`;\n if (seen.has(key)) return;\n seen.add(key);\n attempts.push({ model: m, provider: p });\n };\n\n add(model, provider);\n\n const underlying = underlyingProviderFromModel(model, provider);\n if (provider) add(model, undefined);\n if (underlying) add(model, underlying);\n if (!isOpenRouterProvider(provider)) {\n add(model, \"openrouter\");\n }\n\n return attempts;\n}\n\nexport async function resolveFromCatalogAttempts(\n catalog: AiModelsCatalogClient,\n attempts: ModelResolutionInput[],\n options?: ModelResolverOptions,\n): Promise<ModelResolutionResult | null> {\n let last: ModelResolutionResult | null = null;\n let localPassthrough: ModelResolutionResult | null = null;\n\n for (const attempt of attempts) {\n const result = await catalog.resolveModel(attempt, options);\n last = result;\n if (result.found && result.record) return result;\n if (\n result.found &&\n !result.record &&\n isLocalProviderResolution(result, attempt.provider)\n ) {\n localPassthrough = result;\n }\n }\n\n return localPassthrough ?? last;\n}\n\nexport function resolveRoutedViaOpenRouter(\n inputProvider: string | undefined,\n resolved: ModelResolutionResult | null,\n modelId?: string,\n routingEnv?: OpenRouterRoutingConfig,\n): boolean {\n const env = routingEnv ?? loadOpenRouterRoutingEnv();\n\n if (isOpenRouterProvider(inputProvider)) return true;\n\n if (resolved?.found) {\n return resolved.routedViaOpenRouter;\n }\n\n const vendor = underlyingProviderFromModel(\n modelId ?? (resolved?.found ? resolved.modelId : \"\") ?? \"\",\n inputProvider,\n );\n if (vendor && shouldDefaultRouteViaOpenRouter(vendor, env)) {\n return true;\n }\n\n return false;\n}\n","import { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\nimport { AIProfilesError, resolveAIProfile } from \"@x12i/ai-profiles\";\nimport type {\n AIProfileBackend,\n AIProfileChoice,\n AIModelPricing,\n AIProfilesRegistry,\n InstructionTier,\n ResolvedAIProfile,\n} from \"@x12i/ai-profiles\";\nimport { providerHintForProfiles } from \"./costModelResolution.js\";\nimport { normalizeProvider, normalizeString } from \"../sync/modelNameResolver/normalize.js\";\nimport { stripModelVersionSuffix } from \"../sync/modelNameResolver/stripVersionSuffix.js\";\n\nconst require = createRequire(import.meta.url);\n\ntype LoadRegistryFn = (options?: {\n source?: \"auto\" | \"remote\" | \"bundled\";\n refresh?: boolean;\n}) => Promise<AIProfilesRegistry>;\n\nfunction loadProfilesRegistry(): Promise<AIProfilesRegistry> {\n const entry = dirname(require.resolve(\"@x12i/ai-profiles\"));\n const loader = require(join(entry, \"loader/loadAIProfilesRegistry.js\")) as {\n loadAIProfilesRegistry: LoadRegistryFn;\n };\n return loader.loadAIProfilesRegistry({ source: \"auto\" });\n}\n\nexport type AiProfilesModelMatch = {\n provider: string;\n modelId: string;\n canonicalModelId: string;\n pricing?: AIModelPricing;\n instructionTier: InstructionTier;\n backend: AIProfileBackend;\n matchedVia: \"profile\" | \"shortcut\" | \"profile-alias\" | \"model-id\";\n profile?: string;\n choice?: string;\n};\n\nfunction profileKey(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction canonicalModelId(provider: string, modelId: string): string {\n const normalized = normalizeString(modelId);\n if (normalized.includes(\"/\")) return normalized;\n const p = normalizeProvider(provider) ?? normalizeString(provider);\n return `${p}/${normalized}`;\n}\n\ntype IndexedChoice = {\n provider: string;\n modelId: string;\n canonicalModelId: string;\n pricing?: AIModelPricing;\n profile: string;\n choice: string;\n};\n\nlet cachedIndex: {\n cacheKey: string;\n byKey: Map<string, IndexedChoice[]>;\n} | null = null;\n\n/** Index bare model ids only — profile/shortcut names resolve via {@link resolveAIProfile}. */\nfunction indexRegistry(registry: AIProfilesRegistry): Map<string, IndexedChoice[]> {\n const byKey = new Map<string, IndexedChoice[]>();\n\n const add = (key: string, entry: IndexedChoice) => {\n const k = profileKey(key);\n if (!k) return;\n const list = byKey.get(k) ?? [];\n if (\n list.some(\n (e) =>\n e.canonicalModelId === entry.canonicalModelId &&\n e.choice === entry.choice &&\n e.profile === entry.profile,\n )\n ) {\n return;\n }\n list.push(entry);\n byKey.set(k, list);\n };\n\n for (const profile of Object.values(registry.profiles)) {\n for (const [choiceKey, choice] of Object.entries(profile.choices)) {\n const entry = choiceEntry(choice, profile.profile, choiceKey);\n add(choice.modelId, entry);\n add(canonicalModelId(choice.provider, choice.modelId), entry);\n }\n }\n\n return byKey;\n}\n\nfunction choiceEntry(\n choice: AIProfileChoice,\n profile: string,\n choiceKey: string,\n): IndexedChoice {\n const canonical = canonicalModelId(choice.provider, choice.modelId);\n return {\n provider: normalizeProvider(choice.provider) ?? choice.provider,\n modelId: normalizeString(choice.modelId),\n canonicalModelId: canonical,\n pricing: choice.pricing,\n profile,\n choice: choiceKey,\n };\n}\n\nasync function getProfileIndex(): Promise<Map<string, IndexedChoice[]>> {\n const registry = await loadProfilesRegistry();\n const cacheKey = `${registry.version}:${registry.generatedAt ?? \"\"}:${registry.source}`;\n if (cachedIndex?.cacheKey === cacheKey) {\n return cachedIndex.byKey;\n }\n const byKey = indexRegistry(registry);\n cachedIndex = { cacheKey, byKey };\n return byKey;\n}\n\nfunction scoreCandidate(\n entry: IndexedChoice,\n model: string,\n providerHint?: string,\n): number {\n const normalized = normalizeString(model);\n let score = 0;\n\n if (normalized === entry.canonicalModelId) score += 100;\n if (normalized === entry.modelId) score += 80;\n if (providerHint && entry.provider === providerHint) score += 50;\n if (entry.pricing) score += 2;\n\n return score;\n}\n\nfunction pickBest(\n candidates: IndexedChoice[],\n model: string,\n providerHint?: string,\n): IndexedChoice | null {\n if (candidates.length === 0) return null;\n if (candidates.length === 1) return candidates[0]!;\n\n let best = candidates[0]!;\n let bestScore = scoreCandidate(best, model, providerHint);\n for (let i = 1; i < candidates.length; i++) {\n const c = candidates[i]!;\n const s = scoreCandidate(c, model, providerHint);\n if (s > bestScore) {\n best = c;\n bestScore = s;\n }\n }\n return best;\n}\n\nfunction resolvedToMatch(resolved: ResolvedAIProfile): AiProfilesModelMatch {\n return {\n provider: normalizeProvider(resolved.provider) ?? resolved.provider,\n modelId: normalizeString(resolved.modelId),\n canonicalModelId: canonicalModelId(resolved.provider, resolved.modelId),\n pricing: resolved.pricing,\n instructionTier: resolved.instructionTier,\n backend: resolved.backend,\n matchedVia: resolved.shortcut ? \"shortcut\" : \"profile\",\n profile: resolved.profile,\n choice: resolved.choice,\n };\n}\n\nasync function fromIndexed(entry: IndexedChoice): Promise<AiProfilesModelMatch> {\n const resolved = await resolveAIProfile(entry.profile, { choice: entry.choice });\n return {\n provider: normalizeProvider(resolved.provider) ?? resolved.provider,\n modelId: normalizeString(resolved.modelId),\n canonicalModelId: canonicalModelId(resolved.provider, resolved.modelId),\n pricing: resolved.pricing ?? entry.pricing,\n instructionTier: resolved.instructionTier,\n backend: resolved.backend,\n matchedVia: \"model-id\",\n profile: resolved.profile,\n choice: resolved.choice,\n };\n}\n\nasync function lookupInIndex(\n index: Map<string, IndexedChoice[]>,\n model: string,\n provider?: string,\n): Promise<AiProfilesModelMatch | null> {\n const providerHint = provider ? normalizeProvider(provider) : undefined;\n const keys = [\n profileKey(model),\n profileKey(normalizeString(model)),\n ];\n if (providerHint) {\n keys.push(profileKey(canonicalModelId(providerHint, model)));\n }\n\n const pooled: IndexedChoice[] = [];\n for (const key of keys) {\n const hits = index.get(key);\n if (hits) pooled.push(...hits);\n }\n\n const bare = normalizeString(model);\n if (!bare.includes(\"/\")) {\n for (const list of index.values()) {\n for (const entry of list) {\n if (entry.modelId === bare) pooled.push(entry);\n }\n }\n }\n\n const unique = new Map<string, IndexedChoice>();\n for (const e of pooled) {\n unique.set(`${e.profile}:${e.choice}:${e.canonicalModelId}`, e);\n }\n\n const best = pickBest([...unique.values()], model, providerHint);\n return best ? fromIndexed(best) : null;\n}\n\n/**\n * Resolve a model string via @x12i/ai-profiles — profile/shortcut names, aliases,\n * or a concrete model id that appears on a profile choice.\n */\nexport async function matchModelInAiProfiles(\n model: string,\n provider?: string,\n): Promise<AiProfilesModelMatch | null> {\n try {\n const resolved = await resolveAIProfile(model);\n return resolvedToMatch(resolved);\n } catch (err) {\n if (!(err instanceof AIProfilesError) || err.code !== \"UNKNOWN_PROFILE\") {\n throw err;\n }\n }\n\n const index = await getProfileIndex();\n const hint = providerHintForProfiles(model, provider);\n const direct = await lookupInIndex(index, model, hint);\n if (direct) return direct;\n\n const stripped = stripModelVersionSuffix(model);\n if (stripped && stripped !== normalizeString(model)) {\n return lookupInIndex(\n index,\n stripped,\n providerHintForProfiles(stripped, provider),\n );\n }\n\n return null;\n}\n\n/** @internal Test-only — reset module cache between tests. */\nexport function resetAiProfilesMatchCacheForTests(): void {\n cachedIndex = null;\n}\n"]}
@@ -0,0 +1,123 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+
6
+
7
+ var _chunk5XBMNY7Qcjs = require('./chunk-5XBMNY7Q.cjs');
8
+
9
+ // src/sync/modelNameResolver/resolveModelVendor.ts
10
+ function isOpenRouterProvider(provider) {
11
+ return _chunk5XBMNY7Qcjs.normalizeProvider.call(void 0, provider) === "openrouter";
12
+ }
13
+ function buildVendorResolveAttempts(model) {
14
+ const attempts = [];
15
+ const seen = /* @__PURE__ */ new Set();
16
+ const add = (m, p) => {
17
+ const key = `${_nullishCoalesce(p, () => ( ""))}\0${_chunk5XBMNY7Qcjs.normalizeString.call(void 0, m)}`;
18
+ if (seen.has(key)) return;
19
+ seen.add(key);
20
+ attempts.push({ model: m, provider: p });
21
+ };
22
+ add(model, void 0);
23
+ const normalised = _chunk5XBMNY7Qcjs.normalizeString.call(void 0, model);
24
+ if (normalised.includes("/")) {
25
+ const prefix = normalised.split("/")[0];
26
+ if (!isOpenRouterProvider(prefix)) {
27
+ add(model, _chunk5XBMNY7Qcjs.normalizeProvider.call(void 0, prefix));
28
+ }
29
+ }
30
+ add(model, "openrouter");
31
+ return attempts;
32
+ }
33
+ function inferProviderFromSlug(slug, options) {
34
+ const patterns = [
35
+ ..._nullishCoalesce(_optionalChain([options, 'optionalAccess', _ => _.additionalProviderPatterns]), () => ( [])),
36
+ ..._chunk5XBMNY7Qcjs.PROVIDER_INFERENCE_MAP
37
+ ];
38
+ for (const { pattern, provider } of patterns) {
39
+ if (pattern.test(slug)) return provider;
40
+ }
41
+ return void 0;
42
+ }
43
+ function vendorFromModelId(modelId, record, options) {
44
+ if (_optionalChain([record, 'optionalAccess', _2 => _2.providerId])) {
45
+ const provider = _chunk5XBMNY7Qcjs.normalizeProvider.call(void 0, record.providerId);
46
+ if (provider && !isOpenRouterProvider(provider)) return provider;
47
+ }
48
+ const normalised = _chunk5XBMNY7Qcjs.normalizeString.call(void 0, modelId);
49
+ if (normalised.includes("/")) {
50
+ const prefix = normalised.split("/")[0];
51
+ if (!isOpenRouterProvider(prefix)) {
52
+ return _chunk5XBMNY7Qcjs.normalizeProvider.call(void 0, prefix);
53
+ }
54
+ }
55
+ return inferProviderFromSlug(_chunk5XBMNY7Qcjs.modelSlug.call(void 0, normalised), options);
56
+ }
57
+ function formatModelVendorRef(modelId, record, options) {
58
+ const vendor = vendorFromModelId(modelId, record, options);
59
+ if (!vendor) return null;
60
+ const normalised = _chunk5XBMNY7Qcjs.normalizeString.call(void 0, modelId);
61
+ const slug = normalised.includes("/") ? _chunk5XBMNY7Qcjs.modelSlug.call(void 0, normalised) : normalised;
62
+ const openRouterSlug = normalised.includes("/") ? normalised : `${vendor}/${slug}`;
63
+ if (_optionalChain([options, 'optionalAccess', _3 => _3.asOpenRouter])) {
64
+ return { provider: "openrouter", model: openRouterSlug };
65
+ }
66
+ return { provider: vendor, model: slug };
67
+ }
68
+ function resolveModelVendorFromResolution(result, inputModel, options) {
69
+ if (result.found) {
70
+ const ref = formatModelVendorRef(result.modelId, result.record, options);
71
+ if (ref) return ref;
72
+ }
73
+ if (!result.found && result.bestRejectedCandidate) {
74
+ const ref = formatModelVendorRef(result.bestRejectedCandidate.modelId, null, options);
75
+ if (ref) return ref;
76
+ }
77
+ const normalised = _chunk5XBMNY7Qcjs.normalizeString.call(void 0, inputModel);
78
+ let slug = normalised;
79
+ let vendor;
80
+ if (normalised.includes("/")) {
81
+ const [prefix, ...rest] = normalised.split("/");
82
+ if (!isOpenRouterProvider(prefix)) {
83
+ vendor = _chunk5XBMNY7Qcjs.normalizeProvider.call(void 0, prefix);
84
+ slug = rest.join("/");
85
+ }
86
+ }
87
+ vendor ??= inferProviderFromSlug(slug, options);
88
+ if (!vendor) return null;
89
+ if (_optionalChain([options, 'optionalAccess', _4 => _4.asOpenRouter])) {
90
+ return { provider: "openrouter", model: `${vendor}/${slug}` };
91
+ }
92
+ return { provider: vendor, model: slug };
93
+ }
94
+ function resolveModelVendorSync(model, catalog, options) {
95
+ const resolver = new (0, _chunk5XBMNY7Qcjs.ModelNameResolver)(catalog, options);
96
+ const attempts = buildVendorResolveAttempts(model);
97
+ let last = null;
98
+ for (const attempt of attempts) {
99
+ const result = resolver.resolve(attempt);
100
+ last = result;
101
+ if (result.found) {
102
+ const ref = resolveModelVendorFromResolution(result, model, options);
103
+ if (ref) return ref;
104
+ }
105
+ }
106
+ return resolveModelVendorFromResolution(
107
+ _nullishCoalesce(last, () => ( {
108
+ found: false,
109
+ modelId: null,
110
+ record: null,
111
+ attemptedStrategies: [],
112
+ reason: "Model not found in catalog"
113
+ })),
114
+ model,
115
+ options
116
+ );
117
+ }
118
+
119
+
120
+
121
+
122
+ exports.resolveModelVendorFromResolution = resolveModelVendorFromResolution; exports.resolveModelVendorSync = resolveModelVendorSync;
123
+ //# sourceMappingURL=chunk-TMDWPWKB.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-TMDWPWKB.cjs","../src/sync/modelNameResolver/resolveModelVendor.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACEA,SAAS,oBAAA,CAAqB,QAAA,EAA4B;AACxD,EAAA,OAAO,iDAAA,QAA0B,EAAA,IAAM,YAAA;AACzC;AAEA,SAAS,0BAAA,CAA2B,KAAA,EAAuC;AACzE,EAAA,MAAM,SAAA,EAAmC,CAAC,CAAA;AAC1C,EAAA,MAAM,KAAA,kBAAO,IAAI,GAAA,CAAY,CAAA;AAC7B,EAAA,MAAM,IAAA,EAAM,CAAC,CAAA,EAAW,CAAA,EAAA,GAAe;AACrC,IAAA,MAAM,IAAA,EAAM,CAAA,mBAAA;AACC,IAAA;AACD,IAAA;AACH,IAAA;AACX,EAAA;AAEW,EAAA;AAEL,EAAA;AACS,EAAA;AACP,IAAA;AACD,IAAA;AACQ,MAAA;AACb,IAAA;AACF,EAAA;AAEW,EAAA;AACJ,EAAA;AACT;AAYS;AAID,EAAA;AACS,IAAA;AACV,IAAA;AACL,EAAA;AACa,EAAA;AACC,IAAA;AACd,EAAA;AACO,EAAA;AACT;AAES;AAKK,EAAA;AACJ,IAAA;AACF,IAAA;AACN,EAAA;AAEM,EAAA;AACS,EAAA;AACP,IAAA;AACD,IAAA;AACI,MAAA;AACT,IAAA;AACF,EAAA;AAEO,EAAA;AACT;AAES;AAKQ,EAAA;AACF,EAAA;AAEP,EAAA;AACO,EAAA;AACP,EAAA;AAEO,EAAA;AACF,IAAA;AACX,EAAA;AAES,EAAA;AACX;AAGgB;AAKH,EAAA;AACG,IAAA;AACH,IAAA;AACX,EAAA;AAEY,EAAA;AACE,IAAA;AACH,IAAA;AACX,EAAA;AAEM,EAAA;AACK,EAAA;AACP,EAAA;AAEW,EAAA;AACN,IAAA;AACF,IAAA;AACM,MAAA;AACF,MAAA;AACT,IAAA;AACF,EAAA;AAEW,EAAA;AACE,EAAA;AAEA,EAAA;AACF,IAAA;AACX,EAAA;AAES,EAAA;AACX;AAGgB;AAKR,EAAA;AACA,EAAA;AACmC,EAAA;AAE9B,EAAA;AACH,IAAA;AACC,IAAA;AACI,IAAA;AACH,MAAA;AACG,MAAA;AACX,IAAA;AACF,EAAA;AAEO,EAAA;AACG,qBAAA;AACC,MAAA;AACE,MAAA;AACD,MAAA;AACR,MAAA;AACQ,MAAA;AACV,IAAA;AACA,IAAA;AACA,IAAA;AACF,EAAA;AACF;ADrDiB;AACA;AACA;AACA;AACA","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-TMDWPWKB.cjs","sourcesContent":[null,"import type { AiModelRecord } from \"../../models/types.js\";\nimport { ModelNameResolver } from \"./ModelNameResolver.js\";\nimport { PROVIDER_INFERENCE_MAP } from \"./constants.js\";\nimport { modelSlug, normalizeProvider, normalizeString } from \"./normalize.js\";\nimport type {\n ModelResolutionInput,\n ModelResolutionResult,\n ModelResolverOptions,\n} from \"./types.js\";\n\nfunction isOpenRouterProvider(provider?: string): boolean {\n return normalizeProvider(provider) === \"openrouter\";\n}\n\nfunction buildVendorResolveAttempts(model: string): ModelResolutionInput[] {\n const attempts: ModelResolutionInput[] = [];\n const seen = new Set<string>();\n const add = (m: string, p?: string) => {\n const key = `${p ?? \"\"}\\0${normalizeString(m)}`;\n if (seen.has(key)) return;\n seen.add(key);\n attempts.push({ model: m, provider: p });\n };\n\n add(model, undefined);\n\n const normalised = normalizeString(model);\n if (normalised.includes(\"/\")) {\n const prefix = normalised.split(\"/\")[0]!;\n if (!isOpenRouterProvider(prefix)) {\n add(model, normalizeProvider(prefix));\n }\n }\n\n add(model, \"openrouter\");\n return attempts;\n}\n\nexport type ModelVendorRef = {\n provider: string;\n model: string;\n};\n\nexport type ResolveModelVendorOptions = ModelResolverOptions & {\n /** Return OpenRouter transport shape: provider `openrouter`, model `vendor/slug`. */\n asOpenRouter?: boolean;\n};\n\nfunction inferProviderFromSlug(\n slug: string,\n options?: ResolveModelVendorOptions,\n): string | undefined {\n const patterns = [\n ...(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\nfunction vendorFromModelId(\n modelId: string,\n record: AiModelRecord | null | undefined,\n options?: ResolveModelVendorOptions,\n): string | undefined {\n if (record?.providerId) {\n const provider = normalizeProvider(record.providerId);\n if (provider && !isOpenRouterProvider(provider)) return provider;\n }\n\n const normalised = normalizeString(modelId);\n if (normalised.includes(\"/\")) {\n const prefix = normalised.split(\"/\")[0]!;\n if (!isOpenRouterProvider(prefix)) {\n return normalizeProvider(prefix);\n }\n }\n\n return inferProviderFromSlug(modelSlug(normalised), options);\n}\n\nfunction formatModelVendorRef(\n modelId: string,\n record: AiModelRecord | null | undefined,\n options?: ResolveModelVendorOptions,\n): ModelVendorRef | null {\n const vendor = vendorFromModelId(modelId, record, options);\n if (!vendor) return null;\n\n const normalised = normalizeString(modelId);\n const slug = normalised.includes(\"/\") ? modelSlug(normalised) : normalised;\n const openRouterSlug = normalised.includes(\"/\") ? normalised : `${vendor}/${slug}`;\n\n if (options?.asOpenRouter) {\n return { provider: \"openrouter\", model: openRouterSlug };\n }\n\n return { provider: vendor, model: slug };\n}\n\n/** Map a resolution result (or best-effort fallback) to `{ provider, model }`. */\nexport function resolveModelVendorFromResolution(\n result: ModelResolutionResult,\n inputModel: string,\n options?: ResolveModelVendorOptions,\n): ModelVendorRef | null {\n if (result.found) {\n const ref = formatModelVendorRef(result.modelId, result.record, options);\n if (ref) return ref;\n }\n\n if (!result.found && result.bestRejectedCandidate) {\n const ref = formatModelVendorRef(result.bestRejectedCandidate.modelId, null, options);\n if (ref) return ref;\n }\n\n const normalised = normalizeString(inputModel);\n let slug = normalised;\n let vendor: string | undefined;\n\n if (normalised.includes(\"/\")) {\n const [prefix, ...rest] = normalised.split(\"/\");\n if (!isOpenRouterProvider(prefix)) {\n vendor = normalizeProvider(prefix);\n slug = rest.join(\"/\");\n }\n }\n\n vendor ??= inferProviderFromSlug(slug, options);\n if (!vendor) return null;\n\n if (options?.asOpenRouter) {\n return { provider: \"openrouter\", model: `${vendor}/${slug}` };\n }\n\n return { provider: vendor, model: slug };\n}\n\n/** Best-effort vendor lookup from a model name alone (sync, catalog map only). */\nexport function resolveModelVendorSync(\n model: string,\n catalog: Map<string, AiModelRecord>,\n options?: ResolveModelVendorOptions,\n): ModelVendorRef | null {\n const resolver = new ModelNameResolver(catalog, options);\n const attempts = buildVendorResolveAttempts(model);\n let last: ModelResolutionResult | null = null;\n\n for (const attempt of attempts) {\n const result = resolver.resolve(attempt);\n last = result;\n if (result.found) {\n const ref = resolveModelVendorFromResolution(result, model, options);\n if (ref) return ref;\n }\n }\n\n return resolveModelVendorFromResolution(\n last ?? {\n found: false,\n modelId: null,\n record: null,\n attemptedStrategies: [],\n reason: \"Model not found in catalog\",\n },\n model,\n options,\n );\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  computeSupportsReasoning
3
- } from "./chunk-54GKLIDW.js";
3
+ } from "./chunk-SQ6NOF4Z.js";
4
4
 
5
5
  // src/models/normalizeOpenRouterModel.ts
6
6
  function parsePrice(value) {
@@ -99,4 +99,4 @@ export {
99
99
  extractProviderId,
100
100
  normalizeOpenRouterModel
101
101
  };
102
- //# sourceMappingURL=chunk-MOLWV5LV.js.map
102
+ //# sourceMappingURL=chunk-VDNKQRDG.js.map
@@ -0,0 +1,123 @@
1
+ import {
2
+ ModelNameResolver,
3
+ PROVIDER_INFERENCE_MAP,
4
+ modelSlug,
5
+ normalizeProvider,
6
+ normalizeString
7
+ } from "./chunk-SYHLDADG.js";
8
+
9
+ // src/sync/modelNameResolver/resolveModelVendor.ts
10
+ function isOpenRouterProvider(provider) {
11
+ return normalizeProvider(provider) === "openrouter";
12
+ }
13
+ function buildVendorResolveAttempts(model) {
14
+ const attempts = [];
15
+ const seen = /* @__PURE__ */ new Set();
16
+ const add = (m, p) => {
17
+ const key = `${p ?? ""}\0${normalizeString(m)}`;
18
+ if (seen.has(key)) return;
19
+ seen.add(key);
20
+ attempts.push({ model: m, provider: p });
21
+ };
22
+ add(model, void 0);
23
+ const normalised = normalizeString(model);
24
+ if (normalised.includes("/")) {
25
+ const prefix = normalised.split("/")[0];
26
+ if (!isOpenRouterProvider(prefix)) {
27
+ add(model, normalizeProvider(prefix));
28
+ }
29
+ }
30
+ add(model, "openrouter");
31
+ return attempts;
32
+ }
33
+ function inferProviderFromSlug(slug, options) {
34
+ const patterns = [
35
+ ...options?.additionalProviderPatterns ?? [],
36
+ ...PROVIDER_INFERENCE_MAP
37
+ ];
38
+ for (const { pattern, provider } of patterns) {
39
+ if (pattern.test(slug)) return provider;
40
+ }
41
+ return void 0;
42
+ }
43
+ function vendorFromModelId(modelId, record, options) {
44
+ if (record?.providerId) {
45
+ const provider = normalizeProvider(record.providerId);
46
+ if (provider && !isOpenRouterProvider(provider)) return provider;
47
+ }
48
+ const normalised = normalizeString(modelId);
49
+ if (normalised.includes("/")) {
50
+ const prefix = normalised.split("/")[0];
51
+ if (!isOpenRouterProvider(prefix)) {
52
+ return normalizeProvider(prefix);
53
+ }
54
+ }
55
+ return inferProviderFromSlug(modelSlug(normalised), options);
56
+ }
57
+ function formatModelVendorRef(modelId, record, options) {
58
+ const vendor = vendorFromModelId(modelId, record, options);
59
+ if (!vendor) return null;
60
+ const normalised = normalizeString(modelId);
61
+ const slug = normalised.includes("/") ? modelSlug(normalised) : normalised;
62
+ const openRouterSlug = normalised.includes("/") ? normalised : `${vendor}/${slug}`;
63
+ if (options?.asOpenRouter) {
64
+ return { provider: "openrouter", model: openRouterSlug };
65
+ }
66
+ return { provider: vendor, model: slug };
67
+ }
68
+ function resolveModelVendorFromResolution(result, inputModel, options) {
69
+ if (result.found) {
70
+ const ref = formatModelVendorRef(result.modelId, result.record, options);
71
+ if (ref) return ref;
72
+ }
73
+ if (!result.found && result.bestRejectedCandidate) {
74
+ const ref = formatModelVendorRef(result.bestRejectedCandidate.modelId, null, options);
75
+ if (ref) return ref;
76
+ }
77
+ const normalised = normalizeString(inputModel);
78
+ let slug = normalised;
79
+ let vendor;
80
+ if (normalised.includes("/")) {
81
+ const [prefix, ...rest] = normalised.split("/");
82
+ if (!isOpenRouterProvider(prefix)) {
83
+ vendor = normalizeProvider(prefix);
84
+ slug = rest.join("/");
85
+ }
86
+ }
87
+ vendor ??= inferProviderFromSlug(slug, options);
88
+ if (!vendor) return null;
89
+ if (options?.asOpenRouter) {
90
+ return { provider: "openrouter", model: `${vendor}/${slug}` };
91
+ }
92
+ return { provider: vendor, model: slug };
93
+ }
94
+ function resolveModelVendorSync(model, catalog, options) {
95
+ const resolver = new ModelNameResolver(catalog, options);
96
+ const attempts = buildVendorResolveAttempts(model);
97
+ let last = null;
98
+ for (const attempt of attempts) {
99
+ const result = resolver.resolve(attempt);
100
+ last = result;
101
+ if (result.found) {
102
+ const ref = resolveModelVendorFromResolution(result, model, options);
103
+ if (ref) return ref;
104
+ }
105
+ }
106
+ return resolveModelVendorFromResolution(
107
+ last ?? {
108
+ found: false,
109
+ modelId: null,
110
+ record: null,
111
+ attemptedStrategies: [],
112
+ reason: "Model not found in catalog"
113
+ },
114
+ model,
115
+ options
116
+ );
117
+ }
118
+
119
+ export {
120
+ resolveModelVendorFromResolution,
121
+ resolveModelVendorSync
122
+ };
123
+ //# sourceMappingURL=chunk-VYVX46VO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sync/modelNameResolver/resolveModelVendor.ts"],"sourcesContent":["import type { AiModelRecord } from \"../../models/types.js\";\nimport { ModelNameResolver } from \"./ModelNameResolver.js\";\nimport { PROVIDER_INFERENCE_MAP } from \"./constants.js\";\nimport { modelSlug, normalizeProvider, normalizeString } from \"./normalize.js\";\nimport type {\n ModelResolutionInput,\n ModelResolutionResult,\n ModelResolverOptions,\n} from \"./types.js\";\n\nfunction isOpenRouterProvider(provider?: string): boolean {\n return normalizeProvider(provider) === \"openrouter\";\n}\n\nfunction buildVendorResolveAttempts(model: string): ModelResolutionInput[] {\n const attempts: ModelResolutionInput[] = [];\n const seen = new Set<string>();\n const add = (m: string, p?: string) => {\n const key = `${p ?? \"\"}\\0${normalizeString(m)}`;\n if (seen.has(key)) return;\n seen.add(key);\n attempts.push({ model: m, provider: p });\n };\n\n add(model, undefined);\n\n const normalised = normalizeString(model);\n if (normalised.includes(\"/\")) {\n const prefix = normalised.split(\"/\")[0]!;\n if (!isOpenRouterProvider(prefix)) {\n add(model, normalizeProvider(prefix));\n }\n }\n\n add(model, \"openrouter\");\n return attempts;\n}\n\nexport type ModelVendorRef = {\n provider: string;\n model: string;\n};\n\nexport type ResolveModelVendorOptions = ModelResolverOptions & {\n /** Return OpenRouter transport shape: provider `openrouter`, model `vendor/slug`. */\n asOpenRouter?: boolean;\n};\n\nfunction inferProviderFromSlug(\n slug: string,\n options?: ResolveModelVendorOptions,\n): string | undefined {\n const patterns = [\n ...(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\nfunction vendorFromModelId(\n modelId: string,\n record: AiModelRecord | null | undefined,\n options?: ResolveModelVendorOptions,\n): string | undefined {\n if (record?.providerId) {\n const provider = normalizeProvider(record.providerId);\n if (provider && !isOpenRouterProvider(provider)) return provider;\n }\n\n const normalised = normalizeString(modelId);\n if (normalised.includes(\"/\")) {\n const prefix = normalised.split(\"/\")[0]!;\n if (!isOpenRouterProvider(prefix)) {\n return normalizeProvider(prefix);\n }\n }\n\n return inferProviderFromSlug(modelSlug(normalised), options);\n}\n\nfunction formatModelVendorRef(\n modelId: string,\n record: AiModelRecord | null | undefined,\n options?: ResolveModelVendorOptions,\n): ModelVendorRef | null {\n const vendor = vendorFromModelId(modelId, record, options);\n if (!vendor) return null;\n\n const normalised = normalizeString(modelId);\n const slug = normalised.includes(\"/\") ? modelSlug(normalised) : normalised;\n const openRouterSlug = normalised.includes(\"/\") ? normalised : `${vendor}/${slug}`;\n\n if (options?.asOpenRouter) {\n return { provider: \"openrouter\", model: openRouterSlug };\n }\n\n return { provider: vendor, model: slug };\n}\n\n/** Map a resolution result (or best-effort fallback) to `{ provider, model }`. */\nexport function resolveModelVendorFromResolution(\n result: ModelResolutionResult,\n inputModel: string,\n options?: ResolveModelVendorOptions,\n): ModelVendorRef | null {\n if (result.found) {\n const ref = formatModelVendorRef(result.modelId, result.record, options);\n if (ref) return ref;\n }\n\n if (!result.found && result.bestRejectedCandidate) {\n const ref = formatModelVendorRef(result.bestRejectedCandidate.modelId, null, options);\n if (ref) return ref;\n }\n\n const normalised = normalizeString(inputModel);\n let slug = normalised;\n let vendor: string | undefined;\n\n if (normalised.includes(\"/\")) {\n const [prefix, ...rest] = normalised.split(\"/\");\n if (!isOpenRouterProvider(prefix)) {\n vendor = normalizeProvider(prefix);\n slug = rest.join(\"/\");\n }\n }\n\n vendor ??= inferProviderFromSlug(slug, options);\n if (!vendor) return null;\n\n if (options?.asOpenRouter) {\n return { provider: \"openrouter\", model: `${vendor}/${slug}` };\n }\n\n return { provider: vendor, model: slug };\n}\n\n/** Best-effort vendor lookup from a model name alone (sync, catalog map only). */\nexport function resolveModelVendorSync(\n model: string,\n catalog: Map<string, AiModelRecord>,\n options?: ResolveModelVendorOptions,\n): ModelVendorRef | null {\n const resolver = new ModelNameResolver(catalog, options);\n const attempts = buildVendorResolveAttempts(model);\n let last: ModelResolutionResult | null = null;\n\n for (const attempt of attempts) {\n const result = resolver.resolve(attempt);\n last = result;\n if (result.found) {\n const ref = resolveModelVendorFromResolution(result, model, options);\n if (ref) return ref;\n }\n }\n\n return resolveModelVendorFromResolution(\n last ?? {\n found: false,\n modelId: null,\n record: null,\n attemptedStrategies: [],\n reason: \"Model not found in catalog\",\n },\n model,\n options,\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,9 @@
1
+ import {
2
+ resolveModelVendor
3
+ } from "./chunk-EBBJCLJQ.js";
1
4
  import {
2
5
  AiModelsCatalogClient
3
- } from "./chunk-D6OIUYNC.js";
6
+ } from "./chunk-ET5LPVPT.js";
4
7
 
5
8
  // src/models/filterModels.ts
6
9
  function matchesSearch(record, search) {
@@ -69,6 +72,9 @@ var AiModelsService = class {
69
72
  async resolve(modelIdOrAlias, provider) {
70
73
  return this.client.resolveModel({ model: modelIdOrAlias, provider });
71
74
  }
75
+ async resolveVendor(model, options) {
76
+ return resolveModelVendor(model, this.client, options);
77
+ }
72
78
  async refresh() {
73
79
  await this.client.refresh();
74
80
  }
@@ -83,4 +89,4 @@ export {
83
89
  AiModelsService,
84
90
  getModelInfo
85
91
  };
86
- //# sourceMappingURL=chunk-KSJSLKYI.js.map
92
+ //# sourceMappingURL=chunk-WFRS32EQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/models/filterModels.ts","../src/models/AiModelsService.ts"],"sourcesContent":["import type { AiModelRecord, ModelListFilters } from \"./types.js\";\n\nfunction matchesSearch(record: AiModelRecord, search: string): boolean {\n const q = search.toLowerCase();\n return (\n record.modelId.toLowerCase().includes(q) ||\n record.name.toLowerCase().includes(q) ||\n record.description.toLowerCase().includes(q) ||\n record.canonicalSlug.toLowerCase().includes(q) ||\n record.aliases.some((a) => a.toLowerCase().includes(q))\n );\n}\n\nexport function filterModels(\n models: Iterable<AiModelRecord>,\n filters: ModelListFilters = {},\n): AiModelRecord[] {\n let list = [...models];\n\n if (filters.providerId) {\n list = list.filter((m) => m.providerId === filters.providerId);\n }\n if (filters.status) {\n list = list.filter((m) => m.status === filters.status);\n }\n if (filters.outputModality) {\n list = list.filter((m) => m.outputModalities.includes(filters.outputModality!));\n }\n if (filters.inputModality) {\n list = list.filter((m) => m.inputModalities.includes(filters.inputModality!));\n }\n if (filters.supportedParameter) {\n list = list.filter((m) => m.supportedParameters.includes(filters.supportedParameter!));\n }\n if (filters.supportsTools !== undefined) {\n list = list.filter((m) => m.supportsTools === filters.supportsTools);\n }\n if (filters.supportsReasoning !== undefined) {\n list = list.filter((m) => m.supportsReasoning === filters.supportsReasoning);\n }\n if (filters.search) {\n list = list.filter((m) => matchesSearch(m, filters.search!));\n }\n\n list.sort((a, b) => a.name.localeCompare(b.name));\n\n const offset = filters.offset ?? 0;\n const limit = filters.limit ?? list.length;\n return list.slice(offset, offset + limit);\n}\n\nexport function countModels(\n models: Iterable<AiModelRecord>,\n filters: Omit<ModelListFilters, \"limit\" | \"offset\"> = {},\n): number {\n return filterModels(models, { ...filters, limit: Number.MAX_SAFE_INTEGER, offset: 0 }).length;\n}\n","import { AiModelsCatalogClient } from \"../catalog/AiModelsCatalogClient.js\";\nimport type { AiModelsCatalogClientOptions } from \"../catalog/AiModelsCatalogClient.js\";\nimport { countModels, filterModels } from \"./filterModels.js\";\nimport type { AiModelRecord, ModelListFilters, ModelListResult } from \"./types.js\";\nimport {\n resolveModelVendor,\n type ModelVendorRef,\n type ResolveModelVendorOptions,\n} from \"../cost/resolveModelVendor.js\";\n\nexport type AiModelsServiceOptions = AiModelsCatalogClientOptions;\n\n/**\n * High-level model catalog API — list, filter, count, and get full model info.\n */\nexport class AiModelsService {\n private readonly client: AiModelsCatalogClient;\n\n constructor(options: AiModelsServiceOptions = {}) {\n this.client = new AiModelsCatalogClient(options);\n }\n\n async getAllModels(): Promise<Map<string, AiModelRecord>> {\n return this.client.getAllModels();\n }\n\n async listModels(filters: ModelListFilters = {}): Promise<ModelListResult> {\n const all = await this.getAllModels();\n const total = countModels(all.values(), filters);\n const limit = filters.limit ?? 50;\n const offset = filters.offset ?? 0;\n const models = filterModels(all.values(), { ...filters, limit, offset });\n return { models, total, limit, offset };\n }\n\n async countModels(filters: Omit<ModelListFilters, \"limit\" | \"offset\"> = {}): Promise<number> {\n const all = await this.getAllModels();\n return countModels(all.values(), filters);\n }\n\n async getModelInfo(modelIdOrAlias: string, provider?: string): Promise<AiModelRecord | null> {\n return this.client.getModel(modelIdOrAlias, provider);\n }\n\n async resolve(\n modelIdOrAlias: string,\n provider?: string,\n ): Promise<import(\"../sync/modelNameResolver/types.js\").ModelResolutionResult> {\n return this.client.resolveModel({ model: modelIdOrAlias, provider });\n }\n\n async resolveVendor(\n model: string,\n options?: ResolveModelVendorOptions,\n ): Promise<ModelVendorRef | null> {\n return resolveModelVendor(model, this.client, options);\n }\n\n async refresh(): Promise<void> {\n await this.client.refresh();\n }\n}\n\nexport async function getModelInfo(\n modelIdOrAlias: string,\n options: AiModelsServiceOptions = {},\n provider?: string,\n): Promise<AiModelRecord | null> {\n return new AiModelsService(options).getModelInfo(modelIdOrAlias, provider);\n}\n"],"mappings":"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","names":[]}
@@ -5,7 +5,7 @@ import {
5
5
  normalizeString,
6
6
  shouldDefaultRouteViaOpenRouter,
7
7
  stripModelVersionSuffix
8
- } from "./chunk-SLSKQRMI.js";
8
+ } from "./chunk-SYHLDADG.js";
9
9
 
10
10
  // src/cost/costModelResolution.ts
11
11
  function isOpenRouterProvider(provider) {
@@ -260,4 +260,4 @@ export {
260
260
  resolveRoutedViaOpenRouter,
261
261
  matchModelInAiProfiles
262
262
  };
263
- //# sourceMappingURL=chunk-HEB73GKJ.js.map
263
+ //# sourceMappingURL=chunk-XMOALOYU.js.map
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-XUUPJ7WO.js.map
@@ -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 _chunkRSHI4OOYcjs = require('./chunk-RSHI4OOY.cjs');
3
+ var _chunk2KPWVOOTcjs = require('./chunk-2KPWVOOT.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 = _chunkRSHI4OOYcjs.computeSupportsReasoning.call(void 0, {
57
+ const supportsReasoning = _chunk2KPWVOOTcjs.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-TMA6QSNH.cjs.map
102
+ //# sourceMappingURL=chunk-YO7AJ5Z3.cjs.map
@@ -1 +1 @@
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
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-YO7AJ5Z3.cjs","../src/models/normalizeOpenRouterModel.ts"],"names":[],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-YO7AJ5Z3.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,25 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict"; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; }
3
3
 
4
- var _chunkDDRWORUUcjs = require('../chunk-DDRWORUU.cjs');
4
+ var _chunk2A6EUGR5cjs = require('../chunk-2A6EUGR5.cjs');
5
5
 
6
6
 
7
7
 
8
8
  var _chunkBAHBDADJcjs = require('../chunk-BAHBDADJ.cjs');
9
9
 
10
10
 
11
- var _chunk76FHWQH3cjs = require('../chunk-76FHWQH3.cjs');
11
+ var _chunkGVFL2LRGcjs = require('../chunk-GVFL2LRG.cjs');
12
+ require('../chunk-FISSYP27.cjs');
13
+ require('../chunk-TMDWPWKB.cjs');
12
14
 
13
15
 
14
16
 
15
- var _chunk75ZVXZAVcjs = require('../chunk-75ZVXZAV.cjs');
17
+ var _chunkI6CDT2NGcjs = require('../chunk-I6CDT2NG.cjs');
16
18
 
17
19
 
18
20
 
19
- var _chunkHBNYVRLZcjs = require('../chunk-HBNYVRLZ.cjs');
20
- require('../chunk-WSUFQR3D.cjs');
21
- require('../chunk-RSHI4OOY.cjs');
22
- require('../chunk-BCX5CLJJ.cjs');
21
+ var _chunkSIR4LDHDcjs = require('../chunk-SIR4LDHD.cjs');
22
+ require('../chunk-TDO5SDQ3.cjs');
23
+ require('../chunk-2KPWVOOT.cjs');
24
+ require('../chunk-5XBMNY7Q.cjs');
23
25
  require('../chunk-PADNCGZB.cjs');
24
26
 
25
27
 
@@ -36,8 +38,8 @@ function registry(path) {
36
38
  function resolver(path) {
37
39
  return new (0, _chunkBAHBDADJcjs.AliasResolver)({
38
40
  registry: registry(path),
39
- catalogClient: new (0, _chunkHBNYVRLZcjs.AiModelsCatalogClient)({
40
- cacheTtlMs: _chunkHBNYVRLZcjs.resolveCatalogCacheTtlMs.call(void 0, )
41
+ catalogClient: new (0, _chunkSIR4LDHDcjs.AiModelsCatalogClient)({
42
+ cacheTtlMs: _chunkSIR4LDHDcjs.resolveCatalogCacheTtlMs.call(void 0, )
41
43
  })
42
44
  });
43
45
  }
@@ -162,7 +164,7 @@ function emitHuman(lines) {
162
164
  function registerCatalogCommand(program2) {
163
165
  const catalog = program2.command("catalog").description("Model catalog load and health commands");
164
166
  catalog.command("refresh").description("Fetch catalogs from open-assets.x12i.com and warm the cache").option("--bundled-only", "Use bundled src/data catalogs only (no HTTP)").option("--json", "Machine-readable JSON on stdout").action(async (opts) => {
165
- const result = await _chunk75ZVXZAVcjs.refreshAiModelsCatalog.call(void 0, { bundledOnly: opts.bundledOnly });
167
+ const result = await _chunkI6CDT2NGcjs.refreshAiModelsCatalog.call(void 0, { bundledOnly: opts.bundledOnly });
166
168
  if (opts.json) {
167
169
  emitJson(result);
168
170
  } else {
@@ -174,7 +176,7 @@ function registerCatalogCommand(program2) {
174
176
  }
175
177
  });
176
178
  catalog.command("verify").description("Validate direct + OpenRouter catalogs load successfully").option("--bundled-only", "Use bundled src/data catalogs only (no HTTP)").option("--json", "Machine-readable JSON on stdout").action(async (opts) => {
177
- const report = await _chunk75ZVXZAVcjs.verifyAiModelsCatalog.call(void 0, { bundledOnly: opts.bundledOnly });
179
+ const report = await _chunkI6CDT2NGcjs.verifyAiModelsCatalog.call(void 0, { bundledOnly: opts.bundledOnly });
178
180
  if (opts.json) {
179
181
  emitJson(report);
180
182
  } else {
@@ -202,11 +204,11 @@ function registerCostCommand(program2) {
202
204
  "Completion token count",
203
205
  (v) => Number.parseInt(v, 10)
204
206
  ).option("--cached-tokens <n>", "Cached token count", (v) => Number.parseInt(v, 10)).option("--reasoning-tokens <n>", "Reasoning token count", (v) => Number.parseInt(v, 10)).option("--provider <id>", "Provider for pricing selection", "openrouter").option("--json", "Output raw AiCostResult JSON").option("--bundled-only", "Use src/data catalogs only (no HTTP)").action(async (opts) => {
205
- const catalogClient = new (0, _chunkHBNYVRLZcjs.AiModelsCatalogClient)({
206
- cacheTtlMs: _chunkHBNYVRLZcjs.resolveCatalogCacheTtlMs.call(void 0, ),
207
+ const catalogClient = new (0, _chunkSIR4LDHDcjs.AiModelsCatalogClient)({
208
+ cacheTtlMs: _chunkSIR4LDHDcjs.resolveCatalogCacheTtlMs.call(void 0, ),
207
209
  bundledOnly: opts.bundledOnly
208
210
  });
209
- const calculator = new (0, _chunkDDRWORUUcjs.CostCalculator)(catalogClient, {
211
+ const calculator = new (0, _chunk2A6EUGR5cjs.CostCalculator)(catalogClient, {
210
212
  aliasRegistry: new (0, _chunkBAHBDADJcjs.AliasRegistry)()
211
213
  });
212
214
  const result = await calculator.calculate({
@@ -248,8 +250,8 @@ function registerCostCommand(program2) {
248
250
 
249
251
  // src/cli/commands/models.ts
250
252
  function service(opts) {
251
- return new (0, _chunk76FHWQH3cjs.AiModelsService)({
252
- cacheTtlMs: _chunkHBNYVRLZcjs.resolveCatalogCacheTtlMs.call(void 0, ),
253
+ return new (0, _chunkGVFL2LRGcjs.AiModelsService)({
254
+ cacheTtlMs: _chunkSIR4LDHDcjs.resolveCatalogCacheTtlMs.call(void 0, ),
253
255
  bundledOnly: opts.bundledOnly
254
256
  });
255
257
  }
@@ -333,6 +335,24 @@ ${rows.length} shown \xB7 ${total} matching`);
333
335
  console.log(`Confidence: ${result.confidence.toFixed(2)}`);
334
336
  console.log(`Via OR: ${result.routedViaOpenRouter ? "yes" : "no"}`);
335
337
  });
338
+ models.command("vendor").description("Find model vendor from model name alone (best-effort)").requiredOption("--model <m>", "Model string (required)").option("--openrouter", "Return OpenRouter transport shape (provider openrouter, model vendor/slug)").option("--json", "Output raw JSON").option("--bundled-only", "Use src/data catalogs only (no HTTP)").action(async (opts) => {
339
+ const ref = await service(opts).resolveVendor(opts.model, {
340
+ asOpenRouter: opts.openrouter
341
+ });
342
+ if (opts.json) {
343
+ console.log(JSON.stringify(ref, null, 2));
344
+ if (!ref) process.exit(1);
345
+ return;
346
+ }
347
+ console.log(`Input: model="${opts.model}"`);
348
+ if (!ref) {
349
+ console.log("Result: NOT FOUND");
350
+ process.exit(1);
351
+ return;
352
+ }
353
+ console.log(`Vendor: ${ref.provider}`);
354
+ console.log(`Model: ${ref.model}`);
355
+ });
336
356
  models.command("count").description("Count models matching filters").option("--provider <id>", "Filter by providerId").option("--output-modality <m>", "Filter by output modality").option("--parameter <p>", "Filter by supported parameter").option("--tools", "Only models that support tools").option("--reasoning", "Only reasoning / thinking models").option("--bundled-only", "Use src/data catalogs only (no HTTP)").action(async (opts) => {
337
357
  const n = await service(opts).countModels({
338
358
  providerId: opts.provider,