Skip to content

feat(sdk): expose use_legacy_attributes via Traceloop.init()#4133

Open
dvirski wants to merge 1 commit into
mainfrom
dr/feat(sdk)-expose-use_legacy_attributes-via-Traceloop.init()
Open

feat(sdk): expose use_legacy_attributes via Traceloop.init()#4133
dvirski wants to merge 1 commit into
mainfrom
dr/feat(sdk)-expose-use_legacy_attributes-via-Traceloop.init()

Conversation

@dvirski
Copy link
Copy Markdown

@dvirski dvirski commented May 12, 2026

Fixes #3236.

Problem: use_legacy_attributes existed on every instrumentation but was
unreachable through the SDK — users were locked to legacy gen_ai.prompt/
gen_ai.completion span attributes with no way to opt into the new
event-based format.

Fix: thread use_legacy_attributes=True (default, no behaviour change) from
Traceloop.init() through TracerWrapper, init_instrumentations(), and all
8 instrumentations that support the flag: openai, anthropic, bedrock,
sagemaker, groq, langchain, together, watsonx.

Summary by CodeRabbit

  • New Features
    • Added use_legacy_attributes parameter to SDK initialization, enabling control over tracing attribute formatting. Defaults to True for backward compatibility. This setting propagates across all supported AI service instrumentors for consistent behavior.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

📝 Walkthrough

Walkthrough

The PR adds a use_legacy_attributes parameter to Traceloop.init() and threads it through the initialization chain to all supported instrumentors, enabling users to control legacy attribute formatting without manual setup.

Changes

Legacy Attributes Parameter Threading

Layer / File(s) Summary
Public API parameter
packages/traceloop-sdk/traceloop/sdk/__init__.py
Traceloop.init() gains a new use_legacy_attributes: bool = True parameter and forwards it to TracerWrapper via constructor argument.
Core initialization propagation
packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py
TracerWrapper.__new__ accepts use_legacy_attributes and passes it to init_instrumentations, which routes it through a centralized instrument selection loop to all active initializers.
Instrumentor implementations
packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py
Eight instrument initializers (init_openai_instrumentor, init_anthropic_instrumentor, init_langchain_instrumentor, init_together_instrumentor, init_bedrock_instrumentor, init_sagemaker_instrumentor, init_watsonx_instrumentor, init_groq_instrumentor) now accept the parameter and pass it to their corresponding OpenTelemetry instrumentor constructors.
Test coverage
packages/traceloop-sdk/tests/test_sdk_initialization.py
A new test test_use_legacy_attributes_false_propagates_to_instrumentors() verifies that calling Traceloop.init(use_legacy_attributes=False) propagates the setting to OpenAIConfig.use_legacy_attributes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

A rabbit hops through parameters with glee,
Threading use_legacy_attributes through the tree,
From API to wrapper to every instrumentor bright,
Each one now knows when to emit prompts just right! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% 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 The title accurately describes the main change: exposing use_legacy_attributes parameter through Traceloop.init() method.
Linked Issues check ✅ Passed The PR successfully addresses issue #3236 by exposing use_legacy_attributes parameter through Traceloop.init() and propagating it through TracerWrapper and init_instrumentations to eight supported instrumentations.
Out of Scope Changes check ✅ Passed All changes are directly related to the objective of exposing use_legacy_attributes via Traceloop.init(), with no extraneous modifications detected.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dr/feat(sdk)-expose-use_legacy_attributes-via-Traceloop.init()

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.

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Dvir Rezenman seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
packages/traceloop-sdk/tests/test_sdk_initialization.py (1)

232-253: 💤 Low value

Test correctly verifies propagation to OpenAI instrumentor.

The test properly isolates itself by saving/restoring the TracerWrapper instance and verifies that use_legacy_attributes=False reaches the OpenAI instrumentor configuration.

Consider adding complementary test coverage:

Optional test improvements
  1. Verify the default case: Test that when use_legacy_attributes is not specified (or set to True), the config defaults to True.

  2. Test multiple instrumentors: While testing OpenAI is representative, you could verify that the flag propagates to at least one other instrumentor (e.g., Anthropic or Groq) to ensure the pattern holds across different code paths.

Example for default case:

def test_use_legacy_attributes_defaults_to_true():
    """Verify use_legacy_attributes defaults to True for backward compatibility."""
    from opentelemetry.instrumentation.openai.shared.config import Config as OpenAIConfig
    
    _instance = None
    if hasattr(TracerWrapper, "instance"):
        _instance = TracerWrapper.instance
        del TracerWrapper.instance
    
    exporter = InMemorySpanExporter()
    Traceloop.init(
        exporter=exporter,
        disable_batch=True,
        # use_legacy_attributes not specified, should default to True
    )
    
    assert OpenAIConfig.use_legacy_attributes is True
    
    if _instance is not None:
        TracerWrapper.instance = _instance
🤖 Prompt for 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.

In `@packages/traceloop-sdk/tests/test_sdk_initialization.py` around lines 232 -
253, Add complementary tests: create
test_use_legacy_attributes_defaults_to_true() that mirrors
test_use_legacy_attributes_false_propagates_to_instrumentors but omits the
use_legacy_attributes argument when calling
Traceloop.init(exporter=InMemorySpanExporter(), disable_batch=True) and assert
OpenAIConfig.use_legacy_attributes is True; also add an additional test (e.g.,
test_use_legacy_attributes_propagates_to_other_instrumentor) that initializes
the SDK with use_legacy_attributes=False and asserts the same flag reached
another instrumentor's Config (e.g., AnthropicConfig or GroqConfig) to confirm
propagation; keep the same TracerWrapper instance save/restore pattern used in
the existing test to avoid global state leaks.
🤖 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.

Nitpick comments:
In `@packages/traceloop-sdk/tests/test_sdk_initialization.py`:
- Around line 232-253: Add complementary tests: create
test_use_legacy_attributes_defaults_to_true() that mirrors
test_use_legacy_attributes_false_propagates_to_instrumentors but omits the
use_legacy_attributes argument when calling
Traceloop.init(exporter=InMemorySpanExporter(), disable_batch=True) and assert
OpenAIConfig.use_legacy_attributes is True; also add an additional test (e.g.,
test_use_legacy_attributes_propagates_to_other_instrumentor) that initializes
the SDK with use_legacy_attributes=False and asserts the same flag reached
another instrumentor's Config (e.g., AnthropicConfig or GroqConfig) to confirm
propagation; keep the same TracerWrapper instance save/restore pattern used in
the existing test to avoid global state leaks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cc9db1b3-3297-4a1c-bd8b-32022889f21c

📥 Commits

Reviewing files that changed from the base of the PR and between 6d3e696 and 7541daa.

⛔ Files ignored due to path filters (2)
  • packages/sample-app/uv.lock is excluded by !**/*.lock
  • packages/traceloop-sdk/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • packages/traceloop-sdk/tests/test_sdk_initialization.py
  • packages/traceloop-sdk/traceloop/sdk/__init__.py
  • packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py

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.

🐛 Bug Report: No way to set use_legacy_attributes using TraceLoop.init()

2 participants