fix: check ai.operationId attribute for operation name transformation#891
fix: check ai.operationId attribute for operation name transformation#891obs-gh-trevorColby wants to merge 2 commits intotraceloop:mainfrom
Conversation
The transformOperationName function checks the span name to determine the gen_ai.operation.name attribute. However, by the time this function runs in onSpanEnd, the span name has already been transformed (e.g., from "ai.generateText" to "run.ai") by transformAiSdkSpanNames in onSpanStart. This means the check for 'generateText', 'streamText', etc. never matches, and the gen_ai.operation.name attribute is never set to 'chat'. This fix checks the ai.operationId attribute first, which is set by the Vercel AI SDK and contains the original operation ID (e.g., "ai.generateText"). This allows the function to correctly identify the operation type. Fixes traceloop#882
|
|
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdded Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Important
Looks good to me! 👍
Reviewed everything up to e9ba33a in 13 seconds. Click for details.
- Reviewed
53lines of code in1files - Skipped
0files when reviewing. - Skipped posting
0draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
Workflow ID: wflow_RYsirwZNEWXy8dqr
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts`:
- Around line 508-520: operationId (from AI_OPERATION_ID) may be non-string
which makes nameToCheck.includes(...) throw; guard and coerce before using
includes by ensuring operationId is a string (e.g., check typeof operationId ===
"string" or coerce with String(operationId)) and only set nameToCheck to
operationId when it's a string, otherwise fall back to spanName, then run the
existing includes checks on nameToCheck; update the logic around
AI_OPERATION_ID, operationId, nameToCheck and the includes checks to perform
this type guard.
- Around line 505-508: Add the AI_OPERATION_ID constant to the SpanAttributes
export in SemanticAttributes.ts (e.g., add AI_OPERATION_ID: "ai.operationId" to
the SpanAttributes object/type) and then update ai-sdk-transformations.ts to
import that constant instead of using the hardcoded string; replace the local
const AI_OPERATION_ID = "ai.operationId" with an import of AI_OPERATION_ID from
`@traceloop/ai-semantic-conventions` and use that imported symbol when reading
attributes[AI_OPERATION_ID] in the existing logic.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
| // Check ai.operationId attribute first (set by Vercel AI SDK) | ||
| // This is more reliable since span name may have been transformed already | ||
| const AI_OPERATION_ID = "ai.operationId"; | ||
| const operationId = attributes[AI_OPERATION_ID] as string | undefined; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, locate the ai-semantic-conventions package
find . -type d -name "ai-semantic-conventions" | head -5Repository: traceloop/openllmetry-js
Length of output: 102
🏁 Script executed:
# List files in ai-semantic-conventions to understand its structure
git ls-files packages/ai-semantic-conventions/ | head -20Repository: traceloop/openllmetry-js
Length of output: 451
🏁 Script executed:
# Search for operationId references in ai-semantic-conventions
rg -n "operationId" packages/ai-semantic-conventions/ -SRepository: traceloop/openllmetry-js
Length of output: 50
🏁 Script executed:
# Check the current imports in the file being reviewed
head -30 packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.tsRepository: traceloop/openllmetry-js
Length of output: 994
🏁 Script executed:
# Check the SemanticAttributes.ts in ai-semantic-conventions to see what constants are defined
cat packages/ai-semantic-conventions/src/SemanticAttributes.ts | head -100Repository: traceloop/openllmetry-js
Length of output: 4224
🏁 Script executed:
# Look for all references to operationId in the entire repository
rg -n "operationId" --type ts --type tsx -SRepository: traceloop/openllmetry-js
Length of output: 95
🏁 Script executed:
# Check the specific lines (505-508) in the file being reviewed
sed -n '500,520p' packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.tsRepository: traceloop/openllmetry-js
Length of output: 805
🏁 Script executed:
# Search for all content in SemanticAttributes.ts
cat packages/ai-semantic-conventions/src/SemanticAttributes.tsRepository: traceloop/openllmetry-js
Length of output: 4520
🏁 Script executed:
# Search for operationId in all TypeScript files
rg -n "operationId" -t tsRepository: traceloop/openllmetry-js
Length of output: 851
🏁 Script executed:
# Check the imports in ai-semantic-conventions index.ts
cat packages/ai-semantic-conventions/src/index.tsRepository: traceloop/openllmetry-js
Length of output: 845
Add ai.operationId constant to @traceloop/ai-semantic-conventions and import it here.
This file must import AI/LLM semantic attribute constants from @traceloop/ai-semantic-conventions rather than hardcoding strings. The "ai.operationId" attribute is currently hardcoded at line 507. Add this constant to SpanAttributes in packages/ai-semantic-conventions/src/SemanticAttributes.ts (e.g., AI_OPERATION_ID: "ai.operationId"), then import and use it here to comply with the guideline.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts` around
lines 505 - 508, Add the AI_OPERATION_ID constant to the SpanAttributes export
in SemanticAttributes.ts (e.g., add AI_OPERATION_ID: "ai.operationId" to the
SpanAttributes object/type) and then update ai-sdk-transformations.ts to import
that constant instead of using the hardcoded string; replace the local const
AI_OPERATION_ID = "ai.operationId" with an import of AI_OPERATION_ID from
`@traceloop/ai-semantic-conventions` and use that imported symbol when reading
attributes[AI_OPERATION_ID] in the existing logic.
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
Outdated
Show resolved
Hide resolved
The ai.operationId attribute may be non-string in some cases, which would cause nameToCheck.includes() to throw a runtime error. This fix adds a proper type guard to ensure operationId is a string before using it, falling back to spanName if it's not a string.
Summary
This PR fixes an issue where the
gen_ai.operation.nameattribute was not being set for AI SDK spans due to a timing bug in the span name transformation.Problem
The
transformOperationNamefunction checks the span name to determine thegen_ai.operation.nameattribute (e.g., "chat" for generateText operations). However, by the time this function runs inonSpanEnd, the span name has already been transformed bytransformAiSdkSpanNamesinonSpanStart.Transformation timeline:
onSpanStart→transformAiSdkSpanNamesruns → span name changes from"ai.generateText"to"run.ai"onSpanEnd→transformOperationNameruns → checks span name for"generateText"→ never matchesBecause the span name has already been transformed to
"run.ai", the check for"generateText"fails andgen_ai.operation.nameis never set.Solution
This fix checks the
ai.operationIdattribute first, which is set by the Vercel AI SDK and contains the original operation ID (e.g.,"ai.generateText"). This attribute is not transformed and reliably contains the original operation identifier.Updated logic:
ai.operationIdattribute (set by Vercel AI SDK, contains original operation ID)ai.operationIdis not availableExample
Before (broken)
After (fixed)
Backwards Compatibility
ai.operationIdis not presentnameToCheckandspanNamefor.toolsuffix)Related Issue
Fixes #882
Pull Request opened by Augment Code with guidance from the PR author
Important
Fixes
gen_ai.operation.namesetting by checkingai.operationIdbefore span name intransformOperationNamefunction.transformOperationNameinai-sdk-transformations.tsto checkai.operationIdbefore span name for settinggen_ai.operation.name.gen_ai.operation.nameis set correctly even if span name is transformed.ai.operationIdfirst, falls back to span name if not available.generateText,streamText,generateObject,streamObject, and tool calls.ai-sdk-transformations.tsfor clarity.This description was created by
for e9ba33a. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit