Skip to content

Commit ef7802a

Browse files
create metadata dict in agent run methods again
1 parent b72be0f commit ef7802a

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

sentry_sdk/integrations/pydantic_ai/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,13 @@ class PydanticAIIntegration(Integration):
123123
Hooks using the decorators provided by `pydantic_ai.capabilities` create and manage spans for model calls when these hooks are available (newer library versions).
124124
The span is created in `on_request` and stored in the metadata of the `RunContext` object shared with `on_response` and `on_error`.
125125
126-
The metadata on the RunContext instance is initialized with an empty dictionary in `Agent.__init__()` if no metadata dictionary is provided by the user. The dictionary is
127-
required for the metadata object to be a shared reference between hooks.
126+
The metadata dictionary on the RunContext instance is initialized with `{"_sentry_span": None}` in the `_create_run_wrapper()` and `_create_streaming_wrapper()` wrappers that
127+
instrument `Agent.run()` and `Agent.run_stream()`, respectively. A non-empty dictionary is required for the metadata object to be a shared reference between hooks.
128128
"""
129129

130130
identifier = "pydantic_ai"
131131
origin = f"auto.ai.{identifier}"
132+
are_request_hooks_available = True
132133

133134
def __init__(
134135
self, include_prompts: bool = True, handled_tool_call_exceptions: bool = True
@@ -162,6 +163,7 @@ def setup_once() -> None:
162163
from pydantic_ai.capabilities import Hooks
163164
except ImportError:
164165
Hooks = None
166+
PydanticAIIntegration.are_request_hooks_available = False
165167

166168
if Hooks is None:
167169
_patch_graph_nodes()

sentry_sdk/integrations/pydantic_ai/patches/agent_run.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ def _create_run_wrapper(
9696
original_func: The original run method
9797
is_streaming: Whether this is a streaming method (for future use)
9898
"""
99+
from sentry_sdk.integrations.pydantic_ai import (
100+
PydanticAIIntegration,
101+
) # Required to avoid circular import
99102

100103
@wraps(original_func)
101104
async def wrapper(self: "Any", *args: "Any", **kwargs: "Any") -> "Any":
@@ -107,6 +110,11 @@ async def wrapper(self: "Any", *args: "Any", **kwargs: "Any") -> "Any":
107110
model = kwargs.get("model")
108111
model_settings = kwargs.get("model_settings")
109112

113+
if PydanticAIIntegration.are_request_hooks_available:
114+
metadata = kwargs.get("metadata")
115+
if not metadata:
116+
kwargs["metadata"] = {"_sentry_span": None}
117+
110118
# Create invoke_agent span
111119
with invoke_agent_span(
112120
user_prompt, self, model, model_settings, is_streaming
@@ -140,6 +148,9 @@ def _create_streaming_wrapper(
140148
"""
141149
Wraps run_stream method that returns an async context manager.
142150
"""
151+
from sentry_sdk.integrations.pydantic_ai import (
152+
PydanticAIIntegration,
153+
) # Required to avoid circular import
143154

144155
@wraps(original_func)
145156
def wrapper(self: "Any", *args: "Any", **kwargs: "Any") -> "Any":
@@ -148,6 +159,11 @@ def wrapper(self: "Any", *args: "Any", **kwargs: "Any") -> "Any":
148159
model = kwargs.get("model")
149160
model_settings = kwargs.get("model_settings")
150161

162+
if PydanticAIIntegration.are_request_hooks_available:
163+
metadata = kwargs.get("metadata")
164+
if not metadata:
165+
kwargs["metadata"] = {"_sentry_span": None}
166+
151167
# Call original function to get the context manager
152168
original_ctx_manager = original_func(self, *args, **kwargs)
153169

0 commit comments

Comments
 (0)