From b906ea745859151a806baf76bfcab8ab3c9cdad4 Mon Sep 17 00:00:00 2001 From: Rajat Malik Date: Fri, 4 Sep 2026 12:06:03 +0530 Subject: [PATCH 1/4] fix(anthropic): record reasoning token usage --- .../instrumentation/anthropic/__init__.py | 13 +++++- .../instrumentation/anthropic/streaming.py | 7 +++ .../instrumentation/anthropic/utils.py | 15 +++++++ .../tests/test_thinking.py | 45 +++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py index 0054c99d59..bdb2bcaaec 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py @@ -29,6 +29,7 @@ count_prompt_tokens_from_request, dont_throw, error_metrics_attributes, + get_reasoning_tokens, run_async, set_span_attribute, shared_metrics_attributes, @@ -296,6 +297,12 @@ async def _aset_token_usage( ) set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens) + set_span_attribute( + span, + SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS, + get_reasoning_tokens(usage), + ) + set_span_attribute( span, GenAIAttributes.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens ) @@ -411,7 +418,11 @@ def _set_token_usage( span, GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens ) set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens) - + set_span_attribute( + span, + SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS, + get_reasoning_tokens(usage), + ) set_span_attribute( span, GenAIAttributes.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens ) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py index bd2d6dc15d..544b623306 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py @@ -15,6 +15,7 @@ count_prompt_tokens_from_request, dont_throw, error_metrics_attributes, + get_reasoning_tokens, set_span_attribute, shared_metrics_attributes, should_emit_events, @@ -98,6 +99,12 @@ def _set_token_usage( ) set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens) + set_span_attribute( + span, + SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS, + get_reasoning_tokens(complete_response.get("usage")), + ) + set_span_attribute( span, GenAIAttributes.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens ) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py index a060031017..ccb25306fa 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py @@ -27,6 +27,21 @@ def set_span_attribute(span, name, value): return +def get_reasoning_tokens(usage): + """Return reasoning tokens from an Anthropic usage object or dictionary.""" + if not usage: + return None + + details = ( + usage.get("output_tokens_details") + if isinstance(usage, dict) + else getattr(usage, "output_tokens_details", None) + ) + if isinstance(details, dict): + return details.get("reasoning_tokens") + return getattr(details, "reasoning_tokens", None) + + def should_send_prompts(): return ( os.getenv(TRACELOOP_TRACE_CONTENT) or "true" diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py b/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py index f54b96e06c..4e37e3ba82 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py +++ b/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py @@ -1,5 +1,12 @@ import json +from types import SimpleNamespace +from unittest.mock import Mock + import pytest +from opentelemetry.instrumentation.anthropic import _set_token_usage +from opentelemetry.instrumentation.anthropic.streaming import ( + _set_token_usage as _set_stream_token_usage, +) from opentelemetry.sdk._logs import ReadableLogRecord from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAIAttributes, @@ -8,6 +15,44 @@ from .utils import verify_metrics +def test_reasoning_tokens_are_recorded_for_non_streaming_response(): + span = Mock() + response = SimpleNamespace( + usage=SimpleNamespace( + input_tokens=10, + output_tokens=20, + output_tokens_details=SimpleNamespace(reasoning_tokens=7), + ), + content=[], + completion=None, + stop_reason=None, + ) + + _set_token_usage(span, None, {}, response) + + span.set_attribute.assert_any_call( + GenAIAttributes.GEN_AI_USAGE_REASONING_TOKENS, 7 + ) + + +def test_reasoning_tokens_are_recorded_for_streaming_response(): + span = Mock() + complete_response = { + "usage": { + "input_tokens": 10, + "output_tokens": 20, + "output_tokens_details": {"reasoning_tokens": 7}, + }, + "events": [], + } + + _set_stream_token_usage(span, complete_response, 10, 20) + + span.set_attribute.assert_any_call( + GenAIAttributes.GEN_AI_USAGE_REASONING_TOKENS, 7 + ) + + @pytest.mark.vcr def test_anthropic_thinking_legacy( instrument_legacy, anthropic_client, span_exporter, log_exporter, reader From 8ab20a1f3e3dd7d90c7b42a51c700a02515c0f49 Mon Sep 17 00:00:00 2001 From: Rajat Malik Date: Fri, 4 Sep 2026 12:38:47 +0530 Subject: [PATCH 2/4] docs(anthropic): add docstrings to token usage helpers --- .../opentelemetry/instrumentation/anthropic/__init__.py | 2 ++ .../opentelemetry/instrumentation/anthropic/streaming.py | 1 + .../tests/test_thinking.py | 2 ++ 3 files changed, 5 insertions(+) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py index bdb2bcaaec..1404b74f8d 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py @@ -198,6 +198,7 @@ async def _aset_token_usage( token_histogram: Histogram = None, choice_counter: Counter = None, ): + """Record token usage from an asynchronous Anthropic response.""" import inspect # If we get a coroutine, await it @@ -323,6 +324,7 @@ def _set_token_usage( token_histogram: Histogram = None, choice_counter: Counter = None, ): + """Record token usage from a synchronous Anthropic response.""" import inspect # If we get a coroutine, we cannot process it in sync context diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py index 544b623306..346b66de0c 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py @@ -83,6 +83,7 @@ def _set_token_usage( token_histogram: Histogram = None, choice_counter: Counter = None, ): + """Record token usage collected from a completed streaming response.""" cache_read_tokens = ( complete_response.get("usage", {}).get("cache_read_input_tokens", 0) or 0 ) diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py b/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py index 4e37e3ba82..5bfe1915a9 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py +++ b/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py @@ -16,6 +16,7 @@ def test_reasoning_tokens_are_recorded_for_non_streaming_response(): + """Verify reasoning tokens are recorded for a regular response.""" span = Mock() response = SimpleNamespace( usage=SimpleNamespace( @@ -36,6 +37,7 @@ def test_reasoning_tokens_are_recorded_for_non_streaming_response(): def test_reasoning_tokens_are_recorded_for_streaming_response(): + """Verify reasoning tokens are recorded for a streaming response.""" span = Mock() complete_response = { "usage": { From 2b85c8db84b7d9cc1ae3e8017efedecf56467fa1 Mon Sep 17 00:00:00 2001 From: Rajat Malik <132563425+rjmdhiraj@users.noreply.github.com> Date: Fri, 25 Sep 2026 12:54:44 +0530 Subject: [PATCH 3/4] test(anthropic): use project reasoning token attribute --- .../tests/test_thinking.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py b/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py index 5bfe1915a9..d321ce700f 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py +++ b/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py @@ -12,6 +12,7 @@ gen_ai_attributes as GenAIAttributes, ) +from opentelemetry.semconv_ai import SpanAttributes from .utils import verify_metrics @@ -32,7 +33,7 @@ def test_reasoning_tokens_are_recorded_for_non_streaming_response(): _set_token_usage(span, None, {}, response) span.set_attribute.assert_any_call( - GenAIAttributes.GEN_AI_USAGE_REASONING_TOKENS, 7 + SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS, 7 ) @@ -51,7 +52,7 @@ def test_reasoning_tokens_are_recorded_for_streaming_response(): _set_stream_token_usage(span, complete_response, 10, 20) span.set_attribute.assert_any_call( - GenAIAttributes.GEN_AI_USAGE_REASONING_TOKENS, 7 + SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS, 7 ) From 9f02a3a73db25ffeafe68b51ce5fd38312968094 Mon Sep 17 00:00:00 2001 From: Rajat Malik <132563425+rjmdhiraj@users.noreply.github.com> Date: Mon, 28 Sep 2026 10:44:53 +0530 Subject: [PATCH 4/4] fix(anthropic): handle thinking token usage correctly --- .../instrumentation/anthropic/__init__.py | 8 +-- .../instrumentation/anthropic/streaming.py | 13 +++-- .../instrumentation/anthropic/utils.py | 8 +-- .../pyproject.toml | 2 +- .../test_anthropic_thinking_legacy.yaml | 24 ++++---- ...t_anthropic_thinking_streaming_legacy.yaml | 2 +- ...ng_streaming_with_events_with_content.yaml | 2 +- ...streaming_with_events_with_no_content.yaml | 2 +- ...pic_thinking_with_events_with_content.yaml | 24 ++++---- ..._thinking_with_events_with_no_content.yaml | 24 ++++---- .../test_async_anthropic_thinking_legacy.yaml | 24 ++++---- ...c_anthropic_thinking_streaming_legacy.yaml | 2 +- ...ng_streaming_with_events_with_content.yaml | 2 +- ...streaming_with_events_with_no_content.yaml | 2 +- ...pic_thinking_with_events_with_content.yaml | 24 ++++---- ..._thinking_with_events_with_no_content.yaml | 24 ++++---- .../tests/test_thinking.py | 58 ++++--------------- 17 files changed, 107 insertions(+), 138 deletions(-) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py index 1404b74f8d..27d5c224c7 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py @@ -29,7 +29,7 @@ count_prompt_tokens_from_request, dont_throw, error_metrics_attributes, - get_reasoning_tokens, + get_thinking_tokens, run_async, set_span_attribute, shared_metrics_attributes, @@ -198,7 +198,6 @@ async def _aset_token_usage( token_histogram: Histogram = None, choice_counter: Counter = None, ): - """Record token usage from an asynchronous Anthropic response.""" import inspect # If we get a coroutine, await it @@ -301,7 +300,7 @@ async def _aset_token_usage( set_span_attribute( span, SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS, - get_reasoning_tokens(usage), + get_thinking_tokens(usage), ) set_span_attribute( @@ -324,7 +323,6 @@ def _set_token_usage( token_histogram: Histogram = None, choice_counter: Counter = None, ): - """Record token usage from a synchronous Anthropic response.""" import inspect # If we get a coroutine, we cannot process it in sync context @@ -423,7 +421,7 @@ def _set_token_usage( set_span_attribute( span, SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS, - get_reasoning_tokens(usage), + get_thinking_tokens(usage), ) set_span_attribute( span, GenAIAttributes.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py index 346b66de0c..caa438ea47 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py @@ -15,7 +15,7 @@ count_prompt_tokens_from_request, dont_throw, error_metrics_attributes, - get_reasoning_tokens, + get_thinking_tokens, set_span_attribute, shared_metrics_attributes, should_emit_events, @@ -62,16 +62,21 @@ def _process_response_item(item, complete_response): for event in complete_response.get("events", []): event["finish_reason"] = item.delta.stop_reason if item.usage: + item_usage = dict(item.usage) if "usage" in complete_response: - item_output_tokens = dict(item.usage).get("output_tokens", 0) + item_output_tokens = item_usage.get("output_tokens", 0) existing_output_tokens = complete_response["usage"].get( "output_tokens", 0 ) complete_response["usage"]["output_tokens"] = ( item_output_tokens + existing_output_tokens ) + if item_usage.get("output_tokens_details") is not None: + complete_response["usage"]["output_tokens_details"] = item_usage[ + "output_tokens_details" + ] else: - complete_response["usage"] = dict(item.usage) + complete_response["usage"] = item_usage def _set_token_usage( @@ -103,7 +108,7 @@ def _set_token_usage( set_span_attribute( span, SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS, - get_reasoning_tokens(complete_response.get("usage")), + get_thinking_tokens(complete_response.get("usage")), ) set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py index ccb25306fa..b2aa27b4e6 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py @@ -27,8 +27,8 @@ def set_span_attribute(span, name, value): return -def get_reasoning_tokens(usage): - """Return reasoning tokens from an Anthropic usage object or dictionary.""" +def get_thinking_tokens(usage): + """Return thinking tokens from an Anthropic usage object or dictionary.""" if not usage: return None @@ -38,8 +38,8 @@ def get_reasoning_tokens(usage): else getattr(usage, "output_tokens_details", None) ) if isinstance(details, dict): - return details.get("reasoning_tokens") - return getattr(details, "reasoning_tokens", None) + return details.get("thinking_tokens") + return getattr(details, "thinking_tokens", None) def should_send_prompts(): diff --git a/packages/opentelemetry-instrumentation-anthropic/pyproject.toml b/packages/opentelemetry-instrumentation-anthropic/pyproject.toml index 8655bd11be..627af83cb1 100644 --- a/packages/opentelemetry-instrumentation-anthropic/pyproject.toml +++ b/packages/opentelemetry-instrumentation-anthropic/pyproject.toml @@ -34,7 +34,7 @@ dev = [ "ruff>=0.4.0", ] test = [ - "anthropic[bedrock]>=0.86.0", + "anthropic[bedrock]>=1.8.0", "opentelemetry-sdk>=1.38.0,<2", "pytest-asyncio>=0.23.7,<0.24.0", "pytest-recording>=0.13.1,<0.14.0", diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_legacy.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_legacy.yaml index 3d74732019..954e2a03d3 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_legacy.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_legacy.yaml @@ -46,18 +46,18 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA5xT23LaMBD9FY1e+oDdsQ2G4Jk82NzCLRAgZELdYYS92Ma2ZCQ5DmT4944pmbb0 - Nu2TtOfs7lntat9w5GMLpyJYa7p9yIxRyEnmDEbTrWEIEQc1DytYHjIovUAIEgBWMGdJCRAhIiEJ - lVjBKfMhwRb2EpL7oFbVhioYpSBVQzNMzdCbWMEeoxKoxNant/ekMoxoHNGglHm/WngEEqWAPJZT - iWQIiObpBjhiWySjFMQZS0BK4OgD/4BIlgHhAkX0zBSM+8jFQnJSbIDzg4s/utSli19zKBJIZJAk - 4FsuFapUuUrUQt2ooHKVq4cytsciGiAZcpYHIQLihZcCyhCkIsokIrSsxqXyyuZIRTKMRCn0FVOQ - YJfn3SLdpeQqoriyN1c2/JuC8VePqksPVzldOme/a3T1Moc/NBwrWEQBJTLn5aA7/NFpxc99exa0 - +rEzj6e14xBmhT0YHx1/oBvV5ba97A7q0BgVu+msU9HICpbj3dSumflEONtuW5P8Zfeo97J2zVzG - pqbfOeRw4zdXnck27dRnneC4r+q7XrU1lV19n5hxQNpDm/TiZ7u9eH0yWVOP5/0ivtfJ3p4GIgzi - /q7b7E0m28ELHYxs+27VWPTTu05crdwb82FcOfqm09ArE/k00tuOHm1W7d0wNMZH7b4pB2Q/kcb4 - 5bCYPgzDVmU5HnZbaa1Ob7yHqL6d27e3+KR8++zwWu7K+bDw4v9be/qsYCFZtuZABKPYwkD9tcw5 - xRdCwD4H6gG2aJ4kCs7Pq2u94YhmuVxLFgMV2DINBXvEC2HtcSAyYnT9o4P2znMg/s8cy+X3iKGb - p9MXAAAA//8DAOwgN4dVBAAA + H4sIAAAAAAAC/51T23LaMBD9FY1f+gDuWDaG4Jk82NzCLRAgZELdYYQtbGMjGUkOMRn+vTKFtqG3 + aZ+kPefsRbvaNyXyFUvZ8mCpQTtP9UHIUOr0BuO1rnMeBxVPKSsiT3GhwpyjAEuA0aQAEOcRF4gI + CW2pjxOJeQnKfKwaak3llBAsVF3TTU2HdSnyKBFYyq1Pb5egIoxIHJGgSHO5WsoAC7DFwKMZEUCE + GJBsu8IM0DUQkazjhCVYCIl9YB8ASlOMGAcROTF7ynzgKlwwtJduLHeVjy5xyezXHIg44ClOEuxb + LuGqUJmK1L26UrG8MTUvfDtUliajM5oFIcDIC88FFC5ABYQKgEhRjStrfm8zacvX8SLRV6wMOD0/ + 7xZAl6Arj/2Vvbqy8b9l0P+qMFySX8V0yZT+rtHGeQ5/aLicKI8CgkTGikG32KPTiJ+79iRodGNn + Go8rhz6e7O3e8OD4Pagb83Vz3u5VcW2w34wnrZKGFng+3IztipmNuLNuNzXBXjaPsJM2K+Y8NjV4 + 56D8xq8vWqP1tlWdtILDzoCbjtEYizbcJWYcoGbfRp342W7OXp9MWofxtLuP7yHa2eOAh0Hc3bTr + ndFo3XshvYFt3y1qs+72rhUbpXt92o9LB990arA0Ek8D2HRgtFo0N/1QHx60+7rood1I6MOXfDZ+ + 6IeN0nzYbze2lSq58R6i6npq394qx/L3z45fi105HZYy+//WHj/L5gqaLhlGcs1kMEz8pew0Uc4E + x7sME09mJVmSlJXstLrWmxKRNBNLQWNMuGKZutxK+Zfx0pOhRETJ8r1Au/CS9n/maCZ+RHRoXmFL + HwsUJbxIfVnwb3Ko6ZXj8fgF8IHzCoYEAAA= headers: CF-RAY: - 920acf24eb2b6410-ALA diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_legacy.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_legacy.yaml index 0e5cc10669..404a8929e4 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_legacy.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_legacy.yaml @@ -187,7 +187,7 @@ interactions: event: message_delta - data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":216} } + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":216,"output_tokens_details":{"thinking_tokens":1024}} } event: message_stop diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_with_events_with_content.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_with_events_with_content.yaml index 0e5cc10669..404a8929e4 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_with_events_with_content.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_with_events_with_content.yaml @@ -187,7 +187,7 @@ interactions: event: message_delta - data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":216} } + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":216,"output_tokens_details":{"thinking_tokens":1024}} } event: message_stop diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_with_events_with_no_content.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_with_events_with_no_content.yaml index 0e5cc10669..404a8929e4 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_with_events_with_no_content.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_streaming_with_events_with_no_content.yaml @@ -187,7 +187,7 @@ interactions: event: message_delta - data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":216} } + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":216,"output_tokens_details":{"thinking_tokens":1024}} } event: message_stop diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_with_events_with_content.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_with_events_with_content.yaml index 3d74732019..954e2a03d3 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_with_events_with_content.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_with_events_with_content.yaml @@ -46,18 +46,18 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA5xT23LaMBD9FY1e+oDdsQ2G4Jk82NzCLRAgZELdYYS92Ma2ZCQ5DmT4944pmbb0 - Nu2TtOfs7lntat9w5GMLpyJYa7p9yIxRyEnmDEbTrWEIEQc1DytYHjIovUAIEgBWMGdJCRAhIiEJ - lVjBKfMhwRb2EpL7oFbVhioYpSBVQzNMzdCbWMEeoxKoxNant/ekMoxoHNGglHm/WngEEqWAPJZT - iWQIiObpBjhiWySjFMQZS0BK4OgD/4BIlgHhAkX0zBSM+8jFQnJSbIDzg4s/utSli19zKBJIZJAk - 4FsuFapUuUrUQt2ooHKVq4cytsciGiAZcpYHIQLihZcCyhCkIsokIrSsxqXyyuZIRTKMRCn0FVOQ - YJfn3SLdpeQqoriyN1c2/JuC8VePqksPVzldOme/a3T1Moc/NBwrWEQBJTLn5aA7/NFpxc99exa0 - +rEzj6e14xBmhT0YHx1/oBvV5ba97A7q0BgVu+msU9HICpbj3dSumflEONtuW5P8Zfeo97J2zVzG - pqbfOeRw4zdXnck27dRnneC4r+q7XrU1lV19n5hxQNpDm/TiZ7u9eH0yWVOP5/0ivtfJ3p4GIgzi - /q7b7E0m28ELHYxs+27VWPTTu05crdwb82FcOfqm09ArE/k00tuOHm1W7d0wNMZH7b4pB2Q/kcb4 - 5bCYPgzDVmU5HnZbaa1Ob7yHqL6d27e3+KR8++zwWu7K+bDw4v9be/qsYCFZtuZABKPYwkD9tcw5 - xRdCwD4H6gG2aJ4kCs7Pq2u94YhmuVxLFgMV2DINBXvEC2HtcSAyYnT9o4P2znMg/s8cy+X3iKGb - p9MXAAAA//8DAOwgN4dVBAAA + H4sIAAAAAAAC/51T23LaMBD9FY1f+gDuWDaG4Jk82NzCLRAgZELdYYQtbGMjGUkOMRn+vTKFtqG3 + aZ+kPefsRbvaNyXyFUvZ8mCpQTtP9UHIUOr0BuO1rnMeBxVPKSsiT3GhwpyjAEuA0aQAEOcRF4gI + CW2pjxOJeQnKfKwaak3llBAsVF3TTU2HdSnyKBFYyq1Pb5egIoxIHJGgSHO5WsoAC7DFwKMZEUCE + GJBsu8IM0DUQkazjhCVYCIl9YB8ASlOMGAcROTF7ynzgKlwwtJduLHeVjy5xyezXHIg44ClOEuxb + LuGqUJmK1L26UrG8MTUvfDtUliajM5oFIcDIC88FFC5ABYQKgEhRjStrfm8zacvX8SLRV6wMOD0/ + 7xZAl6Arj/2Vvbqy8b9l0P+qMFySX8V0yZT+rtHGeQ5/aLicKI8CgkTGikG32KPTiJ+79iRodGNn + Go8rhz6e7O3e8OD4Pagb83Vz3u5VcW2w34wnrZKGFng+3IztipmNuLNuNzXBXjaPsJM2K+Y8NjV4 + 56D8xq8vWqP1tlWdtILDzoCbjtEYizbcJWYcoGbfRp342W7OXp9MWofxtLuP7yHa2eOAh0Hc3bTr + ndFo3XshvYFt3y1qs+72rhUbpXt92o9LB990arA0Ek8D2HRgtFo0N/1QHx60+7rood1I6MOXfDZ+ + 6IeN0nzYbze2lSq58R6i6npq394qx/L3z45fi105HZYy+//WHj/L5gqaLhlGcs1kMEz8pew0Uc4E + x7sME09mJVmSlJXstLrWmxKRNBNLQWNMuGKZutxK+Zfx0pOhRETJ8r1Au/CS9n/maCZ+RHRoXmFL + HwsUJbxIfVnwb3Ko6ZXj8fgF8IHzCoYEAAA= headers: CF-RAY: - 920acf24eb2b6410-ALA diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_with_events_with_no_content.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_with_events_with_no_content.yaml index 3d74732019..954e2a03d3 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_with_events_with_no_content.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_anthropic_thinking_with_events_with_no_content.yaml @@ -46,18 +46,18 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA5xT23LaMBD9FY1e+oDdsQ2G4Jk82NzCLRAgZELdYYS92Ma2ZCQ5DmT4944pmbb0 - Nu2TtOfs7lntat9w5GMLpyJYa7p9yIxRyEnmDEbTrWEIEQc1DytYHjIovUAIEgBWMGdJCRAhIiEJ - lVjBKfMhwRb2EpL7oFbVhioYpSBVQzNMzdCbWMEeoxKoxNant/ekMoxoHNGglHm/WngEEqWAPJZT - iWQIiObpBjhiWySjFMQZS0BK4OgD/4BIlgHhAkX0zBSM+8jFQnJSbIDzg4s/utSli19zKBJIZJAk - 4FsuFapUuUrUQt2ooHKVq4cytsciGiAZcpYHIQLihZcCyhCkIsokIrSsxqXyyuZIRTKMRCn0FVOQ - YJfn3SLdpeQqoriyN1c2/JuC8VePqksPVzldOme/a3T1Moc/NBwrWEQBJTLn5aA7/NFpxc99exa0 - +rEzj6e14xBmhT0YHx1/oBvV5ba97A7q0BgVu+msU9HICpbj3dSumflEONtuW5P8Zfeo97J2zVzG - pqbfOeRw4zdXnck27dRnneC4r+q7XrU1lV19n5hxQNpDm/TiZ7u9eH0yWVOP5/0ivtfJ3p4GIgzi - /q7b7E0m28ELHYxs+27VWPTTu05crdwb82FcOfqm09ArE/k00tuOHm1W7d0wNMZH7b4pB2Q/kcb4 - 5bCYPgzDVmU5HnZbaa1Ob7yHqL6d27e3+KR8++zwWu7K+bDw4v9be/qsYCFZtuZABKPYwkD9tcw5 - xRdCwD4H6gG2aJ4kCs7Pq2u94YhmuVxLFgMV2DINBXvEC2HtcSAyYnT9o4P2znMg/s8cy+X3iKGb - p9MXAAAA//8DAOwgN4dVBAAA + H4sIAAAAAAAC/51T23LaMBD9FY1f+gDuWDaG4Jk82NzCLRAgZELdYYQtbGMjGUkOMRn+vTKFtqG3 + aZ+kPefsRbvaNyXyFUvZ8mCpQTtP9UHIUOr0BuO1rnMeBxVPKSsiT3GhwpyjAEuA0aQAEOcRF4gI + CW2pjxOJeQnKfKwaak3llBAsVF3TTU2HdSnyKBFYyq1Pb5egIoxIHJGgSHO5WsoAC7DFwKMZEUCE + GJBsu8IM0DUQkazjhCVYCIl9YB8ASlOMGAcROTF7ynzgKlwwtJduLHeVjy5xyezXHIg44ClOEuxb + LuGqUJmK1L26UrG8MTUvfDtUliajM5oFIcDIC88FFC5ABYQKgEhRjStrfm8zacvX8SLRV6wMOD0/ + 7xZAl6Arj/2Vvbqy8b9l0P+qMFySX8V0yZT+rtHGeQ5/aLicKI8CgkTGikG32KPTiJ+79iRodGNn + Go8rhz6e7O3e8OD4Pagb83Vz3u5VcW2w34wnrZKGFng+3IztipmNuLNuNzXBXjaPsJM2K+Y8NjV4 + 56D8xq8vWqP1tlWdtILDzoCbjtEYizbcJWYcoGbfRp342W7OXp9MWofxtLuP7yHa2eOAh0Hc3bTr + ndFo3XshvYFt3y1qs+72rhUbpXt92o9LB990arA0Ek8D2HRgtFo0N/1QHx60+7rood1I6MOXfDZ+ + 6IeN0nzYbze2lSq58R6i6npq394qx/L3z45fi105HZYy+//WHj/L5gqaLhlGcs1kMEz8pew0Uc4E + x7sME09mJVmSlJXstLrWmxKRNBNLQWNMuGKZutxK+Zfx0pOhRETJ8r1Au/CS9n/maCZ+RHRoXmFL + HwsUJbxIfVnwb3Ko6ZXj8fgF8IHzCoYEAAA= headers: CF-RAY: - 920acf24eb2b6410-ALA diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_legacy.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_legacy.yaml index 97f9e7277c..e84f2c642f 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_legacy.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_legacy.yaml @@ -46,18 +46,18 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA3yTXVPiMBSG/0omN17YutCKQGe8gLYCgivysYjLDhPSQxNbEkxSatfhv+8UZXZd - Ha+SOc/J+XjnzQvmEfbwRsfLSrXvOq5fz7Svi/jZudpmNSX0NbawKbZQZoHWJAZsYSXTMkC05toQ - YbCFNzKCFHuYpiSLwHbtuq2lEGBsp+LUKk61iS1MpTAgDPZ+vhyLGsZFwkVctjlePTwAgzaAqMyE - QYYBEtlmBQrJNTJ8A/oQS8EYUOhEnSCy3QJRGnFxILlUEVpgbRTJV6BUscBnC7EQk88Z4hrpLaQp - RB7StrGVTezcXtlgK1vZRfn0OBEDmqC1VAgIZWVvbyGqZ6isbBhX0XEqrku4EM4rAx4zw/6H7isU - XHxkCzGW5TIKEFGAXMRFqTUFfVDh/f5f7I0trHksiMlUqXeopm0/mfdao9jvJX6yGnSTaTen4UOb - cz6hj4zcnzp6eO+uHdNQNy3d9H2T0Fpj3aVJeMp+V9vudHg6rMdXRaCCRrP9EM4DGd6RkK7MxV23 - 9T2M8+wpHT/mbVl01mG+Hk1JMPR3g1EluT4vJjcDh414Lw9YZ9Lv3c4N8xtsRDq5QypmnM9qznVz - 56r6MzWBX/SmrMI746K+I80GPBQjqN12ZrVJIPusCvPbps+/tURjEN7sguZqZvqz2Yj0dfWRPxY/ - Lla9nn66u7zEe+uv5+C5tOzh8PDkcyu5b077Str9LwtrI7dLBURLgT0MIlqaTAn8BjQ8ZSAoYE9k - aWrh7PCDvBfMxTYzSyMTEBp7NcfClFAGS6qAGC7F8n1C5cgVkOgjk5n5N1I9r+33fwAAAP//AwBI - 0+K+3AMAAA== + H4sIAAAAAAAC/31TXXOiMBT9Kxle+tDSRShVmemDAlWr3Vo/1tp1x4lwhQgmmgQp2/G/b7B1uv2Y + PjDJnHNz7r2He581EmqOthbR3Kh0LdNyq5lwRRE9mdebzOZU3Ghnmiw2UEaBEDgCBXCWlgAWggiJ + qVTQmoWQKixIcRaCbulVXTBKQeqmYdqGWamroIBRCSrc+f18FJUxoQmhUZnmeHW0Hki0BhSwjEok + Y0A0Wy+AI7ZEkqg6DlgKUirshJ8gvNkA5gIRemByxkM004TkOFfPeDHTzmd0Rkdfc4gIJDaQphA6 + SOhS5zrWc32hg7pxvSifHiuKIUjQknEEOIjL3M6MVs5RqazqV9KvVSlJRc6o+cIBiWIZfyStF5IS + +pmb0SErm+GAsPos1VvpdaCaL1143/83fStjBYkolhkv/fb5uOkm005jELmdxE0WvXYybueB/9gk + hIyCVYwfTk3Rf7CWpqzx24aou65MAru2bAeJfxr/rTStcf+0X42uC497tXrz0Z96zL/HfrCQl/ft + xk8/yrNtOlzlTVa0ln6+HIyx13d3vYGR3FwUo9ueGQ9IJ/fi1qjbuZvK2K3FA9zKTWzIYT6xzZv6 + zuLVp0B6btEZxwZpDYvqDtdr8FgMwL5rTeyRx7pxBaZ3dZf8aNBaz7/defXFRHYnkwHuisqKrIpf + l4tOR2zvr660/dnbzMFTObKHw9FGX4+S9Tpp31m7/6PMlWwz54DVtCsxoOFcOU21V0LANgP10zSH + Zml6pmWHDXKeNUI3mZxLlgAVmmObajnUQME8UFKSMDp/H2AceUWHnzmWyf+RyoX9AZuHIDFJRZn6 + uGdv4YZ5sd/v/wFfwnTUDQQAAA== headers: CF-RAY: - 920c28c8fa7eeceb-ALA diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_legacy.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_legacy.yaml index a0cda1e181..8fe45c3dd4 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_legacy.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_legacy.yaml @@ -200,7 +200,7 @@ interactions: event: message_delta - data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":238} } + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":238,"output_tokens_details":{"thinking_tokens":1024}} } event: message_stop diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_with_events_with_content.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_with_events_with_content.yaml index a0cda1e181..8fe45c3dd4 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_with_events_with_content.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_with_events_with_content.yaml @@ -200,7 +200,7 @@ interactions: event: message_delta - data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":238} } + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":238,"output_tokens_details":{"thinking_tokens":1024}} } event: message_stop diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_with_events_with_no_content.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_with_events_with_no_content.yaml index a0cda1e181..8fe45c3dd4 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_with_events_with_no_content.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_streaming_with_events_with_no_content.yaml @@ -200,7 +200,7 @@ interactions: event: message_delta - data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":238} } + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":238,"output_tokens_details":{"thinking_tokens":1024}} } event: message_stop diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_with_events_with_content.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_with_events_with_content.yaml index 97f9e7277c..e84f2c642f 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_with_events_with_content.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_with_events_with_content.yaml @@ -46,18 +46,18 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA3yTXVPiMBSG/0omN17YutCKQGe8gLYCgivysYjLDhPSQxNbEkxSatfhv+8UZXZd - Ha+SOc/J+XjnzQvmEfbwRsfLSrXvOq5fz7Svi/jZudpmNSX0NbawKbZQZoHWJAZsYSXTMkC05toQ - YbCFNzKCFHuYpiSLwHbtuq2lEGBsp+LUKk61iS1MpTAgDPZ+vhyLGsZFwkVctjlePTwAgzaAqMyE - QYYBEtlmBQrJNTJ8A/oQS8EYUOhEnSCy3QJRGnFxILlUEVpgbRTJV6BUscBnC7EQk88Z4hrpLaQp - RB7StrGVTezcXtlgK1vZRfn0OBEDmqC1VAgIZWVvbyGqZ6isbBhX0XEqrku4EM4rAx4zw/6H7isU - XHxkCzGW5TIKEFGAXMRFqTUFfVDh/f5f7I0trHksiMlUqXeopm0/mfdao9jvJX6yGnSTaTen4UOb - cz6hj4zcnzp6eO+uHdNQNy3d9H2T0Fpj3aVJeMp+V9vudHg6rMdXRaCCRrP9EM4DGd6RkK7MxV23 - 9T2M8+wpHT/mbVl01mG+Hk1JMPR3g1EluT4vJjcDh414Lw9YZ9Lv3c4N8xtsRDq5QypmnM9qznVz - 56r6MzWBX/SmrMI746K+I80GPBQjqN12ZrVJIPusCvPbps+/tURjEN7sguZqZvqz2Yj0dfWRPxY/ - Lla9nn66u7zEe+uv5+C5tOzh8PDkcyu5b077Str9LwtrI7dLBURLgT0MIlqaTAn8BjQ8ZSAoYE9k - aWrh7PCDvBfMxTYzSyMTEBp7NcfClFAGS6qAGC7F8n1C5cgVkOgjk5n5N1I9r+33fwAAAP//AwBI - 0+K+3AMAAA== + H4sIAAAAAAAC/31TXXOiMBT9Kxle+tDSRShVmemDAlWr3Vo/1tp1x4lwhQgmmgQp2/G/b7B1uv2Y + PjDJnHNz7r2He581EmqOthbR3Kh0LdNyq5lwRRE9mdebzOZU3Ghnmiw2UEaBEDgCBXCWlgAWggiJ + qVTQmoWQKixIcRaCbulVXTBKQeqmYdqGWamroIBRCSrc+f18FJUxoQmhUZnmeHW0Hki0BhSwjEok + Y0A0Wy+AI7ZEkqg6DlgKUirshJ8gvNkA5gIRemByxkM004TkOFfPeDHTzmd0Rkdfc4gIJDaQphA6 + SOhS5zrWc32hg7pxvSifHiuKIUjQknEEOIjL3M6MVs5RqazqV9KvVSlJRc6o+cIBiWIZfyStF5IS + +pmb0SErm+GAsPos1VvpdaCaL1143/83fStjBYkolhkv/fb5uOkm005jELmdxE0WvXYybueB/9gk + hIyCVYwfTk3Rf7CWpqzx24aou65MAru2bAeJfxr/rTStcf+0X42uC497tXrz0Z96zL/HfrCQl/ft + xk8/yrNtOlzlTVa0ln6+HIyx13d3vYGR3FwUo9ueGQ9IJ/fi1qjbuZvK2K3FA9zKTWzIYT6xzZv6 + zuLVp0B6btEZxwZpDYvqDtdr8FgMwL5rTeyRx7pxBaZ3dZf8aNBaz7/defXFRHYnkwHuisqKrIpf + l4tOR2zvr660/dnbzMFTObKHw9FGX4+S9Tpp31m7/6PMlWwz54DVtCsxoOFcOU21V0LANgP10zSH + Zml6pmWHDXKeNUI3mZxLlgAVmmObajnUQME8UFKSMDp/H2AceUWHnzmWyf+RyoX9AZuHIDFJRZn6 + uGdv4YZ5sd/v/wFfwnTUDQQAAA== headers: CF-RAY: - 920c28c8fa7eeceb-ALA diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_with_events_with_no_content.yaml b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_with_events_with_no_content.yaml index 97f9e7277c..e84f2c642f 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_with_events_with_no_content.yaml +++ b/packages/opentelemetry-instrumentation-anthropic/tests/cassettes/test_thinking/test_async_anthropic_thinking_with_events_with_no_content.yaml @@ -46,18 +46,18 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA3yTXVPiMBSG/0omN17YutCKQGe8gLYCgivysYjLDhPSQxNbEkxSatfhv+8UZXZd - Ha+SOc/J+XjnzQvmEfbwRsfLSrXvOq5fz7Svi/jZudpmNSX0NbawKbZQZoHWJAZsYSXTMkC05toQ - YbCFNzKCFHuYpiSLwHbtuq2lEGBsp+LUKk61iS1MpTAgDPZ+vhyLGsZFwkVctjlePTwAgzaAqMyE - QYYBEtlmBQrJNTJ8A/oQS8EYUOhEnSCy3QJRGnFxILlUEVpgbRTJV6BUscBnC7EQk88Z4hrpLaQp - RB7StrGVTezcXtlgK1vZRfn0OBEDmqC1VAgIZWVvbyGqZ6isbBhX0XEqrku4EM4rAx4zw/6H7isU - XHxkCzGW5TIKEFGAXMRFqTUFfVDh/f5f7I0trHksiMlUqXeopm0/mfdao9jvJX6yGnSTaTen4UOb - cz6hj4zcnzp6eO+uHdNQNy3d9H2T0Fpj3aVJeMp+V9vudHg6rMdXRaCCRrP9EM4DGd6RkK7MxV23 - 9T2M8+wpHT/mbVl01mG+Hk1JMPR3g1EluT4vJjcDh414Lw9YZ9Lv3c4N8xtsRDq5QypmnM9qznVz - 56r6MzWBX/SmrMI746K+I80GPBQjqN12ZrVJIPusCvPbps+/tURjEN7sguZqZvqz2Yj0dfWRPxY/ - Lla9nn66u7zEe+uv5+C5tOzh8PDkcyu5b077Str9LwtrI7dLBURLgT0MIlqaTAn8BjQ8ZSAoYE9k - aWrh7PCDvBfMxTYzSyMTEBp7NcfClFAGS6qAGC7F8n1C5cgVkOgjk5n5N1I9r+33fwAAAP//AwBI - 0+K+3AMAAA== + H4sIAAAAAAAC/31TXXOiMBT9Kxle+tDSRShVmemDAlWr3Vo/1tp1x4lwhQgmmgQp2/G/b7B1uv2Y + PjDJnHNz7r2He581EmqOthbR3Kh0LdNyq5lwRRE9mdebzOZU3Ghnmiw2UEaBEDgCBXCWlgAWggiJ + qVTQmoWQKixIcRaCbulVXTBKQeqmYdqGWamroIBRCSrc+f18FJUxoQmhUZnmeHW0Hki0BhSwjEok + Y0A0Wy+AI7ZEkqg6DlgKUirshJ8gvNkA5gIRemByxkM004TkOFfPeDHTzmd0Rkdfc4gIJDaQphA6 + SOhS5zrWc32hg7pxvSifHiuKIUjQknEEOIjL3M6MVs5RqazqV9KvVSlJRc6o+cIBiWIZfyStF5IS + +pmb0SErm+GAsPos1VvpdaCaL1143/83fStjBYkolhkv/fb5uOkm005jELmdxE0WvXYybueB/9gk + hIyCVYwfTk3Rf7CWpqzx24aou65MAru2bAeJfxr/rTStcf+0X42uC497tXrz0Z96zL/HfrCQl/ft + xk8/yrNtOlzlTVa0ln6+HIyx13d3vYGR3FwUo9ueGQ9IJ/fi1qjbuZvK2K3FA9zKTWzIYT6xzZv6 + zuLVp0B6btEZxwZpDYvqDtdr8FgMwL5rTeyRx7pxBaZ3dZf8aNBaz7/defXFRHYnkwHuisqKrIpf + l4tOR2zvr660/dnbzMFTObKHw9FGX4+S9Tpp31m7/6PMlWwz54DVtCsxoOFcOU21V0LANgP10zSH + Zml6pmWHDXKeNUI3mZxLlgAVmmObajnUQME8UFKSMDp/H2AceUWHnzmWyf+RyoX9AZuHIDFJRZn6 + uGdv4YZ5sd/v/wFfwnTUDQQAAA== headers: CF-RAY: - 920c28c8fa7eeceb-ALA diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py b/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py index d321ce700f..240bc8789b 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py +++ b/packages/opentelemetry-instrumentation-anthropic/tests/test_thinking.py @@ -1,12 +1,6 @@ import json -from types import SimpleNamespace -from unittest.mock import Mock import pytest -from opentelemetry.instrumentation.anthropic import _set_token_usage -from opentelemetry.instrumentation.anthropic.streaming import ( - _set_token_usage as _set_stream_token_usage, -) from opentelemetry.sdk._logs import ReadableLogRecord from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAIAttributes, @@ -16,46 +10,6 @@ from .utils import verify_metrics -def test_reasoning_tokens_are_recorded_for_non_streaming_response(): - """Verify reasoning tokens are recorded for a regular response.""" - span = Mock() - response = SimpleNamespace( - usage=SimpleNamespace( - input_tokens=10, - output_tokens=20, - output_tokens_details=SimpleNamespace(reasoning_tokens=7), - ), - content=[], - completion=None, - stop_reason=None, - ) - - _set_token_usage(span, None, {}, response) - - span.set_attribute.assert_any_call( - SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS, 7 - ) - - -def test_reasoning_tokens_are_recorded_for_streaming_response(): - """Verify reasoning tokens are recorded for a streaming response.""" - span = Mock() - complete_response = { - "usage": { - "input_tokens": 10, - "output_tokens": 20, - "output_tokens_details": {"reasoning_tokens": 7}, - }, - "events": [], - } - - _set_stream_token_usage(span, complete_response, 10, 20) - - span.set_attribute.assert_any_call( - SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS, 7 - ) - - @pytest.mark.vcr def test_anthropic_thinking_legacy( instrument_legacy, anthropic_client, span_exporter, log_exporter, reader @@ -86,6 +40,7 @@ def test_anthropic_thinking_legacy( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 input_messages = json.loads(anthropic_span.attributes[GenAIAttributes.GEN_AI_INPUT_MESSAGES]) assert input_messages[0]["role"] == "user" assert input_messages[0]["parts"][0]["content"] == prompt @@ -138,6 +93,7 @@ def test_anthropic_thinking_with_events_with_content( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 metrics_data = reader.get_metrics_data() resource_metrics = metrics_data.resource_metrics @@ -205,6 +161,7 @@ def test_anthropic_thinking_with_events_with_no_content( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 metrics_data = reader.get_metrics_data() resource_metrics = metrics_data.resource_metrics @@ -265,6 +222,7 @@ async def test_async_anthropic_thinking_legacy( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 input_messages = json.loads(anthropic_span.attributes[GenAIAttributes.GEN_AI_INPUT_MESSAGES]) assert input_messages[0]["role"] == "user" assert input_messages[0]["parts"][0]["content"] == prompt @@ -318,6 +276,7 @@ async def test_async_anthropic_thinking_with_events_with_content( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 metrics_data = reader.get_metrics_data() resource_metrics = metrics_data.resource_metrics @@ -389,6 +348,7 @@ async def test_async_anthropic_thinking_with_events_with_no_content( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 metrics_data = reader.get_metrics_data() resource_metrics = metrics_data.resource_metrics @@ -460,6 +420,7 @@ def test_anthropic_thinking_streaming_legacy( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 input_messages = json.loads(anthropic_span.attributes[GenAIAttributes.GEN_AI_INPUT_MESSAGES]) assert input_messages[0]["role"] == "user" assert input_messages[0]["parts"][0]["content"] == prompt @@ -523,6 +484,7 @@ def test_anthropic_thinking_streaming_with_events_with_content( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 metrics_data = reader.get_metrics_data() resource_metrics = metrics_data.resource_metrics @@ -608,6 +570,7 @@ def test_anthropic_thinking_streaming_with_events_with_no_content( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 metrics_data = reader.get_metrics_data() resource_metrics = metrics_data.resource_metrics @@ -680,6 +643,7 @@ async def test_async_anthropic_thinking_streaming_legacy( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 input_messages = json.loads(anthropic_span.attributes[GenAIAttributes.GEN_AI_INPUT_MESSAGES]) assert input_messages[0]["role"] == "user" assert input_messages[0]["parts"][0]["content"] == prompt @@ -744,6 +708,7 @@ async def test_async_anthropic_thinking_streaming_with_events_with_content( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 metrics_data = reader.get_metrics_data() resource_metrics = metrics_data.resource_metrics @@ -835,6 +800,7 @@ async def test_async_anthropic_thinking_streaming_with_events_with_no_content( anthropic_span = spans[0] assert anthropic_span.name == "anthropic.chat" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_REASONING_TOKENS] == 1024 metrics_data = reader.get_metrics_data() resource_metrics = metrics_data.resource_metrics