From 793064eb094b049783242cee93f58bf15ad026d7 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Thu, 29 Oct 2026 11:40:30 +0100 Subject: [PATCH] fix: Remove unpack parameter from set_data_normalized() --- sentry_sdk/ai/utils.py | 13 ++++----- sentry_sdk/integrations/anthropic.py | 2 -- sentry_sdk/integrations/google_genai/utils.py | 4 --- sentry_sdk/integrations/huggingface_hub.py | 14 +++------- sentry_sdk/integrations/langchain.py | 27 +++++-------------- sentry_sdk/integrations/langgraph.py | 5 ---- sentry_sdk/integrations/litellm.py | 2 -- sentry_sdk/integrations/openai.py | 26 +++++------------- .../openai_agents/spans/invoke_agent.py | 7 ++--- .../integrations/openai_agents/utils.py | 1 - .../pydantic_ai/spans/ai_client.py | 4 +-- .../pydantic_ai/spans/invoke_agent.py | 8 ++---- 12 files changed, 25 insertions(+), 88 deletions(-) diff --git a/sentry_sdk/ai/utils.py b/sentry_sdk/ai/utils.py index 7b1ca9324b..caaa4a03e0 100644 --- a/sentry_sdk/ai/utils.py +++ b/sentry_sdk/ai/utils.py @@ -463,7 +463,7 @@ def transform_message_content(content: "Any") -> "Any": return content -def _normalize_data(data: "Any", unpack: bool = True) -> "Any": +def _normalize_data(data: "Any") -> "Any": # convert pydantic data (e.g. OpenAI v1+) to json compatible format if hasattr(data, "model_dump"): # Check if it's a class (type) rather than an instance @@ -472,18 +472,16 @@ def _normalize_data(data: "Any", unpack: bool = True) -> "Any": return f"" try: - return _normalize_data(data.model_dump(), unpack=unpack) + return _normalize_data(data.model_dump()) except Exception as e: logger.warning("Could not convert pydantic data to JSON: %s", e) return data if isinstance(data, (int, float, bool, str)) else str(data) if isinstance(data, list): - if unpack and len(data) == 1: - return _normalize_data(data[0], unpack=unpack) # remove empty dimensions - return list(_normalize_data(x, unpack=unpack) for x in data) + return list(_normalize_data(x) for x in data) if isinstance(data, dict): - return {k: _normalize_data(v, unpack=unpack) for (k, v) in data.items()} + return {k: _normalize_data(v) for (k, v) in data.items()} return data if isinstance(data, (int, float, bool, str)) else str(data) @@ -492,9 +490,8 @@ def set_data_normalized( span: "Union[Span, StreamedSpan]", key: str, value: "Any", - unpack: bool = True, ) -> None: - normalized = _normalize_data(value, unpack=unpack) + normalized = _normalize_data(value) if isinstance(normalized, (int, float, bool, str)): _set_span_data_attribute(span, key, normalized) else: diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index 4b04bc1cfc..8d34ff80ea 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -564,7 +564,6 @@ def _set_common_input_data( span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) @@ -705,7 +704,6 @@ def _set_output_data( span, SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS, output_messages["tool"], - unpack=False, ) if len(output_messages["response"]) > 0: diff --git a/sentry_sdk/integrations/google_genai/utils.py b/sentry_sdk/integrations/google_genai/utils.py index e56d55033e..e74089b571 100644 --- a/sentry_sdk/integrations/google_genai/utils.py +++ b/sentry_sdk/integrations/google_genai/utils.py @@ -950,7 +950,6 @@ def set_span_data_for_request( span, SPANDATA.GEN_AI_REQUEST_AVAILABLE_TOOLS, formatted_tools, - unpack=False, ) else: # To remove once data collection has been fully rolled out @@ -958,7 +957,6 @@ def set_span_data_for_request( span, SPANDATA.GEN_AI_REQUEST_AVAILABLE_TOOLS, formatted_tools, - unpack=False, ) record_inputs = False @@ -1002,7 +1000,6 @@ def set_span_data_for_request( span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) # Extract parameters directly from config (not nested under generation_config) @@ -1167,7 +1164,6 @@ def set_span_data_for_embed_request( span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, input_texts, - unpack=False, ) diff --git a/sentry_sdk/integrations/huggingface_hub.py b/sentry_sdk/integrations/huggingface_hub.py index 8231749930..e326e72985 100644 --- a/sentry_sdk/integrations/huggingface_hub.py +++ b/sentry_sdk/integrations/huggingface_hub.py @@ -139,13 +139,9 @@ def new_huggingface_task(*args: "Any", **kwargs: "Any") -> "Any": # Input attributes if has_data_collection_enabled(client.options): if client.options["data_collection"]["gen_ai"]["inputs"]: - set_data_normalized( - span, SPANDATA.GEN_AI_REQUEST_MESSAGES, prompt, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_REQUEST_MESSAGES, prompt) elif should_send_default_pii() and integration.include_prompts: - set_data_normalized( - span, SPANDATA.GEN_AI_REQUEST_MESSAGES, prompt, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_REQUEST_MESSAGES, prompt) for attribute, span_attribute in attribute_mapping.items(): value = kwargs.get(attribute, None) @@ -153,7 +149,7 @@ def new_huggingface_task(*args: "Any", **kwargs: "Any") -> "Any": if isinstance(value, (int, float, bool, str)): _set_span_data_attribute(span, span_attribute, value) else: - set_data_normalized(span, span_attribute, value, unpack=False) + set_data_normalized(span, span_attribute, value) # LLM Execution try: @@ -230,14 +226,12 @@ def new_huggingface_task(*args: "Any", **kwargs: "Any") -> "Any": span, SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS, tool_calls, - unpack=False, ) elif should_send_default_pii() and integration.include_prompts: set_data_normalized( span, SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS, tool_calls, - unpack=False, ) if len(response_text_buffer) > 0: @@ -436,7 +430,6 @@ def new_iterator() -> "Iterable[ChatCompletionStreamOutput]": span, SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS, tool_calls, - unpack=False, ) elif ( should_send_default_pii() @@ -446,7 +439,6 @@ def new_iterator() -> "Iterable[ChatCompletionStreamOutput]": span, SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS, tool_calls, - unpack=False, ) if len(response_text_buffer) > 0: diff --git a/sentry_sdk/integrations/langchain.py b/sentry_sdk/integrations/langchain.py index 78242ba92c..edd96bf904 100644 --- a/sentry_sdk/integrations/langchain.py +++ b/sentry_sdk/integrations/langchain.py @@ -441,7 +441,7 @@ def on_llm_start( ): continue - set_data_normalized(span, attribute, all_params[key], unpack=False) + set_data_normalized(span, attribute, all_params[key]) _set_tools_on_span(span, all_params.get("tools")) @@ -472,7 +472,6 @@ def on_llm_start( span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) def on_chat_model_start( @@ -544,7 +543,7 @@ def on_chat_model_start( ): continue - set_data_normalized(span, attribute, all_params[key], unpack=False) + set_data_normalized(span, attribute, all_params[key]) _set_tools_on_span(span, all_params.get("tools")) @@ -585,7 +584,6 @@ def on_chat_model_start( span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) def on_chat_model_end( @@ -673,7 +671,6 @@ def on_llm_end( span, SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS, tool_calls, - unpack=False, ) if record_outputs: @@ -1081,7 +1078,6 @@ def _set_tools_on_span(span: "Union[Span, StreamedSpan]", tools: "Any") -> None: span, attribute_name, simplified_tools, - unpack=False, ) @@ -1218,7 +1214,6 @@ def new_invoke(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) output = result.get("output") @@ -1260,7 +1255,6 @@ def new_invoke(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) output = result.get("output") @@ -1338,7 +1332,6 @@ def new_stream(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) # Run the agent @@ -1454,9 +1447,7 @@ def new_embedding_method(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": input_data = args[0] # Normalize to list format texts = input_data if isinstance(input_data, list) else [input_data] - set_data_normalized( - span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, texts, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, texts) result = f(self, *args, **kwargs) return result @@ -1474,9 +1465,7 @@ def new_embedding_method(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": input_data = args[0] # Normalize to list format texts = input_data if isinstance(input_data, list) else [input_data] - set_data_normalized( - span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, texts, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, texts) result = f(self, *args, **kwargs) return result @@ -1521,9 +1510,7 @@ async def new_async_embedding_method( input_data = args[0] # Normalize to list format texts = input_data if isinstance(input_data, list) else [input_data] - set_data_normalized( - span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, texts, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, texts) result = await f(self, *args, **kwargs) return result @@ -1541,9 +1528,7 @@ async def new_async_embedding_method( input_data = args[0] # Normalize to list format texts = input_data if isinstance(input_data, list) else [input_data] - set_data_normalized( - span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, texts, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, texts) result = await f(self, *args, **kwargs) return result diff --git a/sentry_sdk/integrations/langgraph.py b/sentry_sdk/integrations/langgraph.py index af287b0fd4..ec0315e487 100644 --- a/sentry_sdk/integrations/langgraph.py +++ b/sentry_sdk/integrations/langgraph.py @@ -232,7 +232,6 @@ def new_invoke(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) result = f(self, *args, **kwargs) @@ -274,7 +273,6 @@ def new_invoke(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) result = f(self, *args, **kwargs) @@ -333,7 +331,6 @@ async def new_ainvoke(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) result = await f(self, *args, **kwargs) @@ -372,7 +369,6 @@ async def new_ainvoke(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) result = await f(self, *args, **kwargs) @@ -513,5 +509,4 @@ def _set_response_attributes( span, SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS, safe_serialize(tool_calls), - unpack=False, ) diff --git a/sentry_sdk/integrations/litellm.py b/sentry_sdk/integrations/litellm.py index ce94441a4d..e8240db6b3 100644 --- a/sentry_sdk/integrations/litellm.py +++ b/sentry_sdk/integrations/litellm.py @@ -157,7 +157,6 @@ def _input_callback(kwargs: "Dict[str, Any]") -> None: span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, messages_data, - unpack=False, ) else: # For chat, look for the 'messages' parameter @@ -175,7 +174,6 @@ def _input_callback(kwargs: "Dict[str, Any]") -> None: span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) # Record other parameters diff --git a/sentry_sdk/integrations/openai.py b/sentry_sdk/integrations/openai.py index 04ae33daff..ac04c110b5 100644 --- a/sentry_sdk/integrations/openai.py +++ b/sentry_sdk/integrations/openai.py @@ -486,9 +486,7 @@ def _set_responses_api_input_data( else normalized_messages ) if messages_data is not None: - set_data_normalized( - span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data) return # Input was provided as a list (potentially a multi-turn conversation) @@ -505,9 +503,7 @@ def _set_responses_api_input_data( else normalized_messages ) if messages_data is not None: - set_data_normalized( - span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data) def _set_completions_api_input_data( @@ -592,9 +588,7 @@ def _set_completions_api_input_data( else normalized_messages ) if messages_data is not None: - set_data_normalized( - span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data) return # dict special case following https://github.com/openai/openai-python/blob/3e0c05b84a2056870abf3bd6a5e7849020209cc3/src/openai/_utils/_transform.py#L194-L197 @@ -626,9 +620,7 @@ def _set_completions_api_input_data( else normalized_messages ) if messages_data is not None: - set_data_normalized( - span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data) def _set_embeddings_input_data( @@ -670,9 +662,7 @@ def _set_embeddings_input_data( else normalized_messages ) if messages_data is not None: - set_data_normalized( - span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, messages_data, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, messages_data) return @@ -692,9 +682,7 @@ def _set_embeddings_input_data( else normalized_messages ) if messages_data is not None: - set_data_normalized( - span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, messages_data, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, messages_data) def _set_common_output_data( @@ -775,7 +763,6 @@ def _set_common_output_data( span, SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS, output_messages["tool"], - unpack=False, ) if record_outputs and len(output_messages["response"]) > 0: @@ -804,7 +791,6 @@ def _set_common_output_data( span, SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS, output_messages["tool"], - unpack=False, ) if len(output_messages["response"]) > 0: diff --git a/sentry_sdk/integrations/openai_agents/spans/invoke_agent.py b/sentry_sdk/integrations/openai_agents/spans/invoke_agent.py index eef59bdf0a..c922eae5fc 100644 --- a/sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +++ b/sentry_sdk/integrations/openai_agents/spans/invoke_agent.py @@ -100,7 +100,6 @@ def invoke_agent_span( span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) _set_agent_data(span, agent) @@ -121,11 +120,9 @@ def update_invoke_agent_span( client = sentry_sdk.get_client() if has_data_collection_enabled(client.options): if client.options["data_collection"]["gen_ai"]["outputs"]: - set_data_normalized( - span, SPANDATA.GEN_AI_RESPONSE_TEXT, output, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_RESPONSE_TEXT, output) elif should_send_default_pii(): - set_data_normalized(span, SPANDATA.GEN_AI_RESPONSE_TEXT, output, unpack=False) + set_data_normalized(span, SPANDATA.GEN_AI_RESPONSE_TEXT, output) # Add conversation ID from agent conv_id = getattr(agent, "_sentry_conversation_id", None) diff --git a/sentry_sdk/integrations/openai_agents/utils.py b/sentry_sdk/integrations/openai_agents/utils.py index 0e160193ed..8ec2da2c4a 100644 --- a/sentry_sdk/integrations/openai_agents/utils.py +++ b/sentry_sdk/integrations/openai_agents/utils.py @@ -202,7 +202,6 @@ def _set_input_data( span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, - unpack=False, ) diff --git a/sentry_sdk/integrations/pydantic_ai/spans/ai_client.py b/sentry_sdk/integrations/pydantic_ai/spans/ai_client.py index 4ff5f87577..6e96389707 100644 --- a/sentry_sdk/integrations/pydantic_ai/spans/ai_client.py +++ b/sentry_sdk/integrations/pydantic_ai/spans/ai_client.py @@ -224,9 +224,7 @@ def _set_input_messages( if should_truncate_gen_ai_input(client.options) else normalized_messages ) - set_data_normalized( - span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data) except Exception: # If we fail to format messages, just skip it pass diff --git a/sentry_sdk/integrations/pydantic_ai/spans/invoke_agent.py b/sentry_sdk/integrations/pydantic_ai/spans/invoke_agent.py index a9d020edea..16bf4d531d 100644 --- a/sentry_sdk/integrations/pydantic_ai/spans/invoke_agent.py +++ b/sentry_sdk/integrations/pydantic_ai/spans/invoke_agent.py @@ -145,9 +145,7 @@ def invoke_agent_span( if should_truncate_gen_ai_input(client.options) else normalized_messages ) - set_data_normalized( - span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data) return span @@ -165,9 +163,7 @@ def update_invoke_agent_span( # Set response text if prompts are enabled if _should_send_outputs() and output: - set_data_normalized( - span, SPANDATA.GEN_AI_RESPONSE_TEXT, str(output), unpack=False - ) + set_data_normalized(span, SPANDATA.GEN_AI_RESPONSE_TEXT, str(output)) # Set model name from response if available if hasattr(result, "response"):