Symptom
Asked a cursor-acp/* model to dispatch three subagents in parallel in a single message, one task call each. One dispatched; the other two were silently abandoned — no error, no retry, just absent from the turn.
> build · cursor-grok-4.5-high-fast
✓ General Task — Report today's date
subagent_type result
explore (file count) not dispatched
general (today's date) succeeded
explore (git branch) not dispatched
Root cause
The proxy response builders accept a single tool call and wrap it in a one-element array. src/proxy/tool-loop.ts:
export function createToolCallCompletionResponse(meta: ToolLoopMeta, toolCall: OpenAiToolCall) { // :199
...
tool_calls: [toolCall], // :211
finish_reason: "tool_calls",
}
export function createToolCallStreamChunks(meta: ToolLoopMeta, toolCall: OpenAiToolCall) { // :219
...
tool_calls: [{ index: 0, ...toolCall }], // :230, index hardcoded
}
Those are the only sites in src/ that emit tool_calls — every other occurrence (src/plugin.ts, src/proxy/incremental-prompt.ts) reads inbound calls. So the OpenAI-compatible response this proxy produces structurally cannot carry more than one tool call per assistant turn.
The bridge-JSON envelope reinforces it from the prompt side — src/proxy/bridge-json.ts:15 and :21 both instruct "respond with exactly one JSON object and no prose", and extractBridgeToolCallFromStreamOutput returns on the first detected call.
Impact
Any fan-out workflow is capped at one dispatch per turn. Best case it degrades to serial (dispatch, await result, dispatch again); observed case is worse — the model emits one and drops the rest, so a skill that fans out N reviewers silently does 1/N of its work with no error surfaced.
This affects agent workflows that dispatch multiple subagents concurrently, and more generally any turn where the model wants two or more parallel tool calls (a common pattern for independent reads/greps).
Repro
- Configure a
cursor-acp/* model as the main model.
- Prompt: dispatch three subagents in parallel via the
task tool, issuing all three calls in one message.
- Observe one dispatch; the rest are absent.
Notes
Distinct from #122 (subagentType argument normalization), which fixes the schema mismatch on a single task call. With that patch applied the surviving call validates correctly — the missing parallelism here is a separate, structural limit.
Filing rather than patching because plumbing N calls through looks like it touches the response builders, the stream chunk indices (index is fixed at 0), and the cursor-agent event to tool-call conversion — a bigger change than I want to guess at. Happy to attempt it if you can say which shape you would prefer.
Environment: 2.5.4, main @ 013ff8e, cursor-agent 2026.08.04-aaa8809, macOS.
Symptom
Asked a
cursor-acp/*model to dispatch three subagents in parallel in a single message, onetaskcall each. One dispatched; the other two were silently abandoned — no error, no retry, just absent from the turn.Root cause
The proxy response builders accept a single tool call and wrap it in a one-element array.
src/proxy/tool-loop.ts:Those are the only sites in
src/that emittool_calls— every other occurrence (src/plugin.ts,src/proxy/incremental-prompt.ts) reads inbound calls. So the OpenAI-compatible response this proxy produces structurally cannot carry more than one tool call per assistant turn.The bridge-JSON envelope reinforces it from the prompt side —
src/proxy/bridge-json.ts:15and:21both instruct "respond with exactly one JSON object and no prose", andextractBridgeToolCallFromStreamOutputreturns on the first detected call.Impact
Any fan-out workflow is capped at one dispatch per turn. Best case it degrades to serial (dispatch, await result, dispatch again); observed case is worse — the model emits one and drops the rest, so a skill that fans out N reviewers silently does 1/N of its work with no error surfaced.
This affects agent workflows that dispatch multiple subagents concurrently, and more generally any turn where the model wants two or more parallel tool calls (a common pattern for independent reads/greps).
Repro
cursor-acp/*model as the main model.tasktool, issuing all three calls in one message.Notes
Distinct from #122 (
subagentTypeargument normalization), which fixes the schema mismatch on a singletaskcall. With that patch applied the surviving call validates correctly — the missing parallelism here is a separate, structural limit.Filing rather than patching because plumbing N calls through looks like it touches the response builders, the stream chunk indices (
indexis fixed at 0), and the cursor-agent event to tool-call conversion — a bigger change than I want to guess at. Happy to attempt it if you can say which shape you would prefer.Environment: 2.5.4,
main@ 013ff8e, cursor-agent2026.08.04-aaa8809, macOS.