Skip to content

Fix(anthropic)Async#3744

Merged
nina-kollman merged 12 commits intotraceloop:mainfrom
elinacse:anthropic
Mar 8, 2026
Merged

Fix(anthropic)Async#3744
nina-kollman merged 12 commits intotraceloop:mainfrom
elinacse:anthropic

Conversation

@elinacse
Copy link
Contributor

@elinacse elinacse commented Mar 1, 2026

  • I have added tests that cover my changes.
  • If adding a new instrumentation or changing an existing one, I've added screenshots from some observability platform showing the change.
  • PR name follows conventional commits format: feat(instrumentation): ... or fix(instrumentation): ....
  • (If applicable) I have updated the documentation accordingly.

Important

Fixes async stream handling in Anthropic instrumentation by using a sync wrapper and updates response attribute handling to avoid None values.

  • Behavior:
    • Adds handling for async streams in __init__.py using a sync wrapper to maintain compatibility with async context managers.
    • Updates ashared_metrics_attributes() in utils.py to avoid None values for model attributes.
  • Version:
    • Bumps version in uv.lock from 0.52.4 to 0.52.6.

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

Summary by CodeRabbit

  • Bug Fixes

    • Prevented null model values from being sent in telemetry attributes, improving metric accuracy.
  • Improvements

    • Refined streaming instrumentation so async streaming operations are traced consistently across SDK variants; removed duplicate async wrappers for clearer tracing behavior.
  • Tests

    • Added deterministic streaming fixtures and tests to validate streaming trace behavior, span names, and span attributes.

@elinacse
Copy link
Contributor Author

elinacse commented Mar 1, 2026

Fix for the issue #3701

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 98a66a9 in 16 seconds. Click for details.
  • Reviewed 96 lines of code in 3 files
  • Skipped 0 files when reviewing.
  • Skipped posting 0 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.

Workflow ID: wflow_CjfEUkT3K4EEVDMi

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

@coderabbitai
Copy link

coderabbitai bot commented Mar 1, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e2ec305d-716d-43fa-91e7-ee3d3966787f

📥 Commits

Reviewing files that changed from the base of the PR and between 79944a9 and c6b6e9a.

📒 Files selected for processing (1)
  • packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py

📝 Walkthrough

Walkthrough

Relocated Anthropic async stream method wrappers for beta and bedrock from the async-wrapper list into the sync-wrapper list so methods returning AsyncMessageStreamManager use the synchronous wrapper path; refined metrics attribute builders to omit null model values; added an event-stream cassette and async tests exercising the legacy stream-manager flow.

Changes

Cohort / File(s) Summary
Async stream wrapper config
packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py
Moved AsyncMessages.stream entries for beta (anthropic.resources.beta.messages.messages) and bedrock (anthropic.lib.bedrock._beta_messages) from WRAPPED_AMETHODS into WRAPPED_METHODS so stream methods that return AsyncMessageStreamManager use the synchronous wrapper path; removed their prior async-wrapper entries.
Metrics attributes refinement
packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py
Updated ashared_metrics_attributes/shared_metrics_attributes to build an attrs dict and only include GenAIAttributes.GEN_AI_RESPONSE_MODEL when model is not None, avoiding null-valued attributes.
Tests & fixtures
packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py, packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_messages/test_async_anthropic_beta_message_stream_manager_legacy.yaml
Added async tests that stream a beta messages response and assert span/attribute behavior, and added a new HTTP event-stream cassette simulating Anthropic beta streaming responses for deterministic testing.

Sequence Diagram(s)

(omitted — changes are configuration and small control-flow adjustments that don't introduce a new multi-component sequential feature)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Poem

🐇 I hopped through streams both beta and bedrock,

Wrapped the right paths so the manager's not odd,
I quietly skip models that are merely None,
Spans hum polite, attributes tidy and done,
Then I nibble a carrot and bounce in the sun.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Fix(anthropic)Async' is vague and lacks clarity about what specifically is being fixed in async handling. Provide a more descriptive title following conventional commits format, such as 'fix(anthropic): fix async stream handling for message stream managers' to clearly explain the specific fix.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

Copy link

@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: 1

🤖 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/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py`:
- Around line 171-178: The sync metrics builder shared_metrics_attributes
currently always sets GenAIAttributes.GEN_AI_RESPONSE_MODEL even when model is
None, which OTLP rejects; update shared_metrics_attributes to match
ashared_metrics_attributes by only adding GenAIAttributes.GEN_AI_RESPONSE_MODEL
to attrs when model is not None (i.e., after computing model from
common_attributes/response), leaving the rest of attrs merging with
common_attributes and GenAIAttributes.GEN_AI_SYSTEM = GEN_AI_SYSTEM_ANTHROPIC
unchanged.

ℹ️ 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.

📥 Commits

Reviewing files that changed from the base of the PR and between a78de64 and 98a66a9.

⛔ Files ignored due to path filters (1)
  • packages/opentelemetry-instrumentation-anthropic/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py
  • packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py

Copy link

@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/opentelemetry-instrumentation-anthropic/tests/test_messages.py (1)

2917-2953: Test coverage is incomplete compared to similar streaming tests.

This test is missing several key assertions that test_async_anthropic_message_stream_manager_legacy (lines 2645-2708) includes:

  • Completion content verification (GEN_AI_COMPLETION.0.content == response_content)
  • Completion role verification
  • Token usage assertions (GEN_AI_USAGE_INPUT_TOKENS, total tokens calculation)
  • Response ID assertion
  • Metrics verification via verify_metrics()

These assertions validate that the instrumentation correctly captures the streamed response attributes for the beta API path.

♻️ Suggested additions to improve test coverage
     assert anthropic_span.attributes[f"{GenAIAttributes.GEN_AI_PROMPT}.0.role"] == "user"
+    assert (
+        anthropic_span.attributes.get(f"{GenAIAttributes.GEN_AI_COMPLETION}.0.content")
+        == response_content
+    )
+    assert (
+        anthropic_span.attributes.get(f"{GenAIAttributes.GEN_AI_COMPLETION}.0.role")
+        == "assistant"
+    )
+    assert anthropic_span.attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] == 17
+    assert (
+        anthropic_span.attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS]
+        + anthropic_span.attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS]
+        == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS]
+    )
+
+    metrics_data = reader.get_metrics_data()
+    resource_metrics = metrics_data.resource_metrics
+    verify_metrics(resource_metrics, "claude-3-5-haiku-20241022")
 
     logs = log_exporter.get_finished_logs()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py`
around lines 2917 - 2953, The beta-streaming test is missing the same assertions
as the non-beta streaming test: after collecting response_content and extracting
anthropic_span, add assertions that
anthropic_span.attributes[f"{GenAIAttributes.GEN_AI_COMPLETION}.0.content"] ==
response_content and that GEN_AI_COMPLETION role equals the expected role (e.g.,
"assistant"); assert token usage attributes like GEN_AI_USAGE_INPUT_TOKENS and
total tokens calculation (input + output) match expected values from the mocked
reader/response; assert the response id attribute (e.g.,
GenAIAttributes.GEN_AI_RESPONSE_ID) equals the mocked response id; and call
verify_metrics() at the end to validate metrics—use the same attribute keys and
helper names (response_content, anthropic_span, GenAIAttributes,
GEN_AI_COMPLETION, GEN_AI_USAGE_INPUT_TOKENS, verify_metrics) to mirror
test_async_anthropic_message_stream_manager_legacy.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py`:
- Around line 2917-2953: The beta-streaming test is missing the same assertions
as the non-beta streaming test: after collecting response_content and extracting
anthropic_span, add assertions that
anthropic_span.attributes[f"{GenAIAttributes.GEN_AI_COMPLETION}.0.content"] ==
response_content and that GEN_AI_COMPLETION role equals the expected role (e.g.,
"assistant"); assert token usage attributes like GEN_AI_USAGE_INPUT_TOKENS and
total tokens calculation (input + output) match expected values from the mocked
reader/response; assert the response id attribute (e.g.,
GenAIAttributes.GEN_AI_RESPONSE_ID) equals the mocked response id; and call
verify_metrics() at the end to validate metrics—use the same attribute keys and
helper names (response_content, anthropic_span, GenAIAttributes,
GEN_AI_COMPLETION, GEN_AI_USAGE_INPUT_TOKENS, verify_metrics) to mirror
test_async_anthropic_message_stream_manager_legacy.

ℹ️ 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 98a66a9 and 79944a9.

📒 Files selected for processing (2)
  • packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_messages/test_async_anthropic_beta_message_stream_manager_legacy.yaml
  • packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py
✅ Files skipped from review due to trivial changes (1)
  • packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_messages/test_async_anthropic_beta_message_stream_manager_legacy.yaml

@elinacse
Copy link
Contributor Author

elinacse commented Mar 1, 2026

@galkleinman @nina-kollman please help in review of this PR for this issue #3701. Thanks !

@elinacse
Copy link
Contributor Author

elinacse commented Mar 2, 2026

@galkleinman please help in review of this PR for this issue #3701. Thanks !

@elinacse
Copy link
Contributor Author

elinacse commented Mar 4, 2026

@nirga @galkleinman @nina-kollman Can you please review this pr for the Issue #3701.

@nina-kollman nina-kollman merged commit 93786d9 into traceloop:main Mar 8, 2026
10 checks passed
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.

2 participants