@@ -172,16 +172,12 @@ def __init__(
172172 subcall_semaphore : threading .Semaphore | None = None ,
173173 ** kwargs ,
174174 ):
175- """
176- Args:
177- max_concurrent_subcalls: Max children to dispatch in parallel from
178- THIS REPL instance (controls local ThreadPoolExecutor size).
179- Default 1 = sequential (identical to previous behavior).
180- subcall_semaphore: Global semaphore bounding total concurrent child
181- RLMs across ALL depths. If None, uses the module-level default
182- (16 slots). Pass a custom one for testing or tighter control.
183- """
184- super ().__init__ (persistent = persistent , depth = depth , ** kwargs )
175+ super ().__init__ (
176+ persistent = persistent ,
177+ depth = depth ,
178+ max_concurrent_subcalls = max_concurrent_subcalls ,
179+ ** kwargs ,
180+ )
185181
186182 self .lm_handler_address = lm_handler_address
187183 self .subcall_fn = subcall_fn # Callback for recursive RLM calls (depth > 1 support)
@@ -363,8 +359,7 @@ def _rlm_query(self, prompt: str, model: str | None = None) -> str:
363359 return self ._llm_query (prompt , model )
364360
365361 def _rlm_query_batched (self , prompts : list [str ], model : str | None = None ) -> list [str ]:
366- """Spawn recursive RLM sub-calls for multiple prompts.
367-
362+ """Spawn recursive RLM sub-calls for multiple prompts in parallel.
368363 Each prompt gets its own child RLM for deeper thinking.
369364
370365 Execution modes (controlled by max_concurrent_subcalls):
@@ -401,10 +396,25 @@ def _rlm_query_batched(self, prompts: list[str], model: str | None = None) -> li
401396 for prompt in prompts :
402397 try :
403398 completion = self .subcall_fn (prompt , model )
404- self ._pending_llm_calls .append (completion )
405- results .append (completion .response )
399+ with lock :
400+ completions .append ((index , completion ))
401+ results [index ] = completion .response
406402 except Exception as e :
407- results .append (f"Error: RLM query failed - { e } " )
403+ results [index ] = f"Error: RLM query failed - { e } "
404+
405+ with ThreadPoolExecutor (max_workers = max_workers ) as executor :
406+ futures = [
407+ executor .submit (_run_subcall , i , prompt ) for i , prompt in enumerate (prompts )
408+ ]
409+ # Wait for all futures to complete; exceptions are captured inside _run_subcall
410+ for future in as_completed (futures ):
411+ future .result () # Re-raises unexpected executor errors
412+
413+ # Append completions in original prompt order for deterministic metadata
414+ completions .sort (key = lambda x : x [0 ])
415+ for _ , completion in completions :
416+ self ._pending_llm_calls .append (completion )
417+
408418 return results
409419
410420 # Fall back to plain batched LM call if no recursive capability
0 commit comments