@@ -458,6 +458,7 @@ class BatchRun:
458458 results : dict [str , str ] = field (default_factory = dict )
459459 engine : str = "react"
460460 stall_timeout_s : int = 300
461+ stall_action : str = "blocker"
461462
462463
463464def start_batch (
@@ -471,6 +472,7 @@ def start_batch(
471472 on_event : Optional [Callable [[str , dict ], None ]] = None ,
472473 engine : str = "react" ,
473474 stall_timeout_s : int = 300 ,
475+ stall_action : str = "blocker" ,
474476) -> BatchRun :
475477 """Start a batch execution of multiple tasks.
476478
@@ -518,6 +520,7 @@ def start_batch(
518520 results = {},
519521 engine = engine ,
520522 stall_timeout_s = stall_timeout_s ,
523+ stall_action = stall_action ,
521524 )
522525
523526 # Save to database
@@ -924,7 +927,7 @@ def _execute_serial_resume(
924927 on_event ("batch_task_started" , {"task_id" : task_id , "position" : i + 1 , "is_retry" : True })
925928
926929 # Execute task via subprocess
927- result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s )
930+ result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s , stall_action = batch . stall_action )
928931
929932 # Record result (overwrites previous result)
930933 batch .results [task_id ] = result_status
@@ -1092,7 +1095,7 @@ def _execute_retries(
10921095 print (f" Previous: { previous_status } " )
10931096
10941097 # Execute task
1095- result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s )
1098+ result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s , stall_action = batch . stall_action )
10961099
10971100 # Update result
10981101 batch .results [task_id ] = result_status
@@ -1259,15 +1262,15 @@ def _execute_serial(
12591262 on_event ("batch_task_started" , {"task_id" : task_id , "position" : i + 1 })
12601263
12611264 # Execute task via subprocess
1262- result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s )
1265+ result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s , stall_action = batch . stall_action )
12631266
12641267 # If task is BLOCKED, try supervisor resolution
12651268 if result_status == RunStatus .BLOCKED .value :
12661269 supervisor = get_supervisor (workspace )
12671270 if supervisor .try_resolve_blocked_task (task_id ):
12681271 # Supervisor resolved the blocker - retry the task
12691272 print (" [Supervisor] Retrying task after auto-resolution..." )
1270- result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s )
1273+ result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s , stall_action = batch . stall_action )
12711274
12721275 # Record result
12731276 batch .results [task_id ] = result_status
@@ -1547,15 +1550,15 @@ def _execute_single_task(
15471550 on_event ("batch_task_started" , {"task_id" : task_id , "position" : position })
15481551
15491552 # Execute task via subprocess
1550- result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s )
1553+ result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s , stall_action = batch . stall_action )
15511554
15521555 # If task is BLOCKED, try supervisor resolution
15531556 if result_status == RunStatus .BLOCKED .value :
15541557 supervisor = get_supervisor (workspace )
15551558 if supervisor .try_resolve_blocked_task (task_id ):
15561559 # Supervisor resolved the blocker - retry the task
15571560 print (" [Supervisor] Retrying task after auto-resolution..." )
1558- result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s )
1561+ result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s , stall_action = batch . stall_action )
15591562
15601563 # Record result
15611564 batch .results [task_id ] = result_status
@@ -1646,7 +1649,7 @@ def execute_task(task_id: str) -> tuple[str, str]:
16461649 on_event ("batch_task_started" , {"task_id" : task_id , "parallel" : True })
16471650
16481651 # Execute via subprocess
1649- result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s )
1652+ result_status = _execute_task_subprocess (workspace , task_id , batch .id , engine = batch .engine , stall_timeout_s = batch .stall_timeout_s , stall_action = batch . stall_action )
16501653
16511654 # Record result (thread-safe due to GIL for simple dict operations)
16521655 batch .results [task_id ] = result_status
@@ -1704,6 +1707,7 @@ def _execute_task_subprocess(
17041707 batch_id : Optional [str ] = None ,
17051708 engine : str = "react" ,
17061709 stall_timeout_s : int = 300 ,
1710+ stall_action : str = "blocker" ,
17071711) -> str :
17081712 """Execute a single task via subprocess.
17091713
@@ -1715,6 +1719,7 @@ def _execute_task_subprocess(
17151719 batch_id: Optional batch ID for process tracking (enables force stop)
17161720 engine: Agent engine to use ("plan" or "react")
17171721 stall_timeout_s: Stall detection timeout in seconds (0 = disabled)
1722+ stall_action: Recovery action on stall ("blocker", "retry", or "fail")
17181723
17191724 Returns:
17201725 RunStatus value string (COMPLETED, FAILED, BLOCKED)
@@ -1725,6 +1730,7 @@ def _execute_task_subprocess(
17251730 "work" , "start" , task_id , "--execute" ,
17261731 "--engine" , engine ,
17271732 "--stall-timeout" , str (stall_timeout_s ),
1733+ "--stall-action" , stall_action ,
17281734 ]
17291735
17301736 process = None
0 commit comments