@mastra/observability 1.0.0-beta.5 → 1.0.0-beta.7

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,126 @@
1
1
  # @mastra/observability
2
2
 
3
+ ## 1.0.0-beta.7
4
+
5
+ ### Minor Changes
6
+
7
+ - Unified observability schema with entity-based span identification ([#11132](https://github.com/mastra-ai/mastra/pull/11132))
8
+
9
+ ## What changed
10
+
11
+ Spans now use a unified identification model with `entityId`, `entityType`, and `entityName` instead of separate `agentId`, `toolId`, `workflowId` fields.
12
+
13
+ **Before:**
14
+
15
+ ```typescript
16
+ // Old span structure
17
+ span.agentId; // 'my-agent'
18
+ span.toolId; // undefined
19
+ span.workflowId; // undefined
20
+ ```
21
+
22
+ **After:**
23
+
24
+ ```typescript
25
+ // New span structure
26
+ span.entityType; // EntityType.AGENT
27
+ span.entityId; // 'my-agent'
28
+ span.entityName; // 'My Agent'
29
+ ```
30
+
31
+ ## New `listTraces()` API
32
+
33
+ Query traces with filtering, pagination, and sorting:
34
+
35
+ ```typescript
36
+ const { spans, pagination } = await storage.listTraces({
37
+ filters: {
38
+ entityType: EntityType.AGENT,
39
+ entityId: 'my-agent',
40
+ userId: 'user-123',
41
+ environment: 'production',
42
+ status: TraceStatus.SUCCESS,
43
+ startedAt: { start: new Date('2024-01-01'), end: new Date('2024-01-31') },
44
+ },
45
+ pagination: { page: 0, perPage: 50 },
46
+ orderBy: { field: 'startedAt', direction: 'DESC' },
47
+ });
48
+ ```
49
+
50
+ **Available filters:** date ranges (`startedAt`, `endedAt`), entity (`entityType`, `entityId`, `entityName`), identity (`userId`, `organizationId`), correlation IDs (`runId`, `sessionId`, `threadId`), deployment (`environment`, `source`, `serviceName`), `tags`, `metadata`, and `status`.
51
+
52
+ ## New retrieval methods
53
+ - `getSpan({ traceId, spanId })` - Get a single span
54
+ - `getRootSpan({ traceId })` - Get the root span of a trace
55
+ - `getTrace({ traceId })` - Get all spans for a trace
56
+
57
+ ## Backward compatibility
58
+
59
+ The legacy `getTraces()` method continues to work. When you pass `name: "agent run: my-agent"`, it automatically transforms to `entityId: "my-agent", entityType: AGENT`.
60
+
61
+ ## Migration
62
+
63
+ **Automatic:** SQL-based stores (PostgreSQL, LibSQL, MSSQL) automatically add new columns to existing `spans` tables on initialization. Existing data is preserved with new columns set to `NULL`.
64
+
65
+ **No action required:** Your existing code continues to work. Adopt the new fields and `listTraces()` API at your convenience.
66
+
67
+ ### Patch Changes
68
+
69
+ - Refactor storage architecture to use domain-specific stores via `getStore()` pattern ([#11361](https://github.com/mastra-ai/mastra/pull/11361))
70
+
71
+ ### Summary
72
+
73
+ This release introduces a new storage architecture that replaces passthrough methods on `MastraStorage` with domain-specific storage interfaces accessed via `getStore()`. This change reduces code duplication across storage adapters and provides a cleaner, more modular API.
74
+
75
+ ### Migration Guide
76
+
77
+ All direct method calls on storage instances should be updated to use `getStore()`:
78
+
79
+ ```typescript
80
+ // Before
81
+ const thread = await storage.getThreadById({ threadId });
82
+ await storage.persistWorkflowSnapshot({ workflowName, runId, snapshot });
83
+ await storage.createSpan(span);
84
+
85
+ // After
86
+ const memory = await storage.getStore('memory');
87
+ const thread = await memory?.getThreadById({ threadId });
88
+
89
+ const workflows = await storage.getStore('workflows');
90
+ await workflows?.persistWorkflowSnapshot({ workflowName, runId, snapshot });
91
+
92
+ const observability = await storage.getStore('observability');
93
+ await observability?.createSpan(span);
94
+ ```
95
+
96
+ ### Available Domains
97
+ - **`memory`**: Thread and message operations (`getThreadById`, `saveThread`, `saveMessages`, etc.)
98
+ - **`workflows`**: Workflow state persistence (`persistWorkflowSnapshot`, `loadWorkflowSnapshot`, `getWorkflowRunById`, etc.)
99
+ - **`scores`**: Evaluation scores (`saveScore`, `listScoresByScorerId`, etc.)
100
+ - **`observability`**: Tracing and spans (`createSpan`, `updateSpan`, `getTrace`, etc.)
101
+ - **`agents`**: Stored agent configurations (`createAgent`, `getAgentById`, `listAgents`, etc.)
102
+
103
+ ### Breaking Changes
104
+ - Passthrough methods have been removed from `MastraStorage` base class
105
+ - All storage adapters now require accessing domains via `getStore()`
106
+ - The `stores` property on storage instances is now the canonical way to access domain storage
107
+
108
+ ### Internal Changes
109
+ - Each storage adapter now initializes domain-specific stores in its constructor
110
+ - Domain stores share database connections and handle their own table initialization
111
+
112
+ - Updated dependencies [[`33a4d2e`](https://github.com/mastra-ai/mastra/commit/33a4d2e4ed8af51f69256232f00c34d6b6b51d48), [`4aaa844`](https://github.com/mastra-ai/mastra/commit/4aaa844a4f19d054490f43638a990cc57bda8d2f), [`4a1a6cb`](https://github.com/mastra-ai/mastra/commit/4a1a6cb3facad54b2bb6780b00ce91d6de1edc08), [`31d13d5`](https://github.com/mastra-ai/mastra/commit/31d13d5fdc2e2380e2e3ee3ec9fb29d2a00f265d), [`4c62166`](https://github.com/mastra-ai/mastra/commit/4c621669f4a29b1f443eca3ba70b814afa286266), [`7bcbf10`](https://github.com/mastra-ai/mastra/commit/7bcbf10133516e03df964b941f9a34e9e4ab4177), [`4353600`](https://github.com/mastra-ai/mastra/commit/43536005a65988a8eede236f69122e7f5a284ba2), [`6986fb0`](https://github.com/mastra-ai/mastra/commit/6986fb064f5db6ecc24aa655e1d26529087b43b3), [`053e979`](https://github.com/mastra-ai/mastra/commit/053e9793b28e970086b0507f7f3b76ea32c1e838), [`e26dc9c`](https://github.com/mastra-ai/mastra/commit/e26dc9c3ccfec54ae3dc3e2b2589f741f9ae60a6), [`55edf73`](https://github.com/mastra-ai/mastra/commit/55edf7302149d6c964fbb7908b43babfc2b52145), [`27c0009`](https://github.com/mastra-ai/mastra/commit/27c0009777a6073d7631b0eb7b481d94e165b5ca), [`dee388d`](https://github.com/mastra-ai/mastra/commit/dee388dde02f2e63c53385ae69252a47ab6825cc), [`3f3fc30`](https://github.com/mastra-ai/mastra/commit/3f3fc3096f24c4a26cffeecfe73085928f72aa63), [`d90ea65`](https://github.com/mastra-ai/mastra/commit/d90ea6536f7aa51c6545a4e9215b55858e98e16d), [`d171e55`](https://github.com/mastra-ai/mastra/commit/d171e559ead9f52ec728d424844c8f7b164c4510), [`10c2735`](https://github.com/mastra-ai/mastra/commit/10c27355edfdad1ee2b826b897df74125eb81fb8), [`1924cf0`](https://github.com/mastra-ai/mastra/commit/1924cf06816e5e4d4d5333065ec0f4bb02a97799), [`b339816`](https://github.com/mastra-ai/mastra/commit/b339816df0984d0243d944ac2655d6ba5f809cde)]:
113
+ - @mastra/core@1.0.0-beta.15
114
+
115
+ ## 1.0.0-beta.6
116
+
117
+ ### Patch Changes
118
+
119
+ - Limits the size of large payloads in span data. ([#11237](https://github.com/mastra-ai/mastra/pull/11237))
120
+
121
+ - Updated dependencies [[`4f94ed8`](https://github.com/mastra-ai/mastra/commit/4f94ed8177abfde3ec536e3574883e075423350c), [`ac3cc23`](https://github.com/mastra-ai/mastra/commit/ac3cc2397d1966bc0fc2736a223abc449d3c7719), [`a86f4df`](https://github.com/mastra-ai/mastra/commit/a86f4df0407311e0d2ea49b9a541f0938810d6a9), [`029540c`](https://github.com/mastra-ai/mastra/commit/029540ca1e582fc2dd8d288ecd4a9b0f31a954ef), [`66741d1`](https://github.com/mastra-ai/mastra/commit/66741d1a99c4f42cf23a16109939e8348ac6852e), [`01b20fe`](https://github.com/mastra-ai/mastra/commit/01b20fefb7c67c2b7d79417598ef4e60256d1225), [`0dbf199`](https://github.com/mastra-ai/mastra/commit/0dbf199110f22192ce5c95b1c8148d4872b4d119), [`a7ce182`](https://github.com/mastra-ai/mastra/commit/a7ce1822a8785ce45d62dd5c911af465e144f7d7)]:
122
+ - @mastra/core@1.0.0-beta.14
123
+
3
124
  ## 1.0.0-beta.5
4
125
 
5
126
  ### Patch Changes
@@ -1,4 +1,5 @@
1
- import type { TracingEvent, InitExporterOptions, TracingStorageStrategy } from '@mastra/core/observability';
1
+ import type { TracingEvent, InitExporterOptions } from '@mastra/core/observability';
2
+ import type { TracingStorageStrategy } from '@mastra/core/storage';
2
3
  import type { BaseExporterConfig } from './base.js';
3
4
  import { BaseExporter } from './base.js';
4
5
  interface DefaultExporterConfig extends BaseExporterConfig {
@@ -18,9 +19,9 @@ export declare class DefaultExporter extends BaseExporter {
18
19
  /**
19
20
  * Initialize the exporter (called after all dependencies are ready)
20
21
  */
21
- init(options: InitExporterOptions): void;
22
+ init(options: InitExporterOptions): Promise<void>;
22
23
  /**
23
- * Initialize the resolved strategy once storage is available
24
+ * Initialize the resolved strategy once observability store is available
24
25
  */
25
26
  private initializeStrategy;
26
27
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/exporters/default.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EAEZ,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,UAAU,qBAAsB,SAAQ,kBAAkB;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,QAAQ,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAAC;CAC5C;AAwDD,qBAAa,eAAgB,SAAQ,YAAY;;IAC/C,IAAI,SAA2C;IAK/C,OAAO,CAAC,MAAM,CAAc;IAI5B,OAAO,CAAC,eAAe,CAA0B;gBAErC,MAAM,GAAE,qBAA0B;IAoC9C;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAUxC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAS9B;;OAEG;IACH,OAAO,CAAC,WAAW;IAgFnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAsBnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAiBnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,iBAAiB;IAczB;;OAEG;YACW,mBAAmB;IAyCjC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAgBnC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;OAEG;YACW,KAAK;IAsDnB;;OAEG;YACW,gBAAgB;IA2DxB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBvD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhC"}
1
+ {"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/exporters/default.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAmB,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAErG,OAAO,KAAK,EAKV,sBAAsB,EACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,UAAU,qBAAsB,SAAQ,kBAAkB;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,QAAQ,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAAC;CAC5C;AAmED,qBAAa,eAAgB,SAAQ,YAAY;;IAC/C,IAAI,SAA2C;IAM/C,OAAO,CAAC,MAAM,CAAc;IAI5B,OAAO,CAAC,eAAe,CAA0B;gBAErC,MAAM,GAAE,qBAA0B;IAoC9C;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvD;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAS9B;;OAEG;IACH,OAAO,CAAC,WAAW;IAgFnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAsBnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAiBnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,iBAAiB;IAgDzB,OAAO,CAAC,iBAAiB;IAczB;;OAEG;YACW,mBAAmB;IAyCjC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAgBnC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;OAEG;YACW,KAAK;IAsDnB;;OAEG;YACW,gBAAgB;IA+DxB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBvD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhC"}
package/dist/index.cjs CHANGED
@@ -4489,24 +4489,31 @@ var ConsoleExporter = class extends BaseExporter {
4489
4489
  this.logger.info("ConsoleExporter shutdown");
4490
4490
  }
4491
4491
  };
4492
- function resolveTracingStorageStrategy(config, storage, logger) {
4492
+ function resolveTracingStorageStrategy(config, observability, storageName, logger) {
4493
4493
  if (config.strategy && config.strategy !== "auto") {
4494
- const hints = storage.tracingStrategy;
4494
+ const hints = observability.tracingStrategy;
4495
4495
  if (hints.supported.includes(config.strategy)) {
4496
4496
  return config.strategy;
4497
4497
  }
4498
4498
  logger.warn("User-specified tracing strategy not supported by storage adapter, falling back to auto-selection", {
4499
4499
  userStrategy: config.strategy,
4500
- storageAdapter: storage.constructor.name,
4500
+ storageAdapter: storageName,
4501
4501
  supportedStrategies: hints.supported,
4502
4502
  fallbackStrategy: hints.preferred
4503
4503
  });
4504
4504
  }
4505
- return storage.tracingStrategy.preferred;
4505
+ return observability.tracingStrategy.preferred;
4506
+ }
4507
+ function getStringOrNull(value) {
4508
+ return typeof value === "string" ? value : null;
4509
+ }
4510
+ function getObjectOrNull(value) {
4511
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
4506
4512
  }
4507
4513
  var DefaultExporter = class extends BaseExporter {
4508
4514
  name = "mastra-default-observability-exporter";
4509
4515
  #storage;
4516
+ #observability;
4510
4517
  #config;
4511
4518
  #resolvedStrategy;
4512
4519
  buffer;
@@ -4543,25 +4550,30 @@ var DefaultExporter = class extends BaseExporter {
4543
4550
  /**
4544
4551
  * Initialize the exporter (called after all dependencies are ready)
4545
4552
  */
4546
- init(options) {
4553
+ async init(options) {
4547
4554
  this.#storage = options.mastra?.getStorage();
4548
4555
  if (!this.#storage) {
4549
4556
  this.logger.warn("DefaultExporter disabled: Storage not available. Traces will not be persisted.");
4550
4557
  return;
4551
4558
  }
4552
- this.initializeStrategy(this.#storage);
4559
+ this.#observability = await this.#storage.getStore("observability");
4560
+ if (!this.#observability) {
4561
+ this.logger.warn("DefaultExporter disabled: Observability storage not available. Traces will not be persisted.");
4562
+ return;
4563
+ }
4564
+ this.initializeStrategy(this.#observability, this.#storage.constructor.name);
4553
4565
  }
4554
4566
  /**
4555
- * Initialize the resolved strategy once storage is available
4567
+ * Initialize the resolved strategy once observability store is available
4556
4568
  */
4557
- initializeStrategy(storage) {
4569
+ initializeStrategy(observability, storageName) {
4558
4570
  if (this.#strategyInitialized) return;
4559
- this.#resolvedStrategy = resolveTracingStorageStrategy(this.#config, storage, this.logger);
4571
+ this.#resolvedStrategy = resolveTracingStorageStrategy(this.#config, observability, storageName, this.logger);
4560
4572
  this.#strategyInitialized = true;
4561
4573
  this.logger.debug("tracing storage exporter initialized", {
4562
4574
  strategy: this.#resolvedStrategy,
4563
4575
  source: this.#config.strategy !== "auto" ? "user" : "auto",
4564
- storageAdapter: storage.constructor.name,
4576
+ storageAdapter: storageName,
4565
4577
  maxBatchSize: this.#config.maxBatchSize,
4566
4578
  maxBatchWaitMs: this.#config.maxBatchWaitMs
4567
4579
  });
@@ -4734,22 +4746,44 @@ var DefaultExporter = class extends BaseExporter {
4734
4746
  }
4735
4747
  }
4736
4748
  buildCreateRecord(span) {
4749
+ const metadata = span.metadata ?? {};
4737
4750
  return {
4738
4751
  traceId: span.traceId,
4739
4752
  spanId: span.id,
4740
4753
  parentSpanId: span.parentSpanId ?? null,
4741
4754
  name: span.name,
4742
- scope: null,
4755
+ // Entity identification - from span
4756
+ entityType: span.entityType ?? null,
4757
+ entityId: span.entityId ?? null,
4758
+ entityName: span.entityName ?? null,
4759
+ // Identity & Tenancy - extracted from metadata if present
4760
+ userId: getStringOrNull(metadata.userId),
4761
+ organizationId: getStringOrNull(metadata.organizationId),
4762
+ resourceId: getStringOrNull(metadata.resourceId),
4763
+ // Correlation IDs - extracted from metadata if present
4764
+ runId: getStringOrNull(metadata.runId),
4765
+ sessionId: getStringOrNull(metadata.sessionId),
4766
+ threadId: getStringOrNull(metadata.threadId),
4767
+ requestId: getStringOrNull(metadata.requestId),
4768
+ // Deployment context - extracted from metadata if present
4769
+ environment: getStringOrNull(metadata.environment),
4770
+ source: getStringOrNull(metadata.source),
4771
+ serviceName: getStringOrNull(metadata.serviceName),
4772
+ scope: getObjectOrNull(metadata.scope),
4773
+ // Span data
4743
4774
  spanType: span.type,
4744
4775
  attributes: this.serializeAttributes(span),
4745
4776
  metadata: span.metadata ?? null,
4777
+ // Keep all metadata including extracted fields
4778
+ tags: span.tags ?? null,
4746
4779
  links: null,
4780
+ input: span.input ?? null,
4781
+ output: span.output ?? null,
4782
+ error: span.errorInfo ?? null,
4783
+ isEvent: span.isEvent,
4784
+ // Timestamps
4747
4785
  startedAt: span.startTime,
4748
- endedAt: span.endTime ?? null,
4749
- input: span.input,
4750
- output: span.output,
4751
- error: span.errorInfo,
4752
- isEvent: span.isEvent
4786
+ endedAt: span.endTime ?? null
4753
4787
  };
4754
4788
  }
4755
4789
  buildUpdateRecord(span) {
@@ -4762,36 +4796,36 @@ var DefaultExporter = class extends BaseExporter {
4762
4796
  endedAt: span.endTime ?? null,
4763
4797
  input: span.input,
4764
4798
  output: span.output,
4765
- error: span.errorInfo
4799
+ error: span.errorInfo ?? null
4766
4800
  };
4767
4801
  }
4768
4802
  /**
4769
4803
  * Handles realtime strategy - processes each event immediately
4770
4804
  */
4771
- async handleRealtimeEvent(event, storage) {
4805
+ async handleRealtimeEvent(event, observability$1) {
4772
4806
  const span = event.exportedSpan;
4773
4807
  const spanKey = this.buildSpanKey(span.traceId, span.id);
4774
4808
  if (span.isEvent) {
4775
4809
  if (event.type === observability.TracingEventType.SPAN_ENDED) {
4776
- await storage.createSpan(this.buildCreateRecord(event.exportedSpan));
4810
+ await observability$1.createSpan({ span: this.buildCreateRecord(event.exportedSpan) });
4777
4811
  } else {
4778
4812
  this.logger.warn(`Tracing event type not implemented for event spans: ${event.type}`);
4779
4813
  }
4780
4814
  } else {
4781
4815
  switch (event.type) {
4782
4816
  case observability.TracingEventType.SPAN_STARTED:
4783
- await storage.createSpan(this.buildCreateRecord(event.exportedSpan));
4817
+ await observability$1.createSpan({ span: this.buildCreateRecord(event.exportedSpan) });
4784
4818
  this.allCreatedSpans.add(spanKey);
4785
4819
  break;
4786
4820
  case observability.TracingEventType.SPAN_UPDATED:
4787
- await storage.updateSpan({
4821
+ await observability$1.updateSpan({
4788
4822
  traceId: span.traceId,
4789
4823
  spanId: span.id,
4790
4824
  updates: this.buildUpdateRecord(span)
4791
4825
  });
4792
4826
  break;
4793
4827
  case observability.TracingEventType.SPAN_ENDED:
4794
- await storage.updateSpan({
4828
+ await observability$1.updateSpan({
4795
4829
  traceId: span.traceId,
4796
4830
  spanId: span.id,
4797
4831
  updates: this.buildUpdateRecord(span)
@@ -4845,8 +4879,8 @@ var DefaultExporter = class extends BaseExporter {
4845
4879
  * Flushes the current buffer to storage with retry logic
4846
4880
  */
4847
4881
  async flush() {
4848
- if (!this.#storage) {
4849
- this.logger.debug("Cannot flush traces. Mastra storage is not initialized");
4882
+ if (!this.#observability) {
4883
+ this.logger.debug("Cannot flush traces. Observability storage is not initialized");
4850
4884
  return;
4851
4885
  }
4852
4886
  if (this.#flushTimer) {
@@ -4870,7 +4904,7 @@ var DefaultExporter = class extends BaseExporter {
4870
4904
  totalSize: this.buffer.totalSize
4871
4905
  };
4872
4906
  this.resetBuffer();
4873
- await this.flushWithRetries(this.#storage, bufferCopy, 0);
4907
+ await this.flushWithRetries(this.#observability, bufferCopy, 0);
4874
4908
  const elapsed = Date.now() - startTime;
4875
4909
  this.logger.debug("Batch flushed", {
4876
4910
  strategy: this.#resolvedStrategy,
@@ -4883,11 +4917,11 @@ var DefaultExporter = class extends BaseExporter {
4883
4917
  /**
4884
4918
  * Attempts to flush with exponential backoff retry logic
4885
4919
  */
4886
- async flushWithRetries(storage, buffer, attempt) {
4920
+ async flushWithRetries(observability, buffer, attempt) {
4887
4921
  try {
4888
4922
  if (this.#resolvedStrategy === "batch-with-updates") {
4889
4923
  if (buffer.creates.length > 0) {
4890
- await storage.batchCreateSpans({ records: buffer.creates });
4924
+ await observability.batchCreateSpans({ records: buffer.creates });
4891
4925
  }
4892
4926
  if (buffer.updates.length > 0) {
4893
4927
  const sortedUpdates = buffer.updates.sort((a, b) => {
@@ -4897,11 +4931,11 @@ var DefaultExporter = class extends BaseExporter {
4897
4931
  if (spanCompare !== 0) return spanCompare;
4898
4932
  return a.sequenceNumber - b.sequenceNumber;
4899
4933
  });
4900
- await storage.batchUpdateSpans({ records: sortedUpdates });
4934
+ await observability.batchUpdateSpans({ records: sortedUpdates });
4901
4935
  }
4902
4936
  } else if (this.#resolvedStrategy === "insert-only") {
4903
4937
  if (buffer.insertOnly.length > 0) {
4904
- await storage.batchCreateSpans({ records: buffer.insertOnly });
4938
+ await observability.batchCreateSpans({ records: buffer.insertOnly });
4905
4939
  }
4906
4940
  }
4907
4941
  for (const spanKey of buffer.completedSpans) {
@@ -4917,7 +4951,7 @@ var DefaultExporter = class extends BaseExporter {
4917
4951
  error: error instanceof Error ? error.message : String(error)
4918
4952
  });
4919
4953
  await new Promise((resolve) => setTimeout(resolve, retryDelay));
4920
- return this.flushWithRetries(storage, buffer, attempt + 1);
4954
+ return this.flushWithRetries(observability, buffer, attempt + 1);
4921
4955
  } else {
4922
4956
  this.logger.error("Batch flush failed after all retries, dropping batch", {
4923
4957
  finalAttempt: attempt + 1,
@@ -4932,16 +4966,16 @@ var DefaultExporter = class extends BaseExporter {
4932
4966
  }
4933
4967
  }
4934
4968
  async _exportTracingEvent(event) {
4935
- if (!this.#storage) {
4936
- this.logger.debug("Cannot store traces. Mastra storage is not initialized");
4969
+ if (!this.#observability) {
4970
+ this.logger.debug("Cannot store traces. Observability storage is not initialized");
4937
4971
  return;
4938
4972
  }
4939
4973
  if (!this.#strategyInitialized) {
4940
- this.initializeStrategy(this.#storage);
4974
+ this.initializeStrategy(this.#observability, this.#storage?.constructor.name ?? "Unknown");
4941
4975
  }
4942
4976
  switch (this.#resolvedStrategy) {
4943
4977
  case "realtime":
4944
- await this.handleRealtimeEvent(event, this.#storage);
4978
+ await this.handleRealtimeEvent(event, this.#observability);
4945
4979
  break;
4946
4980
  case "batch-with-updates":
4947
4981
  this.handleBatchWithUpdatesEvent(event);
@@ -5454,6 +5488,110 @@ var ModelSpanTracker = class {
5454
5488
  }
5455
5489
  };
5456
5490
 
5491
+ // src/spans/serialization.ts
5492
+ var DEFAULT_KEYS_TO_STRIP = /* @__PURE__ */ new Set([
5493
+ "logger",
5494
+ "experimental_providerMetadata",
5495
+ "providerMetadata",
5496
+ "steps",
5497
+ "tracingContext"
5498
+ ]);
5499
+ var DEFAULT_DEEP_CLEAN_OPTIONS = Object.freeze({
5500
+ keysToStrip: DEFAULT_KEYS_TO_STRIP,
5501
+ maxDepth: 6,
5502
+ maxStringLength: 1024,
5503
+ maxArrayLength: 50,
5504
+ maxObjectKeys: 50
5505
+ });
5506
+ function truncateString(s, maxChars) {
5507
+ if (s.length <= maxChars) {
5508
+ return s;
5509
+ }
5510
+ return s.slice(0, maxChars) + "\u2026[truncated]";
5511
+ }
5512
+ function deepClean(value, options = DEFAULT_DEEP_CLEAN_OPTIONS) {
5513
+ const { keysToStrip, maxDepth, maxStringLength, maxArrayLength, maxObjectKeys } = options;
5514
+ const seen = /* @__PURE__ */ new WeakSet();
5515
+ function helper(val, depth) {
5516
+ if (depth > maxDepth) {
5517
+ return "[MaxDepth]";
5518
+ }
5519
+ if (val === null || val === void 0) {
5520
+ return val;
5521
+ }
5522
+ if (typeof val === "string") {
5523
+ return truncateString(val, maxStringLength);
5524
+ }
5525
+ if (typeof val === "number" || typeof val === "boolean") {
5526
+ return val;
5527
+ }
5528
+ if (typeof val === "bigint") {
5529
+ return `${val}n`;
5530
+ }
5531
+ if (typeof val === "function") {
5532
+ return "[Function]";
5533
+ }
5534
+ if (typeof val === "symbol") {
5535
+ return val.description ? `[Symbol(${val.description})]` : "[Symbol]";
5536
+ }
5537
+ if (val instanceof Date) {
5538
+ return val;
5539
+ }
5540
+ if (val instanceof Error) {
5541
+ return {
5542
+ name: val.name,
5543
+ message: val.message ? truncateString(val.message, maxStringLength) : void 0
5544
+ };
5545
+ }
5546
+ if (typeof val === "object") {
5547
+ if (seen.has(val)) {
5548
+ return "[Circular]";
5549
+ }
5550
+ seen.add(val);
5551
+ }
5552
+ if (Array.isArray(val)) {
5553
+ const limitedArray = val.slice(0, maxArrayLength);
5554
+ const cleaned2 = limitedArray.map((item) => helper(item, depth + 1));
5555
+ if (val.length > maxArrayLength) {
5556
+ cleaned2.push(`[\u2026${val.length - maxArrayLength} more items]`);
5557
+ }
5558
+ return cleaned2;
5559
+ }
5560
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(val)) {
5561
+ return `[Buffer length=${val.length}]`;
5562
+ }
5563
+ if (ArrayBuffer.isView(val)) {
5564
+ const ctor = val.constructor?.name ?? "TypedArray";
5565
+ const byteLength = val.byteLength ?? "?";
5566
+ return `[${ctor} byteLength=${byteLength}]`;
5567
+ }
5568
+ if (val instanceof ArrayBuffer) {
5569
+ return `[ArrayBuffer byteLength=${val.byteLength}]`;
5570
+ }
5571
+ const cleaned = {};
5572
+ const entries = Object.entries(val);
5573
+ let keyCount = 0;
5574
+ for (const [key, v] of entries) {
5575
+ if (keysToStrip.has(key)) {
5576
+ continue;
5577
+ }
5578
+ if (keyCount >= maxObjectKeys) {
5579
+ cleaned["__truncated"] = `${entries.length - keyCount} more keys omitted`;
5580
+ break;
5581
+ }
5582
+ try {
5583
+ cleaned[key] = helper(v, depth + 1);
5584
+ keyCount++;
5585
+ } catch (error) {
5586
+ cleaned[key] = `[${error instanceof Error ? error.message : String(error)}]`;
5587
+ keyCount++;
5588
+ }
5589
+ }
5590
+ return cleaned;
5591
+ }
5592
+ return helper(value, 0);
5593
+ }
5594
+
5457
5595
  // src/spans/base.ts
5458
5596
  function isSpanInternal(spanType, flags) {
5459
5597
  if (flags === void 0 || flags === observability.InternalSpans.NONE) {
@@ -5513,6 +5651,12 @@ var BaseSpan = class {
5513
5651
  metadata;
5514
5652
  tags;
5515
5653
  traceState;
5654
+ /** Entity type that created the span (e.g., agent, workflow) */
5655
+ entityType;
5656
+ /** Entity ID that created the span */
5657
+ entityId;
5658
+ /** Entity name that created the span */
5659
+ entityName;
5516
5660
  /** Parent span ID (for root spans that are children of external spans) */
5517
5661
  parentSpanId;
5518
5662
  constructor(options, observabilityInstance) {
@@ -5527,6 +5671,9 @@ var BaseSpan = class {
5527
5671
  this.isInternal = isSpanInternal(this.type, options.tracingPolicy?.internal);
5528
5672
  this.traceState = options.traceState;
5529
5673
  this.tags = !options.parent && options.tags?.length ? options.tags : void 0;
5674
+ this.entityType = options.entityType;
5675
+ this.entityId = options.entityId;
5676
+ this.entityName = options.entityName;
5530
5677
  if (this.isEvent) {
5531
5678
  this.output = deepClean(options.output);
5532
5679
  } else {
@@ -5580,6 +5727,9 @@ var BaseSpan = class {
5580
5727
  traceId: this.traceId,
5581
5728
  name: this.name,
5582
5729
  type: this.type,
5730
+ entityType: this.entityType,
5731
+ entityId: this.entityId,
5732
+ entityName: this.entityName,
5583
5733
  attributes: this.attributes,
5584
5734
  metadata: this.metadata,
5585
5735
  startTime: this.startTime,
@@ -5620,49 +5770,6 @@ var BaseSpan = class {
5620
5770
  return fn();
5621
5771
  }
5622
5772
  };
5623
- var DEFAULT_KEYS_TO_STRIP = /* @__PURE__ */ new Set([
5624
- "logger",
5625
- "experimental_providerMetadata",
5626
- "providerMetadata",
5627
- "steps",
5628
- "tracingContext"
5629
- ]);
5630
- function deepClean(value, options = {}, _seen = /* @__PURE__ */ new WeakSet(), _depth = 0) {
5631
- const { keysToStrip = DEFAULT_KEYS_TO_STRIP, maxDepth = 10 } = options;
5632
- if (_depth > maxDepth) {
5633
- return "[MaxDepth]";
5634
- }
5635
- if (value === null || typeof value !== "object") {
5636
- try {
5637
- JSON.stringify(value);
5638
- return value;
5639
- } catch (error) {
5640
- return `[${error instanceof Error ? error.message : String(error)}]`;
5641
- }
5642
- }
5643
- if (_seen.has(value)) {
5644
- return "[Circular]";
5645
- }
5646
- _seen.add(value);
5647
- if (value instanceof Date) {
5648
- return value;
5649
- }
5650
- if (Array.isArray(value)) {
5651
- return value.map((item) => deepClean(item, options, _seen, _depth + 1));
5652
- }
5653
- const cleaned = {};
5654
- for (const [key, val] of Object.entries(value)) {
5655
- if (keysToStrip.has(key)) {
5656
- continue;
5657
- }
5658
- try {
5659
- cleaned[key] = deepClean(val, options, _seen, _depth + 1);
5660
- } catch (error) {
5661
- cleaned[key] = `[${error instanceof Error ? error.message : String(error)}]`;
5662
- }
5663
- }
5664
- return cleaned;
5665
- }
5666
5773
  var DefaultSpan = class extends BaseSpan {
5667
5774
  id;
5668
5775
  traceId;
@@ -6545,6 +6652,8 @@ exports.BaseObservabilityInstance = BaseObservabilityInstance;
6545
6652
  exports.BaseSpan = BaseSpan;
6546
6653
  exports.CloudExporter = CloudExporter;
6547
6654
  exports.ConsoleExporter = ConsoleExporter;
6655
+ exports.DEFAULT_DEEP_CLEAN_OPTIONS = DEFAULT_DEEP_CLEAN_OPTIONS;
6656
+ exports.DEFAULT_KEYS_TO_STRIP = DEFAULT_KEYS_TO_STRIP;
6548
6657
  exports.DefaultExporter = DefaultExporter;
6549
6658
  exports.DefaultObservabilityInstance = DefaultObservabilityInstance;
6550
6659
  exports.DefaultSpan = DefaultSpan;
@@ -6561,5 +6670,6 @@ exports.observabilityConfigValueSchema = observabilityConfigValueSchema;
6561
6670
  exports.observabilityInstanceConfigSchema = observabilityInstanceConfigSchema;
6562
6671
  exports.observabilityRegistryConfigSchema = observabilityRegistryConfigSchema;
6563
6672
  exports.samplingStrategySchema = samplingStrategySchema;
6673
+ exports.truncateString = truncateString;
6564
6674
  //# sourceMappingURL=index.cjs.map
6565
6675
  //# sourceMappingURL=index.cjs.map