@agentproto/model-catalog 0.9.0 → 0.9.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 (29) hide show
  1. package/dist/access/index.mjs +3 -3
  2. package/dist/{chunk-HL2G36MT.mjs → chunk-3Y5TQDGE.mjs} +3 -3
  3. package/dist/{chunk-HL2G36MT.mjs.map → chunk-3Y5TQDGE.mjs.map} +1 -1
  4. package/dist/{chunk-BR4ZEPA7.mjs → chunk-4ROXWVQD.mjs} +5 -5
  5. package/dist/{chunk-BR4ZEPA7.mjs.map → chunk-4ROXWVQD.mjs.map} +1 -1
  6. package/dist/{chunk-W7HLNKXV.mjs → chunk-AJLMLBEZ.mjs} +3 -3
  7. package/dist/{chunk-W7HLNKXV.mjs.map → chunk-AJLMLBEZ.mjs.map} +1 -1
  8. package/dist/{chunk-GEXPCKCK.mjs → chunk-AVCHKXUD.mjs} +114 -62
  9. package/dist/chunk-AVCHKXUD.mjs.map +1 -0
  10. package/dist/{chunk-CBP4SNOX.mjs → chunk-OH37WKVA.mjs} +423 -151
  11. package/dist/chunk-OH37WKVA.mjs.map +1 -0
  12. package/dist/{chunk-NSTJSCCC.mjs → chunk-QDQWHWDU.mjs} +3 -3
  13. package/dist/{chunk-NSTJSCCC.mjs.map → chunk-QDQWHWDU.mjs.map} +1 -1
  14. package/dist/{chunk-DW45X6XT.mjs → chunk-QNJRWRWC.mjs} +18 -3
  15. package/dist/chunk-QNJRWRWC.mjs.map +1 -0
  16. package/dist/{chunk-RCQRQD3A.mjs → chunk-W4VANZM3.mjs} +4 -4
  17. package/dist/{chunk-RCQRQD3A.mjs.map → chunk-W4VANZM3.mjs.map} +1 -1
  18. package/dist/{chunk-FTHTPPAY.mjs → chunk-XC355MAQ.mjs} +4 -4
  19. package/dist/{chunk-FTHTPPAY.mjs.map → chunk-XC355MAQ.mjs.map} +1 -1
  20. package/dist/cost/index.mjs +6 -6
  21. package/dist/curation/index.mjs +6 -6
  22. package/dist/index.mjs +11 -11
  23. package/dist/llm/index.mjs +1 -1
  24. package/dist/route-identity/index.mjs +3 -3
  25. package/dist/schema/index.mjs +2 -2
  26. package/package.json +3 -2
  27. package/dist/chunk-CBP4SNOX.mjs.map +0 -1
  28. package/dist/chunk-DW45X6XT.mjs.map +0 -1
  29. package/dist/chunk-GEXPCKCK.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
- export { evaluateAccess, evaluateCatalogDefaults } from '../chunk-NSTJSCCC.mjs';
2
- import '../chunk-W7HLNKXV.mjs';
1
+ export { evaluateAccess, evaluateCatalogDefaults } from '../chunk-QDQWHWDU.mjs';
2
+ import '../chunk-AJLMLBEZ.mjs';
3
3
  import '../chunk-ZTTWZ7PL.mjs';
4
- import '../chunk-CBP4SNOX.mjs';
4
+ import '../chunk-OH37WKVA.mjs';
5
5
  import '../chunk-QHELXPSL.mjs';
6
6
  //# sourceMappingURL=index.mjs.map
7
7
  //# sourceMappingURL=index.mjs.map
@@ -1,4 +1,4 @@
1
- import { baseEntryShape } from './chunk-DW45X6XT.mjs';
1
+ import { baseEntryShape } from './chunk-QNJRWRWC.mjs';
2
2
  import { z } from 'zod';
3
3
 
4
4
  /**
@@ -148,5 +148,5 @@ var ModelEntrySchema = z.discriminatedUnion("kind", [
148
148
  ]);
149
149
 
150
150
  export { AudioCapabilitiesSchema, AudioEntrySchema, AudioPricingSchema, ImageAspectRatioSchema, ImageCapabilitiesSchema, ImageEntrySchema, ImagePricingSchema, ImageReferenceImagesSchema, LLMEntrySchema, LlmPricingSchema, ModelEntrySchema, VideoCapabilitiesSchema, VideoCostMultipliersSchema, VideoEntrySchema, VideoPricingSchema, VideoResolutionSchema };
151
- //# sourceMappingURL=chunk-HL2G36MT.mjs.map
152
- //# sourceMappingURL=chunk-HL2G36MT.mjs.map
151
+ //# sourceMappingURL=chunk-3Y5TQDGE.mjs.map
152
+ //# sourceMappingURL=chunk-3Y5TQDGE.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schema/llm.ts","../src/schema/image.ts","../src/schema/video.ts","../src/schema/audio.ts","../src/schema/index.ts"],"names":["z"],"mappings":"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","file":"chunk-HL2G36MT.mjs","sourcesContent":["import { z } from \"zod\"\nimport { baseEntryShape } from \"./base.js\"\n\n/**\n * LLM pricing — token-based. Mirrors the historical `LLMPricing` shape in\n * `packages/core/src/config/llm-pricing.ts` so the existing\n * `calculateLLMCreditCost` formula carries over verbatim.\n */\nexport const LlmPricingSchema = z.object({\n inputPer1M: z.number().nonnegative(),\n outputPer1M: z.number().nonnegative(),\n creditInputPer1M: z.number().nonnegative(),\n creditOutputPer1M: z.number().nonnegative(),\n cacheReadMultiplier: z.number().nonnegative().optional(),\n cacheWriteMultiplier: z.number().nonnegative().optional(),\n // Router (how we call the model) vs vendor (who made it). See\n // `LLMPricing` in ../llm/catalog.ts for the contract.\n provider: z.string().optional(),\n vendor: z.string().optional(),\n})\nexport type LlmPricing = z.infer<typeof LlmPricingSchema>\n\nexport const LLMEntrySchema = z.object({\n ...baseEntryShape,\n kind: z.literal(\"llm\"),\n pricing: LlmPricingSchema,\n contextWindow: z.number().int().positive().optional(),\n})\nexport type LLMEntry = z.infer<typeof LLMEntrySchema>\n","import { z } from \"zod\"\nimport { baseEntryShape } from \"./base.js\"\n\nexport const ImageCapabilitiesSchema = z.object({\n generate: z.boolean(),\n edit: z.boolean(),\n upscale: z.boolean().optional(),\n})\nexport type ImageCapabilities = z.infer<typeof ImageCapabilitiesSchema>\n\nexport const ImageReferenceImagesSchema = z.object({\n supported: z.boolean(),\n fieldName: z.enum([\"image_input\", \"input_images\", \"input_image\", \"none\"]),\n maxCount: z.number().int().nonnegative(),\n singular: z.boolean(),\n})\nexport type ImageReferenceImages = z.infer<typeof ImageReferenceImagesSchema>\n\nexport const ImageAspectRatioSchema = z.object({\n supported: z.array(z.string()).min(1),\n default: z.string(),\n})\nexport type ImageAspectRatio = z.infer<typeof ImageAspectRatioSchema>\n\n/**\n * Pricing inputs for a model entry.\n *\n * Credit math is **derived at call time** by `computeCenticredits()` from\n * `baseCost × category-markup`. The catalog only carries the\n * production-cost input. An entry can opt out of the formula via\n * `overrideCreditCost` (strategic subsidy / partner pricing) — used\n * sparingly so a category-wide tune stays a one-line change in\n * `pricing/index.ts`.\n *\n * `costPerImage` / `costTier` / `creditCost` are deprecated but kept\n * readable so production data + admin UI keep parsing. New entries\n * should not set them.\n */\nexport const ImagePricingSchema = z.object({\n costPerImage: z.number().nonnegative().optional(),\n costTier: z.enum([\"low\", \"medium\", \"high\"]).optional(),\n billingUnit: z.literal(\"per_image\"),\n baseCost: z.number().nonnegative(),\n /** @deprecated Derived at call time. Kept for back-compat. */\n creditCost: z.number().nonnegative().optional(),\n /**\n * Strategic per-model override. When set, bypasses the formula and\n * the user is charged this many credits per output regardless of\n * provider cost or category markup.\n */\n overrideCreditCost: z.number().nonnegative().optional(),\n})\nexport type ImagePricing = z.infer<typeof ImagePricingSchema>\n\nexport const ImageEntrySchema = z.object({\n ...baseEntryShape,\n kind: z.literal(\"image\"),\n capabilities: ImageCapabilitiesSchema,\n referenceImages: ImageReferenceImagesSchema,\n aspectRatio: ImageAspectRatioSchema,\n output: z.enum([\"string\", \"array\"]),\n pricing: ImagePricingSchema,\n triggerWord: z.string().optional(),\n})\nexport type ImageEntry = z.infer<typeof ImageEntrySchema>\n","import { z } from \"zod\"\nimport { baseEntryShape } from \"./base.js\"\n\nexport const VideoCapabilitiesSchema = z.object({\n textToVideo: z.boolean(),\n imageToVideo: z.boolean(),\n subjectReference: z.boolean(),\n audio: z.boolean(),\n})\nexport type VideoCapabilities = z.infer<typeof VideoCapabilitiesSchema>\n\nexport const VideoResolutionSchema = z.enum([\n \"480p\",\n \"540p\",\n \"720p\",\n \"1080p\",\n \"1440p\",\n \"4k\",\n])\nexport type VideoResolution = z.infer<typeof VideoResolutionSchema>\n\n/**\n * Mirrors `CostMultipliers` from `the app integration-core`. Keys are\n * stringified so JSON round-trips cleanly.\n */\nexport const VideoCostMultipliersSchema = z.object({\n resolution: z.record(z.string(), z.number().positive()).optional(),\n duration: z.record(z.string(), z.number().positive()).optional(),\n mode: z.record(z.string(), z.number().positive()).optional(),\n})\nexport type VideoCostMultipliers = z.infer<typeof VideoCostMultipliersSchema>\n\nexport const VideoPricingSchema = z.object({\n costPerClip: z.number().nonnegative().optional(),\n costTier: z.enum([\"low\", \"medium\", \"high\"]).optional(),\n billingUnit: z.enum([\"per_clip\", \"per_second\"]),\n baseCost: z.number().nonnegative(),\n baseCostUnit: z.string(),\n /** Provider-cost multipliers (resolution / duration / mode). */\n multipliers: VideoCostMultipliersSchema.optional(),\n /** @deprecated Derived at call time. */\n creditCost: z.number().nonnegative().optional(),\n /**\n * @deprecated Use `multipliers` (provider-side) + per-category markup\n * in `pricing-registry`. The credit multipliers used to be a parallel\n * structure; now the formula re-applies `multipliers` to the derived\n * credit count automatically.\n */\n creditMultipliers: VideoCostMultipliersSchema.optional(),\n /** Strategic per-model override — bypasses the formula. */\n overrideCreditCost: z.number().nonnegative().optional(),\n})\nexport type VideoPricing = z.infer<typeof VideoPricingSchema>\n\nexport const VideoEntrySchema = z.object({\n ...baseEntryShape,\n kind: z.literal(\"video\"),\n capabilities: VideoCapabilitiesSchema,\n maxDuration: z.number().positive(),\n supportedResolutions: z.array(VideoResolutionSchema).min(1),\n supportedAspectRatios: z.array(z.string()).min(1),\n pricing: VideoPricingSchema,\n})\nexport type VideoEntry = z.infer<typeof VideoEntrySchema>\n","import { z } from \"zod\"\nimport { baseEntryShape } from \"./base.js\"\n\n// Single source of truth for audio model capabilities — mirrors (and is\n// re-used by) the runtime `AudioModelDefinition` in `audio/catalog.ts`.\n// Modality is multi-valued boolean flags (`tts`/`stt`/`s2s`) — a model may\n// do more than one; `s2s` is a speech↔speech engine (distinct from a\n// tts+llm+stt cascade). Transport (`streaming`) is a SEPARATE axis.\nexport const AudioCapabilitiesSchema = z.object({\n tts: z.boolean().optional(),\n stt: z.boolean().optional(),\n s2s: z.boolean().optional(),\n languages: z.array(z.string()),\n voiceCloning: z.boolean().optional(),\n streaming: z.boolean().optional(),\n timestamps: z.boolean().optional(),\n diarization: z.boolean().optional(),\n languageDetection: z.boolean().optional(),\n})\nexport type AudioCapabilities = z.infer<typeof AudioCapabilitiesSchema>\n\nexport const AudioPricingSchema = z.object({\n billingUnit: z.enum([\"per_character\", \"per_second\"]),\n baseCost: z.number().nonnegative(),\n baseCostUnit: z.string().optional(),\n /** @deprecated Derived at call time from `baseCost × category-markup`. */\n creditCost: z.number().nonnegative().optional(),\n /** Strategic per-model override — bypasses the formula. */\n overrideCreditCost: z.number().nonnegative().optional(),\n})\nexport type AudioPricing = z.infer<typeof AudioPricingSchema>\n\n// Voices are NOT per-model metadata — they live in the shared, provider-\n// neutral voice catalog (an app voice-catalog module,\n// `CatalogVoice`), referenced by id. The old per-entry `voice` placeholder\n// (+ its `VoiceMetadataSchema`) was never populated — removed.\nexport const AudioEntrySchema = z.object({\n ...baseEntryShape,\n kind: z.literal(\"audio\"),\n capabilities: AudioCapabilitiesSchema,\n pricing: AudioPricingSchema,\n supportedLocales: z.array(z.string()).optional(),\n})\nexport type AudioEntry = z.infer<typeof AudioEntrySchema>\n","import { z } from \"zod\"\nimport { LLMEntrySchema } from \"./llm.js\"\nimport { ImageEntrySchema } from \"./image.js\"\nimport { VideoEntrySchema } from \"./video.js\"\nimport { AudioEntrySchema } from \"./audio.js\"\n\nexport * from \"./base.js\"\nexport * from \"./llm.js\"\nexport * from \"./image.js\"\nexport * from \"./video.js\"\nexport * from \"./audio.js\"\nexport * from \"./voice.js\"\n\n/** Discriminated union over every kind. */\nexport const ModelEntrySchema = z.discriminatedUnion(\"kind\", [\n LLMEntrySchema,\n ImageEntrySchema,\n VideoEntrySchema,\n AudioEntrySchema,\n])\nexport type ModelEntry = z.infer<typeof ModelEntrySchema>\n"]}
1
+ {"version":3,"sources":["../src/schema/llm.ts","../src/schema/image.ts","../src/schema/video.ts","../src/schema/audio.ts","../src/schema/index.ts"],"names":["z"],"mappings":"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","file":"chunk-3Y5TQDGE.mjs","sourcesContent":["import { z } from \"zod\"\nimport { baseEntryShape } from \"./base.js\"\n\n/**\n * LLM pricing — token-based. Mirrors the historical `LLMPricing` shape in\n * `packages/core/src/config/llm-pricing.ts` so the existing\n * `calculateLLMCreditCost` formula carries over verbatim.\n */\nexport const LlmPricingSchema = z.object({\n inputPer1M: z.number().nonnegative(),\n outputPer1M: z.number().nonnegative(),\n creditInputPer1M: z.number().nonnegative(),\n creditOutputPer1M: z.number().nonnegative(),\n cacheReadMultiplier: z.number().nonnegative().optional(),\n cacheWriteMultiplier: z.number().nonnegative().optional(),\n // Router (how we call the model) vs vendor (who made it). See\n // `LLMPricing` in ../llm/catalog.ts for the contract.\n provider: z.string().optional(),\n vendor: z.string().optional(),\n})\nexport type LlmPricing = z.infer<typeof LlmPricingSchema>\n\nexport const LLMEntrySchema = z.object({\n ...baseEntryShape,\n kind: z.literal(\"llm\"),\n pricing: LlmPricingSchema,\n contextWindow: z.number().int().positive().optional(),\n})\nexport type LLMEntry = z.infer<typeof LLMEntrySchema>\n","import { z } from \"zod\"\nimport { baseEntryShape } from \"./base.js\"\n\nexport const ImageCapabilitiesSchema = z.object({\n generate: z.boolean(),\n edit: z.boolean(),\n upscale: z.boolean().optional(),\n})\nexport type ImageCapabilities = z.infer<typeof ImageCapabilitiesSchema>\n\nexport const ImageReferenceImagesSchema = z.object({\n supported: z.boolean(),\n fieldName: z.enum([\"image_input\", \"input_images\", \"input_image\", \"none\"]),\n maxCount: z.number().int().nonnegative(),\n singular: z.boolean(),\n})\nexport type ImageReferenceImages = z.infer<typeof ImageReferenceImagesSchema>\n\nexport const ImageAspectRatioSchema = z.object({\n supported: z.array(z.string()).min(1),\n default: z.string(),\n})\nexport type ImageAspectRatio = z.infer<typeof ImageAspectRatioSchema>\n\n/**\n * Pricing inputs for a model entry.\n *\n * Credit math is **derived at call time** by `computeCenticredits()` from\n * `baseCost × category-markup`. The catalog only carries the\n * production-cost input. An entry can opt out of the formula via\n * `overrideCreditCost` (strategic subsidy / partner pricing) — used\n * sparingly so a category-wide tune stays a one-line change in\n * `pricing/index.ts`.\n *\n * `costPerImage` / `costTier` / `creditCost` are deprecated but kept\n * readable so production data + admin UI keep parsing. New entries\n * should not set them.\n */\nexport const ImagePricingSchema = z.object({\n costPerImage: z.number().nonnegative().optional(),\n costTier: z.enum([\"low\", \"medium\", \"high\"]).optional(),\n billingUnit: z.literal(\"per_image\"),\n baseCost: z.number().nonnegative(),\n /** @deprecated Derived at call time. Kept for back-compat. */\n creditCost: z.number().nonnegative().optional(),\n /**\n * Strategic per-model override. When set, bypasses the formula and\n * the user is charged this many credits per output regardless of\n * provider cost or category markup.\n */\n overrideCreditCost: z.number().nonnegative().optional(),\n})\nexport type ImagePricing = z.infer<typeof ImagePricingSchema>\n\nexport const ImageEntrySchema = z.object({\n ...baseEntryShape,\n kind: z.literal(\"image\"),\n capabilities: ImageCapabilitiesSchema,\n referenceImages: ImageReferenceImagesSchema,\n aspectRatio: ImageAspectRatioSchema,\n output: z.enum([\"string\", \"array\"]),\n pricing: ImagePricingSchema,\n triggerWord: z.string().optional(),\n})\nexport type ImageEntry = z.infer<typeof ImageEntrySchema>\n","import { z } from \"zod\"\nimport { baseEntryShape } from \"./base.js\"\n\nexport const VideoCapabilitiesSchema = z.object({\n textToVideo: z.boolean(),\n imageToVideo: z.boolean(),\n subjectReference: z.boolean(),\n audio: z.boolean(),\n})\nexport type VideoCapabilities = z.infer<typeof VideoCapabilitiesSchema>\n\nexport const VideoResolutionSchema = z.enum([\n \"480p\",\n \"540p\",\n \"720p\",\n \"1080p\",\n \"1440p\",\n \"4k\",\n])\nexport type VideoResolution = z.infer<typeof VideoResolutionSchema>\n\n/**\n * Mirrors `CostMultipliers` from `the app integration-core`. Keys are\n * stringified so JSON round-trips cleanly.\n */\nexport const VideoCostMultipliersSchema = z.object({\n resolution: z.record(z.string(), z.number().positive()).optional(),\n duration: z.record(z.string(), z.number().positive()).optional(),\n mode: z.record(z.string(), z.number().positive()).optional(),\n})\nexport type VideoCostMultipliers = z.infer<typeof VideoCostMultipliersSchema>\n\nexport const VideoPricingSchema = z.object({\n costPerClip: z.number().nonnegative().optional(),\n costTier: z.enum([\"low\", \"medium\", \"high\"]).optional(),\n billingUnit: z.enum([\"per_clip\", \"per_second\"]),\n baseCost: z.number().nonnegative(),\n baseCostUnit: z.string(),\n /** Provider-cost multipliers (resolution / duration / mode). */\n multipliers: VideoCostMultipliersSchema.optional(),\n /** @deprecated Derived at call time. */\n creditCost: z.number().nonnegative().optional(),\n /**\n * @deprecated Use `multipliers` (provider-side) + per-category markup\n * in `pricing-registry`. The credit multipliers used to be a parallel\n * structure; now the formula re-applies `multipliers` to the derived\n * credit count automatically.\n */\n creditMultipliers: VideoCostMultipliersSchema.optional(),\n /** Strategic per-model override — bypasses the formula. */\n overrideCreditCost: z.number().nonnegative().optional(),\n})\nexport type VideoPricing = z.infer<typeof VideoPricingSchema>\n\nexport const VideoEntrySchema = z.object({\n ...baseEntryShape,\n kind: z.literal(\"video\"),\n capabilities: VideoCapabilitiesSchema,\n maxDuration: z.number().positive(),\n supportedResolutions: z.array(VideoResolutionSchema).min(1),\n supportedAspectRatios: z.array(z.string()).min(1),\n pricing: VideoPricingSchema,\n})\nexport type VideoEntry = z.infer<typeof VideoEntrySchema>\n","import { z } from \"zod\"\nimport { baseEntryShape } from \"./base.js\"\n\n// Single source of truth for audio model capabilities — mirrors (and is\n// re-used by) the runtime `AudioModelDefinition` in `audio/catalog.ts`.\n// Modality is multi-valued boolean flags (`tts`/`stt`/`s2s`) — a model may\n// do more than one; `s2s` is a speech↔speech engine (distinct from a\n// tts+llm+stt cascade). Transport (`streaming`) is a SEPARATE axis.\nexport const AudioCapabilitiesSchema = z.object({\n tts: z.boolean().optional(),\n stt: z.boolean().optional(),\n s2s: z.boolean().optional(),\n languages: z.array(z.string()),\n voiceCloning: z.boolean().optional(),\n streaming: z.boolean().optional(),\n timestamps: z.boolean().optional(),\n diarization: z.boolean().optional(),\n languageDetection: z.boolean().optional(),\n})\nexport type AudioCapabilities = z.infer<typeof AudioCapabilitiesSchema>\n\nexport const AudioPricingSchema = z.object({\n billingUnit: z.enum([\"per_character\", \"per_second\"]),\n baseCost: z.number().nonnegative(),\n baseCostUnit: z.string().optional(),\n /** @deprecated Derived at call time from `baseCost × category-markup`. */\n creditCost: z.number().nonnegative().optional(),\n /** Strategic per-model override — bypasses the formula. */\n overrideCreditCost: z.number().nonnegative().optional(),\n})\nexport type AudioPricing = z.infer<typeof AudioPricingSchema>\n\n// Voices are NOT per-model metadata — they live in the shared, provider-\n// neutral voice catalog (an app voice-catalog module,\n// `CatalogVoice`), referenced by id. The old per-entry `voice` placeholder\n// (+ its `VoiceMetadataSchema`) was never populated — removed.\nexport const AudioEntrySchema = z.object({\n ...baseEntryShape,\n kind: z.literal(\"audio\"),\n capabilities: AudioCapabilitiesSchema,\n pricing: AudioPricingSchema,\n supportedLocales: z.array(z.string()).optional(),\n})\nexport type AudioEntry = z.infer<typeof AudioEntrySchema>\n","import { z } from \"zod\"\nimport { LLMEntrySchema } from \"./llm.js\"\nimport { ImageEntrySchema } from \"./image.js\"\nimport { VideoEntrySchema } from \"./video.js\"\nimport { AudioEntrySchema } from \"./audio.js\"\n\nexport * from \"./base.js\"\nexport * from \"./llm.js\"\nexport * from \"./image.js\"\nexport * from \"./video.js\"\nexport * from \"./audio.js\"\nexport * from \"./voice.js\"\n\n/** Discriminated union over every kind. */\nexport const ModelEntrySchema = z.discriminatedUnion(\"kind\", [\n LLMEntrySchema,\n ImageEntrySchema,\n VideoEntrySchema,\n AudioEntrySchema,\n])\nexport type ModelEntry = z.infer<typeof ModelEntrySchema>\n"]}
@@ -1,7 +1,7 @@
1
- import { listRouterLlmRoutes, formatModelRef } from './chunk-GEXPCKCK.mjs';
2
- import { modelHasTag } from './chunk-W7HLNKXV.mjs';
1
+ import { listRouterLlmRoutes, formatModelRef } from './chunk-AVCHKXUD.mjs';
2
+ import { modelHasTag } from './chunk-AJLMLBEZ.mjs';
3
3
  import { getMergedOverlay } from './chunk-H6JUTF3U.mjs';
4
- import { resolvePricing, resolveAlias, isKnownLlmId, getModelProvider, LLM_PRICING_CATALOG, listUnpricedKnownLlmIds } from './chunk-CBP4SNOX.mjs';
4
+ import { resolvePricing, resolveAlias, isKnownLlmId, getModelProvider, LLM_PRICING_CATALOG, listUnpricedKnownLlmIds } from './chunk-OH37WKVA.mjs';
5
5
  import { IMAGE_MODEL_CATALOG } from './chunk-2LWYZOWB.mjs';
6
6
  import { VIDEO_MODEL_CATALOG } from './chunk-IJZ4XPO2.mjs';
7
7
  import { AUDIO_MODEL_CATALOG } from './chunk-WRUWNKDB.mjs';
@@ -202,5 +202,5 @@ function resolveAlias2(id) {
202
202
  }
203
203
 
204
204
  export { getModel, getModelsByProvider, getStaticModelProvider, isAgentVisible, listModels, resolveAlias2 as resolveAlias };
205
- //# sourceMappingURL=chunk-BR4ZEPA7.mjs.map
206
- //# sourceMappingURL=chunk-BR4ZEPA7.mjs.map
205
+ //# sourceMappingURL=chunk-4ROXWVQD.mjs.map
206
+ //# sourceMappingURL=chunk-4ROXWVQD.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/registry/index.ts"],"names":["resolveAlias"],"mappings":"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","file":"chunk-BR4ZEPA7.mjs","sourcesContent":["/**\n * Cross-kind registry. Resolves a model id against every catalog (LLM,\n * image, video, audio) and returns a discriminated `ResolvedModel`.\n *\n * v1 returns the legacy per-kind data shapes verbatim — image/video keep\n * `*ModelDefinition`, LLM keeps `LLMPricing`, audio surfaces voices.\n * Callers (cost dispatcher, access evaluator) match on `.kind` and dig\n * into the per-kind payload as needed.\n */\n\nimport {\n LLM_PRICING_CATALOG,\n resolveAlias as resolveLlmAlias,\n resolvePricing,\n isKnownLlmId,\n listUnpricedKnownLlmIds,\n getModelProvider,\n type LLMPricing,\n} from \"../llm/index.js\"\nimport {\n IMAGE_MODEL_CATALOG,\n type ImageModelDefinition,\n} from \"../image/index.js\"\nimport {\n VIDEO_MODEL_CATALOG,\n type VideoModelDefinition,\n} from \"../video/index.js\"\nimport {\n AUDIO_MODEL_CATALOG,\n type AudioModelDefinition,\n} from \"../audio/index.js\"\nimport { VOICE_CATALOG, type CatalogVoice } from \"../voice/index.js\"\nimport { modelHasTag } from \"../enrichment/index.js\"\nimport { getMergedOverlay, type MergedOverlay } from \"../overlay/index.js\"\nimport { listRouterLlmRoutes, formatModelRef } from \"../route-identity/index.js\"\n\n/** Follow consumer-overlay alias hops to a concrete id (cycle-guarded).\n * Ids with no overlay alias pass through unchanged. */\nfunction followAlias(id: string, ov: MergedOverlay): string {\n let cur = id\n const seen = new Set<string>()\n for (;;) {\n const next = ov.aliases[cur]\n if (next === undefined || seen.has(cur)) break\n seen.add(cur)\n cur = next\n }\n return cur\n}\n\n/** Find an overlay voice by catalogId / providerVoiceId / alias. */\nfunction overlayVoice(ov: MergedOverlay, key: string): CatalogVoice | undefined {\n return ov.voice.find(\n v =>\n v.catalogId === key ||\n v.providerVoiceId === key ||\n (v.aliases ?? []).includes(key),\n )\n}\n\n/**\n * `audio` resolves to either an audio MODEL (priced TTS/STT) or a\n * voice (downstream metadata). Most call sites care about the model\n * (pricing, capabilities); a few (voice pickers) want the voice. They\n * share the resolver but discriminate on the inner payload.\n */\nexport type ResolvedModel =\n | {\n kind: \"llm\"\n id: string\n canonicalId: string\n /** Undefined for a real, known id with no pricing row yet — existence\n * and pricing are independent, see `LlmModelId`'s doc comment in\n * `llm/catalog.ts`. Every reader MUST handle the absent case; never\n * assume a `kind: \"llm\"` result is priced. */\n pricing: LLMPricing | undefined\n /** Best-effort provider even when `pricing` is absent (falls back to\n * `CONTEXT_WINDOWS`'s own provider field — see `getModelProvider`).\n * Prefer this over `pricing?.provider` when you only need routing. */\n provider: string | undefined\n }\n | { kind: \"image\"; id: string; def: ImageModelDefinition }\n | { kind: \"video\"; id: string; def: VideoModelDefinition }\n | { kind: \"audio\"; id: string; def: AudioModelDefinition }\n | { kind: \"voice\"; id: string; voice: CatalogVoice }\n\n/**\n * Every kind the registry can resolve. Broader than the catalog\n * `ModelKind` (llm/image/video/audio) because voices are a first-class\n * registry kind but not a priced model family. Derived from\n * `ResolvedModel` so it can never drift.\n */\nexport type CatalogKind = ResolvedModel[\"kind\"]\n\n// Voices resolve by canonical id (\"minimax-french-female-anchor\"), native\n// provider id (\"French_FemaleAnchor\"), or a consumer-overlay alias — index\n// all three so new slugs, native ids, and persisted operator rows all hit.\nconst VOICE_INDEX: Map<string, CatalogVoice> = new Map([\n ...VOICE_CATALOG.map(v => [v.providerVoiceId, v] as const),\n ...VOICE_CATALOG.map(v => [v.catalogId, v] as const),\n ...VOICE_CATALOG.flatMap((v: CatalogVoice) =>\n (v.aliases ?? []).map(a => [a, v] as const)\n ),\n])\n\n/**\n * Resolves a model id across every catalog.\n *\n * Lookup order: image → video → audio → LLM (last because LLM has the\n * partial-prefix fallback that can match other strings if probed first).\n *\n * Returns `undefined` for unknown ids — callers decide whether to throw\n * or fall back. LLM uses fallback pricing inside its own dispatcher\n * (preserves existing behavior at the orchestrator).\n */\nexport function getModel(id: string): ResolvedModel | undefined {\n // Consumer overlays first: resolve any overlay alias to a concrete id,\n // then let overlay entries override/extend the generated catalogs. The\n // returned `id` echoes what the caller asked for (alias-preserving), as\n // the legacy voice-alias path already did.\n const ov = getMergedOverlay()\n const key = followAlias(id, ov)\n\n if (ov.image[key]) return { kind: \"image\", id, def: ov.image[key]! }\n if (ov.video[key]) return { kind: \"video\", id, def: ov.video[key]! }\n if (ov.audio[key]) return { kind: \"audio\", id, def: ov.audio[key]! }\n const ovVoice = overlayVoice(ov, key)\n if (ovVoice) return { kind: \"voice\", id, voice: ovVoice }\n if (ov.llm[key]) {\n const pricing = ov.llm[key]!\n return { kind: \"llm\", id, canonicalId: key, pricing, provider: pricing.provider }\n }\n\n const imageDef = IMAGE_MODEL_CATALOG[key]\n if (imageDef) return { kind: \"image\", id, def: imageDef }\n\n const videoDef = VIDEO_MODEL_CATALOG[key]\n if (videoDef) return { kind: \"video\", id, def: videoDef }\n\n // Audio MODEL (priced TTS/STT) — checked before voice lookup so an\n // id that exists in both maps lands on the priced entry.\n const audioDef = AUDIO_MODEL_CATALOG[key]\n if (audioDef) return { kind: \"audio\", id, def: audioDef }\n\n const voice = VOICE_INDEX.get(key)\n if (voice) return { kind: \"voice\", id, voice }\n\n const llmPricing = resolvePricing(key)\n if (llmPricing) {\n const canonicalId = resolveLlmAlias(key)\n return { kind: \"llm\", id, canonicalId, pricing: llmPricing, provider: llmPricing.provider }\n }\n // Known id, no pricing row yet (see `LlmModelId`'s doc comment in\n // llm/catalog.ts) — still resolves, just unpriced. This is the case that\n // used to make a real, live, provider-published model (e.g. a brand-new\n // Anthropic release the day it ships, before the next pricing sync)\n // disappear from every downstream surface instead of showing up unpriced.\n if (isKnownLlmId(key)) {\n return { kind: \"llm\", id, canonicalId: key, pricing: undefined, provider: getModelProvider(key) }\n }\n\n return undefined\n}\n\n/**\n * Returns true iff the id is exposed to agents.\n *\n * - LLM: every entry in `LLM_PRICING_CATALOG` is considered visible\n * (legacy convention; refine in v2 with per-entry `agentVisible`).\n * - Image / Video: respects the `agentVisible` flag.\n * - Audio voices: all voices are visible (catalog itself is curated).\n */\nexport function isAgentVisible(id: string): boolean {\n const m = getModel(id)\n if (!m) return false\n switch (m.kind) {\n case \"image\":\n return m.def.agentVisible\n case \"video\":\n return m.def.agentVisible\n case \"audio\":\n return m.def.agentVisible\n case \"llm\":\n return (\n id in LLM_PRICING_CATALOG || resolveLlmAlias(id) in LLM_PRICING_CATALOG\n )\n case \"voice\":\n return true\n }\n}\n\nexport interface ListModelsFilter {\n kind?: CatalogKind\n /** Single provider (back-compat). Folded into `providers` internally. */\n provider?: string\n /** Provider OR-set — a model matches if its provider is any of these. */\n providers?: string[]\n /**\n * Capability tags a model must carry (ALL of them). Capabilities are\n * emitted as tags by enrichment — audio `tts`/`stt`/`s2s`, image\n * `edit`/`upscale`, video `i2v`/`t2v` — so this filters on the same\n * vocabulary `listModels({capabilities:[\"s2s\"]})` would expect.\n */\n capabilities?: string[]\n /** Arbitrary tags a model must carry (ALL of them). */\n tags?: string[]\n agentVisibleOnly?: boolean\n}\n\n/**\n * Cross-kind listing. Useful for catalog browsers and capability search.\n * Returns `ResolvedModel[]` (discriminated by kind).\n *\n * Provider is an OR-set (`providers` ∪ the singular `provider`); capability\n * and tag filters are AND-sets (a model must carry every listed value).\n * Composed: `listModels({ kind:\"audio\", capabilities:[\"s2s\"],\n * providers:[\"gemini-live\",\"openai-realtime\"] })` → all s2s models from\n * Gemini OR OpenAI.\n */\nexport function listModels(filter: ListModelsFilter = {}): ResolvedModel[] {\n const providerSet =\n filter.provider || filter.providers\n ? new Set([\n ...(filter.provider ? [filter.provider] : []),\n ...(filter.providers ?? []),\n ])\n : undefined\n const providerMatches = (provider: string | undefined): boolean =>\n !providerSet || (provider !== undefined && providerSet.has(provider))\n\n const ov = getMergedOverlay()\n const out: ResolvedModel[] = []\n // Overlay entries override core ones with the same id, so collect ids the\n // overlay has already supplied per kind and skip the core duplicate.\n const seen = { image: new Set<string>(), video: new Set<string>(), audio: new Set<string>(), voice: new Set<string>(), llm: new Set<string>() }\n\n if (!filter.kind || filter.kind === \"image\") {\n for (const [id, def] of Object.entries(ov.image)) {\n if (!providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n seen.image.add(id)\n out.push({ kind: \"image\", id, def })\n }\n for (const [id, def] of Object.entries(IMAGE_MODEL_CATALOG)) {\n if (seen.image.has(id) || !providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n out.push({ kind: \"image\", id, def })\n }\n }\n if (!filter.kind || filter.kind === \"video\") {\n for (const [id, def] of Object.entries(ov.video)) {\n if (!providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n seen.video.add(id)\n out.push({ kind: \"video\", id, def })\n }\n for (const [id, def] of Object.entries(VIDEO_MODEL_CATALOG)) {\n if (seen.video.has(id) || !providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n out.push({ kind: \"video\", id, def })\n }\n }\n if (!filter.kind || filter.kind === \"audio\") {\n for (const [id, def] of Object.entries(ov.audio)) {\n if (!providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n seen.audio.add(id)\n out.push({ kind: \"audio\", id, def })\n }\n for (const [id, def] of Object.entries(AUDIO_MODEL_CATALOG)) {\n if (seen.audio.has(id) || !providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n out.push({ kind: \"audio\", id, def })\n }\n }\n if (!filter.kind || filter.kind === \"voice\") {\n for (const v of ov.voice) {\n if (!providerMatches(v.provider)) continue\n seen.voice.add(v.catalogId)\n out.push({ kind: \"voice\", id: v.catalogId, voice: v })\n }\n for (const v of VOICE_CATALOG) {\n if (seen.voice.has(v.catalogId) || !providerMatches(v.provider)) continue\n out.push({ kind: \"voice\", id: v.catalogId, voice: v })\n }\n }\n if (!filter.kind || filter.kind === \"llm\") {\n for (const [id, pricing] of Object.entries(ov.llm)) {\n if (!providerMatches(pricing.provider)) continue\n seen.llm.add(id)\n out.push({ kind: \"llm\", id, canonicalId: id, pricing, provider: pricing.provider })\n }\n for (const [id, pricing] of Object.entries(LLM_PRICING_CATALOG)) {\n if (seen.llm.has(id) || !providerMatches(pricing.provider)) continue\n seen.llm.add(id)\n out.push({ kind: \"llm\", id, canonicalId: id, pricing, provider: pricing.provider })\n }\n // Known ids with no pricing row yet (see `LlmModelId`'s doc comment in\n // llm/catalog.ts) — surfaced unpriced rather than silently dropped.\n for (const { id, provider } of listUnpricedKnownLlmIds()) {\n if (seen.llm.has(id) || !providerMatches(provider)) continue\n out.push({ kind: \"llm\", id, canonicalId: id, pricing: undefined, provider })\n }\n }\n\n // Capability + tag filters are AND-sets, applied over the enrichment tag\n // vocabulary (capabilities are emitted as tags). Skipped entirely when\n // unset so the common path stays allocation-free.\n const required = [...(filter.capabilities ?? []), ...(filter.tags ?? [])]\n if (required.length === 0) return out\n return out.filter(model => required.every(tag => modelHasTag(model, tag)))\n}\n\n/**\n * Provider-centric view — every model a provider offers across all kinds\n * (llm / image / video / audio incl. tts/stt/s2s). This is the \"provider\n * catalog\" (openai, google, anthropic, replicate, openrouter, …): a\n * derived query over the kind-organized catalogs, NOT a parallel store.\n *\n * When `provider` names a router (openrouter, requesty, huggingface),\n * this also folds in that router's generated route table\n * (`listRouterLlmRoutes`), emitting `vendor/product@router` ids — the\n * router's full surface, not just what happens to be curated into\n * `LLM_PRICING_CATALOG`. OpenRouter's routes are already spread into that\n * catalog (bare `vendor/product` ids, `llm/catalog.ts`), so its router-table\n * entries are deduped against the bare ids `listModels` already returned;\n * Requesty and HuggingFace have no such overlap today, so their route table\n * entries are added in full. Deliberately NOT achieved by spreading\n * `REQUESTY_ROUTES`/`HUGGINGFACE_ROUTES` into `LLM_PRICING_CATALOG` itself —\n * that catalog is the legacy bare-id path, and a bare id must keep meaning\n * direct-vendor pricing (`route-identity/index.ts`).\n */\nexport function getModelsByProvider(provider: string): ResolvedModel[] {\n const models = listModels({ provider })\n const routerRoutes = listRouterLlmRoutes(provider)\n if (routerRoutes.length === 0) return models\n\n const existingIds = new Set(models.map(m => m.id))\n const routed: ResolvedModel[] = []\n for (const route of routerRoutes) {\n const bareId = `${route.vendor}/${route.product}`\n if (existingIds.has(bareId)) continue\n const id = formatModelRef(route.ref)\n routed.push({ kind: \"llm\", id, canonicalId: id, pricing: route.pricing, provider: route.pricing.provider })\n }\n return [...models, ...routed]\n}\n\n/**\n * Returns the platform a model's adapter is **statically pinned** to,\n * if known. ONLY meaningful for image / video / audio — those adapters\n * are constructed per-platform (Replicate adapter, MiniMax adapter…),\n * so the model's `def.provider` IS the runtime connector.\n *\n * For LLM, returns `undefined` — the runtime connector is determined\n * at call time by `pickLlmConnector(connectors, parseModelId(id).provider)`\n * against the guild's installed connectors, NOT by the model id alone.\n * The same `anthropic/claude-sonnet-4-5` can route through OpenRouter\n * OR direct Anthropic depending on which connectors the guild has\n * installed. Recording call sites MUST pass the actual `connectorUsed`\n * they invoked; do not infer from id.\n *\n * Use case: image/video workflow steps fetch `model.def.provider`\n * directly (no ambiguity). LLM call sites use the runtime resolver.\n */\nexport function getStaticModelProvider(\n model: ResolvedModel\n): string | undefined {\n switch (model.kind) {\n case \"image\":\n case \"video\":\n case \"audio\":\n return model.def.provider\n case \"voice\":\n return model.voice.provider\n case \"llm\":\n // Runtime routing — caller knows, we don't.\n return undefined\n }\n}\n\n/**\n * Resolves an id to its canonical catalog key across kinds. For ids that\n * have no alias, returns the id unchanged. Used by callers that want to\n * normalize before persisting (e.g., `byok_usage` rows).\n */\nexport function resolveAlias(id: string): string {\n const ov = getMergedOverlay()\n const key = followAlias(id, ov)\n if (ov.image[key] || ov.video[key] || ov.audio[key]) return key\n if (overlayVoice(ov, key)) return key\n if (ov.llm[key]) return key\n if (IMAGE_MODEL_CATALOG[key]) return key\n if (VIDEO_MODEL_CATALOG[key]) return key\n if (AUDIO_MODEL_CATALOG[key]) return key\n if (VOICE_INDEX.has(key)) return key\n return resolveLlmAlias(key)\n}\n"]}
1
+ {"version":3,"sources":["../src/registry/index.ts"],"names":["resolveAlias"],"mappings":"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","file":"chunk-4ROXWVQD.mjs","sourcesContent":["/**\n * Cross-kind registry. Resolves a model id against every catalog (LLM,\n * image, video, audio) and returns a discriminated `ResolvedModel`.\n *\n * v1 returns the legacy per-kind data shapes verbatim — image/video keep\n * `*ModelDefinition`, LLM keeps `LLMPricing`, audio surfaces voices.\n * Callers (cost dispatcher, access evaluator) match on `.kind` and dig\n * into the per-kind payload as needed.\n */\n\nimport {\n LLM_PRICING_CATALOG,\n resolveAlias as resolveLlmAlias,\n resolvePricing,\n isKnownLlmId,\n listUnpricedKnownLlmIds,\n getModelProvider,\n type LLMPricing,\n} from \"../llm/index.js\"\nimport {\n IMAGE_MODEL_CATALOG,\n type ImageModelDefinition,\n} from \"../image/index.js\"\nimport {\n VIDEO_MODEL_CATALOG,\n type VideoModelDefinition,\n} from \"../video/index.js\"\nimport {\n AUDIO_MODEL_CATALOG,\n type AudioModelDefinition,\n} from \"../audio/index.js\"\nimport { VOICE_CATALOG, type CatalogVoice } from \"../voice/index.js\"\nimport { modelHasTag } from \"../enrichment/index.js\"\nimport { getMergedOverlay, type MergedOverlay } from \"../overlay/index.js\"\nimport { listRouterLlmRoutes, formatModelRef } from \"../route-identity/index.js\"\n\n/** Follow consumer-overlay alias hops to a concrete id (cycle-guarded).\n * Ids with no overlay alias pass through unchanged. */\nfunction followAlias(id: string, ov: MergedOverlay): string {\n let cur = id\n const seen = new Set<string>()\n for (;;) {\n const next = ov.aliases[cur]\n if (next === undefined || seen.has(cur)) break\n seen.add(cur)\n cur = next\n }\n return cur\n}\n\n/** Find an overlay voice by catalogId / providerVoiceId / alias. */\nfunction overlayVoice(ov: MergedOverlay, key: string): CatalogVoice | undefined {\n return ov.voice.find(\n v =>\n v.catalogId === key ||\n v.providerVoiceId === key ||\n (v.aliases ?? []).includes(key),\n )\n}\n\n/**\n * `audio` resolves to either an audio MODEL (priced TTS/STT) or a\n * voice (downstream metadata). Most call sites care about the model\n * (pricing, capabilities); a few (voice pickers) want the voice. They\n * share the resolver but discriminate on the inner payload.\n */\nexport type ResolvedModel =\n | {\n kind: \"llm\"\n id: string\n canonicalId: string\n /** Undefined for a real, known id with no pricing row yet — existence\n * and pricing are independent, see `LlmModelId`'s doc comment in\n * `llm/catalog.ts`. Every reader MUST handle the absent case; never\n * assume a `kind: \"llm\"` result is priced. */\n pricing: LLMPricing | undefined\n /** Best-effort provider even when `pricing` is absent (falls back to\n * `CONTEXT_WINDOWS`'s own provider field — see `getModelProvider`).\n * Prefer this over `pricing?.provider` when you only need routing. */\n provider: string | undefined\n }\n | { kind: \"image\"; id: string; def: ImageModelDefinition }\n | { kind: \"video\"; id: string; def: VideoModelDefinition }\n | { kind: \"audio\"; id: string; def: AudioModelDefinition }\n | { kind: \"voice\"; id: string; voice: CatalogVoice }\n\n/**\n * Every kind the registry can resolve. Broader than the catalog\n * `ModelKind` (llm/image/video/audio) because voices are a first-class\n * registry kind but not a priced model family. Derived from\n * `ResolvedModel` so it can never drift.\n */\nexport type CatalogKind = ResolvedModel[\"kind\"]\n\n// Voices resolve by canonical id (\"minimax-french-female-anchor\"), native\n// provider id (\"French_FemaleAnchor\"), or a consumer-overlay alias — index\n// all three so new slugs, native ids, and persisted operator rows all hit.\nconst VOICE_INDEX: Map<string, CatalogVoice> = new Map([\n ...VOICE_CATALOG.map(v => [v.providerVoiceId, v] as const),\n ...VOICE_CATALOG.map(v => [v.catalogId, v] as const),\n ...VOICE_CATALOG.flatMap((v: CatalogVoice) =>\n (v.aliases ?? []).map(a => [a, v] as const)\n ),\n])\n\n/**\n * Resolves a model id across every catalog.\n *\n * Lookup order: image → video → audio → LLM (last because LLM has the\n * partial-prefix fallback that can match other strings if probed first).\n *\n * Returns `undefined` for unknown ids — callers decide whether to throw\n * or fall back. LLM uses fallback pricing inside its own dispatcher\n * (preserves existing behavior at the orchestrator).\n */\nexport function getModel(id: string): ResolvedModel | undefined {\n // Consumer overlays first: resolve any overlay alias to a concrete id,\n // then let overlay entries override/extend the generated catalogs. The\n // returned `id` echoes what the caller asked for (alias-preserving), as\n // the legacy voice-alias path already did.\n const ov = getMergedOverlay()\n const key = followAlias(id, ov)\n\n if (ov.image[key]) return { kind: \"image\", id, def: ov.image[key]! }\n if (ov.video[key]) return { kind: \"video\", id, def: ov.video[key]! }\n if (ov.audio[key]) return { kind: \"audio\", id, def: ov.audio[key]! }\n const ovVoice = overlayVoice(ov, key)\n if (ovVoice) return { kind: \"voice\", id, voice: ovVoice }\n if (ov.llm[key]) {\n const pricing = ov.llm[key]!\n return { kind: \"llm\", id, canonicalId: key, pricing, provider: pricing.provider }\n }\n\n const imageDef = IMAGE_MODEL_CATALOG[key]\n if (imageDef) return { kind: \"image\", id, def: imageDef }\n\n const videoDef = VIDEO_MODEL_CATALOG[key]\n if (videoDef) return { kind: \"video\", id, def: videoDef }\n\n // Audio MODEL (priced TTS/STT) — checked before voice lookup so an\n // id that exists in both maps lands on the priced entry.\n const audioDef = AUDIO_MODEL_CATALOG[key]\n if (audioDef) return { kind: \"audio\", id, def: audioDef }\n\n const voice = VOICE_INDEX.get(key)\n if (voice) return { kind: \"voice\", id, voice }\n\n const llmPricing = resolvePricing(key)\n if (llmPricing) {\n const canonicalId = resolveLlmAlias(key)\n return { kind: \"llm\", id, canonicalId, pricing: llmPricing, provider: llmPricing.provider }\n }\n // Known id, no pricing row yet (see `LlmModelId`'s doc comment in\n // llm/catalog.ts) — still resolves, just unpriced. This is the case that\n // used to make a real, live, provider-published model (e.g. a brand-new\n // Anthropic release the day it ships, before the next pricing sync)\n // disappear from every downstream surface instead of showing up unpriced.\n if (isKnownLlmId(key)) {\n return { kind: \"llm\", id, canonicalId: key, pricing: undefined, provider: getModelProvider(key) }\n }\n\n return undefined\n}\n\n/**\n * Returns true iff the id is exposed to agents.\n *\n * - LLM: every entry in `LLM_PRICING_CATALOG` is considered visible\n * (legacy convention; refine in v2 with per-entry `agentVisible`).\n * - Image / Video: respects the `agentVisible` flag.\n * - Audio voices: all voices are visible (catalog itself is curated).\n */\nexport function isAgentVisible(id: string): boolean {\n const m = getModel(id)\n if (!m) return false\n switch (m.kind) {\n case \"image\":\n return m.def.agentVisible\n case \"video\":\n return m.def.agentVisible\n case \"audio\":\n return m.def.agentVisible\n case \"llm\":\n return (\n id in LLM_PRICING_CATALOG || resolveLlmAlias(id) in LLM_PRICING_CATALOG\n )\n case \"voice\":\n return true\n }\n}\n\nexport interface ListModelsFilter {\n kind?: CatalogKind\n /** Single provider (back-compat). Folded into `providers` internally. */\n provider?: string\n /** Provider OR-set — a model matches if its provider is any of these. */\n providers?: string[]\n /**\n * Capability tags a model must carry (ALL of them). Capabilities are\n * emitted as tags by enrichment — audio `tts`/`stt`/`s2s`, image\n * `edit`/`upscale`, video `i2v`/`t2v` — so this filters on the same\n * vocabulary `listModels({capabilities:[\"s2s\"]})` would expect.\n */\n capabilities?: string[]\n /** Arbitrary tags a model must carry (ALL of them). */\n tags?: string[]\n agentVisibleOnly?: boolean\n}\n\n/**\n * Cross-kind listing. Useful for catalog browsers and capability search.\n * Returns `ResolvedModel[]` (discriminated by kind).\n *\n * Provider is an OR-set (`providers` ∪ the singular `provider`); capability\n * and tag filters are AND-sets (a model must carry every listed value).\n * Composed: `listModels({ kind:\"audio\", capabilities:[\"s2s\"],\n * providers:[\"gemini-live\",\"openai-realtime\"] })` → all s2s models from\n * Gemini OR OpenAI.\n */\nexport function listModels(filter: ListModelsFilter = {}): ResolvedModel[] {\n const providerSet =\n filter.provider || filter.providers\n ? new Set([\n ...(filter.provider ? [filter.provider] : []),\n ...(filter.providers ?? []),\n ])\n : undefined\n const providerMatches = (provider: string | undefined): boolean =>\n !providerSet || (provider !== undefined && providerSet.has(provider))\n\n const ov = getMergedOverlay()\n const out: ResolvedModel[] = []\n // Overlay entries override core ones with the same id, so collect ids the\n // overlay has already supplied per kind and skip the core duplicate.\n const seen = { image: new Set<string>(), video: new Set<string>(), audio: new Set<string>(), voice: new Set<string>(), llm: new Set<string>() }\n\n if (!filter.kind || filter.kind === \"image\") {\n for (const [id, def] of Object.entries(ov.image)) {\n if (!providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n seen.image.add(id)\n out.push({ kind: \"image\", id, def })\n }\n for (const [id, def] of Object.entries(IMAGE_MODEL_CATALOG)) {\n if (seen.image.has(id) || !providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n out.push({ kind: \"image\", id, def })\n }\n }\n if (!filter.kind || filter.kind === \"video\") {\n for (const [id, def] of Object.entries(ov.video)) {\n if (!providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n seen.video.add(id)\n out.push({ kind: \"video\", id, def })\n }\n for (const [id, def] of Object.entries(VIDEO_MODEL_CATALOG)) {\n if (seen.video.has(id) || !providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n out.push({ kind: \"video\", id, def })\n }\n }\n if (!filter.kind || filter.kind === \"audio\") {\n for (const [id, def] of Object.entries(ov.audio)) {\n if (!providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n seen.audio.add(id)\n out.push({ kind: \"audio\", id, def })\n }\n for (const [id, def] of Object.entries(AUDIO_MODEL_CATALOG)) {\n if (seen.audio.has(id) || !providerMatches(def.provider)) continue\n if (filter.agentVisibleOnly && !def.agentVisible) continue\n out.push({ kind: \"audio\", id, def })\n }\n }\n if (!filter.kind || filter.kind === \"voice\") {\n for (const v of ov.voice) {\n if (!providerMatches(v.provider)) continue\n seen.voice.add(v.catalogId)\n out.push({ kind: \"voice\", id: v.catalogId, voice: v })\n }\n for (const v of VOICE_CATALOG) {\n if (seen.voice.has(v.catalogId) || !providerMatches(v.provider)) continue\n out.push({ kind: \"voice\", id: v.catalogId, voice: v })\n }\n }\n if (!filter.kind || filter.kind === \"llm\") {\n for (const [id, pricing] of Object.entries(ov.llm)) {\n if (!providerMatches(pricing.provider)) continue\n seen.llm.add(id)\n out.push({ kind: \"llm\", id, canonicalId: id, pricing, provider: pricing.provider })\n }\n for (const [id, pricing] of Object.entries(LLM_PRICING_CATALOG)) {\n if (seen.llm.has(id) || !providerMatches(pricing.provider)) continue\n seen.llm.add(id)\n out.push({ kind: \"llm\", id, canonicalId: id, pricing, provider: pricing.provider })\n }\n // Known ids with no pricing row yet (see `LlmModelId`'s doc comment in\n // llm/catalog.ts) — surfaced unpriced rather than silently dropped.\n for (const { id, provider } of listUnpricedKnownLlmIds()) {\n if (seen.llm.has(id) || !providerMatches(provider)) continue\n out.push({ kind: \"llm\", id, canonicalId: id, pricing: undefined, provider })\n }\n }\n\n // Capability + tag filters are AND-sets, applied over the enrichment tag\n // vocabulary (capabilities are emitted as tags). Skipped entirely when\n // unset so the common path stays allocation-free.\n const required = [...(filter.capabilities ?? []), ...(filter.tags ?? [])]\n if (required.length === 0) return out\n return out.filter(model => required.every(tag => modelHasTag(model, tag)))\n}\n\n/**\n * Provider-centric view — every model a provider offers across all kinds\n * (llm / image / video / audio incl. tts/stt/s2s). This is the \"provider\n * catalog\" (openai, google, anthropic, replicate, openrouter, …): a\n * derived query over the kind-organized catalogs, NOT a parallel store.\n *\n * When `provider` names a router (openrouter, requesty, huggingface),\n * this also folds in that router's generated route table\n * (`listRouterLlmRoutes`), emitting `vendor/product@router` ids — the\n * router's full surface, not just what happens to be curated into\n * `LLM_PRICING_CATALOG`. OpenRouter's routes are already spread into that\n * catalog (bare `vendor/product` ids, `llm/catalog.ts`), so its router-table\n * entries are deduped against the bare ids `listModels` already returned;\n * Requesty and HuggingFace have no such overlap today, so their route table\n * entries are added in full. Deliberately NOT achieved by spreading\n * `REQUESTY_ROUTES`/`HUGGINGFACE_ROUTES` into `LLM_PRICING_CATALOG` itself —\n * that catalog is the legacy bare-id path, and a bare id must keep meaning\n * direct-vendor pricing (`route-identity/index.ts`).\n */\nexport function getModelsByProvider(provider: string): ResolvedModel[] {\n const models = listModels({ provider })\n const routerRoutes = listRouterLlmRoutes(provider)\n if (routerRoutes.length === 0) return models\n\n const existingIds = new Set(models.map(m => m.id))\n const routed: ResolvedModel[] = []\n for (const route of routerRoutes) {\n const bareId = `${route.vendor}/${route.product}`\n if (existingIds.has(bareId)) continue\n const id = formatModelRef(route.ref)\n routed.push({ kind: \"llm\", id, canonicalId: id, pricing: route.pricing, provider: route.pricing.provider })\n }\n return [...models, ...routed]\n}\n\n/**\n * Returns the platform a model's adapter is **statically pinned** to,\n * if known. ONLY meaningful for image / video / audio — those adapters\n * are constructed per-platform (Replicate adapter, MiniMax adapter…),\n * so the model's `def.provider` IS the runtime connector.\n *\n * For LLM, returns `undefined` — the runtime connector is determined\n * at call time by `pickLlmConnector(connectors, parseModelId(id).provider)`\n * against the guild's installed connectors, NOT by the model id alone.\n * The same `anthropic/claude-sonnet-4-5` can route through OpenRouter\n * OR direct Anthropic depending on which connectors the guild has\n * installed. Recording call sites MUST pass the actual `connectorUsed`\n * they invoked; do not infer from id.\n *\n * Use case: image/video workflow steps fetch `model.def.provider`\n * directly (no ambiguity). LLM call sites use the runtime resolver.\n */\nexport function getStaticModelProvider(\n model: ResolvedModel\n): string | undefined {\n switch (model.kind) {\n case \"image\":\n case \"video\":\n case \"audio\":\n return model.def.provider\n case \"voice\":\n return model.voice.provider\n case \"llm\":\n // Runtime routing — caller knows, we don't.\n return undefined\n }\n}\n\n/**\n * Resolves an id to its canonical catalog key across kinds. For ids that\n * have no alias, returns the id unchanged. Used by callers that want to\n * normalize before persisting (e.g., `byok_usage` rows).\n */\nexport function resolveAlias(id: string): string {\n const ov = getMergedOverlay()\n const key = followAlias(id, ov)\n if (ov.image[key] || ov.video[key] || ov.audio[key]) return key\n if (overlayVoice(ov, key)) return key\n if (ov.llm[key]) return key\n if (IMAGE_MODEL_CATALOG[key]) return key\n if (VIDEO_MODEL_CATALOG[key]) return key\n if (AUDIO_MODEL_CATALOG[key]) return key\n if (VOICE_INDEX.has(key)) return key\n return resolveLlmAlias(key)\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { DEFAULT_PRICING } from './chunk-CBP4SNOX.mjs';
1
+ import { DEFAULT_PRICING } from './chunk-OH37WKVA.mjs';
2
2
 
3
3
  /**
4
4
  * @agentproto/model-catalog v0.1.0
@@ -364,5 +364,5 @@ function modelMatchesKind(model, kind) {
364
364
  }
365
365
 
366
366
  export { assertReservedPrefixDiscipline, getActions, getEnrichment, isActionTag, modelHasAction, modelHasTag, modelMatchesCatalogPriceTier, modelMatchesKind, modelMatchesPriceTier, priceTierForModel };
367
- //# sourceMappingURL=chunk-W7HLNKXV.mjs.map
368
- //# sourceMappingURL=chunk-W7HLNKXV.mjs.map
367
+ //# sourceMappingURL=chunk-AJLMLBEZ.mjs.map
368
+ //# sourceMappingURL=chunk-AJLMLBEZ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/registry/actions.ts","../src/enrichment/index.ts"],"names":[],"mappings":"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","file":"chunk-W7HLNKXV.mjs","sourcesContent":["/**\n * Action projection — `<kind>:<verb>` namespaced strings derived from\n * each model's per-kind capability object.\n *\n * Convention:\n * - `image:generate`, `image:edit`, `image:upscale`, `image:reference`\n * - `video:text_to`, `video:image_to`, `video:subject_reference`,\n * `video:audio`\n * - `audio:tts`, `audio:stt`, `audio:realtime`\n * - `llm:vision`, `llm:tool_use`, `llm:reasoning`, `llm:long_context`\n *\n * Always `<kind>:<verb_or_modifier>`, snake_case.\n *\n * Action tags share a string array with curation tags but live behind the\n * reserved `<kind>:` prefix. Curation tags MUST NOT use the prefix —\n * `assertReservedPrefixDiscipline` enforces this at module load.\n *\n * The reason this lives in the catalog package (not enrichment) is that\n * actions are intrinsic to a model — derived from its capability fields,\n * not subjectively curated. Keeping the projection separate makes it\n * trivially callable from anywhere (e.g. a UI badge component) without\n * pulling the heuristic enrichment table.\n */\n\nimport type { ResolvedModel } from \"./index.js\"\n\nconst RESERVED_KIND_PREFIXES = [\"llm:\", \"image:\", \"video:\", \"audio:\"] as const\n\n/**\n * Compute the action tags a model supports. Returns an empty array for\n * models with no recognized capability bits (defensive — never throws).\n */\nexport function getActions(model: ResolvedModel): string[] {\n switch (model.kind) {\n case \"image\": {\n const out: string[] = []\n const c = model.def.capabilities\n if (c.generate) out.push(\"image:generate\")\n if (c.edit) out.push(\"image:edit\")\n if (c.upscale) out.push(\"image:upscale\")\n if (model.def.referenceImages.supported) out.push(\"image:reference\")\n return out\n }\n case \"video\": {\n const out: string[] = []\n const c = model.def.capabilities\n if (c.textToVideo) out.push(\"video:text_to\")\n if (c.imageToVideo) out.push(\"video:image_to\")\n if (c.subjectReference) out.push(\"video:subject_reference\")\n if (c.audio) out.push(\"video:audio\")\n return out\n }\n case \"audio\": {\n const out: string[] = []\n const c = model.def.capabilities\n // One action per enabled modality (a model may do more than one).\n if (c.tts) out.push(\"audio:tts\")\n if (c.stt) out.push(\"audio:stt\")\n if (c.s2s) out.push(\"audio:s2s\")\n if (c.voiceCloning) out.push(\"audio:voice_cloning\")\n if (c.streaming) out.push(\"audio:streaming\")\n if (c.diarization) out.push(\"audio:diarization\")\n if (c.timestamps) out.push(\"audio:timestamps\")\n return out\n }\n case \"voice\":\n // Voice metadata represents a render-target, not an action — tag it\n // with the engine modality so it matches the same action vocabulary\n // as audio models (s2s engines vs sequential tts).\n return model.voice.provider === \"openai-realtime\" ||\n model.voice.provider === \"gemini-live\"\n ? [\"audio:s2s\"]\n : [\"audio:tts\"]\n case \"llm\": {\n // LLM actions piggyback on the catalog-attached capability metadata\n // when present. The legacy `LLMPricing` shape doesn't carry\n // capabilities directly — those live in the agent-framework\n // catalog (to be folded into model-catalog/llm in a future phase).\n // For v1, infer from canonical id heuristics. Keep conservative:\n // only emit actions we can prove from the id.\n const out: string[] = []\n const id = model.canonicalId.toLowerCase()\n // Tool use: every modern frontier LLM supports it. Bare `gpt`,\n // `claude`, `gemini` are tool-capable; small fast variants\n // (haiku, mini, flash, lite) are too. We assume yes unless the\n // id obviously rules it out.\n out.push(\"llm:tool_use\")\n // Reasoning: opus / sonnet / pro / r1 / o1 / o3 / thinking models.\n if (\n /opus|sonnet|claude-3.7|gpt-4\\.5|gpt-5|gemini-.*-pro|deepseek-r1|o1|o3|thinking|reasoning/.test(\n id\n )\n ) {\n out.push(\"llm:reasoning\")\n }\n // Vision: Sonnet, Opus, GPT-4o, Gemini, multimodal-marked ids.\n if (\n /sonnet|opus|gpt-4o|gpt-5|gemini|claude-3|claude-haiku-4|vision|vl/.test(\n id\n )\n ) {\n out.push(\"llm:vision\")\n }\n // Long context: Gemini, GPT-4.1, Sonnet 4 (1M), Kimi, Grok 4 fast.\n if (\n /gemini|gpt-4\\.1|claude-sonnet-4|kimi|grok-4|qwen3-next|long.context/.test(\n id\n )\n ) {\n out.push(\"llm:long_context\")\n }\n return out\n }\n }\n}\n\n/**\n * Validate that a string array intended as curation tags does not use a\n * reserved `<kind>:` prefix. Run at module load on the explicit\n * enrichment map; throws on violation so the offending entry is caught\n * before any access decision is made.\n *\n * Caller pattern (in tests / module-load init):\n * for (const e of Object.values(EXPLICIT_ENRICHMENT))\n * assertReservedPrefixDiscipline(e.tags)\n */\nexport function assertReservedPrefixDiscipline(\n curationTags: readonly string[]\n): void {\n for (const tag of curationTags) {\n for (const prefix of RESERVED_KIND_PREFIXES) {\n if (tag.startsWith(prefix)) {\n throw new Error(\n `Reserved tag prefix \"${prefix}\" used in curation tag \"${tag}\". ` +\n `Action tags (\\`<kind>:<verb>\\`) are derived automatically by ` +\n `getActions() — do not put them in curation arrays.`\n )\n }\n }\n }\n}\n\n/**\n * Returns true iff the given tag is in the reserved action-tag namespace.\n * Useful for callers that need to display curation tags only (e.g.\n * an admin UI) without hardcoding the prefix list.\n */\nexport function isActionTag(tag: string): boolean {\n return RESERVED_KIND_PREFIXES.some(p => tag.startsWith(p))\n}\n","/**\n * Model enrichment — `catalogPriceTier` / `tags` / `lifecycle` / `actions`\n * per model id.\n *\n * Bridge between the legacy data shape (`ImageModelDefinition`,\n * `VideoModelDefinition`, `LLMPricing`) and the v2 access-rule\n * primitives that target by tier, tag, and action. Without this, rules\n * like `priceTier:premium` and `tag:nsfw` would never match anything.\n *\n * Two layers:\n * 1. Explicit map for the curated set we know about (overrides win).\n * 2. Heuristic inference for any model not in the explicit map\n * (catalogPriceTier from creditCost / token rates; tags from kind +\n * provider).\n *\n * Actions (`<kind>:<verb>` — e.g. `image:generate`, `llm:tool_use`) are\n * computed from per-kind capability objects via `getActions` and merged\n * into `tags` so existing tag-based access rules match action targets\n * without any evaluator change. The reserved `<kind>:` prefix is enforced\n * by `assertReservedPrefixDiscipline` at module load — free-form curation\n * tags must NOT use it.\n *\n * Add an entry to `EXPLICIT_ENRICHMENT` when you want exact control;\n * skip it when defaults are good enough.\n */\n\nimport type { CatalogPriceTier, Lifecycle, ModelKind } from \"../schema/index.js\"\nimport type { ResolvedModel } from \"../registry/index.js\"\nimport { DEFAULT_PRICING } from \"../llm/index.js\"\nimport {\n getActions,\n assertReservedPrefixDiscipline,\n} from \"../registry/actions.js\"\n\nexport interface ModelEnrichment {\n catalogPriceTier: CatalogPriceTier\n /** Curation tags + action tags (`<kind>:<verb>`) merged. */\n tags: readonly string[]\n lifecycle: Lifecycle\n /** Action tags only — convenience subset of `tags`. */\n actions: readonly string[]\n}\n\n/**\n * Internal shape for the curated explicit-enrichment map. The map carries\n * only the *curation* fields — `tags` here is curation-only (no action\n * tags). `getEnrichment` adds derived `actions` and merges them into\n * `tags` at read time.\n */\ninterface ExplicitEnrichment {\n catalogPriceTier: CatalogPriceTier\n tags: readonly string[]\n lifecycle: Lifecycle\n}\n\nconst EXPLICIT_ENRICHMENT: Record<string, ExplicitEnrichment> = {\n // ── LLM ──────────────────────────────────────────────────────────────\n \"claude-opus-4-5\": {\n catalogPriceTier: \"premium\",\n tags: [\"llm\", \"anthropic\", \"premium\", \"reasoning\"],\n lifecycle: \"stable\",\n },\n \"claude-sonnet-4-5\": {\n catalogPriceTier: \"high\",\n tags: [\"llm\", \"anthropic\"],\n lifecycle: \"stable\",\n },\n \"claude-haiku-4-5\": {\n catalogPriceTier: \"low\",\n tags: [\"llm\", \"anthropic\", \"fast\"],\n lifecycle: \"stable\",\n },\n \"gemini-2.5-flash\": {\n catalogPriceTier: \"low\",\n tags: [\"llm\", \"google\", \"fast\"],\n lifecycle: \"stable\",\n },\n \"gemini-2.5-pro\": {\n catalogPriceTier: \"mid\",\n tags: [\"llm\", \"google\", \"reasoning\"],\n lifecycle: \"stable\",\n },\n \"gpt-4.1\": {\n catalogPriceTier: \"mid\",\n tags: [\"llm\", \"openai\"],\n lifecycle: \"stable\",\n },\n \"gpt-4.1-mini\": {\n catalogPriceTier: \"low\",\n tags: [\"llm\", \"openai\", \"fast\"],\n lifecycle: \"stable\",\n },\n \"gpt-4o\": {\n catalogPriceTier: \"mid\",\n tags: [\"llm\", \"openai\"],\n lifecycle: \"stable\",\n },\n \"gpt-4o-mini\": {\n catalogPriceTier: \"low\",\n tags: [\"llm\", \"openai\", \"fast\"],\n lifecycle: \"stable\",\n },\n\n // ── Image (highlights — others fall through to heuristic) ────────────\n \"nano-banana-pro\": {\n catalogPriceTier: \"high\",\n tags: [\"image\", \"google\", \"high-quality\", \"text-rendering\"],\n lifecycle: \"stable\",\n },\n \"nano-banana-2\": {\n catalogPriceTier: \"mid\",\n tags: [\"image\", \"google\"],\n lifecycle: \"stable\",\n },\n \"nano-banana\": {\n catalogPriceTier: \"low\",\n tags: [\"image\", \"google\", \"fast\"],\n lifecycle: \"stable\",\n },\n \"flux-2-dev\": {\n catalogPriceTier: \"low\",\n tags: [\"image\", \"bfl\", \"flux\"],\n lifecycle: \"stable\",\n },\n \"flux-kontext-pro\": {\n catalogPriceTier: \"low\",\n tags: [\"image\", \"bfl\", \"flux\", \"edit\"],\n lifecycle: \"stable\",\n },\n \"flux-kontext-max\": {\n catalogPriceTier: \"mid\",\n tags: [\"image\", \"bfl\", \"flux\", \"edit\", \"high-quality\"],\n lifecycle: \"stable\",\n },\n \"seedream-4\": {\n catalogPriceTier: \"low\",\n tags: [\"image\", \"bytedance\", \"photorealistic\"],\n lifecycle: \"stable\",\n },\n\n // ── Video (highlights) ──────────────────────────────────────────────\n \"google/veo-3.1\": {\n catalogPriceTier: \"high\",\n tags: [\"video\", \"google\", \"veo\", \"high-quality\", \"audio\"],\n lifecycle: \"stable\",\n },\n \"google/veo-3.1-fast\": {\n catalogPriceTier: \"mid\",\n tags: [\"video\", \"google\", \"veo\", \"fast\", \"audio\"],\n lifecycle: \"stable\",\n },\n \"kwaivgi/kling-v2.5-turbo-pro\": {\n catalogPriceTier: \"low\",\n tags: [\"video\", \"kling\", \"fast\"],\n lifecycle: \"deprecated\",\n },\n}\n\n// Module-load lint: every curation tag in the explicit map must avoid the\n// reserved `<kind>:` prefix. Action tags are derived by `getActions`,\n// never written by hand.\nfor (const entry of Object.values(EXPLICIT_ENRICHMENT)) {\n assertReservedPrefixDiscipline(entry.tags)\n}\n\n/**\n * Heuristic catalogPriceTier — used when an entry has no explicit\n * enrichment. Buckets are intentionally generous so rules don't need\n * every model priced exactly.\n */\nfunction inferCatalogPriceTier(model: ResolvedModel): CatalogPriceTier {\n switch (model.kind) {\n case \"image\": {\n // Derive from baseCost (USD) — formula bucketing keeps tiers\n // stable when category markup changes.\n const usd = model.def.pricing.baseCost\n if (usd <= 0.02) return \"low\"\n if (usd <= 0.05) return \"mid\"\n if (usd <= 0.1) return \"high\"\n return \"premium\"\n }\n case \"video\": {\n const usd = model.def.pricing.baseCost\n if (usd <= 0.3) return \"low\"\n if (usd <= 0.7) return \"mid\"\n if (usd <= 1.2) return \"high\"\n return \"premium\"\n }\n case \"llm\": {\n // Bucket on provider USD/1M output tokens (output dominates spend).\n // Stable across markup changes — was previously keyed on the\n // credit-side rate, which moved with formula tweaks. A known-but-\n // unpriced id (pricing undefined — see ResolvedModel's doc comment)\n // buckets on DEFAULT_PRICING, same fallback convention as\n // `calculateLLMCreditCost` and the HuggingFace route in\n // `route-identity/index.ts`.\n const out = model.pricing?.outputPer1M ?? DEFAULT_PRICING.outputPer1M\n if (out <= 1) return \"low\"\n if (out <= 10) return \"mid\"\n if (out <= 30) return \"high\"\n return \"premium\"\n }\n case \"audio\": {\n // Bucket on production USD per billing unit (1k chars or 1 min).\n const usd = model.def.pricing.baseCost\n if (usd <= 0.01) return \"low\"\n if (usd <= 0.05) return \"mid\"\n if (usd <= 0.2) return \"high\"\n return \"premium\"\n }\n case \"voice\":\n // Voice metadata isn't priced on its own.\n return \"low\"\n }\n}\n\n/**\n * Display price gauge level (1..5) for a model — the **visual** \"price\n * mostly\" indicator (Low / Medium / High / Max / Ultra) the pickers and the\n * estimator render as a bar. Distinct from {@link inferCatalogPriceTier}:\n * that one drives 4-value *access* rules (`priceTier:premium`) and must stay a\n * `CatalogPriceTier`; this is cosmetic and free to span 5 bands. Both bucket\n * the same provider USD cost, so they move together by construction.\n */\nexport function priceTierForModel(model: ResolvedModel): number {\n switch (model.kind) {\n case \"image\": {\n const usd = model.def.pricing.baseCost\n if (usd <= 0.02) return 1\n if (usd <= 0.05) return 2\n if (usd <= 0.1) return 3\n if (usd <= 0.2) return 4\n return 5\n }\n case \"video\": {\n const usd = model.def.pricing.baseCost\n if (usd <= 0.3) return 1\n if (usd <= 0.7) return 2\n if (usd <= 1.2) return 3\n if (usd <= 2.5) return 4\n return 5\n }\n case \"llm\": {\n // Same DEFAULT_PRICING fallback as inferCatalogPriceTier above.\n const out = model.pricing?.outputPer1M ?? DEFAULT_PRICING.outputPer1M\n if (out <= 1) return 1\n if (out <= 10) return 2\n if (out <= 30) return 3\n if (out <= 75) return 4\n return 5\n }\n case \"audio\": {\n const usd = model.def.pricing.baseCost\n if (usd <= 0.01) return 1\n if (usd <= 0.05) return 2\n if (usd <= 0.2) return 3\n if (usd <= 0.5) return 4\n return 5\n }\n case \"voice\":\n return 1\n }\n}\n\nfunction inferTags(model: ResolvedModel): string[] {\n const tags: string[] = [model.kind]\n switch (model.kind) {\n case \"image\":\n if (model.def.provider) tags.push(model.def.provider)\n if (model.def.capabilities.edit) tags.push(\"edit\")\n if (model.def.capabilities.upscale) tags.push(\"upscale\")\n if (model.def.referenceImages.supported) tags.push(\"ref-images\")\n if (!model.def.agentVisible) tags.push(\"hidden\")\n break\n case \"video\":\n tags.push(model.def.provider)\n if (model.def.capabilities.audio) tags.push(\"audio\")\n if (model.def.capabilities.subjectReference) tags.push(\"subject-ref\")\n if (model.def.capabilities.imageToVideo) tags.push(\"i2v\")\n if (model.def.capabilities.textToVideo) tags.push(\"t2v\")\n if (!model.def.agentVisible) tags.push(\"hidden\")\n break\n case \"llm\":\n // Provider inferred from canonical id prefix (anthropic / openai / google).\n if (model.canonicalId.includes(\"claude\")) tags.push(\"anthropic\")\n else if (model.canonicalId.includes(\"gpt\")) tags.push(\"openai\")\n else if (model.canonicalId.includes(\"gemini\")) tags.push(\"google\")\n break\n case \"audio\":\n tags.push(model.def.provider)\n // Modality is multi-valued — emit a tag per enabled capability so\n // access rules can target `s2s` / `tts` / `stt` independently.\n if (model.def.capabilities.tts) tags.push(\"tts\")\n if (model.def.capabilities.stt) tags.push(\"stt\")\n if (model.def.capabilities.s2s) tags.push(\"s2s\")\n for (const lang of model.def.capabilities.languages) {\n tags.push(`lang:${lang}`)\n }\n if (model.def.capabilities.voiceCloning) tags.push(\"voice-cloning\")\n if (model.def.capabilities.streaming) tags.push(\"streaming\")\n if (model.def.capabilities.diarization) tags.push(\"diarization\")\n if (model.def.capabilities.timestamps) tags.push(\"timestamps\")\n if (!model.def.agentVisible) tags.push(\"hidden\")\n break\n case \"voice\": {\n // \"voice\" is already pushed via `model.kind`. Tag the engine provider\n // and its modality (s2s engines vs sequential tts) so voice access\n // rules can target the same `s2s`/`tts` vocabulary as audio models.\n tags.push(model.voice.provider)\n const s2sVoice =\n model.voice.provider === \"openai-realtime\" ||\n model.voice.provider === \"gemini-live\"\n tags.push(s2sVoice ? \"s2s\" : \"tts\")\n tags.push(`gender:${model.voice.gender}`)\n tags.push(`lang:${model.voice.primaryLanguage}`)\n break\n }\n }\n return tags\n}\n\nfunction inferLifecycle(model: ResolvedModel): Lifecycle {\n // Image / video catalogs use `agentVisible: false` to mark legacy /\n // less-used entries — treat those as \"deprecated\" for rule purposes.\n if (model.kind === \"image\" && !model.def.agentVisible) return \"deprecated\"\n if (model.kind === \"video\" && !model.def.agentVisible) return \"deprecated\"\n return \"stable\"\n}\n\n/**\n * Compose the curation portion of enrichment (everything except actions).\n * Internal — `getEnrichment` is the public entry that adds actions.\n */\nfunction getCurationEnrichment(model: ResolvedModel): ExplicitEnrichment {\n const explicit = EXPLICIT_ENRICHMENT[model.id]\n if (explicit) return explicit\n // For LLM, also try the canonical id (e.g., \"claude-sonnet-4-5\" →\n // \"claude-sonnet-4\" maps via aliases).\n if (model.kind === \"llm\" && model.canonicalId !== model.id) {\n const byCanonical = EXPLICIT_ENRICHMENT[model.canonicalId]\n if (byCanonical) return byCanonical\n }\n return {\n catalogPriceTier: inferCatalogPriceTier(model),\n tags: inferTags(model),\n lifecycle: inferLifecycle(model),\n }\n}\n\n/**\n * Merge two tag arrays preserving first-occurrence order, deduped.\n * Used to fold action tags into curation tags without duplicating.\n */\nfunction mergeTags(\n curation: readonly string[],\n actions: readonly string[]\n): string[] {\n const out: string[] = []\n const seen = new Set<string>()\n for (const t of curation) {\n if (seen.has(t)) continue\n seen.add(t)\n out.push(t)\n }\n for (const t of actions) {\n if (seen.has(t)) continue\n seen.add(t)\n out.push(t)\n }\n return out\n}\n\n/**\n * Resolve enrichment for any model. Explicit map wins; heuristic fallback\n * fills the rest. Action tags (`<kind>:<verb>`) are derived from the\n * model's capability fields and merged into `tags`. Always returns a\n * value (never undefined).\n */\nexport function getEnrichment(model: ResolvedModel): ModelEnrichment {\n const curation = getCurationEnrichment(model)\n const actions = getActions(model)\n return {\n catalogPriceTier: curation.catalogPriceTier,\n tags: mergeTags(curation.tags, actions),\n lifecycle: curation.lifecycle,\n actions,\n }\n}\n\nexport function modelHasTag(model: ResolvedModel, tag: string): boolean {\n return getEnrichment(model).tags.includes(tag)\n}\n\nexport function modelHasAction(model: ResolvedModel, action: string): boolean {\n return getEnrichment(model).actions.includes(action)\n}\n\nexport function modelMatchesCatalogPriceTier(\n model: ResolvedModel,\n tier: CatalogPriceTier\n): boolean {\n return getEnrichment(model).catalogPriceTier === tier\n}\n\n/**\n * @deprecated Use `modelMatchesCatalogPriceTier`. Kept for back-compat\n * with the v1 evaluator's switch case which still uses the\n * `priceTier` discriminator string. The function itself routes to the\n * canonical name.\n */\nexport function modelMatchesPriceTier(\n model: ResolvedModel,\n tier: CatalogPriceTier\n): boolean {\n return modelMatchesCatalogPriceTier(model, tier)\n}\n\nexport function modelMatchesKind(\n model: ResolvedModel,\n kind: ModelKind\n): boolean {\n return model.kind === kind\n}\n"]}
1
+ {"version":3,"sources":["../src/registry/actions.ts","../src/enrichment/index.ts"],"names":[],"mappings":"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","file":"chunk-AJLMLBEZ.mjs","sourcesContent":["/**\n * Action projection — `<kind>:<verb>` namespaced strings derived from\n * each model's per-kind capability object.\n *\n * Convention:\n * - `image:generate`, `image:edit`, `image:upscale`, `image:reference`\n * - `video:text_to`, `video:image_to`, `video:subject_reference`,\n * `video:audio`\n * - `audio:tts`, `audio:stt`, `audio:realtime`\n * - `llm:vision`, `llm:tool_use`, `llm:reasoning`, `llm:long_context`\n *\n * Always `<kind>:<verb_or_modifier>`, snake_case.\n *\n * Action tags share a string array with curation tags but live behind the\n * reserved `<kind>:` prefix. Curation tags MUST NOT use the prefix —\n * `assertReservedPrefixDiscipline` enforces this at module load.\n *\n * The reason this lives in the catalog package (not enrichment) is that\n * actions are intrinsic to a model — derived from its capability fields,\n * not subjectively curated. Keeping the projection separate makes it\n * trivially callable from anywhere (e.g. a UI badge component) without\n * pulling the heuristic enrichment table.\n */\n\nimport type { ResolvedModel } from \"./index.js\"\n\nconst RESERVED_KIND_PREFIXES = [\"llm:\", \"image:\", \"video:\", \"audio:\"] as const\n\n/**\n * Compute the action tags a model supports. Returns an empty array for\n * models with no recognized capability bits (defensive — never throws).\n */\nexport function getActions(model: ResolvedModel): string[] {\n switch (model.kind) {\n case \"image\": {\n const out: string[] = []\n const c = model.def.capabilities\n if (c.generate) out.push(\"image:generate\")\n if (c.edit) out.push(\"image:edit\")\n if (c.upscale) out.push(\"image:upscale\")\n if (model.def.referenceImages.supported) out.push(\"image:reference\")\n return out\n }\n case \"video\": {\n const out: string[] = []\n const c = model.def.capabilities\n if (c.textToVideo) out.push(\"video:text_to\")\n if (c.imageToVideo) out.push(\"video:image_to\")\n if (c.subjectReference) out.push(\"video:subject_reference\")\n if (c.audio) out.push(\"video:audio\")\n return out\n }\n case \"audio\": {\n const out: string[] = []\n const c = model.def.capabilities\n // One action per enabled modality (a model may do more than one).\n if (c.tts) out.push(\"audio:tts\")\n if (c.stt) out.push(\"audio:stt\")\n if (c.s2s) out.push(\"audio:s2s\")\n if (c.voiceCloning) out.push(\"audio:voice_cloning\")\n if (c.streaming) out.push(\"audio:streaming\")\n if (c.diarization) out.push(\"audio:diarization\")\n if (c.timestamps) out.push(\"audio:timestamps\")\n return out\n }\n case \"voice\":\n // Voice metadata represents a render-target, not an action — tag it\n // with the engine modality so it matches the same action vocabulary\n // as audio models (s2s engines vs sequential tts).\n return model.voice.provider === \"openai-realtime\" ||\n model.voice.provider === \"gemini-live\"\n ? [\"audio:s2s\"]\n : [\"audio:tts\"]\n case \"llm\": {\n // LLM actions piggyback on the catalog-attached capability metadata\n // when present. The legacy `LLMPricing` shape doesn't carry\n // capabilities directly — those live in the agent-framework\n // catalog (to be folded into model-catalog/llm in a future phase).\n // For v1, infer from canonical id heuristics. Keep conservative:\n // only emit actions we can prove from the id.\n const out: string[] = []\n const id = model.canonicalId.toLowerCase()\n // Tool use: every modern frontier LLM supports it. Bare `gpt`,\n // `claude`, `gemini` are tool-capable; small fast variants\n // (haiku, mini, flash, lite) are too. We assume yes unless the\n // id obviously rules it out.\n out.push(\"llm:tool_use\")\n // Reasoning: opus / sonnet / pro / r1 / o1 / o3 / thinking models.\n if (\n /opus|sonnet|claude-3.7|gpt-4\\.5|gpt-5|gemini-.*-pro|deepseek-r1|o1|o3|thinking|reasoning/.test(\n id\n )\n ) {\n out.push(\"llm:reasoning\")\n }\n // Vision: Sonnet, Opus, GPT-4o, Gemini, multimodal-marked ids.\n if (\n /sonnet|opus|gpt-4o|gpt-5|gemini|claude-3|claude-haiku-4|vision|vl/.test(\n id\n )\n ) {\n out.push(\"llm:vision\")\n }\n // Long context: Gemini, GPT-4.1, Sonnet 4 (1M), Kimi, Grok 4 fast.\n if (\n /gemini|gpt-4\\.1|claude-sonnet-4|kimi|grok-4|qwen3-next|long.context/.test(\n id\n )\n ) {\n out.push(\"llm:long_context\")\n }\n return out\n }\n }\n}\n\n/**\n * Validate that a string array intended as curation tags does not use a\n * reserved `<kind>:` prefix. Run at module load on the explicit\n * enrichment map; throws on violation so the offending entry is caught\n * before any access decision is made.\n *\n * Caller pattern (in tests / module-load init):\n * for (const e of Object.values(EXPLICIT_ENRICHMENT))\n * assertReservedPrefixDiscipline(e.tags)\n */\nexport function assertReservedPrefixDiscipline(\n curationTags: readonly string[]\n): void {\n for (const tag of curationTags) {\n for (const prefix of RESERVED_KIND_PREFIXES) {\n if (tag.startsWith(prefix)) {\n throw new Error(\n `Reserved tag prefix \"${prefix}\" used in curation tag \"${tag}\". ` +\n `Action tags (\\`<kind>:<verb>\\`) are derived automatically by ` +\n `getActions() — do not put them in curation arrays.`\n )\n }\n }\n }\n}\n\n/**\n * Returns true iff the given tag is in the reserved action-tag namespace.\n * Useful for callers that need to display curation tags only (e.g.\n * an admin UI) without hardcoding the prefix list.\n */\nexport function isActionTag(tag: string): boolean {\n return RESERVED_KIND_PREFIXES.some(p => tag.startsWith(p))\n}\n","/**\n * Model enrichment — `catalogPriceTier` / `tags` / `lifecycle` / `actions`\n * per model id.\n *\n * Bridge between the legacy data shape (`ImageModelDefinition`,\n * `VideoModelDefinition`, `LLMPricing`) and the v2 access-rule\n * primitives that target by tier, tag, and action. Without this, rules\n * like `priceTier:premium` and `tag:nsfw` would never match anything.\n *\n * Two layers:\n * 1. Explicit map for the curated set we know about (overrides win).\n * 2. Heuristic inference for any model not in the explicit map\n * (catalogPriceTier from creditCost / token rates; tags from kind +\n * provider).\n *\n * Actions (`<kind>:<verb>` — e.g. `image:generate`, `llm:tool_use`) are\n * computed from per-kind capability objects via `getActions` and merged\n * into `tags` so existing tag-based access rules match action targets\n * without any evaluator change. The reserved `<kind>:` prefix is enforced\n * by `assertReservedPrefixDiscipline` at module load — free-form curation\n * tags must NOT use it.\n *\n * Add an entry to `EXPLICIT_ENRICHMENT` when you want exact control;\n * skip it when defaults are good enough.\n */\n\nimport type { CatalogPriceTier, Lifecycle, ModelKind } from \"../schema/index.js\"\nimport type { ResolvedModel } from \"../registry/index.js\"\nimport { DEFAULT_PRICING } from \"../llm/index.js\"\nimport {\n getActions,\n assertReservedPrefixDiscipline,\n} from \"../registry/actions.js\"\n\nexport interface ModelEnrichment {\n catalogPriceTier: CatalogPriceTier\n /** Curation tags + action tags (`<kind>:<verb>`) merged. */\n tags: readonly string[]\n lifecycle: Lifecycle\n /** Action tags only — convenience subset of `tags`. */\n actions: readonly string[]\n}\n\n/**\n * Internal shape for the curated explicit-enrichment map. The map carries\n * only the *curation* fields — `tags` here is curation-only (no action\n * tags). `getEnrichment` adds derived `actions` and merges them into\n * `tags` at read time.\n */\ninterface ExplicitEnrichment {\n catalogPriceTier: CatalogPriceTier\n tags: readonly string[]\n lifecycle: Lifecycle\n}\n\nconst EXPLICIT_ENRICHMENT: Record<string, ExplicitEnrichment> = {\n // ── LLM ──────────────────────────────────────────────────────────────\n \"claude-opus-4-5\": {\n catalogPriceTier: \"premium\",\n tags: [\"llm\", \"anthropic\", \"premium\", \"reasoning\"],\n lifecycle: \"stable\",\n },\n \"claude-sonnet-4-5\": {\n catalogPriceTier: \"high\",\n tags: [\"llm\", \"anthropic\"],\n lifecycle: \"stable\",\n },\n \"claude-haiku-4-5\": {\n catalogPriceTier: \"low\",\n tags: [\"llm\", \"anthropic\", \"fast\"],\n lifecycle: \"stable\",\n },\n \"gemini-2.5-flash\": {\n catalogPriceTier: \"low\",\n tags: [\"llm\", \"google\", \"fast\"],\n lifecycle: \"stable\",\n },\n \"gemini-2.5-pro\": {\n catalogPriceTier: \"mid\",\n tags: [\"llm\", \"google\", \"reasoning\"],\n lifecycle: \"stable\",\n },\n \"gpt-4.1\": {\n catalogPriceTier: \"mid\",\n tags: [\"llm\", \"openai\"],\n lifecycle: \"stable\",\n },\n \"gpt-4.1-mini\": {\n catalogPriceTier: \"low\",\n tags: [\"llm\", \"openai\", \"fast\"],\n lifecycle: \"stable\",\n },\n \"gpt-4o\": {\n catalogPriceTier: \"mid\",\n tags: [\"llm\", \"openai\"],\n lifecycle: \"stable\",\n },\n \"gpt-4o-mini\": {\n catalogPriceTier: \"low\",\n tags: [\"llm\", \"openai\", \"fast\"],\n lifecycle: \"stable\",\n },\n\n // ── Image (highlights — others fall through to heuristic) ────────────\n \"nano-banana-pro\": {\n catalogPriceTier: \"high\",\n tags: [\"image\", \"google\", \"high-quality\", \"text-rendering\"],\n lifecycle: \"stable\",\n },\n \"nano-banana-2\": {\n catalogPriceTier: \"mid\",\n tags: [\"image\", \"google\"],\n lifecycle: \"stable\",\n },\n \"nano-banana\": {\n catalogPriceTier: \"low\",\n tags: [\"image\", \"google\", \"fast\"],\n lifecycle: \"stable\",\n },\n \"flux-2-dev\": {\n catalogPriceTier: \"low\",\n tags: [\"image\", \"bfl\", \"flux\"],\n lifecycle: \"stable\",\n },\n \"flux-kontext-pro\": {\n catalogPriceTier: \"low\",\n tags: [\"image\", \"bfl\", \"flux\", \"edit\"],\n lifecycle: \"stable\",\n },\n \"flux-kontext-max\": {\n catalogPriceTier: \"mid\",\n tags: [\"image\", \"bfl\", \"flux\", \"edit\", \"high-quality\"],\n lifecycle: \"stable\",\n },\n \"seedream-4\": {\n catalogPriceTier: \"low\",\n tags: [\"image\", \"bytedance\", \"photorealistic\"],\n lifecycle: \"stable\",\n },\n\n // ── Video (highlights) ──────────────────────────────────────────────\n \"google/veo-3.1\": {\n catalogPriceTier: \"high\",\n tags: [\"video\", \"google\", \"veo\", \"high-quality\", \"audio\"],\n lifecycle: \"stable\",\n },\n \"google/veo-3.1-fast\": {\n catalogPriceTier: \"mid\",\n tags: [\"video\", \"google\", \"veo\", \"fast\", \"audio\"],\n lifecycle: \"stable\",\n },\n \"kwaivgi/kling-v2.5-turbo-pro\": {\n catalogPriceTier: \"low\",\n tags: [\"video\", \"kling\", \"fast\"],\n lifecycle: \"deprecated\",\n },\n}\n\n// Module-load lint: every curation tag in the explicit map must avoid the\n// reserved `<kind>:` prefix. Action tags are derived by `getActions`,\n// never written by hand.\nfor (const entry of Object.values(EXPLICIT_ENRICHMENT)) {\n assertReservedPrefixDiscipline(entry.tags)\n}\n\n/**\n * Heuristic catalogPriceTier — used when an entry has no explicit\n * enrichment. Buckets are intentionally generous so rules don't need\n * every model priced exactly.\n */\nfunction inferCatalogPriceTier(model: ResolvedModel): CatalogPriceTier {\n switch (model.kind) {\n case \"image\": {\n // Derive from baseCost (USD) — formula bucketing keeps tiers\n // stable when category markup changes.\n const usd = model.def.pricing.baseCost\n if (usd <= 0.02) return \"low\"\n if (usd <= 0.05) return \"mid\"\n if (usd <= 0.1) return \"high\"\n return \"premium\"\n }\n case \"video\": {\n const usd = model.def.pricing.baseCost\n if (usd <= 0.3) return \"low\"\n if (usd <= 0.7) return \"mid\"\n if (usd <= 1.2) return \"high\"\n return \"premium\"\n }\n case \"llm\": {\n // Bucket on provider USD/1M output tokens (output dominates spend).\n // Stable across markup changes — was previously keyed on the\n // credit-side rate, which moved with formula tweaks. A known-but-\n // unpriced id (pricing undefined — see ResolvedModel's doc comment)\n // buckets on DEFAULT_PRICING, same fallback convention as\n // `calculateLLMCreditCost` and the HuggingFace route in\n // `route-identity/index.ts`.\n const out = model.pricing?.outputPer1M ?? DEFAULT_PRICING.outputPer1M\n if (out <= 1) return \"low\"\n if (out <= 10) return \"mid\"\n if (out <= 30) return \"high\"\n return \"premium\"\n }\n case \"audio\": {\n // Bucket on production USD per billing unit (1k chars or 1 min).\n const usd = model.def.pricing.baseCost\n if (usd <= 0.01) return \"low\"\n if (usd <= 0.05) return \"mid\"\n if (usd <= 0.2) return \"high\"\n return \"premium\"\n }\n case \"voice\":\n // Voice metadata isn't priced on its own.\n return \"low\"\n }\n}\n\n/**\n * Display price gauge level (1..5) for a model — the **visual** \"price\n * mostly\" indicator (Low / Medium / High / Max / Ultra) the pickers and the\n * estimator render as a bar. Distinct from {@link inferCatalogPriceTier}:\n * that one drives 4-value *access* rules (`priceTier:premium`) and must stay a\n * `CatalogPriceTier`; this is cosmetic and free to span 5 bands. Both bucket\n * the same provider USD cost, so they move together by construction.\n */\nexport function priceTierForModel(model: ResolvedModel): number {\n switch (model.kind) {\n case \"image\": {\n const usd = model.def.pricing.baseCost\n if (usd <= 0.02) return 1\n if (usd <= 0.05) return 2\n if (usd <= 0.1) return 3\n if (usd <= 0.2) return 4\n return 5\n }\n case \"video\": {\n const usd = model.def.pricing.baseCost\n if (usd <= 0.3) return 1\n if (usd <= 0.7) return 2\n if (usd <= 1.2) return 3\n if (usd <= 2.5) return 4\n return 5\n }\n case \"llm\": {\n // Same DEFAULT_PRICING fallback as inferCatalogPriceTier above.\n const out = model.pricing?.outputPer1M ?? DEFAULT_PRICING.outputPer1M\n if (out <= 1) return 1\n if (out <= 10) return 2\n if (out <= 30) return 3\n if (out <= 75) return 4\n return 5\n }\n case \"audio\": {\n const usd = model.def.pricing.baseCost\n if (usd <= 0.01) return 1\n if (usd <= 0.05) return 2\n if (usd <= 0.2) return 3\n if (usd <= 0.5) return 4\n return 5\n }\n case \"voice\":\n return 1\n }\n}\n\nfunction inferTags(model: ResolvedModel): string[] {\n const tags: string[] = [model.kind]\n switch (model.kind) {\n case \"image\":\n if (model.def.provider) tags.push(model.def.provider)\n if (model.def.capabilities.edit) tags.push(\"edit\")\n if (model.def.capabilities.upscale) tags.push(\"upscale\")\n if (model.def.referenceImages.supported) tags.push(\"ref-images\")\n if (!model.def.agentVisible) tags.push(\"hidden\")\n break\n case \"video\":\n tags.push(model.def.provider)\n if (model.def.capabilities.audio) tags.push(\"audio\")\n if (model.def.capabilities.subjectReference) tags.push(\"subject-ref\")\n if (model.def.capabilities.imageToVideo) tags.push(\"i2v\")\n if (model.def.capabilities.textToVideo) tags.push(\"t2v\")\n if (!model.def.agentVisible) tags.push(\"hidden\")\n break\n case \"llm\":\n // Provider inferred from canonical id prefix (anthropic / openai / google).\n if (model.canonicalId.includes(\"claude\")) tags.push(\"anthropic\")\n else if (model.canonicalId.includes(\"gpt\")) tags.push(\"openai\")\n else if (model.canonicalId.includes(\"gemini\")) tags.push(\"google\")\n break\n case \"audio\":\n tags.push(model.def.provider)\n // Modality is multi-valued — emit a tag per enabled capability so\n // access rules can target `s2s` / `tts` / `stt` independently.\n if (model.def.capabilities.tts) tags.push(\"tts\")\n if (model.def.capabilities.stt) tags.push(\"stt\")\n if (model.def.capabilities.s2s) tags.push(\"s2s\")\n for (const lang of model.def.capabilities.languages) {\n tags.push(`lang:${lang}`)\n }\n if (model.def.capabilities.voiceCloning) tags.push(\"voice-cloning\")\n if (model.def.capabilities.streaming) tags.push(\"streaming\")\n if (model.def.capabilities.diarization) tags.push(\"diarization\")\n if (model.def.capabilities.timestamps) tags.push(\"timestamps\")\n if (!model.def.agentVisible) tags.push(\"hidden\")\n break\n case \"voice\": {\n // \"voice\" is already pushed via `model.kind`. Tag the engine provider\n // and its modality (s2s engines vs sequential tts) so voice access\n // rules can target the same `s2s`/`tts` vocabulary as audio models.\n tags.push(model.voice.provider)\n const s2sVoice =\n model.voice.provider === \"openai-realtime\" ||\n model.voice.provider === \"gemini-live\"\n tags.push(s2sVoice ? \"s2s\" : \"tts\")\n tags.push(`gender:${model.voice.gender}`)\n tags.push(`lang:${model.voice.primaryLanguage}`)\n break\n }\n }\n return tags\n}\n\nfunction inferLifecycle(model: ResolvedModel): Lifecycle {\n // Image / video catalogs use `agentVisible: false` to mark legacy /\n // less-used entries — treat those as \"deprecated\" for rule purposes.\n if (model.kind === \"image\" && !model.def.agentVisible) return \"deprecated\"\n if (model.kind === \"video\" && !model.def.agentVisible) return \"deprecated\"\n return \"stable\"\n}\n\n/**\n * Compose the curation portion of enrichment (everything except actions).\n * Internal — `getEnrichment` is the public entry that adds actions.\n */\nfunction getCurationEnrichment(model: ResolvedModel): ExplicitEnrichment {\n const explicit = EXPLICIT_ENRICHMENT[model.id]\n if (explicit) return explicit\n // For LLM, also try the canonical id (e.g., \"claude-sonnet-4-5\" →\n // \"claude-sonnet-4\" maps via aliases).\n if (model.kind === \"llm\" && model.canonicalId !== model.id) {\n const byCanonical = EXPLICIT_ENRICHMENT[model.canonicalId]\n if (byCanonical) return byCanonical\n }\n return {\n catalogPriceTier: inferCatalogPriceTier(model),\n tags: inferTags(model),\n lifecycle: inferLifecycle(model),\n }\n}\n\n/**\n * Merge two tag arrays preserving first-occurrence order, deduped.\n * Used to fold action tags into curation tags without duplicating.\n */\nfunction mergeTags(\n curation: readonly string[],\n actions: readonly string[]\n): string[] {\n const out: string[] = []\n const seen = new Set<string>()\n for (const t of curation) {\n if (seen.has(t)) continue\n seen.add(t)\n out.push(t)\n }\n for (const t of actions) {\n if (seen.has(t)) continue\n seen.add(t)\n out.push(t)\n }\n return out\n}\n\n/**\n * Resolve enrichment for any model. Explicit map wins; heuristic fallback\n * fills the rest. Action tags (`<kind>:<verb>`) are derived from the\n * model's capability fields and merged into `tags`. Always returns a\n * value (never undefined).\n */\nexport function getEnrichment(model: ResolvedModel): ModelEnrichment {\n const curation = getCurationEnrichment(model)\n const actions = getActions(model)\n return {\n catalogPriceTier: curation.catalogPriceTier,\n tags: mergeTags(curation.tags, actions),\n lifecycle: curation.lifecycle,\n actions,\n }\n}\n\nexport function modelHasTag(model: ResolvedModel, tag: string): boolean {\n return getEnrichment(model).tags.includes(tag)\n}\n\nexport function modelHasAction(model: ResolvedModel, action: string): boolean {\n return getEnrichment(model).actions.includes(action)\n}\n\nexport function modelMatchesCatalogPriceTier(\n model: ResolvedModel,\n tier: CatalogPriceTier\n): boolean {\n return getEnrichment(model).catalogPriceTier === tier\n}\n\n/**\n * @deprecated Use `modelMatchesCatalogPriceTier`. Kept for back-compat\n * with the v1 evaluator's switch case which still uses the\n * `priceTier` discriminator string. The function itself routes to the\n * canonical name.\n */\nexport function modelMatchesPriceTier(\n model: ResolvedModel,\n tier: CatalogPriceTier\n): boolean {\n return modelMatchesCatalogPriceTier(model, tier)\n}\n\nexport function modelMatchesKind(\n model: ResolvedModel,\n kind: ModelKind\n): boolean {\n return model.kind === kind\n}\n"]}