From 34ec2dd561841227510a534c4569492155260e69 Mon Sep 17 00:00:00 2001 From: Erica Pisani Date: Fri, 13 Mar 2026 10:15:12 +0000 Subject: [PATCH] feat(anthropic): Add `gen_ai.system` attribute to spans Set the `gen_ai.system` span attribute to "anthropic" for consistency with other AI integrations (OpenAI, Langchain, Google GenAI) that already include this attribute. Refs PY-2135 Co-Authored-By: Claude Opus 4.6 --- sentry_sdk/integrations/anthropic.py | 1 + tests/integrations/anthropic/test_anthropic.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index 0aa812cab3..37ace1a64a 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -247,6 +247,7 @@ def _set_input_data( """ Set input data for the span based on the provided keyword arguments for the anthropic message creation. """ + span.set_data(SPANDATA.GEN_AI_SYSTEM, "anthropic") span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "chat") system_instructions: "Union[str, Iterable[TextBlockParam]]" = kwargs.get("system") # type: ignore messages = kwargs.get("messages") diff --git a/tests/integrations/anthropic/test_anthropic.py b/tests/integrations/anthropic/test_anthropic.py index ea48f5d4db..1c9ddfa3c7 100644 --- a/tests/integrations/anthropic/test_anthropic.py +++ b/tests/integrations/anthropic/test_anthropic.py @@ -117,6 +117,7 @@ def test_nonstreaming_create_message( assert span["op"] == OP.GEN_AI_CHAT assert span["description"] == "chat model" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" @@ -187,6 +188,7 @@ async def test_nonstreaming_create_message_async( assert span["op"] == OP.GEN_AI_CHAT assert span["description"] == "chat model" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" @@ -288,6 +290,7 @@ def test_streaming_create_message( assert span["op"] == OP.GEN_AI_CHAT assert span["description"] == "chat model" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" @@ -393,6 +396,7 @@ async def test_streaming_create_message_async( assert span["op"] == OP.GEN_AI_CHAT assert span["description"] == "chat model" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" @@ -525,6 +529,7 @@ def test_streaming_create_message_with_input_json_delta( assert span["op"] == OP.GEN_AI_CHAT assert span["description"] == "chat model" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" @@ -666,6 +671,7 @@ async def test_streaming_create_message_with_input_json_delta_async( assert span["op"] == OP.GEN_AI_CHAT assert span["description"] == "chat model" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" @@ -730,6 +736,7 @@ def test_span_status_error(sentry_init, capture_events): assert transaction["spans"][0]["status"] == "internal_error" assert transaction["spans"][0]["tags"]["status"] == "internal_error" assert transaction["contexts"]["trace"]["status"] == "internal_error" + assert transaction["spans"][0]["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert transaction["spans"][0]["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" @@ -755,6 +762,7 @@ async def test_span_status_error_async(sentry_init, capture_events): assert transaction["spans"][0]["status"] == "internal_error" assert transaction["spans"][0]["tags"]["status"] == "internal_error" assert transaction["contexts"]["trace"]["status"] == "internal_error" + assert transaction["spans"][0]["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert transaction["spans"][0]["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" @@ -803,6 +811,7 @@ def test_span_origin(sentry_init, capture_events): assert event["contexts"]["trace"]["origin"] == "manual" assert event["spans"][0]["origin"] == "auto.ai.anthropic" + assert event["spans"][0]["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert event["spans"][0]["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" @@ -831,6 +840,7 @@ async def test_span_origin_async(sentry_init, capture_events): assert event["contexts"]["trace"]["origin"] == "manual" assert event["spans"][0]["origin"] == "auto.ai.anthropic" + assert event["spans"][0]["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert event["spans"][0]["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" @@ -951,6 +961,7 @@ def mock_messages_create(*args, **kwargs): # Verify that the span was created correctly assert span["op"] == "gen_ai.chat" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] @@ -996,6 +1007,7 @@ def test_anthropic_message_truncation(sentry_init, capture_events): assert len(chat_spans) > 0 chat_span = chat_spans[0] + assert chat_span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert chat_span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert SPANDATA.GEN_AI_REQUEST_MESSAGES in chat_span["data"] @@ -1047,6 +1059,7 @@ async def test_anthropic_message_truncation_async(sentry_init, capture_events): assert len(chat_spans) > 0 chat_span = chat_spans[0] + assert chat_span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert chat_span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert SPANDATA.GEN_AI_REQUEST_MESSAGES in chat_span["data"] @@ -1115,6 +1128,7 @@ def test_nonstreaming_create_message_with_system_prompt( assert span["op"] == OP.GEN_AI_CHAT assert span["description"] == "chat model" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" @@ -1199,6 +1213,7 @@ async def test_nonstreaming_create_message_with_system_prompt_async( assert span["op"] == OP.GEN_AI_CHAT assert span["description"] == "chat model" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" @@ -1315,6 +1330,7 @@ def test_streaming_create_message_with_system_prompt( assert span["op"] == OP.GEN_AI_CHAT assert span["description"] == "chat model" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" @@ -1435,6 +1451,7 @@ async def test_streaming_create_message_with_system_prompt_async( assert span["op"] == OP.GEN_AI_CHAT assert span["description"] == "chat model" + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" @@ -1501,6 +1518,7 @@ def test_system_prompt_with_complex_structure(sentry_init, capture_events): assert len(event["spans"]) == 1 (span,) = event["spans"] + assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic" assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"]