From 4c31b521e14250178413546bbbed55c8763e6116 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Wed, 21 Jan 2026 10:51:58 +0100 Subject: [PATCH 01/11] feat(anthropic): Set system instruction attribute --- sentry_sdk/integrations/anthropic.py | 25 +----- .../integrations/anthropic/test_anthropic.py | 82 ++++++++++--------- 2 files changed, 46 insertions(+), 61 deletions(-) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index 2bc48e54e3..c20d3cd7cd 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -192,29 +192,12 @@ def _set_input_data( and should_send_default_pii() and integration.include_prompts ): - normalized_messages = [] if system_prompt: - system_prompt_content: "Optional[Union[str, List[dict[str, Any]]]]" = None - if isinstance(system_prompt, str): - system_prompt_content = system_prompt - elif isinstance(system_prompt, Iterable): - system_prompt_content = [] - for item in system_prompt: - if ( - isinstance(item, dict) - and item.get("type") == "text" - and item.get("text") - ): - system_prompt_content.append(item.copy()) - - if system_prompt_content: - normalized_messages.append( - { - "role": GEN_AI_ALLOWED_MESSAGE_ROLES.SYSTEM, - "content": system_prompt_content, - } - ) + set_data_normalized( + span, SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS, system_prompt, unpack=False + ) + normalized_messages = [] for message in messages: if ( message.get("role") == GEN_AI_ALLOWED_MESSAGE_ROLES.USER diff --git a/tests/integrations/anthropic/test_anthropic.py b/tests/integrations/anthropic/test_anthropic.py index e8bc4648b6..ec0bbbfec9 100644 --- a/tests/integrations/anthropic/test_anthropic.py +++ b/tests/integrations/anthropic/test_anthropic.py @@ -1074,15 +1074,15 @@ def test_nonstreaming_create_message_with_system_prompt( assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" if send_default_pii and include_prompts: + assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] + system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] + assert system_instructions == "You are a helpful assistant." + assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) - assert len(stored_messages) == 2 - # System message should be first - assert stored_messages[0]["role"] == "system" - assert stored_messages[0]["content"] == "You are a helpful assistant." - # User message should be second - assert stored_messages[1]["role"] == "user" - assert stored_messages[1]["content"] == "Hello, Claude" + assert len(stored_messages) == 1 + assert stored_messages[0]["role"] == "user" + assert stored_messages[0]["content"] == "Hello, Claude" assert span["data"][SPANDATA.GEN_AI_RESPONSE_TEXT] == "Hi, I'm Claude." else: assert SPANDATA.GEN_AI_REQUEST_MESSAGES not in span["data"] @@ -1153,15 +1153,15 @@ async def test_nonstreaming_create_message_with_system_prompt_async( assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" if send_default_pii and include_prompts: + assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] + system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] + assert system_instructions == "You are a helpful assistant." + assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) - assert len(stored_messages) == 2 - # System message should be first - assert stored_messages[0]["role"] == "system" - assert stored_messages[0]["content"] == "You are a helpful assistant." - # User message should be second - assert stored_messages[1]["role"] == "user" - assert stored_messages[1]["content"] == "Hello, Claude" + assert len(stored_messages) == 1 + assert stored_messages[0]["role"] == "user" + assert stored_messages[0]["content"] == "Hello, Claude" assert span["data"][SPANDATA.GEN_AI_RESPONSE_TEXT] == "Hi, I'm Claude." else: assert SPANDATA.GEN_AI_REQUEST_MESSAGES not in span["data"] @@ -1264,15 +1264,15 @@ def test_streaming_create_message_with_system_prompt( assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" if send_default_pii and include_prompts: + assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] + system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] + assert system_instructions == "You are a helpful assistant." + assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) - assert len(stored_messages) == 2 - # System message should be first - assert stored_messages[0]["role"] == "system" - assert stored_messages[0]["content"] == "You are a helpful assistant." - # User message should be second - assert stored_messages[1]["role"] == "user" - assert stored_messages[1]["content"] == "Hello, Claude" + assert len(stored_messages) == 1 + assert stored_messages[0]["role"] == "user" + assert stored_messages[0]["content"] == "Hello, Claude" assert span["data"][SPANDATA.GEN_AI_RESPONSE_TEXT] == "Hi! I'm Claude!" else: @@ -1379,15 +1379,15 @@ async def test_streaming_create_message_with_system_prompt_async( assert span["data"][SPANDATA.GEN_AI_REQUEST_MODEL] == "model" if send_default_pii and include_prompts: + assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] + system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] + assert system_instructions == "You are a helpful assistant." + assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) - assert len(stored_messages) == 2 - # System message should be first - assert stored_messages[0]["role"] == "system" - assert stored_messages[0]["content"] == "You are a helpful assistant." - # User message should be second - assert stored_messages[1]["role"] == "user" - assert stored_messages[1]["content"] == "Hello, Claude" + assert len(stored_messages) == 1 + assert stored_messages[0]["role"] == "user" + assert stored_messages[0]["content"] == "Hello, Claude" assert span["data"][SPANDATA.GEN_AI_RESPONSE_TEXT] == "Hi! I'm Claude!" else: @@ -1437,21 +1437,23 @@ def test_system_prompt_with_complex_structure(sentry_init, capture_events): (span,) = event["spans"] assert span["data"][SPANDATA.GEN_AI_OPERATION_NAME] == "chat" + + assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] + system_instructions = json.loads(span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS]) + + # System content should be a list of text blocks + assert isinstance(system_instructions, list) + assert system_instructions[0]["type"] == "text" + assert system_instructions[0]["text"] == "You are a helpful assistant." + assert system_instructions[1]["type"] == "text" + assert system_instructions[1]["text"] == "Be concise and clear." + assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) - # Should have system message first, then user message - assert len(stored_messages) == 2 - assert stored_messages[0]["role"] == "system" - # System content should be a list of text blocks - assert isinstance(stored_messages[0]["content"], list) - assert len(stored_messages[0]["content"]) == 2 - assert stored_messages[0]["content"][0]["type"] == "text" - assert stored_messages[0]["content"][0]["text"] == "You are a helpful assistant." - assert stored_messages[0]["content"][1]["type"] == "text" - assert stored_messages[0]["content"][1]["text"] == "Be concise and clear." - assert stored_messages[1]["role"] == "user" - assert stored_messages[1]["content"] == "Hello" + assert len(stored_messages) == 1 + assert stored_messages[0]["role"] == "user" + assert stored_messages[0]["content"] == "Hello" # Tests for transform_content_part (shared) and _transform_anthropic_content_block helper functions From f39d8b9e0617a50cf4bb6ee06a35a6815bb66f1c Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Wed, 21 Jan 2026 10:52:33 +0100 Subject: [PATCH 02/11] add const --- sentry_sdk/consts.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 93fca6ba3e..c30392d344 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -542,6 +542,12 @@ class SPANDATA: Example: 2048 """ + GEN_AI_SYSTEM_INSTRUCTIONS = "gen_ai.system_instructions" + """ + The system instructions passed to the model. + Example: {"role": "system", "content": "You are a helpful assistant"} + """ + GEN_AI_REQUEST_MESSAGES = "gen_ai.request.messages" """ The messages passed to the model. The "content" can be a string or an array of objects. From 9ad123374de755df65efaa0560b5d767234d7869 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Wed, 21 Jan 2026 10:57:08 +0100 Subject: [PATCH 03/11] update example --- sentry_sdk/consts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index c30392d344..4b61a317fb 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -545,7 +545,7 @@ class SPANDATA: GEN_AI_SYSTEM_INSTRUCTIONS = "gen_ai.system_instructions" """ The system instructions passed to the model. - Example: {"role": "system", "content": "You are a helpful assistant"} + Example: [{"type": "text", "text": "You are a helpful assistant."},{"type": "text", "text": "Be concise and clear."}] """ GEN_AI_REQUEST_MESSAGES = "gen_ai.request.messages" From 167e231e438f17e03bfc6aecee3a90abec599102 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Wed, 21 Jan 2026 11:17:28 +0100 Subject: [PATCH 04/11] . --- tests/integrations/anthropic/test_anthropic.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/integrations/anthropic/test_anthropic.py b/tests/integrations/anthropic/test_anthropic.py index ec0bbbfec9..460995e108 100644 --- a/tests/integrations/anthropic/test_anthropic.py +++ b/tests/integrations/anthropic/test_anthropic.py @@ -1085,6 +1085,7 @@ def test_nonstreaming_create_message_with_system_prompt( assert stored_messages[0]["content"] == "Hello, Claude" assert span["data"][SPANDATA.GEN_AI_RESPONSE_TEXT] == "Hi, I'm Claude." else: + assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS not in span["data"] assert SPANDATA.GEN_AI_REQUEST_MESSAGES not in span["data"] assert SPANDATA.GEN_AI_RESPONSE_TEXT not in span["data"] @@ -1164,6 +1165,7 @@ async def test_nonstreaming_create_message_with_system_prompt_async( assert stored_messages[0]["content"] == "Hello, Claude" assert span["data"][SPANDATA.GEN_AI_RESPONSE_TEXT] == "Hi, I'm Claude." else: + assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS not in span["data"] assert SPANDATA.GEN_AI_REQUEST_MESSAGES not in span["data"] assert SPANDATA.GEN_AI_RESPONSE_TEXT not in span["data"] @@ -1276,6 +1278,7 @@ def test_streaming_create_message_with_system_prompt( assert span["data"][SPANDATA.GEN_AI_RESPONSE_TEXT] == "Hi! I'm Claude!" else: + assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS not in span["data"] assert SPANDATA.GEN_AI_REQUEST_MESSAGES not in span["data"] assert SPANDATA.GEN_AI_RESPONSE_TEXT not in span["data"] @@ -1391,6 +1394,7 @@ async def test_streaming_create_message_with_system_prompt_async( assert span["data"][SPANDATA.GEN_AI_RESPONSE_TEXT] == "Hi! I'm Claude!" else: + assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS not in span["data"] assert SPANDATA.GEN_AI_REQUEST_MESSAGES not in span["data"] assert SPANDATA.GEN_AI_RESPONSE_TEXT not in span["data"] From ff9b77c41c11bf9164bdbe999c3555b9605f65ea Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Thu, 22 Jan 2026 08:43:22 +0100 Subject: [PATCH 05/11] . --- sentry_sdk/integrations/anthropic.py | 33 ++++++++++++++++--- .../integrations/anthropic/test_anthropic.py | 28 +++++++++++----- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index c20d3cd7cd..e9b8fb8621 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -39,13 +39,14 @@ from anthropic.resources import AsyncMessages, Messages if TYPE_CHECKING: - from anthropic.types import MessageStreamEvent + from anthropic.types import MessageStreamEvent, TextBlockParam except ImportError: raise DidNotEnable("Anthropic not installed") if TYPE_CHECKING: from typing import Any, AsyncIterator, Iterator, List, Optional, Union from sentry_sdk.tracing import Span + from sentry_sdk._types import TextPart class AnthropicIntegration(Integration): @@ -177,6 +178,27 @@ def _transform_anthropic_content_block( return result if result is not None else content_block +def _transform_system_instructions( + system_instructions: "Union[str, Iterable[TextBlockParam]]", +) -> "list[TextPart]": + if isinstance(system_instructions, str): + return [ + { + "type": "text", + "content": system_instructions, + } + ] + + return [ + { + "type": "text", + "content": instruction["text"], # type: ignore + } + for instruction in system_instructions + if "text" in instruction + ] + + def _set_input_data( span: "Span", kwargs: "dict[str, Any]", integration: "AnthropicIntegration" ) -> None: @@ -184,7 +206,7 @@ def _set_input_data( Set input data for the span based on the provided keyword arguments for the anthropic message creation. """ set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "chat") - system_prompt = kwargs.get("system") + system_instructions: "Union[str, Iterable[TextBlockParam]]" = kwargs.get("system") # type: ignore messages = kwargs.get("messages") if ( messages is not None @@ -192,9 +214,12 @@ def _set_input_data( and should_send_default_pii() and integration.include_prompts ): - if system_prompt: + if system_instructions: set_data_normalized( - span, SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS, system_prompt, unpack=False + span, + SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS, + _transform_system_instructions(system_instructions), + unpack=False, ) normalized_messages = [] diff --git a/tests/integrations/anthropic/test_anthropic.py b/tests/integrations/anthropic/test_anthropic.py index 460995e108..cf1aef5eb5 100644 --- a/tests/integrations/anthropic/test_anthropic.py +++ b/tests/integrations/anthropic/test_anthropic.py @@ -1076,7 +1076,10 @@ def test_nonstreaming_create_message_with_system_prompt( if send_default_pii and include_prompts: assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] - assert system_instructions == "You are a helpful assistant." + assert ( + system_instructions + == '[{"type": "text", "content": "You are a helpful assistant."}]' + ) assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) @@ -1156,7 +1159,10 @@ async def test_nonstreaming_create_message_with_system_prompt_async( if send_default_pii and include_prompts: assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] - assert system_instructions == "You are a helpful assistant." + assert ( + system_instructions + == '[{"type": "text", "content": "You are a helpful assistant."}]' + ) assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) @@ -1268,7 +1274,10 @@ def test_streaming_create_message_with_system_prompt( if send_default_pii and include_prompts: assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] - assert system_instructions == "You are a helpful assistant." + assert ( + system_instructions + == '[{"type": "text", "content": "You are a helpful assistant."}]' + ) assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) @@ -1384,7 +1393,10 @@ async def test_streaming_create_message_with_system_prompt_async( if send_default_pii and include_prompts: assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] - assert system_instructions == "You are a helpful assistant." + assert ( + system_instructions + == '[{"type": "text", "content": "You are a helpful assistant."}]' + ) assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) @@ -1447,10 +1459,10 @@ def test_system_prompt_with_complex_structure(sentry_init, capture_events): # System content should be a list of text blocks assert isinstance(system_instructions, list) - assert system_instructions[0]["type"] == "text" - assert system_instructions[0]["text"] == "You are a helpful assistant." - assert system_instructions[1]["type"] == "text" - assert system_instructions[1]["text"] == "Be concise and clear." + assert system_instructions == [ + {"type": "text", "content": "You are a helpful assistant."}, + {"type": "text", "content": "Be concise and clear."}, + ] assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) From 23a582c9dad38ffef1fe2a903afbde72a4379458 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Thu, 22 Jan 2026 08:44:01 +0100 Subject: [PATCH 06/11] push type --- sentry_sdk/_types.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sentry_sdk/_types.py b/sentry_sdk/_types.py index 7043bbc2ee..ecb8abcd10 100644 --- a/sentry_sdk/_types.py +++ b/sentry_sdk/_types.py @@ -359,3 +359,7 @@ class SDKInfo(TypedDict): ) HttpStatusCodeRange = Union[int, Container[int]] + + class TextPart(TypedDict): + type: Literal["text"] + content: str From aa1e7aaaafb7226262b6d38a222c30ba90dee0ee Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Thu, 22 Jan 2026 09:00:20 +0100 Subject: [PATCH 07/11] . --- .../integrations/anthropic/test_anthropic.py | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/tests/integrations/anthropic/test_anthropic.py b/tests/integrations/anthropic/test_anthropic.py index cf1aef5eb5..dc6d6ffda4 100644 --- a/tests/integrations/anthropic/test_anthropic.py +++ b/tests/integrations/anthropic/test_anthropic.py @@ -1075,11 +1075,12 @@ def test_nonstreaming_create_message_with_system_prompt( if send_default_pii and include_prompts: assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] - system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] - assert ( - system_instructions - == '[{"type": "text", "content": "You are a helpful assistant."}]' + system_instructions = json.loads( + span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] ) + assert system_instructions == [ + {"type": "text", "content": "You are a helpful assistant."} + ] assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) @@ -1158,11 +1159,12 @@ async def test_nonstreaming_create_message_with_system_prompt_async( if send_default_pii and include_prompts: assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] - system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] - assert ( - system_instructions - == '[{"type": "text", "content": "You are a helpful assistant."}]' + system_instructions = json.loads( + span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] ) + assert system_instructions == [ + {"type": "text", "content": "You are a helpful assistant."} + ] assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) @@ -1273,7 +1275,9 @@ def test_streaming_create_message_with_system_prompt( if send_default_pii and include_prompts: assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] - system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] + system_instructions = json.loads( + span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] + ) assert ( system_instructions == '[{"type": "text", "content": "You are a helpful assistant."}]' @@ -1392,11 +1396,12 @@ async def test_streaming_create_message_with_system_prompt_async( if send_default_pii and include_prompts: assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS in span["data"] - system_instructions = span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] - assert ( - system_instructions - == '[{"type": "text", "content": "You are a helpful assistant."}]' + system_instructions = json.loads( + span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] ) + assert system_instructions == [ + {"type": "text", "content": "You are a helpful assistant."} + ] assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) From 2478bd786dd0224786646bc9624d561ce11d78b2 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Thu, 22 Jan 2026 09:03:15 +0100 Subject: [PATCH 08/11] update test --- tests/integrations/anthropic/test_anthropic.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/integrations/anthropic/test_anthropic.py b/tests/integrations/anthropic/test_anthropic.py index dc6d6ffda4..0041aab928 100644 --- a/tests/integrations/anthropic/test_anthropic.py +++ b/tests/integrations/anthropic/test_anthropic.py @@ -1278,10 +1278,9 @@ def test_streaming_create_message_with_system_prompt( system_instructions = json.loads( span["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS] ) - assert ( - system_instructions - == '[{"type": "text", "content": "You are a helpful assistant."}]' - ) + assert system_instructions == [ + {"type": "text", "content": "You are a helpful assistant."} + ] assert SPANDATA.GEN_AI_REQUEST_MESSAGES in span["data"] stored_messages = json.loads(span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]) From 46aa328b0a37731cd42f356f407a173c874b42eb Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Thu, 22 Jan 2026 14:55:29 +0100 Subject: [PATCH 09/11] update existance check --- sentry_sdk/integrations/anthropic.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index e9b8fb8621..f213b90cef 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -214,7 +214,9 @@ def _set_input_data( and should_send_default_pii() and integration.include_prompts ): - if system_instructions: + if isinstance(system_instructions, str) or isinstance( + system_instructions, Iterable + ): set_data_normalized( span, SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS, From 3a90ad6e22b59035532760ff30e2f158e9eaaa83 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Thu, 22 Jan 2026 15:03:02 +0100 Subject: [PATCH 10/11] add dict check --- sentry_sdk/integrations/anthropic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index f213b90cef..5002d744e8 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -195,7 +195,7 @@ def _transform_system_instructions( "content": instruction["text"], # type: ignore } for instruction in system_instructions - if "text" in instruction + if isinstance(instruction, dict) and "text" in instruction ] From 19b24efcba7c9469ddeecd80065de1c6a201c170 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Thu, 22 Jan 2026 15:05:11 +0100 Subject: [PATCH 11/11] remove unused type ignore --- sentry_sdk/integrations/anthropic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index 5002d744e8..862f073cad 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -192,7 +192,7 @@ def _transform_system_instructions( return [ { "type": "text", - "content": instruction["text"], # type: ignore + "content": instruction["text"], } for instruction in system_instructions if isinstance(instruction, dict) and "text" in instruction