@mastra/observability 1.17.1-alpha.0 → 1.17.1-alpha.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.
- package/CHANGELOG.md +9 -0
- package/README.md +3 -1
- package/dist/index.cjs +73 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +73 -5
- package/dist/index.js.map +1 -1
- package/dist/metrics/estimator.d.ts.map +1 -1
- package/dist/metrics/pricing-registry.d.ts.map +1 -1
- package/dist/metrics/types.d.ts +4 -0
- package/dist/metrics/types.d.ts.map +1 -1
- package/dist/metrics/usage-metrics.d.ts.map +1 -1
- package/dist/usage.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1077,6 +1077,8 @@ const MINIFIED_METER_TO_CANONICAL = {
|
|
|
1077
1077
|
ot: "output_tokens",
|
|
1078
1078
|
icrt: "input_cache_read_tokens",
|
|
1079
1079
|
icwt: "input_cache_write_tokens",
|
|
1080
|
+
icwt5m: "input_cache_write_5m_tokens",
|
|
1081
|
+
icwt1h: "input_cache_write_1h_tokens",
|
|
1080
1082
|
iat: "input_audio_tokens",
|
|
1081
1083
|
oat: "output_audio_tokens",
|
|
1082
1084
|
ort: "output_reasoning_tokens"
|
|
@@ -1133,6 +1135,15 @@ function parsePricingModelText(content) {
|
|
|
1133
1135
|
}
|
|
1134
1136
|
return pricingModels;
|
|
1135
1137
|
}
|
|
1138
|
+
function expandRates(row, tier) {
|
|
1139
|
+
const rates = Object.fromEntries(Object.entries(tier.r).map(([meter, value]) => [MINIFIED_METER_TO_CANONICAL[meter], value.c]));
|
|
1140
|
+
const cacheWriteRate = rates.input_cache_write_tokens;
|
|
1141
|
+
if (row.m.includes("claude") && typeof cacheWriteRate === "number") {
|
|
1142
|
+
rates.input_cache_write_5m_tokens ??= cacheWriteRate;
|
|
1143
|
+
rates.input_cache_write_1h_tokens ??= cacheWriteRate * 1.6;
|
|
1144
|
+
}
|
|
1145
|
+
return rates;
|
|
1146
|
+
}
|
|
1136
1147
|
function expandPricingModelRow(row) {
|
|
1137
1148
|
return new PricingModel({
|
|
1138
1149
|
id: row.i,
|
|
@@ -1147,7 +1158,7 @@ function expandPricingModelRow(row) {
|
|
|
1147
1158
|
op: condition.op,
|
|
1148
1159
|
value: condition.value
|
|
1149
1160
|
})),
|
|
1150
|
-
rates:
|
|
1161
|
+
rates: expandRates(row, tier)
|
|
1151
1162
|
}))
|
|
1152
1163
|
});
|
|
1153
1164
|
}
|
|
@@ -1278,6 +1289,8 @@ const PricingMeter = {
|
|
|
1278
1289
|
INPUT_AUDIO_TOKENS: "input_audio_tokens",
|
|
1279
1290
|
INPUT_CACHE_READ_TOKENS: "input_cache_read_tokens",
|
|
1280
1291
|
INPUT_CACHE_WRITE_TOKENS: "input_cache_write_tokens",
|
|
1292
|
+
INPUT_CACHE_WRITE_5M_TOKENS: "input_cache_write_5m_tokens",
|
|
1293
|
+
INPUT_CACHE_WRITE_1H_TOKENS: "input_cache_write_1h_tokens",
|
|
1281
1294
|
INPUT_IMAGE_TOKENS: "input_image_tokens",
|
|
1282
1295
|
OUTPUT_TOKENS: "output_tokens",
|
|
1283
1296
|
OUTPUT_AUDIO_TOKENS: "output_audio_tokens",
|
|
@@ -1290,6 +1303,8 @@ const TokenMetrics = {
|
|
|
1290
1303
|
INPUT_TEXT: "mastra_model_input_text_tokens",
|
|
1291
1304
|
INPUT_CACHE_READ: "mastra_model_input_cache_read_tokens",
|
|
1292
1305
|
INPUT_CACHE_WRITE: "mastra_model_input_cache_write_tokens",
|
|
1306
|
+
INPUT_CACHE_WRITE_5M: "mastra_model_input_cache_write_5m_tokens",
|
|
1307
|
+
INPUT_CACHE_WRITE_1H: "mastra_model_input_cache_write_1h_tokens",
|
|
1293
1308
|
INPUT_AUDIO: "mastra_model_input_audio_tokens",
|
|
1294
1309
|
INPUT_IMAGE: "mastra_model_input_image_tokens",
|
|
1295
1310
|
OUTPUT_TEXT: "mastra_model_output_text_tokens",
|
|
@@ -1319,6 +1334,8 @@ function getTokenMetricSamples(usage) {
|
|
|
1319
1334
|
pushIfPositive(TokenMetrics.INPUT_TEXT, usage.inputDetails.text);
|
|
1320
1335
|
pushIfPositive(TokenMetrics.INPUT_CACHE_READ, usage.inputDetails.cacheRead);
|
|
1321
1336
|
pushIfPositive(TokenMetrics.INPUT_CACHE_WRITE, usage.inputDetails.cacheWrite);
|
|
1337
|
+
pushIfPositive(TokenMetrics.INPUT_CACHE_WRITE_5M, usage.inputDetails.cacheWrite5m);
|
|
1338
|
+
pushIfPositive(TokenMetrics.INPUT_CACHE_WRITE_1H, usage.inputDetails.cacheWrite1h);
|
|
1322
1339
|
pushIfPositive(TokenMetrics.INPUT_AUDIO, usage.inputDetails.audio);
|
|
1323
1340
|
pushIfPositive(TokenMetrics.INPUT_IMAGE, usage.inputDetails.image);
|
|
1324
1341
|
}
|
|
@@ -1385,15 +1402,40 @@ function estimateCosts(args, pricingRegistry = PricingRegistry.getGlobal()) {
|
|
|
1385
1402
|
results.set(TokenMetrics.INPUT_CACHE_READ, result.costContext);
|
|
1386
1403
|
inputDetailResults.push(result);
|
|
1387
1404
|
}
|
|
1388
|
-
|
|
1405
|
+
const cacheWriteDetailResults = [];
|
|
1406
|
+
const cacheWrite5m = usage.inputDetails?.cacheWrite5m ?? 0;
|
|
1407
|
+
const cacheWrite1h = usage.inputDetails?.cacheWrite1h ?? 0;
|
|
1408
|
+
if (cacheWrite5m > 0) {
|
|
1409
|
+
const result = estimateCostForMeter({
|
|
1410
|
+
meter: PricingMeter.INPUT_CACHE_WRITE_5M_TOKENS,
|
|
1411
|
+
tokenCount: cacheWrite5m,
|
|
1412
|
+
...estimateFields
|
|
1413
|
+
});
|
|
1414
|
+
results.set(TokenMetrics.INPUT_CACHE_WRITE_5M, result.costContext);
|
|
1415
|
+
cacheWriteDetailResults.push(result);
|
|
1416
|
+
inputDetailResults.push(result);
|
|
1417
|
+
}
|
|
1418
|
+
if (cacheWrite1h > 0) {
|
|
1419
|
+
const result = estimateCostForMeter({
|
|
1420
|
+
meter: PricingMeter.INPUT_CACHE_WRITE_1H_TOKENS,
|
|
1421
|
+
tokenCount: cacheWrite1h,
|
|
1422
|
+
...estimateFields
|
|
1423
|
+
});
|
|
1424
|
+
results.set(TokenMetrics.INPUT_CACHE_WRITE_1H, result.costContext);
|
|
1425
|
+
cacheWriteDetailResults.push(result);
|
|
1426
|
+
inputDetailResults.push(result);
|
|
1427
|
+
}
|
|
1428
|
+
const unclassifiedCacheWrite = Math.max(0, (usage.inputDetails?.cacheWrite ?? 0) - cacheWrite5m - cacheWrite1h);
|
|
1429
|
+
if (unclassifiedCacheWrite > 0) {
|
|
1389
1430
|
const result = estimateCostForMeter({
|
|
1390
1431
|
meter: PricingMeter.INPUT_CACHE_WRITE_TOKENS,
|
|
1391
|
-
tokenCount:
|
|
1432
|
+
tokenCount: unclassifiedCacheWrite,
|
|
1392
1433
|
...estimateFields
|
|
1393
1434
|
});
|
|
1394
|
-
|
|
1435
|
+
cacheWriteDetailResults.push(result);
|
|
1395
1436
|
inputDetailResults.push(result);
|
|
1396
1437
|
}
|
|
1438
|
+
if (cacheWriteDetailResults.length > 0) setCombinedCostContext(results, TokenMetrics.INPUT_CACHE_WRITE, cacheWriteDetailResults, pricingModel, costMetadata);
|
|
1397
1439
|
if (usage.inputDetails?.image) {
|
|
1398
1440
|
const result = estimateCostForMeter({
|
|
1399
1441
|
meter: PricingMeter.INPUT_IMAGE_TOKENS,
|
|
@@ -1470,6 +1512,20 @@ function estimateCosts(args, pricingRegistry = PricingRegistry.getGlobal()) {
|
|
|
1470
1512
|
function applyErrorContextForUsage(results, usage, errorContext) {
|
|
1471
1513
|
for (const sample of getTokenMetricSamples(usage)) results.set(sample.name, errorContext);
|
|
1472
1514
|
}
|
|
1515
|
+
function setCombinedCostContext(results, metric, detailResults, pricingModel, costMetadata) {
|
|
1516
|
+
const estimatedCosts = detailResults.map((result) => result.costContext.estimatedCost).filter((value) => typeof value === "number");
|
|
1517
|
+
const hasFailedCost = detailResults.some((result) => !result.success);
|
|
1518
|
+
results.set(metric, {
|
|
1519
|
+
provider: pricingModel.provider,
|
|
1520
|
+
model: pricingModel.model,
|
|
1521
|
+
...estimatedCosts.length > 0 && { estimatedCost: estimatedCosts.reduce((sum, value) => sum + value, 0) },
|
|
1522
|
+
...estimatedCosts.length > 0 && { costUnit: pricingModel.currency },
|
|
1523
|
+
costMetadata: hasFailedCost ? {
|
|
1524
|
+
...costMetadata,
|
|
1525
|
+
error: "partial_cost"
|
|
1526
|
+
} : { ...costMetadata }
|
|
1527
|
+
});
|
|
1528
|
+
}
|
|
1473
1529
|
function setAggregateCostContext(args) {
|
|
1474
1530
|
const { results, totalMetric, fallbackMeter, totalTokenCount, detailResults, pricingModel, pricingTier, costMetadata } = args;
|
|
1475
1531
|
if (totalTokenCount == null) return;
|
|
@@ -1710,14 +1766,24 @@ function extractUsageMetrics(usage, providerMetadata) {
|
|
|
1710
1766
|
if (isDefined(aiSdkDetails?.cacheReadTokens)) inputDetails.cacheRead = aiSdkDetails.cacheReadTokens;
|
|
1711
1767
|
if (isDefined(aiSdkDetails?.cacheWriteTokens)) inputDetails.cacheWrite = aiSdkDetails.cacheWriteTokens;
|
|
1712
1768
|
if (!isDefined(inputDetails.cacheRead) && isDefined(usage.cachedInputTokens)) inputDetails.cacheRead = usage.cachedInputTokens;
|
|
1769
|
+
if (isDefined(usage.cacheCreationInputTokens5m)) inputDetails.cacheWrite5m = usage.cacheCreationInputTokens5m;
|
|
1770
|
+
if (isDefined(usage.cacheCreationInputTokens1h)) inputDetails.cacheWrite1h = usage.cacheCreationInputTokens1h;
|
|
1713
1771
|
if (!isDefined(inputDetails.cacheWrite) && isDefined(usage.cacheCreationInputTokens)) inputDetails.cacheWrite = usage.cacheCreationInputTokens;
|
|
1772
|
+
if (!isDefined(inputDetails.cacheWrite) && (isDefined(inputDetails.cacheWrite5m) || isDefined(inputDetails.cacheWrite1h))) inputDetails.cacheWrite = (inputDetails.cacheWrite5m ?? 0) + (inputDetails.cacheWrite1h ?? 0);
|
|
1714
1773
|
if (isDefined(usage.reasoningTokens)) outputDetails.reasoning = usage.reasoningTokens;
|
|
1715
1774
|
const anthropic = providerMetadata?.anthropic;
|
|
1716
1775
|
if (anthropic) {
|
|
1717
1776
|
const rawV3InputUsage = isV3RawUsage(usage.raw) ? usage.raw.inputTokens : void 0;
|
|
1718
1777
|
const hasV3CachedTotals = rawV3InputUsage?.total !== void 0 && (rawV3InputUsage.cacheRead !== void 0 || rawV3InputUsage.cacheWrite !== void 0);
|
|
1719
1778
|
if (!isDefined(inputDetails.cacheRead) && isDefined(anthropic.cacheReadInputTokens)) inputDetails.cacheRead = anthropic.cacheReadInputTokens;
|
|
1720
|
-
|
|
1779
|
+
const cacheWrite5m = anthropic.cacheCreation?.ephemeral_5m_input_tokens ?? anthropic.cacheCreation?.ephemeral5mInputTokens;
|
|
1780
|
+
const cacheWrite1h = anthropic.cacheCreation?.ephemeral_1h_input_tokens ?? anthropic.cacheCreation?.ephemeral1hInputTokens;
|
|
1781
|
+
if (!isDefined(inputDetails.cacheWrite5m) && isDefined(cacheWrite5m)) inputDetails.cacheWrite5m = cacheWrite5m;
|
|
1782
|
+
if (!isDefined(inputDetails.cacheWrite1h) && isDefined(cacheWrite1h)) inputDetails.cacheWrite1h = cacheWrite1h;
|
|
1783
|
+
if (!isDefined(inputDetails.cacheWrite)) {
|
|
1784
|
+
if (isDefined(anthropic.cacheCreationInputTokens)) inputDetails.cacheWrite = anthropic.cacheCreationInputTokens;
|
|
1785
|
+
else if (isDefined(cacheWrite5m) || isDefined(cacheWrite1h)) inputDetails.cacheWrite = (cacheWrite5m ?? 0) + (cacheWrite1h ?? 0);
|
|
1786
|
+
}
|
|
1721
1787
|
if (!(hasV3CachedTotals || isDefined(usage.cachedInputTokens) && usage.cachedInputTokens > 0 || isDefined(usage.cacheCreationInputTokens) && usage.cacheCreationInputTokens > 0) && (isDefined(inputDetails.cacheRead) || isDefined(inputDetails.cacheWrite))) inputTokens = (usage.inputTokens ?? 0) + (inputDetails.cacheRead ?? 0) + (inputDetails.cacheWrite ?? 0);
|
|
1722
1788
|
}
|
|
1723
1789
|
const google = providerMetadata?.google;
|
|
@@ -1758,6 +1824,8 @@ function mergeInputDetails(a, b) {
|
|
|
1758
1824
|
text: addOptional(a.text, b.text),
|
|
1759
1825
|
cacheRead: addOptional(a.cacheRead, b.cacheRead),
|
|
1760
1826
|
cacheWrite: addOptional(a.cacheWrite, b.cacheWrite),
|
|
1827
|
+
cacheWrite5m: addOptional(a.cacheWrite5m, b.cacheWrite5m),
|
|
1828
|
+
cacheWrite1h: addOptional(a.cacheWrite1h, b.cacheWrite1h),
|
|
1761
1829
|
audio: addOptional(a.audio, b.audio),
|
|
1762
1830
|
image: addOptional(a.image, b.image)
|
|
1763
1831
|
};
|