fix: cap MCP tool-call concurrency via MCP_TOOL_CALL_CONCURRENCY (default 4) - #767
bhaveshpatel640 wants to merge 9 commits into
Conversation
🦋 Changeset detectedLatest commit: ee677e1 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
720abec to
eeef0b8
Compare
0ae1487 to
49e242e
Compare
708c5c3 to
d3df9f2
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ee677e1. Configure here.
| // After a step, abort must return before the next deriveState(). | ||
| // A partial tool batch leaves open calls; tool-response-required → tool-response-required is invalid. | ||
| // Do not check at the top of the loop: user-input-required must still emit. | ||
| if (outcome === 'exit' || signal?.aborted) { |
There was a problem hiding this comment.
Abort skips user-input events
Medium Severity
The new post-step signal?.aborted return runs after every step, not only after a partial tool batch. If an LLM step commits approval or client-side tool calls and the run is already aborted, execute() returns before user-input-required, so TOOL_APPROVAL_REQUIRED / TOOL_RESPONSE_REQUIRED never emit even though the comment says that step must still run.
Reviewed by Cursor Bugbot for commit ee677e1. Configure here.


Summary
Cap unbounded
Promise.allinexecuteToolCallsso a large tool batch cannot multiply RAM (bodies stay in memory untilLargeToolResponsetruncates).AGE-2257 / INFOSEC-15
Changes
mapWithConcurrencyinstead of unboundedPromise.allconcurrency/mcpToolCallConcurrencyfrom config → resolver →AgentThread→executeToolCalls(no silent fallback)MCP_TOOL_CALL_CONCURRENCYdefaults toDEFAULT_MCP_TOOL_CALL_CONCURRENCY(4)How was this tested?
packages/trueforge-coretypecheckexecuteToolCallsunit test: 8 calls, cap 2, order preservedChecklist
pnpm build,pnpm test,pnpm typecheck,pnpm lint:ci, andpnpm format:checkpass locallypackages/trueforge-sdk,python/trueforge_sdk,.github/fern/openapi/openapi.json,docs/openapi.json) — fork PRs omit SDK regen; maintainers regenerate after merge.env.exampleupdated if configuration or behavior changedNote
Medium Risk
Changes core MCP tool execution concurrency and cancellation semantics on the agent turn loop; behavior is tested but affects resource usage and turn completion on abort.
Overview
Replaces unbounded parallel MCP tool execution with a concurrency-limited batch so large assistant tool dumps cannot spike memory (tool bodies stay in RAM until truncation).
executeToolCallsnow runs throughmapWithConcurrencywith a requiredconcurrencyargument and optionalAbortSignal; queued work stops after cancel while in-flight calls may still finish.DEFAULT_MCP_TOOL_CALL_CONCURRENCY(4) is exported and wired explicitly fromMCP_TOOL_CALL_CONCURRENCYin TrueForge config →TurnResourceResolver/ITurnResourceResolver→AgentThread(including sub-agents), with no silent fallback.AgentThreadpasses the turn abort signal into tool execution and exits the run loop after a step when aborted, avoiding invalid partial batches and leftover open tool calls. Docs/.env.exampledocument the knob; new unit tests cover the cap and abort behavior.Reviewed by Cursor Bugbot for commit ee677e1. Bugbot is set up for automated code reviews on this repo. Configure here.