@mastra/otel-exporter 0.0.0-fix-9244-clickhouse-metadata-20251105010900 → 0.0.0-fix-thread-list-20251105222841

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