Manages parallel execution of concurrent-safe tools while serialising
non-concurrent-safe tools. Mirrors Claude Code's StreamingToolExecutor.
Rules:
Concurrent-safe tools run immediately (in parallel with other safe tools).
Non-concurrent-safe tools wait for all running tools to finish, execute exclusively, then release the queue.
Tool calls submitted while an unsafe tool is running are queued and executed in order when the unsafe tool completes.
Methods
StreamingToolExecutor$submit()
Submit a tool call for execution.
StreamingToolExecutor$drain_queue()
Drain the queue for any unsafe tool that was running. Call this after marking the unsafe tool as complete.
StreamingToolExecutor$execute_batch_async()
Async variant of execute_batch() for use inside
coro::async / Shiny ExtendedTask contexts.
Concurrent-safe tools are dispatched as a group via
promises::promise_all(), so the Shiny event loop can interleave
other work while they run. Unsafe tools execute serially after all
safe tools have resolved.
If the promises package is not installed the method falls back to
execute_batch() and returns the result directly (not wrapped in a
promise); coro::await() handles plain values transparently.
Arguments
tool_callsList of tool call objects (each with
id,name,input).exec_fnFunction
(tool_call) -> character. Must be callable from the current R process.
Returns
A promises::promise resolving to the same list that
execute_batch() returns, or that list directly when promises is
unavailable.