Skip to content

Conversation

@galkleinman
Copy link
Contributor

@galkleinman galkleinman commented Nov 30, 2025

Important

Enhance AI SDK by integrating agent metadata into span naming and attributes, supporting generateObject and streamText operations, and adding cache token transformations.

  • Behavior:
    • Agent metadata now influences span naming and attributes in AI SDK, using agent names when metadata is present.
    • Supports generateObject and streamText operations with agent metadata.
  • Transformations:
    • transformLLMSpans() in ai-sdk-transformations.ts updated to handle cache token transformations and agent metadata.
    • New functions transformCacheCreationInputTokens(), transformCacheReadInputTokens(), and transformCachedInputTokens() added for cache token handling.
  • Tests:
    • Added tests in ai-sdk-agent-integration.test.ts and ai-sdk-integration.test.ts to verify agent name propagation and cache token transformations.
    • Updated test recordings in recordings/ to reflect new span naming and cache handling.

This description was created by Ellipsis for cc54052. You can customize this summary. It will automatically update as commits are pushed.


Summary by CodeRabbit

  • New Features

    • Agent metadata now drives top-level span naming and agent-related span attributes for AI SDK flows.
    • New public span attributes for cache token metrics added (cache creation/read tokens).
  • Tests

    • Added and updated test cases and recordings to verify agent-based span naming, cache-token transformations, and streaming/object generation behaviors.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 30, 2025

Walkthrough

Adds top-level AI span renaming to use agent metadata, new AI span type constants (generateObject/streamText/streamObject), cache-related token attribute transformations, expanded semantic attributes, and test/fixture additions for agent-aware span naming and cache-token handling.

Changes

Cohort / File(s) Summary
Test Fixtures
packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/*, packages/traceloop-sdk/recordings/Test-AI-SDK-Integration-with-Recording_156038438/*
Added and updated multiple HAR recordings used as fixtures (new/updated timestamps, IDs, streaming events, and response payloads) covering agent-metadata scenarios and cache-token prompt-caching interactions.
Span Transformation Logic
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
Adds new AI span constants (ai.streamText, ai.generateObject, ai.streamObject), introduces TOP_LEVEL_AI_SPANS, implements agent-aware top-level span renaming, extends telemetry metadata handling to mark AGENT spans on top-level AI spans, and adds cache-token transformation helpers invoked during LLM span transforms.
Semantic Conventions
packages/ai-semantic-conventions/src/SemanticAttributes.ts
Adds two public span attribute constants: LLM_USAGE_CACHE_CREATION_INPUT_TOKENS and LLM_USAGE_CACHE_READ_INPUT_TOKENS mapped to gen_ai.usage.* keys.
Agent Integration Tests
packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
Expands imports to include generateObject and streamText; updates expectations so root spans use agent names when agent metadata present; adds tests for generateObject/streamText agent scenarios and a default no-agent case; adds forceFlush calls before span assertions.
Transformation Unit Tests
packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
Adds test suite for cache-token attribute transformations (creation/read/cached tokens), updates root-span simulation to use an agent name, and validates removal/mapping of legacy token attributes and propagation of totals.
Integration Tests
packages/traceloop-sdk/test/ai-sdk-integration.test.ts
Adds integration test verifying capture and transformation of cache tokens through two sequential OpenAI calls (cache creation and cache read) and assertions on transformed attributes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review transformAiSdkSpanNames and transformTelemetryMetadata logic for correct identification of top-level spans and safe fallbacks when agent metadata is absent.
  • Inspect cache-token transformation helpers and ensure token totals and attribute deletions/mappings are correct and consistent with SemanticAttributes.
  • Check updated tests (unit and integration) for proper setup/teardown (forceFlush, exporter resets) and that HAR fixtures match expected HTTP shapes.

Possibly related PRs

Suggested reviewers

  • nirga
  • avivhalfon

Poem

🐰 I hopped through spans with a curious twitch,
Gave each AI root its very own badge—and a stitch.
Tokens counted, names passed down like a crown,
Streams and objects now wear the agent gown.
Hooray—tracing hops forward, not backward a stitch!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(ai-sdk): agent name in span names when available' directly describes the main change: propagating agent names to trace span names in the AI SDK when agent metadata is present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch gk/ai-sdk-fixes

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

galkleinman and others added 5 commits November 30, 2025 17:46
- Keep original span names (ai.generateText, ai.streamText, etc.) when no agent metadata
- Only transform top-level spans to agent name when agent metadata is present
- Transform child spans (text.generate, object.generate) to OpenLLMetry format
- Updated unit test to pass agent name instead of deprecated "run.ai" name
- Added tests for generateObject and streamText with agent metadata
- Updated test recordings to match new behavior

Fixes customer complaint where generic "AI" or "run" names appeared instead of actual agent names

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@galkleinman galkleinman marked this pull request as ready for review November 30, 2025 16:02
Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed everything up to ec097de in 2 minutes and 25 seconds. Click for details.
  • Reviewed 965 lines of code in 7 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 draft 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.
1. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:515
  • Draft comment:
    Bug: In transformAiSdkSpanNames the agent name is retrieved using the key constructed from AI_TELEMETRY_METADATA_PREFIX ('ai.telemetry.metadata.agent'), but transformTelemetryMetadata deletes these keys and instead sets the agent name on the GEN_AI_AGENT_NAME attribute. Use span.attributes[SpanAttributes.GEN_AI_AGENT_NAME] instead.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 20% vs. threshold = 50% The comment is making an assumption about execution order that I cannot verify from this file alone. The two functions are separate exports - transformAiSdkSpanNames and transformAiSdkSpanAttributes. Without seeing where these are called in the broader codebase, I cannot determine if transformTelemetryMetadata (which deletes the metadata prefix keys and sets GEN_AI_AGENT_NAME) runs before or after transformAiSdkSpanNames. The comment could be correct, but it requires cross-file context to verify. According to the rules, I should delete comments that require more context to understand. I'm assuming the comment is wrong because I can't verify the execution order, but the reviewer might have knowledge of the calling code that shows transformTelemetryMetadata does run first. The comment provides a specific, actionable fix which suggests the reviewer has investigated this. Even if the reviewer has investigated this, the rule states I need STRONG EVIDENCE from the diff itself. The execution order is not clear from this file alone, and understanding this requires seeing other files or parts of the codebase. This falls under "cross-file issues" which I should ignore. Delete this comment because verifying whether it's correct requires understanding the execution order of these functions across multiple files, which is cross-file context I don't have access to in this diff.

Workflow ID: wflow_PbFsV69q7gHjvGZo

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Changed test name from "should use default 'run.ai' span name" to
"should preserve original AI SDK span name" to accurately reflect that
we now preserve the original AI SDK span names (ai.generateText, etc.)
when no agent metadata is provided, rather than transforming to "run.ai"

Created new test recording to match updated test name

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)

430-443: Deduplicate the list of top-level AI span names

You now maintain two separate arrays of top-level AI span identifiers:

  • An inline topLevelSpanNames inside transformTelemetryMetadata (Lines 430-438).
  • The module-level TOP_LEVEL_AI_SPANS (Lines 501-507).

Keeping these in sync is error-prone when adding new top-level span types. Consider reusing TOP_LEVEL_AI_SPANS in transformTelemetryMetadata (or centralizing the list elsewhere) to avoid future drift.

Also applies to: 501-507

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9e28821 and ec097de.

📒 Files selected for processing (7)
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har (10 hunks)
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-use-agent-name-for-generateObject-with-agent-metadata_1744675110/recording.har (1 hunks)
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-use-agent-name-for-streamText-with-agent-metadata_4019571713/recording.har (1 hunks)
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-use-default-run-ai-span-name-when-no-agent-metadata-is-provided_1300307112/recording.har (1 hunks)
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (3 hunks)
  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts (4 hunks)
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Import AI/LLM semantic attribute constants from @traceloop/ai-semantic-conventions rather than hardcoding strings

Files:

  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
packages/traceloop-sdk/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/traceloop-sdk/**/*.{ts,tsx}: Use the provided decorators (@workflow, @task, @agent) for workflow/task/agent spans instead of re-implementing them
For manual LLM operations, use trace.withLLMSpan from @traceloop/node-server-sdk

Files:

  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
**/recordings/**

📄 CodeRabbit inference engine (CLAUDE.md)

Store HTTP interaction recordings for tests under recordings/ directories for Polly.js replay

Files:

  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-use-agent-name-for-generateObject-with-agent-metadata_1744675110/recording.har
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-use-default-run-ai-span-name-when-no-agent-metadata-is-provided_1300307112/recording.har
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-use-agent-name-for-streamText-with-agent-metadata_4019571713/recording.har
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings

Applied to files:

  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-use-default-run-ai-span-name-when-no-agent-metadata-is-provided_1300307112/recording.har
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap

Applied to files:

  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk

Applied to files:

  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/ai-semantic-conventions/src/SemanticAttributes.ts : Define all AI/LLM span attribute constants in packages/ai-semantic-conventions/src/SemanticAttributes.ts

Applied to files:

  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them

Applied to files:

  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-12T13:58:25.583Z
Learnt from: galzilber
Repo: traceloop/openllmetry-js PR: 643
File: packages/traceloop-sdk/src/lib/client/dataset/column.ts:41-47
Timestamp: 2025-08-12T13:58:25.583Z
Learning: In packages/traceloop-sdk/src/lib/client/dataset/column.ts, when the user mentioned "its working there is transform func", they were confirming that the response transformer is functioning correctly and converting snake_case API responses to camelCase, which means the Column class should access camelCase properties (createdAt, updatedAt) from the transformed ColumnResponse data.

Applied to files:

  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
🧬 Code graph analysis (2)
packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (1)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
  • transformLLMSpans (459-473)
packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts (2)
packages/traceloop-sdk/src/lib/tracing/decorators.ts (1)
  • tool (289-295)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
  • SpanAttributes (23-75)
🔇 Additional comments (7)
packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-use-default-run-ai-span-name-when-no-agent-metadata-is-provided_1300307112/recording.har (1)

1-172: Test fixture properly structured and placed.

The HAR recording is correctly formatted for Polly.js replay, captures a realistic OpenAI API interaction with function-calling tools, and aligns with the test scenario ("no agent metadata, default run.ai span name"). Placement in the recordings/ directory follows coding guidelines.

packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-use-agent-name-for-streamText-with-agent-metadata_4019571713/recording.har (1)

1-144: HAR fixture structure looks correct

Recording follows the existing Polly HAR structure and matches the expected OpenAI streaming response shape; fine as a test fixture.

packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (1)

1777-1780: Root-span simulation now matches production behavior

Passing "research_assistant" as spanName into transformLLMSpans correctly mirrors the post-name-transformation root span and validates the new agent-root logic.

packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har (1)

23-167: Updated HAR recording is structurally consistent

Only identifiers, cookie values, and timing/header fields changed; JSON structure is intact and suitable for Polly replay.

packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-use-agent-name-for-generateObject-with-agent-metadata_1744675110/recording.har (1)

1-172: New generateObject HAR fixture is well-formed

Recording cleanly captures the json_schema-based generateObject call and response; appropriate as a Polly fixture.

packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)

7-24: Agent-aware span naming for top-level vs child AI spans looks correct

The extended constants and updated transformAiSdkSpanNames cleanly separate concerns:

  • Top-level AI spans (ai.generateText, ai.streamText, ai.generateObject, ai.streamObject) are renamed to the agent name when ai.telemetry.metadata.agent is present, leaving them as ai.* when no agent metadata is provided.
  • Child spans (*.doGenerate / *.doStream) still map to internal names like text.generate, object.generate, text.stream, object.stream, so downstream processing remains stable.
  • Combined with passing span.name into transformLLMSpans, this gives you root spans named after the agent while preserving consistent child span naming.

The behavior aligns with the new tests and the stated PR objective.

Also applies to: 501-527

packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts (1)

20-21: Tests correctly cover agent naming for generateText/generateObject/streamText

The three tests accurately exercise:

  • Default root naming ("ai.generateText") when no agent metadata is provided
  • Agent-named root spans (with AGENT span kind and entity name) for generateObject and streamText when agent metadata is present
  • Proper export flushing via traceloop.forceFlush() before assertions

The ai package dependency (^5.0.22) is properly configured and supports generateObject, streamText, and the experimental_telemetry options used throughout.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed 3bc47c5 in 44 seconds. Click for details.
  • Reviewed 119 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 2 draft 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.
1. packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-preserve-original-AI-SDK-span-name-when-no-agent-metadata-is-provided_1735519430/recording.har:3
  • Draft comment:
    Updated the recording name and associated timestamps/cookie values to reflect the new behavior, i.e. preserving the original AI SDK span name when no agent metadata is provided. Ensure these fixture updates stay in sync with expected behavior.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts:236
  • Draft comment:
    Renamed test description from 'use default "run.ai" span name' to 'preserve original AI SDK span name' to better reflect the intended behavior when agent metadata is missing.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_rf6T22D6rzzwLjcW

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-preserve-original-AI-SDK-span-name-when-no-agent-metadata-is-provided_1735519430/recording.har (1)

1-172: HAR fixture is well-formed and correctly placed; consider optional sanitization of opaque IDs

The HAR looks structurally valid for Polly.js (HAR 1.2, single POST entry, realistic OpenAI request/response) and the path under recordings/ matches the intended usage for HTTP interaction fixtures. It also correctly represents a “no agent metadata” scenario that your tests rely on.

If you want to further harden/simplify fixtures, you could optionally normalize or redact opaque values like cf-ray, x-request-id, openai-project, _cfuvid, and similar IDs/cookies to reduce churn on re-recording and avoid storing third-party identifiers verbatim in the repo. Not strictly necessary, but worth considering for future recordings.

As per coding guidelines, this aligns with the requirement that **/recordings/** store Polly.js HTTP interaction recordings.

packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts (1)

239-318: Good fallback test for no-agent case, with minor tool duplication

This test nicely covers the case where AI SDK spans should retain the original ai.generateText name and lack agent-related attributes when no agent metadata is supplied. The only nit is that the calculator tool definition duplicates the one in the first test; consider extracting a shared helper to reduce duplication and keep future changes to the tool logic in one place.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ec097de and 3bc47c5.

📒 Files selected for processing (2)
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-preserve-original-AI-SDK-span-name-when-no-agent-metadata-is-provided_1735519430/recording.har (1 hunks)
  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/recordings/**

📄 CodeRabbit inference engine (CLAUDE.md)

Store HTTP interaction recordings for tests under recordings/ directories for Polly.js replay

Files:

  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-preserve-original-AI-SDK-span-name-when-no-agent-metadata-is-provided_1735519430/recording.har
packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Import AI/LLM semantic attribute constants from @traceloop/ai-semantic-conventions rather than hardcoding strings

Files:

  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
packages/traceloop-sdk/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/traceloop-sdk/**/*.{ts,tsx}: Use the provided decorators (@workflow, @task, @agent) for workflow/task/agent spans instead of re-implementing them
For manual LLM operations, use trace.withLLMSpan from @traceloop/node-server-sdk

Files:

  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to **/recordings/** : Store HTTP interaction recordings for tests under recordings/ directories for Polly.js replay

Applied to files:

  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-preserve-original-AI-SDK-span-name-when-no-agent-metadata-is-provided_1735519430/recording.har
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings

Applied to files:

  • packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-preserve-original-AI-SDK-span-name-when-no-agent-metadata-is-provided_1735519430/recording.har
  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them

Applied to files:

  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap

Applied to files:

  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk

Applied to files:

  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/ai-semantic-conventions/src/SemanticAttributes.ts : Define all AI/LLM span attribute constants in packages/ai-semantic-conventions/src/SemanticAttributes.ts

Applied to files:

  • packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
🧬 Code graph analysis (1)
packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts (2)
packages/traceloop-sdk/src/lib/tracing/decorators.ts (1)
  • tool (289-295)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
  • SpanAttributes (23-75)
🔇 Additional comments (4)
packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts (4)

20-20: Expanded ai imports correctly match new usages

Importing generateObject, streamText, and tool alongside generateText lines up with how the tests use these helpers later in the file; no issues here.


144-147: Root span selection now validates agent-based naming

Finding the root span by the agent name and asserting its existence with a clear message directly exercises the new naming behavior for top-level AI spans when agent metadata is present; this is an appropriate and focused expectation.

Also applies to: 158-161


320-378: Solid coverage for generateObject agent naming and attributes

This test cleanly verifies that generateObject spans are renamed to the agent name and carry the expected GEN_AI_AGENT_NAME, TRACELOOP_SPAN_KIND = "agent", and TRACELOOP_ENTITY_NAME attributes when agent metadata is present, which aligns with the intended transformation behavior and uses SpanAttributes constants instead of raw strings, as per semantic-conventions guidance.


380-437: Streaming scenario is well-covered for agent-based span naming

The streamText test fully consumes the stream and then asserts that the root span is renamed to the agent and tagged with the correct agent-related attributes, giving good coverage of the streaming path for the new naming logic.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed 22b79f9 in 1 minute and 19 seconds. Click for details.
  • Reviewed 1136 lines of code in 6 files
  • Skipped 0 files when reviewing.
  • Skipped posting 8 draft 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.
1. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:35
  • Draft comment:
    New constants for cache tokens are defined. Consider adding explicit type annotations for clarity.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:374
  • Draft comment:
    transformCacheCreationInputTokens correctly maps and removes the legacy attribute. Consider adding a comment on expected value type (e.g. number or string).
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
3. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:383
  • Draft comment:
    transformCacheReadInputTokens implementation is clear and follows the pattern. No issues detected.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
4. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:392
  • Draft comment:
    transformCachedInputTokens properly overwrites the cache read attribute if present; the ordering of these functions is critical.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
5. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:501
  • Draft comment:
    The order of cache token transformation calls (creation, read, then cached) ensures that 'cachedInputTokens' takes precedence. Consider adding an inline comment explaining this ordering for future maintainability.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
6. packages/traceloop-sdk/test/ai-sdk-integration.test.ts:273
  • Draft comment:
    New integration test for cache tokens transformation is comprehensive; it verifies removal of old keys and correct mapping of cache creation and read tokens.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
7. packages/traceloop-sdk/test/ai-sdk-transformations.test.ts:942
  • Draft comment:
    The new test suite for cache tokens in ai-sdk-transformations covers multiple edge cases, including overriding and string values. Excellent coverage.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
8. packages/traceloop-sdk/test/ai-sdk-transformations.test.ts:1964
  • Draft comment:
    Overall, the new attribute transformation tests (including telemetry metadata and tool calls) integrate well with existing functionality. No critical issues found.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_NAbAr5c82Wm42HHN

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed cc54052 in 1 minute and 37 seconds. Click for details.
  • Reviewed 162 lines of code in 4 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 draft 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.
1. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:431
  • Draft comment:
    Good use of telemetry metadata to extract and attach agent info. Consider adding logging or error details in the catch blocks to help diagnose parsing issues in production.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:548
  • Draft comment:
    Span name transformation uses agent metadata for top-level spans. It might be helpful to clarify in comments that child spans retain their mapped names when agent metadata isn’t applied.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
3. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:397
  • Draft comment:
    When both 'ai.usage.cacheReadInputTokens' and 'ai.usage.cachedInputTokens' are present, the latter overwrites the former (last write wins). Confirm this behavior is intentional as per tests.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_lEnRXLusaNUq0zNd

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (1)

943-1170: Cache token tests look correct, but some names/comments are misleading

The new cache token tests exercise all relevant paths (creation, read, OpenAI cachedInputTokens, coexistence, zero/string values, and integration) and match the implementation of the cache transforms and calculateTotalTokens.

Two minor clarity issues you may want to tidy up:

  • Test name vs behavior mismatch:
    • it("should prefer cacheReadInputTokens over cachedInputTokens when both present", ...) actually verifies that cachedInputTokens wins (last write wins) and the inline comment also explains that. Renaming the test (e.g. to “should prefer cachedInputTokens when both present (last write wins)”) would avoid confusion.
  • Comment vs behavior mismatch:
    • In it("should not modify attributes when cache token attributes are not present", ...), the comment says “Should preserve input tokens and add total tokens”, but with only input tokens present calculateTotalTokens intentionally does not set a total. The assertions don’t depend on this, so either adjust or drop that part of the comment.

These are cosmetic only; the assertions correctly reflect the current transform behavior.

packages/traceloop-sdk/test/ai-sdk-integration.test.ts (1)

273-446: Strong coverage for prompt-cache token transformation, with minor coupling to fixture token count

This test does a good job validating both directions of the cache token mapping: it forces a cacheable prompt, checks gen_ai.usage.* input/output and cache-* attributes via SpanAttributes, and asserts that the legacy ai.usage.* cache keys are fully stripped from spans. Resetting the exporter between calls and guarding the cache-token assertions behind existence checks keeps it robust across providers. As per coding guidelines, using SpanAttributes for the gen_ai.* keys is exactly what we want here.

One nit: the strict expectation of 6900 cache-read tokens ties the test to a particular HAR/model/tokenizer. That’s fine for a recorded fixture, but if recordings are regenerated or models change you’ll need to update this constant. If you want to reduce that coupling, you could keep only the > 0 check or assert a looser lower bound.

packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)

7-24: Agent-aware span naming for top-level AI SDK spans looks correct; consider de-duplicating the top-level list

The new constants and HANDLED_SPAN_NAMES entries for ai.streamText, ai.generateObject, and ai.streamObject, together with TOP_LEVEL_AI_SPANS and the updated transformAiSdkSpanNames, give you the intended behavior:

  • Top-level AI spans (ai.generateText/ai.streamText/ai.generateObject/ai.streamObject) are renamed to the agent name only when ai.telemetry.metadata.agent is present.
  • Child spans (*.doGenerate/*.doStream) are always normalized to text.generate, object.generate, text.stream, object.stream, preserving the previous observability surface.

This aligns with the PR’s goal and keeps non-agent spans from being renamed unexpectedly. As per coding guidelines, you’re correctly keeping semantic attribute strings out of here and delegating them to SpanAttributes elsewhere.

One small maintainability improvement: transformTelemetryMetadata defines its own topLevelSpanNames array with the same four values as TOP_LEVEL_AI_SPANS. Reusing TOP_LEVEL_AI_SPANS there would avoid the risk of future drift when new top-level operations are added.

Also applies to: 540-565

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3bc47c5 and cc54052.

📒 Files selected for processing (6)
  • packages/ai-semantic-conventions/src/SemanticAttributes.ts (1 hunks)
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Integration-with-Recording_156038438/should-capture-and-transform-cache-tokens-from-OpenAI-with-prompt-caching_4027203422/recording.har (1 hunks)
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Integration-with-Recording_156038438/should-capture-and-transform-cache-tokens-from-OpenAI-with-prompt-caching_4027203422/recording.har.backup (1 hunks)
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (6 hunks)
  • packages/traceloop-sdk/test/ai-sdk-integration.test.ts (1 hunks)
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Integration-with-Recording_156038438/should-capture-and-transform-cache-tokens-from-OpenAI-with-prompt-caching_4027203422/recording.har
  • packages/traceloop-sdk/recordings/Test-AI-SDK-Integration-with-Recording_156038438/should-capture-and-transform-cache-tokens-from-OpenAI-with-prompt-caching_4027203422/recording.har.backup
🧰 Additional context used
📓 Path-based instructions (3)
packages/ai-semantic-conventions/src/SemanticAttributes.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Define all AI/LLM span attribute constants in packages/ai-semantic-conventions/src/SemanticAttributes.ts

Files:

  • packages/ai-semantic-conventions/src/SemanticAttributes.ts
packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Import AI/LLM semantic attribute constants from @traceloop/ai-semantic-conventions rather than hardcoding strings

Files:

  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
  • packages/traceloop-sdk/test/ai-sdk-integration.test.ts
packages/traceloop-sdk/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/traceloop-sdk/**/*.{ts,tsx}: Use the provided decorators (@workflow, @task, @agent) for workflow/task/agent spans instead of re-implementing them
For manual LLM operations, use trace.withLLMSpan from @traceloop/node-server-sdk

Files:

  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
  • packages/traceloop-sdk/test/ai-sdk-integration.test.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/ai-semantic-conventions/src/SemanticAttributes.ts : Define all AI/LLM span attribute constants in packages/ai-semantic-conventions/src/SemanticAttributes.ts
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/ai-semantic-conventions/src/SemanticAttributes.ts : Define all AI/LLM span attribute constants in packages/ai-semantic-conventions/src/SemanticAttributes.ts

Applied to files:

  • packages/ai-semantic-conventions/src/SemanticAttributes.ts
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings

Applied to files:

  • packages/ai-semantic-conventions/src/SemanticAttributes.ts
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
  • packages/traceloop-sdk/test/ai-sdk-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap

Applied to files:

  • packages/ai-semantic-conventions/src/SemanticAttributes.ts
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk

Applied to files:

  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them

Applied to files:

  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
🧬 Code graph analysis (3)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
  • SpanAttributes (23-78)
packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (2)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
  • transformLLMSpans (495-512)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
  • SpanAttributes (23-78)
packages/traceloop-sdk/test/ai-sdk-integration.test.ts (1)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
  • SpanAttributes (23-78)
🔇 Additional comments (4)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)

38-40: Cache token span attributes are consistent and correctly scoped

The new cache creation/read attributes follow the existing gen_ai.usage.* convention and are correctly centralized in SpanAttributes, matching how downstream transforms consume them. This aligns with the guidance to define AI/LLM span attribute constants here.

packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (1)

2006-2008: Agent metadata test now accurately simulates production spanName flow

Passing "research_assistant" as the spanName argument to transformLLMSpans matches the real pipeline where transformAiSdkSpanNames renames the top-level span before attribute transformation. This keeps the agent root-span test aligned with runtime behavior.

packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (2)

35-38: Cache token transformations correctly normalize AI SDK attributes to gen_ai cache usage attributes

The new cache-related constants and transformer functions cleanly map AI SDK–specific usage fields into the semantic gen_ai.usage.* space:

  • ai.usage.cacheCreationInputTokensSpanAttributes.LLM_USAGE_CACHE_CREATION_INPUT_TOKENS.
  • ai.usage.cacheReadInputTokensSpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS.
  • ai.usage.cachedInputTokens (OpenAI-specific) → SpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS.

Each transformer deletes the legacy ai.usage.* key after mapping, and transformLLMSpans calls them before calculateTotalTokens, so cache tokens don’t interfere with the standard input/output token sum. This matches the semantics exercised in the new integration test and keeps all externally consumed keys on the SpanAttributes surface. Based on learnings, this is the right place to centralize these attribute mappings.

Also applies to: 375-405, 506-508


466-483: Agent span-kind logic now correctly scopes AGENT to top-level AI spans

The updated transformTelemetryMetadata behavior—always setting SpanAttributes.GEN_AI_AGENT_NAME when an agent metadata key is present, but only marking TRACELOOP_SPAN_KIND = AGENT (and TRACELOOP_ENTITY_NAME) when the span is top-level (original AI span name or renamed to the agent) — cleanly distinguishes agent root spans from their children. This keeps downstream analysis from over-tagging nested LLM/tool spans while still propagating the agent name as context to all spans via GEN_AI_AGENT_NAME. The logic is sound and lines up with the agent-aware naming introduced in transformAiSdkSpanNames.

}
};

const transformCacheCreationInputTokens = (
Copy link
Member

Choose a reason for hiding this comment

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

@galkleinman maybe we can just transform any ai.usage. prefix to gen_ai.usage.?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I prefer the explicity. it makes our life easier understanding what should be published and what not.

if (span.name in HANDLED_SPAN_NAMES) {
span.updateName(HANDLED_SPAN_NAMES[span.name]);
// Check if this is a top-level AI span with agent metadata
const agentName = span.attributes[`${AI_TELEMETRY_METADATA_PREFIX}agent`];
Copy link
Member

Choose a reason for hiding this comment

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

I think there's already a method for checking / extracting the agent name

}
if (span.name in HANDLED_SPAN_NAMES) {
span.updateName(HANDLED_SPAN_NAMES[span.name]);
// Check if this is a top-level AI span with agent metadata
Copy link
Member

Choose a reason for hiding this comment

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

nit: redundant comment (this entire section is overly commented which reduces readability)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants