@mastra/observability 1.16.6-alpha.0 → 1.16.6-alpha.2

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @mastra/observability
2
2
 
3
+ ## 1.16.6-alpha.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Use Vercel AI Gateway reported costs for completed model generations when every step reports a valid cost. ([#19921](https://github.com/mastra-ai/mastra/pull/19921))
8
+
9
+ - Updated dependencies [[`cdd5c33`](https://github.com/mastra-ai/mastra/commit/cdd5c33ac6c7118a9f139e6dc0e14e6a8ae31658), [`d7cf7fa`](https://github.com/mastra-ai/mastra/commit/d7cf7fafc1ae1b50bd8462dd0e6c671a8606db93), [`0f9a448`](https://github.com/mastra-ai/mastra/commit/0f9a448502157e59f7b76f24360ad497168f5ef8), [`289f4ce`](https://github.com/mastra-ai/mastra/commit/289f4ce16e3293370440172132c52ee787cbc09f), [`4f16ff8`](https://github.com/mastra-ai/mastra/commit/4f16ff824bf2f9b0ddc93f210477c10c8a4fb1ab), [`1c67d85`](https://github.com/mastra-ai/mastra/commit/1c67d85e9da8285662f4dbbf47e0378c3fee0747), [`ba24be6`](https://github.com/mastra-ai/mastra/commit/ba24be662439c331ab23a600041f93803c89eca8), [`842b5fe`](https://github.com/mastra-ai/mastra/commit/842b5fe22b6a7fa811bd14e48eb9af523ac989f2), [`80bdf3a`](https://github.com/mastra-ai/mastra/commit/80bdf3ae16ade6ff63bde0cb16fa2df8ab7dd4dd), [`9ba1247`](https://github.com/mastra-ai/mastra/commit/9ba12470c77f1c03642d720ce67e517e878f666e), [`fd96298`](https://github.com/mastra-ai/mastra/commit/fd96298a8367622f4ebfcaa97b5b6c1fbbd14564), [`6a84954`](https://github.com/mastra-ai/mastra/commit/6a84954a2667f85b6d59da652dab1bbff007ccb0), [`52d8ef0`](https://github.com/mastra-ai/mastra/commit/52d8ef03801f1deb7ee48532fc4190dd4a33916c), [`cdd5c33`](https://github.com/mastra-ai/mastra/commit/cdd5c33ac6c7118a9f139e6dc0e14e6a8ae31658), [`efd5c81`](https://github.com/mastra-ai/mastra/commit/efd5c81cc25fde3c2ddd86fc1178deb4ec176e19), [`0976933`](https://github.com/mastra-ai/mastra/commit/0976933142333ec78451feef265b68bcb45aa5e7), [`242b945`](https://github.com/mastra-ai/mastra/commit/242b94558777bfbdeb42cbfea84afff0b6ad0633), [`fea5cae`](https://github.com/mastra-ai/mastra/commit/fea5caedc7e2cfea51784a15e015952692027abf), [`4b59f78`](https://github.com/mastra-ai/mastra/commit/4b59f786cbc9a7d1ef07a07517dbd4b96865e99d), [`7010c5d`](https://github.com/mastra-ai/mastra/commit/7010c5d15728bf9c5dfe4fb6b1bf80ce23bf143a)]:
10
+ - @mastra/core@1.58.0-alpha.3
11
+
12
+ ## 1.16.6-alpha.1
13
+
14
+ ### Patch Changes
15
+
16
+ - Fixed span exports when `excludeSpanTypes` removes a parent span. Descendant spans now use the nearest exported parent, so exporters retain tool calls. ([#20881](https://github.com/mastra-ai/mastra/pull/20881))
17
+
18
+ - Updated dependencies [[`b4c89b4`](https://github.com/mastra-ai/mastra/commit/b4c89b4371b0c86da57403ad1a3b3ef0681f3128), [`e44e8f3`](https://github.com/mastra-ai/mastra/commit/e44e8f370b66c339ddcaba946d33da6d3c3f06cd), [`c967a5e`](https://github.com/mastra-ai/mastra/commit/c967a5eec150c5dc5418c4a4388982d1fb7ad27c), [`f53d5bd`](https://github.com/mastra-ai/mastra/commit/f53d5bd4885b29e4ac29a428a6044088ea8d6aa3), [`bda2235`](https://github.com/mastra-ai/mastra/commit/bda22353ee28f2df0eaea555f7cae1549f979c0b), [`a7eb4a1`](https://github.com/mastra-ai/mastra/commit/a7eb4a11450f6170274ed5141bffe821d4fdd5a6), [`2f9ef3f`](https://github.com/mastra-ai/mastra/commit/2f9ef3f4ca06fc2dcdd5088c26b7f4da6a016791), [`e7eefcb`](https://github.com/mastra-ai/mastra/commit/e7eefcb162cda7c493e8c3bf43050ead0efbcb2c), [`4d7aca2`](https://github.com/mastra-ai/mastra/commit/4d7aca2fe75f225c83d1502d63079568e6ec163f), [`c4ec889`](https://github.com/mastra-ai/mastra/commit/c4ec889561c0264c43f66d04d587bee4ce35e792), [`9be8878`](https://github.com/mastra-ai/mastra/commit/9be8878dcf0388e84fc4873e0eec27bd49b881a4)]:
19
+ - @mastra/core@1.58.0-alpha.2
20
+
3
21
  ## 1.16.6-alpha.0
4
22
 
5
23
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1784,6 +1784,34 @@ function addUsageStats(a, b) {
1784
1784
  function supportsModelInference() {
1785
1785
  return _mastra_core_features.coreFeatures.has("model-inference-span");
1786
1786
  }
1787
+ function parseGatewayCost(providerMetadata) {
1788
+ const rawCost = providerMetadata?.gateway?.cost;
1789
+ const cost = typeof rawCost === "number" ? rawCost : typeof rawCost === "string" && rawCost.trim().length > 0 ? Number(rawCost) : void 0;
1790
+ return typeof cost === "number" && Number.isFinite(cost) && cost >= 0 ? cost : void 0;
1791
+ }
1792
+ function getGatewayCostContext({ stepProviderMetadata }) {
1793
+ if (!stepProviderMetadata) return;
1794
+ if (!stepProviderMetadata.some((metadata) => metadata?.gateway !== void 0)) return;
1795
+ const costs = [];
1796
+ for (const metadata of stepProviderMetadata) {
1797
+ const cost = parseGatewayCost(metadata);
1798
+ if (cost === void 0) return;
1799
+ costs.push(cost);
1800
+ }
1801
+ const estimatedCost = costs.reduce((total, cost) => total + cost, 0);
1802
+ if (!Number.isFinite(estimatedCost)) return;
1803
+ return {
1804
+ estimatedCost,
1805
+ costUnit: "USD",
1806
+ costMetadata: {
1807
+ source: "provider_reported",
1808
+ sdkProvider: "vercel_ai_gateway",
1809
+ sdkCostField: "gateway.cost",
1810
+ scope: "query_total",
1811
+ reportedStepCount: costs.length
1812
+ }
1813
+ };
1814
+ }
1787
1815
  function formatPreviewLabel(label, fallback) {
1788
1816
  return typeof label === "string" && label.length > 0 ? label : fallback;
1789
1817
  }
@@ -1965,10 +1993,11 @@ var ModelSpanTracker = class {
1965
1993
  * If usage is provided, it will be converted to UsageStats with cache token details.
1966
1994
  */
1967
1995
  endGeneration(options) {
1968
- const { usage, providerMetadata, ...spanOptions } = options ?? {};
1996
+ const { usage, providerMetadata, stepProviderMetadata, ...spanOptions } = options ?? {};
1969
1997
  if (spanOptions.attributes) {
1970
1998
  spanOptions.attributes.completionStartTime = this.#completionStartTime;
1971
1999
  spanOptions.attributes.usage = extractUsageMetrics(usage, providerMetadata);
2000
+ if (!spanOptions.attributes.costContext) spanOptions.attributes.costContext = getGatewayCostContext({ stepProviderMetadata });
1972
2001
  }
1973
2002
  this.#modelSpan?.end(spanOptions);
1974
2003
  }
@@ -2456,12 +2485,12 @@ function isSpanInternal(spanType, flags) {
2456
2485
  /**
2457
2486
  * Get the external parent span ID from CreateSpanOptions.
2458
2487
  *
2459
- * If the parent is internal, walks up the parent chain to find
2460
- * the closest external ancestor. If the parent is already external,
2461
- * returns its ID directly.
2488
+ * If the parent is internal or excluded from export (`excludeSpanTypes`),
2489
+ * walks up the parent chain to find the closest exported ancestor.
2490
+ * If the parent is already exportable, returns its ID directly.
2462
2491
  *
2463
2492
  * This is useful when exporting spans to external observability systems
2464
- * that shouldn't include internal framework spans.
2493
+ * that shouldn't include internal framework spans or excluded types.
2465
2494
  *
2466
2495
  * @param options - Span creation options
2467
2496
  * @returns The external parent span ID, or undefined if no external parent exists
@@ -2482,8 +2511,9 @@ function isSpanInternal(spanType, flags) {
2482
2511
  */
2483
2512
  function getExternalParentId(options) {
2484
2513
  if (!options.parent) return;
2485
- if (options.parent.isInternal) return options.parent.getParentSpanId(false);
2486
- else return options.parent.id;
2514
+ const parent = options.parent;
2515
+ if (parent.isInternal || parent.isExcluded) return parent.getParentSpanId(false);
2516
+ return parent.id;
2487
2517
  }
2488
2518
  var BaseSpan = class {
2489
2519
  name;
@@ -2522,6 +2552,10 @@ var BaseSpan = class {
2522
2552
  * when the span is internal and includeInternalSpans is false, or when
2523
2553
  * the subclass is always excluded (e.g., NoOpSpan).
2524
2554
  *
2555
+ * Public so parent-chain walks (`getParentSpan`) can skip ancestors that
2556
+ * exporters will never receive — otherwise descendants export a
2557
+ * `parentSpanId` pointing at a dropped span and become orphans.
2558
+ *
2525
2559
  * Note: metadata is still attached and deepCleaned because it is read in
2526
2560
  * process by getCorrelationContext() and by getLoggerContext() /
2527
2561
  * getMetricsContext() (which structuredClone it).
@@ -2593,14 +2627,20 @@ var BaseSpan = class {
2593
2627
  get isRootSpan() {
2594
2628
  return !this.parent;
2595
2629
  }
2596
- /** Get the closest parent span, optionally skipping internal spans */
2630
+ /**
2631
+ * Get the closest parent span.
2632
+ * Always skips ancestors dropped by `excludeSpanTypes` (`isExcluded`), so
2633
+ * exported `parentSpanId` values never point at spans exporters omit.
2634
+ * When `includeInternalSpans` is false/undefined, also skips `isInternal`
2635
+ * ancestors.
2636
+ */
2597
2637
  getParentSpan(includeInternalSpans) {
2598
2638
  if (!this.parent) return;
2599
- if (includeInternalSpans) return this.parent;
2600
- if (this.parent.isInternal) return this.parent.getParentSpan(includeInternalSpans);
2639
+ const parent = this.parent;
2640
+ if (parent.isExcluded || !includeInternalSpans && parent.isInternal) return parent.getParentSpan(includeInternalSpans);
2601
2641
  return this.parent;
2602
2642
  }
2603
- /** Get the closest parent spanId that isn't an internal span */
2643
+ /** Get the closest parent spanId that will reach exporters (unless includeInternalSpans) */
2604
2644
  getParentSpanId(includeInternalSpans) {
2605
2645
  if (!this.parent) return this.parentSpanId;
2606
2646
  const parentSpan = this.getParentSpan(includeInternalSpans);