Skip to content

gen_ai.operation.name attribute not set for AI SDK spans due to span name transformation timing #882

@obs-gh-trevorColby

Description

@obs-gh-trevorColby

Description

When using @traceloop/node-server-sdk with the Vercel AI SDK, the gen_ai.operation.name attribute is not being properly set on spans, even though other transformations (like gen_ai.prompt.0.content, gen_ai.completion.0.content, etc.) are working correctly.

Expected Behavior

For a span with original name ai.generateText, the gen_ai.operation.name attribute should be set to "chat" according to the transformOperationName function in ai-sdk-transformations.ts.

Actual Behavior

The gen_ai.operation.name attribute is not present on the span. Instead, only the original ai.operationId attribute remains with value "ai.generateText" as well as"operation.name" (missing the gen_ai prefix and with the original non-transformed operation name as well).

Root Cause Analysis

After investigating the code, I believe this is a timing issue:

  1. onSpanStart (line ~3326 in bundled index.js) calls transformAiSdkSpanNames(span) which transforms the span name from "ai.generateText" to "run.ai" or "<agentName>.agent"

  2. onSpanEnd calls transformAiSdkSpanAttributes(span) which eventually calls transformLLMSpans(span.attributes, span.name)

  3. transformOperationName checks if spanName.includes("generateText") to determine if it should set operationName = "chat"

  4. But by the time onSpanEnd runs, span.name has already been changed from "ai.generateText" to "run.ai", so the condition spanName.includes("generateText") fails and gen_ai.operation.name is never set.

Relevant Code

// In transformOperationName:
const transformOperationName = (attributes, spanName) => {
    if (!spanName)
        return;
    let operationName;
    if (spanName.includes("generateText") ||  // <-- This check fails because spanName is now "run.ai"
        spanName.includes("streamText") ||
        spanName.includes("generateObject") ||
        spanName.includes("streamObject")) {
        operationName = "chat";
    }
    // ...
};

Suggested Fix

Either:

  1. Store the original span name before transformation and use it in transformOperationName
  2. Move transformOperationName to run in onSpanStart before the span name is transformed
  3. Check ai.operationId attribute instead of (or in addition to) the span name

Environment

  • @traceloop/node-server-sdk: 0.22.6
  • ai (Vercel AI SDK): 5.0.108
  • Node.js: v20+

Reproduction

  1. Initialize traceloop with traceloop.initialize()
  2. Use Vercel AI SDK's generateText or streamText with experimental_telemetry: {isEnabled: true}
  3. Observe the exported spans - gen_ai.operation.name is missing while other gen_ai.* attributes are present

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions