@@ -16,6 +16,9 @@ use tokio::sync::Mutex;
1616use tokio:: time:: { timeout, Duration } ;
1717
1818const DEFAULT_SCRIPT_TIMEOUT_MS : u64 = 30_000 ;
19+ /// Scripts allowed to delegate (`task`/`parallel_task`) run child agents that
20+ /// each take a full LLM turn, so they need a far more generous default timeout.
21+ const DELEGATION_SCRIPT_TIMEOUT_MS : u64 = 600_000 ;
1922const DEFAULT_SCRIPT_MAX_TOOL_CALLS : usize = 20 ;
2023const DEFAULT_SCRIPT_MAX_OUTPUT_BYTES : usize = 64 * 1024 ;
2124const MAX_SCRIPT_SOURCE_BYTES : usize = 64 * 1024 ;
@@ -266,7 +269,17 @@ async fn run_quickjs_script(
266269 allowed_tools : HashSet < String > ,
267270 limits : ScriptLimits ,
268271) -> Result < ToolOutput > {
269- let timeout_ms = limits. timeout_ms . unwrap_or ( DEFAULT_SCRIPT_TIMEOUT_MS ) ;
272+ // A script that can delegate runs child agents (each a full LLM turn, often
273+ // 30s to several minutes), so the 30s default is far too short and silently
274+ // times out real workflows. Default delegation-capable scripts to a generous
275+ // timeout; pure compute/search scripts keep the short default. An explicit
276+ // limits.timeoutMs always wins.
277+ let delegating = allowed_tools. contains ( "parallel_task" ) || allowed_tools. contains ( "task" ) ;
278+ let timeout_ms = limits. timeout_ms . unwrap_or ( if delegating {
279+ DELEGATION_SCRIPT_TIMEOUT_MS
280+ } else {
281+ DEFAULT_SCRIPT_TIMEOUT_MS
282+ } ) ;
270283 let max_tool_calls = limits
271284 . max_tool_calls
272285 . unwrap_or ( DEFAULT_SCRIPT_MAX_TOOL_CALLS ) ;
0 commit comments