fix(pydantic-ai): Determine if response is streamed based on the method - #5957
fix(pydantic-ai): Determine if response is streamed based on the method#5957alexander-alderman-webb wants to merge 18 commits into
Conversation
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨
Bug Fixes 🐛Pydantic Ai
Internal Changes 🔧Pydantic Ai
Other
🤖 This preview updates automatically when you update the PR. |
Codecov Results 📊✅ 98938 passed | ❌ 164 failed | ⏭️ 6479 skipped | Total: 105581 | Pass Rate: 93.71% | Execution Time: 355m 47s 📊 Comparison with Base Branch
➕ New Tests (164)View new tests
❌ Failed Tests
|
| File | Patch % | Lines |
|---|---|---|
| sentry_sdk/integrations/pydantic_ai/patches/graph_nodes.py | 87.50% |
Coverage diff
@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 89.93% 89.96% +0.03%
==========================================
Files 193 193 —
Lines 24963 24973 +10
Branches 9010 9016 +6
==========================================
+ Hits 22448 22465 +17
- Misses 2515 2508 -7
- Partials 1436 1435 -1Generated by Codecov Action
| did_stream = getattr(self, "_did_stream", None) | ||
| if did_stream: | ||
| async with original_stream_method(self, ctx) as stream: |
There was a problem hiding this comment.
Async stream wrapper falls through and yields twice when did_stream is true
When did_stream is true, the early guard yields the stream but then falls through to a second yield, which @asynccontextmanager will reject with RuntimeError: generator didn't stop.
Evidence
wrapped_model_request_streamis decorated with@asynccontextmanager.- When
did_streamis truthy, the wrapper yields fromoriginal_stream_methodat line 102 but does not return or use anelseguard. - Execution falls through to a second
async with original_stream_method(self, ctx)at line 114 andyield streamat line 115. @asynccontextmanagerexpects exactly one yield; a second yield causesRuntimeError: generator didn't stop.
Identified by Warden · code-review · EAF-FN4
| if isinstance(span, StreamedSpan): | ||
| span.set_attribute(SPANDATA.GEN_AI_RESPONSE_STREAMING, False) | ||
| else: |
There was a problem hiding this comment.
Stream wrapper sets GEN_AI_RESPONSE_STREAMING to False instead of True
The wrapped_model_request_stream wrapper sets GEN_AI_RESPONSE_STREAMING to False, but since this is the streaming method it should be True.
Evidence
- The PR title says the goal is to determine if the response is streamed based on the method.
wrapped_model_request_run(non-streaming) correctly sets the value toFalseat lines 72-74.wrapped_model_request_stream(streaming) sets the same value toFalseat lines 109-111, but streaming methods in other integrations (openai_agents,anthropic,google_genai) set it toTrue.
Identified by Warden · code-review · 6UA-65U
Description
Issues
Reminders
tox -e linters.feat:,fix:,ref:,meta:)