Run Tools in Parallel, With Timeouts
A model asks for three tools in one turn. Run them together, and survive the one that never returns.
Implement run_parallel(tools, calls, timeout=0.5).
toolsmaps a name to a function;callsis a list of{"name": ..., "arguments": {...}}.- Run every call concurrently;
concurrent.futures.ThreadPoolExecutoris enough. - Return one result per call, in the order the calls were given, each
{"name": ..., "content": str, "is_error": bool}. - A tool that raises:
is_error: True, content is the error message. One failure must not lose the others. - A tool that exceeds
timeout:is_error: True, content mentions the timeout. The others still return. - An unknown tool name:
is_error: True, content says it is unknown, never submitted.
The catch: concurrent work finishes in any order, and a result in the wrong slot answers the wrong question. Submit in order, collect in order.
The tests time a run: two tools that each sleep 0.3s must finish together in well under 0.6s.