@@ -330,43 +330,40 @@ async def execute_tools_and_side_effects(
330
330
ItemHelpers .extract_last_text (message_items [- 1 ].raw_item ) if message_items else None
331
331
)
332
332
333
- # There are two possibilities that lead to a final output:
334
- # 1. Structured output schema => always leads to a final output
335
- # 2. Plain text output schema => only leads to a final output if there are no tool calls
336
- if output_schema and not output_schema .is_plain_text () and potential_final_output_text :
337
- final_output = output_schema .validate_json (potential_final_output_text )
338
- return await cls .execute_final_output (
339
- agent = agent ,
340
- original_input = original_input ,
341
- new_response = new_response ,
342
- pre_step_items = pre_step_items ,
343
- new_step_items = new_step_items ,
344
- final_output = final_output ,
345
- hooks = hooks ,
346
- context_wrapper = context_wrapper ,
347
- )
348
- elif (
349
- not output_schema or output_schema .is_plain_text ()
350
- ) and not processed_response .has_tools_or_approvals_to_run ():
351
- return await cls .execute_final_output (
352
- agent = agent ,
353
- original_input = original_input ,
354
- new_response = new_response ,
355
- pre_step_items = pre_step_items ,
356
- new_step_items = new_step_items ,
357
- final_output = potential_final_output_text or "" ,
358
- hooks = hooks ,
359
- context_wrapper = context_wrapper ,
360
- )
361
- else :
362
- # If there's no final output, we can just run again
363
- return SingleStepResult (
364
- original_input = original_input ,
365
- model_response = new_response ,
366
- pre_step_items = pre_step_items ,
367
- new_step_items = new_step_items ,
368
- next_step = NextStepRunAgain (),
369
- )
333
+ # Generate final output only when there are no pending tool calls or approval requests.
334
+ if not processed_response .has_tools_or_approvals_to_run ():
335
+ if output_schema and not output_schema .is_plain_text () and potential_final_output_text :
336
+ final_output = output_schema .validate_json (potential_final_output_text )
337
+ return await cls .execute_final_output (
338
+ agent = agent ,
339
+ original_input = original_input ,
340
+ new_response = new_response ,
341
+ pre_step_items = pre_step_items ,
342
+ new_step_items = new_step_items ,
343
+ final_output = final_output ,
344
+ hooks = hooks ,
345
+ context_wrapper = context_wrapper ,
346
+ )
347
+ elif not output_schema or output_schema .is_plain_text ():
348
+ return await cls .execute_final_output (
349
+ agent = agent ,
350
+ original_input = original_input ,
351
+ new_response = new_response ,
352
+ pre_step_items = pre_step_items ,
353
+ new_step_items = new_step_items ,
354
+ final_output = potential_final_output_text or "" ,
355
+ hooks = hooks ,
356
+ context_wrapper = context_wrapper ,
357
+ )
358
+
359
+ # If there's no final output, we can just run again
360
+ return SingleStepResult (
361
+ original_input = original_input ,
362
+ model_response = new_response ,
363
+ pre_step_items = pre_step_items ,
364
+ new_step_items = new_step_items ,
365
+ next_step = NextStepRunAgain (),
366
+ )
370
367
371
368
@classmethod
372
369
def maybe_reset_tool_choice (
0 commit comments