Skip to content

Commit e1b6e16

Browse files
authored
ref(pydantic_ai): Split prompt gating into separate inputs/outputs controls (#7181)
Replace the single \_should_send_prompts check with \_should_send_inputs and \_should_send_outputs, gated by the new data_collection.gen_ai.inputs/outputs experimental options when set, falling back to the existing send_default_pii * include_prompts behavior otherwise. Available tools are now gated on inputs specifically. This lets callers control request and response data collection independently. Refs PY-2588 Refs #6748
1 parent 16b6497 commit e1b6e16

5 files changed

Lines changed: 538 additions & 18 deletions

File tree

sentry_sdk/integrations/pydantic_ai/spans/ai_client.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
_set_agent_data,
2222
_set_available_tools,
2323
_set_model_data,
24-
_should_send_prompts,
24+
_should_send_inputs,
25+
_should_send_outputs,
2526
get_current_agent,
2627
get_is_streaming,
2728
)
@@ -107,7 +108,7 @@ def _set_input_messages(
107108
span: "Union[sentry_sdk.tracing.Span, StreamedSpan]", messages: "Any"
108109
) -> None:
109110
"""Set input messages data on a span."""
110-
if not _should_send_prompts():
111+
if not _should_send_inputs():
111112
return
112113

113114
if not messages:
@@ -236,8 +237,7 @@ def _set_output_data(
236237
response: "Optional[ModelResponse]",
237238
) -> None:
238239
"""Set output data on a span."""
239-
if not _should_send_prompts():
240-
return
240+
record_outputs = _should_send_outputs()
241241

242242
if not response:
243243
return
@@ -247,6 +247,9 @@ def _set_output_data(
247247
)
248248
set_on_span(SPANDATA.GEN_AI_RESPONSE_MODEL, response.model_name) # type: ignore[arg-type]
249249

250+
if not record_outputs:
251+
return
252+
250253
try:
251254
if hasattr(response, "parts"):
252255
parts: "list[Union[_types.TextPart, _types.ReasoningPart, _types.ToolCallPart]]" = []

sentry_sdk/integrations/pydantic_ai/spans/execute_tool.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from sentry_sdk.utils import safe_serialize
88

99
from ..consts import SPAN_ORIGIN
10-
from ..utils import _set_agent_data, _should_send_prompts
10+
from ..utils import _set_agent_data, _should_send_inputs, _should_send_outputs
1111

1212
if TYPE_CHECKING:
1313
from typing import Any, Optional, Union
@@ -62,7 +62,7 @@ def execute_tool_span(
6262

6363
_set_agent_data(span, agent)
6464

65-
if _should_send_prompts() and tool_args is not None:
65+
if _should_send_inputs() and tool_args is not None:
6666
set_on_span(SPANDATA.GEN_AI_TOOL_INPUT, safe_serialize(tool_args))
6767

6868
return span
@@ -75,7 +75,7 @@ def update_execute_tool_span(
7575
if not span:
7676
return
7777

78-
if not _should_send_prompts() or result is None:
78+
if not _should_send_outputs() or result is None:
7979
return
8080

8181
if isinstance(span, StreamedSpan):

sentry_sdk/integrations/pydantic_ai/spans/invoke_agent.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
_set_agent_data,
2020
_set_available_tools,
2121
_set_model_data,
22-
_should_send_prompts,
22+
_should_send_inputs,
23+
_should_send_outputs,
2324
)
2425
from .utils import (
2526
_serialize_binary_content_item,
@@ -73,7 +74,7 @@ def invoke_agent_span(
7374
_set_available_tools(span, agent)
7475

7576
# Add user prompt and system prompts if available and prompts are enabled
76-
if _should_send_prompts():
77+
if _should_send_inputs():
7778
messages = []
7879

7980
# Add system prompts (both instructions and system_prompt)
@@ -163,7 +164,7 @@ def update_invoke_agent_span(
163164
output = getattr(result, "output", None)
164165

165166
# Set response text if prompts are enabled
166-
if _should_send_prompts() and output:
167+
if _should_send_outputs() and output:
167168
set_data_normalized(
168169
span, SPANDATA.GEN_AI_RESPONSE_TEXT, str(output), unpack=False
169170
)

sentry_sdk/integrations/pydantic_ai/utils.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
from sentry_sdk.consts import SPANDATA
66
from sentry_sdk.scope import should_send_default_pii
77
from sentry_sdk.traces import StreamedSpan
8-
from sentry_sdk.utils import event_from_exception, safe_serialize
8+
from sentry_sdk.utils import (
9+
event_from_exception,
10+
has_data_collection_enabled,
11+
safe_serialize,
12+
)
913

1014
if TYPE_CHECKING:
1115
from typing import Any, Optional, Union
@@ -49,11 +53,12 @@ def get_is_streaming() -> bool:
4953
return False
5054

5155

52-
def _should_send_prompts() -> bool:
56+
def _should_send_prompts_legacy() -> bool:
5357
"""
54-
Check if prompts should be sent to Sentry.
58+
Check if prompts should be sent to Sentry based on the deprecated
59+
``send_default_pii`` option and the ``include_prompts`` integration setting.
5560
56-
This checks both send_default_pii and the include_prompts integration setting.
61+
TODO: Remove this once `send_default_pii` is deprecated.
5762
"""
5863
if not should_send_default_pii():
5964
return False
@@ -69,6 +74,22 @@ def _should_send_prompts() -> bool:
6974
return getattr(integration, "include_prompts", False)
7075

7176

77+
def _should_send_inputs() -> bool:
78+
client = sentry_sdk.get_client()
79+
if has_data_collection_enabled(client.options):
80+
return bool(client.options["data_collection"]["gen_ai"]["inputs"])
81+
82+
return _should_send_prompts_legacy()
83+
84+
85+
def _should_send_outputs() -> bool:
86+
client = sentry_sdk.get_client()
87+
if has_data_collection_enabled(client.options):
88+
return bool(client.options["data_collection"]["gen_ai"]["outputs"])
89+
90+
return _should_send_prompts_legacy()
91+
92+
7293
def _set_agent_data(
7394
span: "Union[sentry_sdk.tracing.Span, StreamedSpan]", agent: "Any"
7495
) -> None:
@@ -191,6 +212,11 @@ def _set_available_tools(
191212
if not agent or not hasattr(agent, "_function_toolset"):
192213
return
193214

215+
client_options = sentry_sdk.get_client().options
216+
if has_data_collection_enabled(client_options):
217+
if not client_options["data_collection"]["gen_ai"]["inputs"]:
218+
return
219+
194220
try:
195221
tools = []
196222
# Get tools from the function toolset

0 commit comments

Comments
 (0)