fix(pydantic-ai): Use first-class hooks when available#5947
fix(pydantic-ai): Use first-class hooks when available#5947alexander-alderman-webb wants to merge 34 commits intomasterfrom
Conversation
…lying on SDK internals
…on the request object
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨
Bug Fixes 🐛Anthropic
Other
Internal Changes 🔧
🤖 This preview updates automatically when you update the PR. |
Codecov Results 📊✅ 13 passed | Total: 13 | Pass Rate: 100% | Execution Time: 11.23s All tests are passing successfully. ❌ Patch coverage is 4.23%. Project has 14925 uncovered lines. Files with missing lines (2)
Generated by Codecov Action |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Streaming path sets input messages before model execution
- Moved
_set_input_messagesin the streaming wrapper to execute after the original stream context finishes so instruction mutations done during execution are captured.
- Moved
Or push these changes by commenting:
@cursor push 6153a56a6a
Preview (6153a56a6a)
diff --git a/sentry_sdk/integrations/pydantic_ai/patches/graph_nodes.py b/sentry_sdk/integrations/pydantic_ai/patches/graph_nodes.py
--- a/sentry_sdk/integrations/pydantic_ai/patches/graph_nodes.py
+++ b/sentry_sdk/integrations/pydantic_ai/patches/graph_nodes.py
@@ -91,13 +91,13 @@
# Create chat span for streaming request
with ai_client_span(None, model, model_settings) as span:
- if messages:
- _set_input_messages(span, messages)
-
# Call the original stream method
async with original_stream_method(self, ctx) as stream:
yield stream
+ if messages:
+ _set_input_messages(span, messages)
+
# After streaming completes, update span with response data
# The ModelRequestNode stores the final response in _result
model_response = NoneThis Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ffcb5f3. Configure here.
| if PydanticAIIntegration.are_request_hooks_available: | ||
| metadata = kwargs.get("metadata") | ||
| if not metadata: | ||
| kwargs["metadata"] = {"_sentry_span": None} |
There was a problem hiding this comment.
Metadata check inconsistency overwrites user-provided empty dicts
Low Severity
The run wrappers use if not metadata: which treats any falsy value (including {}) as missing, while patched_init in register_hooks correctly uses if metadata is None:. A user who explicitly passes metadata={} to run() or run_stream() will have their metadata silently replaced with {"_sentry_span": None}. Using if metadata is None: would be consistent with the patched_init check and correctly distinguish "not provided" from "provided as empty dict".
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ffcb5f3. Configure here.
|
|
||
| return original_init(self, *args, **kwargs) | ||
|
|
||
| Agent.__init__ = patched_init |
There was a problem hiding this comment.
Pre-existing agents silently lose chat span instrumentation
Medium Severity
register_hooks patches Agent.__init__ to inject hooks into capabilities, but agents created before sentry_init() never go through patched_init and thus lack hooks. Those agents will still get invoke_agent and execute_tool spans (patched at class level), but will silently produce no gen_ai.chat spans. This is a regression from the monkey-patching fallback path, which patches ModelRequestNode/Model at the class level and works for all agent instances regardless of creation time.
Reviewed by Cursor Bugbot for commit ffcb5f3. Configure here.



Description
Resolve tox failure by using the
pydantic-aihooks when available. See the failing run in #5945See changes to instruction setting in https://github.com/pydantic/pydantic-ai/pull/4123/changes#diff-71730070455237accebd709ba7fe41ce60edbd238af02e7d86a208cf8f10ab12. Per-run system instructions are now added inside
ModelRequestNode.runandModelRequestNode.stream, and are therefore not available before the functions run.Issues
Reminders
tox -e linters.feat:,fix:,ref:,meta:)