usage-tab 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -2
- package/dist/index.cjs +82 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -2
- package/dist/index.d.ts +65 -2
- package/dist/index.js +82 -14
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.d.cts
CHANGED
|
@@ -201,7 +201,18 @@ interface PriceRequest {
|
|
|
201
201
|
readonly usage: LlmUsage | unknown;
|
|
202
202
|
/** `'batch'` applies the resolved period's `batchMultiplier` when one is published; falls back to standard pricing (with a warning) otherwise. */
|
|
203
203
|
readonly mode?: PriceMode;
|
|
204
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* Effective date for pricing-period selection. Defaults to `new Date()`.
|
|
206
|
+
*
|
|
207
|
+
* Pricing periods start at UTC midnight, so every ISO string form is read
|
|
208
|
+
* as UTC: an ISO date (`'2026-09-01'`) and an offset-carrying datetime
|
|
209
|
+
* (`'2026-09-01T05:00:00Z'`) already are, and one *without* an offset
|
|
210
|
+
* (`'2026-09-01T05:00:00'` — a log timestamp, a `datetime-local` input,
|
|
211
|
+
* several DB drivers) is read as UTC too, rather than in whatever timezone
|
|
212
|
+
* the process happens to run. A non-ISO string (`'2026/09/01'`,
|
|
213
|
+
* `'September 1, 2026'`) is implementation-defined and local in practice —
|
|
214
|
+
* pass a `Date` or an ISO form instead.
|
|
215
|
+
*/
|
|
205
216
|
readonly at?: Date | string;
|
|
206
217
|
}
|
|
207
218
|
interface CostLine {
|
|
@@ -323,6 +334,32 @@ interface CustomPriceInput {
|
|
|
323
334
|
readonly observedAt?: string;
|
|
324
335
|
readonly notes?: readonly string[];
|
|
325
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* An exact running total over one or more `CostBreakdown`s — see
|
|
339
|
+
* `createCostAggregator`.
|
|
340
|
+
*/
|
|
341
|
+
interface CostTotal {
|
|
342
|
+
/** How many breakdowns this total covers. */
|
|
343
|
+
readonly count: number;
|
|
344
|
+
/** Ergonomic numeric total. Not the authoritative value — see `totalUsdExact`. */
|
|
345
|
+
readonly totalUsd: number;
|
|
346
|
+
/** Exact decimal string total, summed with the same fixed-point arithmetic each individual cost was computed with. */
|
|
347
|
+
readonly totalUsdExact: string;
|
|
348
|
+
/**
|
|
349
|
+
* Every distinct `registryVersion` the aggregated breakdowns were priced
|
|
350
|
+
* against, sorted. More than one means the total mixes pricing snapshots —
|
|
351
|
+
* expected for a report spanning a registry update, a bug for a total meant
|
|
352
|
+
* to be reproducible against a single one.
|
|
353
|
+
*/
|
|
354
|
+
readonly registryVersions: readonly string[];
|
|
355
|
+
}
|
|
356
|
+
interface CostAggregator {
|
|
357
|
+
/** Adds one breakdown to the running totals. Throws `InvalidRateError` if its `totalUsdExact` is not a non-negative decimal string. */
|
|
358
|
+
add(breakdown: CostBreakdown): void;
|
|
359
|
+
total(): CostTotal;
|
|
360
|
+
/** Per-model totals, keyed `` `${provider}:${canonicalModel}` `` — the resolved identity, so two aliases of one model share a bucket. */
|
|
361
|
+
byModel(): ReadonlyMap<string, CostTotal>;
|
|
362
|
+
}
|
|
326
363
|
|
|
327
364
|
declare function calculateCost(request: PriceRequest, options?: PriceOptions): CostBreakdown;
|
|
328
365
|
|
|
@@ -345,6 +382,32 @@ declare function createPriceCalculator(defaults?: PriceCalculatorOptions): Price
|
|
|
345
382
|
*/
|
|
346
383
|
declare function createPriceOverride(input: CustomPriceInput): ModelDescriptor;
|
|
347
384
|
|
|
385
|
+
/**
|
|
386
|
+
* Exact sum of decimal USD strings — `totalUsdExact`/`costUsdExact` values,
|
|
387
|
+
* or any string in the same non-negative decimal format. Returns a decimal
|
|
388
|
+
* string in that same format (`"0.00"` for an empty list).
|
|
389
|
+
*
|
|
390
|
+
* Throws `InvalidRateError` (`INVALID_RATE`) for anything that is not a
|
|
391
|
+
* non-negative decimal string, rather than coercing it: a stringified
|
|
392
|
+
* `NaN`, a float-formatted `"1e-7"`, or a `number` that slipped past a
|
|
393
|
+
* `readonly string[]` at the type level are all silent under-reporting
|
|
394
|
+
* waiting to happen.
|
|
395
|
+
*/
|
|
396
|
+
declare function sumExactUsd(values: readonly string[]): string;
|
|
397
|
+
/**
|
|
398
|
+
* Accumulates `CostBreakdown`s into exact running totals — overall and per
|
|
399
|
+
* `provider:canonicalModel`. Sums are kept as exact fixed-point amounts, so
|
|
400
|
+
* memory does not grow with the number of breakdowns added; only the number
|
|
401
|
+
* of distinct models does.
|
|
402
|
+
*
|
|
403
|
+
* `total().registryVersions` carries the aggregate's provenance: more than
|
|
404
|
+
* one entry means the total mixes pricing snapshots, which is legitimate for
|
|
405
|
+
* a historical report spanning a registry update and a bug for a total that
|
|
406
|
+
* was supposed to be priced against one snapshot. This package cannot tell
|
|
407
|
+
* the two apart, so it reports rather than warns.
|
|
408
|
+
*/
|
|
409
|
+
declare function createCostAggregator(): CostAggregator;
|
|
410
|
+
|
|
348
411
|
/**
|
|
349
412
|
* Stable error types this package throws directly. `resolveModel` and
|
|
350
413
|
* `calculateCost` also propagate `AmbiguousAliasError`, `UnknownModelError`,
|
|
@@ -417,4 +480,4 @@ declare function normalizeGoogleUsage(value: unknown): NormalizedUsageResult;
|
|
|
417
480
|
|
|
418
481
|
declare function normalizeOpenAICompatibleUsage(value: unknown): NormalizedUsageResult;
|
|
419
482
|
|
|
420
|
-
export { AmbiguousAliasError, type CostBreakdown, type CostLine, type CustomPriceInput, InvalidLookupDateError, InvalidRateError, InvalidTokenCountError, InvalidUsageError, type LlmUsage, MODEL_REGISTRY, type ModelCandidate, type ModelDescriptor, NoPricingPeriodError, type NormalizedUsageResult, type PriceCalculator, type PriceCalculatorOptions, type PriceMode, type PriceOptions, type PriceRequest, type PriceWarning, type PriceWarningCode, type PricingPeriod, type ProviderId, REGISTRY_VERSION, type RegistrySource, type ResolveModelOptions, type ResolvedModel, UnknownModelError, calculateCost, createPriceCalculator, createPriceOverride, normalizeAnthropicUsage, normalizeGoogleUsage, normalizeOpenAICompatibleUsage, normalizeOpenAIUsage, resolveModel };
|
|
483
|
+
export { AmbiguousAliasError, type CostAggregator, type CostBreakdown, type CostLine, type CostTotal, type CustomPriceInput, InvalidLookupDateError, InvalidRateError, InvalidTokenCountError, InvalidUsageError, type LlmUsage, MODEL_REGISTRY, type ModelCandidate, type ModelDescriptor, NoPricingPeriodError, type NormalizedUsageResult, type PriceCalculator, type PriceCalculatorOptions, type PriceMode, type PriceOptions, type PriceRequest, type PriceWarning, type PriceWarningCode, type PricingPeriod, type ProviderId, REGISTRY_VERSION, type RegistrySource, type ResolveModelOptions, type ResolvedModel, UnknownModelError, calculateCost, createCostAggregator, createPriceCalculator, createPriceOverride, normalizeAnthropicUsage, normalizeGoogleUsage, normalizeOpenAICompatibleUsage, normalizeOpenAIUsage, resolveModel, sumExactUsd };
|
package/dist/index.d.ts
CHANGED
|
@@ -201,7 +201,18 @@ interface PriceRequest {
|
|
|
201
201
|
readonly usage: LlmUsage | unknown;
|
|
202
202
|
/** `'batch'` applies the resolved period's `batchMultiplier` when one is published; falls back to standard pricing (with a warning) otherwise. */
|
|
203
203
|
readonly mode?: PriceMode;
|
|
204
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* Effective date for pricing-period selection. Defaults to `new Date()`.
|
|
206
|
+
*
|
|
207
|
+
* Pricing periods start at UTC midnight, so every ISO string form is read
|
|
208
|
+
* as UTC: an ISO date (`'2026-09-01'`) and an offset-carrying datetime
|
|
209
|
+
* (`'2026-09-01T05:00:00Z'`) already are, and one *without* an offset
|
|
210
|
+
* (`'2026-09-01T05:00:00'` — a log timestamp, a `datetime-local` input,
|
|
211
|
+
* several DB drivers) is read as UTC too, rather than in whatever timezone
|
|
212
|
+
* the process happens to run. A non-ISO string (`'2026/09/01'`,
|
|
213
|
+
* `'September 1, 2026'`) is implementation-defined and local in practice —
|
|
214
|
+
* pass a `Date` or an ISO form instead.
|
|
215
|
+
*/
|
|
205
216
|
readonly at?: Date | string;
|
|
206
217
|
}
|
|
207
218
|
interface CostLine {
|
|
@@ -323,6 +334,32 @@ interface CustomPriceInput {
|
|
|
323
334
|
readonly observedAt?: string;
|
|
324
335
|
readonly notes?: readonly string[];
|
|
325
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* An exact running total over one or more `CostBreakdown`s — see
|
|
339
|
+
* `createCostAggregator`.
|
|
340
|
+
*/
|
|
341
|
+
interface CostTotal {
|
|
342
|
+
/** How many breakdowns this total covers. */
|
|
343
|
+
readonly count: number;
|
|
344
|
+
/** Ergonomic numeric total. Not the authoritative value — see `totalUsdExact`. */
|
|
345
|
+
readonly totalUsd: number;
|
|
346
|
+
/** Exact decimal string total, summed with the same fixed-point arithmetic each individual cost was computed with. */
|
|
347
|
+
readonly totalUsdExact: string;
|
|
348
|
+
/**
|
|
349
|
+
* Every distinct `registryVersion` the aggregated breakdowns were priced
|
|
350
|
+
* against, sorted. More than one means the total mixes pricing snapshots —
|
|
351
|
+
* expected for a report spanning a registry update, a bug for a total meant
|
|
352
|
+
* to be reproducible against a single one.
|
|
353
|
+
*/
|
|
354
|
+
readonly registryVersions: readonly string[];
|
|
355
|
+
}
|
|
356
|
+
interface CostAggregator {
|
|
357
|
+
/** Adds one breakdown to the running totals. Throws `InvalidRateError` if its `totalUsdExact` is not a non-negative decimal string. */
|
|
358
|
+
add(breakdown: CostBreakdown): void;
|
|
359
|
+
total(): CostTotal;
|
|
360
|
+
/** Per-model totals, keyed `` `${provider}:${canonicalModel}` `` — the resolved identity, so two aliases of one model share a bucket. */
|
|
361
|
+
byModel(): ReadonlyMap<string, CostTotal>;
|
|
362
|
+
}
|
|
326
363
|
|
|
327
364
|
declare function calculateCost(request: PriceRequest, options?: PriceOptions): CostBreakdown;
|
|
328
365
|
|
|
@@ -345,6 +382,32 @@ declare function createPriceCalculator(defaults?: PriceCalculatorOptions): Price
|
|
|
345
382
|
*/
|
|
346
383
|
declare function createPriceOverride(input: CustomPriceInput): ModelDescriptor;
|
|
347
384
|
|
|
385
|
+
/**
|
|
386
|
+
* Exact sum of decimal USD strings — `totalUsdExact`/`costUsdExact` values,
|
|
387
|
+
* or any string in the same non-negative decimal format. Returns a decimal
|
|
388
|
+
* string in that same format (`"0.00"` for an empty list).
|
|
389
|
+
*
|
|
390
|
+
* Throws `InvalidRateError` (`INVALID_RATE`) for anything that is not a
|
|
391
|
+
* non-negative decimal string, rather than coercing it: a stringified
|
|
392
|
+
* `NaN`, a float-formatted `"1e-7"`, or a `number` that slipped past a
|
|
393
|
+
* `readonly string[]` at the type level are all silent under-reporting
|
|
394
|
+
* waiting to happen.
|
|
395
|
+
*/
|
|
396
|
+
declare function sumExactUsd(values: readonly string[]): string;
|
|
397
|
+
/**
|
|
398
|
+
* Accumulates `CostBreakdown`s into exact running totals — overall and per
|
|
399
|
+
* `provider:canonicalModel`. Sums are kept as exact fixed-point amounts, so
|
|
400
|
+
* memory does not grow with the number of breakdowns added; only the number
|
|
401
|
+
* of distinct models does.
|
|
402
|
+
*
|
|
403
|
+
* `total().registryVersions` carries the aggregate's provenance: more than
|
|
404
|
+
* one entry means the total mixes pricing snapshots, which is legitimate for
|
|
405
|
+
* a historical report spanning a registry update and a bug for a total that
|
|
406
|
+
* was supposed to be priced against one snapshot. This package cannot tell
|
|
407
|
+
* the two apart, so it reports rather than warns.
|
|
408
|
+
*/
|
|
409
|
+
declare function createCostAggregator(): CostAggregator;
|
|
410
|
+
|
|
348
411
|
/**
|
|
349
412
|
* Stable error types this package throws directly. `resolveModel` and
|
|
350
413
|
* `calculateCost` also propagate `AmbiguousAliasError`, `UnknownModelError`,
|
|
@@ -417,4 +480,4 @@ declare function normalizeGoogleUsage(value: unknown): NormalizedUsageResult;
|
|
|
417
480
|
|
|
418
481
|
declare function normalizeOpenAICompatibleUsage(value: unknown): NormalizedUsageResult;
|
|
419
482
|
|
|
420
|
-
export { AmbiguousAliasError, type CostBreakdown, type CostLine, type CustomPriceInput, InvalidLookupDateError, InvalidRateError, InvalidTokenCountError, InvalidUsageError, type LlmUsage, MODEL_REGISTRY, type ModelCandidate, type ModelDescriptor, NoPricingPeriodError, type NormalizedUsageResult, type PriceCalculator, type PriceCalculatorOptions, type PriceMode, type PriceOptions, type PriceRequest, type PriceWarning, type PriceWarningCode, type PricingPeriod, type ProviderId, REGISTRY_VERSION, type RegistrySource, type ResolveModelOptions, type ResolvedModel, UnknownModelError, calculateCost, createPriceCalculator, createPriceOverride, normalizeAnthropicUsage, normalizeGoogleUsage, normalizeOpenAICompatibleUsage, normalizeOpenAIUsage, resolveModel };
|
|
483
|
+
export { AmbiguousAliasError, type CostAggregator, type CostBreakdown, type CostLine, type CostTotal, type CustomPriceInput, InvalidLookupDateError, InvalidRateError, InvalidTokenCountError, InvalidUsageError, type LlmUsage, MODEL_REGISTRY, type ModelCandidate, type ModelDescriptor, NoPricingPeriodError, type NormalizedUsageResult, type PriceCalculator, type PriceCalculatorOptions, type PriceMode, type PriceOptions, type PriceRequest, type PriceWarning, type PriceWarningCode, type PricingPeriod, type ProviderId, REGISTRY_VERSION, type RegistrySource, type ResolveModelOptions, type ResolvedModel, UnknownModelError, calculateCost, createCostAggregator, createPriceCalculator, createPriceOverride, normalizeAnthropicUsage, normalizeGoogleUsage, normalizeOpenAICompatibleUsage, normalizeOpenAIUsage, resolveModel, sumExactUsd };
|
package/dist/index.js
CHANGED
|
@@ -80,8 +80,9 @@ function toCandidate(descriptor) {
|
|
|
80
80
|
}
|
|
81
81
|
function matchExact(pool, id, provider) {
|
|
82
82
|
if (provider !== void 0) {
|
|
83
|
-
const canonical = pool.
|
|
84
|
-
if (canonical
|
|
83
|
+
const canonical = pool.filter((d) => d.provider === provider && d.canonicalId === id);
|
|
84
|
+
if (canonical.length === 1) return { unique: canonical[0] };
|
|
85
|
+
if (canonical.length > 1) return { ambiguous: canonical };
|
|
85
86
|
const scoped = pool.filter((d) => d.provider === provider && d.aliases.includes(id));
|
|
86
87
|
if (scoped.length === 1) return { unique: scoped[0] };
|
|
87
88
|
if (scoped.length > 1) return { ambiguous: scoped };
|
|
@@ -109,16 +110,22 @@ function resolveModel(requestedId, registry, options = {}) {
|
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
if (provider !== void 0) {
|
|
112
|
-
const canonical = registry.
|
|
113
|
+
const canonical = registry.filter(
|
|
113
114
|
(d) => d.provider === provider && d.canonicalId === requestedId
|
|
114
115
|
);
|
|
115
|
-
if (canonical
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
if (canonical.length === 1) {
|
|
117
|
+
const descriptor = canonical[0];
|
|
118
|
+
if (descriptor !== void 0) {
|
|
119
|
+
return {
|
|
120
|
+
descriptor,
|
|
121
|
+
matchedBy: "canonical-qualified",
|
|
122
|
+
requestedId,
|
|
123
|
+
requestedProvider: provider
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (canonical.length > 1) {
|
|
128
|
+
throw new AmbiguousAliasError(requestedId, canonical.map(toCandidate));
|
|
122
129
|
}
|
|
123
130
|
const scoped = registry.filter(
|
|
124
131
|
(d) => d.provider === provider && d.aliases.includes(requestedId)
|
|
@@ -172,10 +179,16 @@ function resolveModel(requestedId, registry, options = {}) {
|
|
|
172
179
|
}
|
|
173
180
|
|
|
174
181
|
// ../../internal/model-registry/src/pricing-period.ts
|
|
182
|
+
var OFFSETLESS_ISO_DATETIME = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d+)?)?$/;
|
|
175
183
|
function toTimestamp(value) {
|
|
176
|
-
|
|
184
|
+
if (value instanceof Date) {
|
|
185
|
+
const ms2 = value.getTime();
|
|
186
|
+
if (Number.isNaN(ms2)) throw new InvalidLookupDateError(String(value));
|
|
187
|
+
return ms2;
|
|
188
|
+
}
|
|
189
|
+
const ms = Date.parse(OFFSETLESS_ISO_DATETIME.test(value) ? `${value}Z` : value);
|
|
177
190
|
if (Number.isNaN(ms)) {
|
|
178
|
-
throw new InvalidLookupDateError(value
|
|
191
|
+
throw new InvalidLookupDateError(value);
|
|
179
192
|
}
|
|
180
193
|
return ms;
|
|
181
194
|
}
|
|
@@ -1507,7 +1520,7 @@ var InvalidRateError = class extends Error {
|
|
|
1507
1520
|
var ZERO = { numerator: 0n, scale: 0 };
|
|
1508
1521
|
var DECIMAL_PATTERN = /^\d+(\.\d+)?$/;
|
|
1509
1522
|
function parseDecimalRate(value, field) {
|
|
1510
|
-
if (!DECIMAL_PATTERN.test(value)) {
|
|
1523
|
+
if (typeof value !== "string" || !DECIMAL_PATTERN.test(value)) {
|
|
1511
1524
|
throw new InvalidRateError(field, value);
|
|
1512
1525
|
}
|
|
1513
1526
|
const dot = value.indexOf(".");
|
|
@@ -1941,6 +1954,59 @@ function createPriceOverride(input) {
|
|
|
1941
1954
|
};
|
|
1942
1955
|
}
|
|
1943
1956
|
|
|
1957
|
+
// src/aggregate.ts
|
|
1958
|
+
function sumExactUsd(values) {
|
|
1959
|
+
const amounts = [];
|
|
1960
|
+
for (const [index, value] of values.entries()) {
|
|
1961
|
+
amounts.push(parseDecimalRate(value, `values[${String(index)}]`));
|
|
1962
|
+
}
|
|
1963
|
+
return formatExact(addExact(amounts));
|
|
1964
|
+
}
|
|
1965
|
+
function modelKey(breakdown) {
|
|
1966
|
+
return `${breakdown.provider}:${breakdown.canonicalModel}`;
|
|
1967
|
+
}
|
|
1968
|
+
function newBucket() {
|
|
1969
|
+
return { count: 0, sum: ZERO, registryVersions: /* @__PURE__ */ new Set() };
|
|
1970
|
+
}
|
|
1971
|
+
function accumulate(bucket, amount, registryVersion) {
|
|
1972
|
+
bucket.count += 1;
|
|
1973
|
+
bucket.sum = addExact([bucket.sum, amount]);
|
|
1974
|
+
bucket.registryVersions.add(registryVersion);
|
|
1975
|
+
}
|
|
1976
|
+
function toTotal(bucket) {
|
|
1977
|
+
return {
|
|
1978
|
+
count: bucket.count,
|
|
1979
|
+
totalUsd: toDisplayNumber(bucket.sum),
|
|
1980
|
+
totalUsdExact: formatExact(bucket.sum),
|
|
1981
|
+
registryVersions: [...bucket.registryVersions].sort()
|
|
1982
|
+
};
|
|
1983
|
+
}
|
|
1984
|
+
function createCostAggregator() {
|
|
1985
|
+
const overall = newBucket();
|
|
1986
|
+
const byModelBuckets = /* @__PURE__ */ new Map();
|
|
1987
|
+
return {
|
|
1988
|
+
add(breakdown) {
|
|
1989
|
+
const amount = parseDecimalRate(breakdown.totalUsdExact, "totalUsdExact");
|
|
1990
|
+
const key = modelKey(breakdown);
|
|
1991
|
+
let bucket = byModelBuckets.get(key);
|
|
1992
|
+
if (bucket === void 0) {
|
|
1993
|
+
bucket = newBucket();
|
|
1994
|
+
byModelBuckets.set(key, bucket);
|
|
1995
|
+
}
|
|
1996
|
+
accumulate(bucket, amount, breakdown.registryVersion);
|
|
1997
|
+
accumulate(overall, amount, breakdown.registryVersion);
|
|
1998
|
+
},
|
|
1999
|
+
total() {
|
|
2000
|
+
return toTotal(overall);
|
|
2001
|
+
},
|
|
2002
|
+
byModel() {
|
|
2003
|
+
const result = /* @__PURE__ */ new Map();
|
|
2004
|
+
for (const [key, bucket] of byModelBuckets) result.set(key, toTotal(bucket));
|
|
2005
|
+
return result;
|
|
2006
|
+
}
|
|
2007
|
+
};
|
|
2008
|
+
}
|
|
2009
|
+
|
|
1944
2010
|
// src/normalize/openai.ts
|
|
1945
2011
|
var KNOWN_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
1946
2012
|
"prompt_tokens",
|
|
@@ -2139,12 +2205,14 @@ export {
|
|
|
2139
2205
|
REGISTRY_VERSION,
|
|
2140
2206
|
UnknownModelError,
|
|
2141
2207
|
calculateCost,
|
|
2208
|
+
createCostAggregator,
|
|
2142
2209
|
createPriceCalculator,
|
|
2143
2210
|
createPriceOverride,
|
|
2144
2211
|
normalizeAnthropicUsage,
|
|
2145
2212
|
normalizeGoogleUsage,
|
|
2146
2213
|
normalizeOpenAICompatibleUsage,
|
|
2147
2214
|
normalizeOpenAIUsage,
|
|
2148
|
-
resolveModel2 as resolveModel
|
|
2215
|
+
resolveModel2 as resolveModel,
|
|
2216
|
+
sumExactUsd
|
|
2149
2217
|
};
|
|
2150
2218
|
//# sourceMappingURL=index.js.map
|