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