@@ -1341,6 +1341,15 @@ async def _do_stream(
13411341 except asyncio .CancelledError :
13421342 if accumulated_text :
13431343 await conversation .add_assistant_message (content = accumulated_text )
1344+ # Distinguish cancel_current_turn() (cancels the child
1345+ # _stream_task) from stop_worker (cancels the parent
1346+ # execution task). When the parent itself is cancelled,
1347+ # cancelling() > 0 — propagate so the executor can save
1348+ # state. When only the child was cancelled, convert to
1349+ # TurnCancelled so the event loop continues.
1350+ task = asyncio .current_task ()
1351+ if task and task .cancelling () > 0 :
1352+ raise
13441353 raise TurnCancelled () from None
13451354 finally :
13461355 self ._stream_task = None
@@ -1533,6 +1542,12 @@ async def _do_stream(
15331542 * (self ._execute_tool (tc ) for tc in pending_real ),
15341543 return_exceptions = True ,
15351544 )
1545+ # gather(return_exceptions=True) captures CancelledError
1546+ # as a return value instead of propagating it. Re-raise
1547+ # so stop_worker actually stops the execution.
1548+ for raw in raw_results :
1549+ if isinstance (raw , asyncio .CancelledError ):
1550+ raise raw
15361551 for tc , raw in zip (pending_real , raw_results , strict = True ):
15371552 if isinstance (raw , BaseException ):
15381553 result = ToolResult (
0 commit comments