Skip to content

fix(otel-exporter): export RAG_EMBEDDING spans using GenAI embedding semantics#17917

Open
Akash504-ai wants to merge 2 commits into
mastra-ai:mainfrom
Akash504-ai:feat/rag-embedding-genai-semantics
Open

fix(otel-exporter): export RAG_EMBEDDING spans using GenAI embedding semantics#17917
Akash504-ai wants to merge 2 commits into
mastra-ai:mainfrom
Akash504-ai:feat/rag-embedding-genai-semantics

Conversation

@Akash504-ai

@Akash504-ai Akash504-ai commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes missing OpenTelemetry GenAI semantic mappings for RAG_EMBEDDING spans.

RAG_EMBEDDING spans already include model, provider, usage, dimensions, mode, and inputCount metadata, but the OTel exporter only mapped GenAI semantic attributes for MODEL_GENERATION spans. As a result, embedding spans were exported without model/provider/usage information and were treated as generic internal spans by downstream observability tools.

This PR:

  • Maps RAG_EMBEDDING to gen_ai.operation.name = "embeddings"
  • Exports gen_ai.request.model
  • Exports gen_ai.provider.name
  • Exports gen_ai.usage.* metrics
  • Preserves embedding-specific metadata (mode, dimensions, inputCount)
  • Uses model-based span naming for embedding spans
  • Exports RAG_EMBEDDING spans as SpanKind.CLIENT

These changes allow downstream consumers such as Langfuse to receive the embedding metadata required for model attribution and cost tracking without custom span rewriting.

Related issue(s)

Fixes #17914

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • Performance improvement
  • Test update

Checklist

  • I have linked the related issue(s) in the description above
  • I have made corresponding changes to the documentation (if applicable)
  • I have added tests that prove my fix is effective or that my feature works
  • I have addressed all Coderabbit comments on this PR

ELI5

This PR teaches the OpenTelemetry exporter how to recognize “embedding” spans (RAG embedding jobs) the same way it already does for text generation. As a result, monitoring tools now see which embedding model was used and how many tokens it used, instead of showing it as a vague “internal” event.

Summary

Mastra already attaches rich metadata to RAG_EMBEDDING spans (model/provider, token usage, and embedding-specific details), but the OTel exporter wasn’t translating that metadata into OpenTelemetry GenAI semantic attributes. That made downstream observability tools (e.g., Langfuse) treat embedding runs as generic internal spans, losing model attribution and usage/cost information.

Solution

The OTel exporter was updated to add explicit RAG_EMBEDDING handling:

  • Sets gen_ai.operation.name = "embeddings" for RAG_EMBEDDING spans
  • Exports GenAI semantic attributes for embedding spans:
    • gen_ai.request.model (from the embedding model attribute)
    • gen_ai.provider.name (normalized from the provider attribute)
    • gen_ai.usage.* token usage fields (including token/cost-related metrics)
  • Generates embedding-aware span naming based on the embedding model (with a safe fallback when missing)
  • Preserves embedding-specific metadata on dedicated attributes:
    • mastra.rag_embedding.* (mode, dimensions, input count)
  • Maps RAG_EMBEDDING span kind from INTERNAL to SpanKind.CLIENT so it’s categorized as an outbound/GenAI operation

Changes

  • observability/otel-exporter/src/gen-ai-semantics.ts
    • Adds RAG_EMBEDDINGgen_ai.operation.name = "embeddings" mapping
    • Consolidates model/provider/usage attribute generation for both MODEL_GENERATION and RAG_EMBEDDING
    • Adds a dedicated RAG_EMBEDDING attributes branch to emit embedding-specific mastra.rag_embedding.* metadata
  • observability/otel-exporter/src/span-converter.ts
    • Updates getSpanKind() so RAG_EMBEDDING converts to SpanKind.CLIENT
  • Tests
    • gen-ai-semantics.test.ts: Adds coverage ensuring embedding spans export operation/request/provider/model and token usage GenAI fields, plus mastra.rag_embedding.* attributes
    • span-converter.test.ts: Adds conversion tests for embedding operation naming, span naming (model-present + fallback), and SpanKind.CLIENT
  • Changeset
    • Bumps @mastra/otel-exporter with a documented patch fix for RAG embedding span OTel exports

@changeset-bot

changeset-bot Bot commented Jun 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ae7ac9a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@mastra/otel-exporter Patch
@mastra/arize Patch
@mastra/arthur Patch
@mastra/langfuse Patch
@mastra/otel-bridge Patch
@mastra/sentry Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jun 14, 2026

Copy link
Copy Markdown

@Akash504-ai is attempting to deploy a commit to the Mastra Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e89c2c73-4972-4d7e-b826-abc977315326

📥 Commits

Reviewing files that changed from the base of the PR and between 4c135ed and ae7ac9a.

📒 Files selected for processing (2)
  • observability/otel-exporter/src/gen-ai-semantics.test.ts
  • observability/otel-exporter/src/span-converter.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • observability/otel-exporter/src/span-converter.test.ts
  • observability/otel-exporter/src/gen-ai-semantics.test.ts

Walkthrough

Extends @mastra/otel-exporter to map RAG_EMBEDDING spans to OpenTelemetry GenAI semantic conventions. The change introduces a shared request-attribute helper in gen-ai-semantics.ts, maps the operation name to embeddings, extracts model for span identification, and adds RAG-specific attributes. span-converter.ts maps the span kind to SpanKind.CLIENT. Tests validate operation naming, span kinds, and full attribute mapping. A patch changeset documents the fix.

Changes

RAG Embedding OTel Span Mapping

Layer / File(s) Summary
gen-ai-semantics: RAG_EMBEDDING attribute and operation mapping
observability/otel-exporter/src/gen-ai-semantics.ts
Imports RagEmbeddingAttributes; introduces addModelRequestAttributes helper to consolidate model, provider, and usage field population across span types; extends getOperationName to return 'embeddings' for RAG_EMBEDDING; updates span identifier extraction to read the model from RagEmbeddingAttributes; refactors MODEL_GENERATION to use the helper instead of inline assignment; adds a dedicated RAG_EMBEDDING branch in getAttributes emitting mode, dimensions, and input count.
span-converter: RAG_EMBEDDING → SpanKind.CLIENT
observability/otel-exporter/src/span-converter.ts
Adds a case SpanType.RAG_EMBEDDING fallthrough in getSpanKind, changing the resolved span kind from SpanKind.INTERNAL to SpanKind.CLIENT.
gen-ai-semantics tests: attribute mapping validation
observability/otel-exporter/src/gen-ai-semantics.test.ts
Reformats type imports to multi-line format; adds createRagEmbeddingSpan test helper; extends token usage tests with a RAG embedding case asserting operation name, request model/provider, usage metrics, and embedding-specific mastra.rag_embedding.* metadata.
span-converter tests: naming, span kind, and attribute mapping
observability/otel-exporter/src/span-converter.test.ts
Adds type and constant imports for RagEmbeddingAttributes and MODEL_TOKENS; implements RAG embedding span naming tests (with and without explicit model); adds span-kind mapping test asserting SpanKind.CLIENT; extends OTEL GenAI attribute mapping test to verify operation name, request model/provider, token usage and cache-read tokens, embedding dimensions, and Mastra-specific RAG embedding metadata.
Patch version and changeset documentation
.changeset/quiet-clouds-embed.md
Records a patch release for @mastra/otel-exporter documenting the fix to RAG embedding span metadata export.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • intojhanurag
  • epinzur
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title accurately describes the main fix: mapping RAG_EMBEDDING spans to GenAI embedding semantics in the otel-exporter. It follows imperative mood and concise naming conventions.
Linked Issues check ✅ Passed All primary objectives from #17914 are met: RAG_EMBEDDING maps to 'embeddings' operation, model-based span naming implemented, gen_ai attributes exported, SpanKind.CLIENT applied, and comprehensive tests added.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing RAG_EMBEDDING span handling in otel-exporter. No unrelated modifications to other modules or functionality detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dane-ai-mastra dane-ai-mastra Bot added the complexity: low Low-complexity PR label Jun 14, 2026
@dane-ai-mastra

dane-ai-mastra Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

PR triage

Linked issue check passed (#17914).

Mastra uses CodeRabbit for automated code reviews. Please address all feedback from CodeRabbit by either making changes to your PR or leaving a comment explaining why you disagree with the feedback. Since CodeRabbit is an AI, it may occasionally provide incorrect feedback.


PR complexity score

Factor Value Score impact
Files changed 5 +10
Lines changed 200 +12
Author merged PRs 11 -11
Test files changed Yes -10
Final score 1

Applied label: complexity: low


Changed test gate

Changed Test Gate is pending. The Changed Test Gate / changed-tests check will update the test label when it completes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@observability/otel-exporter/src/gen-ai-semantics.test.ts`:
- Around line 93-112: The test `should extract model, provider, usage, and RAG
metadata for embedding spans` uses a hardcoded literal model ID
`text-embedding-3-small` in the createRagEmbeddingSpan function call. Replace
this hardcoded model ID with a registered placeholder token from
docs/src/plugins/remark-model-tokens/models.ts to comply with the repo's coding
guidelines for model names and IDs in tests.

In `@observability/otel-exporter/src/span-converter.test.ts`:
- Around line 75-95: Replace the literal model IDs with placeholder tokens from
docs/src/plugins/remark-model-tokens/models.ts according to coding guidelines.
In the test case spanning lines 75-95 (the convertSpan test for RAG_EMBEDDING
spans), replace the hardcoded model value 'text-embedding-3-small' in the
attributes object at line 86 and the corresponding assertion at line 94 with an
appropriate placeholder token from the models.ts file. Apply the same approach
to all other test cases in the file that use literal model IDs, specifically in
the sections at lines 242-260 and 364-399, replacing all hardcoded model names
with registered placeholder tokens and updating their corresponding assertions
consistently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e75d497c-56ee-4943-8e23-376de6abbbb0

📥 Commits

Reviewing files that changed from the base of the PR and between 1b1c82d and 4c135ed.

📒 Files selected for processing (5)
  • .changeset/quiet-clouds-embed.md
  • observability/otel-exporter/src/gen-ai-semantics.test.ts
  • observability/otel-exporter/src/gen-ai-semantics.ts
  • observability/otel-exporter/src/span-converter.test.ts
  • observability/otel-exporter/src/span-converter.ts

Comment thread observability/otel-exporter/src/gen-ai-semantics.test.ts
Comment thread observability/otel-exporter/src/span-converter.test.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

complexity: low Low-complexity PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Map RAG_EMBEDDING spans to GenAI / Langfuse embedding observations

1 participant