@mastra/observability 1.0.0-beta.6 → 1.0.0-beta.8

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,132 @@
1
1
  # @mastra/observability
2
2
 
3
+ ## 1.0.0-beta.8
4
+
5
+ ### Patch Changes
6
+
7
+ - fix(observability): start MODEL_STEP span at beginning of LLM execution ([#11409](https://github.com/mastra-ai/mastra/pull/11409))
8
+
9
+ The MODEL_STEP span was being created when the step-start chunk arrived (after the model API call completed), causing the span's startTime to be close to its endTime instead of accurately reflecting when the step began.
10
+
11
+ This fix ensures MODEL_STEP spans capture the full duration of each LLM execution step, including the API call latency, by starting the span at the beginning of the step execution rather than when the response starts streaming.
12
+
13
+ Fixes #11271
14
+
15
+ - Updated dependencies [[`3d93a15`](https://github.com/mastra-ai/mastra/commit/3d93a15796b158c617461c8b98bede476ebb43e2), [`efe406a`](https://github.com/mastra-ai/mastra/commit/efe406a1353c24993280ebc2ed61dd9f65b84b26), [`119e5c6`](https://github.com/mastra-ai/mastra/commit/119e5c65008f3e5cfca954eefc2eb85e3bf40da4), [`74e504a`](https://github.com/mastra-ai/mastra/commit/74e504a3b584eafd2f198001c6a113bbec589fd3), [`e33fdbd`](https://github.com/mastra-ai/mastra/commit/e33fdbd07b33920d81e823122331b0c0bee0bb59), [`929f69c`](https://github.com/mastra-ai/mastra/commit/929f69c3436fa20dd0f0e2f7ebe8270bd82a1529), [`8a73529`](https://github.com/mastra-ai/mastra/commit/8a73529ca01187f604b1f3019d0a725ac63ae55f)]:
16
+ - @mastra/core@1.0.0-beta.16
17
+
18
+ ## 1.0.0-beta.7
19
+
20
+ ### Minor Changes
21
+
22
+ - Unified observability schema with entity-based span identification ([#11132](https://github.com/mastra-ai/mastra/pull/11132))
23
+
24
+ ## What changed
25
+
26
+ Spans now use a unified identification model with `entityId`, `entityType`, and `entityName` instead of separate `agentId`, `toolId`, `workflowId` fields.
27
+
28
+ **Before:**
29
+
30
+ ```typescript
31
+ // Old span structure
32
+ span.agentId; // 'my-agent'
33
+ span.toolId; // undefined
34
+ span.workflowId; // undefined
35
+ ```
36
+
37
+ **After:**
38
+
39
+ ```typescript
40
+ // New span structure
41
+ span.entityType; // EntityType.AGENT
42
+ span.entityId; // 'my-agent'
43
+ span.entityName; // 'My Agent'
44
+ ```
45
+
46
+ ## New `listTraces()` API
47
+
48
+ Query traces with filtering, pagination, and sorting:
49
+
50
+ ```typescript
51
+ const { spans, pagination } = await storage.listTraces({
52
+ filters: {
53
+ entityType: EntityType.AGENT,
54
+ entityId: 'my-agent',
55
+ userId: 'user-123',
56
+ environment: 'production',
57
+ status: TraceStatus.SUCCESS,
58
+ startedAt: { start: new Date('2024-01-01'), end: new Date('2024-01-31') },
59
+ },
60
+ pagination: { page: 0, perPage: 50 },
61
+ orderBy: { field: 'startedAt', direction: 'DESC' },
62
+ });
63
+ ```
64
+
65
+ **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`.
66
+
67
+ ## New retrieval methods
68
+ - `getSpan({ traceId, spanId })` - Get a single span
69
+ - `getRootSpan({ traceId })` - Get the root span of a trace
70
+ - `getTrace({ traceId })` - Get all spans for a trace
71
+
72
+ ## Backward compatibility
73
+
74
+ The legacy `getTraces()` method continues to work. When you pass `name: "agent run: my-agent"`, it automatically transforms to `entityId: "my-agent", entityType: AGENT`.
75
+
76
+ ## Migration
77
+
78
+ **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`.
79
+
80
+ **No action required:** Your existing code continues to work. Adopt the new fields and `listTraces()` API at your convenience.
81
+
82
+ ### Patch Changes
83
+
84
+ - Refactor storage architecture to use domain-specific stores via `getStore()` pattern ([#11361](https://github.com/mastra-ai/mastra/pull/11361))
85
+
86
+ ### Summary
87
+
88
+ 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.
89
+
90
+ ### Migration Guide
91
+
92
+ All direct method calls on storage instances should be updated to use `getStore()`:
93
+
94
+ ```typescript
95
+ // Before
96
+ const thread = await storage.getThreadById({ threadId });
97
+ await storage.persistWorkflowSnapshot({ workflowName, runId, snapshot });
98
+ await storage.createSpan(span);
99
+
100
+ // After
101
+ const memory = await storage.getStore('memory');
102
+ const thread = await memory?.getThreadById({ threadId });
103
+
104
+ const workflows = await storage.getStore('workflows');
105
+ await workflows?.persistWorkflowSnapshot({ workflowName, runId, snapshot });
106
+
107
+ const observability = await storage.getStore('observability');
108
+ await observability?.createSpan(span);
109
+ ```
110
+
111
+ ### Available Domains
112
+ - **`memory`**: Thread and message operations (`getThreadById`, `saveThread`, `saveMessages`, etc.)
113
+ - **`workflows`**: Workflow state persistence (`persistWorkflowSnapshot`, `loadWorkflowSnapshot`, `getWorkflowRunById`, etc.)
114
+ - **`scores`**: Evaluation scores (`saveScore`, `listScoresByScorerId`, etc.)
115
+ - **`observability`**: Tracing and spans (`createSpan`, `updateSpan`, `getTrace`, etc.)
116
+ - **`agents`**: Stored agent configurations (`createAgent`, `getAgentById`, `listAgents`, etc.)
117
+
118
+ ### Breaking Changes
119
+ - Passthrough methods have been removed from `MastraStorage` base class
120
+ - All storage adapters now require accessing domains via `getStore()`
121
+ - The `stores` property on storage instances is now the canonical way to access domain storage
122
+
123
+ ### Internal Changes
124
+ - Each storage adapter now initializes domain-specific stores in its constructor
125
+ - Domain stores share database connections and handle their own table initialization
126
+
127
+ - 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)]:
128
+ - @mastra/core@1.0.0-beta.15
129
+
3
130
  ## 1.0.0-beta.6
4
131
 
5
132
  ### 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);
@@ -5102,9 +5136,14 @@ var ModelSpanTracker = class {
5102
5136
  this.#modelSpan?.update(options);
5103
5137
  }
5104
5138
  /**
5105
- * Start a new Model execution step
5139
+ * Start a new Model execution step.
5140
+ * This should be called at the beginning of LLM execution to capture accurate startTime.
5141
+ * The step-start chunk payload can be passed later via updateStep() if needed.
5106
5142
  */
5107
- #startStepSpan(payload) {
5143
+ startStep(payload) {
5144
+ if (this.#currentStepSpan) {
5145
+ return;
5146
+ }
5108
5147
  this.#currentStepSpan = this.#modelSpan?.createChildSpan({
5109
5148
  name: `step: ${this.#stepIndex}`,
5110
5149
  type: observability.SpanType.MODEL_STEP,
@@ -5117,6 +5156,22 @@ var ModelSpanTracker = class {
5117
5156
  });
5118
5157
  this.#chunkSequence = 0;
5119
5158
  }
5159
+ /**
5160
+ * Update the current step span with additional payload data.
5161
+ * Called when step-start chunk arrives with request/warnings info.
5162
+ */
5163
+ updateStep(payload) {
5164
+ if (!this.#currentStepSpan || !payload) {
5165
+ return;
5166
+ }
5167
+ this.#currentStepSpan.update({
5168
+ input: payload.request,
5169
+ attributes: {
5170
+ ...payload.messageId ? { messageId: payload.messageId } : {},
5171
+ ...payload.warnings?.length ? { warnings: payload.warnings } : {}
5172
+ }
5173
+ });
5174
+ }
5120
5175
  /**
5121
5176
  * End the current Model execution step with token usage, finish reason, output, and metadata
5122
5177
  */
@@ -5151,7 +5206,7 @@ var ModelSpanTracker = class {
5151
5206
  */
5152
5207
  #startChunkSpan(chunkType, initialData) {
5153
5208
  if (!this.#currentStepSpan) {
5154
- this.#startStepSpan();
5209
+ this.startStep();
5155
5210
  }
5156
5211
  this.#currentChunkSpan = this.#currentStepSpan?.createChildSpan({
5157
5212
  name: `chunk: '${chunkType}'`,
@@ -5191,7 +5246,7 @@ var ModelSpanTracker = class {
5191
5246
  */
5192
5247
  #createEventSpan(chunkType, output) {
5193
5248
  if (!this.#currentStepSpan) {
5194
- this.#startStepSpan();
5249
+ this.startStep();
5195
5250
  }
5196
5251
  const span = this.#currentStepSpan?.createEventSpan({
5197
5252
  name: `chunk: '${chunkType}'`,
@@ -5310,7 +5365,7 @@ var ModelSpanTracker = class {
5310
5365
  let acc = this.#toolOutputAccumulators.get(toolCallId);
5311
5366
  if (!acc) {
5312
5367
  if (!this.#currentStepSpan) {
5313
- this.#startStepSpan();
5368
+ this.startStep();
5314
5369
  }
5315
5370
  acc = {
5316
5371
  toolName: toolName || "unknown",
@@ -5410,7 +5465,11 @@ var ModelSpanTracker = class {
5410
5465
  this.#handleObjectChunk(chunk);
5411
5466
  break;
5412
5467
  case "step-start":
5413
- this.#startStepSpan(chunk.payload);
5468
+ if (this.#currentStepSpan) {
5469
+ this.updateStep(chunk.payload);
5470
+ } else {
5471
+ this.startStep(chunk.payload);
5472
+ }
5414
5473
  break;
5415
5474
  case "step-finish":
5416
5475
  this.#endStepSpan(chunk.payload);
@@ -5617,6 +5676,12 @@ var BaseSpan = class {
5617
5676
  metadata;
5618
5677
  tags;
5619
5678
  traceState;
5679
+ /** Entity type that created the span (e.g., agent, workflow) */
5680
+ entityType;
5681
+ /** Entity ID that created the span */
5682
+ entityId;
5683
+ /** Entity name that created the span */
5684
+ entityName;
5620
5685
  /** Parent span ID (for root spans that are children of external spans) */
5621
5686
  parentSpanId;
5622
5687
  constructor(options, observabilityInstance) {
@@ -5631,6 +5696,9 @@ var BaseSpan = class {
5631
5696
  this.isInternal = isSpanInternal(this.type, options.tracingPolicy?.internal);
5632
5697
  this.traceState = options.traceState;
5633
5698
  this.tags = !options.parent && options.tags?.length ? options.tags : void 0;
5699
+ this.entityType = options.entityType;
5700
+ this.entityId = options.entityId;
5701
+ this.entityName = options.entityName;
5634
5702
  if (this.isEvent) {
5635
5703
  this.output = deepClean(options.output);
5636
5704
  } else {
@@ -5684,6 +5752,9 @@ var BaseSpan = class {
5684
5752
  traceId: this.traceId,
5685
5753
  name: this.name,
5686
5754
  type: this.type,
5755
+ entityType: this.entityType,
5756
+ entityId: this.entityId,
5757
+ entityName: this.entityName,
5687
5758
  attributes: this.attributes,
5688
5759
  metadata: this.metadata,
5689
5760
  startTime: this.startTime,