@mastra/core 0.15.2 → 0.15.3-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/agent.types.d.ts +2 -0
- package/dist/agent/agent.types.d.ts.map +1 -1
- package/dist/agent/index.cjs +8 -8
- package/dist/agent/index.d.ts +0 -2
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/input-processor/index.cjs +6 -6
- package/dist/agent/input-processor/index.js +1 -1
- package/dist/ai-tracing/base.d.ts +3 -1
- package/dist/ai-tracing/base.d.ts.map +1 -1
- package/dist/ai-tracing/default.d.ts +1 -9
- package/dist/ai-tracing/default.d.ts.map +1 -1
- package/dist/ai-tracing/exporters/console.d.ts +10 -0
- package/dist/ai-tracing/exporters/console.d.ts.map +1 -0
- package/dist/ai-tracing/exporters/default.d.ts +97 -0
- package/dist/ai-tracing/exporters/default.d.ts.map +1 -0
- package/dist/ai-tracing/exporters/index.d.ts +6 -0
- package/dist/ai-tracing/exporters/index.d.ts.map +1 -0
- package/dist/ai-tracing/index.cjs +31 -27
- package/dist/ai-tracing/index.d.ts +1 -0
- package/dist/ai-tracing/index.d.ts.map +1 -1
- package/dist/ai-tracing/index.js +1 -1
- package/dist/ai-tracing/no-op.d.ts +8 -0
- package/dist/ai-tracing/no-op.d.ts.map +1 -1
- package/dist/ai-tracing/types.d.ts +33 -0
- package/dist/ai-tracing/types.d.ts.map +1 -1
- package/dist/{chunk-EQLCC3M7.cjs → chunk-4DKPMUAC.cjs} +646 -101
- package/dist/chunk-4DKPMUAC.cjs.map +1 -0
- package/dist/{chunk-QLRALF4I.js → chunk-5MCNXLGT.js} +6 -4
- package/dist/chunk-5MCNXLGT.js.map +1 -0
- package/dist/{chunk-RMEG4MOG.cjs → chunk-6VROHRAR.cjs} +45 -30
- package/dist/chunk-6VROHRAR.cjs.map +1 -0
- package/dist/{chunk-SNYSVGIU.cjs → chunk-6Z7D7CA3.cjs} +144 -113
- package/dist/chunk-6Z7D7CA3.cjs.map +1 -0
- package/dist/{chunk-HRPTZGDT.js → chunk-BRNBKCHE.js} +4 -4
- package/dist/chunk-BRNBKCHE.js.map +1 -0
- package/dist/{chunk-DAJYN7HG.cjs → chunk-CDLIHAX2.cjs} +4 -4
- package/dist/{chunk-DAJYN7HG.cjs.map → chunk-CDLIHAX2.cjs.map} +1 -1
- package/dist/{chunk-VKJWTAHZ.js → chunk-E3LAPNKY.js} +3 -3
- package/dist/{chunk-VKJWTAHZ.js.map → chunk-E3LAPNKY.js.map} +1 -1
- package/dist/{chunk-FCFQE5BD.js → chunk-FGCA6CCM.js} +130 -99
- package/dist/chunk-FGCA6CCM.js.map +1 -0
- package/dist/{chunk-FFGJPMKP.js → chunk-FLXWZUIG.js} +45 -30
- package/dist/chunk-FLXWZUIG.js.map +1 -0
- package/dist/{chunk-GVMFAUQR.cjs → chunk-GEPX327P.cjs} +12 -2
- package/dist/chunk-GEPX327P.cjs.map +1 -0
- package/dist/{chunk-DPE6K23N.cjs → chunk-HRDADYVX.cjs} +47 -8
- package/dist/chunk-HRDADYVX.cjs.map +1 -0
- package/dist/{chunk-UKQI74TN.cjs → chunk-K6UMYGK5.cjs} +17 -2
- package/dist/chunk-K6UMYGK5.cjs.map +1 -0
- package/dist/{chunk-XJFIB2FO.js → chunk-MKWJKRSX.js} +3 -3
- package/dist/{chunk-XJFIB2FO.js.map → chunk-MKWJKRSX.js.map} +1 -1
- package/dist/{chunk-7EXGDKNQ.cjs → chunk-QBNRMJAN.cjs} +4 -4
- package/dist/{chunk-7EXGDKNQ.cjs.map → chunk-QBNRMJAN.cjs.map} +1 -1
- package/dist/{chunk-6NYFECSO.js → chunk-TINMY4WA.js} +43 -4
- package/dist/chunk-TINMY4WA.js.map +1 -0
- package/dist/{chunk-G6WYC4SF.cjs → chunk-VBAWR62U.cjs} +7 -7
- package/dist/chunk-VBAWR62U.cjs.map +1 -0
- package/dist/{chunk-7TH2KSEC.js → chunk-WOTBMZCN.js} +645 -101
- package/dist/chunk-WOTBMZCN.js.map +1 -0
- package/dist/{chunk-ASRKKIW7.cjs → chunk-XEY3CWQW.cjs} +10 -8
- package/dist/chunk-XEY3CWQW.cjs.map +1 -0
- package/dist/{chunk-Y44DK4T5.js → chunk-YGW2WEJ5.js} +17 -2
- package/dist/chunk-YGW2WEJ5.js.map +1 -0
- package/dist/{chunk-IKOGUY3M.js → chunk-Z73WO76N.js} +4 -2
- package/dist/chunk-Z73WO76N.js.map +1 -0
- package/dist/index.cjs +52 -44
- package/dist/index.js +11 -10
- package/dist/index.js.map +1 -1
- package/dist/llm/model/model.d.ts.map +1 -1
- package/dist/llm/model/model.loop.d.ts +1 -1
- package/dist/llm/model/model.loop.d.ts.map +1 -1
- package/dist/loop/index.cjs +2 -2
- package/dist/loop/index.js +1 -1
- package/dist/loop/types.d.ts +1 -0
- package/dist/loop/types.d.ts.map +1 -1
- package/dist/mastra/index.cjs +2 -2
- package/dist/mastra/index.d.ts +8 -0
- package/dist/mastra/index.d.ts.map +1 -1
- package/dist/mastra/index.js +1 -1
- package/dist/memory/index.cjs +4 -4
- package/dist/memory/index.js +1 -1
- package/dist/network/index.cjs +2 -2
- package/dist/network/index.js +1 -1
- package/dist/network/vNext/index.cjs +15 -13
- package/dist/network/vNext/index.cjs.map +1 -1
- package/dist/network/vNext/index.d.ts.map +1 -1
- package/dist/network/vNext/index.js +4 -2
- package/dist/network/vNext/index.js.map +1 -1
- package/dist/processors/index.cjs +8 -8
- package/dist/processors/index.js +2 -2
- package/dist/relevance/index.cjs +4 -4
- package/dist/relevance/index.js +1 -1
- package/dist/scores/index.cjs +282 -88
- package/dist/scores/index.cjs.map +1 -1
- package/dist/scores/index.d.ts +1 -1
- package/dist/scores/index.js +279 -85
- package/dist/scores/index.js.map +1 -1
- package/dist/scores/run-experiment/index.d.ts +59 -0
- package/dist/scores/run-experiment/index.d.ts.map +1 -0
- package/dist/scores/run-experiment/scorerAccumulator.d.ts +12 -0
- package/dist/scores/run-experiment/scorerAccumulator.d.ts.map +1 -0
- package/dist/storage/base.d.ts +9 -0
- package/dist/storage/base.d.ts.map +1 -1
- package/dist/storage/domains/observability/base.d.ts +9 -0
- package/dist/storage/domains/observability/base.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +1 -0
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/inmemory.d.ts +5 -0
- package/dist/storage/domains/observability/inmemory.d.ts.map +1 -1
- package/dist/storage/index.cjs +24 -6
- package/dist/storage/index.cjs.map +1 -1
- package/dist/storage/index.js +20 -3
- package/dist/storage/index.js.map +1 -1
- package/dist/stream/index.cjs +3 -3
- package/dist/stream/index.js +1 -1
- package/dist/test-utils/llm-mock.cjs +2 -2
- package/dist/test-utils/llm-mock.js +1 -1
- package/dist/tools/tool-builder/builder.d.ts.map +1 -1
- package/dist/tools/types.d.ts +2 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/utils.cjs +16 -16
- package/dist/utils.js +1 -1
- package/dist/vector/embed.d.ts +3 -0
- package/dist/vector/embed.d.ts.map +1 -0
- package/dist/vector/index.cjs +10 -2
- package/dist/vector/index.d.ts +1 -0
- package/dist/vector/index.d.ts.map +1 -1
- package/dist/vector/index.js +1 -1
- package/dist/vector/vector.d.ts +3 -0
- package/dist/vector/vector.d.ts.map +1 -1
- package/dist/workflows/default.d.ts +25 -6
- package/dist/workflows/default.d.ts.map +1 -1
- package/dist/workflows/evented/index.cjs +10 -10
- package/dist/workflows/evented/index.js +1 -1
- package/dist/workflows/evented/workflow.d.ts.map +1 -1
- package/dist/workflows/execution-engine.d.ts +1 -0
- package/dist/workflows/execution-engine.d.ts.map +1 -1
- package/dist/workflows/index.cjs +10 -10
- package/dist/workflows/index.js +1 -1
- package/dist/workflows/legacy/index.cjs +22 -22
- package/dist/workflows/legacy/index.js +1 -1
- package/dist/workflows/workflow.d.ts +7 -0
- package/dist/workflows/workflow.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-6NYFECSO.js.map +0 -1
- package/dist/chunk-7TH2KSEC.js.map +0 -1
- package/dist/chunk-ASRKKIW7.cjs.map +0 -1
- package/dist/chunk-DPE6K23N.cjs.map +0 -1
- package/dist/chunk-EQLCC3M7.cjs.map +0 -1
- package/dist/chunk-FCFQE5BD.js.map +0 -1
- package/dist/chunk-FFGJPMKP.js.map +0 -1
- package/dist/chunk-G6WYC4SF.cjs.map +0 -1
- package/dist/chunk-GVMFAUQR.cjs.map +0 -1
- package/dist/chunk-HRPTZGDT.js.map +0 -1
- package/dist/chunk-IKOGUY3M.js.map +0 -1
- package/dist/chunk-QLRALF4I.js.map +0 -1
- package/dist/chunk-RMEG4MOG.cjs.map +0 -1
- package/dist/chunk-SNYSVGIU.cjs.map +0 -1
- package/dist/chunk-UKQI74TN.cjs.map +0 -1
- package/dist/chunk-Y44DK4T5.js.map +0 -1
- package/dist/scores/run-experiment.d.ts +0 -35
- 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(
|
|
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
|
-
|
|
132
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
845
|
-
//# sourceMappingURL=chunk-
|
|
846
|
-
//# sourceMappingURL=chunk-
|
|
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
|