@@ -439,51 +439,41 @@ async def close(self) -> TaskMessage:
439439 if not self .task_message :
440440 raise ValueError ("Context not properly initialized - no task message" )
441441
442- # Mark closing before reaping so a concurrent coalesced delta can't slip
443- # past the now-None buffer and publish after DONE. Rolled back below if
444- # the terminal write fails, so a failed close doesn't wedge the context
445- # into silently dropping later deltas.
446- self ._is_closing = True
447- try :
448- # Reap the buffer (stopping its ticker) before the _is_closed
449- # short-circuit, so a context already marked done by a Full update
450- # can't leave the ticker orphaned. Draining here also lets consumers
451- # see the full delta sequence in order before DONE.
452- await self ._reap_buffer ()
442+ # Reap the buffer (stopping its ticker) before the _is_closed
443+ # short-circuit, so a context already marked done by a Full update can't
444+ # leave the ticker orphaned. Draining here also lets consumers see the
445+ # full delta sequence in order before DONE.
446+ await self ._reap_buffer ()
453447
454- if self ._is_closed :
455- return self .task_message # Already done (buffer reaped above)
448+ if self ._is_closed :
449+ return self .task_message # Already done (buffer reaped above)
456450
457- # Send the DONE event
458- done_event = StreamTaskMessageDone (
459- parent_task_message = self .task_message ,
460- type = "done" ,
461- )
462- await self ._streaming_service .stream_update (done_event )
451+ # Send the DONE event
452+ done_event = StreamTaskMessageDone (
453+ parent_task_message = self .task_message ,
454+ type = "done" ,
455+ )
456+ await self ._streaming_service .stream_update (done_event )
463457
464- # Update the task message with the final content
465- has_deltas = (
466- self ._delta_accumulator ._accumulated_deltas
467- or self ._delta_accumulator ._reasoning_summaries
468- or self ._delta_accumulator ._reasoning_contents
469- )
470- if has_deltas :
471- self .task_message .content = self ._delta_accumulator .convert_to_content ()
458+ # Update the task message with the final content
459+ has_deltas = (
460+ self ._delta_accumulator ._accumulated_deltas
461+ or self ._delta_accumulator ._reasoning_summaries
462+ or self ._delta_accumulator ._reasoning_contents
463+ )
464+ if has_deltas :
465+ self .task_message .content = self ._delta_accumulator .convert_to_content ()
472466
473- await self ._agentex_client .messages .update (
474- task_id = self .task_id ,
475- message_id = self .task_message .id ,
476- content = self .task_message .content .model_dump (),
477- streaming_status = "DONE" ,
478- )
467+ await self ._agentex_client .messages .update (
468+ task_id = self .task_id ,
469+ message_id = self .task_message .id ,
470+ content = self .task_message .content .model_dump (),
471+ streaming_status = "DONE" ,
472+ )
479473
480- # Mark the context as done
481- self ._is_closed = True
482- return self .task_message
483- except Exception :
484- if not self ._is_closed :
485- self ._is_closing = False
486- raise
474+ # Mark the context as done
475+ self ._is_closed = True
476+ return self .task_message
487477
488478 async def stream_update (self , update : TaskMessageUpdate ) -> TaskMessageUpdate | None :
489479 """Stream an update to the repository.
@@ -522,38 +512,32 @@ async def stream_update(self, update: TaskMessageUpdate) -> TaskMessageUpdate |
522512
523513 # From here the update is terminal. Mark closing so a concurrent delta
524514 # can't fall through and publish after the terminal once the buffer is
525- # reaped below. Rolled back if the terminal path fails, so a failed
526- # terminal doesn't wedge the context into silently dropping later deltas.
527- is_terminal = isinstance (update , (StreamTaskMessageFull , StreamTaskMessageDone ))
528- if is_terminal :
515+ # reaped below.
516+ if isinstance (update , (StreamTaskMessageFull , StreamTaskMessageDone )):
529517 self ._is_closing = True
530- try :
531- # A Full ends the stream and supersedes buffered deltas. Drain and
532- # stop the buffer BEFORE publishing the Full, so leftover deltas land
533- # in order (deltas -> Full) instead of trailing the terminal Full as
534- # a stale duplicate tail. This also stops the ticker, which would
535- # otherwise be orphaned when __aexit__'s close() short-circuits.
536- if isinstance (update , StreamTaskMessageFull ):
537- await self ._reap_buffer ()
538-
539- result = await self ._streaming_service .stream_update (update )
540-
541- if isinstance (update , StreamTaskMessageDone ):
542- await self .close ()
543- return update
544- elif isinstance (update , StreamTaskMessageFull ):
545- await self ._agentex_client .messages .update (
546- task_id = self .task_id ,
547- message_id = update .parent_task_message .id , # type: ignore[union-attr]
548- content = update .content .model_dump (),
549- streaming_status = "DONE" ,
550- )
551- self ._is_closed = True
552- return result
553- except Exception :
554- if not self ._is_closed :
555- self ._is_closing = False
556- raise
518+
519+ # A Full ends the stream and supersedes buffered deltas. Drain and stop
520+ # the buffer BEFORE publishing the Full, so leftover deltas land in order
521+ # (deltas -> Full) instead of trailing the terminal Full as a stale
522+ # duplicate tail. This also stops the ticker, which would otherwise be
523+ # orphaned when __aexit__'s close() short-circuits on _is_closed.
524+ if isinstance (update , StreamTaskMessageFull ):
525+ await self ._reap_buffer ()
526+
527+ result = await self ._streaming_service .stream_update (update )
528+
529+ if isinstance (update , StreamTaskMessageDone ):
530+ await self .close ()
531+ return update
532+ elif isinstance (update , StreamTaskMessageFull ):
533+ await self ._agentex_client .messages .update (
534+ task_id = self .task_id ,
535+ message_id = update .parent_task_message .id , # type: ignore[union-attr]
536+ content = update .content .model_dump (),
537+ streaming_status = "DONE" ,
538+ )
539+ self ._is_closed = True
540+ return result
557541
558542
559543class StreamingService :
0 commit comments