@mastra/observability 1.6.0-alpha.2 → 1.6.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/dist/index.js CHANGED
@@ -14,6 +14,47 @@ var __export = (target, all) => {
14
14
  for (var name in all)
15
15
  __defProp(target, name, { get: all[name], enumerable: true });
16
16
  };
17
+ function routeToHandler(handler, event, logger) {
18
+ try {
19
+ switch (event.type) {
20
+ case TracingEventType.SPAN_STARTED:
21
+ case TracingEventType.SPAN_UPDATED:
22
+ case TracingEventType.SPAN_ENDED: {
23
+ const fn = handler.onTracingEvent ? handler.onTracingEvent.bind(handler) : handler.exportTracingEvent.bind(handler);
24
+ return catchAsyncResult(fn(event), handler.name, "tracing", logger);
25
+ }
26
+ case "log":
27
+ if (handler.onLogEvent) {
28
+ return catchAsyncResult(handler.onLogEvent(event), handler.name, "log", logger);
29
+ }
30
+ break;
31
+ case "metric":
32
+ if (handler.onMetricEvent) {
33
+ return catchAsyncResult(handler.onMetricEvent(event), handler.name, "metric", logger);
34
+ }
35
+ break;
36
+ case "score":
37
+ if (handler.onScoreEvent) {
38
+ return catchAsyncResult(handler.onScoreEvent(event), handler.name, "score", logger);
39
+ }
40
+ break;
41
+ case "feedback":
42
+ if (handler.onFeedbackEvent) {
43
+ return catchAsyncResult(handler.onFeedbackEvent(event), handler.name, "feedback", logger);
44
+ }
45
+ break;
46
+ }
47
+ } catch (err) {
48
+ logger.error(`[Observability] Handler error [handler=${handler.name}]:`, err);
49
+ }
50
+ }
51
+ function catchAsyncResult(result, handlerName, signal, logger) {
52
+ if (result && typeof result.then === "function") {
53
+ return result.catch((err) => {
54
+ logger.error(`[Observability] ${signal} handler error [handler=${handlerName}]:`, err);
55
+ });
56
+ }
57
+ }
17
58
 
18
59
  // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
19
60
  var external_exports = {};
@@ -15893,7 +15934,7 @@ var TestExporter = class extends BaseExporter {
15893
15934
  this.#trackEvent("log");
15894
15935
  if (this.#config.storeLogs) {
15895
15936
  const log = event.log;
15896
- const traceId = log.correlationContext?.traceId;
15937
+ const traceId = log.traceId;
15897
15938
  const logMessage = `[TestExporter] log.${log.level}: "${log.message}"${traceId ? ` (trace: ${traceId.slice(-8)})` : ""}`;
15898
15939
  this.#debugLogs.push(logMessage);
15899
15940
  }
@@ -16011,7 +16052,7 @@ var TestExporter = class extends BaseExporter {
16011
16052
  getByTraceId(traceId) {
16012
16053
  const events = this.#tracingEvents.filter((e) => e.exportedSpan.traceId === traceId);
16013
16054
  const spans = this.#getUniqueSpansFromEvents(events);
16014
- const logs = this.#logEvents.filter((e) => e.log.correlationContext?.traceId === traceId).map((e) => e.log);
16055
+ const logs = this.#logEvents.filter((e) => e.log.traceId === traceId).map((e) => e.log);
16015
16056
  const scores = this.#scoreEvents.filter((e) => e.score.traceId === traceId).map((e) => e.score);
16016
16057
  const feedback = this.#feedbackEvents.filter((e) => e.feedback.traceId === traceId).map((e) => e.feedback);
16017
16058
  return { events, spans, logs, scores, feedback };
@@ -16078,7 +16119,7 @@ var TestExporter = class extends BaseExporter {
16078
16119
  traceIds.add(event.exportedSpan.traceId);
16079
16120
  }
16080
16121
  for (const event of this.#logEvents) {
16081
- if (event.log.correlationContext?.traceId) traceIds.add(event.log.correlationContext.traceId);
16122
+ if (event.log.traceId) traceIds.add(event.log.traceId);
16082
16123
  }
16083
16124
  for (const event of this.#scoreEvents) {
16084
16125
  traceIds.add(event.score.traceId);
@@ -16113,7 +16154,7 @@ var TestExporter = class extends BaseExporter {
16113
16154
  * Get logs for a specific trace
16114
16155
  */
16115
16156
  getLogsByTraceId(traceId) {
16116
- return this.#logEvents.filter((e) => e.log.correlationContext?.traceId === traceId).map((e) => e.log);
16157
+ return this.#logEvents.filter((e) => e.log.traceId === traceId).map((e) => e.log);
16117
16158
  }
16118
16159
  // ============================================================================
16119
16160
  // Metric Query Methods
@@ -16987,47 +17028,6 @@ var BaseObservabilityEventBus = class _BaseObservabilityEventBus extends MastraB
16987
17028
  this.subscribers.clear();
16988
17029
  }
16989
17030
  };
16990
- function routeToHandler(handler, event, logger) {
16991
- try {
16992
- switch (event.type) {
16993
- case TracingEventType.SPAN_STARTED:
16994
- case TracingEventType.SPAN_UPDATED:
16995
- case TracingEventType.SPAN_ENDED: {
16996
- const fn = handler.onTracingEvent ? handler.onTracingEvent.bind(handler) : handler.exportTracingEvent.bind(handler);
16997
- return catchAsyncResult(fn(event), handler.name, "tracing", logger);
16998
- }
16999
- case "log":
17000
- if (handler.onLogEvent) {
17001
- return catchAsyncResult(handler.onLogEvent(event), handler.name, "log", logger);
17002
- }
17003
- break;
17004
- case "metric":
17005
- if (handler.onMetricEvent) {
17006
- return catchAsyncResult(handler.onMetricEvent(event), handler.name, "metric", logger);
17007
- }
17008
- break;
17009
- case "score":
17010
- if (handler.onScoreEvent) {
17011
- return catchAsyncResult(handler.onScoreEvent(event), handler.name, "score", logger);
17012
- }
17013
- break;
17014
- case "feedback":
17015
- if (handler.onFeedbackEvent) {
17016
- return catchAsyncResult(handler.onFeedbackEvent(event), handler.name, "feedback", logger);
17017
- }
17018
- break;
17019
- }
17020
- } catch (err) {
17021
- logger.error(`[Observability] Handler error [handler=${handler.name}]:`, err);
17022
- }
17023
- }
17024
- function catchAsyncResult(result, handlerName, signal, logger) {
17025
- if (result && typeof result.then === "function") {
17026
- return result.catch((err) => {
17027
- logger.error(`[Observability] ${signal} handler error [handler=${handlerName}]:`, err);
17028
- });
17029
- }
17030
- }
17031
17031
 
17032
17032
  // src/bus/observability-bus.ts
17033
17033
  var MAX_FLUSH_ITERATIONS = 3;
@@ -17187,9 +17187,12 @@ var LoggerContextImpl = class {
17187
17187
  * mutations after construction do not affect emitted logs.
17188
17188
  */
17189
17189
  constructor(config2) {
17190
+ const correlationContext = config2.correlationContext ? { ...config2.correlationContext } : void 0;
17190
17191
  this.config = {
17191
17192
  ...config2,
17192
- correlationContext: config2.correlationContext ? { ...config2.correlationContext } : void 0,
17193
+ traceId: config2.traceId ?? correlationContext?.traceId,
17194
+ spanId: config2.spanId ?? correlationContext?.spanId,
17195
+ correlationContext,
17193
17196
  metadata: config2.metadata ? structuredClone(config2.metadata) : void 0
17194
17197
  };
17195
17198
  }
@@ -17226,6 +17229,8 @@ var LoggerContextImpl = class {
17226
17229
  level,
17227
17230
  message,
17228
17231
  data,
17232
+ traceId: this.config.traceId,
17233
+ spanId: this.config.spanId,
17229
17234
  correlationContext: this.config.correlationContext,
17230
17235
  metadata: this.config.metadata
17231
17236
  };
@@ -17236,6 +17241,8 @@ var LoggerContextImpl = class {
17236
17241
 
17237
17242
  // src/context/metrics.ts
17238
17243
  var MetricsContextImpl = class {
17244
+ traceId;
17245
+ spanId;
17239
17246
  correlationContext;
17240
17247
  metadata;
17241
17248
  cardinalityFilter;
@@ -17246,6 +17253,8 @@ var MetricsContextImpl = class {
17246
17253
  */
17247
17254
  constructor(config2) {
17248
17255
  this.correlationContext = config2.correlationContext ? { ...config2.correlationContext } : void 0;
17256
+ this.traceId = config2.traceId ?? this.correlationContext?.traceId;
17257
+ this.spanId = config2.spanId ?? this.correlationContext?.spanId;
17249
17258
  this.metadata = config2.metadata ? structuredClone(config2.metadata) : void 0;
17250
17259
  this.cardinalityFilter = config2.cardinalityFilter;
17251
17260
  this.observabilityBus = config2.observabilityBus;
@@ -17259,6 +17268,8 @@ var MetricsContextImpl = class {
17259
17268
  const costContext = options?.costContext ? cloneCostContext(options.costContext) : void 0;
17260
17269
  const exportedMetric = {
17261
17270
  timestamp: /* @__PURE__ */ new Date(),
17271
+ traceId: this.traceId,
17272
+ spanId: this.spanId,
17262
17273
  name,
17263
17274
  value,
17264
17275
  labels: filteredLabels,
@@ -19193,6 +19204,8 @@ var BaseObservabilityInstance = class extends MastraBase {
19193
19204
  const correlationContext = span?.getCorrelationContext?.();
19194
19205
  const metadata = span?.metadata ? structuredClone(span.metadata) : void 0;
19195
19206
  return new LoggerContextImpl({
19207
+ traceId: span?.traceId,
19208
+ spanId: span?.id,
19196
19209
  correlationContext,
19197
19210
  metadata,
19198
19211
  observabilityBus: this.observabilityBus
@@ -19207,6 +19220,8 @@ var BaseObservabilityInstance = class extends MastraBase {
19207
19220
  const correlationContext = span?.getCorrelationContext?.();
19208
19221
  const metadata = span?.metadata ? structuredClone(span.metadata) : void 0;
19209
19222
  return new MetricsContextImpl({
19223
+ traceId: span?.traceId,
19224
+ spanId: span?.id,
19210
19225
  correlationContext,
19211
19226
  metadata,
19212
19227
  cardinalityFilter: this.cardinalityFilter,
@@ -19221,6 +19236,13 @@ var BaseObservabilityInstance = class extends MastraBase {
19221
19236
  emitObservabilityEvent(event) {
19222
19237
  this.observabilityBus.emit(event);
19223
19238
  }
19239
+ /**
19240
+ * Internal hook used by RecordedTrace/RecordedSpan hydration to route
19241
+ * non-tracing annotation events back through the normal exporter pipeline.
19242
+ */
19243
+ __emitRecordedEvent(event) {
19244
+ this.emitObservabilityEvent(event);
19245
+ }
19224
19246
  // ============================================================================
19225
19247
  // Span Lifecycle Management
19226
19248
  // ============================================================================
@@ -19495,6 +19517,311 @@ var DefaultObservabilityInstance = class extends BaseObservabilityInstance {
19495
19517
  }
19496
19518
  };
19497
19519
 
19520
+ // src/recorded.ts
19521
+ function nullToUndefined(value) {
19522
+ return value ?? void 0;
19523
+ }
19524
+ function mergeMetadata(base, extra) {
19525
+ if (!base && !extra) return void 0;
19526
+ return {
19527
+ ...base ?? {},
19528
+ ...extra ?? {}
19529
+ };
19530
+ }
19531
+ function normalizeErrorInfo(error48) {
19532
+ if (!error48 || typeof error48 !== "object" || !("message" in error48) || typeof error48.message !== "string") {
19533
+ return void 0;
19534
+ }
19535
+ return {
19536
+ message: error48.message,
19537
+ id: "id" in error48 && typeof error48.id === "string" ? error48.id : void 0,
19538
+ domain: "domain" in error48 && typeof error48.domain === "string" ? error48.domain : void 0,
19539
+ category: "category" in error48 && typeof error48.category === "string" ? error48.category : void 0,
19540
+ details: "details" in error48 && error48.details && typeof error48.details === "object" ? error48.details : void 0
19541
+ };
19542
+ }
19543
+ function buildCorrelationContext(span, rootSpan, parent) {
19544
+ return {
19545
+ tags: rootSpan.tags ?? void 0,
19546
+ entityType: nullToUndefined(span.entityType),
19547
+ entityId: nullToUndefined(span.entityId),
19548
+ entityName: nullToUndefined(span.entityName),
19549
+ parentEntityType: parent?.entityType ?? void 0,
19550
+ parentEntityId: parent?.entityId ?? void 0,
19551
+ parentEntityName: parent?.entityName ?? void 0,
19552
+ rootEntityType: nullToUndefined(rootSpan.entityType),
19553
+ rootEntityId: nullToUndefined(rootSpan.entityId),
19554
+ rootEntityName: nullToUndefined(rootSpan.entityName),
19555
+ userId: nullToUndefined(span.userId),
19556
+ organizationId: nullToUndefined(span.organizationId),
19557
+ resourceId: nullToUndefined(span.resourceId),
19558
+ runId: nullToUndefined(span.runId),
19559
+ sessionId: nullToUndefined(span.sessionId),
19560
+ threadId: nullToUndefined(span.threadId),
19561
+ requestId: nullToUndefined(span.requestId),
19562
+ environment: nullToUndefined(span.environment),
19563
+ source: nullToUndefined(span.source),
19564
+ serviceName: nullToUndefined(span.serviceName),
19565
+ experimentId: nullToUndefined(span.experimentId)
19566
+ };
19567
+ }
19568
+ function buildRecordedScoreEvent(args) {
19569
+ const { span, rootSpan, parent, score, spanId } = args;
19570
+ return {
19571
+ type: "score",
19572
+ score: {
19573
+ timestamp: /* @__PURE__ */ new Date(),
19574
+ traceId: span.traceId,
19575
+ spanId,
19576
+ scorerId: score.scorerId,
19577
+ scorerVersion: score.scorerVersion,
19578
+ source: score.source,
19579
+ scoreSource: score.scoreSource,
19580
+ score: score.score,
19581
+ reason: score.reason,
19582
+ experimentId: score.experimentId,
19583
+ scoreTraceId: score.scoreTraceId,
19584
+ correlationContext: buildCorrelationContext(span, rootSpan, parent),
19585
+ metadata: mergeMetadata(span.metadata, score.metadata)
19586
+ }
19587
+ };
19588
+ }
19589
+ function buildRecordedFeedbackEvent(args) {
19590
+ const { span, rootSpan, parent, feedback, spanId } = args;
19591
+ return {
19592
+ type: "feedback",
19593
+ feedback: {
19594
+ timestamp: /* @__PURE__ */ new Date(),
19595
+ traceId: span.traceId,
19596
+ spanId,
19597
+ source: feedback.source,
19598
+ feedbackSource: feedback.feedbackSource,
19599
+ feedbackType: feedback.feedbackType,
19600
+ value: feedback.value,
19601
+ userId: feedback.userId,
19602
+ feedbackUserId: feedback.feedbackUserId,
19603
+ comment: feedback.comment,
19604
+ sourceId: feedback.sourceId,
19605
+ experimentId: feedback.experimentId,
19606
+ correlationContext: buildCorrelationContext(span, rootSpan, parent),
19607
+ metadata: mergeMetadata(span.metadata, feedback.metadata)
19608
+ }
19609
+ };
19610
+ }
19611
+ function findSpanById(spans, spanId) {
19612
+ if (!spanId) return void 0;
19613
+ return spans.find((span) => span.spanId === spanId);
19614
+ }
19615
+ function buildRecordedScoreEventFromTrace(args) {
19616
+ const rootSpan = findRootSpan(args.trace.spans);
19617
+ if (!rootSpan) return null;
19618
+ const span = args.spanId ? findSpanById(args.trace.spans, args.spanId) : rootSpan;
19619
+ if (!span) return null;
19620
+ const parent = span.parentSpanId ? findSpanById(args.trace.spans, span.parentSpanId) : void 0;
19621
+ return buildRecordedScoreEvent({
19622
+ span,
19623
+ rootSpan,
19624
+ parent,
19625
+ score: args.score,
19626
+ spanId: args.spanId
19627
+ });
19628
+ }
19629
+ function buildRecordedFeedbackEventFromTrace(args) {
19630
+ const rootSpan = findRootSpan(args.trace.spans);
19631
+ if (!rootSpan) return null;
19632
+ const span = args.spanId ? findSpanById(args.trace.spans, args.spanId) : rootSpan;
19633
+ if (!span) return null;
19634
+ const parent = span.parentSpanId ? findSpanById(args.trace.spans, span.parentSpanId) : void 0;
19635
+ return buildRecordedFeedbackEvent({
19636
+ span,
19637
+ rootSpan,
19638
+ parent,
19639
+ feedback: args.feedback,
19640
+ spanId: args.spanId
19641
+ });
19642
+ }
19643
+ var RecordedSpanImpl = class {
19644
+ id;
19645
+ traceId;
19646
+ name;
19647
+ type;
19648
+ entityType;
19649
+ entityId;
19650
+ entityName;
19651
+ startTime;
19652
+ endTime;
19653
+ attributes;
19654
+ metadata;
19655
+ tags;
19656
+ input;
19657
+ output;
19658
+ errorInfo;
19659
+ requestContext;
19660
+ isEvent;
19661
+ isRootSpan;
19662
+ parentSpanId;
19663
+ parent;
19664
+ children = [];
19665
+ #raw;
19666
+ #rootSpan;
19667
+ #emitRecordedEvent;
19668
+ #canEmitRecordedEvent;
19669
+ #debugRecordedAnnotationUnavailable;
19670
+ constructor(args) {
19671
+ const { raw, rootSpan, emitRecordedEvent, canEmitRecordedEvent, debugRecordedAnnotationUnavailable } = args;
19672
+ this.#raw = raw;
19673
+ this.#rootSpan = rootSpan;
19674
+ this.#emitRecordedEvent = emitRecordedEvent;
19675
+ this.#canEmitRecordedEvent = canEmitRecordedEvent;
19676
+ this.#debugRecordedAnnotationUnavailable = debugRecordedAnnotationUnavailable;
19677
+ this.id = raw.spanId;
19678
+ this.traceId = raw.traceId;
19679
+ this.name = raw.name;
19680
+ this.type = raw.spanType;
19681
+ this.entityType = raw.entityType ?? void 0;
19682
+ this.entityId = raw.entityId ?? void 0;
19683
+ this.entityName = raw.entityName ?? void 0;
19684
+ this.startTime = raw.startedAt;
19685
+ this.endTime = raw.endedAt ?? void 0;
19686
+ this.attributes = raw.attributes ?? void 0;
19687
+ this.metadata = raw.metadata ?? void 0;
19688
+ this.tags = raw.tags ?? void 0;
19689
+ this.input = raw.input ?? void 0;
19690
+ this.output = raw.output ?? void 0;
19691
+ this.errorInfo = normalizeErrorInfo(raw.error);
19692
+ this.requestContext = raw.requestContext ?? void 0;
19693
+ this.isEvent = raw.isEvent;
19694
+ this.isRootSpan = !raw.parentSpanId;
19695
+ this.parentSpanId = raw.parentSpanId ?? void 0;
19696
+ }
19697
+ async addScore(score) {
19698
+ if (!this.#canEmitRecordedEvent()) {
19699
+ this.#debugRecordedAnnotationUnavailable({ kind: "score", traceId: this.traceId, spanId: this.id });
19700
+ return;
19701
+ }
19702
+ await this.#emitRecordedEvent(
19703
+ buildRecordedScoreEvent({
19704
+ span: this.#raw,
19705
+ rootSpan: this.#rootSpan,
19706
+ parent: this.parent,
19707
+ score,
19708
+ spanId: this.id
19709
+ })
19710
+ );
19711
+ }
19712
+ async addFeedback(feedback) {
19713
+ if (!this.#canEmitRecordedEvent()) {
19714
+ this.#debugRecordedAnnotationUnavailable({ kind: "feedback", traceId: this.traceId, spanId: this.id });
19715
+ return;
19716
+ }
19717
+ await this.#emitRecordedEvent(
19718
+ buildRecordedFeedbackEvent({
19719
+ span: this.#raw,
19720
+ rootSpan: this.#rootSpan,
19721
+ parent: this.parent,
19722
+ feedback,
19723
+ spanId: this.id
19724
+ })
19725
+ );
19726
+ }
19727
+ };
19728
+ var RecordedTraceImpl = class {
19729
+ traceId;
19730
+ rootSpan;
19731
+ spans;
19732
+ #rootRecord;
19733
+ #emitRecordedEvent;
19734
+ #spanMap;
19735
+ #canEmitRecordedEvent;
19736
+ #debugRecordedAnnotationUnavailable;
19737
+ constructor(args) {
19738
+ this.traceId = args.traceId;
19739
+ this.rootSpan = args.rootSpan;
19740
+ this.#rootRecord = args.rootRecord;
19741
+ this.spans = args.spans;
19742
+ this.#emitRecordedEvent = args.emitRecordedEvent;
19743
+ this.#spanMap = new Map(args.spans.map((span) => [span.id, span]));
19744
+ this.#canEmitRecordedEvent = args.canEmitRecordedEvent;
19745
+ this.#debugRecordedAnnotationUnavailable = args.debugRecordedAnnotationUnavailable;
19746
+ }
19747
+ getSpan(spanId) {
19748
+ return this.#spanMap.get(spanId) ?? null;
19749
+ }
19750
+ async addScore(score) {
19751
+ if (!this.#canEmitRecordedEvent()) {
19752
+ this.#debugRecordedAnnotationUnavailable({ kind: "score", traceId: this.traceId });
19753
+ return;
19754
+ }
19755
+ await this.#emitRecordedEvent(
19756
+ buildRecordedScoreEvent({
19757
+ span: this.#rootRecord,
19758
+ rootSpan: this.#rootRecord,
19759
+ score
19760
+ })
19761
+ );
19762
+ }
19763
+ async addFeedback(feedback) {
19764
+ if (!this.#canEmitRecordedEvent()) {
19765
+ this.#debugRecordedAnnotationUnavailable({ kind: "feedback", traceId: this.traceId });
19766
+ return;
19767
+ }
19768
+ await this.#emitRecordedEvent(
19769
+ buildRecordedFeedbackEvent({
19770
+ span: this.#rootRecord,
19771
+ rootSpan: this.#rootRecord,
19772
+ feedback
19773
+ })
19774
+ );
19775
+ }
19776
+ };
19777
+ function findRootSpan(spans) {
19778
+ const spanIds = new Set(spans.map((span) => span.spanId));
19779
+ return spans.find((span) => !span.parentSpanId || !spanIds.has(span.parentSpanId)) ?? spans[0];
19780
+ }
19781
+ function hydrateRecordedTrace(args) {
19782
+ const {
19783
+ trace,
19784
+ emitRecordedEvent,
19785
+ canEmitRecordedEvent = () => true,
19786
+ debugRecordedAnnotationUnavailable = () => {
19787
+ }
19788
+ } = args;
19789
+ const rootSpan = findRootSpan(trace.spans);
19790
+ if (!rootSpan) {
19791
+ return null;
19792
+ }
19793
+ const recordedSpans = trace.spans.map(
19794
+ (raw) => new RecordedSpanImpl({
19795
+ raw,
19796
+ rootSpan,
19797
+ emitRecordedEvent,
19798
+ canEmitRecordedEvent,
19799
+ debugRecordedAnnotationUnavailable
19800
+ })
19801
+ );
19802
+ const spanMap = new Map(recordedSpans.map((span) => [span.id, span]));
19803
+ for (const span of recordedSpans) {
19804
+ if (!span.parentSpanId) continue;
19805
+ const parent = spanMap.get(span.parentSpanId);
19806
+ if (!parent) continue;
19807
+ span.parent = parent;
19808
+ parent.children.push(span);
19809
+ }
19810
+ const hydratedRootSpan = spanMap.get(rootSpan.spanId);
19811
+ if (!hydratedRootSpan) {
19812
+ return null;
19813
+ }
19814
+ return new RecordedTraceImpl({
19815
+ traceId: trace.traceId,
19816
+ rootSpan: hydratedRootSpan,
19817
+ rootRecord: rootSpan,
19818
+ spans: recordedSpans,
19819
+ emitRecordedEvent,
19820
+ canEmitRecordedEvent,
19821
+ debugRecordedAnnotationUnavailable
19822
+ });
19823
+ }
19824
+
19498
19825
  // src/registry.ts
19499
19826
  var ObservabilityRegistry = class {
19500
19827
  #instances = /* @__PURE__ */ new Map();
@@ -19735,6 +20062,7 @@ function isInstance(obj) {
19735
20062
  }
19736
20063
  var Observability = class extends MastraBase {
19737
20064
  #registry = new ObservabilityRegistry();
20065
+ #mastra;
19738
20066
  constructor(config2) {
19739
20067
  super({
19740
20068
  component: RegisteredLogger.OBSERVABILITY,
@@ -19809,6 +20137,7 @@ var Observability = class extends MastraBase {
19809
20137
  setMastraContext(options) {
19810
20138
  const instances = this.listInstances();
19811
20139
  const { mastra } = options;
20140
+ this.#mastra = mastra;
19812
20141
  instances.forEach((instance) => {
19813
20142
  const config2 = instance.getConfig();
19814
20143
  const exporters = instance.getExporters();
@@ -19837,6 +20166,60 @@ var Observability = class extends MastraBase {
19837
20166
  getSelectedInstance(options) {
19838
20167
  return this.#registry.getSelected(options);
19839
20168
  }
20169
+ async getRecordedTrace(args) {
20170
+ const observabilityStorage = await this.#getObservabilityStorage();
20171
+ if (!observabilityStorage) {
20172
+ return null;
20173
+ }
20174
+ const trace = await observabilityStorage.getTrace({ traceId: args.traceId });
20175
+ if (!trace) {
20176
+ return null;
20177
+ }
20178
+ return hydrateRecordedTrace({
20179
+ trace,
20180
+ emitRecordedEvent: (event) => this.#emitRecordedEvent(event),
20181
+ canEmitRecordedEvent: () => !!this.#getRecordedTraceInstance(),
20182
+ debugRecordedAnnotationUnavailable: ({ kind, traceId, spanId }) => {
20183
+ this.logger?.debug(
20184
+ kind === "score" ? "addScore() is unavailable; rehydrate the trace before calling addScore()" : "addFeedback() is unavailable; rehydrate the trace before calling addFeedback()",
20185
+ {
20186
+ traceId,
20187
+ spanId
20188
+ }
20189
+ );
20190
+ }
20191
+ });
20192
+ }
20193
+ async addScore(args) {
20194
+ const trace = await this.#getStoredTrace(args.traceId);
20195
+ if (!trace) {
20196
+ return;
20197
+ }
20198
+ const event = buildRecordedScoreEventFromTrace({
20199
+ trace,
20200
+ spanId: args.spanId,
20201
+ score: args.score
20202
+ });
20203
+ if (!event) {
20204
+ return;
20205
+ }
20206
+ await this.#emitRecordedEvent(event);
20207
+ }
20208
+ async addFeedback(args) {
20209
+ const trace = await this.#getStoredTrace(args.traceId);
20210
+ if (!trace) {
20211
+ return;
20212
+ }
20213
+ const event = buildRecordedFeedbackEventFromTrace({
20214
+ trace,
20215
+ spanId: args.spanId,
20216
+ feedback: args.feedback
20217
+ });
20218
+ if (!event) {
20219
+ return;
20220
+ }
20221
+ await this.#emitRecordedEvent(event);
20222
+ }
19840
20223
  /** Register a named observability instance, optionally marking it as default. */
19841
20224
  registerInstance(name, instance, isDefault = false) {
19842
20225
  this.#registry.register(name, instance, isDefault);
@@ -19873,6 +20256,45 @@ var Observability = class extends MastraBase {
19873
20256
  async shutdown() {
19874
20257
  await this.#registry.shutdown();
19875
20258
  }
20259
+ async #getObservabilityStorage() {
20260
+ const storage = this.#mastra?.getStorage();
20261
+ if (!storage) {
20262
+ return null;
20263
+ }
20264
+ return await storage.getStore("observability") ?? null;
20265
+ }
20266
+ async #getStoredTrace(traceId) {
20267
+ const observabilityStorage = await this.#getObservabilityStorage();
20268
+ if (!observabilityStorage) {
20269
+ return null;
20270
+ }
20271
+ return observabilityStorage.getTrace({ traceId });
20272
+ }
20273
+ #getRecordedTraceInstance() {
20274
+ return this.getDefaultInstance() ?? Array.from(this.listInstances().values())[0];
20275
+ }
20276
+ async #emitRecordedEvent(event) {
20277
+ const instance = this.#getRecordedTraceInstance();
20278
+ if (!instance) {
20279
+ this.logger?.debug(
20280
+ event.type === "score" ? "Score event was dropped because no observability instance is registered" : "Feedback event was dropped because no observability instance is registered",
20281
+ { eventType: event.type }
20282
+ );
20283
+ return;
20284
+ }
20285
+ if (instance instanceof BaseObservabilityInstance) {
20286
+ instance.__emitRecordedEvent(event);
20287
+ return;
20288
+ }
20289
+ const bridge = instance.getBridge();
20290
+ const handlerResults = [
20291
+ ...instance.getExporters().map((exporter) => routeToHandler(exporter, event, this.logger)),
20292
+ ...bridge ? [routeToHandler(bridge, event, this.logger)] : []
20293
+ ].filter((result) => !!result && typeof result.then === "function");
20294
+ if (handlerResults.length > 0) {
20295
+ await Promise.allSettled(handlerResults);
20296
+ }
20297
+ }
19876
20298
  };
19877
20299
 
19878
20300
  // src/tracing-options.ts