@agentproto/model-catalog 0.9.4 → 0.10.1

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 (47) hide show
  1. package/dist/access/index.d.ts +5 -5
  2. package/dist/access/index.mjs +4 -4
  3. package/dist/audio/index.d.ts +1 -1
  4. package/dist/{audio-DR0g_ZH_.d.ts → audio-Do2j3wDC.d.ts} +2 -0
  5. package/dist/{base-B8IIoaqg.d.ts → base-BaiI72Da.d.ts} +4 -0
  6. package/dist/{catalog-Cg0AJJZ7.d.ts → catalog-BAb74hY-.d.ts} +1 -1
  7. package/dist/{chunk-H467PHUU.mjs → chunk-B67THXMQ.mjs} +3 -3
  8. package/dist/{chunk-H467PHUU.mjs.map → chunk-B67THXMQ.mjs.map} +1 -1
  9. package/dist/{chunk-5XUA72EH.mjs → chunk-E3IERKDC.mjs} +3 -3
  10. package/dist/{chunk-5XUA72EH.mjs.map → chunk-E3IERKDC.mjs.map} +1 -1
  11. package/dist/{chunk-JHBSGPWH.mjs → chunk-E5CVTRPJ.mjs} +5 -5
  12. package/dist/{chunk-JHBSGPWH.mjs.map → chunk-E5CVTRPJ.mjs.map} +1 -1
  13. package/dist/{chunk-GW52XH4V.mjs → chunk-G6CA3BXI.mjs} +204 -197
  14. package/dist/chunk-G6CA3BXI.mjs.map +1 -0
  15. package/dist/{chunk-6VUL4I7V.mjs → chunk-I5E7F6KY.mjs} +1454 -192
  16. package/dist/chunk-I5E7F6KY.mjs.map +1 -0
  17. package/dist/{chunk-V2BMFFUF.mjs → chunk-O6SQMVPM.mjs} +4 -4
  18. package/dist/{chunk-V2BMFFUF.mjs.map → chunk-O6SQMVPM.mjs.map} +1 -1
  19. package/dist/{chunk-ZTTWZ7PL.mjs → chunk-TC6S3SY3.mjs} +15 -3
  20. package/dist/chunk-TC6S3SY3.mjs.map +1 -0
  21. package/dist/{chunk-3Y5TQDGE.mjs → chunk-TTIJME5T.mjs} +3 -3
  22. package/dist/{chunk-3Y5TQDGE.mjs.map → chunk-TTIJME5T.mjs.map} +1 -1
  23. package/dist/{chunk-UREM2UZK.mjs → chunk-UZDL26T7.mjs} +4 -4
  24. package/dist/{chunk-UREM2UZK.mjs.map → chunk-UZDL26T7.mjs.map} +1 -1
  25. package/dist/{chunk-QNJRWRWC.mjs → chunk-WG4F6IRS.mjs} +22 -2
  26. package/dist/chunk-WG4F6IRS.mjs.map +1 -0
  27. package/dist/cost/index.mjs +7 -7
  28. package/dist/curation/index.d.ts +4 -4
  29. package/dist/curation/index.mjs +7 -7
  30. package/dist/{evaluate-D3gXrAg-.d.ts → evaluate-B83jX17h.d.ts} +2 -2
  31. package/dist/{index-DC8jecem.d.ts → index-BWvtVzEG.d.ts} +3 -3
  32. package/dist/{index-BZfxAdXA.d.ts → index-vC37SFpk.d.ts} +18 -13
  33. package/dist/index.d.ts +7 -7
  34. package/dist/index.mjs +12 -12
  35. package/dist/llm/index.d.ts +44 -3
  36. package/dist/llm/index.mjs +2 -2
  37. package/dist/overlay/index.d.ts +3 -3
  38. package/dist/picker/index.d.ts +6 -6
  39. package/dist/route-identity/index.d.ts +5 -2
  40. package/dist/route-identity/index.mjs +3 -3
  41. package/dist/schema/index.d.ts +16 -2
  42. package/dist/schema/index.mjs +2 -2
  43. package/package.json +3 -3
  44. package/dist/chunk-6VUL4I7V.mjs.map +0 -1
  45. package/dist/chunk-GW52XH4V.mjs.map +0 -1
  46. package/dist/chunk-QNJRWRWC.mjs.map +0 -1
  47. package/dist/chunk-ZTTWZ7PL.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
- import { getModel } from './chunk-JHBSGPWH.mjs';
2
- import { calculateLLMCreditCost } from './chunk-6VUL4I7V.mjs';
1
+ import { getModel } from './chunk-E5CVTRPJ.mjs';
2
+ import { calculateLLMCreditCost } from './chunk-I5E7F6KY.mjs';
3
3
  import { computeCenticredits, pricingRegistry } from './chunk-QHELXPSL.mjs';
4
4
 
5
5
  /**
@@ -223,5 +223,5 @@ function calculateAudioCost(modelId, usage, opts) {
223
223
  }
224
224
 
225
225
  export { CostUsageKindMismatchError, UnknownModelError, calculateAudioCost, calculateCost, calculateImageCost, calculateLLMCost, calculateVideoCost };
226
- //# sourceMappingURL=chunk-V2BMFFUF.mjs.map
227
- //# sourceMappingURL=chunk-V2BMFFUF.mjs.map
226
+ //# sourceMappingURL=chunk-O6SQMVPM.mjs.map
227
+ //# sourceMappingURL=chunk-O6SQMVPM.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cost/index.ts"],"names":["resolved","baseCostUsd","credits","calculatedCredits","markup"],"mappings":"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","file":"chunk-V2BMFFUF.mjs","sourcesContent":["/**\n * Cost dispatcher — computes credit cost + production USD cost for any\n * model id, regardless of kind. Single entry point used by orchestrator,\n * billing audits, and (eventually) the metered MCP gen layer.\n *\n * Per-kind formulas:\n * - LLM → reuses `calculateLLMCreditCost` (token math + cache + markup)\n * - Image → `creditCost × numOutputs`\n * - Video → `creditCost × multipliers[resolution|duration|mode]`\n * - Audio → `creditCost × (characters or seconds)` per `billingUnit`\n */\n\nimport {\n calculateLLMCreditCost,\n type LLMCreditCostResult,\n} from \"../llm/index.js\"\nimport { getModel } from \"../registry/index.js\"\nimport { computeCenticredits, pricingRegistry } from \"../pricing/index.js\"\n\n/**\n * Voice metadata → default audio model the dispatcher bills through.\n *\n * Voices are render-targets, not priced units. A MiniMax voice can be\n * played through `minimax/speech-02-hd` OR `…-turbo`; an ElevenLabs\n * voice through any of their model tiers. We default to the cheapest\n * model per provider so a drive-by voice-id call doesn't over-bill.\n * Callers wanting HD / premium-tier pricing should pass the audio\n * model id directly with the voice as metadata — see\n * `text-to-speech.tool.ts` for the canonical pattern.\n *\n * Add a new provider here when a new voice catalog lands (e.g.\n * `ELEVENLABS_VOICES` if/when we surface their voice IDs).\n */\nconst VOICE_PROVIDER_DEFAULT_MODEL: Record<string, string> = {\n minimax: \"minimax/speech-02-turbo\",\n elevenlabs: \"elevenlabs/flash-v2.5\",\n}\n\nexport type CostUsage =\n | {\n kind: \"llm\"\n inputTokens: number\n outputTokens: number\n cacheReadInputTokens?: number\n cacheCreationInputTokens?: number\n }\n | { kind: \"image\"; numOutputs?: number }\n | {\n kind: \"video\"\n resolution?: string\n duration?: number\n mode?: string\n }\n | { kind: \"audio\"; characters?: number; seconds?: number }\n\nexport interface CostResult {\n kind: \"llm\" | \"image\" | \"video\" | \"audio\"\n modelId: string\n /** Canonical model id after alias resolution (LLM only; same as modelId for media) */\n canonicalId: string\n /**\n * Total **centicredits** to charge (1 displayed credit = 100 cc).\n * Honors per-model overrides. Feed straight into the ledger — the\n * `credit_transactions.credits` column stores cc, so no `× 100`\n * conversion at the call site. Format for display with\n * `displayCredits(cc) → cr`.\n */\n credits: number\n /**\n * Centicredits the pure formula (provider cost × category markup)\n * would have charged, independent of any per-model override. Equal\n * to `credits` when no override is in play. Surfaced so\n * reconciliation can diff \"what we did\" vs \"what the formula said\"\n * without recomputing — persisted to `usage_events.calculated_credits`.\n */\n calculatedCredits: number\n /** Production cost in USD (provider-side, before markup) */\n baseCostUsd: number\n /** Per-kind breakdown — inputCredits/outputCredits for LLM, etc. All in cc. */\n breakdown: Record<string, number>\n /** True iff fallback pricing was used (currently LLM-only) */\n isFallback: boolean\n /** Markup applied (1.0 = catalog rate as-is) */\n markup: number\n}\n\nexport class UnknownModelError extends Error {\n constructor(public readonly modelId: string) {\n super(`Unknown model id: \"${modelId}\"`)\n this.name = \"UnknownModelError\"\n }\n}\n\nexport class CostUsageKindMismatchError extends Error {\n constructor(\n public readonly modelId: string,\n public readonly expected: string,\n public readonly got: string\n ) {\n super(\n `Model \"${modelId}\" is kind \"${expected}\", but received usage of kind \"${got}\"`\n )\n this.name = \"CostUsageKindMismatchError\"\n }\n}\n\nexport interface CalculateCostOptions {\n /**\n * App that's invoking the model. Routes per-app markup overrides\n * registered via `pricingRegistry.registerApp(appId, ...)`. When\n * omitted, core defaults apply.\n */\n appId?: string\n}\n\n/**\n * Computes credit + USD cost for a model run.\n *\n * Throws `UnknownModelError` for ids not in any catalog (LLM has its own\n * fallback path inside `calculateLLMCreditCost` — this surface preserves\n * that for back-compat).\n *\n * Throws `CostUsageKindMismatchError` if `usage.kind` doesn't match the\n * resolved model's kind (data integrity guard).\n *\n * Image / video / audio credits are derived at call time via the\n * pricing registry (`provider_cost × category-markup`). LLM keeps its\n * own per-model markup table inside `calculateLLMCreditCost` —\n * collapsing that follows in W6b.\n */\nexport function calculateCost(\n modelId: string,\n usage: CostUsage,\n opts: CalculateCostOptions = {}\n): CostResult {\n // LLM has a fallback path that returns valid pricing even for unknown\n // ids (preserves the orchestrator's existing tolerance). Other kinds\n // throw for unknowns.\n if (usage.kind === \"llm\") {\n const llmResult: LLMCreditCostResult = calculateLLMCreditCost(modelId, {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n cacheReadInputTokens: usage.cacheReadInputTokens,\n cacheCreationInputTokens: usage.cacheCreationInputTokens,\n })\n const resolved = getModel(modelId)\n const canonicalId =\n resolved && resolved.kind === \"llm\" ? resolved.canonicalId : modelId\n return {\n kind: \"llm\",\n modelId,\n canonicalId,\n credits: llmResult.credits,\n calculatedCredits: llmResult.calculatedCredits,\n baseCostUsd: llmResult.productionCost,\n breakdown: {\n inputCredits: llmResult.inputCredits,\n outputCredits: llmResult.outputCredits,\n cacheReadCredits: llmResult.cacheReadCredits,\n cacheWriteCredits: llmResult.cacheWriteCredits,\n },\n isFallback: llmResult.isFallback,\n markup: llmResult.markup,\n }\n }\n\n const resolved = getModel(modelId)\n if (!resolved) throw new UnknownModelError(modelId)\n // `voice` is structurally audio for billing purposes (MiniMax voice\n // metadata billed via per-character output). Accept `audio` usage on\n // voice models so the per-kind branches below can pattern-match.\n const expectedUsageKind: CostUsage[\"kind\"] =\n resolved.kind === \"voice\" ? \"audio\" : resolved.kind\n if (expectedUsageKind !== usage.kind) {\n // Pass `expectedUsageKind` (not `resolved.kind`) so the error message\n // accurately says \"audio\" rather than \"voice\" when a voice model is\n // billed — the caller must supply audio usage, not voice usage.\n throw new CostUsageKindMismatchError(modelId, expectedUsageKind, usage.kind)\n }\n\n if (resolved.kind === \"image\") {\n // `usage.kind` is \"image\" here (guarded above) but TS won't cross-narrow\n // it from `resolved.kind`, so check explicitly before reading numOutputs.\n const numOutputs = Math.max(\n 1,\n usage.kind === \"image\" ? (usage.numOutputs ?? 1) : 1\n )\n const baseCostUsd = resolved.def.pricing.baseCost * numOutputs\n const perOutputCredits = computeCenticredits({\n baseCostUsd: resolved.def.pricing.baseCost,\n category: \"image\",\n overrideCreditCost: resolved.def.pricing.overrideCreditCost,\n appId: opts.appId,\n })\n const credits = perOutputCredits * numOutputs\n // Formula-only (ignores override) — for `usage_events.calculated_credits`.\n const formulaPerOutput = computeCenticredits({\n baseCostUsd: resolved.def.pricing.baseCost,\n category: \"image\",\n appId: opts.appId,\n })\n const calculatedCredits = formulaPerOutput * numOutputs\n const markup = pricingRegistry.getMarkup(\"image\", opts.appId)\n return {\n kind: \"image\",\n modelId,\n canonicalId: modelId,\n credits,\n calculatedCredits,\n baseCostUsd,\n breakdown: {\n perOutputCredits,\n numOutputs,\n },\n isFallback: false,\n markup,\n }\n }\n\n if (resolved.kind === \"video\") {\n if (usage.kind !== \"video\") {\n throw new CostUsageKindMismatchError(modelId, \"video\", usage.kind)\n }\n const pricing = resolved.def.pricing\n // Provider-side multipliers — re-applied to BOTH the provider cost\n // (what we pay) AND the derived credit cost (so margin holds).\n const mult = pricing.multipliers\n const resMult =\n usage.resolution && mult?.resolution\n ? (mult.resolution[usage.resolution] ?? 1.0)\n : 1.0\n const durMult =\n usage.duration && mult?.duration\n ? (mult.duration[usage.duration] ?? 1.0)\n : 1.0\n const modMult =\n usage.mode && mult?.mode ? (mult.mode[usage.mode] ?? 1.0) : 1.0\n const variantMultiplier = resMult * durMult * modMult\n const baseCostUsd = pricing.baseCost * variantMultiplier\n const perClipCredits = computeCenticredits({\n baseCostUsd: pricing.baseCost,\n category: \"video\",\n overrideCreditCost: pricing.overrideCreditCost,\n appId: opts.appId,\n })\n const credits = Math.ceil(perClipCredits * variantMultiplier)\n const formulaPerClip = computeCenticredits({\n baseCostUsd: pricing.baseCost,\n category: \"video\",\n appId: opts.appId,\n })\n const calculatedCredits = Math.ceil(formulaPerClip * variantMultiplier)\n const markup = pricingRegistry.getMarkup(\"video\", opts.appId)\n return {\n kind: \"video\",\n modelId,\n canonicalId: modelId,\n credits,\n calculatedCredits,\n baseCostUsd,\n breakdown: {\n perClipCredits,\n resolutionMultiplier: resMult,\n durationMultiplier: durMult,\n modeMultiplier: modMult,\n variantMultiplier,\n },\n isFallback: false,\n markup,\n }\n }\n\n // Audio (and voice, delegated as audio — see expectedUsageKind above).\n if (usage.kind !== \"audio\") {\n throw new CostUsageKindMismatchError(modelId, \"audio\", usage.kind)\n }\n\n if (resolved.kind === \"voice\") {\n // Voice rows are metadata; delegate to the provider's default audio model.\n const provider = resolved.voice.provider\n const delegateModelId = VOICE_PROVIDER_DEFAULT_MODEL[provider]\n if (!delegateModelId) throw new UnknownModelError(modelId)\n const delegateResult = calculateCost(delegateModelId, usage, opts)\n return {\n ...delegateResult,\n modelId,\n canonicalId: delegateModelId,\n }\n }\n\n // Only `audio` remains (llm returned at top; image/video/voice handled\n // above). Narrow explicitly so `.def` is type-safe.\n if (resolved.kind !== \"audio\") throw new UnknownModelError(modelId)\n const audioPricing = resolved.def.pricing\n // Map the provider's billing unit to a quantity of billable units.\n // The catalog DATA uses `per_1k_chars` (chars ÷ 1000) and `per_minute`\n // (whole minutes, rounded UP to match provider invoicing). `per_character`\n // / `per_second` are handled too so a future data migration to those units\n // keeps working. NOTE: do not switch on the zod enum value alone — the\n // audio schema enum is stale (`per_character|per_second`) while the data\n // still ships `per_1k_chars|per_minute`; trusting the enum bills 0.\n const billingUnit = audioPricing.billingUnit as string\n let quantity: number\n switch (billingUnit) {\n case \"per_1k_chars\":\n quantity = Math.max(0, usage.characters ?? 0) / 1000\n break\n case \"per_character\":\n quantity = Math.max(0, usage.characters ?? 0)\n break\n case \"per_minute\":\n quantity = Math.ceil(Math.max(0, usage.seconds ?? 0) / 60)\n break\n case \"per_second\":\n default:\n quantity = Math.max(0, usage.seconds ?? 0)\n break\n }\n const baseCostUsd = audioPricing.baseCost * quantity\n const perUnitCredits = computeCenticredits({\n baseCostUsd: audioPricing.baseCost,\n category: \"audio\",\n overrideCreditCost: audioPricing.overrideCreditCost,\n appId: opts.appId,\n })\n // Per-call floor (1 cc) so a non-empty call never rounds to 0; a genuinely\n // empty call (quantity 0, e.g. empty-string TTS) bills nothing.\n const credits =\n quantity > 0 ? Math.max(1, Math.ceil(perUnitCredits * quantity)) : 0\n const formulaPerUnit = computeCenticredits({\n baseCostUsd: audioPricing.baseCost,\n category: \"audio\",\n appId: opts.appId,\n })\n const calculatedCredits =\n quantity > 0 ? Math.max(1, Math.ceil(formulaPerUnit * quantity)) : 0\n const markup = pricingRegistry.getMarkup(\"audio\", opts.appId)\n return {\n kind: \"audio\",\n modelId,\n canonicalId: modelId,\n credits,\n calculatedCredits,\n baseCostUsd,\n breakdown: {\n perUnitCredits,\n quantity,\n },\n isFallback: false,\n markup,\n }\n}\n\n// Thin ergonomic wrappers around `calculateCost`. Two reasons they exist:\n// 1. Callers with a known kind don't want to construct the full union.\n// 2. The kind/usage union is a `calculateCost` implementation detail —\n// wrapper types are narrower and easier to read at call sites.\n\nexport function calculateLLMCost(\n modelId: string,\n usage: {\n inputTokens: number\n outputTokens: number\n cacheReadInputTokens?: number\n cacheCreationInputTokens?: number\n },\n opts?: CalculateCostOptions\n): CostResult {\n return calculateCost(modelId, { kind: \"llm\", ...usage }, opts)\n}\n\nexport function calculateImageCost(\n modelId: string,\n usage: { numOutputs?: number },\n opts?: CalculateCostOptions\n): CostResult {\n return calculateCost(modelId, { kind: \"image\", ...usage }, opts)\n}\n\nexport function calculateVideoCost(\n modelId: string,\n usage: { resolution?: string; duration?: number; mode?: string },\n opts?: CalculateCostOptions\n): CostResult {\n return calculateCost(modelId, { kind: \"video\", ...usage }, opts)\n}\n\nexport function calculateAudioCost(\n modelId: string,\n usage: { characters?: number; seconds?: number },\n opts?: CalculateCostOptions\n): CostResult {\n return calculateCost(modelId, { kind: \"audio\", ...usage }, opts)\n}\n"]}
1
+ {"version":3,"sources":["../src/cost/index.ts"],"names":["resolved","baseCostUsd","credits","calculatedCredits","markup"],"mappings":"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","file":"chunk-O6SQMVPM.mjs","sourcesContent":["/**\n * Cost dispatcher — computes credit cost + production USD cost for any\n * model id, regardless of kind. Single entry point used by orchestrator,\n * billing audits, and (eventually) the metered MCP gen layer.\n *\n * Per-kind formulas:\n * - LLM → reuses `calculateLLMCreditCost` (token math + cache + markup)\n * - Image → `creditCost × numOutputs`\n * - Video → `creditCost × multipliers[resolution|duration|mode]`\n * - Audio → `creditCost × (characters or seconds)` per `billingUnit`\n */\n\nimport {\n calculateLLMCreditCost,\n type LLMCreditCostResult,\n} from \"../llm/index.js\"\nimport { getModel } from \"../registry/index.js\"\nimport { computeCenticredits, pricingRegistry } from \"../pricing/index.js\"\n\n/**\n * Voice metadata → default audio model the dispatcher bills through.\n *\n * Voices are render-targets, not priced units. A MiniMax voice can be\n * played through `minimax/speech-02-hd` OR `…-turbo`; an ElevenLabs\n * voice through any of their model tiers. We default to the cheapest\n * model per provider so a drive-by voice-id call doesn't over-bill.\n * Callers wanting HD / premium-tier pricing should pass the audio\n * model id directly with the voice as metadata — see\n * `text-to-speech.tool.ts` for the canonical pattern.\n *\n * Add a new provider here when a new voice catalog lands (e.g.\n * `ELEVENLABS_VOICES` if/when we surface their voice IDs).\n */\nconst VOICE_PROVIDER_DEFAULT_MODEL: Record<string, string> = {\n minimax: \"minimax/speech-02-turbo\",\n elevenlabs: \"elevenlabs/flash-v2.5\",\n}\n\nexport type CostUsage =\n | {\n kind: \"llm\"\n inputTokens: number\n outputTokens: number\n cacheReadInputTokens?: number\n cacheCreationInputTokens?: number\n }\n | { kind: \"image\"; numOutputs?: number }\n | {\n kind: \"video\"\n resolution?: string\n duration?: number\n mode?: string\n }\n | { kind: \"audio\"; characters?: number; seconds?: number }\n\nexport interface CostResult {\n kind: \"llm\" | \"image\" | \"video\" | \"audio\"\n modelId: string\n /** Canonical model id after alias resolution (LLM only; same as modelId for media) */\n canonicalId: string\n /**\n * Total **centicredits** to charge (1 displayed credit = 100 cc).\n * Honors per-model overrides. Feed straight into the ledger — the\n * `credit_transactions.credits` column stores cc, so no `× 100`\n * conversion at the call site. Format for display with\n * `displayCredits(cc) → cr`.\n */\n credits: number\n /**\n * Centicredits the pure formula (provider cost × category markup)\n * would have charged, independent of any per-model override. Equal\n * to `credits` when no override is in play. Surfaced so\n * reconciliation can diff \"what we did\" vs \"what the formula said\"\n * without recomputing — persisted to `usage_events.calculated_credits`.\n */\n calculatedCredits: number\n /** Production cost in USD (provider-side, before markup) */\n baseCostUsd: number\n /** Per-kind breakdown — inputCredits/outputCredits for LLM, etc. All in cc. */\n breakdown: Record<string, number>\n /** True iff fallback pricing was used (currently LLM-only) */\n isFallback: boolean\n /** Markup applied (1.0 = catalog rate as-is) */\n markup: number\n}\n\nexport class UnknownModelError extends Error {\n constructor(public readonly modelId: string) {\n super(`Unknown model id: \"${modelId}\"`)\n this.name = \"UnknownModelError\"\n }\n}\n\nexport class CostUsageKindMismatchError extends Error {\n constructor(\n public readonly modelId: string,\n public readonly expected: string,\n public readonly got: string\n ) {\n super(\n `Model \"${modelId}\" is kind \"${expected}\", but received usage of kind \"${got}\"`\n )\n this.name = \"CostUsageKindMismatchError\"\n }\n}\n\nexport interface CalculateCostOptions {\n /**\n * App that's invoking the model. Routes per-app markup overrides\n * registered via `pricingRegistry.registerApp(appId, ...)`. When\n * omitted, core defaults apply.\n */\n appId?: string\n}\n\n/**\n * Computes credit + USD cost for a model run.\n *\n * Throws `UnknownModelError` for ids not in any catalog (LLM has its own\n * fallback path inside `calculateLLMCreditCost` — this surface preserves\n * that for back-compat).\n *\n * Throws `CostUsageKindMismatchError` if `usage.kind` doesn't match the\n * resolved model's kind (data integrity guard).\n *\n * Image / video / audio credits are derived at call time via the\n * pricing registry (`provider_cost × category-markup`). LLM keeps its\n * own per-model markup table inside `calculateLLMCreditCost` —\n * collapsing that follows in W6b.\n */\nexport function calculateCost(\n modelId: string,\n usage: CostUsage,\n opts: CalculateCostOptions = {}\n): CostResult {\n // LLM has a fallback path that returns valid pricing even for unknown\n // ids (preserves the orchestrator's existing tolerance). Other kinds\n // throw for unknowns.\n if (usage.kind === \"llm\") {\n const llmResult: LLMCreditCostResult = calculateLLMCreditCost(modelId, {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n cacheReadInputTokens: usage.cacheReadInputTokens,\n cacheCreationInputTokens: usage.cacheCreationInputTokens,\n })\n const resolved = getModel(modelId)\n const canonicalId =\n resolved && resolved.kind === \"llm\" ? resolved.canonicalId : modelId\n return {\n kind: \"llm\",\n modelId,\n canonicalId,\n credits: llmResult.credits,\n calculatedCredits: llmResult.calculatedCredits,\n baseCostUsd: llmResult.productionCost,\n breakdown: {\n inputCredits: llmResult.inputCredits,\n outputCredits: llmResult.outputCredits,\n cacheReadCredits: llmResult.cacheReadCredits,\n cacheWriteCredits: llmResult.cacheWriteCredits,\n },\n isFallback: llmResult.isFallback,\n markup: llmResult.markup,\n }\n }\n\n const resolved = getModel(modelId)\n if (!resolved) throw new UnknownModelError(modelId)\n // `voice` is structurally audio for billing purposes (MiniMax voice\n // metadata billed via per-character output). Accept `audio` usage on\n // voice models so the per-kind branches below can pattern-match.\n const expectedUsageKind: CostUsage[\"kind\"] =\n resolved.kind === \"voice\" ? \"audio\" : resolved.kind\n if (expectedUsageKind !== usage.kind) {\n // Pass `expectedUsageKind` (not `resolved.kind`) so the error message\n // accurately says \"audio\" rather than \"voice\" when a voice model is\n // billed — the caller must supply audio usage, not voice usage.\n throw new CostUsageKindMismatchError(modelId, expectedUsageKind, usage.kind)\n }\n\n if (resolved.kind === \"image\") {\n // `usage.kind` is \"image\" here (guarded above) but TS won't cross-narrow\n // it from `resolved.kind`, so check explicitly before reading numOutputs.\n const numOutputs = Math.max(\n 1,\n usage.kind === \"image\" ? (usage.numOutputs ?? 1) : 1\n )\n const baseCostUsd = resolved.def.pricing.baseCost * numOutputs\n const perOutputCredits = computeCenticredits({\n baseCostUsd: resolved.def.pricing.baseCost,\n category: \"image\",\n overrideCreditCost: resolved.def.pricing.overrideCreditCost,\n appId: opts.appId,\n })\n const credits = perOutputCredits * numOutputs\n // Formula-only (ignores override) — for `usage_events.calculated_credits`.\n const formulaPerOutput = computeCenticredits({\n baseCostUsd: resolved.def.pricing.baseCost,\n category: \"image\",\n appId: opts.appId,\n })\n const calculatedCredits = formulaPerOutput * numOutputs\n const markup = pricingRegistry.getMarkup(\"image\", opts.appId)\n return {\n kind: \"image\",\n modelId,\n canonicalId: modelId,\n credits,\n calculatedCredits,\n baseCostUsd,\n breakdown: {\n perOutputCredits,\n numOutputs,\n },\n isFallback: false,\n markup,\n }\n }\n\n if (resolved.kind === \"video\") {\n if (usage.kind !== \"video\") {\n throw new CostUsageKindMismatchError(modelId, \"video\", usage.kind)\n }\n const pricing = resolved.def.pricing\n // Provider-side multipliers — re-applied to BOTH the provider cost\n // (what we pay) AND the derived credit cost (so margin holds).\n const mult = pricing.multipliers\n const resMult =\n usage.resolution && mult?.resolution\n ? (mult.resolution[usage.resolution] ?? 1.0)\n : 1.0\n const durMult =\n usage.duration && mult?.duration\n ? (mult.duration[usage.duration] ?? 1.0)\n : 1.0\n const modMult =\n usage.mode && mult?.mode ? (mult.mode[usage.mode] ?? 1.0) : 1.0\n const variantMultiplier = resMult * durMult * modMult\n const baseCostUsd = pricing.baseCost * variantMultiplier\n const perClipCredits = computeCenticredits({\n baseCostUsd: pricing.baseCost,\n category: \"video\",\n overrideCreditCost: pricing.overrideCreditCost,\n appId: opts.appId,\n })\n const credits = Math.ceil(perClipCredits * variantMultiplier)\n const formulaPerClip = computeCenticredits({\n baseCostUsd: pricing.baseCost,\n category: \"video\",\n appId: opts.appId,\n })\n const calculatedCredits = Math.ceil(formulaPerClip * variantMultiplier)\n const markup = pricingRegistry.getMarkup(\"video\", opts.appId)\n return {\n kind: \"video\",\n modelId,\n canonicalId: modelId,\n credits,\n calculatedCredits,\n baseCostUsd,\n breakdown: {\n perClipCredits,\n resolutionMultiplier: resMult,\n durationMultiplier: durMult,\n modeMultiplier: modMult,\n variantMultiplier,\n },\n isFallback: false,\n markup,\n }\n }\n\n // Audio (and voice, delegated as audio — see expectedUsageKind above).\n if (usage.kind !== \"audio\") {\n throw new CostUsageKindMismatchError(modelId, \"audio\", usage.kind)\n }\n\n if (resolved.kind === \"voice\") {\n // Voice rows are metadata; delegate to the provider's default audio model.\n const provider = resolved.voice.provider\n const delegateModelId = VOICE_PROVIDER_DEFAULT_MODEL[provider]\n if (!delegateModelId) throw new UnknownModelError(modelId)\n const delegateResult = calculateCost(delegateModelId, usage, opts)\n return {\n ...delegateResult,\n modelId,\n canonicalId: delegateModelId,\n }\n }\n\n // Only `audio` remains (llm returned at top; image/video/voice handled\n // above). Narrow explicitly so `.def` is type-safe.\n if (resolved.kind !== \"audio\") throw new UnknownModelError(modelId)\n const audioPricing = resolved.def.pricing\n // Map the provider's billing unit to a quantity of billable units.\n // The catalog DATA uses `per_1k_chars` (chars ÷ 1000) and `per_minute`\n // (whole minutes, rounded UP to match provider invoicing). `per_character`\n // / `per_second` are handled too so a future data migration to those units\n // keeps working. NOTE: do not switch on the zod enum value alone — the\n // audio schema enum is stale (`per_character|per_second`) while the data\n // still ships `per_1k_chars|per_minute`; trusting the enum bills 0.\n const billingUnit = audioPricing.billingUnit as string\n let quantity: number\n switch (billingUnit) {\n case \"per_1k_chars\":\n quantity = Math.max(0, usage.characters ?? 0) / 1000\n break\n case \"per_character\":\n quantity = Math.max(0, usage.characters ?? 0)\n break\n case \"per_minute\":\n quantity = Math.ceil(Math.max(0, usage.seconds ?? 0) / 60)\n break\n case \"per_second\":\n default:\n quantity = Math.max(0, usage.seconds ?? 0)\n break\n }\n const baseCostUsd = audioPricing.baseCost * quantity\n const perUnitCredits = computeCenticredits({\n baseCostUsd: audioPricing.baseCost,\n category: \"audio\",\n overrideCreditCost: audioPricing.overrideCreditCost,\n appId: opts.appId,\n })\n // Per-call floor (1 cc) so a non-empty call never rounds to 0; a genuinely\n // empty call (quantity 0, e.g. empty-string TTS) bills nothing.\n const credits =\n quantity > 0 ? Math.max(1, Math.ceil(perUnitCredits * quantity)) : 0\n const formulaPerUnit = computeCenticredits({\n baseCostUsd: audioPricing.baseCost,\n category: \"audio\",\n appId: opts.appId,\n })\n const calculatedCredits =\n quantity > 0 ? Math.max(1, Math.ceil(formulaPerUnit * quantity)) : 0\n const markup = pricingRegistry.getMarkup(\"audio\", opts.appId)\n return {\n kind: \"audio\",\n modelId,\n canonicalId: modelId,\n credits,\n calculatedCredits,\n baseCostUsd,\n breakdown: {\n perUnitCredits,\n quantity,\n },\n isFallback: false,\n markup,\n }\n}\n\n// Thin ergonomic wrappers around `calculateCost`. Two reasons they exist:\n// 1. Callers with a known kind don't want to construct the full union.\n// 2. The kind/usage union is a `calculateCost` implementation detail —\n// wrapper types are narrower and easier to read at call sites.\n\nexport function calculateLLMCost(\n modelId: string,\n usage: {\n inputTokens: number\n outputTokens: number\n cacheReadInputTokens?: number\n cacheCreationInputTokens?: number\n },\n opts?: CalculateCostOptions\n): CostResult {\n return calculateCost(modelId, { kind: \"llm\", ...usage }, opts)\n}\n\nexport function calculateImageCost(\n modelId: string,\n usage: { numOutputs?: number },\n opts?: CalculateCostOptions\n): CostResult {\n return calculateCost(modelId, { kind: \"image\", ...usage }, opts)\n}\n\nexport function calculateVideoCost(\n modelId: string,\n usage: { resolution?: string; duration?: number; mode?: string },\n opts?: CalculateCostOptions\n): CostResult {\n return calculateCost(modelId, { kind: \"video\", ...usage }, opts)\n}\n\nexport function calculateAudioCost(\n modelId: string,\n usage: { characters?: number; seconds?: number },\n opts?: CalculateCostOptions\n): CostResult {\n return calculateCost(modelId, { kind: \"audio\", ...usage }, opts)\n}\n"]}
@@ -1,9 +1,21 @@
1
+ import { OPENCODE_GO_ROUTES, OPENCODE_ZEN_ROUTES, OPENCODE_GO_ANTHROPIC_MODELS, OPENCODE_ZEN_ANTHROPIC_MODELS } from './chunk-I5E7F6KY.mjs';
2
+
1
3
  /**
2
4
  * @agentproto/model-catalog v0.1.0
3
5
  * Unified model catalog: LLM, image, video, audio entries + cost dispatcher + picker.
4
6
  * Zod-only OSS core; @agstudio/model-catalog layers billing/access/BYOK on top.
5
7
  */
6
8
 
9
+ // src/llm/opencode.ts
10
+ function listOpencodeModelRefs(endpoint) {
11
+ const routes = endpoint === "opencode-go" ? OPENCODE_GO_ROUTES : OPENCODE_ZEN_ROUTES;
12
+ return Object.keys(routes).sort();
13
+ }
14
+ function listOpencodeAnthropicModelRefs(endpoint) {
15
+ const bareIds = endpoint === "opencode-go" ? OPENCODE_GO_ANTHROPIC_MODELS : OPENCODE_ZEN_ANTHROPIC_MODELS;
16
+ return bareIds.map((id) => `${endpoint}/${id}`).sort();
17
+ }
18
+
7
19
  // src/llm/tokens.ts
8
20
  function formatTokens(n) {
9
21
  if (typeof n !== "number" || n <= 0) return null;
@@ -63,6 +75,6 @@ var LLM_TIERS = {
63
75
  ]
64
76
  };
65
77
 
66
- export { LLM_TIERS, OPERATOR_AGENT_MODELS, OPERATOR_DEFAULT_GEMINI, OPERATOR_DEFAULT_PREMIUM, OPERATOR_DEFAULT_STANDARD, WORKFLOW_FAST_MODEL, WORKFLOW_PREMIUM_MODEL, WORKFLOW_TINY_MODEL, formatTokens };
67
- //# sourceMappingURL=chunk-ZTTWZ7PL.mjs.map
68
- //# sourceMappingURL=chunk-ZTTWZ7PL.mjs.map
78
+ export { LLM_TIERS, OPERATOR_AGENT_MODELS, OPERATOR_DEFAULT_GEMINI, OPERATOR_DEFAULT_PREMIUM, OPERATOR_DEFAULT_STANDARD, WORKFLOW_FAST_MODEL, WORKFLOW_PREMIUM_MODEL, WORKFLOW_TINY_MODEL, formatTokens, listOpencodeAnthropicModelRefs, listOpencodeModelRefs };
79
+ //# sourceMappingURL=chunk-TC6S3SY3.mjs.map
80
+ //# sourceMappingURL=chunk-TC6S3SY3.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/llm/opencode.ts","../src/llm/tokens.ts","../src/llm/defaults.ts"],"names":[],"mappings":";;;;;;;;;AAiCO,SAAS,sBAAsB,QAAA,EAAsC;AAC1E,EAAA,MAAM,MAAA,GAAS,QAAA,KAAa,aAAA,GAAgB,kBAAA,GAAqB,mBAAA;AACjE,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,IAAA,EAAK;AAClC;AAkBO,SAAS,+BAA+B,QAAA,EAAsC;AACnF,EAAA,MAAM,OAAA,GACJ,QAAA,KAAa,aAAA,GAAgB,4BAAA,GAA+B,6BAAA;AAC9D,EAAA,OAAO,OAAA,CAAQ,IAAI,CAAA,EAAA,KAAM,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,EAAE,CAAA,CAAE,CAAA,CAAE,IAAA,EAAK;AACrD;;;ACjDO,SAAS,aAAa,CAAA,EAAsC;AACjE,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,IAAK,GAAG,OAAO,IAAA;AAC5C,EAAA,IAAI,KAAK,GAAA,EAAW;AAClB,IAAA,MAAM,IAAI,CAAA,GAAI,GAAA;AACd,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,SAAA,CAAU,CAAC,CAAA,GAAI,OAAO,CAAC,CAAA,GAAI,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAC1D,IAAA,OAAO,GAAG,IAAI,CAAA,CAAA,CAAA;AAAA,EAChB;AACA,EAAA,IAAI,KAAK,GAAA,EAAO;AACd,IAAA,MAAM,IAAI,CAAA,GAAI,GAAA;AACd,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,SAAA,CAAU,CAAC,CAAA,GAAI,OAAO,CAAC,CAAA,GAAI,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAC1D,IAAA,OAAO,GAAG,IAAI,CAAA,CAAA,CAAA;AAAA,EAChB;AACA,EAAA,OAAO,OAAO,CAAC,CAAA;AACjB;;;ACRO,IAAM,mBAAA,GAAsB;AAG5B,IAAM,sBAAA,GAAyB;AAG/B,IAAM,mBAAA,GAAsB;AAO5B,IAAM,qBAAA,GAAwB;AAAA,EACnC,iBAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF;AAKO,IAAM,wBAAA,GAA+C;AACrD,IAAM,yBAAA,GAAgD;AACtD,IAAM,uBAAA,GACX;AAcK,IAAM,SAAA,GAAY;AAAA;AAAA,EAEvB,IAAA,EAAM,CAAC,+BAA+B,CAAA;AAAA;AAAA,EAEtC,IAAA,EAAM;AAAA,IACJ,cAAA;AAAA,IACA,cAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACF;AAAA;AAAA,EAEA,IAAA,EAAM;AAAA,IACJ,kBAAA;AAAA,IACA,sBAAA;AAAA,IACA;AAAA,GACF;AAAA;AAAA,EAEA,IAAA,EAAM;AAAA,IACJ,mBAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACF;AAAA;AAAA,EAEA,GAAA,EAAK;AAAA,IACH,iBAAA;AAAA,IACA,+BAAA;AAAA,IACA;AAAA;AAEJ","file":"chunk-TC6S3SY3.mjs","sourcesContent":["/**\n * OpenCode's two hosted endpoints — the small hand-written surface over their\n * generated route tables.\n *\n * Deliberately its OWN module rather than an addition to `catalog.ts`: that\n * file owns `LLM_PRICING_CATALOG`, and the one invariant these tables have is\n * that they are NEVER spread into it (a bare `claude-sonnet-5` must keep\n * meaning direct Anthropic, not a Zen-priced route — see the OpenCode branch\n * in `route-identity/index.ts`). Keeping the import out of `catalog.ts`\n * keeps that temptation out of reach.\n */\n\nimport {\n OPENCODE_GO_ANTHROPIC_MODELS,\n OPENCODE_GO_ROUTES,\n} from \"./opencode-go-routes.generated.js\"\nimport {\n OPENCODE_ZEN_ANTHROPIC_MODELS,\n OPENCODE_ZEN_ROUTES,\n} from \"./opencode-zen-routes.generated.js\"\n\n/**\n * The two OpenCode hosted endpoints, by catalog provider id.\n * - `\"opencode\"` — OpenCode Zen, pay-as-you-go (`.../zen/v1`).\n * - `\"opencode-go\"` — OpenCode Go, the flat subscription (`.../zen/go/v1`).\n */\nexport type OpencodeEndpoint = \"opencode\" | \"opencode-go\"\n\n/**\n * Every model ref an OpenCode endpoint serves, in the `<provider>/<bare-id>`\n * form the route tables are keyed by — which is also opencode's own config\n * spelling and what a caller passes to `agent_start`.\n */\nexport function listOpencodeModelRefs(endpoint: OpencodeEndpoint): string[] {\n const routes = endpoint === \"opencode-go\" ? OPENCODE_GO_ROUTES : OPENCODE_ZEN_ROUTES\n return Object.keys(routes).sort()\n}\n\n/**\n * The subset of {@link listOpencodeModelRefs} whose wire surface is the\n * Anthropic Messages API — exactly what the matching `opencode` /\n * `opencode-go` gateway preset can serve, and therefore exactly what an\n * Anthropic-native adapter (claude-code / claude-sdk) may offer on that\n * route. Both endpoints also serve OpenAI chat/completions, OpenAI Responses\n * and (Zen only) Gemini models behind the same base URL; those are\n * unreachable from an Anthropic client and are excluded here.\n *\n * Derived from the generated `*_ANTHROPIC_MODELS` lists, which come from the\n * source's own per-model `provider.npm` discriminator — so an adapter menu\n * built on this can never drift into offering an id the endpoint won't answer\n * on `/v1/messages`, and a newly-added Anthropic-surface model becomes\n * offerable on the next catalog-sync run with no code change (the same\n * rationale as `listNativeModelIds`).\n */\nexport function listOpencodeAnthropicModelRefs(endpoint: OpencodeEndpoint): string[] {\n const bareIds =\n endpoint === \"opencode-go\" ? OPENCODE_GO_ANTHROPIC_MODELS : OPENCODE_ZEN_ANTHROPIC_MODELS\n return bareIds.map(id => `${endpoint}/${id}`).sort()\n}\n","/**\n * Shared human-readable token formatting, so the `agentproto models` CLI and\n * the `catalog_models` MCP tool render the same `1M`/`200k` shapes instead of\n * raw integers. Lives next to `resolveContextWindow` (its data source) — one\n * formatter per concept, both output surfaces consume it.\n */\n\n/** Format a token count compactly — `1M`, `500k`, `2k`, `448`. Undefined ⇒\n * null so JSON output omits rather than fabricates a value. */\nexport function formatTokens(n: number | undefined): string | null {\n if (typeof n !== \"number\" || n <= 0) return null\n if (n >= 1_000_000) {\n const m = n / 1_000_000\n const text = Number.isInteger(m) ? String(m) : m.toFixed(1)\n return `${text}M`\n }\n if (n >= 1_000) {\n const k = n / 1_000\n const text = Number.isInteger(k) ? String(k) : k.toFixed(1)\n return `${text}k`\n }\n return String(n)\n}\n","/**\n * Curated, SDK-ready LLM model ids.\n *\n * Centralizes the version-specific provider ids used at runtime so call\n * sites stop carrying string literals. Pricing for each is resolved\n * automatically through `MODEL_ALIASES` in `catalog.ts` (e.g.\n * `claude-sonnet-4-6` → `claude-sonnet-4-5`).\n *\n * Update one constant here when bumping the platform-wide default —\n * every workflow step and operator config picks up the new id with a\n * single rebuild.\n */\n\n/** Fast workhorse for content workflows (outline, post, sections). */\nexport const WORKFLOW_FAST_MODEL = \"claude-sonnet-4-6\" as const\n\n/** Premium tier for high-stakes generation (rarely used in workflows). */\nexport const WORKFLOW_PREMIUM_MODEL = \"claude-opus-4-6\" as const\n\n/** Cheap-and-quick for short outputs like titles. */\nexport const WORKFLOW_TINY_MODEL = \"claude-haiku-4-5-20251001\" as const\n\n/**\n * Models eligible for operator agents (an app). Keep in sync with the\n * agent-framework's model-provider config. The literal tuple drives the\n * `OperatorAgentModel` union type below.\n */\nexport const OPERATOR_AGENT_MODELS = [\n \"claude-opus-4-5\",\n \"claude-sonnet-4-5\",\n \"gemini-3.1-pro-preview\",\n] as const\n\nexport type OperatorAgentModel = (typeof OPERATOR_AGENT_MODELS)[number]\n\n/** Default operator model when no explicit choice is made. */\nexport const OPERATOR_DEFAULT_PREMIUM: OperatorAgentModel = \"claude-opus-4-5\"\nexport const OPERATOR_DEFAULT_STANDARD: OperatorAgentModel = \"claude-sonnet-4-5\"\nexport const OPERATOR_DEFAULT_GEMINI: OperatorAgentModel =\n \"gemini-3.1-pro-preview\"\n\n// ── Plan-tier → model lists ─────────────────────────────────────────────\n//\n// Catalog-canonical equivalent of agent-framework's `MODEL_TIERS`. Used\n// by per-app `AppPlanRegistry` files as the source list when a plan\n// surfaces \"all of the X tier\". Keeping this in the catalog keeps the\n// app registries declarative — they pick from `LLM_TIERS.plus` rather\n// than re-specifying ids.\n//\n// All ids resolve through `resolvePricing` (direct match → alias →\n// partial-prefix). Names are app-vocabulary-neutral; per-app registries\n// re-key as needed (`PaygoTier.nano` → `LLM_TIERS.nano`, etc.).\n\nexport const LLM_TIERS = {\n /** Cheap-and-quick. Single-model fallback. */\n nano: [\"mistral-small-creative-latest\"] as const,\n /** Low-cost, agentic-capable. Direct alt-providers. */\n mini: [\n \"MiniMax-M2.5\",\n \"MiniMax-M2.1\",\n \"MiniMax-M2\",\n \"mistral-large-latest\",\n ] as const,\n /** Medium cost, fast inference + good general perf. OpenRouter-routed. */\n lite: [\n \"x-ai/grok-4-fast\",\n \"xiaomi/mimo-v2-flash\",\n \"google/gemini-3-flash-preview\",\n ] as const,\n /** High quality, premium features. Mix of direct + OpenRouter. */\n plus: [\n \"claude-sonnet-4-5\",\n \"gpt-4o\",\n \"kimi-k2.5\",\n \"deepseek/deepseek-v3.2\",\n ] as const,\n /** Top-tier, best performance. */\n pro: [\n \"claude-opus-4-5\",\n \"google/gemini-3.1-pro-preview\",\n \"kimi-k2-thinking\",\n ] as const,\n} as const\n\nexport type LlmTierName = keyof typeof LLM_TIERS\n"]}
@@ -1,4 +1,4 @@
1
- import { baseEntryShape } from './chunk-QNJRWRWC.mjs';
1
+ import { baseEntryShape } from './chunk-WG4F6IRS.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-3Y5TQDGE.mjs.map
152
- //# sourceMappingURL=chunk-3Y5TQDGE.mjs.map
151
+ //# sourceMappingURL=chunk-TTIJME5T.mjs.map
152
+ //# sourceMappingURL=chunk-TTIJME5T.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-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
+ {"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-TTIJME5T.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,5 +1,5 @@
1
- import { listModels } from './chunk-JHBSGPWH.mjs';
2
- import { modelHasTag } from './chunk-H467PHUU.mjs';
1
+ import { listModels } from './chunk-E5CVTRPJ.mjs';
2
+ import { modelHasTag } from './chunk-B67THXMQ.mjs';
3
3
 
4
4
  /**
5
5
  * @agentproto/model-catalog v0.1.0
@@ -130,5 +130,5 @@ function filterVoicesByProviders(voices, providerTokens) {
130
130
  }
131
131
 
132
132
  export { applyProfile, expandProviders, filterVoicesByProviders, getProviderGroup, getSurfaceProfile, groupForProvider, listProviderGroups, listSurfaceProfiles, listSurfaced, modelMatchesProfile };
133
- //# sourceMappingURL=chunk-UREM2UZK.mjs.map
134
- //# sourceMappingURL=chunk-UREM2UZK.mjs.map
133
+ //# sourceMappingURL=chunk-UZDL26T7.mjs.map
134
+ //# sourceMappingURL=chunk-UZDL26T7.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/curation/index.ts"],"names":[],"mappings":"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","file":"chunk-UREM2UZK.mjs","sourcesContent":["/**\n * Curation — what an app SURFACES from the catalog, distinct from\n * model-access (who MAY use a model: tier/scope policy). Curation is the\n * \"feature/provider catalog\" layer: an app composes views over the one\n * registry (\"all s2s voices from OpenAI OR Google\", \"images only\", …)\n * without touching the underlying data.\n *\n * Two registries, both following the canonical profile-registry shape\n * (`listX()` / `getX(id)` throwing with the known-id list):\n *\n * 1. PROVIDER GROUPS — a company (`openai`) maps to every provider tag\n * it owns across kinds (`openai` for the LLM/audio company tag,\n * `openai-realtime` for its voice engine). This is what reconciles\n * the two provider vocabularies in the registry: audio MODELS are\n * tagged by company, voices by engine. Curating by group spans both.\n *\n * 2. SURFACE PROFILES — named presets (`voice-s2s`, `images`, …) an app\n * selects from. Permissive by default (`all`); apps narrow only when\n * a picker should diverge.\n *\n * Selection precedence (caller's job): per-call arg → per-app/guild\n * config → env → `all` fallback.\n */\n\nimport {\n listModels,\n type CatalogKind,\n type ResolvedModel,\n} from \"../registry/index.js\"\nimport { modelHasTag } from \"../enrichment/index.js\"\nimport type { CatalogVoice } from \"../schema/voice.js\"\n\n// ───────────────────────────────────────────────────────────────────────\n// Provider groups — company → provider tags across kinds\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface ProviderGroup {\n /** Canonical company id, e.g. \"openai\", \"google\". */\n id: string\n /** Display label. */\n label: string\n /**\n * Every provider tag this company owns across kinds. Audio/image/LLM use\n * the company tag (`openai`); the voice engine uses its own (`openai-realtime`).\n */\n providers: readonly string[]\n}\n\nconst PROVIDER_GROUPS: readonly ProviderGroup[] = [\n { id: \"openai\", label: \"OpenAI\", providers: [\"openai\", \"openai-realtime\"] },\n { id: \"google\", label: \"Google\", providers: [\"google\", \"gemini-live\"] },\n { id: \"anthropic\", label: \"Anthropic\", providers: [\"anthropic\"] },\n { id: \"minimax\", label: \"MiniMax\", providers: [\"minimax\"] },\n { id: \"elevenlabs\", label: \"ElevenLabs\", providers: [\"elevenlabs\"] },\n { id: \"replicate\", label: \"Replicate\", providers: [\"replicate\"] },\n { id: \"deepgram\", label: \"Deepgram\", providers: [\"deepgram\"] },\n { id: \"assemblyai\", label: \"AssemblyAI\", providers: [\"assemblyai\"] },\n]\n\nexport function listProviderGroups(): readonly ProviderGroup[] {\n return PROVIDER_GROUPS\n}\n\nexport function getProviderGroup(id: string): ProviderGroup {\n const group = PROVIDER_GROUPS.find(g => g.id === id)\n if (!group) {\n const known = PROVIDER_GROUPS.map(g => g.id).join(\", \")\n throw new Error(`curation: unknown provider group \"${id}\". Known: ${known}`)\n }\n return group\n}\n\n/** The group that owns a raw provider tag, if any. */\nexport function groupForProvider(\n providerTag: string\n): ProviderGroup | undefined {\n return PROVIDER_GROUPS.find(g => g.providers.includes(providerTag))\n}\n\n/**\n * Expand a mixed list of provider-group ids and raw provider tags into the\n * flat set of provider tags to match against. A token that is a known\n * group id expands to its members; anything else passes through as a raw\n * tag (so callers can target an engine directly, e.g. `gemini-live`).\n */\nexport function expandProviders(tokens: readonly string[]): string[] {\n const out = new Set<string>()\n for (const token of tokens) {\n const group = PROVIDER_GROUPS.find(g => g.id === token)\n if (group) {\n for (const p of group.providers) out.add(p)\n } else {\n out.add(token)\n }\n }\n return [...out]\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Surface profiles — named views an app surfaces\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface SurfaceProfile {\n id: string\n description: string\n /** Restrict to these kinds. Undefined/empty = every kind. */\n kinds?: readonly CatalogKind[]\n /**\n * Restrict to these provider GROUP ids or raw provider tags (OR-set).\n * Expanded via `expandProviders`, so `[\"openai\"]` covers both the\n * `openai` company tag and the `openai-realtime` voice engine.\n */\n providers?: readonly string[]\n /** Require all of these capability tags (AND-set): `s2s`, `tts`, `edit`, … */\n capabilities?: readonly string[]\n /** Require all of these arbitrary tags (AND-set). */\n tags?: readonly string[]\n}\n\nconst SURFACE_PROFILES: readonly SurfaceProfile[] = [\n {\n id: \"all\",\n description: \"Everything the catalog offers — the permissive default\",\n },\n {\n id: \"text\",\n description: \"Text models (LLMs) only\",\n kinds: [\"llm\"],\n },\n {\n id: \"images\",\n description: \"Image models only\",\n kinds: [\"image\"],\n },\n {\n id: \"video\",\n description: \"Video models only\",\n kinds: [\"video\"],\n },\n {\n id: \"audio\",\n description: \"Audio models (TTS / STT / s2s) only\",\n kinds: [\"audio\"],\n },\n {\n id: \"voice\",\n description: \"Every curated voice, any provider\",\n kinds: [\"voice\"],\n },\n {\n id: \"voice-s2s\",\n description:\n \"Speech-to-speech voice engines (OpenAI Realtime, Gemini Live)\",\n kinds: [\"voice\"],\n capabilities: [\"s2s\"],\n },\n {\n id: \"voice-tts\",\n description: \"Sequential TTS voices (MiniMax, ElevenLabs)\",\n kinds: [\"voice\"],\n capabilities: [\"tts\"],\n },\n]\n\nexport function listSurfaceProfiles(): readonly SurfaceProfile[] {\n return SURFACE_PROFILES\n}\n\nexport function getSurfaceProfile(id: string): SurfaceProfile {\n const profile = SURFACE_PROFILES.find(p => p.id === id)\n if (!profile) {\n const known = SURFACE_PROFILES.map(p => p.id).join(\", \")\n throw new Error(\n `curation: unknown surface profile \"${id}\". Known: ${known}`\n )\n }\n return profile\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Filters\n// ───────────────────────────────────────────────────────────────────────\n\n/**\n * True iff a model passes a surface profile. Provider membership, like\n * capability/tag membership, is checked against the enrichment tag\n * vocabulary (every kind emits its provider as a tag), so this is uniform\n * across kinds and naturally spans the company/engine provider split.\n */\nexport function modelMatchesProfile(\n model: ResolvedModel,\n profile: SurfaceProfile\n): boolean {\n if (profile.kinds && profile.kinds.length > 0) {\n if (!profile.kinds.includes(model.kind)) return false\n }\n if (profile.providers && profile.providers.length > 0) {\n const tags = expandProviders(profile.providers)\n if (!tags.some(tag => modelHasTag(model, tag))) return false\n }\n if (profile.capabilities) {\n if (!profile.capabilities.every(cap => modelHasTag(model, cap)))\n return false\n }\n if (profile.tags) {\n if (!profile.tags.every(tag => modelHasTag(model, tag))) return false\n }\n return true\n}\n\n/** Filter a model list down to what a surface profile exposes. */\nexport function applyProfile(\n models: ResolvedModel[],\n profile: SurfaceProfile\n): ResolvedModel[] {\n return models.filter(model => modelMatchesProfile(model, profile))\n}\n\n/**\n * The catalog as a surface profile exposes it — `applyProfile` over the\n * full registry. The composable entry point for \"show me this view\".\n */\nexport function listSurfaced(profile: SurfaceProfile): ResolvedModel[] {\n return applyProfile(listModels(), profile)\n}\n\n/**\n * Voice-list curation. The merged voice catalog (curated + live\n * ElevenLabs) is `CatalogVoice[]`, not `ResolvedModel[]`, so it gets its\n * own provider filter — same group-expansion semantics. Only the provider\n * facet of a profile applies to a raw voice list (kind is implicitly\n * voice; capability/tag live on the registry projection).\n */\nexport function filterVoicesByProviders(\n voices: CatalogVoice[],\n providerTokens: readonly string[]\n): CatalogVoice[] {\n if (providerTokens.length === 0) return voices\n const tags = new Set(expandProviders(providerTokens))\n return voices.filter(v => tags.has(v.provider))\n}\n"]}
1
+ {"version":3,"sources":["../src/curation/index.ts"],"names":[],"mappings":"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","file":"chunk-UZDL26T7.mjs","sourcesContent":["/**\n * Curation — what an app SURFACES from the catalog, distinct from\n * model-access (who MAY use a model: tier/scope policy). Curation is the\n * \"feature/provider catalog\" layer: an app composes views over the one\n * registry (\"all s2s voices from OpenAI OR Google\", \"images only\", …)\n * without touching the underlying data.\n *\n * Two registries, both following the canonical profile-registry shape\n * (`listX()` / `getX(id)` throwing with the known-id list):\n *\n * 1. PROVIDER GROUPS — a company (`openai`) maps to every provider tag\n * it owns across kinds (`openai` for the LLM/audio company tag,\n * `openai-realtime` for its voice engine). This is what reconciles\n * the two provider vocabularies in the registry: audio MODELS are\n * tagged by company, voices by engine. Curating by group spans both.\n *\n * 2. SURFACE PROFILES — named presets (`voice-s2s`, `images`, …) an app\n * selects from. Permissive by default (`all`); apps narrow only when\n * a picker should diverge.\n *\n * Selection precedence (caller's job): per-call arg → per-app/guild\n * config → env → `all` fallback.\n */\n\nimport {\n listModels,\n type CatalogKind,\n type ResolvedModel,\n} from \"../registry/index.js\"\nimport { modelHasTag } from \"../enrichment/index.js\"\nimport type { CatalogVoice } from \"../schema/voice.js\"\n\n// ───────────────────────────────────────────────────────────────────────\n// Provider groups — company → provider tags across kinds\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface ProviderGroup {\n /** Canonical company id, e.g. \"openai\", \"google\". */\n id: string\n /** Display label. */\n label: string\n /**\n * Every provider tag this company owns across kinds. Audio/image/LLM use\n * the company tag (`openai`); the voice engine uses its own (`openai-realtime`).\n */\n providers: readonly string[]\n}\n\nconst PROVIDER_GROUPS: readonly ProviderGroup[] = [\n { id: \"openai\", label: \"OpenAI\", providers: [\"openai\", \"openai-realtime\"] },\n { id: \"google\", label: \"Google\", providers: [\"google\", \"gemini-live\"] },\n { id: \"anthropic\", label: \"Anthropic\", providers: [\"anthropic\"] },\n { id: \"minimax\", label: \"MiniMax\", providers: [\"minimax\"] },\n { id: \"elevenlabs\", label: \"ElevenLabs\", providers: [\"elevenlabs\"] },\n { id: \"replicate\", label: \"Replicate\", providers: [\"replicate\"] },\n { id: \"deepgram\", label: \"Deepgram\", providers: [\"deepgram\"] },\n { id: \"assemblyai\", label: \"AssemblyAI\", providers: [\"assemblyai\"] },\n]\n\nexport function listProviderGroups(): readonly ProviderGroup[] {\n return PROVIDER_GROUPS\n}\n\nexport function getProviderGroup(id: string): ProviderGroup {\n const group = PROVIDER_GROUPS.find(g => g.id === id)\n if (!group) {\n const known = PROVIDER_GROUPS.map(g => g.id).join(\", \")\n throw new Error(`curation: unknown provider group \"${id}\". Known: ${known}`)\n }\n return group\n}\n\n/** The group that owns a raw provider tag, if any. */\nexport function groupForProvider(\n providerTag: string\n): ProviderGroup | undefined {\n return PROVIDER_GROUPS.find(g => g.providers.includes(providerTag))\n}\n\n/**\n * Expand a mixed list of provider-group ids and raw provider tags into the\n * flat set of provider tags to match against. A token that is a known\n * group id expands to its members; anything else passes through as a raw\n * tag (so callers can target an engine directly, e.g. `gemini-live`).\n */\nexport function expandProviders(tokens: readonly string[]): string[] {\n const out = new Set<string>()\n for (const token of tokens) {\n const group = PROVIDER_GROUPS.find(g => g.id === token)\n if (group) {\n for (const p of group.providers) out.add(p)\n } else {\n out.add(token)\n }\n }\n return [...out]\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Surface profiles — named views an app surfaces\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface SurfaceProfile {\n id: string\n description: string\n /** Restrict to these kinds. Undefined/empty = every kind. */\n kinds?: readonly CatalogKind[]\n /**\n * Restrict to these provider GROUP ids or raw provider tags (OR-set).\n * Expanded via `expandProviders`, so `[\"openai\"]` covers both the\n * `openai` company tag and the `openai-realtime` voice engine.\n */\n providers?: readonly string[]\n /** Require all of these capability tags (AND-set): `s2s`, `tts`, `edit`, … */\n capabilities?: readonly string[]\n /** Require all of these arbitrary tags (AND-set). */\n tags?: readonly string[]\n}\n\nconst SURFACE_PROFILES: readonly SurfaceProfile[] = [\n {\n id: \"all\",\n description: \"Everything the catalog offers — the permissive default\",\n },\n {\n id: \"text\",\n description: \"Text models (LLMs) only\",\n kinds: [\"llm\"],\n },\n {\n id: \"images\",\n description: \"Image models only\",\n kinds: [\"image\"],\n },\n {\n id: \"video\",\n description: \"Video models only\",\n kinds: [\"video\"],\n },\n {\n id: \"audio\",\n description: \"Audio models (TTS / STT / s2s) only\",\n kinds: [\"audio\"],\n },\n {\n id: \"voice\",\n description: \"Every curated voice, any provider\",\n kinds: [\"voice\"],\n },\n {\n id: \"voice-s2s\",\n description:\n \"Speech-to-speech voice engines (OpenAI Realtime, Gemini Live)\",\n kinds: [\"voice\"],\n capabilities: [\"s2s\"],\n },\n {\n id: \"voice-tts\",\n description: \"Sequential TTS voices (MiniMax, ElevenLabs)\",\n kinds: [\"voice\"],\n capabilities: [\"tts\"],\n },\n]\n\nexport function listSurfaceProfiles(): readonly SurfaceProfile[] {\n return SURFACE_PROFILES\n}\n\nexport function getSurfaceProfile(id: string): SurfaceProfile {\n const profile = SURFACE_PROFILES.find(p => p.id === id)\n if (!profile) {\n const known = SURFACE_PROFILES.map(p => p.id).join(\", \")\n throw new Error(\n `curation: unknown surface profile \"${id}\". Known: ${known}`\n )\n }\n return profile\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Filters\n// ───────────────────────────────────────────────────────────────────────\n\n/**\n * True iff a model passes a surface profile. Provider membership, like\n * capability/tag membership, is checked against the enrichment tag\n * vocabulary (every kind emits its provider as a tag), so this is uniform\n * across kinds and naturally spans the company/engine provider split.\n */\nexport function modelMatchesProfile(\n model: ResolvedModel,\n profile: SurfaceProfile\n): boolean {\n if (profile.kinds && profile.kinds.length > 0) {\n if (!profile.kinds.includes(model.kind)) return false\n }\n if (profile.providers && profile.providers.length > 0) {\n const tags = expandProviders(profile.providers)\n if (!tags.some(tag => modelHasTag(model, tag))) return false\n }\n if (profile.capabilities) {\n if (!profile.capabilities.every(cap => modelHasTag(model, cap)))\n return false\n }\n if (profile.tags) {\n if (!profile.tags.every(tag => modelHasTag(model, tag))) return false\n }\n return true\n}\n\n/** Filter a model list down to what a surface profile exposes. */\nexport function applyProfile(\n models: ResolvedModel[],\n profile: SurfaceProfile\n): ResolvedModel[] {\n return models.filter(model => modelMatchesProfile(model, profile))\n}\n\n/**\n * The catalog as a surface profile exposes it — `applyProfile` over the\n * full registry. The composable entry point for \"show me this view\".\n */\nexport function listSurfaced(profile: SurfaceProfile): ResolvedModel[] {\n return applyProfile(listModels(), profile)\n}\n\n/**\n * Voice-list curation. The merged voice catalog (curated + live\n * ElevenLabs) is `CatalogVoice[]`, not `ResolvedModel[]`, so it gets its\n * own provider filter — same group-expansion semantics. Only the provider\n * facet of a profile applies to a raw voice list (kind is implicitly\n * voice; capability/tag live on the registry projection).\n */\nexport function filterVoicesByProviders(\n voices: CatalogVoice[],\n providerTokens: readonly string[]\n): CatalogVoice[] {\n if (providerTokens.length === 0) return voices\n const tags = new Set(expandProviders(providerTokens))\n return voices.filter(v => tags.has(v.provider))\n}\n"]}
@@ -21,6 +21,14 @@ var CatalogProviderSchema = z.enum([
21
21
  "minimax",
22
22
  "mistral",
23
23
  "moonshot",
24
+ // OpenCode's two hosted endpoints, DISTINCT billing rails with distinct
25
+ // lineups and prices: `opencode` is OpenCode Zen (pay-as-you-go,
26
+ // https://opencode.ai/zen/v1) and `opencode-go` is the flat OpenCode Go
27
+ // subscription (https://opencode.ai/zen/go/v1). Both are keyed the same way
28
+ // in opencode's own config (`opencode/<id>`, `opencode-go/<id>`), which is
29
+ // also this catalog's route-table key form.
30
+ "opencode",
31
+ "opencode-go",
24
32
  "openai",
25
33
  "openai-realtime",
26
34
  "openrouter",
@@ -54,6 +62,18 @@ var PROVIDER_KEY_ENV = {
54
62
  minimax: "MINIMAX_API_KEY",
55
63
  mistral: "MISTRAL_API_KEY",
56
64
  moonshot: "MOONSHOT_API_KEY",
65
+ // BOTH OpenCode endpoints read the SAME env name — that is opencode's own
66
+ // convention (models.dev records `env: ["OPENCODE_API_KEY"]` for each), and
67
+ // it is precedented here (`openai`/`openai-realtime`, `google`/
68
+ // `gemini-live`). The difference that matters: a Zen key and a Go key are
69
+ // two DIFFERENT secrets sharing one env name, so a host holding both can
70
+ // only ever inject one of them (`injectProviderKeysIntoEnv` in
71
+ // `@agentproto/providers-store` resolves that collision deterministically,
72
+ // by sorted provider name). The per-spawn auth profile (`accessProfile`,
73
+ // whose `endpoint` is `opencode` or `opencode-go`) is what disambiguates
74
+ // which rail a session bills — never the store.
75
+ opencode: "OPENCODE_API_KEY",
76
+ "opencode-go": "OPENCODE_API_KEY",
57
77
  openai: "OPENAI_API_KEY",
58
78
  "openai-realtime": "OPENAI_API_KEY",
59
79
  openrouter: "OPENROUTER_API_KEY",
@@ -81,5 +101,5 @@ var baseEntryShape = {
81
101
  };
82
102
 
83
103
  export { CatalogPriceTierSchema, CatalogProviderSchema, LifecycleSchema, ModelKindSchema, NsfwPolicySchema, PROVIDER_KEY_ENV, PROVIDER_KEY_ENV_ALIASES, baseEntryShape };
84
- //# sourceMappingURL=chunk-QNJRWRWC.mjs.map
85
- //# sourceMappingURL=chunk-QNJRWRWC.mjs.map
104
+ //# sourceMappingURL=chunk-WG4F6IRS.mjs.map
105
+ //# sourceMappingURL=chunk-WG4F6IRS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema/base.ts"],"names":[],"mappings":"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","file":"chunk-WG4F6IRS.mjs","sourcesContent":["import { z } from \"zod\"\n\n/**\n * Shared schema fragments for every model catalog entry.\n *\n * `baseEntryShape` is spread into per-kind schemas so each kind stays a\n * plain `z.object` — required by `z.discriminatedUnion`.\n *\n * Mirrors the pattern in\n * `packages/agencies/registry-client/src/types.ts` (`basePayloadShape`).\n */\n\nexport const ModelKindSchema = z.enum([\"llm\", \"image\", \"video\", \"audio\"])\nexport type ModelKind = z.infer<typeof ModelKindSchema>\n\nexport const LifecycleSchema = z.enum([\"stable\", \"preview\", \"deprecated\"])\nexport type Lifecycle = z.infer<typeof LifecycleSchema>\n\n/**\n * `catalogPriceTier` — the model's intrinsic cost bucket. Distinct from\n * `subscriptionPlanTier` (the user's billing level) and `modelPreset`\n * (an app's per-conversation UX picker). Always qualify when discussing\n * tiers — bare `priceTier` / `tier` is ambiguous in this codebase.\n */\nexport const CatalogPriceTierSchema = z.enum([\"low\", \"mid\", \"high\", \"premium\"])\nexport type CatalogPriceTier = z.infer<typeof CatalogPriceTierSchema>\n\nexport const NsfwPolicySchema = z.enum([\"filtered\", \"permissive\", \"strict\"])\nexport type NsfwPolicy = z.infer<typeof NsfwPolicySchema>\n\n/**\n * Canonical model-provider registry — the single source of truth for the\n * `provider` field on every catalog entry. Adding a model on a new\n * provider means adding it here first, so a typo or an un-onboarded\n * provider is a validation/build error rather than a silently-broken\n * entry. `CatalogVoiceProviderSchema` is the voice-callable subset.\n */\nexport const CatalogProviderSchema = z.enum([\n \"anthropic\",\n \"assemblyai\",\n \"deepgram\",\n \"elevenlabs\",\n \"gemini-live\",\n \"google\",\n \"huggingface\",\n \"minimax\",\n \"mistral\",\n \"moonshot\",\n // OpenCode's two hosted endpoints, DISTINCT billing rails with distinct\n // lineups and prices: `opencode` is OpenCode Zen (pay-as-you-go,\n // https://opencode.ai/zen/v1) and `opencode-go` is the flat OpenCode Go\n // subscription (https://opencode.ai/zen/go/v1). Both are keyed the same way\n // in opencode's own config (`opencode/<id>`, `opencode-go/<id>`), which is\n // also this catalog's route-table key form.\n \"opencode\",\n \"opencode-go\",\n \"openai\",\n \"openai-realtime\",\n \"openrouter\",\n \"replicate\",\n \"requesty\",\n \"xai\",\n])\nexport type CatalogProvider = z.infer<typeof CatalogProviderSchema>\n\n/**\n * Canonical provider → api-key ENVIRONMENT VARIABLE name — the single source\n * of truth for \"which env var carries this provider's LLM billing key\". Lives\n * here, next to {@link CatalogProviderSchema}, because provider identity and\n * its key env are the same fact (adding a provider to the enum forces adding\n * its key env, or this `Record<CatalogProvider, string>` fails to type-check —\n * the compile-time equivalent of catalog-sync keeping it current).\n *\n * `@agentproto/runtime`'s `providers-store` DERIVES `PROVIDER_ENV_VARS` from\n * this map (re-exporting it plus a few non-catalog gateway keys like `groq` /\n * `vercel-ai-gateway`), and the billing-auth resolver calls\n * `providerEnvVar(provider)` rather than ever re-listing these names per\n * adapter manifest. Names follow each SDK's own convention (matching the\n * adapter manifests' `models.env` maps). This is the api-key axis ONLY — the\n * `subscription` (Anthropic OAuth) env var is consumer-specific and declared\n * per Claude adapter, not here.\n */\nexport const PROVIDER_KEY_ENV: Record<CatalogProvider, string> = {\n anthropic: \"ANTHROPIC_API_KEY\",\n assemblyai: \"ASSEMBLYAI_API_KEY\",\n deepgram: \"DEEPGRAM_API_KEY\",\n elevenlabs: \"ELEVENLABS_API_KEY\",\n \"gemini-live\": \"GOOGLE_GENERATIVE_AI_API_KEY\",\n google: \"GOOGLE_GENERATIVE_AI_API_KEY\",\n // Ecosystem convention, not our own invention: every HF tool (transformers,\n // huggingface_hub, the `hf` CLI) and — load-bearing here — opencode's own\n // bundled huggingface provider (`@ai-sdk/openai-compatible`, reads\n // `env:[\"HF_TOKEN\"]` off its models.dev-style catalog entry, confirmed by\n // inspecting the shipped `opencode acp` binary) read `HF_TOKEN`, never\n // `HUGGINGFACE_API_KEY`. `ANTHROPIC_GATEWAY_PRESETS.huggingface.keyEnv`\n // (`provider-presets/src/anthropic-gateways.ts`) already got this right for\n // the explicit `route.gateway` path; this was the other half — the\n // model-derived-api-key path (`resolveAuthSpec`'s non-gateway branch calls\n // `providerEnvVar(provider)`, i.e. THIS map, directly) still injected the\n // wrong var, so any `<model>@huggingface` spawn through a model-derived\n // router (opencode) got a credential opencode's huggingface provider never\n // reads — it sees no HF_TOKEN, treats the provider as unconfigured, and\n // 404s with \"model not found: huggingface/<model>\" even though the model\n // itself is present in opencode's own catalog.\n huggingface: \"HF_TOKEN\",\n minimax: \"MINIMAX_API_KEY\",\n mistral: \"MISTRAL_API_KEY\",\n moonshot: \"MOONSHOT_API_KEY\",\n // BOTH OpenCode endpoints read the SAME env name — that is opencode's own\n // convention (models.dev records `env: [\"OPENCODE_API_KEY\"]` for each), and\n // it is precedented here (`openai`/`openai-realtime`, `google`/\n // `gemini-live`). The difference that matters: a Zen key and a Go key are\n // two DIFFERENT secrets sharing one env name, so a host holding both can\n // only ever inject one of them (`injectProviderKeysIntoEnv` in\n // `@agentproto/providers-store` resolves that collision deterministically,\n // by sorted provider name). The per-spawn auth profile (`accessProfile`,\n // whose `endpoint` is `opencode` or `opencode-go`) is what disambiguates\n // which rail a session bills — never the store.\n opencode: \"OPENCODE_API_KEY\",\n \"opencode-go\": \"OPENCODE_API_KEY\",\n openai: \"OPENAI_API_KEY\",\n \"openai-realtime\": \"OPENAI_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n replicate: \"REPLICATE_API_TOKEN\",\n requesty: \"REQUESTY_API_KEY\",\n xai: \"XAI_API_KEY\",\n}\n\n/**\n * ADDITIONAL env-var names that carry the *same* provider key, beyond the one\n * canonical name in {@link PROVIDER_KEY_ENV}. Some consumers read a different\n * alias for a provider than the name we canonically inject, so a key set once\n * (`agentproto auth provider set <provider> <key>`) must be able to satisfy\n * every alias, not just the canonical name. `providers-store` derives its\n * `PROVIDER_ENV_ALIASES` from this and injects the canonical name PLUS every\n * alias at `serve` boot (explicit env still wins, per env name).\n *\n * Aliases are VERIFIED against a real consumer, never guessed — an alias we\n * cannot prove a consumer reads does not belong here:\n *\n * - `google: [\"GOOGLE_API_KEY\"]` — mastracode / `@mastra/core`. Its\n * `PROVIDER_REGISTRY.google.apiKeyEnvVar` is the alias array\n * `[\"GOOGLE_API_KEY\", \"GOOGLE_GENERATIVE_AI_API_KEY\"]`, but\n * `@mastra/code-sdk`'s `getApiKeyEnvVar()` collapses it to `envVars[0]`\n * (`GOOGLE_API_KEY`) before testing `Boolean(process.env[…])`. So mastracode\n * consults ONLY `GOOGLE_API_KEY`; our canonical `GOOGLE_GENERATIVE_AI_API_KEY`\n * is invisible to it. (Confirmed in the installed mastracode 0.26.x tree.)\n * - `moonshot: [\"MOONSHOT_AI_API_KEY\"]` — mastracode again, but via a HARDCODED\n * branch that bypasses the registry entirely:\n * `@mastra/code-sdk/dist/agents/mastracode-gateway.js:331-333` does\n * `if (args.providerId === \"moonshotai\") { if (!process.env.MOONSHOT_AI_API_KEY) throw … }`.\n * It reads `MOONSHOT_AI_API_KEY` (note the `_AI_`); we inject `MOONSHOT_API_KEY`\n * via {@link PROVIDER_KEY_ENV}. Because the name is hardcoded, not\n * registry-declared, the next reader cannot discover it from the registry —\n * hence this comment. (The provider slug drifts too: `moonshotai` upstream vs\n * our `moonshot`; the alias handles the env NAME, which is what matters here.)\n *\n * `gemini-live` is deliberately absent: no consumer of that provider is known\n * to read `GOOGLE_API_KEY`, so per the verify-not-guess rule it stays out. The\n * drift set is capped: across the providers we share with mastracode, only\n * `google` and `moonshot` diverge — anthropic / openai / openrouter / xai /\n * mistral / minimax (and the non-catalog groq) all match, so none are added.\n *\n * `Partial` because most providers have no known alias — a provider absent\n * here just gets its single canonical name injected.\n */\nexport const PROVIDER_KEY_ENV_ALIASES = {\n google: [\"GOOGLE_API_KEY\"],\n moonshot: [\"MOONSHOT_AI_API_KEY\"],\n} satisfies Partial<Record<CatalogProvider, readonly string[]>>\n\nexport const baseEntryShape = {\n id: z.string().min(1),\n name: z.string().min(1),\n description: z.string().default(\"\"),\n provider: CatalogProviderSchema,\n providerId: z.string().min(1),\n agentVisible: z.boolean().default(false),\n lifecycle: LifecycleSchema.default(\"stable\"),\n tags: z.array(z.string()).default([]),\n catalogPriceTier: CatalogPriceTierSchema.default(\"mid\"),\n nsfwPolicy: NsfwPolicySchema.default(\"filtered\"),\n regions: z.array(z.string()).optional(),\n aliases: z.array(z.string()).optional(),\n} as const\n"]}
@@ -1,11 +1,11 @@
1
- export { CostUsageKindMismatchError, UnknownModelError, calculateAudioCost, calculateCost, calculateImageCost, calculateLLMCost, calculateVideoCost } from '../chunk-V2BMFFUF.mjs';
2
- import '../chunk-JHBSGPWH.mjs';
3
- import '../chunk-GW52XH4V.mjs';
4
- import '../chunk-H467PHUU.mjs';
1
+ export { CostUsageKindMismatchError, UnknownModelError, calculateAudioCost, calculateCost, calculateImageCost, calculateLLMCost, calculateVideoCost } from '../chunk-O6SQMVPM.mjs';
2
+ import '../chunk-E5CVTRPJ.mjs';
3
+ import '../chunk-G6CA3BXI.mjs';
4
+ import '../chunk-B67THXMQ.mjs';
5
5
  import '../chunk-H6JUTF3U.mjs';
6
- import '../chunk-QNJRWRWC.mjs';
7
- import '../chunk-ZTTWZ7PL.mjs';
8
- import '../chunk-6VUL4I7V.mjs';
6
+ import '../chunk-WG4F6IRS.mjs';
7
+ import '../chunk-TC6S3SY3.mjs';
8
+ import '../chunk-I5E7F6KY.mjs';
9
9
  import '../chunk-QHELXPSL.mjs';
10
10
  import '../chunk-2LWYZOWB.mjs';
11
11
  import '../chunk-IJZ4XPO2.mjs';
@@ -1,12 +1,12 @@
1
- import { C as CatalogKind, R as ResolvedModel } from '../index-BZfxAdXA.js';
1
+ import { C as CatalogKind, R as ResolvedModel } from '../index-vC37SFpk.js';
2
2
  import { CatalogVoice } from '../schema/voice.js';
3
- import '../catalog-Cg0AJJZ7.js';
4
- import '../base-B8IIoaqg.js';
3
+ import '../catalog-BAb74hY-.js';
4
+ import '../base-BaiI72Da.js';
5
5
  import 'zod';
6
6
  import '../image/index.js';
7
7
  import '../video/index.js';
8
8
  import '../audio/index.js';
9
- import '../audio-DR0g_ZH_.js';
9
+ import '../audio-Do2j3wDC.js';
10
10
 
11
11
  /**
12
12
  * Curation — what an app SURFACES from the catalog, distinct from
@@ -1,11 +1,11 @@
1
- export { applyProfile, expandProviders, filterVoicesByProviders, getProviderGroup, getSurfaceProfile, groupForProvider, listProviderGroups, listSurfaceProfiles, listSurfaced, modelMatchesProfile } from '../chunk-UREM2UZK.mjs';
2
- import '../chunk-JHBSGPWH.mjs';
3
- import '../chunk-GW52XH4V.mjs';
4
- import '../chunk-H467PHUU.mjs';
1
+ export { applyProfile, expandProviders, filterVoicesByProviders, getProviderGroup, getSurfaceProfile, groupForProvider, listProviderGroups, listSurfaceProfiles, listSurfaced, modelMatchesProfile } from '../chunk-UZDL26T7.mjs';
2
+ import '../chunk-E5CVTRPJ.mjs';
3
+ import '../chunk-G6CA3BXI.mjs';
4
+ import '../chunk-B67THXMQ.mjs';
5
5
  import '../chunk-H6JUTF3U.mjs';
6
- import '../chunk-QNJRWRWC.mjs';
7
- import '../chunk-ZTTWZ7PL.mjs';
8
- import '../chunk-6VUL4I7V.mjs';
6
+ import '../chunk-WG4F6IRS.mjs';
7
+ import '../chunk-TC6S3SY3.mjs';
8
+ import '../chunk-I5E7F6KY.mjs';
9
9
  import '../chunk-QHELXPSL.mjs';
10
10
  import '../chunk-2LWYZOWB.mjs';
11
11
  import '../chunk-IJZ4XPO2.mjs';
@@ -1,5 +1,5 @@
1
- import { R as ResolvedModel } from './index-BZfxAdXA.js';
2
- import { M as ModelKind } from './base-B8IIoaqg.js';
1
+ import { R as ResolvedModel } from './index-vC37SFpk.js';
2
+ import { M as ModelKind } from './base-BaiI72Da.js';
3
3
 
4
4
  /**
5
5
  * Access control types — workspace-override rules + app scope.
@@ -1,6 +1,6 @@
1
- import { A as AccessDecision } from './evaluate-D3gXrAg-.js';
2
- import { C as CatalogPriceTier, L as Lifecycle, M as ModelKind } from './base-B8IIoaqg.js';
3
- import { R as ResolvedModel } from './index-BZfxAdXA.js';
1
+ import { A as AccessDecision } from './evaluate-B83jX17h.js';
2
+ import { C as CatalogPriceTier, L as Lifecycle, M as ModelKind } from './base-BaiI72Da.js';
3
+ import { R as ResolvedModel } from './index-vC37SFpk.js';
4
4
 
5
5
  /**
6
6
  * Model enrichment — `catalogPriceTier` / `tags` / `lifecycle` / `actions`
@@ -1,4 +1,4 @@
1
- import { L as LLMPricing } from './catalog-Cg0AJJZ7.js';
1
+ import { L as LLMPricing } from './catalog-BAb74hY-.js';
2
2
  import { ImageModelDefinition } from './image/index.js';
3
3
  import { VideoModelDefinition } from './video/index.js';
4
4
  import { AudioModelDefinition } from './audio/index.js';
@@ -111,18 +111,23 @@ declare function listModels(filter?: ListModelsFilter): ResolvedModel[];
111
111
  * catalog" (openai, google, anthropic, replicate, openrouter, …): a
112
112
  * derived query over the kind-organized catalogs, NOT a parallel store.
113
113
  *
114
- * When `provider` names a router (openrouter, requesty, huggingface),
115
- * this also folds in that router's generated route table
116
- * (`listRouterLlmRoutes`), emitting `vendor/product@router` ids — the
117
- * router's full surface, not just what happens to be curated into
118
- * `LLM_PRICING_CATALOG`. OpenRouter's routes are already spread into that
119
- * catalog (bare `vendor/product` ids, `llm/catalog.ts`), so its router-table
120
- * entries are deduped against the bare ids `listModels` already returned;
121
- * Requesty and HuggingFace have no such overlap today, so their route table
122
- * entries are added in full. Deliberately NOT achieved by spreading
123
- * `REQUESTY_ROUTES`/`HUGGINGFACE_ROUTES` into `LLM_PRICING_CATALOG` itself —
124
- * that catalog is the legacy bare-id path, and a bare id must keep meaning
125
- * direct-vendor pricing (`route-identity/index.ts`).
114
+ * When `provider` names a router or a routed endpoint (openrouter, requesty,
115
+ * huggingface, opencode, opencode-go), this also folds in that provider's
116
+ * generated route table (`listRouterLlmRoutes`) — the provider's full
117
+ * surface, not just what happens to be curated into `LLM_PRICING_CATALOG`.
118
+ * The emitted id is whatever `formatModelRef` produces for the resolved ref:
119
+ * `vendor/product@router` for the vendor-namespacing routers, and the bare
120
+ * `opencode-go/glm-5.3` / `opencode/claude-sonnet-4-6` form for the two
121
+ * OpenCode endpoints, whose route IS the id's leading segment (so there is no
122
+ * `@route` to append). OpenRouter's routes are already spread into
123
+ * `LLM_PRICING_CATALOG` (bare `vendor/product` ids, `llm/catalog.ts`), so its
124
+ * router-table entries are deduped against the bare ids `listModels` already
125
+ * returned; Requesty, HuggingFace and the two OpenCode endpoints have no such
126
+ * overlap, so their route table entries are added in full. Deliberately NOT
127
+ * achieved by spreading `REQUESTY_ROUTES`/`HUGGINGFACE_ROUTES`/
128
+ * `OPENCODE_*_ROUTES` into `LLM_PRICING_CATALOG` itself — that catalog is the
129
+ * legacy bare-id path, and a bare id must keep meaning direct-vendor pricing
130
+ * (`route-identity/index.ts`).
126
131
  */
127
132
  declare function getModelsByProvider(provider: string): ResolvedModel[];
128
133
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { ImageAspectRatio, ImageAspectRatioSchema, ImageCapabilities, ImageCapabilitiesSchema, ImageEntry, ImageEntrySchema, ImagePricing, ImagePricingSchema, ImageReferenceImages, ImageReferenceImagesSchema, LLMEntry, LLMEntrySchema, LlmPricing, LlmPricingSchema, ModelEntry, ModelEntrySchema, VideoCapabilities, VideoCapabilitiesSchema, VideoCostMultipliers, VideoCostMultipliersSchema, VideoEntry, VideoEntrySchema, VideoPricing, VideoPricingSchema, VideoResolution, VideoResolutionSchema } from './schema/index.js';
2
- export { D as DEFAULT_PRICING, a as LLMCreditCostResult, L as LLMPricing, b as LLMUsageBreakdown, c as LLM_PRICING_CATALOG, M as MODEL_ALIASES, d as calculateLLMCreditCost, r as resolvePricing } from './catalog-Cg0AJJZ7.js';
2
+ export { D as DEFAULT_PRICING, a as LLMCreditCostResult, L as LLMPricing, b as LLMUsageBreakdown, c as LLM_PRICING_CATALOG, M as MODEL_ALIASES, d as calculateLLMCreditCost, r as resolvePricing } from './catalog-BAb74hY-.js';
3
3
  export { AGENT_EDITABLE_MODEL_IDS, AGENT_GENERATIVE_MODEL_IDS, AGENT_IMAGE_MODEL_IDS, IMAGE_MODEL_CATALOG, IMAGE_MODEL_IDS, ImageModelDefinition, generateImageModelTable } from './image/index.js';
4
4
  export { AGENT_VIDEO_MODEL_IDS, VIDEO_MODEL_CATALOG, VIDEO_MODEL_IDS, VideoModelDefinition, generateVideoModelTable } from './video/index.js';
5
5
  export { AGENT_AUDIO_MODEL_IDS, AGENT_STT_MODEL_IDS, AGENT_TTS_MODEL_IDS, AUDIO_MODEL_CATALOG, AUDIO_MODEL_IDS, AudioBillingUnit, AudioModality, AudioModelDefinition, AudioProvider, DEFAULT_GEMINI_LIVE_MODEL, GEMINI_LIVE_MODEL_IDS, S2S_MODEL_IDS, generateAudioModelTable, isAcceptedGeminiLiveModel } from './audio/index.js';
@@ -9,14 +9,14 @@ export { ProviderGroup, SurfaceProfile, applyProfile, expandProviders, filterVoi
9
9
  export { CC_USD_RATE, CREDIT_USD_RATE, DEFAULT_PRICING_FLOORS, DEFAULT_PRICING_MARKUP, PricingCategory, PricingMarkup, computeCenticredits, pricingRegistry } from './pricing/index.js';
10
10
  export { CalculateCostOptions, CostResult, CostUsage, CostUsageKindMismatchError, UnknownModelError, calculateAudioCost, calculateCost, calculateImageCost, calculateLLMCost, calculateVideoCost } from './cost/index.js';
11
11
  export { ShouldDebitDecision, ShouldDebitInput, shouldDebit } from './byok/index.js';
12
- export { A as AccessDecision, a as AccessEffect, b as AccessEvalInput, c as AccessRule, d as AccessTarget, e as AppScope, f as evaluateAccess } from './evaluate-D3gXrAg-.js';
12
+ export { A as AccessDecision, a as AccessEffect, b as AccessEvalInput, c as AccessRule, d as AccessTarget, e as AppScope, f as evaluateAccess } from './evaluate-B83jX17h.js';
13
13
  export { CatalogDefaultDecision, evaluateCatalogDefaults } from './access/index.js';
14
14
  export { CatalogOverlay, MergedOverlay, clearCatalogOverlays, getMergedOverlay, registerCatalogOverlay } from './overlay/index.js';
15
- import { R as ResolvedModel } from './index-BZfxAdXA.js';
16
- export { C as CatalogKind, L as ListModelsFilter, g as getModel, a as getModelsByProvider, b as getStaticModelProvider, i as isAgentVisible, l as listModels, r as resolveAlias } from './index-BZfxAdXA.js';
17
- export { A as AvailableConnector, a as AvailableModel, b as AvailableModelCapabilities, c as AvailableModelsActor, d as AvailableModelsResponse, L as ListAvailableModelsParams, M as ModelEnrichment, g as getEnrichment, m as modelHasAction, e as modelHasTag, f as modelMatchesCatalogPriceTier, h as modelMatchesKind, i as modelMatchesPriceTier, p as priceTierForModel } from './index-DC8jecem.js';
18
- export { A as AudioCapabilities, a as AudioCapabilitiesSchema, b as AudioEntry, c as AudioEntrySchema, d as AudioPricing, e as AudioPricingSchema } from './audio-DR0g_ZH_.js';
19
- export { C as CatalogPriceTier, a as CatalogPriceTierSchema, b as CatalogProvider, c as CatalogProviderSchema, L as Lifecycle, d as LifecycleSchema, M as ModelKind, e as ModelKindSchema, N as NsfwPolicy, f as NsfwPolicySchema, P as PROVIDER_KEY_ENV, g as PROVIDER_KEY_ENV_ALIASES, h as baseEntryShape } from './base-B8IIoaqg.js';
15
+ import { R as ResolvedModel } from './index-vC37SFpk.js';
16
+ export { C as CatalogKind, L as ListModelsFilter, g as getModel, a as getModelsByProvider, b as getStaticModelProvider, i as isAgentVisible, l as listModels, r as resolveAlias } from './index-vC37SFpk.js';
17
+ export { A as AvailableConnector, a as AvailableModel, b as AvailableModelCapabilities, c as AvailableModelsActor, d as AvailableModelsResponse, L as ListAvailableModelsParams, M as ModelEnrichment, g as getEnrichment, m as modelHasAction, e as modelHasTag, f as modelMatchesCatalogPriceTier, h as modelMatchesKind, i as modelMatchesPriceTier, p as priceTierForModel } from './index-BWvtVzEG.js';
18
+ export { A as AudioCapabilities, a as AudioCapabilitiesSchema, b as AudioEntry, c as AudioEntrySchema, d as AudioPricing, e as AudioPricingSchema } from './audio-Do2j3wDC.js';
19
+ export { C as CatalogPriceTier, a as CatalogPriceTierSchema, b as CatalogProvider, c as CatalogProviderSchema, L as Lifecycle, d as LifecycleSchema, M as ModelKind, e as ModelKindSchema, N as NsfwPolicy, f as NsfwPolicySchema, P as PROVIDER_KEY_ENV, g as PROVIDER_KEY_ENV_ALIASES, h as baseEntryShape } from './base-BaiI72Da.js';
20
20
  import 'zod';
21
21
 
22
22
  /**