@mastra/core 0.15.2 → 0.15.3-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/agent/agent.types.d.ts +2 -0
  2. package/dist/agent/agent.types.d.ts.map +1 -1
  3. package/dist/agent/index.cjs +8 -8
  4. package/dist/agent/index.d.ts +0 -2
  5. package/dist/agent/index.d.ts.map +1 -1
  6. package/dist/agent/index.js +1 -1
  7. package/dist/agent/input-processor/index.cjs +6 -6
  8. package/dist/agent/input-processor/index.js +1 -1
  9. package/dist/ai-tracing/base.d.ts +3 -1
  10. package/dist/ai-tracing/base.d.ts.map +1 -1
  11. package/dist/ai-tracing/default.d.ts +1 -9
  12. package/dist/ai-tracing/default.d.ts.map +1 -1
  13. package/dist/ai-tracing/exporters/console.d.ts +10 -0
  14. package/dist/ai-tracing/exporters/console.d.ts.map +1 -0
  15. package/dist/ai-tracing/exporters/default.d.ts +97 -0
  16. package/dist/ai-tracing/exporters/default.d.ts.map +1 -0
  17. package/dist/ai-tracing/exporters/index.d.ts +6 -0
  18. package/dist/ai-tracing/exporters/index.d.ts.map +1 -0
  19. package/dist/ai-tracing/index.cjs +31 -27
  20. package/dist/ai-tracing/index.d.ts +1 -0
  21. package/dist/ai-tracing/index.d.ts.map +1 -1
  22. package/dist/ai-tracing/index.js +1 -1
  23. package/dist/ai-tracing/no-op.d.ts +8 -0
  24. package/dist/ai-tracing/no-op.d.ts.map +1 -1
  25. package/dist/ai-tracing/types.d.ts +33 -0
  26. package/dist/ai-tracing/types.d.ts.map +1 -1
  27. package/dist/{chunk-DPE6K23N.cjs → chunk-2KK7QQH2.cjs} +47 -8
  28. package/dist/chunk-2KK7QQH2.cjs.map +1 -0
  29. package/dist/{chunk-EQLCC3M7.cjs → chunk-4DKPMUAC.cjs} +646 -101
  30. package/dist/chunk-4DKPMUAC.cjs.map +1 -0
  31. package/dist/{chunk-FCFQE5BD.js → chunk-6JAIHLZY.js} +130 -99
  32. package/dist/chunk-6JAIHLZY.js.map +1 -0
  33. package/dist/{chunk-RMEG4MOG.cjs → chunk-6VROHRAR.cjs} +45 -30
  34. package/dist/chunk-6VROHRAR.cjs.map +1 -0
  35. package/dist/{chunk-DAJYN7HG.cjs → chunk-7U76TYYN.cjs} +4 -4
  36. package/dist/{chunk-DAJYN7HG.cjs.map → chunk-7U76TYYN.cjs.map} +1 -1
  37. package/dist/{chunk-VKJWTAHZ.js → chunk-E3LAPNKY.js} +3 -3
  38. package/dist/{chunk-VKJWTAHZ.js.map → chunk-E3LAPNKY.js.map} +1 -1
  39. package/dist/{chunk-QLRALF4I.js → chunk-EEGBKQYC.js} +6 -4
  40. package/dist/chunk-EEGBKQYC.js.map +1 -0
  41. package/dist/{chunk-FFGJPMKP.js → chunk-FLXWZUIG.js} +45 -30
  42. package/dist/chunk-FLXWZUIG.js.map +1 -0
  43. package/dist/{chunk-SNYSVGIU.cjs → chunk-I2YGYG3Y.cjs} +144 -113
  44. package/dist/chunk-I2YGYG3Y.cjs.map +1 -0
  45. package/dist/{chunk-HRPTZGDT.js → chunk-IAOFOXVA.js} +3 -3
  46. package/dist/{chunk-HRPTZGDT.js.map → chunk-IAOFOXVA.js.map} +1 -1
  47. package/dist/{chunk-UKQI74TN.cjs → chunk-K6UMYGK5.cjs} +17 -2
  48. package/dist/chunk-K6UMYGK5.cjs.map +1 -0
  49. package/dist/{chunk-XJFIB2FO.js → chunk-Q67FV4QB.js} +3 -3
  50. package/dist/{chunk-XJFIB2FO.js.map → chunk-Q67FV4QB.js.map} +1 -1
  51. package/dist/{chunk-7EXGDKNQ.cjs → chunk-QBNRMJAN.cjs} +4 -4
  52. package/dist/{chunk-7EXGDKNQ.cjs.map → chunk-QBNRMJAN.cjs.map} +1 -1
  53. package/dist/{chunk-G6WYC4SF.cjs → chunk-SFLYVXLG.cjs} +6 -6
  54. package/dist/{chunk-G6WYC4SF.cjs.map → chunk-SFLYVXLG.cjs.map} +1 -1
  55. package/dist/{chunk-7TH2KSEC.js → chunk-WOTBMZCN.js} +645 -101
  56. package/dist/chunk-WOTBMZCN.js.map +1 -0
  57. package/dist/{chunk-6NYFECSO.js → chunk-Y3WIANDM.js} +43 -4
  58. package/dist/chunk-Y3WIANDM.js.map +1 -0
  59. package/dist/{chunk-Y44DK4T5.js → chunk-YGW2WEJ5.js} +17 -2
  60. package/dist/chunk-YGW2WEJ5.js.map +1 -0
  61. package/dist/{chunk-ASRKKIW7.cjs → chunk-YPT3YX6U.cjs} +10 -8
  62. package/dist/chunk-YPT3YX6U.cjs.map +1 -0
  63. package/dist/index.cjs +42 -42
  64. package/dist/index.js +9 -9
  65. package/dist/llm/model/model.loop.d.ts +1 -1
  66. package/dist/llm/model/model.loop.d.ts.map +1 -1
  67. package/dist/loop/index.cjs +2 -2
  68. package/dist/loop/index.js +1 -1
  69. package/dist/loop/types.d.ts +1 -0
  70. package/dist/loop/types.d.ts.map +1 -1
  71. package/dist/mastra/index.cjs +2 -2
  72. package/dist/mastra/index.d.ts +8 -0
  73. package/dist/mastra/index.d.ts.map +1 -1
  74. package/dist/mastra/index.js +1 -1
  75. package/dist/memory/index.cjs +4 -4
  76. package/dist/memory/index.js +1 -1
  77. package/dist/network/index.cjs +2 -2
  78. package/dist/network/index.js +1 -1
  79. package/dist/network/vNext/index.cjs +15 -13
  80. package/dist/network/vNext/index.cjs.map +1 -1
  81. package/dist/network/vNext/index.d.ts.map +1 -1
  82. package/dist/network/vNext/index.js +4 -2
  83. package/dist/network/vNext/index.js.map +1 -1
  84. package/dist/processors/index.cjs +8 -8
  85. package/dist/processors/index.js +2 -2
  86. package/dist/relevance/index.cjs +4 -4
  87. package/dist/relevance/index.js +1 -1
  88. package/dist/scores/index.cjs +282 -88
  89. package/dist/scores/index.cjs.map +1 -1
  90. package/dist/scores/index.d.ts +1 -1
  91. package/dist/scores/index.js +279 -85
  92. package/dist/scores/index.js.map +1 -1
  93. package/dist/scores/run-experiment/index.d.ts +59 -0
  94. package/dist/scores/run-experiment/index.d.ts.map +1 -0
  95. package/dist/scores/run-experiment/scorerAccumulator.d.ts +12 -0
  96. package/dist/scores/run-experiment/scorerAccumulator.d.ts.map +1 -0
  97. package/dist/storage/base.d.ts +9 -0
  98. package/dist/storage/base.d.ts.map +1 -1
  99. package/dist/storage/domains/observability/base.d.ts +9 -0
  100. package/dist/storage/domains/observability/base.d.ts.map +1 -1
  101. package/dist/storage/domains/observability/index.d.ts +1 -0
  102. package/dist/storage/domains/observability/index.d.ts.map +1 -1
  103. package/dist/storage/domains/observability/inmemory.d.ts +5 -0
  104. package/dist/storage/domains/observability/inmemory.d.ts.map +1 -1
  105. package/dist/storage/index.cjs +24 -6
  106. package/dist/storage/index.cjs.map +1 -1
  107. package/dist/storage/index.js +20 -3
  108. package/dist/storage/index.js.map +1 -1
  109. package/dist/stream/index.cjs +3 -3
  110. package/dist/stream/index.js +1 -1
  111. package/dist/test-utils/llm-mock.cjs +2 -2
  112. package/dist/test-utils/llm-mock.js +1 -1
  113. package/dist/tools/tool-builder/builder.d.ts.map +1 -1
  114. package/dist/tools/types.d.ts +2 -2
  115. package/dist/tools/types.d.ts.map +1 -1
  116. package/dist/utils.cjs +16 -16
  117. package/dist/utils.js +1 -1
  118. package/dist/workflows/default.d.ts +25 -6
  119. package/dist/workflows/default.d.ts.map +1 -1
  120. package/dist/workflows/evented/index.cjs +10 -10
  121. package/dist/workflows/evented/index.js +1 -1
  122. package/dist/workflows/evented/workflow.d.ts.map +1 -1
  123. package/dist/workflows/execution-engine.d.ts +1 -0
  124. package/dist/workflows/execution-engine.d.ts.map +1 -1
  125. package/dist/workflows/index.cjs +10 -10
  126. package/dist/workflows/index.js +1 -1
  127. package/dist/workflows/legacy/index.cjs +22 -22
  128. package/dist/workflows/legacy/index.js +1 -1
  129. package/dist/workflows/workflow.d.ts +7 -0
  130. package/dist/workflows/workflow.d.ts.map +1 -1
  131. package/package.json +1 -1
  132. package/dist/chunk-6NYFECSO.js.map +0 -1
  133. package/dist/chunk-7TH2KSEC.js.map +0 -1
  134. package/dist/chunk-ASRKKIW7.cjs.map +0 -1
  135. package/dist/chunk-DPE6K23N.cjs.map +0 -1
  136. package/dist/chunk-EQLCC3M7.cjs.map +0 -1
  137. package/dist/chunk-FCFQE5BD.js.map +0 -1
  138. package/dist/chunk-FFGJPMKP.js.map +0 -1
  139. package/dist/chunk-QLRALF4I.js.map +0 -1
  140. package/dist/chunk-RMEG4MOG.cjs.map +0 -1
  141. package/dist/chunk-SNYSVGIU.cjs.map +0 -1
  142. package/dist/chunk-UKQI74TN.cjs.map +0 -1
  143. package/dist/chunk-Y44DK4T5.js.map +0 -1
  144. package/dist/scores/run-experiment.d.ts +0 -35
  145. package/dist/scores/run-experiment.d.ts.map +0 -1
@@ -13,6 +13,7 @@ var NoOpAISpan = class _NoOpAISpan {
13
13
  traceId;
14
14
  startTime;
15
15
  endTime;
16
+ isEvent;
16
17
  aiTracing;
17
18
  input;
18
19
  output;
@@ -30,13 +31,18 @@ var NoOpAISpan = class _NoOpAISpan {
30
31
  this.startTime = /* @__PURE__ */ new Date();
31
32
  this.aiTracing = aiTracing;
32
33
  this.input = options.input;
34
+ this.output = options.isEvent ? options.output : void 0;
35
+ this.isEvent = options.isEvent;
33
36
  }
34
37
  end(_options) {
35
38
  }
36
39
  error(_options) {
37
40
  }
38
41
  createChildSpan(options) {
39
- return new _NoOpAISpan({ ...options, parent: this }, this.aiTracing);
42
+ return new _NoOpAISpan({ ...options, parent: this, isEvent: false }, this.aiTracing);
43
+ }
44
+ createEventSpan(options) {
45
+ return new _NoOpAISpan({ ...options, parent: this, isEvent: true }, this.aiTracing);
40
46
  }
41
47
  update(_options) {
42
48
  }
@@ -50,6 +56,7 @@ var AISpanType = /* @__PURE__ */ ((AISpanType2) => {
50
56
  AISpanType2["AGENT_RUN"] = "agent_run";
51
57
  AISpanType2["GENERIC"] = "generic";
52
58
  AISpanType2["LLM_GENERATION"] = "llm_generation";
59
+ AISpanType2["LLM_CHUNK"] = "llm_chunk";
53
60
  AISpanType2["MCP_TOOL_CALL"] = "mcp_tool_call";
54
61
  AISpanType2["TOOL_CALL"] = "tool_call";
55
62
  AISpanType2["WORKFLOW_RUN"] = "workflow_run";
@@ -114,22 +121,31 @@ var MastraAITracing = class extends MastraBase {
114
121
  * Start a new span of a specific AISpanType
115
122
  */
116
123
  startSpan(options) {
117
- const { type, name, input, attributes, metadata, parent, startOptions } = options;
124
+ const { type, name, input, output, attributes, metadata, parent, startOptions, isEvent } = options;
118
125
  const { runtimeContext } = startOptions || {};
119
126
  if (!this.shouldSample({ runtimeContext })) {
120
- return new NoOpAISpan({ type, name, input, attributes, metadata, parent }, this);
127
+ return new NoOpAISpan(
128
+ { type, name, input, output, attributes, metadata, parent, isEvent: isEvent === true },
129
+ this
130
+ );
121
131
  }
122
132
  const spanOptions = {
123
133
  type,
124
134
  name,
125
135
  input,
136
+ output,
126
137
  attributes,
127
138
  metadata,
128
- parent
139
+ parent,
140
+ isEvent: isEvent === true
129
141
  };
130
142
  const span = this.createSpan(spanOptions);
131
- this.wireSpanLifecycle(span);
132
- this.emitSpanStarted(span);
143
+ if (span.isEvent) {
144
+ this.emitSpanEnded(span);
145
+ } else {
146
+ this.wireSpanLifecycle(span);
147
+ this.emitSpanStarted(span);
148
+ }
133
149
  return span;
134
150
  }
135
151
  // ============================================================================
@@ -283,7 +299,7 @@ var MastraAITracing = class extends MastraBase {
283
299
  /**
284
300
  * Initialize AI tracing (called by Mastra during component registration)
285
301
  */
286
- async init() {
302
+ init() {
287
303
  this.logger.debug(`[AI Tracing] Initialization started [name=${this.name}]`);
288
304
  this.logger.info(`[AI Tracing] Initialized successfully [name=${this.name}]`);
289
305
  }
@@ -298,6 +314,592 @@ var MastraAITracing = class extends MastraBase {
298
314
  }
299
315
  };
300
316
 
317
+ // src/ai-tracing/exporters/console.ts
318
+ var ConsoleExporter = class {
319
+ name = "tracing-console-exporter";
320
+ logger;
321
+ constructor(logger) {
322
+ if (logger) {
323
+ this.logger = logger;
324
+ } else {
325
+ this.logger = new ConsoleLogger({ level: LogLevel.INFO });
326
+ }
327
+ }
328
+ async exportEvent(event) {
329
+ const span = event.span;
330
+ const formatAttributes = (attributes) => {
331
+ try {
332
+ return JSON.stringify(attributes, null, 2);
333
+ } catch (error) {
334
+ const errMsg = error instanceof Error ? error.message : "Unknown formatting error";
335
+ return `[Unable to serialize attributes: ${errMsg}]`;
336
+ }
337
+ };
338
+ const formatDuration = (startTime, endTime) => {
339
+ if (!endTime) return "N/A";
340
+ const duration = endTime.getTime() - startTime.getTime();
341
+ return `${duration}ms`;
342
+ };
343
+ switch (event.type) {
344
+ case "span_started" /* SPAN_STARTED */:
345
+ this.logger.info(`\u{1F680} SPAN_STARTED`);
346
+ this.logger.info(` Type: ${span.type}`);
347
+ this.logger.info(` Name: ${span.name}`);
348
+ this.logger.info(` ID: ${span.id}`);
349
+ this.logger.info(` Trace ID: ${span.traceId}`);
350
+ if (span.input !== void 0) {
351
+ this.logger.info(` Input: ${formatAttributes(span.input)}`);
352
+ }
353
+ this.logger.info(` Attributes: ${formatAttributes(span.attributes)}`);
354
+ this.logger.info("\u2500".repeat(80));
355
+ break;
356
+ case "span_ended" /* SPAN_ENDED */:
357
+ const duration = formatDuration(span.startTime, span.endTime);
358
+ this.logger.info(`\u2705 SPAN_ENDED`);
359
+ this.logger.info(` Type: ${span.type}`);
360
+ this.logger.info(` Name: ${span.name}`);
361
+ this.logger.info(` ID: ${span.id}`);
362
+ this.logger.info(` Duration: ${duration}`);
363
+ this.logger.info(` Trace ID: ${span.traceId}`);
364
+ if (span.input !== void 0) {
365
+ this.logger.info(` Input: ${formatAttributes(span.input)}`);
366
+ }
367
+ if (span.output !== void 0) {
368
+ this.logger.info(` Output: ${formatAttributes(span.output)}`);
369
+ }
370
+ if (span.errorInfo) {
371
+ this.logger.info(` Error: ${formatAttributes(span.errorInfo)}`);
372
+ }
373
+ this.logger.info(` Attributes: ${formatAttributes(span.attributes)}`);
374
+ this.logger.info("\u2500".repeat(80));
375
+ break;
376
+ case "span_updated" /* SPAN_UPDATED */:
377
+ this.logger.info(`\u{1F4DD} SPAN_UPDATED`);
378
+ this.logger.info(` Type: ${span.type}`);
379
+ this.logger.info(` Name: ${span.name}`);
380
+ this.logger.info(` ID: ${span.id}`);
381
+ this.logger.info(` Trace ID: ${span.traceId}`);
382
+ if (span.input !== void 0) {
383
+ this.logger.info(` Input: ${formatAttributes(span.input)}`);
384
+ }
385
+ if (span.output !== void 0) {
386
+ this.logger.info(` Output: ${formatAttributes(span.output)}`);
387
+ }
388
+ if (span.errorInfo) {
389
+ this.logger.info(` Error: ${formatAttributes(span.errorInfo)}`);
390
+ }
391
+ this.logger.info(` Updated Attributes: ${formatAttributes(span.attributes)}`);
392
+ this.logger.info("\u2500".repeat(80));
393
+ break;
394
+ default:
395
+ this.logger.warn(`Tracing event type not implemented: ${event.type}`);
396
+ }
397
+ }
398
+ async shutdown() {
399
+ this.logger.info("ConsoleExporter shutdown");
400
+ }
401
+ };
402
+
403
+ // src/ai-tracing/exporters/default.ts
404
+ function resolveStrategy(userConfig, storage, logger) {
405
+ if (userConfig.strategy && userConfig.strategy !== "auto") {
406
+ const hints = storage.aiTracingStrategy;
407
+ if (hints.supported.includes(userConfig.strategy)) {
408
+ return userConfig.strategy;
409
+ }
410
+ logger.warn("User-specified AI tracing strategy not supported by storage adapter, falling back to auto-selection", {
411
+ userStrategy: userConfig.strategy,
412
+ storageAdapter: storage.constructor.name,
413
+ supportedStrategies: hints.supported,
414
+ fallbackStrategy: hints.preferred
415
+ });
416
+ }
417
+ return storage.aiTracingStrategy.preferred;
418
+ }
419
+ var DefaultExporter = class {
420
+ name = "tracing-default-exporter";
421
+ logger;
422
+ mastra = null;
423
+ config;
424
+ resolvedStrategy;
425
+ buffer;
426
+ flushTimer = null;
427
+ constructor(config = {}, logger) {
428
+ if (logger) {
429
+ this.logger = logger;
430
+ } else {
431
+ this.logger = new ConsoleLogger({ level: LogLevel.INFO });
432
+ }
433
+ this.config = {
434
+ maxBatchSize: config.maxBatchSize ?? 1e3,
435
+ maxBufferSize: config.maxBufferSize ?? 1e4,
436
+ maxBatchWaitMs: config.maxBatchWaitMs ?? 5e3,
437
+ maxRetries: config.maxRetries ?? 4,
438
+ retryDelayMs: config.retryDelayMs ?? 500,
439
+ strategy: config.strategy ?? "auto"
440
+ };
441
+ this.buffer = {
442
+ creates: [],
443
+ updates: [],
444
+ insertOnly: [],
445
+ seenSpans: /* @__PURE__ */ new Set(),
446
+ spanSequences: /* @__PURE__ */ new Map(),
447
+ outOfOrderCount: 0,
448
+ totalSize: 0
449
+ };
450
+ this.resolvedStrategy = "batch-with-updates";
451
+ }
452
+ strategyInitialized = false;
453
+ /**
454
+ * Register the Mastra instance (called after Mastra construction is complete)
455
+ */
456
+ __registerMastra(mastra) {
457
+ this.mastra = mastra;
458
+ }
459
+ /**
460
+ * Initialize the exporter (called after all dependencies are ready)
461
+ */
462
+ init() {
463
+ if (!this.mastra) {
464
+ throw new Error("DefaultExporter: init() called before __registerMastra()");
465
+ }
466
+ const storage = this.mastra.getStorage();
467
+ if (!storage) {
468
+ throw new Error("DefaultExporter: Storage not available during initialization");
469
+ }
470
+ this.initializeStrategy(storage);
471
+ }
472
+ /**
473
+ * Initialize the resolved strategy once storage is available
474
+ */
475
+ initializeStrategy(storage) {
476
+ if (this.strategyInitialized) return;
477
+ this.resolvedStrategy = resolveStrategy(this.config, storage, this.logger);
478
+ this.strategyInitialized = true;
479
+ this.logger.info("AI tracing exporter initialized", {
480
+ strategy: this.resolvedStrategy,
481
+ source: this.config.strategy !== "auto" ? "user" : "auto",
482
+ storageAdapter: storage.constructor.name,
483
+ maxBatchSize: this.config.maxBatchSize,
484
+ maxBatchWaitMs: this.config.maxBatchWaitMs
485
+ });
486
+ }
487
+ /**
488
+ * Builds a unique span key for tracking
489
+ */
490
+ buildSpanKey(traceId, spanId) {
491
+ return `${traceId}:${spanId}`;
492
+ }
493
+ /**
494
+ * Gets the next sequence number for a span
495
+ */
496
+ getNextSequence(spanKey) {
497
+ const current = this.buffer.spanSequences.get(spanKey) || 0;
498
+ const next = current + 1;
499
+ this.buffer.spanSequences.set(spanKey, next);
500
+ return next;
501
+ }
502
+ /**
503
+ * Handles out-of-order span updates by logging and skipping
504
+ */
505
+ handleOutOfOrderUpdate(event) {
506
+ this.logger.warn("Out-of-order span update detected - skipping event", {
507
+ spanId: event.span.id,
508
+ traceId: event.span.traceId,
509
+ eventType: event.type
510
+ });
511
+ }
512
+ /**
513
+ * Adds an event to the appropriate buffer based on strategy
514
+ */
515
+ addToBuffer(event) {
516
+ const spanKey = this.buildSpanKey(event.span.traceId, event.span.id);
517
+ if (this.buffer.totalSize === 0) {
518
+ this.buffer.firstEventTime = /* @__PURE__ */ new Date();
519
+ }
520
+ switch (event.type) {
521
+ case "span_started" /* SPAN_STARTED */:
522
+ if (this.resolvedStrategy === "batch-with-updates") {
523
+ const createRecord = {
524
+ traceId: event.span.traceId,
525
+ spanId: event.span.id,
526
+ ...this.buildCreateRecord(event.span),
527
+ createdAt: /* @__PURE__ */ new Date(),
528
+ updatedAt: null
529
+ };
530
+ this.buffer.creates.push(createRecord);
531
+ this.buffer.seenSpans.add(spanKey);
532
+ }
533
+ break;
534
+ case "span_updated" /* SPAN_UPDATED */:
535
+ if (this.resolvedStrategy === "batch-with-updates") {
536
+ if (this.buffer.seenSpans.has(spanKey)) {
537
+ this.buffer.updates.push({
538
+ traceId: event.span.traceId,
539
+ spanId: event.span.id,
540
+ updates: {
541
+ ...this.buildUpdateRecord(event.span),
542
+ updatedAt: /* @__PURE__ */ new Date()
543
+ },
544
+ sequenceNumber: this.getNextSequence(spanKey)
545
+ });
546
+ } else {
547
+ this.handleOutOfOrderUpdate(event);
548
+ this.buffer.outOfOrderCount++;
549
+ }
550
+ }
551
+ break;
552
+ case "span_ended" /* SPAN_ENDED */:
553
+ if (this.resolvedStrategy === "batch-with-updates") {
554
+ if (this.buffer.seenSpans.has(spanKey)) {
555
+ this.buffer.updates.push({
556
+ traceId: event.span.traceId,
557
+ spanId: event.span.id,
558
+ updates: {
559
+ ...this.buildUpdateRecord(event.span),
560
+ updatedAt: /* @__PURE__ */ new Date()
561
+ },
562
+ sequenceNumber: this.getNextSequence(spanKey)
563
+ });
564
+ } else {
565
+ this.handleOutOfOrderUpdate(event);
566
+ this.buffer.outOfOrderCount++;
567
+ }
568
+ } else if (this.resolvedStrategy === "insert-only") {
569
+ const createRecord = {
570
+ traceId: event.span.traceId,
571
+ spanId: event.span.id,
572
+ ...this.buildCreateRecord(event.span),
573
+ createdAt: /* @__PURE__ */ new Date(),
574
+ updatedAt: null
575
+ };
576
+ this.buffer.insertOnly.push(createRecord);
577
+ }
578
+ break;
579
+ }
580
+ this.buffer.totalSize = this.buffer.creates.length + this.buffer.updates.length + this.buffer.insertOnly.length;
581
+ }
582
+ /**
583
+ * Checks if buffer should be flushed based on size or time triggers
584
+ */
585
+ shouldFlush() {
586
+ if (this.buffer.totalSize >= this.config.maxBufferSize) {
587
+ return true;
588
+ }
589
+ if (this.buffer.totalSize >= this.config.maxBatchSize) {
590
+ return true;
591
+ }
592
+ if (this.buffer.firstEventTime && this.buffer.totalSize > 0) {
593
+ const elapsed = Date.now() - this.buffer.firstEventTime.getTime();
594
+ if (elapsed >= this.config.maxBatchWaitMs) {
595
+ return true;
596
+ }
597
+ }
598
+ return false;
599
+ }
600
+ /**
601
+ * Resets the buffer after successful flush
602
+ */
603
+ resetBuffer() {
604
+ this.buffer.creates = [];
605
+ this.buffer.updates = [];
606
+ this.buffer.insertOnly = [];
607
+ this.buffer.seenSpans.clear();
608
+ this.buffer.spanSequences.clear();
609
+ this.buffer.outOfOrderCount = 0;
610
+ this.buffer.firstEventTime = void 0;
611
+ this.buffer.totalSize = 0;
612
+ }
613
+ /**
614
+ * Schedules a flush using setTimeout
615
+ */
616
+ scheduleFlush() {
617
+ if (this.flushTimer) {
618
+ clearTimeout(this.flushTimer);
619
+ }
620
+ this.flushTimer = setTimeout(() => {
621
+ this.flush().catch((error) => {
622
+ this.logger.error("Scheduled flush failed", {
623
+ error: error instanceof Error ? error.message : String(error)
624
+ });
625
+ });
626
+ }, this.config.maxBatchWaitMs);
627
+ }
628
+ /**
629
+ * Serializes span attributes to storage record format
630
+ * Handles all AI span types and their specific attributes
631
+ */
632
+ serializeAttributes(span) {
633
+ if (!span.attributes) {
634
+ return null;
635
+ }
636
+ try {
637
+ return JSON.parse(
638
+ JSON.stringify(span.attributes, (_key, value) => {
639
+ if (value instanceof Date) {
640
+ return value.toISOString();
641
+ }
642
+ if (typeof value === "object" && value !== null) {
643
+ return value;
644
+ }
645
+ return value;
646
+ })
647
+ );
648
+ } catch (error) {
649
+ this.logger.warn("Failed to serialize span attributes, storing as null", {
650
+ spanId: span.id,
651
+ spanType: span.type,
652
+ error: error instanceof Error ? error.message : String(error)
653
+ });
654
+ return null;
655
+ }
656
+ }
657
+ buildCreateRecord(span) {
658
+ return {
659
+ parentSpanId: span.parent?.id ?? null,
660
+ name: span.name,
661
+ scope: null,
662
+ spanType: span.type,
663
+ attributes: this.serializeAttributes(span),
664
+ metadata: span.metadata ?? null,
665
+ links: null,
666
+ startedAt: span.startTime,
667
+ endedAt: span.endTime ?? null,
668
+ input: span.input,
669
+ output: span.output,
670
+ error: span.errorInfo,
671
+ isEvent: span.isEvent
672
+ };
673
+ }
674
+ buildUpdateRecord(span) {
675
+ return {
676
+ name: span.name,
677
+ scope: null,
678
+ attributes: this.serializeAttributes(span),
679
+ metadata: span.metadata ?? null,
680
+ links: null,
681
+ endedAt: span.endTime ?? null,
682
+ input: span.input,
683
+ output: span.output,
684
+ error: span.errorInfo
685
+ };
686
+ }
687
+ /**
688
+ * Handles realtime strategy - processes each event immediately
689
+ */
690
+ async handleRealtimeEvent(event, storage) {
691
+ const span = event.span;
692
+ if (span.isEvent) {
693
+ if (event.type === "span_ended" /* SPAN_ENDED */) {
694
+ await storage.createAISpan({
695
+ traceId: span.traceId,
696
+ spanId: span.id,
697
+ ...this.buildCreateRecord(span),
698
+ createdAt: /* @__PURE__ */ new Date(),
699
+ updatedAt: null
700
+ });
701
+ } else {
702
+ this.logger.warn(`Tracing event type not implemented for event spans: ${event.type}`);
703
+ }
704
+ } else {
705
+ switch (event.type) {
706
+ case "span_started" /* SPAN_STARTED */:
707
+ await storage.createAISpan({
708
+ traceId: span.traceId,
709
+ spanId: span.id,
710
+ ...this.buildCreateRecord(span),
711
+ createdAt: /* @__PURE__ */ new Date(),
712
+ updatedAt: null
713
+ });
714
+ break;
715
+ case "span_updated" /* SPAN_UPDATED */:
716
+ case "span_ended" /* SPAN_ENDED */:
717
+ await storage.updateAISpan({
718
+ traceId: span.traceId,
719
+ spanId: span.id,
720
+ updates: {
721
+ ...this.buildUpdateRecord(span),
722
+ updatedAt: /* @__PURE__ */ new Date()
723
+ }
724
+ });
725
+ break;
726
+ default:
727
+ this.logger.warn(`Tracing event type not implemented for span spans: ${event.type}`);
728
+ }
729
+ }
730
+ }
731
+ /**
732
+ * Handles batch-with-updates strategy - buffers events and processes in batches
733
+ */
734
+ handleBatchWithUpdatesEvent(event) {
735
+ this.addToBuffer(event);
736
+ if (this.shouldFlush()) {
737
+ this.flush().catch((error) => {
738
+ this.logger.error("Batch flush failed", {
739
+ error: error instanceof Error ? error.message : String(error)
740
+ });
741
+ });
742
+ } else if (this.buffer.totalSize === 1) {
743
+ this.scheduleFlush();
744
+ }
745
+ }
746
+ /**
747
+ * Handles insert-only strategy - only processes SPAN_ENDED events in batches
748
+ */
749
+ handleInsertOnlyEvent(event) {
750
+ if (event.type === "span_ended" /* SPAN_ENDED */) {
751
+ this.addToBuffer(event);
752
+ if (this.shouldFlush()) {
753
+ this.flush().catch((error) => {
754
+ this.logger.error("Batch flush failed", {
755
+ error: error instanceof Error ? error.message : String(error)
756
+ });
757
+ });
758
+ } else if (this.buffer.totalSize === 1) {
759
+ this.scheduleFlush();
760
+ }
761
+ }
762
+ }
763
+ /**
764
+ * Calculates retry delay using exponential backoff
765
+ */
766
+ calculateRetryDelay(attempt) {
767
+ return this.config.retryDelayMs * Math.pow(2, attempt);
768
+ }
769
+ /**
770
+ * Flushes the current buffer to storage with retry logic
771
+ */
772
+ async flush() {
773
+ if (!this.mastra) {
774
+ this.logger.warn("Cannot flush traces. Mastra instance not registered yet.");
775
+ return;
776
+ }
777
+ const storage = this.mastra.getStorage();
778
+ if (!storage) {
779
+ this.logger.warn("Cannot flush traces. Mastra storage is not initialized");
780
+ return;
781
+ }
782
+ if (this.flushTimer) {
783
+ clearTimeout(this.flushTimer);
784
+ this.flushTimer = null;
785
+ }
786
+ if (this.buffer.totalSize === 0) {
787
+ return;
788
+ }
789
+ const startTime = Date.now();
790
+ const flushReason = this.buffer.totalSize >= this.config.maxBufferSize ? "overflow" : this.buffer.totalSize >= this.config.maxBatchSize ? "size" : "time";
791
+ const bufferCopy = {
792
+ creates: [...this.buffer.creates],
793
+ updates: [...this.buffer.updates],
794
+ insertOnly: [...this.buffer.insertOnly],
795
+ seenSpans: new Set(this.buffer.seenSpans),
796
+ spanSequences: new Map(this.buffer.spanSequences),
797
+ outOfOrderCount: this.buffer.outOfOrderCount,
798
+ firstEventTime: this.buffer.firstEventTime,
799
+ totalSize: this.buffer.totalSize
800
+ };
801
+ this.resetBuffer();
802
+ await this.flushWithRetries(storage, bufferCopy, 0);
803
+ const elapsed = Date.now() - startTime;
804
+ this.logger.debug("Batch flushed", {
805
+ strategy: this.resolvedStrategy,
806
+ batchSize: bufferCopy.totalSize,
807
+ flushReason,
808
+ durationMs: elapsed,
809
+ outOfOrderCount: bufferCopy.outOfOrderCount > 0 ? bufferCopy.outOfOrderCount : void 0
810
+ });
811
+ }
812
+ /**
813
+ * Attempts to flush with exponential backoff retry logic
814
+ */
815
+ async flushWithRetries(storage, buffer, attempt) {
816
+ try {
817
+ if (this.resolvedStrategy === "batch-with-updates") {
818
+ if (buffer.creates.length > 0) {
819
+ await storage.batchCreateAISpans({ records: buffer.creates });
820
+ }
821
+ if (buffer.updates.length > 0) {
822
+ const sortedUpdates = buffer.updates.sort((a, b) => {
823
+ const spanCompare = this.buildSpanKey(a.traceId, a.spanId).localeCompare(
824
+ this.buildSpanKey(b.traceId, b.spanId)
825
+ );
826
+ if (spanCompare !== 0) return spanCompare;
827
+ return a.sequenceNumber - b.sequenceNumber;
828
+ });
829
+ await storage.batchUpdateAISpans({ records: sortedUpdates });
830
+ }
831
+ } else if (this.resolvedStrategy === "insert-only") {
832
+ if (buffer.insertOnly.length > 0) {
833
+ await storage.batchCreateAISpans({ records: buffer.insertOnly });
834
+ }
835
+ }
836
+ } catch (error) {
837
+ if (attempt < this.config.maxRetries) {
838
+ const retryDelay = this.calculateRetryDelay(attempt);
839
+ this.logger.warn("Batch flush failed, retrying", {
840
+ attempt: attempt + 1,
841
+ maxRetries: this.config.maxRetries,
842
+ nextRetryInMs: retryDelay,
843
+ error: error instanceof Error ? error.message : String(error)
844
+ });
845
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
846
+ return this.flushWithRetries(storage, buffer, attempt + 1);
847
+ } else {
848
+ this.logger.error("Batch flush failed after all retries, dropping batch", {
849
+ finalAttempt: attempt + 1,
850
+ maxRetries: this.config.maxRetries,
851
+ droppedBatchSize: buffer.totalSize,
852
+ error: error instanceof Error ? error.message : String(error)
853
+ });
854
+ }
855
+ }
856
+ }
857
+ async exportEvent(event) {
858
+ if (!this.mastra) {
859
+ this.logger.warn("Cannot export AI tracing event. Mastra instance not registered yet.");
860
+ return;
861
+ }
862
+ const storage = this.mastra.getStorage();
863
+ if (!storage) {
864
+ this.logger.warn("Cannot store traces. Mastra storage is not initialized");
865
+ return;
866
+ }
867
+ if (!this.strategyInitialized) {
868
+ this.initializeStrategy(storage);
869
+ }
870
+ switch (this.resolvedStrategy) {
871
+ case "realtime":
872
+ await this.handleRealtimeEvent(event, storage);
873
+ break;
874
+ case "batch-with-updates":
875
+ this.handleBatchWithUpdatesEvent(event);
876
+ break;
877
+ case "insert-only":
878
+ this.handleInsertOnlyEvent(event);
879
+ break;
880
+ }
881
+ }
882
+ async shutdown() {
883
+ if (this.flushTimer) {
884
+ clearTimeout(this.flushTimer);
885
+ this.flushTimer = null;
886
+ }
887
+ if (this.buffer.totalSize > 0) {
888
+ this.logger.info("Flushing remaining events on shutdown", {
889
+ remainingEvents: this.buffer.totalSize
890
+ });
891
+ try {
892
+ await this.flush();
893
+ } catch (error) {
894
+ this.logger.error("Failed to flush remaining events during shutdown", {
895
+ error: error instanceof Error ? error.message : String(error)
896
+ });
897
+ }
898
+ }
899
+ this.logger.info("DefaultExporter shutdown complete");
900
+ }
901
+ };
902
+
301
903
  // src/ai-tracing/default.ts
302
904
  function generateSpanId() {
303
905
  const bytes = new Uint8Array(8);
@@ -331,11 +933,13 @@ var DefaultAISpan = class {
331
933
  traceId;
332
934
  startTime;
333
935
  endTime;
936
+ isEvent;
334
937
  aiTracing;
335
938
  input;
336
939
  output;
337
940
  errorInfo;
338
941
  metadata;
942
+ logger;
339
943
  constructor(options, aiTracing) {
340
944
  this.id = generateSpanId();
341
945
  this.name = options.name;
@@ -347,13 +951,26 @@ var DefaultAISpan = class {
347
951
  this.startTime = /* @__PURE__ */ new Date();
348
952
  this.aiTracing = aiTracing;
349
953
  this.input = options.input;
954
+ this.isEvent = options.isEvent;
955
+ this.logger = new ConsoleLogger({
956
+ name: "default-ai-span",
957
+ level: LogLevel.INFO
958
+ // Set to INFO so that info() calls actually log
959
+ });
350
960
  if (!options.parent) {
351
961
  this.traceId = generateTraceId();
352
962
  } else {
353
963
  this.traceId = options.parent.trace.traceId;
354
964
  }
965
+ if (this.isEvent) {
966
+ this.output = options.output;
967
+ }
355
968
  }
356
969
  end(options) {
970
+ if (this.isEvent) {
971
+ this.logger.warn(`End event is not available on event spans`);
972
+ return;
973
+ }
357
974
  this.endTime = /* @__PURE__ */ new Date();
358
975
  if (options?.output !== void 0) {
359
976
  this.output = options.output;
@@ -366,6 +983,10 @@ var DefaultAISpan = class {
366
983
  }
367
984
  }
368
985
  error(options) {
986
+ if (this.isEvent) {
987
+ this.logger.warn(`Error event is not available on event spans`);
988
+ return;
989
+ }
369
990
  const { error, endSpan = true, attributes, metadata } = options;
370
991
  this.errorInfo = error instanceof MastraError ? {
371
992
  id: error.id,
@@ -391,10 +1012,22 @@ var DefaultAISpan = class {
391
1012
  createChildSpan(options) {
392
1013
  return this.aiTracing.startSpan({
393
1014
  ...options,
394
- parent: this
1015
+ parent: this,
1016
+ isEvent: false
1017
+ });
1018
+ }
1019
+ createEventSpan(options) {
1020
+ return this.aiTracing.startSpan({
1021
+ ...options,
1022
+ parent: this,
1023
+ isEvent: true
395
1024
  });
396
1025
  }
397
1026
  update(options) {
1027
+ if (this.isEvent) {
1028
+ this.logger.warn(`Update() is not available on event spans`);
1029
+ return;
1030
+ }
398
1031
  if (options?.input !== void 0) {
399
1032
  this.input = options.input;
400
1033
  }
@@ -487,100 +1120,11 @@ var SensitiveDataFilter = class {
487
1120
  async shutdown() {
488
1121
  }
489
1122
  };
490
- var DefaultConsoleExporter = class {
491
- name = "default-console";
492
- logger;
493
- constructor(logger) {
494
- if (logger) {
495
- this.logger = logger;
496
- } else {
497
- this.logger = new ConsoleLogger({
498
- name: "default-console-exporter",
499
- level: LogLevel.INFO
500
- // Set to INFO so that info() calls actually log
501
- });
502
- }
503
- }
504
- async exportEvent(event) {
505
- const span = event.span;
506
- const formatAttributes = (attributes) => {
507
- try {
508
- return JSON.stringify(attributes, null, 2);
509
- } catch (error) {
510
- const errMsg = error instanceof Error ? error.message : "Unknown formatting error";
511
- return `[Unable to serialize attributes: ${errMsg}]`;
512
- }
513
- };
514
- const formatDuration = (startTime, endTime) => {
515
- if (!endTime) return "N/A";
516
- const duration = endTime.getTime() - startTime.getTime();
517
- return `${duration}ms`;
518
- };
519
- switch (event.type) {
520
- case "span_started" /* SPAN_STARTED */:
521
- this.logger.info(`\u{1F680} SPAN_STARTED`);
522
- this.logger.info(` Type: ${span.type}`);
523
- this.logger.info(` Name: ${span.name}`);
524
- this.logger.info(` ID: ${span.id}`);
525
- this.logger.info(` Trace ID: ${span.traceId}`);
526
- if (span.input !== void 0) {
527
- this.logger.info(` Input: ${formatAttributes(span.input)}`);
528
- }
529
- this.logger.info(` Attributes: ${formatAttributes(span.attributes)}`);
530
- this.logger.info("\u2500".repeat(80));
531
- break;
532
- case "span_ended" /* SPAN_ENDED */:
533
- const duration = formatDuration(span.startTime, span.endTime);
534
- this.logger.info(`\u2705 SPAN_ENDED`);
535
- this.logger.info(` Type: ${span.type}`);
536
- this.logger.info(` Name: ${span.name}`);
537
- this.logger.info(` ID: ${span.id}`);
538
- this.logger.info(` Duration: ${duration}`);
539
- this.logger.info(` Trace ID: ${span.traceId}`);
540
- if (span.input !== void 0) {
541
- this.logger.info(` Input: ${formatAttributes(span.input)}`);
542
- }
543
- if (span.output !== void 0) {
544
- this.logger.info(` Output: ${formatAttributes(span.output)}`);
545
- }
546
- if (span.errorInfo) {
547
- this.logger.info(` Error: ${formatAttributes(span.errorInfo)}`);
548
- }
549
- this.logger.info(` Attributes: ${formatAttributes(span.attributes)}`);
550
- this.logger.info("\u2500".repeat(80));
551
- break;
552
- case "span_updated" /* SPAN_UPDATED */:
553
- this.logger.info(`\u{1F4DD} SPAN_UPDATED`);
554
- this.logger.info(` Type: ${span.type}`);
555
- this.logger.info(` Name: ${span.name}`);
556
- this.logger.info(` ID: ${span.id}`);
557
- this.logger.info(` Trace ID: ${span.traceId}`);
558
- if (span.input !== void 0) {
559
- this.logger.info(` Input: ${formatAttributes(span.input)}`);
560
- }
561
- if (span.output !== void 0) {
562
- this.logger.info(` Output: ${formatAttributes(span.output)}`);
563
- }
564
- if (span.errorInfo) {
565
- this.logger.info(` Error: ${formatAttributes(span.errorInfo)}`);
566
- }
567
- this.logger.info(` Updated Attributes: ${formatAttributes(span.attributes)}`);
568
- this.logger.info("\u2500".repeat(80));
569
- break;
570
- default:
571
- throw new Error(`Tracing event type not implemented: ${event.type}`);
572
- }
573
- }
574
- async shutdown() {
575
- this.logger.info("DefaultConsoleExporter shutdown");
576
- }
577
- };
578
1123
  var aiTracingDefaultConfig = {
579
1124
  serviceName: "mastra-ai-service",
580
1125
  instanceName: "default",
581
1126
  sampling: { type: "always" /* ALWAYS */ },
582
- exporters: [new DefaultConsoleExporter()],
583
- // Uses its own fallback logger
1127
+ exporters: [new ConsoleExporter()],
584
1128
  processors: [new SensitiveDataFilter()]
585
1129
  };
586
1130
  var DefaultAITracing = class extends MastraAITracing {
@@ -841,6 +1385,6 @@ function wrapWorkflow(workflow, tracingContext) {
841
1385
  }
842
1386
  }
843
1387
 
844
- export { AISpanType, AITracingEventType, DefaultAITracing, DefaultConsoleExporter, MastraAITracing, SamplingStrategyType, SensitiveDataFilter, aiTracingDefaultConfig, clearAITracingRegistry, getAITracing, getAllAITracing, getDefaultAITracing, getSelectedAITracing, hasAITracing, isSerializable, omitKeys, registerAITracing, sanitizeMetadata, setAITracingSelector, setupAITracing, shutdownAITracingRegistry, unregisterAITracing, wrapAgent, wrapMastra, wrapWorkflow };
845
- //# sourceMappingURL=chunk-7TH2KSEC.js.map
846
- //# sourceMappingURL=chunk-7TH2KSEC.js.map
1388
+ export { AISpanType, AITracingEventType, ConsoleExporter, DefaultAITracing, DefaultExporter, MastraAITracing, SamplingStrategyType, SensitiveDataFilter, aiTracingDefaultConfig, clearAITracingRegistry, getAITracing, getAllAITracing, getDefaultAITracing, getSelectedAITracing, hasAITracing, isSerializable, omitKeys, registerAITracing, sanitizeMetadata, setAITracingSelector, setupAITracing, shutdownAITracingRegistry, unregisterAITracing, wrapAgent, wrapMastra, wrapWorkflow };
1389
+ //# sourceMappingURL=chunk-WOTBMZCN.js.map
1390
+ //# sourceMappingURL=chunk-WOTBMZCN.js.map