{"version":3,"file":"image-cost.mjs","names":[],"sources":["../../../../../../../ai/src/image/image-cost.ts"],"sourcesContent":["import type { ImageModelPricing } from \"../contracts/image-model.contract\";\nimport type { ModelPricing } from \"../contracts/result/model-pricing.type\";\nimport type { Usage } from \"../contracts/result/usage.type\";\nimport { computeCost } from \"../utils/compute-cost\";\n\n/**\n * Price one image-generation `Usage` against an\n * {@link ImageModelPricing}, returning a `ModelPricing`-shaped USD\n * breakdown so image spend folds into the exact same `Usage.cost`\n * rollup the text path uses (`accumulateCost` / `mergeUsage`). There is\n * no separate image-cost field anywhere downstream — only this one\n * function, which knows the two metering models:\n *\n * - **Per-image** (DALL·E, Imagen): `perImageBySize[size]` (when the\n *   request `size` matches a tier) else flat `perImage`, times the\n *   number of images returned, attributed to `cost.output` (the image\n *   IS the output). Token channels stay 0.\n * - **Token** (gpt-image-1): delegates to the standard\n *   {@link computeCost} against the prompt/image token `Usage`.\n *\n * Per-image wins when both shapes are configured (a provider is one or\n * the other). Returns `undefined` when no usable pricing is present —\n * the framework treats that as \"cost unknown\", never a false zero.\n *\n * @example\n * computeImageCost({ input: 0, output: 0, total: 0 }, 2, \"1024x1024\", { perImage: 0.04 });\n * // → { input: 0, output: 0.08 }\n */\nexport function computeImageCost(\n  usage: Usage,\n  imageCount: number,\n  size: string | undefined,\n  pricing: ImageModelPricing | undefined,\n): ModelPricing | undefined {\n  if (!pricing) {\n    return undefined;\n  }\n\n  const perImageMetered = pricing.perImage !== undefined || pricing.perImageBySize !== undefined;\n\n  if (perImageMetered) {\n    const perImage = resolvePerImageRate(size, pricing);\n\n    if (perImage === undefined) {\n      return undefined;\n    }\n\n    return { input: 0, output: perImage * imageCount };\n  }\n\n  if (pricing.input !== undefined && pricing.output !== undefined) {\n    return computeCost(usage, { input: pricing.input, output: pricing.output });\n  }\n\n  return undefined;\n}\n\n/**\n * Resolve the USD-per-image rate: a `perImageBySize` tier matching the\n * requested `size` wins, otherwise the flat `perImage`. Returns\n * `undefined` only when neither is set (the caller already gated on\n * per-image metering being configured at all).\n */\nfunction resolvePerImageRate(\n  size: string | undefined,\n  pricing: ImageModelPricing,\n): number | undefined {\n  if (size !== undefined && pricing.perImageBySize?.[size] !== undefined) {\n    return pricing.perImageBySize[size];\n  }\n\n  return pricing.perImage;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,iBACd,OACA,YACA,MACA,SAC0B;CAC1B,IAAI,CAAC,SACH;CAKF,IAFwB,QAAQ,aAAa,UAAa,QAAQ,mBAAmB,QAEhE;EACnB,MAAM,WAAW,oBAAoB,MAAM,OAAO;EAElD,IAAI,aAAa,QACf;EAGF,OAAO;GAAE,OAAO;GAAG,QAAQ,WAAW;EAAW;CACnD;CAEA,IAAI,QAAQ,UAAU,UAAa,QAAQ,WAAW,QACpD,OAAO,YAAY,OAAO;EAAE,OAAO,QAAQ;EAAO,QAAQ,QAAQ;CAAO,CAAC;AAI9E;;;;;;;AAQA,SAAS,oBACP,MACA,SACoB;CACpB,IAAI,SAAS,UAAa,QAAQ,iBAAiB,UAAU,QAC3D,OAAO,QAAQ,eAAe;CAGhC,OAAO,QAAQ;AACjB"}