{"version":3,"sources":["../src/openInferenceOTLPExporter.ts","../src/tracing.ts"],"names":["OpenInferenceSpanKind","ATTR_GEN_AI_USAGE_INPUT_TOKENS","ATTR_GEN_AI_USAGE_OUTPUT_TOKENS","LLM_TOKEN_COUNT_PROMPT","LLM_TOKEN_COUNT_COMPLETION","LLM_TOKEN_COUNT_TOTAL","LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_READ","LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_WRITE","LLM_TOKEN_COUNT_COMPLETION_DETAILS_REASONING","LLM_TOKEN_COUNT_PROMPT_DETAILS_AUDIO","LLM_TOKEN_COUNT_COMPLETION_DETAILS_AUDIO","OTLPTraceExporter","convertGenAISpanAttributesToOpenInferenceSpanAttributes","SESSION_ID","TAG_TAGS","USER_ID","METADATA","ATTR_GEN_AI_INPUT_MESSAGES","ATTR_GEN_AI_TOOL_CALL_ARGUMENTS","INPUT_MIME_TYPE","INPUT_VALUE","ATTR_GEN_AI_OUTPUT_MESSAGES","ATTR_GEN_AI_TOOL_CALL_RESULT","OUTPUT_MIME_TYPE","OUTPUT_VALUE","SemanticConventions","OtelExporter","SEMRESATTRS_PROJECT_NAME"],"mappings":"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","file":"index.cjs","sourcesContent":["import { convertGenAISpanAttributesToOpenInferenceSpanAttributes } from '@arizeai/openinference-genai';\nimport type { Mutable } from '@arizeai/openinference-genai/types';\nimport {\n  INPUT_MIME_TYPE,\n  INPUT_VALUE,\n  LLM_TOKEN_COUNT_COMPLETION,\n  LLM_TOKEN_COUNT_COMPLETION_DETAILS_AUDIO,\n  LLM_TOKEN_COUNT_COMPLETION_DETAILS_REASONING,\n  LLM_TOKEN_COUNT_PROMPT,\n  LLM_TOKEN_COUNT_PROMPT_DETAILS_AUDIO,\n  LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_READ,\n  LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_WRITE,\n  LLM_TOKEN_COUNT_TOTAL,\n  METADATA,\n  OpenInferenceSpanKind,\n  OUTPUT_MIME_TYPE,\n  OUTPUT_VALUE,\n  SemanticConventions,\n  SESSION_ID,\n  TAG_TAGS,\n  USER_ID,\n} from '@arizeai/openinference-semantic-conventions';\nimport type { ExportResult } from '@opentelemetry/core';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-base';\nimport {\n  ATTR_GEN_AI_INPUT_MESSAGES,\n  ATTR_GEN_AI_OUTPUT_MESSAGES,\n  ATTR_GEN_AI_USAGE_INPUT_TOKENS,\n  ATTR_GEN_AI_USAGE_OUTPUT_TOKENS,\n  ATTR_GEN_AI_TOOL_CALL_ARGUMENTS,\n  ATTR_GEN_AI_TOOL_CALL_RESULT,\n} from '@opentelemetry/semantic-conventions/incubating';\n\n// GenAI usage attribute keys (not all are in @opentelemetry/semantic-conventions yet)\n// @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/\nconst GEN_AI_USAGE_REASONING_TOKENS = 'gen_ai.usage.reasoning_tokens';\nconst GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS = 'gen_ai.usage.cache_read.input_tokens';\nconst GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS = 'gen_ai.usage.cache_creation.input_tokens';\nconst GEN_AI_USAGE_AUDIO_INPUT_TOKENS = 'gen_ai.usage.audio_input_tokens';\nconst GEN_AI_USAGE_AUDIO_OUTPUT_TOKENS = 'gen_ai.usage.audio_output_tokens';\n\nconst MASTRA_GENERAL_PREFIX = 'mastra.';\nconst MASTRA_METADATA_PREFIX = 'mastra.metadata.';\nconst MASTRA_MODEL_STEP_INPUT = 'mastra.model_step.input';\nconst MASTRA_MODEL_STEP_OUTPUT = 'mastra.model_step.output';\nconst MASTRA_MODEL_CHUNK_OUTPUT = 'mastra.model_chunk.output';\nconst MASTRA_SPAN_TYPE = 'mastra.span.type';\n\n/**\n * Maps Mastra span types to OpenInference span kinds for proper trace categorization.\n *\n * Only non-CHAIN types are mapped here - all other span types default to CHAIN.\n */\nconst SPAN_TYPE_TO_KIND: Record<string, OpenInferenceSpanKind> = {\n  // Model spans -> LLM\n  model_generation: OpenInferenceSpanKind.LLM,\n  model_step: OpenInferenceSpanKind.LLM,\n  model_chunk: OpenInferenceSpanKind.LLM,\n  // Tool spans -> TOOL\n  tool_call: OpenInferenceSpanKind.TOOL,\n  mcp_tool_call: OpenInferenceSpanKind.TOOL,\n  // Agent spans -> AGENT\n  agent_run: OpenInferenceSpanKind.AGENT,\n};\n\n/**\n * Converts GenAI usage metrics to OpenInference LLM token count attributes.\n * Maps from OTEL GenAI semantic conventions to OpenInference semantic conventions.\n *\n * @param attributes - The span attributes containing GenAI usage metrics\n * @returns OpenInference token count attributes\n */\nfunction convertUsageMetricsToOpenInference(attributes: Record<string, any>): Record<string, any> {\n  const result: Record<string, any> = {};\n\n  const inputTokens = attributes[ATTR_GEN_AI_USAGE_INPUT_TOKENS];\n  const outputTokens = attributes[ATTR_GEN_AI_USAGE_OUTPUT_TOKENS];\n\n  // Core token counts\n  if (inputTokens !== undefined) {\n    result[LLM_TOKEN_COUNT_PROMPT] = inputTokens;\n  }\n  if (outputTokens !== undefined) {\n    result[LLM_TOKEN_COUNT_COMPLETION] = outputTokens;\n  }\n\n  // Total tokens (compute if we have both input and output)\n  if (inputTokens !== undefined && outputTokens !== undefined) {\n    result[LLM_TOKEN_COUNT_TOTAL] = inputTokens + outputTokens;\n  }\n\n  // Cache tokens (prompt details)\n  const cacheReadInputTokens = attributes[GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS];\n  if (cacheReadInputTokens !== undefined) {\n    result[LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_READ] = cacheReadInputTokens;\n  }\n\n  const cacheCreationInputTokens = attributes[GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS];\n  if (cacheCreationInputTokens !== undefined) {\n    result[LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_WRITE] = cacheCreationInputTokens;\n  }\n\n  // Reasoning tokens (completion details)\n  const reasoningTokens = attributes[GEN_AI_USAGE_REASONING_TOKENS];\n  if (reasoningTokens !== undefined) {\n    result[LLM_TOKEN_COUNT_COMPLETION_DETAILS_REASONING] = reasoningTokens;\n  }\n\n  // Audio tokens\n  const audioInputTokens = attributes[GEN_AI_USAGE_AUDIO_INPUT_TOKENS];\n  if (audioInputTokens !== undefined) {\n    result[LLM_TOKEN_COUNT_PROMPT_DETAILS_AUDIO] = audioInputTokens;\n  }\n\n  const audioOutputTokens = attributes[GEN_AI_USAGE_AUDIO_OUTPUT_TOKENS];\n  if (audioOutputTokens !== undefined) {\n    result[LLM_TOKEN_COUNT_COMPLETION_DETAILS_AUDIO] = audioOutputTokens;\n  }\n\n  return result;\n}\n\n/**\n * Splits Mastra span attributes into two groups:\n * - `metadata`: keys starting with \"mastra.metadata.\" (prefix removed)\n * - `other`: all remaining keys starting with \"mastra.\"\n *\n * Any attributes not starting with \"mastra.\" are ignored entirely.\n */\nfunction splitMastraAttributes(attributes: Record<string, any>): {\n  mastraMetadata: Record<string, any>;\n  mastraOther: Record<string, any>;\n} {\n  return Object.entries(attributes).reduce(\n    (acc, [key, value]) => {\n      if (key.startsWith(MASTRA_GENERAL_PREFIX)) {\n        if (key.startsWith(MASTRA_METADATA_PREFIX)) {\n          const strippedKey = key.slice(MASTRA_METADATA_PREFIX.length);\n          acc.mastraMetadata[strippedKey] = value;\n        } else {\n          acc.mastraOther[key] = value;\n        }\n      }\n      return acc;\n    },\n    {\n      mastraMetadata: {} as Record<string, any>,\n      mastraOther: {} as Record<string, any>,\n    },\n  );\n}\n\nexport class OpenInferenceOTLPTraceExporter extends OTLPTraceExporter {\n  export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void) {\n    const processedSpans = spans.map(span => {\n      const attributes = { ...(span.attributes ?? {}) };\n      const mutableSpan = span as Mutable<ReadableSpan>;\n\n      const { mastraMetadata, mastraOther } = splitMastraAttributes(attributes);\n      const processedAttributes = convertGenAISpanAttributesToOpenInferenceSpanAttributes(attributes);\n\n      // only add processed attributes if conversion was successful\n      if (processedAttributes) {\n        const threadId = mastraMetadata['threadId'];\n        if (threadId) {\n          delete mastraMetadata['threadId'];\n          processedAttributes[SESSION_ID] = threadId;\n        }\n\n        // Map mastra.tags to OpenInference native tag.tags convention (tags are only on root spans)\n        if (mastraOther['mastra.tags']) {\n          processedAttributes[TAG_TAGS] = mastraOther['mastra.tags'];\n          delete mastraOther['mastra.tags'];\n        }\n\n        const userId = mastraMetadata['userId'];\n        if (userId) {\n          delete mastraMetadata['userId'];\n          processedAttributes[USER_ID] = userId;\n        }\n\n        // Gather custom metadata into OpenInference metadata (flat best-effort)\n        if (Object.keys(mastraMetadata).length > 0) {\n          try {\n            processedAttributes[METADATA] = JSON.stringify(mastraMetadata);\n          } catch {\n            // best-effort only\n          }\n        }\n\n        const inputMessages =\n          attributes[ATTR_GEN_AI_INPUT_MESSAGES] ??\n          attributes[ATTR_GEN_AI_TOOL_CALL_ARGUMENTS] ??\n          mastraOther[MASTRA_MODEL_STEP_INPUT];\n        if (inputMessages) {\n          processedAttributes[INPUT_MIME_TYPE] = 'application/json';\n          processedAttributes[INPUT_VALUE] = inputMessages;\n        }\n        const outputMessages =\n          attributes[ATTR_GEN_AI_OUTPUT_MESSAGES] ??\n          attributes[ATTR_GEN_AI_TOOL_CALL_RESULT] ??\n          mastraOther[MASTRA_MODEL_STEP_OUTPUT] ??\n          mastraOther[MASTRA_MODEL_CHUNK_OUTPUT];\n        if (outputMessages) {\n          processedAttributes[OUTPUT_MIME_TYPE] = 'application/json';\n          processedAttributes[OUTPUT_VALUE] = outputMessages;\n        }\n\n        // Map generic Mastra span input/output to OpenInference input/output\n        // These are set by Mastra's gen-ai-semantics.ts for non-LLM/tool spans\n        // (e.g., mastra.processor_run.input, mastra.workflow_run.input, etc.)\n        if (!processedAttributes[INPUT_VALUE]) {\n          for (const key of Object.keys(mastraOther)) {\n            if (key.endsWith('.input')) {\n              processedAttributes[INPUT_MIME_TYPE] = 'application/json';\n              processedAttributes[INPUT_VALUE] = mastraOther[key];\n              break;\n            }\n          }\n        }\n        if (!processedAttributes[OUTPUT_VALUE]) {\n          for (const key of Object.keys(mastraOther)) {\n            if (key.endsWith('.output')) {\n              processedAttributes[OUTPUT_MIME_TYPE] = 'application/json';\n              processedAttributes[OUTPUT_VALUE] = mastraOther[key];\n              break;\n            }\n          }\n        }\n\n        // Convert GenAI usage metrics to OpenInference token count attributes\n        const usageMetrics = convertUsageMetricsToOpenInference(attributes);\n        Object.assign(processedAttributes, usageMetrics);\n\n        mutableSpan.attributes = { ...processedAttributes, ...mastraOther };\n\n        // Set span kind based on mastra.span.type for proper trace categorization\n        const spanType = mastraOther[MASTRA_SPAN_TYPE];\n        if (typeof spanType === 'string') {\n          mutableSpan.attributes[SemanticConventions.OPENINFERENCE_SPAN_KIND] =\n            SPAN_TYPE_TO_KIND[spanType] ?? OpenInferenceSpanKind.CHAIN;\n        }\n      }\n\n      return mutableSpan;\n    });\n\n    super.export(processedSpans, resultCallback);\n  }\n}\n","import { SEMRESATTRS_PROJECT_NAME } from '@arizeai/openinference-semantic-conventions';\nimport { OtelExporter } from '@mastra/otel-exporter';\nimport type { OtelExporterConfig } from '@mastra/otel-exporter';\n\nimport { OpenInferenceOTLPTraceExporter } from './openInferenceOTLPExporter.js';\n\nconst LOG_PREFIX = '[ArizeExporter]';\n\nexport const ARIZE_AX_ENDPOINT = 'https://otlp.arize.com/v1/traces';\n\nexport type ArizeExporterConfig = Omit<OtelExporterConfig, 'provider'> & {\n  /**\n   * Required if sending traces to Arize AX\n   */\n  spaceId?: string;\n  /**\n   * Required if sending traces to Arize AX, or to any other collector that\n   * requires an Authorization header\n   */\n  apiKey?: string;\n  /**\n   * Collector endpoint destination for trace exports.\n   * Required when sending traces to Phoenix, Phoenix Cloud, or other collectors.\n   * Optional when sending traces to Arize AX.\n   */\n  endpoint?: string;\n  /**\n   * Optional project name to be added as a resource attribute using\n   * OpenInference Semantic Conventions\n   */\n  projectName?: string;\n  /**\n   * Optional headers to be added to each OTLP request\n   */\n  headers?: Record<string, string>;\n};\n\nexport class ArizeExporter extends OtelExporter {\n  name = 'arize';\n\n  constructor(config: ArizeExporterConfig = {}) {\n    // Read configuration from config or environment variables\n    // Priority: config > ARIZE_* env vars > PHOENIX_* env vars\n    const spaceId = config.spaceId ?? process.env.ARIZE_SPACE_ID;\n    const apiKey = config.apiKey ?? process.env.ARIZE_API_KEY ?? process.env.PHOENIX_API_KEY;\n    const projectName = config.projectName ?? process.env.ARIZE_PROJECT_NAME ?? process.env.PHOENIX_PROJECT_NAME;\n\n    // Determine endpoint: config > PHOENIX_COLLECTOR_ENDPOINT > PHOENIX_ENDPOINT > ARIZE_AX_ENDPOINT (if spaceId is set)\n    let endpoint: string | undefined =\n      config.endpoint ?? process.env.PHOENIX_COLLECTOR_ENDPOINT ?? process.env.PHOENIX_ENDPOINT;\n\n    const headers: Record<string, string> = {\n      ...config.headers,\n    };\n\n    // Validate credentials based on mode\n    let disabledReason: string | undefined;\n\n    if (spaceId) {\n      // Arize AX mode requires an API key\n      if (!apiKey) {\n        disabledReason =\n          `${LOG_PREFIX} API key is required for Arize AX. ` +\n          `Set ARIZE_API_KEY environment variable or pass apiKey in config.`;\n      } else {\n        // arize ax header configuration\n        headers['space_id'] = spaceId;\n        headers['api_key'] = apiKey;\n        endpoint = endpoint || ARIZE_AX_ENDPOINT;\n      }\n    } else if (apiKey) {\n      // standard otel header configuration\n      headers['Authorization'] = `Bearer ${apiKey}`;\n    }\n\n    if (!disabledReason && !endpoint) {\n      disabledReason =\n        `${LOG_PREFIX} Endpoint is required in configuration. ` +\n        `Set PHOENIX_COLLECTOR_ENDPOINT environment variable, or ARIZE_SPACE_ID for Arize AX, or pass endpoint in config.`;\n    }\n\n    // If disabled, create with minimal config and disable\n    if (disabledReason) {\n      super({\n        ...config,\n        provider: {\n          custom: {\n            endpoint: 'http://disabled',\n            headers: {},\n            protocol: 'http/protobuf',\n          },\n        },\n      });\n      this.setDisabled(disabledReason);\n      return;\n    }\n\n    super({\n      exporter: new OpenInferenceOTLPTraceExporter({\n        url: endpoint!,\n        headers,\n      }),\n      ...config,\n      resourceAttributes: {\n        ...(projectName ? { [SEMRESATTRS_PROJECT_NAME]: projectName } : {}),\n        ...config.resourceAttributes,\n      },\n      provider: {\n        custom: {\n          endpoint: endpoint!,\n          headers,\n          protocol: 'http/protobuf',\n        },\n      } satisfies OtelExporterConfig['provider'],\n    } satisfies OtelExporterConfig);\n  }\n}\n"]}