@mastra/observability 1.12.0 → 1.13.0-alpha.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/CHANGELOG.md +15 -0
- package/dist/features.d.ts.map +1 -1
- package/dist/index.cjs +114 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +114 -2
- package/dist/index.js.map +1 -1
- package/dist/instances/base.d.ts +35 -1
- package/dist/instances/base.d.ts.map +1 -1
- package/dist/metrics/auto-extract.d.ts +11 -1
- package/dist/metrics/auto-extract.d.ts.map +1 -1
- package/dist/usage.d.ts +7 -0
- package/dist/usage.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -19021,6 +19021,7 @@ var PricingRegistry = class _PricingRegistry {
|
|
|
19021
19021
|
constructor(pricingModels) {
|
|
19022
19022
|
this.pricingModels = pricingModels;
|
|
19023
19023
|
}
|
|
19024
|
+
pricingModels;
|
|
19024
19025
|
static globalRegistry = null;
|
|
19025
19026
|
static fromText(pricingModelText) {
|
|
19026
19027
|
return new _PricingRegistry(parsePricingModelText(pricingModelText));
|
|
@@ -19424,6 +19425,9 @@ function emitTokenMetrics(span, metrics) {
|
|
|
19424
19425
|
}
|
|
19425
19426
|
emitUsageMetrics(attrs, attrs.usage, metrics);
|
|
19426
19427
|
}
|
|
19428
|
+
function emitTokenMetricsForUsage(usage, provider, model, metrics) {
|
|
19429
|
+
emitUsageMetrics({ provider, model }, usage, metrics);
|
|
19430
|
+
}
|
|
19427
19431
|
function emitAutoExtractedMetrics(span, metrics) {
|
|
19428
19432
|
emitDurationMetrics(span, metrics);
|
|
19429
19433
|
emitTokenMetrics(span, metrics);
|
|
@@ -19585,6 +19589,46 @@ function extractUsageMetrics(usage, providerMetadata) {
|
|
|
19585
19589
|
function sumDefinedValues(obj, keys) {
|
|
19586
19590
|
return keys.reduce((sum, key) => sum + (obj[key] ?? 0), 0);
|
|
19587
19591
|
}
|
|
19592
|
+
function addOptional(a, b) {
|
|
19593
|
+
if (a === void 0 && b === void 0) return void 0;
|
|
19594
|
+
return (a ?? 0) + (b ?? 0);
|
|
19595
|
+
}
|
|
19596
|
+
function mergeInputDetails(a, b) {
|
|
19597
|
+
if (!a) return b ? { ...b } : void 0;
|
|
19598
|
+
if (!b) return { ...a };
|
|
19599
|
+
return {
|
|
19600
|
+
text: addOptional(a.text, b.text),
|
|
19601
|
+
cacheRead: addOptional(a.cacheRead, b.cacheRead),
|
|
19602
|
+
cacheWrite: addOptional(a.cacheWrite, b.cacheWrite),
|
|
19603
|
+
audio: addOptional(a.audio, b.audio),
|
|
19604
|
+
image: addOptional(a.image, b.image)
|
|
19605
|
+
};
|
|
19606
|
+
}
|
|
19607
|
+
function mergeOutputDetails(a, b) {
|
|
19608
|
+
if (!a) return b ? { ...b } : void 0;
|
|
19609
|
+
if (!b) return { ...a };
|
|
19610
|
+
return {
|
|
19611
|
+
text: addOptional(a.text, b.text),
|
|
19612
|
+
reasoning: addOptional(a.reasoning, b.reasoning),
|
|
19613
|
+
audio: addOptional(a.audio, b.audio),
|
|
19614
|
+
image: addOptional(a.image, b.image)
|
|
19615
|
+
};
|
|
19616
|
+
}
|
|
19617
|
+
function addUsageStats(a, b) {
|
|
19618
|
+
if (!a) {
|
|
19619
|
+
return {
|
|
19620
|
+
...b,
|
|
19621
|
+
inputDetails: b.inputDetails ? { ...b.inputDetails } : void 0,
|
|
19622
|
+
outputDetails: b.outputDetails ? { ...b.outputDetails } : void 0
|
|
19623
|
+
};
|
|
19624
|
+
}
|
|
19625
|
+
return {
|
|
19626
|
+
inputTokens: addOptional(a.inputTokens, b.inputTokens),
|
|
19627
|
+
outputTokens: addOptional(a.outputTokens, b.outputTokens),
|
|
19628
|
+
inputDetails: mergeInputDetails(a.inputDetails, b.inputDetails),
|
|
19629
|
+
outputDetails: mergeOutputDetails(a.outputDetails, b.outputDetails)
|
|
19630
|
+
};
|
|
19631
|
+
}
|
|
19588
19632
|
|
|
19589
19633
|
// src/model-tracing.ts
|
|
19590
19634
|
function supportsModelInference() {
|
|
@@ -21114,7 +21158,7 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
21114
21158
|
* This ensures all spans emit events regardless of implementation
|
|
21115
21159
|
*/
|
|
21116
21160
|
wireSpanLifecycle(span) {
|
|
21117
|
-
if (!this.config.includeInternalSpans && span.isInternal) {
|
|
21161
|
+
if (!this.config.includeInternalSpans && span.isInternal && span.type !== SpanType.MODEL_GENERATION) {
|
|
21118
21162
|
return;
|
|
21119
21163
|
}
|
|
21120
21164
|
const originalEnd = span.end.bind(span);
|
|
@@ -21124,7 +21168,11 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
21124
21168
|
this.logger.warn(`End event is not available on event spans`);
|
|
21125
21169
|
return;
|
|
21126
21170
|
}
|
|
21171
|
+
const rollupTarget = this.captureModelUsageRollup(span, options);
|
|
21127
21172
|
originalEnd(options);
|
|
21173
|
+
if (rollupTarget) {
|
|
21174
|
+
this.applyUsageRollup(rollupTarget);
|
|
21175
|
+
}
|
|
21128
21176
|
this.emitSpanEnded(span);
|
|
21129
21177
|
};
|
|
21130
21178
|
span.update = (options) => {
|
|
@@ -21298,6 +21346,70 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
21298
21346
|
this.emitTracingEvent(event);
|
|
21299
21347
|
}
|
|
21300
21348
|
}
|
|
21349
|
+
/**
|
|
21350
|
+
* When an internal MODEL_GENERATION span ends, capture the rollup payload
|
|
21351
|
+
* (usage, provider, model, target ancestor) needed to attribute its cost
|
|
21352
|
+
* to the closest exported ancestor span. Returns undefined when no rollup
|
|
21353
|
+
* applies — non-MODEL_GENERATION spans, spans that will be exported, or
|
|
21354
|
+
* spans whose usage isn't available at end time.
|
|
21355
|
+
*/
|
|
21356
|
+
captureModelUsageRollup(span, endOptions) {
|
|
21357
|
+
if (span.type !== SpanType.MODEL_GENERATION) return void 0;
|
|
21358
|
+
if (!span.isInternal || this.config.includeInternalSpans) return void 0;
|
|
21359
|
+
const endAttrs = endOptions?.attributes ?? void 0;
|
|
21360
|
+
const liveAttrs = span.attributes;
|
|
21361
|
+
const usage = endAttrs?.usage ?? liveAttrs?.usage;
|
|
21362
|
+
if (!usage) return void 0;
|
|
21363
|
+
const ancestor = this.findExportedAncestor(span);
|
|
21364
|
+
if (!ancestor) return void 0;
|
|
21365
|
+
const provider = endAttrs?.provider ?? liveAttrs?.provider;
|
|
21366
|
+
const model = endAttrs?.responseModel ?? endAttrs?.model ?? liveAttrs?.responseModel ?? liveAttrs?.model;
|
|
21367
|
+
return { ancestor, usage, provider, model };
|
|
21368
|
+
}
|
|
21369
|
+
/**
|
|
21370
|
+
* Accumulate usage onto the ancestor's `internalUsage` attribute (for trace
|
|
21371
|
+
* UI visibility) and emit auto-extracted token metrics now, using the
|
|
21372
|
+
* ancestor's metrics context so cost / token labels point at the visible
|
|
21373
|
+
* span instead of the hidden agent that incurred them.
|
|
21374
|
+
*/
|
|
21375
|
+
applyUsageRollup(target) {
|
|
21376
|
+
const { ancestor, usage, provider, model } = target;
|
|
21377
|
+
const attrs = ancestor.attributes;
|
|
21378
|
+
attrs.internalUsage = addUsageStats(attrs.internalUsage, usage);
|
|
21379
|
+
try {
|
|
21380
|
+
emitTokenMetricsForUsage(usage, provider, model, this.getMetricsContext(ancestor));
|
|
21381
|
+
} catch (err) {
|
|
21382
|
+
this.logger.error("[Observability] Usage rollup metric emission error:", err);
|
|
21383
|
+
}
|
|
21384
|
+
}
|
|
21385
|
+
/**
|
|
21386
|
+
* Walk up the parent chain to find the closest ancestor that will actually
|
|
21387
|
+
* reach exporters. Skips both internal-filtered ancestors and ancestors
|
|
21388
|
+
* whose type matches `excludeSpanTypes`, so the rollup target is one whose
|
|
21389
|
+
* mutated `internalUsage` attribute is visible in exported traces.
|
|
21390
|
+
*
|
|
21391
|
+
* Note: this does not preemptively run `spanFilter` — that filter can be
|
|
21392
|
+
* async and have side effects, so the rare case of a `spanFilter`-dropped
|
|
21393
|
+
* ancestor falls through.
|
|
21394
|
+
*/
|
|
21395
|
+
findExportedAncestor(span) {
|
|
21396
|
+
let ancestor = span.parent;
|
|
21397
|
+
while (ancestor && this.isFilteredFromExport(ancestor)) {
|
|
21398
|
+
ancestor = ancestor.parent;
|
|
21399
|
+
}
|
|
21400
|
+
return ancestor;
|
|
21401
|
+
}
|
|
21402
|
+
/**
|
|
21403
|
+
* Returns true when a span would be dropped by `getSpanForExport` for a
|
|
21404
|
+
* reason cheap to check up-front (internal-span filtering or
|
|
21405
|
+
* `excludeSpanTypes`). Used by `findExportedAncestor` to skip rollup
|
|
21406
|
+
* targets that would silently lose their `internalUsage` attribute.
|
|
21407
|
+
*/
|
|
21408
|
+
isFilteredFromExport(span) {
|
|
21409
|
+
if (span.isInternal && !this.config.includeInternalSpans) return true;
|
|
21410
|
+
if (this.config.excludeSpanTypes?.includes(span.type)) return true;
|
|
21411
|
+
return false;
|
|
21412
|
+
}
|
|
21301
21413
|
/**
|
|
21302
21414
|
* Emit a tracing event through the bus.
|
|
21303
21415
|
*
|
|
@@ -22248,7 +22360,7 @@ var Observability = class extends MastraBase {
|
|
|
22248
22360
|
};
|
|
22249
22361
|
|
|
22250
22362
|
// src/features.ts
|
|
22251
|
-
var observabilityFeatures = /* @__PURE__ */ new Set(["model-inference-span"]);
|
|
22363
|
+
var observabilityFeatures = /* @__PURE__ */ new Set(["model-inference-span", "internal-usage-rollup"]);
|
|
22252
22364
|
|
|
22253
22365
|
// src/tracing-options.ts
|
|
22254
22366
|
function buildTracingOptions(...updaters) {
|