@@ -851,52 +851,40 @@ async def _exec_with_plugin(
851851
852852 plugin_manager = invocation_context .plugin_manager
853853
854- # Step 1: Run the before_run callbacks to see if we should early exit.
855- early_exit_result = await plugin_manager .run_before_run_callback (
856- invocation_context = invocation_context
857- )
858- if isinstance (early_exit_result , types .Content ):
859- early_exit_event = Event (
860- invocation_id = invocation_context .invocation_id ,
861- author = 'model' ,
862- content = early_exit_result ,
863- )
864- _apply_run_config_custom_metadata (
865- early_exit_event , invocation_context .run_config
854+ try :
855+ # Step 1: Run the before_run callbacks to see if we should
856+ # early exit.
857+ early_exit_result = await plugin_manager .run_before_run_callback (
858+ invocation_context = invocation_context
866859 )
867- if self ._should_append_event (early_exit_event , is_live_call ):
868- await self .session_service .append_event (
869- session = session ,
870- event = early_exit_event ,
860+ if isinstance (early_exit_result , types .Content ):
861+ early_exit_event = Event (
862+ invocation_id = invocation_context .invocation_id ,
863+ author = 'model' ,
864+ content = early_exit_result ,
871865 )
872- yield early_exit_event
873- else :
874- # Step 2: Otherwise continue with normal execution
875- # Note for live/bidi:
876- # the transcription may arrive later than the action(function call
877- # event and thus function response event). In this case, the order of
878- # transcription and function call event will be wrong if we just
879- # append as it arrives. To address this, we should check if there is
880- # transcription going on. If there is transcription going on, we
881- # should hold on appending the function call event until the
882- # transcription is finished. The transcription in progress can be
883- # identified by checking if the transcription event is partial. When
884- # the next transcription event is not partial, it means the previous
885- # transcription is finished. Then if there is any buffered function
886- # call event, we should append them after this finished(non-partial)
887- # transcription event.
888- buffered_events : list [Event ] = []
889- is_transcribing : bool = False
866+ _apply_run_config_custom_metadata (
867+ early_exit_event , invocation_context .run_config
868+ )
869+ if self ._should_append_event (early_exit_event , is_live_call ):
870+ await self .session_service .append_event (
871+ session = session ,
872+ event = early_exit_event ,
873+ )
874+ yield early_exit_event
875+ else :
876+ # Step 2: Otherwise continue with normal execution
877+ buffered_events : list [Event ] = []
878+ is_transcribing : bool = False
890879
891- try :
892880 async with Aclosing (execute_fn (invocation_context )) as agen :
893881 async for event in agen :
894882 _apply_run_config_custom_metadata (
895883 event , invocation_context .run_config
896884 )
897- # Step 3: Run the on_event callbacks before persisting so
898- # callback changes are stored in the session and match the
899- # streamed event.
885+ # Step 3: Run the on_event callbacks before persisting
886+ # so callback changes are stored in the session and
887+ # match the streamed event.
900888 modified_event = await plugin_manager .run_on_event_callback (
901889 invocation_context = invocation_context , event = event
902890 )
@@ -910,23 +898,15 @@ async def _exec_with_plugin(
910898 if event .partial and _is_transcription (event ):
911899 is_transcribing = True
912900 if is_transcribing and _is_tool_call_or_response (event ):
913- # only buffer function call and function response event
914- # which is non-partial
915901 buffered_events .append (output_event )
916902 continue
917- # Note for live/bidi: for audio response, it's considered
918- # as non-partial event(event.partial=None)
919- # event.partial=False and event.partial=None are considered
920- # as non-partial event; event.partial=True is considered as
921- # partial event.
922903 if event .partial is not True :
923904 if _is_transcription (event ) and (
924905 _has_non_empty_transcription_text (event .input_transcription )
925906 or _has_non_empty_transcription_text (
926907 event .output_transcription
927908 )
928909 ):
929- # transcription end signal, append buffered events
930910 is_transcribing = False
931911 logger .debug (
932912 'Appending transcription finished event: %s' ,
@@ -938,14 +918,16 @@ async def _exec_with_plugin(
938918 )
939919
940920 for buffered_event in buffered_events :
941- logger .debug ('Appending buffered event: %s' , buffered_event )
921+ logger .debug (
922+ 'Appending buffered event: %s' ,
923+ buffered_event ,
924+ )
942925 await self .session_service .append_event (
943926 session = session , event = buffered_event
944927 )
945928 yield buffered_event
946929 buffered_events = []
947930 else :
948- # non-transcription event or empty transcription event
949931 if self ._should_append_event (event , is_live_call ):
950932 logger .debug ('Appending non-buffered event: %s' , event )
951933 await self .session_service .append_event (
@@ -958,17 +940,18 @@ async def _exec_with_plugin(
958940 )
959941
960942 yield output_event
961- except Exception as e :
962- # Notify plugins of the unhandled execution error.
963- # Notification-only; the exception is always re-raised.
964- await plugin_manager .run_on_run_error_callback (
965- invocation_context = invocation_context ,
966- error = e ,
967- )
968- raise
943+ except Exception as e :
944+ # Notify plugins of the unhandled execution error. Covers
945+ # failures in before_run_callback, early-exit, and the main
946+ # execution loop. Notification-only; always re-raised.
947+ await plugin_manager .run_on_run_error_callback (
948+ invocation_context = invocation_context ,
949+ error = e ,
950+ )
951+ raise
969952
970- # Step 4: Run the after_run callbacks to perform global cleanup tasks
971- # or finalizing logs and metrics data.
953+ # Step 4: Run the after_run callbacks to perform global cleanup
954+ # tasks or finalizing logs and metrics data.
972955 # This does NOT emit any event. Only runs on success.
973956 await plugin_manager .run_after_run_callback (
974957 invocation_context = invocation_context
0 commit comments