Skip to content

feat(anthropic): conform instrumentation to OTel GenAI semantic conventions#3835

Open
max-deygin-traceloop wants to merge 15 commits intomainfrom
max/tlp-1926-anthropic-instrumentation
Open

feat(anthropic): conform instrumentation to OTel GenAI semantic conventions#3835
max-deygin-traceloop wants to merge 15 commits intomainfrom
max/tlp-1926-anthropic-instrumentation

Conversation

@max-deygin-traceloop
Copy link
Contributor

@max-deygin-traceloop max-deygin-traceloop commented Mar 22, 2026

What

Refactors the Anthropic instrumentation package to emit span attributes that comply with the OpenTelemetry GenAI semantic conventions spec.

Changes

New attributes (replaces legacy flat gen_ai.prompt.* / gen_ai.completion.* keys):

  • gen_ai.input.messages — full message array as JSON
  • gen_ai.output.messages — assistant response as JSON
  • gen_ai.system_instructions — system prompt as standalone attribute
  • gen_ai.tool.definitions — tool definitions as JSON
  • gen_ai.provider.name — new required attribute ("anthropic")
  • gen_ai.operation.name — new required attribute ("chat" / "text_completion")
  • gen_ai.response.finish_reasons — now emitted as an array regardless of TRACELOOP_TRACE_CONTENT setting

Bug fixes:

  • gen_ai.system value corrected from "Anthropic" to "anthropic" (spec enum value)
  • gen_ai.request.max_tokens now correctly reads max_tokens (Messages API) with fallback to max_tokens_to_sample (legacy Completions API)
  • Tool-use blocks in input messages no longer duplicated across both content and tool_calls
  • Streaming tool_calls.arguments correctly handles both string (streaming delta accumulation) and dict inputs without double-encoding

Checklist

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

  • Validated locally against a running agent using ConsoleSpanExporter.

  • Confirmed all appear correctly on anthropic.chat spans:

    gen_ai.provider.name: "anthropic", gen_ai.operation.name: "chat",
    gen_ai.input.messages, gen_ai.output.messages, gen_ai.response.finish_reasons
    

Note: This is a recreation of #3808, which was auto-closed when its target branch was merged into main. No code changes were made; the branch is identical except for a fix removing the redundant gen_ai.system attribute (deprecated, replaced by gen_ai.provider.name).

Summary by CodeRabbit

  • Refactor

    • Aligned instrumentation with GenAI semantic conventions: consolidated per-message attributes into JSON-encoded input/output/tool/message payloads, standardized finish-reason and total-token keys, and unified provider/operation naming for traced calls.
  • Tests

    • Updated and added tests to validate the new consolidated span payloads, finish-reason mappings, token accounting, and semconv compliance.
  • Chores

    • Bumped opentelemetry-semconv-ai constraint to >=0.5.0.

max-deygin-servicenow and others added 10 commits March 22, 2026 10:21
…→ GEN_AI_

- Import GEN_AI_REQUEST_FREQUENCY/PRESENCE_PENALTY from upstream gen_ai_attributes
- Use SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS/IS_STREAMING/RESPONSE_FINISH_REASON/
  RESPONSE_STOP_REASON (renamed from LLM_*)
- Remove duplicate LLM_REQUEST_TYPE dict entry (operation_name var already handles it)
- Update test_messages.py and test_bedrock_with_raw_response.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pan_attrs.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- llm.usage.total_tokens → gen_ai.usage.total_tokens
- gen_ai.usage.cache_creation_input_tokens → gen_ai.usage.cache_creation.input_tokens
- gen_ai.usage.cache_read_input_tokens → gen_ai.usage.cache_read.input_tokens

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ max-deygin-traceloop
❌ max-deygin-servicenow
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link

coderabbitai bot commented Mar 22, 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: 8a31880e-2917-4b25-8ec6-9b178356767f

📥 Commits

Reviewing files that changed from the base of the PR and between 32b81dd and f1971c3.

⛔ 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/pyproject.toml
  • packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py
✅ Files skipped from review due to trivial changes (1)
  • packages/opentelemetry-instrumentation-anthropic/pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py

📝 Walkthrough

Walkthrough

Migrates Anthropic instrumentation from legacy LLM semconv to GenAI semantic-convention keys, consolidates per-index prompt/completion attributes into JSON message payloads, updates span provider/operation attributes, revises streaming/output serialization, and adjusts tests and dependency ranges.

Changes

Cohort / File(s) Summary
Instrumentation entrypoints
packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py, packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py
Replaced legacy LLM span attribute keys with GenAI keys for provider/operation, token usage, and response stop/finish reasons; updated span init to emit gen_ai.provider.name and gen_ai.operation.name.
Span serialization utils
packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py
Added finish-reason mapping and content→parts conversion; replaced per-index prompt/completion attributes with consolidated gen_ai.input.messages / gen_ai.output.messages JSON payloads; serialized gen_ai.system_instructions and gen_ai.tool.definitions; adjusted request/completion key names (penalties, max_tokens fallback, streaming flag) and streaming aggregation logic.
Streaming helpers
packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py
Minor key renames to use GenAI semantic keys for token totals and per-choice finish reasons; behavior otherwise unchanged.
Tests — assertions & schema updates
packages/opentelemetry-instrumentation-anthropic/tests/* (e.g., test_messages.py, test_thinking.py, test_completion.py, test_structured_outputs.py, test_bedrock_with_raw_response.py, test_prompt_caching.py)
Updated tests to parse JSON-encoded GEN_AI_INPUT_MESSAGES / GEN_AI_OUTPUT_MESSAGES and GEN_AI_TOOL_DEFINITIONS; replaced indexed attribute assertions with checks against consolidated message/parts structures and new gen_ai.usage.* token attributes.
New semconv compliance/unit tests
packages/opentelemetry-instrumentation-anthropic/tests/test_semconv_compliance.py, packages/opentelemetry-instrumentation-anthropic/tests/test_semconv_span_attrs.py
Added re-exported semconv compliance checks and detailed unit tests validating GenAI attribute emission, parts schema, tool call serialization, finish-reason mapping, streaming consolidation, and provider/operation identity.
Deps / config
packages/opentelemetry-instrumentation-anthropic/pyproject.toml
Bumped opentelemetry-semantic-conventions-ai constraint to >=0.5.0,<0.6.0; updated anthropic[bedrock] test dependency floor.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • nirga

Poem

🐰 I hopped through spans and payload streams,

Swapped old LLM keys for GenAI dreams,
Prompts in JSON, parts snug and neat,
Tools and reasons gathered, tidy and sweet,
A carrot-coded hop — observability beams 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: conforming the Anthropic instrumentation to OpenTelemetry GenAI semantic conventions, which aligns with the comprehensive refactoring documented in the changeset.

✏️ 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 max/tlp-1926-anthropic-instrumentation

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: 2

🧹 Nitpick comments (2)
packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py (1)

1274-1275: Assert the exact finish_reasons payload here.

in is too weak for the new array semantics—it will still pass if the instrumentation emits duplicates or unrelated finish reasons. These fixtures look single-choice, so an exact assertion will catch the regression this PR is trying to prevent.

Based on learnings: Follow the OpenTelemetry GenAI semantic specification at https://opentelemetry.io/docs/specs/semconv/gen-ai/

Also applies to: 1613-1614

🤖 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 1274 - 1275, Replace the weak membership check with an exact
payload assertion: instead of asserting response.stop_reason in finish_reasons,
assert that
anthropic_span.attributes[GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS] equals
the exact list expected (e.g. [response.stop_reason]) so duplicates or extra
values fail; do the same change for the other occurrence referenced (lines
around 1613-1614) and keep the reference to
GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS to locate the test.
packages/opentelemetry-instrumentation-anthropic/tests/test_semconv_span_attrs.py (1)

228-237: Consider simplifying the content parsing logic.

The nested conditional parsing (if isinstance(content, str)json.loads check → if isinstance(content_parsed, list)) is complex. Since you control the span_utils output, you could assert a more specific expected structure.

However, this defensive approach does handle edge cases, so it's acceptable as-is.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/opentelemetry-instrumentation-anthropic/tests/test_semconv_span_attrs.py`
around lines 228 - 237, The current nested parsing around
assistant_msg["content"] (variables content → content_parsed) is more defensive
than needed; simplify by asserting the expected shape up front, e.g. require
content to be a str containing JSON when produced by span_utils, parse it once
into content_parsed, then assert isinstance(content_parsed, list) before
building types_in_content and checking "tool_use" is not present; update the
test code that references assistant_msg, content, content_parsed, and
types_in_content to remove the nested isinstance checks and make the expected
structure explicit.
🤖 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/pyproject.toml`:
- Line 16: The pyproject.toml entry under tool.uv.sources masks the PyPI package
opentelemetry-semantic-conventions-ai so our tests never validate that the
published 0.5.0 wheel actually exports the symbols we import
(opentelemetry.semconv_ai.SpanAttributes, Meters,
SUPPRESS_LANGUAGE_MODEL_INSTRUMENTATION_KEY, and _testing); remove or
conditionally disable the local source override for
opentelemetry-semantic-conventions-ai in tool.uv.sources (or add an integration
test that installs the released wheel and imports those symbols) so CI/monorepo
tests exercise the real published artifact rather than the sibling checkout.

In `@packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py`:
- Around line 1918-1932: The test fails because streaming builds separate
output.message entries for the same assistant turn (one for text and another for
tool_calls) instead of consolidating them like the non-streaming path; update
the streaming serialization to accumulate all blocks for a single assistant turn
and emit one message object with both "content" and "tool_calls" before writing
GEN_AI_OUTPUT_MESSAGES. Locate the streaming code that appends to
output_messages (the logic that produces the separate text_msg and tool_msgs)
and change it to merge content fragments and tool call entries into a single
assistant message (matching the non-streaming behavior shown around the
serialize logic in span_utils.py lines ~220–223), ensuring output_messages
yields one assistant message containing "content", "role":"assistant", and a
combined "tool_calls" array with arguments serialized the same way the
non-streaming path does.

---

Nitpick comments:
In `@packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py`:
- Around line 1274-1275: Replace the weak membership check with an exact payload
assertion: instead of asserting response.stop_reason in finish_reasons, assert
that anthropic_span.attributes[GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS]
equals the exact list expected (e.g. [response.stop_reason]) so duplicates or
extra values fail; do the same change for the other occurrence referenced (lines
around 1613-1614) and keep the reference to
GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS to locate the test.

In
`@packages/opentelemetry-instrumentation-anthropic/tests/test_semconv_span_attrs.py`:
- Around line 228-237: The current nested parsing around
assistant_msg["content"] (variables content → content_parsed) is more defensive
than needed; simplify by asserting the expected shape up front, e.g. require
content to be a str containing JSON when produced by span_utils, parse it once
into content_parsed, then assert isinstance(content_parsed, list) before
building types_in_content and checking "tool_use" is not present; update the
test code that references assistant_msg, content, content_parsed, and
types_in_content to remove the nested isinstance checks and make the expected
structure explicit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8fd99eb7-5d57-4e35-9b6e-765b533d3d31

📥 Commits

Reviewing files that changed from the base of the PR and between 3f2418b and 4b2e8b8.

⛔ Files ignored due to path filters (1)
  • packages/opentelemetry-instrumentation-anthropic/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (12)
  • packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py
  • packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py
  • packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py
  • packages/opentelemetry-instrumentation-anthropic/pyproject.toml
  • packages/opentelemetry-instrumentation-anthropic/tests/test_bedrock_with_raw_response.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_completion.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_prompt_caching.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_semconv_compliance.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_semconv_span_attrs.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_structured_outputs.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py

No longer needed since 0.5.0 is published on PyPI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
doronkopit5
doronkopit5 previously approved these changes Mar 23, 2026
Copy link
Contributor

@OzBenSimhonTraceloop OzBenSimhonTraceloop left a comment

Choose a reason for hiding this comment

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

Furhter more, current anthropic sdk version is

Comment on lines +96 to +98
span,
GenAIAttributes.GEN_AI_INPUT_MESSAGES,
json.dumps([{"role": "user", "content": kwargs.get("prompt")}]),
Copy link
Contributor

Choose a reason for hiding this comment

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

Based on gen_ai.input.messages messages
the structure should be

[{"role": "user", "parts": [{"type": "text", "content": "Hello"}]}]

not

[{"role": "user", "content": "Hello"}]

stop_reason = response.get("stop_reason")

if stop_reason:
span.set_attribute(GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS, [stop_reason])
Copy link
Contributor

Choose a reason for hiding this comment

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

The OTel FinishReason enum defines: stop, length, content_filter, tool_call, error, while Anthropic are different AFAIK, so u need mapping here instead of taking Anthropic as is

Comment on lines +105 to 107
GenAIAttributes.GEN_AI_SYSTEM_INSTRUCTIONS,
await _dump_content(
message_index=0, span=span, content=kwargs.get("system")
Copy link
Contributor

Choose a reason for hiding this comment

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

The _dump_content might return plain string in many cases while the Otel schema for it its array of objects

Copy link
Contributor

Choose a reason for hiding this comment

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

Bump to latest

response.get("role"),
)
thinking_messages.append({
"role": "thinking",
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't`"role": "thinking" should be in the message parts and here u should have ,
Same for sync, streaming and tests.
As now u're generating

[
  {
    "role": "thinking",
    "content": "Let me analyze this step by step. The user is asking about the weather in Paris..."
  },
  {
    "role": "assistant",
    "content": "The weather in Paris is currently rainy with a temperature of 57°F."
  }
]

instead of

[
  {
    "role": "assistant",
    "parts": [
      {
        "type": "reasoning",
        "content": "Let me analyze this step by step. The user is asking about the weather in Paris..."
      },
      {
        "type": "text",
        "content": "The weather in Paris is currently rainy with a temperature of 57°F."
      }
    ],
    "finish_reason": "stop"
  }
]

@doronkopit5 doronkopit5 dismissed their stale review March 23, 2026 10:54

lets fix the content format

Address PR #3835 review comments from OzBenSimhonTraceloop:

- Input/output messages now use "parts" array structure per
  gen-ai-input-messages.json and gen-ai-output-messages.json schemas
- Map Anthropic finish reasons to OTel enum: end_turn→stop,
  tool_use→tool_call, max_tokens→length, stop_sequence→stop
- Thinking content is now a ReasoningPart (type: "reasoning") inside
  the assistant message's parts array, not a separate message
- Tool calls are now tool_call parts, not a separate "tool_calls" key
- Streaming events consolidated into a single assistant message
- Rewrote test_semconv_span_attrs.py as spec-driven unit tests (TDD)
- Updated all VCR integration test assertions to match

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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 (2)
packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py (2)

401-402: Remove dead code.

Lines 401-402 are a no-op – tool_arguments is already None if the condition is true.

🧹 Remove redundant lines
                 if isinstance(tool_arguments, str):
                     try:
                         tool_arguments = json.loads(tool_arguments)
                     except (json.JSONDecodeError, TypeError):
                         pass
-                elif tool_arguments is None:
-                    tool_arguments = None
                 parts.append({
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py`
around lines 401 - 402, Remove the redundant no-op branch that checks "elif
tool_arguments is None: tool_arguments = None" in span_utils.py; delete those
two lines so the surrounding if/elif logic no longer contains this dead branch
and the behavior for tool_arguments remains handled by the other existing
branches.

207-220: Async operations inside list comprehension may not work as expected.

The list comprehension on lines 207-220 contains await inside a regular list comprehension. While Python 3.10+ allows await in list comprehensions within async functions, this pattern creates all coroutines first and then awaits them sequentially, which is correct here. However, the structure is complex and hard to read.

Consider using an explicit loop or asyncio.gather for clarity:

♻️ Suggested simplification
-        content = [
-            (
-                await _process_image_item(
-                    model_as_dict(item),
-                    span.context.trace_id,
-                    span.context.span_id,
-                    message_index,
-                    j,
-                )
-                if _is_base64_image(model_as_dict(item))
-                else model_as_dict(item)
-            )
-            for j, item in enumerate(content)
-        ]
+        processed = []
+        for j, item in enumerate(content):
+            item_dict = model_as_dict(item)
+            if _is_base64_image(item_dict):
+                processed.append(await _process_image_item(
+                    item_dict,
+                    span.context.trace_id,
+                    span.context.span_id,
+                    message_index,
+                    j,
+                ))
+            else:
+                processed.append(item_dict)
+        content = processed
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py`
around lines 207 - 220, The list comprehension mixes await with conditional
logic (using _process_image_item, _is_base64_image, model_as_dict and
span.context.trace_id/span_id) which is hard to read; replace it by first
building a list of coroutines for items that need processing (e.g., for j,item
in enumerate(content) append _process_image_item(...) when
_is_base64_image(model_as_dict(item)) else append a completed value or use
asyncio.sleep(0)/None), then run them with asyncio.gather(...) to concurrently
await all results and assign the returned list back to content; alternatively
use an explicit async for loop to sequentially await _process_image_item for
clarity.
🤖 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/opentelemetry/instrumentation/anthropic/span_utils.py`:
- Around line 401-402: Remove the redundant no-op branch that checks "elif
tool_arguments is None: tool_arguments = None" in span_utils.py; delete those
two lines so the surrounding if/elif logic no longer contains this dead branch
and the behavior for tool_arguments remains handled by the other existing
branches.
- Around line 207-220: The list comprehension mixes await with conditional logic
(using _process_image_item, _is_base64_image, model_as_dict and
span.context.trace_id/span_id) which is hard to read; replace it by first
building a list of coroutines for items that need processing (e.g., for j,item
in enumerate(content) append _process_image_item(...) when
_is_base64_image(model_as_dict(item)) else append a completed value or use
asyncio.sleep(0)/None), then run them with asyncio.gather(...) to concurrently
await all results and assign the returned list back to content; alternatively
use an explicit async for loop to sequentially await _process_image_item for
clarity.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 90a921e4-eef5-4e54-84b5-ba910e5af755

📥 Commits

Reviewing files that changed from the base of the PR and between c73dd21 and 32b81dd.

📒 Files selected for processing (8)
  • packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_bedrock_with_raw_response.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_completion.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_prompt_caching.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_semconv_span_attrs.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_structured_outputs.py
  • packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py
✅ Files skipped from review due to trivial changes (1)
  • packages/opentelemetry-instrumentation-anthropic/tests/test_prompt_caching.py

Copy link
Contributor

@OzBenSimhonTraceloop OzBenSimhonTraceloop left a comment

Choose a reason for hiding this comment

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

@max-deygin-servicenow please bump the Anthropic SDK from 0.76 to 0.86 + fix the lint issue :)

max-deygin-traceloop and others added 2 commits March 23, 2026 14:40
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants