@@ -215,34 +215,32 @@ def _coerce_outputs_to_steps(cls, data: Any) -> Any:
215215 coerced , _ = cls ._maybe_coerce_outputs (data )
216216 return coerced
217217
218- @property
219- def _last_model_output_steps (self ) -> List [ModelOutputStep ]:
220- if not self .steps :
221- return []
222- trailing : List [ModelOutputStep ] = []
223- for step in reversed (self .steps ):
224- if isinstance (step , ModelOutputStep ):
225- trailing .append (step )
226- else :
227- break
228- trailing .reverse ()
229- return trailing
230-
231218 @property
232219 def output_text (self ) -> str :
233- """Concatenated last consecutive text from the last consecutive model output steps."""
220+ """The last consecutive run of text from the trailing model output steps.
221+
222+ Scans backwards through the steps (stopping at any UserInputStep) and
223+ skips non-text content until the first text item is found, then
224+ continues collecting text until a non-text item is encountered.
225+ Returns an empty string when no text content is present.
226+ """
234227 parts : List [str ] = []
235- done = False
236- for step in reversed (self ._last_model_output_steps ):
237- if done :
228+ collecting = False
229+ for step in reversed (self .steps or [] ):
230+ if isinstance ( step , UserInputStep ) :
238231 break
239- if step .content :
240- for content in reversed (step .content ):
241- if isinstance (content , TextContent ):
242- parts .append (content .text )
243- else :
244- done = True
245- break
232+ if not isinstance (step , ModelOutputStep ) or not step .content :
233+ if collecting :
234+ break
235+ continue
236+ for content in reversed (step .content ):
237+ if isinstance (content , TextContent ):
238+ collecting = True
239+ parts .append (content .text )
240+ elif collecting :
241+ # Hit a non-text barrier after we started collecting.
242+ parts .reverse ()
243+ return "" .join (parts )
246244 parts .reverse ()
247245 return "" .join (parts )
248246
0 commit comments