@agentproto/model-catalog 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/access/index.d.ts +30 -0
- package/dist/access/index.mjs +4 -0
- package/dist/access/index.mjs.map +1 -0
- package/dist/audio/index.d.ts +84 -0
- package/dist/audio/index.mjs +3 -0
- package/dist/audio/index.mjs.map +1 -0
- package/dist/audio-BzVF_wke.d.ts +92 -0
- package/dist/base-BNHcMifc.d.ts +109 -0
- package/dist/byok/index.d.ts +33 -0
- package/dist/byok/index.mjs +3 -0
- package/dist/byok/index.mjs.map +1 -0
- package/dist/catalog-aQHd559b.d.ts +594 -0
- package/dist/chunk-2LWYZOWB.mjs +643 -0
- package/dist/chunk-2LWYZOWB.mjs.map +1 -0
- package/dist/chunk-CINXNTU3.mjs +134 -0
- package/dist/chunk-CINXNTU3.mjs.map +1 -0
- package/dist/chunk-F7OEHYUI.mjs +187 -0
- package/dist/chunk-F7OEHYUI.mjs.map +1 -0
- package/dist/chunk-GH7PB5FB.mjs +183 -0
- package/dist/chunk-GH7PB5FB.mjs.map +1 -0
- package/dist/chunk-H6JUTF3U.mjs +33 -0
- package/dist/chunk-H6JUTF3U.mjs.map +1 -0
- package/dist/chunk-HEDDSOZF.mjs +47 -0
- package/dist/chunk-HEDDSOZF.mjs.map +1 -0
- package/dist/chunk-HRRG2RZO.mjs +116 -0
- package/dist/chunk-HRRG2RZO.mjs.map +1 -0
- package/dist/chunk-IJZ4XPO2.mjs +606 -0
- package/dist/chunk-IJZ4XPO2.mjs.map +1 -0
- package/dist/chunk-IORIAFK2.mjs +227 -0
- package/dist/chunk-IORIAFK2.mjs.map +1 -0
- package/dist/chunk-OHAMH3ZE.mjs +2629 -0
- package/dist/chunk-OHAMH3ZE.mjs.map +1 -0
- package/dist/chunk-QHELXPSL.mjs +85 -0
- package/dist/chunk-QHELXPSL.mjs.map +1 -0
- package/dist/chunk-SGJR6ZQH.mjs +1230 -0
- package/dist/chunk-SGJR6ZQH.mjs.map +1 -0
- package/dist/chunk-WRUWNKDB.mjs +521 -0
- package/dist/chunk-WRUWNKDB.mjs.map +1 -0
- package/dist/chunk-WTHHXXIK.mjs +366 -0
- package/dist/chunk-WTHHXXIK.mjs.map +1 -0
- package/dist/chunk-XFDXTFV3.mjs +28 -0
- package/dist/chunk-XFDXTFV3.mjs.map +1 -0
- package/dist/cost/index.d.ts +114 -0
- package/dist/cost/index.mjs +13 -0
- package/dist/cost/index.mjs.map +1 -0
- package/dist/curation/index.d.ts +98 -0
- package/dist/curation/index.mjs +13 -0
- package/dist/curation/index.mjs.map +1 -0
- package/dist/evaluate-DisH3H7u.d.ts +84 -0
- package/dist/image/index.d.ts +79 -0
- package/dist/image/index.mjs +3 -0
- package/dist/image/index.mjs.map +1 -0
- package/dist/index-BICjPG8H.d.ts +132 -0
- package/dist/index-D8nL3fPZ.d.ts +171 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.mjs +33 -0
- package/dist/index.mjs.map +1 -0
- package/dist/llm/index.d.ts +48 -0
- package/dist/llm/index.mjs +4 -0
- package/dist/llm/index.mjs.map +1 -0
- package/dist/overlay/index.d.ts +67 -0
- package/dist/overlay/index.mjs +3 -0
- package/dist/overlay/index.mjs.map +1 -0
- package/dist/picker/index.d.ts +11 -0
- package/dist/picker/index.mjs +26 -0
- package/dist/picker/index.mjs.map +1 -0
- package/dist/pricing/index.d.ts +106 -0
- package/dist/pricing/index.mjs +3 -0
- package/dist/pricing/index.mjs.map +1 -0
- package/dist/providers/index.d.ts +78 -0
- package/dist/providers/index.mjs +237 -0
- package/dist/providers/index.mjs.map +1 -0
- package/dist/schema/index.d.ts +627 -0
- package/dist/schema/index.mjs +4 -0
- package/dist/schema/index.mjs.map +1 -0
- package/dist/schema/voice.d.ts +66 -0
- package/dist/schema/voice.mjs +3 -0
- package/dist/schema/voice.mjs.map +1 -0
- package/dist/video/index.d.ts +78 -0
- package/dist/video/index.mjs +3 -0
- package/dist/video/index.mjs.map +1 -0
- package/dist/voice/index.d.ts +1300 -0
- package/dist/voice/index.mjs +4 -0
- package/dist/voice/index.mjs.map +1 -0
- package/package.json +137 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { getModel } from './chunk-GH7PB5FB.mjs';
|
|
2
|
+
import { calculateLLMCreditCost } from './chunk-OHAMH3ZE.mjs';
|
|
3
|
+
import { computeCenticredits, pricingRegistry } from './chunk-QHELXPSL.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @agentproto/model-catalog v0.1.0
|
|
7
|
+
* Unified model catalog: LLM, image, video, audio entries + cost dispatcher + picker.
|
|
8
|
+
* Zod-only OSS core; @agstudio/model-catalog layers billing/access/BYOK on top.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// src/cost/index.ts
|
|
12
|
+
var VOICE_PROVIDER_DEFAULT_MODEL = {
|
|
13
|
+
minimax: "minimax/speech-02-turbo",
|
|
14
|
+
elevenlabs: "elevenlabs/flash-v2.5"
|
|
15
|
+
};
|
|
16
|
+
var UnknownModelError = class extends Error {
|
|
17
|
+
constructor(modelId) {
|
|
18
|
+
super(`Unknown model id: "${modelId}"`);
|
|
19
|
+
this.modelId = modelId;
|
|
20
|
+
this.name = "UnknownModelError";
|
|
21
|
+
}
|
|
22
|
+
modelId;
|
|
23
|
+
};
|
|
24
|
+
var CostUsageKindMismatchError = class extends Error {
|
|
25
|
+
constructor(modelId, expected, got) {
|
|
26
|
+
super(
|
|
27
|
+
`Model "${modelId}" is kind "${expected}", but received usage of kind "${got}"`
|
|
28
|
+
);
|
|
29
|
+
this.modelId = modelId;
|
|
30
|
+
this.expected = expected;
|
|
31
|
+
this.got = got;
|
|
32
|
+
this.name = "CostUsageKindMismatchError";
|
|
33
|
+
}
|
|
34
|
+
modelId;
|
|
35
|
+
expected;
|
|
36
|
+
got;
|
|
37
|
+
};
|
|
38
|
+
function calculateCost(modelId, usage, opts = {}) {
|
|
39
|
+
if (usage.kind === "llm") {
|
|
40
|
+
const llmResult = calculateLLMCreditCost(modelId, {
|
|
41
|
+
inputTokens: usage.inputTokens,
|
|
42
|
+
outputTokens: usage.outputTokens,
|
|
43
|
+
cacheReadInputTokens: usage.cacheReadInputTokens,
|
|
44
|
+
cacheCreationInputTokens: usage.cacheCreationInputTokens
|
|
45
|
+
});
|
|
46
|
+
const resolved2 = getModel(modelId);
|
|
47
|
+
const canonicalId = resolved2 && resolved2.kind === "llm" ? resolved2.canonicalId : modelId;
|
|
48
|
+
return {
|
|
49
|
+
kind: "llm",
|
|
50
|
+
modelId,
|
|
51
|
+
canonicalId,
|
|
52
|
+
credits: llmResult.credits,
|
|
53
|
+
calculatedCredits: llmResult.calculatedCredits,
|
|
54
|
+
baseCostUsd: llmResult.productionCost,
|
|
55
|
+
breakdown: {
|
|
56
|
+
inputCredits: llmResult.inputCredits,
|
|
57
|
+
outputCredits: llmResult.outputCredits,
|
|
58
|
+
cacheReadCredits: llmResult.cacheReadCredits,
|
|
59
|
+
cacheWriteCredits: llmResult.cacheWriteCredits
|
|
60
|
+
},
|
|
61
|
+
isFallback: llmResult.isFallback,
|
|
62
|
+
markup: llmResult.markup
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const resolved = getModel(modelId);
|
|
66
|
+
if (!resolved) throw new UnknownModelError(modelId);
|
|
67
|
+
const expectedUsageKind = resolved.kind === "voice" ? "audio" : resolved.kind;
|
|
68
|
+
if (expectedUsageKind !== usage.kind) {
|
|
69
|
+
throw new CostUsageKindMismatchError(modelId, expectedUsageKind, usage.kind);
|
|
70
|
+
}
|
|
71
|
+
if (resolved.kind === "image") {
|
|
72
|
+
const numOutputs = Math.max(
|
|
73
|
+
1,
|
|
74
|
+
usage.kind === "image" ? usage.numOutputs ?? 1 : 1
|
|
75
|
+
);
|
|
76
|
+
const baseCostUsd2 = resolved.def.pricing.baseCost * numOutputs;
|
|
77
|
+
const perOutputCredits = computeCenticredits({
|
|
78
|
+
baseCostUsd: resolved.def.pricing.baseCost,
|
|
79
|
+
category: "image",
|
|
80
|
+
overrideCreditCost: resolved.def.pricing.overrideCreditCost,
|
|
81
|
+
appId: opts.appId
|
|
82
|
+
});
|
|
83
|
+
const credits2 = perOutputCredits * numOutputs;
|
|
84
|
+
const formulaPerOutput = computeCenticredits({
|
|
85
|
+
baseCostUsd: resolved.def.pricing.baseCost,
|
|
86
|
+
category: "image",
|
|
87
|
+
appId: opts.appId
|
|
88
|
+
});
|
|
89
|
+
const calculatedCredits2 = formulaPerOutput * numOutputs;
|
|
90
|
+
const markup2 = pricingRegistry.getMarkup("image", opts.appId);
|
|
91
|
+
return {
|
|
92
|
+
kind: "image",
|
|
93
|
+
modelId,
|
|
94
|
+
canonicalId: modelId,
|
|
95
|
+
credits: credits2,
|
|
96
|
+
calculatedCredits: calculatedCredits2,
|
|
97
|
+
baseCostUsd: baseCostUsd2,
|
|
98
|
+
breakdown: {
|
|
99
|
+
perOutputCredits,
|
|
100
|
+
numOutputs
|
|
101
|
+
},
|
|
102
|
+
isFallback: false,
|
|
103
|
+
markup: markup2
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (resolved.kind === "video") {
|
|
107
|
+
if (usage.kind !== "video") {
|
|
108
|
+
throw new CostUsageKindMismatchError(modelId, "video", usage.kind);
|
|
109
|
+
}
|
|
110
|
+
const pricing = resolved.def.pricing;
|
|
111
|
+
const mult = pricing.multipliers;
|
|
112
|
+
const resMult = usage.resolution && mult?.resolution ? mult.resolution[usage.resolution] ?? 1 : 1;
|
|
113
|
+
const durMult = usage.duration && mult?.duration ? mult.duration[usage.duration] ?? 1 : 1;
|
|
114
|
+
const modMult = usage.mode && mult?.mode ? mult.mode[usage.mode] ?? 1 : 1;
|
|
115
|
+
const variantMultiplier = resMult * durMult * modMult;
|
|
116
|
+
const baseCostUsd2 = pricing.baseCost * variantMultiplier;
|
|
117
|
+
const perClipCredits = computeCenticredits({
|
|
118
|
+
baseCostUsd: pricing.baseCost,
|
|
119
|
+
category: "video",
|
|
120
|
+
overrideCreditCost: pricing.overrideCreditCost,
|
|
121
|
+
appId: opts.appId
|
|
122
|
+
});
|
|
123
|
+
const credits2 = Math.ceil(perClipCredits * variantMultiplier);
|
|
124
|
+
const formulaPerClip = computeCenticredits({
|
|
125
|
+
baseCostUsd: pricing.baseCost,
|
|
126
|
+
category: "video",
|
|
127
|
+
appId: opts.appId
|
|
128
|
+
});
|
|
129
|
+
const calculatedCredits2 = Math.ceil(formulaPerClip * variantMultiplier);
|
|
130
|
+
const markup2 = pricingRegistry.getMarkup("video", opts.appId);
|
|
131
|
+
return {
|
|
132
|
+
kind: "video",
|
|
133
|
+
modelId,
|
|
134
|
+
canonicalId: modelId,
|
|
135
|
+
credits: credits2,
|
|
136
|
+
calculatedCredits: calculatedCredits2,
|
|
137
|
+
baseCostUsd: baseCostUsd2,
|
|
138
|
+
breakdown: {
|
|
139
|
+
perClipCredits,
|
|
140
|
+
resolutionMultiplier: resMult,
|
|
141
|
+
durationMultiplier: durMult,
|
|
142
|
+
modeMultiplier: modMult,
|
|
143
|
+
variantMultiplier
|
|
144
|
+
},
|
|
145
|
+
isFallback: false,
|
|
146
|
+
markup: markup2
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (usage.kind !== "audio") {
|
|
150
|
+
throw new CostUsageKindMismatchError(modelId, "audio", usage.kind);
|
|
151
|
+
}
|
|
152
|
+
if (resolved.kind === "voice") {
|
|
153
|
+
const provider = resolved.voice.provider;
|
|
154
|
+
const delegateModelId = VOICE_PROVIDER_DEFAULT_MODEL[provider];
|
|
155
|
+
if (!delegateModelId) throw new UnknownModelError(modelId);
|
|
156
|
+
const delegateResult = calculateCost(delegateModelId, usage, opts);
|
|
157
|
+
return {
|
|
158
|
+
...delegateResult,
|
|
159
|
+
modelId,
|
|
160
|
+
canonicalId: delegateModelId
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
if (resolved.kind !== "audio") throw new UnknownModelError(modelId);
|
|
164
|
+
const audioPricing = resolved.def.pricing;
|
|
165
|
+
const billingUnit = audioPricing.billingUnit;
|
|
166
|
+
let quantity;
|
|
167
|
+
switch (billingUnit) {
|
|
168
|
+
case "per_1k_chars":
|
|
169
|
+
quantity = Math.max(0, usage.characters ?? 0) / 1e3;
|
|
170
|
+
break;
|
|
171
|
+
case "per_character":
|
|
172
|
+
quantity = Math.max(0, usage.characters ?? 0);
|
|
173
|
+
break;
|
|
174
|
+
case "per_minute":
|
|
175
|
+
quantity = Math.ceil(Math.max(0, usage.seconds ?? 0) / 60);
|
|
176
|
+
break;
|
|
177
|
+
case "per_second":
|
|
178
|
+
default:
|
|
179
|
+
quantity = Math.max(0, usage.seconds ?? 0);
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
const baseCostUsd = audioPricing.baseCost * quantity;
|
|
183
|
+
const perUnitCredits = computeCenticredits({
|
|
184
|
+
baseCostUsd: audioPricing.baseCost,
|
|
185
|
+
category: "audio",
|
|
186
|
+
overrideCreditCost: audioPricing.overrideCreditCost,
|
|
187
|
+
appId: opts.appId
|
|
188
|
+
});
|
|
189
|
+
const credits = quantity > 0 ? Math.max(1, Math.ceil(perUnitCredits * quantity)) : 0;
|
|
190
|
+
const formulaPerUnit = computeCenticredits({
|
|
191
|
+
baseCostUsd: audioPricing.baseCost,
|
|
192
|
+
category: "audio",
|
|
193
|
+
appId: opts.appId
|
|
194
|
+
});
|
|
195
|
+
const calculatedCredits = quantity > 0 ? Math.max(1, Math.ceil(formulaPerUnit * quantity)) : 0;
|
|
196
|
+
const markup = pricingRegistry.getMarkup("audio", opts.appId);
|
|
197
|
+
return {
|
|
198
|
+
kind: "audio",
|
|
199
|
+
modelId,
|
|
200
|
+
canonicalId: modelId,
|
|
201
|
+
credits,
|
|
202
|
+
calculatedCredits,
|
|
203
|
+
baseCostUsd,
|
|
204
|
+
breakdown: {
|
|
205
|
+
perUnitCredits,
|
|
206
|
+
quantity
|
|
207
|
+
},
|
|
208
|
+
isFallback: false,
|
|
209
|
+
markup
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function calculateLLMCost(modelId, usage, opts) {
|
|
213
|
+
return calculateCost(modelId, { kind: "llm", ...usage }, opts);
|
|
214
|
+
}
|
|
215
|
+
function calculateImageCost(modelId, usage, opts) {
|
|
216
|
+
return calculateCost(modelId, { kind: "image", ...usage }, opts);
|
|
217
|
+
}
|
|
218
|
+
function calculateVideoCost(modelId, usage, opts) {
|
|
219
|
+
return calculateCost(modelId, { kind: "video", ...usage }, opts);
|
|
220
|
+
}
|
|
221
|
+
function calculateAudioCost(modelId, usage, opts) {
|
|
222
|
+
return calculateCost(modelId, { kind: "audio", ...usage }, opts);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export { CostUsageKindMismatchError, UnknownModelError, calculateAudioCost, calculateCost, calculateImageCost, calculateLLMCost, calculateVideoCost };
|
|
226
|
+
//# sourceMappingURL=chunk-IORIAFK2.mjs.map
|
|
227
|
+
//# sourceMappingURL=chunk-IORIAFK2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cost/index.ts"],"names":["resolved","baseCostUsd","credits","calculatedCredits","markup"],"mappings":";;;;;;;;;;;AAiCA,IAAM,4BAAA,GAAuD;AAAA,EAC3D,OAAA,EAAS,yBAAA;AAAA,EACT,UAAA,EAAY;AACd,CAAA;AAkDO,IAAM,iBAAA,GAAN,cAAgC,KAAA,CAAM;AAAA,EAC3C,YAA4B,OAAA,EAAiB;AAC3C,IAAA,KAAA,CAAM,CAAA,mBAAA,EAAsB,OAAO,CAAA,CAAA,CAAG,CAAA;AADZ,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAE1B,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AAAA,EACd;AAAA,EAH4B,OAAA;AAI9B;AAEO,IAAM,0BAAA,GAAN,cAAyC,KAAA,CAAM;AAAA,EACpD,WAAA,CACkB,OAAA,EACA,QAAA,EACA,GAAA,EAChB;AACA,IAAA,KAAA;AAAA,MACE,CAAA,OAAA,EAAU,OAAO,CAAA,WAAA,EAAc,QAAQ,kCAAkC,GAAG,CAAA,CAAA;AAAA,KAC9E;AANgB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAKhB,IAAA,IAAA,CAAK,IAAA,GAAO,4BAAA;AAAA,EACd;AAAA,EARkB,OAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAA;AAOpB;AA0BO,SAAS,aAAA,CACd,OAAA,EACA,KAAA,EACA,IAAA,GAA6B,EAAC,EAClB;AAIZ,EAAA,IAAI,KAAA,CAAM,SAAS,KAAA,EAAO;AACxB,IAAA,MAAM,SAAA,GAAiC,uBAAuB,OAAA,EAAS;AAAA,MACrE,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,cAAc,KAAA,CAAM,YAAA;AAAA,MACpB,sBAAsB,KAAA,CAAM,oBAAA;AAAA,MAC5B,0BAA0B,KAAA,CAAM;AAAA,KACjC,CAAA;AACD,IAAA,MAAMA,SAAAA,GAAW,SAAS,OAAO,CAAA;AACjC,IAAA,MAAM,cACJA,SAAAA,IAAYA,SAAAA,CAAS,IAAA,KAAS,KAAA,GAAQA,UAAS,WAAA,GAAc,OAAA;AAC/D,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,KAAA;AAAA,MACN,OAAA;AAAA,MACA,WAAA;AAAA,MACA,SAAS,SAAA,CAAU,OAAA;AAAA,MACnB,mBAAmB,SAAA,CAAU,iBAAA;AAAA,MAC7B,aAAa,SAAA,CAAU,cAAA;AAAA,MACvB,SAAA,EAAW;AAAA,QACT,cAAc,SAAA,CAAU,YAAA;AAAA,QACxB,eAAe,SAAA,CAAU,aAAA;AAAA,QACzB,kBAAkB,SAAA,CAAU,gBAAA;AAAA,QAC5B,mBAAmB,SAAA,CAAU;AAAA,OAC/B;AAAA,MACA,YAAY,SAAA,CAAU,UAAA;AAAA,MACtB,QAAQ,SAAA,CAAU;AAAA,KACpB;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAW,SAAS,OAAO,CAAA;AACjC,EAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,kBAAkB,OAAO,CAAA;AAIlD,EAAA,MAAM,iBAAA,GACJ,QAAA,CAAS,IAAA,KAAS,OAAA,GAAU,UAAU,QAAA,CAAS,IAAA;AACjD,EAAA,IAAI,iBAAA,KAAsB,MAAM,IAAA,EAAM;AAIpC,IAAA,MAAM,IAAI,0BAAA,CAA2B,OAAA,EAAS,iBAAA,EAAmB,MAAM,IAAI,CAAA;AAAA,EAC7E;AAEA,EAAA,IAAI,QAAA,CAAS,SAAS,OAAA,EAAS;AAG7B,IAAA,MAAM,aAAa,IAAA,CAAK,GAAA;AAAA,MACtB,CAAA;AAAA,MACA,KAAA,CAAM,IAAA,KAAS,OAAA,GAAW,KAAA,CAAM,cAAc,CAAA,GAAK;AAAA,KACrD;AACA,IAAA,MAAMC,YAAAA,GAAc,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,QAAA,GAAW,UAAA;AACpD,IAAA,MAAM,mBAAmB,mBAAA,CAAoB;AAAA,MAC3C,WAAA,EAAa,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,QAAA;AAAA,MAClC,QAAA,EAAU,OAAA;AAAA,MACV,kBAAA,EAAoB,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,kBAAA;AAAA,MACzC,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,MAAMC,WAAU,gBAAA,GAAmB,UAAA;AAEnC,IAAA,MAAM,mBAAmB,mBAAA,CAAoB;AAAA,MAC3C,WAAA,EAAa,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,QAAA;AAAA,MAClC,QAAA,EAAU,OAAA;AAAA,MACV,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,MAAMC,qBAAoB,gBAAA,GAAmB,UAAA;AAC7C,IAAA,MAAMC,OAAAA,GAAS,eAAA,CAAgB,SAAA,CAAU,OAAA,EAAS,KAAK,KAAK,CAAA;AAC5D,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,OAAA;AAAA,MACN,OAAA;AAAA,MACA,WAAA,EAAa,OAAA;AAAA,MACb,OAAA,EAAAF,QAAAA;AAAA,MACA,iBAAA,EAAAC,kBAAAA;AAAA,MACA,WAAA,EAAAF,YAAAA;AAAA,MACA,SAAA,EAAW;AAAA,QACT,gBAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,UAAA,EAAY,KAAA;AAAA,MACZ,MAAA,EAAAG;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,QAAA,CAAS,SAAS,OAAA,EAAS;AAC7B,IAAA,IAAI,KAAA,CAAM,SAAS,OAAA,EAAS;AAC1B,MAAA,MAAM,IAAI,0BAAA,CAA2B,OAAA,EAAS,OAAA,EAAS,MAAM,IAAI,CAAA;AAAA,IACnE;AACA,IAAA,MAAM,OAAA,GAAU,SAAS,GAAA,CAAI,OAAA;AAG7B,IAAA,MAAM,OAAO,OAAA,CAAQ,WAAA;AACrB,IAAA,MAAM,OAAA,GACJ,KAAA,CAAM,UAAA,IAAc,IAAA,EAAM,UAAA,GACrB,KAAK,UAAA,CAAW,KAAA,CAAM,UAAU,CAAA,IAAK,CAAA,GACtC,CAAA;AACN,IAAA,MAAM,OAAA,GACJ,KAAA,CAAM,QAAA,IAAY,IAAA,EAAM,QAAA,GACnB,KAAK,QAAA,CAAS,KAAA,CAAM,QAAQ,CAAA,IAAK,CAAA,GAClC,CAAA;AACN,IAAA,MAAM,OAAA,GACJ,KAAA,CAAM,IAAA,IAAQ,IAAA,EAAM,IAAA,GAAQ,KAAK,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,IAAK,CAAA,GAAO,CAAA;AAC9D,IAAA,MAAM,iBAAA,GAAoB,UAAU,OAAA,GAAU,OAAA;AAC9C,IAAA,MAAMH,YAAAA,GAAc,QAAQ,QAAA,GAAW,iBAAA;AACvC,IAAA,MAAM,iBAAiB,mBAAA,CAAoB;AAAA,MACzC,aAAa,OAAA,CAAQ,QAAA;AAAA,MACrB,QAAA,EAAU,OAAA;AAAA,MACV,oBAAoB,OAAA,CAAQ,kBAAA;AAAA,MAC5B,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,MAAMC,QAAAA,GAAU,IAAA,CAAK,IAAA,CAAK,cAAA,GAAiB,iBAAiB,CAAA;AAC5D,IAAA,MAAM,iBAAiB,mBAAA,CAAoB;AAAA,MACzC,aAAa,OAAA,CAAQ,QAAA;AAAA,MACrB,QAAA,EAAU,OAAA;AAAA,MACV,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,MAAMC,kBAAAA,GAAoB,IAAA,CAAK,IAAA,CAAK,cAAA,GAAiB,iBAAiB,CAAA;AACtE,IAAA,MAAMC,OAAAA,GAAS,eAAA,CAAgB,SAAA,CAAU,OAAA,EAAS,KAAK,KAAK,CAAA;AAC5D,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,OAAA;AAAA,MACN,OAAA;AAAA,MACA,WAAA,EAAa,OAAA;AAAA,MACb,OAAA,EAAAF,QAAAA;AAAA,MACA,iBAAA,EAAAC,kBAAAA;AAAA,MACA,WAAA,EAAAF,YAAAA;AAAA,MACA,SAAA,EAAW;AAAA,QACT,cAAA;AAAA,QACA,oBAAA,EAAsB,OAAA;AAAA,QACtB,kBAAA,EAAoB,OAAA;AAAA,QACpB,cAAA,EAAgB,OAAA;AAAA,QAChB;AAAA,OACF;AAAA,MACA,UAAA,EAAY,KAAA;AAAA,MACZ,MAAA,EAAAG;AAAA,KACF;AAAA,EACF;AAGA,EAAA,IAAI,KAAA,CAAM,SAAS,OAAA,EAAS;AAC1B,IAAA,MAAM,IAAI,0BAAA,CAA2B,OAAA,EAAS,OAAA,EAAS,MAAM,IAAI,CAAA;AAAA,EACnE;AAEA,EAAA,IAAI,QAAA,CAAS,SAAS,OAAA,EAAS;AAE7B,IAAA,MAAM,QAAA,GAAW,SAAS,KAAA,CAAM,QAAA;AAChC,IAAA,MAAM,eAAA,GAAkB,6BAA6B,QAAQ,CAAA;AAC7D,IAAA,IAAI,CAAC,eAAA,EAAiB,MAAM,IAAI,kBAAkB,OAAO,CAAA;AACzD,IAAA,MAAM,cAAA,GAAiB,aAAA,CAAc,eAAA,EAAiB,KAAA,EAAO,IAAI,CAAA;AACjE,IAAA,OAAO;AAAA,MACL,GAAG,cAAA;AAAA,MACH,OAAA;AAAA,MACA,WAAA,EAAa;AAAA,KACf;AAAA,EACF;AAIA,EAAA,IAAI,SAAS,IAAA,KAAS,OAAA,EAAS,MAAM,IAAI,kBAAkB,OAAO,CAAA;AAClE,EAAA,MAAM,YAAA,GAAe,SAAS,GAAA,CAAI,OAAA;AAQlC,EAAA,MAAM,cAAc,YAAA,CAAa,WAAA;AACjC,EAAA,IAAI,QAAA;AACJ,EAAA,QAAQ,WAAA;AAAa,IACnB,KAAK,cAAA;AACH,MAAA,QAAA,GAAW,KAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,UAAA,IAAc,CAAC,CAAA,GAAI,GAAA;AAChD,MAAA;AAAA,IACF,KAAK,eAAA;AACH,MAAA,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,cAAc,CAAC,CAAA;AAC5C,MAAA;AAAA,IACF,KAAK,YAAA;AACH,MAAA,QAAA,GAAW,IAAA,CAAK,KAAK,IAAA,CAAK,GAAA,CAAI,GAAG,KAAA,CAAM,OAAA,IAAW,CAAC,CAAA,GAAI,EAAE,CAAA;AACzD,MAAA;AAAA,IACF,KAAK,YAAA;AAAA,IACL;AACE,MAAA,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,WAAW,CAAC,CAAA;AACzC,MAAA;AAAA;AAEJ,EAAA,MAAM,WAAA,GAAc,aAAa,QAAA,GAAW,QAAA;AAC5C,EAAA,MAAM,iBAAiB,mBAAA,CAAoB;AAAA,IACzC,aAAa,YAAA,CAAa,QAAA;AAAA,IAC1B,QAAA,EAAU,OAAA;AAAA,IACV,oBAAoB,YAAA,CAAa,kBAAA;AAAA,IACjC,OAAO,IAAA,CAAK;AAAA,GACb,CAAA;AAGD,EAAA,MAAM,OAAA,GACJ,QAAA,GAAW,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAA,CAAK,cAAA,GAAiB,QAAQ,CAAC,CAAA,GAAI,CAAA;AACrE,EAAA,MAAM,iBAAiB,mBAAA,CAAoB;AAAA,IACzC,aAAa,YAAA,CAAa,QAAA;AAAA,IAC1B,QAAA,EAAU,OAAA;AAAA,IACV,OAAO,IAAA,CAAK;AAAA,GACb,CAAA;AACD,EAAA,MAAM,iBAAA,GACJ,QAAA,GAAW,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAA,CAAK,cAAA,GAAiB,QAAQ,CAAC,CAAA,GAAI,CAAA;AACrE,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,SAAA,CAAU,OAAA,EAAS,KAAK,KAAK,CAAA;AAC5D,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,OAAA;AAAA,IACN,OAAA;AAAA,IACA,WAAA,EAAa,OAAA;AAAA,IACb,OAAA;AAAA,IACA,iBAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA,EAAW;AAAA,MACT,cAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,UAAA,EAAY,KAAA;AAAA,IACZ;AAAA,GACF;AACF;AAOO,SAAS,gBAAA,CACd,OAAA,EACA,KAAA,EAMA,IAAA,EACY;AACZ,EAAA,OAAO,aAAA,CAAc,SAAS,EAAE,IAAA,EAAM,OAAO,GAAG,KAAA,IAAS,IAAI,CAAA;AAC/D;AAEO,SAAS,kBAAA,CACd,OAAA,EACA,KAAA,EACA,IAAA,EACY;AACZ,EAAA,OAAO,aAAA,CAAc,SAAS,EAAE,IAAA,EAAM,SAAS,GAAG,KAAA,IAAS,IAAI,CAAA;AACjE;AAEO,SAAS,kBAAA,CACd,OAAA,EACA,KAAA,EACA,IAAA,EACY;AACZ,EAAA,OAAO,aAAA,CAAc,SAAS,EAAE,IAAA,EAAM,SAAS,GAAG,KAAA,IAAS,IAAI,CAAA;AACjE;AAEO,SAAS,kBAAA,CACd,OAAA,EACA,KAAA,EACA,IAAA,EACY;AACZ,EAAA,OAAO,aAAA,CAAc,SAAS,EAAE,IAAA,EAAM,SAAS,GAAG,KAAA,IAAS,IAAI,CAAA;AACjE","file":"chunk-IORIAFK2.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"]}
|