@mastra/otel-exporter 0.0.0-extract-tool-ui-inp-playground-ui-20251023135343 → 0.0.0-feat-improve-processors-20251205191721

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/index.cjs CHANGED
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var aiTracing = require('@mastra/core/ai-tracing');
4
- var logger = require('@mastra/core/logger');
3
+ var observability = require('@mastra/core/observability');
4
+ var observability$1 = require('@mastra/observability');
5
5
  var api = require('@opentelemetry/api');
6
6
  var resources = require('@opentelemetry/resources');
7
7
  var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
8
8
  var semanticConventions = require('@opentelemetry/semantic-conventions');
9
9
 
10
- // src/ai-tracing.ts
10
+ // src/tracing.ts
11
11
 
12
12
  // src/loadExporter.ts
13
13
  var OTLPHttpExporter;
@@ -225,45 +225,45 @@ var MastraReadableSpan = class {
225
225
  droppedAttributesCount = 0;
226
226
  droppedEventsCount = 0;
227
227
  droppedLinksCount = 0;
228
- constructor(aiSpan, attributes, kind, parentSpanId, resource, instrumentationLibrary) {
229
- this.name = aiSpan.name;
228
+ constructor(span, attributes, kind, parentSpanId, resource, instrumentationLibrary) {
229
+ this.name = span.name;
230
230
  this.kind = kind;
231
231
  this.attributes = attributes;
232
232
  this.parentSpanId = parentSpanId;
233
233
  this.links = [];
234
234
  this.events = [];
235
- this.startTime = this.dateToHrTime(aiSpan.startTime);
236
- this.endTime = aiSpan.endTime ? this.dateToHrTime(aiSpan.endTime) : this.startTime;
237
- this.ended = !!aiSpan.endTime;
238
- if (aiSpan.endTime) {
239
- const durationMs = aiSpan.endTime.getTime() - aiSpan.startTime.getTime();
235
+ this.startTime = this.dateToHrTime(span.startTime);
236
+ this.endTime = span.endTime ? this.dateToHrTime(span.endTime) : this.startTime;
237
+ this.ended = !!span.endTime;
238
+ if (span.endTime) {
239
+ const durationMs = span.endTime.getTime() - span.startTime.getTime();
240
240
  this.duration = [Math.floor(durationMs / 1e3), durationMs % 1e3 * 1e6];
241
241
  } else {
242
242
  this.duration = [0, 0];
243
243
  }
244
- if (aiSpan.errorInfo) {
244
+ if (span.errorInfo) {
245
245
  this.status = {
246
246
  code: api.SpanStatusCode.ERROR,
247
- message: aiSpan.errorInfo.message
247
+ message: span.errorInfo.message
248
248
  };
249
249
  this.events.push({
250
250
  name: "exception",
251
251
  attributes: {
252
- "exception.message": aiSpan.errorInfo.message,
252
+ "exception.message": span.errorInfo.message,
253
253
  "exception.type": "Error",
254
- ...aiSpan.errorInfo.details?.stack && {
255
- "exception.stacktrace": aiSpan.errorInfo.details.stack
254
+ ...span.errorInfo.details?.stack && {
255
+ "exception.stacktrace": span.errorInfo.details.stack
256
256
  }
257
257
  },
258
258
  time: this.startTime,
259
259
  droppedAttributesCount: 0
260
260
  });
261
- } else if (aiSpan.endTime) {
261
+ } else if (span.endTime) {
262
262
  this.status = { code: api.SpanStatusCode.OK };
263
263
  } else {
264
264
  this.status = { code: api.SpanStatusCode.UNSET };
265
265
  }
266
- if (aiSpan.isEvent) {
266
+ if (span.isEvent) {
267
267
  this.events.push({
268
268
  name: "instant_event",
269
269
  attributes: {},
@@ -272,14 +272,14 @@ var MastraReadableSpan = class {
272
272
  });
273
273
  }
274
274
  this.spanContext = () => ({
275
- traceId: aiSpan.traceId,
276
- spanId: aiSpan.id,
275
+ traceId: span.traceId,
276
+ spanId: span.id,
277
277
  traceFlags: api.TraceFlags.SAMPLED,
278
278
  isRemote: false
279
279
  });
280
280
  if (parentSpanId) {
281
281
  this.parentSpanContext = {
282
- traceId: aiSpan.traceId,
282
+ traceId: span.traceId,
283
283
  spanId: parentSpanId,
284
284
  traceFlags: api.TraceFlags.SAMPLED,
285
285
  isRemote: false
@@ -306,121 +306,118 @@ var MastraReadableSpan = class {
306
306
  // src/span-converter.ts
307
307
  var SPAN_KIND_MAPPING = {
308
308
  // Model operations are CLIENT spans (calling external AI services)
309
- [aiTracing.AISpanType.MODEL_GENERATION]: api.SpanKind.CLIENT,
310
- [aiTracing.AISpanType.MODEL_CHUNK]: api.SpanKind.CLIENT,
309
+ [observability.SpanType.MODEL_GENERATION]: api.SpanKind.CLIENT,
310
+ [observability.SpanType.MODEL_CHUNK]: api.SpanKind.CLIENT,
311
311
  // MCP tool calls are CLIENT (external service calls)
312
- [aiTracing.AISpanType.MCP_TOOL_CALL]: api.SpanKind.CLIENT,
312
+ [observability.SpanType.MCP_TOOL_CALL]: api.SpanKind.CLIENT,
313
313
  // Root spans for agent/workflow are SERVER (entry points)
314
- [aiTracing.AISpanType.AGENT_RUN]: api.SpanKind.SERVER,
315
- [aiTracing.AISpanType.WORKFLOW_RUN]: api.SpanKind.SERVER
314
+ [observability.SpanType.AGENT_RUN]: api.SpanKind.SERVER,
315
+ [observability.SpanType.WORKFLOW_RUN]: api.SpanKind.SERVER
316
316
  };
317
+ function getSpanKind(type, isRootSpan) {
318
+ if (isRootSpan) {
319
+ if (type === observability.SpanType.AGENT_RUN || type === observability.SpanType.WORKFLOW_RUN) {
320
+ return api.SpanKind.SERVER;
321
+ }
322
+ }
323
+ return SPAN_KIND_MAPPING[type] || api.SpanKind.INTERNAL;
324
+ }
317
325
  var SpanConverter = class {
318
326
  resource;
319
327
  instrumentationLibrary;
320
328
  constructor(resource) {
321
329
  this.resource = resource;
322
330
  this.instrumentationLibrary = {
323
- name: "@mastra/otel",
331
+ name: "@mastra/otel-exporter",
324
332
  version: "1.0.0"
325
333
  };
326
334
  }
327
335
  /**
328
- * Convert a Mastra AI span to an OpenTelemetry ReadableSpan
336
+ * Convert a Mastra Span to an OpenTelemetry ReadableSpan
329
337
  * This preserves Mastra's trace and span IDs
330
338
  */
331
- convertSpan(aiSpan) {
332
- const spanKind = this.getSpanKind(aiSpan);
333
- const attributes = this.buildAttributes(aiSpan);
334
- const spanName = this.buildSpanName(aiSpan);
335
- const otelSpan = { ...aiSpan, name: spanName };
339
+ convertSpan(span) {
340
+ const spanKind = getSpanKind(span.type, span.isRootSpan);
341
+ const attributes = this.buildAttributes(span);
342
+ const spanName = this.buildSpanName(span);
343
+ const otelSpan = { ...span, name: spanName };
336
344
  return new MastraReadableSpan(
337
345
  otelSpan,
338
346
  attributes,
339
347
  spanKind,
340
- aiSpan.parentSpanId,
348
+ span.parentSpanId,
341
349
  // Use the parentSpanId from the Mastra span directly
342
350
  this.resource,
343
351
  this.instrumentationLibrary
344
352
  );
345
353
  }
346
- /**
347
- * Get the appropriate SpanKind based on span type and context
348
- */
349
- getSpanKind(aiSpan) {
350
- if (aiSpan.isRootSpan) {
351
- if (aiSpan.type === aiTracing.AISpanType.AGENT_RUN || aiSpan.type === aiTracing.AISpanType.WORKFLOW_RUN) {
352
- return api.SpanKind.SERVER;
353
- }
354
- }
355
- return SPAN_KIND_MAPPING[aiSpan.type] || api.SpanKind.INTERNAL;
356
- }
357
354
  /**
358
355
  * Build OTEL-compliant span name based on span type and attributes
359
356
  */
360
- buildSpanName(aiSpan) {
361
- switch (aiSpan.type) {
362
- case aiTracing.AISpanType.MODEL_GENERATION: {
363
- const attrs = aiSpan.attributes;
357
+ buildSpanName(Span) {
358
+ switch (Span.type) {
359
+ case observability.SpanType.MODEL_GENERATION: {
360
+ const attrs = Span.attributes;
364
361
  const operation = attrs?.resultType === "tool_selection" ? "tool_selection" : "chat";
365
362
  const model = attrs?.model || "unknown";
366
363
  return `${operation} ${model}`;
367
364
  }
368
- case aiTracing.AISpanType.TOOL_CALL:
369
- case aiTracing.AISpanType.MCP_TOOL_CALL: {
370
- const toolAttrs = aiSpan.attributes;
365
+ case observability.SpanType.TOOL_CALL:
366
+ case observability.SpanType.MCP_TOOL_CALL: {
367
+ const toolAttrs = Span.attributes;
371
368
  const toolName = toolAttrs?.toolId || "unknown";
372
369
  return `tool.execute ${toolName}`;
373
370
  }
374
- case aiTracing.AISpanType.AGENT_RUN: {
375
- const agentAttrs = aiSpan.attributes;
371
+ case observability.SpanType.AGENT_RUN: {
372
+ const agentAttrs = Span.attributes;
376
373
  const agentId = agentAttrs?.agentId || "unknown";
377
374
  return `agent.${agentId}`;
378
375
  }
379
- case aiTracing.AISpanType.WORKFLOW_RUN: {
380
- const workflowAttrs = aiSpan.attributes;
376
+ case observability.SpanType.WORKFLOW_RUN: {
377
+ const workflowAttrs = Span.attributes;
381
378
  const workflowId = workflowAttrs?.workflowId || "unknown";
382
379
  return `workflow.${workflowId}`;
383
380
  }
384
- case aiTracing.AISpanType.WORKFLOW_STEP:
385
- return aiSpan.name;
381
+ case observability.SpanType.WORKFLOW_STEP:
382
+ return Span.name;
386
383
  default:
387
- return aiSpan.name;
384
+ return Span.name;
388
385
  }
389
386
  }
390
387
  /**
391
- * Build OpenTelemetry attributes from Mastra AI span
388
+ * Build OpenTelemetry attributes from Mastra Span
392
389
  * Following OTEL Semantic Conventions for GenAI
393
390
  */
394
- buildAttributes(aiSpan) {
391
+ buildAttributes(Span) {
395
392
  const attributes = {};
396
- attributes["gen_ai.operation.name"] = this.getOperationName(aiSpan);
397
- attributes["span.kind"] = this.getSpanKindString(aiSpan);
398
- attributes["mastra.span.type"] = aiSpan.type;
399
- attributes["mastra.trace_id"] = aiSpan.traceId;
400
- attributes["mastra.span_id"] = aiSpan.id;
401
- if (aiSpan.parentSpanId) {
402
- attributes["mastra.parent_span_id"] = aiSpan.parentSpanId;
403
- }
404
- if (aiSpan.input !== void 0) {
405
- const inputStr = typeof aiSpan.input === "string" ? aiSpan.input : JSON.stringify(aiSpan.input);
393
+ attributes["gen_ai.operation.name"] = this.getOperationName(Span);
394
+ attributes["span.kind"] = this.getSpanKindString(Span);
395
+ attributes["mastra.span.type"] = Span.type;
396
+ attributes["mastra.trace_id"] = Span.traceId;
397
+ attributes["mastra.span_id"] = Span.id;
398
+ if (Span.parentSpanId) {
399
+ attributes["mastra.parent_span_id"] = Span.parentSpanId;
400
+ }
401
+ if (Span.input !== void 0) {
402
+ const inputStr = typeof Span.input === "string" ? Span.input : JSON.stringify(Span.input);
406
403
  attributes["input"] = inputStr;
407
- if (aiSpan.type === aiTracing.AISpanType.MODEL_GENERATION) {
404
+ if (Span.type === observability.SpanType.MODEL_GENERATION) {
408
405
  attributes["gen_ai.prompt"] = inputStr;
409
- } else if (aiSpan.type === aiTracing.AISpanType.TOOL_CALL || aiSpan.type === aiTracing.AISpanType.MCP_TOOL_CALL) {
406
+ } else if (Span.type === observability.SpanType.TOOL_CALL || Span.type === observability.SpanType.MCP_TOOL_CALL) {
410
407
  attributes["gen_ai.tool.input"] = inputStr;
411
408
  }
412
409
  }
413
- if (aiSpan.output !== void 0) {
414
- const outputStr = typeof aiSpan.output === "string" ? aiSpan.output : JSON.stringify(aiSpan.output);
410
+ if (Span.output !== void 0) {
411
+ const outputStr = typeof Span.output === "string" ? Span.output : JSON.stringify(Span.output);
415
412
  attributes["output"] = outputStr;
416
- if (aiSpan.type === aiTracing.AISpanType.MODEL_GENERATION) {
413
+ if (Span.type === observability.SpanType.MODEL_GENERATION) {
417
414
  attributes["gen_ai.completion"] = outputStr;
418
- } else if (aiSpan.type === aiTracing.AISpanType.TOOL_CALL || aiSpan.type === aiTracing.AISpanType.MCP_TOOL_CALL) {
415
+ } else if (Span.type === observability.SpanType.TOOL_CALL || Span.type === observability.SpanType.MCP_TOOL_CALL) {
419
416
  attributes["gen_ai.tool.output"] = outputStr;
420
417
  }
421
418
  }
422
- if (aiSpan.type === aiTracing.AISpanType.MODEL_GENERATION && aiSpan.attributes) {
423
- const modelAttrs = aiSpan.attributes;
419
+ if (Span.type === observability.SpanType.MODEL_GENERATION && Span.attributes) {
420
+ const modelAttrs = Span.attributes;
424
421
  if (modelAttrs.model) {
425
422
  attributes["gen_ai.request.model"] = modelAttrs.model;
426
423
  }
@@ -473,12 +470,12 @@ var SpanConverter = class {
473
470
  attributes["gen_ai.response.finish_reasons"] = modelAttrs.finishReason;
474
471
  }
475
472
  }
476
- if ((aiSpan.type === aiTracing.AISpanType.TOOL_CALL || aiSpan.type === aiTracing.AISpanType.MCP_TOOL_CALL) && aiSpan.attributes) {
477
- const toolAttrs = aiSpan.attributes;
473
+ if ((Span.type === observability.SpanType.TOOL_CALL || Span.type === observability.SpanType.MCP_TOOL_CALL) && Span.attributes) {
474
+ const toolAttrs = Span.attributes;
478
475
  if (toolAttrs.toolId) {
479
476
  attributes["gen_ai.tool.name"] = toolAttrs.toolId;
480
477
  }
481
- if (aiSpan.type === aiTracing.AISpanType.MCP_TOOL_CALL) {
478
+ if (Span.type === observability.SpanType.MCP_TOOL_CALL) {
482
479
  const mcpAttrs = toolAttrs;
483
480
  if (mcpAttrs.mcpServer) {
484
481
  attributes["mcp.server"] = mcpAttrs.mcpServer;
@@ -495,8 +492,8 @@ var SpanConverter = class {
495
492
  attributes["gen_ai.tool.success"] = toolAttrs.success;
496
493
  }
497
494
  }
498
- if (aiSpan.type === aiTracing.AISpanType.AGENT_RUN && aiSpan.attributes) {
499
- const agentAttrs = aiSpan.attributes;
495
+ if (Span.type === observability.SpanType.AGENT_RUN && Span.attributes) {
496
+ const agentAttrs = Span.attributes;
500
497
  if (agentAttrs.agentId) {
501
498
  attributes["agent.id"] = agentAttrs.agentId;
502
499
  attributes["gen_ai.agent.id"] = agentAttrs.agentId;
@@ -508,8 +505,8 @@ var SpanConverter = class {
508
505
  attributes["agent.available_tools"] = JSON.stringify(agentAttrs.availableTools);
509
506
  }
510
507
  }
511
- if (aiSpan.type === aiTracing.AISpanType.WORKFLOW_RUN && aiSpan.attributes) {
512
- const workflowAttrs = aiSpan.attributes;
508
+ if (Span.type === observability.SpanType.WORKFLOW_RUN && Span.attributes) {
509
+ const workflowAttrs = Span.attributes;
513
510
  if (workflowAttrs.workflowId) {
514
511
  attributes["workflow.id"] = workflowAttrs.workflowId;
515
512
  }
@@ -517,19 +514,19 @@ var SpanConverter = class {
517
514
  attributes["workflow.status"] = workflowAttrs.status;
518
515
  }
519
516
  }
520
- if (aiSpan.errorInfo) {
517
+ if (Span.errorInfo) {
521
518
  attributes["error"] = true;
522
- attributes["error.type"] = aiSpan.errorInfo.id || "unknown";
523
- attributes["error.message"] = aiSpan.errorInfo.message;
524
- if (aiSpan.errorInfo.domain) {
525
- attributes["error.domain"] = aiSpan.errorInfo.domain;
519
+ attributes["error.type"] = Span.errorInfo.id || "unknown";
520
+ attributes["error.message"] = Span.errorInfo.message;
521
+ if (Span.errorInfo.domain) {
522
+ attributes["error.domain"] = Span.errorInfo.domain;
526
523
  }
527
- if (aiSpan.errorInfo.category) {
528
- attributes["error.category"] = aiSpan.errorInfo.category;
524
+ if (Span.errorInfo.category) {
525
+ attributes["error.category"] = Span.errorInfo.category;
529
526
  }
530
527
  }
531
- if (aiSpan.metadata) {
532
- Object.entries(aiSpan.metadata).forEach(([key, value]) => {
528
+ if (Span.metadata) {
529
+ Object.entries(Span.metadata).forEach(([key, value]) => {
533
530
  if (!attributes[key]) {
534
531
  if (value === null || value === void 0) {
535
532
  return;
@@ -542,12 +539,12 @@ var SpanConverter = class {
542
539
  }
543
540
  });
544
541
  }
545
- if (aiSpan.startTime) {
546
- attributes["mastra.start_time"] = aiSpan.startTime.toISOString();
542
+ if (Span.startTime) {
543
+ attributes["mastra.start_time"] = Span.startTime.toISOString();
547
544
  }
548
- if (aiSpan.endTime) {
549
- attributes["mastra.end_time"] = aiSpan.endTime.toISOString();
550
- const duration = aiSpan.endTime.getTime() - aiSpan.startTime.getTime();
545
+ if (Span.endTime) {
546
+ attributes["mastra.end_time"] = Span.endTime.toISOString();
547
+ const duration = Span.endTime.getTime() - Span.startTime.getTime();
551
548
  attributes["mastra.duration_ms"] = duration;
552
549
  }
553
550
  return attributes;
@@ -555,28 +552,28 @@ var SpanConverter = class {
555
552
  /**
556
553
  * Get the operation name based on span type for gen_ai.operation.name
557
554
  */
558
- getOperationName(aiSpan) {
559
- switch (aiSpan.type) {
560
- case aiTracing.AISpanType.MODEL_GENERATION: {
561
- const attrs = aiSpan.attributes;
555
+ getOperationName(Span) {
556
+ switch (Span.type) {
557
+ case observability.SpanType.MODEL_GENERATION: {
558
+ const attrs = Span.attributes;
562
559
  return attrs?.resultType === "tool_selection" ? "tool_selection" : "chat";
563
560
  }
564
- case aiTracing.AISpanType.TOOL_CALL:
565
- case aiTracing.AISpanType.MCP_TOOL_CALL:
561
+ case observability.SpanType.TOOL_CALL:
562
+ case observability.SpanType.MCP_TOOL_CALL:
566
563
  return "tool.execute";
567
- case aiTracing.AISpanType.AGENT_RUN:
564
+ case observability.SpanType.AGENT_RUN:
568
565
  return "agent.run";
569
- case aiTracing.AISpanType.WORKFLOW_RUN:
566
+ case observability.SpanType.WORKFLOW_RUN:
570
567
  return "workflow.run";
571
568
  default:
572
- return aiSpan.type.replace(/_/g, ".");
569
+ return Span.type.replace(/_/g, ".");
573
570
  }
574
571
  }
575
572
  /**
576
573
  * Get span kind as string for attribute
577
574
  */
578
- getSpanKindString(aiSpan) {
579
- const kind = this.getSpanKind(aiSpan);
575
+ getSpanKindString(Span) {
576
+ const kind = getSpanKind(Span.type, Span.isRootSpan);
580
577
  switch (kind) {
581
578
  case api.SpanKind.SERVER:
582
579
  return "server";
@@ -594,21 +591,19 @@ var SpanConverter = class {
594
591
  }
595
592
  };
596
593
 
597
- // src/ai-tracing.ts
598
- var OtelExporter = class {
594
+ // src/tracing.ts
595
+ var OtelExporter = class extends observability$1.BaseExporter {
599
596
  config;
600
597
  tracingConfig;
601
598
  spanConverter;
602
599
  processor;
603
600
  exporter;
604
601
  isSetup = false;
605
- isDisabled = false;
606
- logger;
607
602
  name = "opentelemetry";
608
603
  constructor(config) {
604
+ super(config);
609
605
  this.config = config;
610
606
  this.spanConverter = new SpanConverter();
611
- this.logger = new logger.ConsoleLogger({ level: config.logLevel ?? "warn" });
612
607
  if (config.logLevel === "debug") {
613
608
  api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.DEBUG);
614
609
  }
@@ -616,8 +611,8 @@ var OtelExporter = class {
616
611
  /**
617
612
  * Initialize with tracing configuration
618
613
  */
619
- init(config) {
620
- this.tracingConfig = config;
614
+ init(options) {
615
+ this.tracingConfig = options.config;
621
616
  }
622
617
  async setupExporter() {
623
618
  if (this.isSetup || this.exporter) return;
@@ -730,11 +725,8 @@ var OtelExporter = class {
730
725
  await this.setupProcessor();
731
726
  this.isSetup = true;
732
727
  }
733
- async exportEvent(event) {
734
- if (this.isDisabled) {
735
- return;
736
- }
737
- if (event.type !== aiTracing.AITracingEventType.SPAN_ENDED) {
728
+ async _exportTracingEvent(event) {
729
+ if (event.type !== observability.TracingEventType.SPAN_ENDED) {
738
730
  return;
739
731
  }
740
732
  const span = event.exportedSpan;
@@ -767,6 +759,9 @@ var OtelExporter = class {
767
759
  }
768
760
  };
769
761
 
762
+ exports.MastraReadableSpan = MastraReadableSpan;
770
763
  exports.OtelExporter = OtelExporter;
764
+ exports.SpanConverter = SpanConverter;
765
+ exports.getSpanKind = getSpanKind;
771
766
  //# sourceMappingURL=index.cjs.map
772
767
  //# sourceMappingURL=index.cjs.map