Commit 64c68ca
authored
Python: Skip get_final_response in OTel _finalize_stream when stream errored (#5232)
* Python: Skip get_final_response in OTel _finalize_stream when stream errored
When a streaming error occurs, _finalize_stream (a cleanup hook registered by
AgentTelemetryLayer) was unconditionally calling get_final_response(), which
triggers all registered result hooks including after_run context providers.
This caused providers to fire incorrectly on error paths.
Guard against this by checking result_stream._consumed: True only after
StopAsyncIteration (normal completion), False when an exception was raised.
The fix applies to both the chat client and agent telemetry layers.
Closes #5231
* Python: Expose consumed/stream_error on ResponseStream and capture error in OTel span
Address Copilot review feedback on #5232:
- Add `_stream_error: Exception | None` to ResponseStream, set in __anext__'s
except branch so cleanup hooks can inspect the failure.
- Expose public `consumed` and `stream_error` properties to avoid coupling
observability.py to private stream internals.
- Update both _finalize_stream closures (chat and agent layers) to use the
public properties and call capture_exception() with the stream error before
returning early, ensuring the OTel span records the failure rather than
closing silently.
* Python: Address Copilot review feedback on stream error handling
- Use stream_error is not None as the guard in _finalize_stream instead of
not consumed, so the early-return path is keyed precisely to actual errors
rather than any non-normal completion state.
- Clear _stream_error after _run_cleanup_hooks() completes to avoid retaining
the exception traceback (and any large object graphs it references) on the
stream instance beyond the cleanup phase.
* Python: Remove consumed/stream_error properties, use private attrs directly
Per review feedback: since observability.py and _types.py are in the same
package, accessing _stream_error directly is fine and the public properties
are unnecessary.
* Python: Fix Pyright reportPrivateUsage via inline ignore comments
Keep _stream_error private (consistent with rest of ResponseStream), and
suppress reportPrivateUsage at the call sites in observability.py with
inline pyright: ignore comments — access is intentional within the package.1 parent 98e1776 commit 64c68ca
File tree
2 files changed
+19
-2
lines changed- python/packages/core/agent_framework
2 files changed
+19
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2816 | 2816 | | |
2817 | 2817 | | |
2818 | 2818 | | |
| 2819 | + | |
2819 | 2820 | | |
2820 | 2821 | | |
2821 | 2822 | | |
| |||
2948 | 2949 | | |
2949 | 2950 | | |
2950 | 2951 | | |
2951 | | - | |
2952 | | - | |
| 2952 | + | |
| 2953 | + | |
| 2954 | + | |
| 2955 | + | |
| 2956 | + | |
| 2957 | + | |
2953 | 2958 | | |
2954 | 2959 | | |
2955 | 2960 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1323 | 1323 | | |
1324 | 1324 | | |
1325 | 1325 | | |
| 1326 | + | |
| 1327 | + | |
| 1328 | + | |
| 1329 | + | |
| 1330 | + | |
| 1331 | + | |
1326 | 1332 | | |
1327 | 1333 | | |
1328 | 1334 | | |
| |||
1579 | 1585 | | |
1580 | 1586 | | |
1581 | 1587 | | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
| 1591 | + | |
| 1592 | + | |
| 1593 | + | |
1582 | 1594 | | |
1583 | 1595 | | |
1584 | 1596 | | |
| |||
0 commit comments