Description
ToolScheduler.execute() allows consecutive read-only tool calls to execute concurrently.
When a sequence contains only read-only calls, the complete group is scheduled without a concurrency bound.
As a result, the number of simultaneously active tool operations grows directly with the number of consecutive read-only calls in the input.
I reproduced this behavior with 512 controlled read-only tool calls.
Observed behavior:
Input tool calls: 512
Peak active tool calls: 512
Pending child tasks before release: 512
External service contacted: No
A large read-only tool-call group can therefore produce a correspondingly large number of outstanding operations rather than maintaining bounded execution concurrency.
Affected Version
Confirmed on:
windcode==0.2.1
Python 3.11.0rc1
src/windcode/runtime/scheduler.py:251-275
ToolScheduler.execute()
Other versions have not been tested.
Reproduction
The attached PoC executes the released ToolScheduler.execute() implementation with 512 controlled tool calls, all classified as read-only.
The individual tool execution boundary is replaced with a local asynchronous operation that records active calls and waits on a shared gate. This allows the number of operations admitted by the scheduler to be measured before any call completes.
Observed result:
input calls: 512
peak active tool calls: 512
pending child tasks before release: 512
fan-out reproduced: yes
All 512 read-only tool operations become active before any of them is released.
No external tool or service is contacted during reproduction.
Expected behavior
Concurrent execution of read-only tool calls should remain bounded for large groups rather than growing directly with the total number of consecutive calls.
A semaphore, bounded worker pool, or batched scheduling strategy could preserve parallel execution while limiting the number of simultaneously outstanding tool operations.
Attachment
run.py
Description
ToolScheduler.execute() allows consecutive read-only tool calls to execute concurrently.
When a sequence contains only read-only calls, the complete group is scheduled without a concurrency bound.
As a result, the number of simultaneously active tool operations grows directly with the number of consecutive read-only calls in the input.
I reproduced this behavior with 512 controlled read-only tool calls.
Observed behavior:
Input tool calls: 512
Peak active tool calls: 512
Pending child tasks before release: 512
External service contacted: No
A large read-only tool-call group can therefore produce a correspondingly large number of outstanding operations rather than maintaining bounded execution concurrency.
Affected Version
Confirmed on:
windcode==0.2.1
Python 3.11.0rc1
src/windcode/runtime/scheduler.py:251-275
ToolScheduler.execute()
Other versions have not been tested.
Reproduction
The attached PoC executes the released ToolScheduler.execute() implementation with 512 controlled tool calls, all classified as read-only.
The individual tool execution boundary is replaced with a local asynchronous operation that records active calls and waits on a shared gate. This allows the number of operations admitted by the scheduler to be measured before any call completes.
Observed result:
input calls: 512
peak active tool calls: 512
pending child tasks before release: 512
fan-out reproduced: yes
All 512 read-only tool operations become active before any of them is released.
No external tool or service is contacted during reproduction.
Expected behavior
Concurrent execution of read-only tool calls should remain bounded for large groups rather than growing directly with the total number of consecutive calls.
A semaphore, bounded worker pool, or batched scheduling strategy could preserve parallel execution while limiting the number of simultaneously outstanding tool operations.
Attachment
run.py