fix: ensure parallel tool calls flag consistency between API and client

- Fix mismatch between disable_parallel_tool_use API flag and client-side handling
- Client now uses same parallelToolCallsEnabled flag as API metadata
- Prevents tool_use/tool_result mismatch errors after 20-30 conversation turns
- Resolves issue #9700 where Anthropic API returns 400 invalid_request_error
This commit is contained in:
Roo Code 2025-11-30 09:32:14 +00:00
parent 4591e960ed
commit 83614949bd

View file

@ -481,10 +481,12 @@ export async function presentAssistantMessage(cline: Task) {
const toolCallId = (block as any).id
const toolProtocol = toolCallId ? TOOL_PROTOCOL.NATIVE : TOOL_PROTOCOL.XML
// Check experimental setting for multiple native tool calls
// Check if parallel tool calls are enabled
// This should match the parallelToolCallsEnabled flag passed to the API
const provider = cline.providerRef.deref()
const state = await provider?.getState()
const isMultipleNativeToolCallsEnabled = experiments.isEnabled(
// Use the same logic as Task.ts to determine if parallel tool calls are enabled
const parallelToolCallsEnabled = experiments.isEnabled(
state?.experiments ?? {},
EXPERIMENT_IDS.MULTIPLE_NATIVE_TOOL_CALLS,
)
@ -545,18 +547,18 @@ export async function presentAssistantMessage(cline: Task) {
}
// For XML protocol: Only one tool per message is allowed
// For native protocol with experimental flag enabled: Multiple tools can be executed in sequence
// For native protocol with experimental flag disabled: Single tool per message (default safe behavior)
// For native protocol with parallel tool calls enabled: Multiple tools can be executed in sequence
// For native protocol with parallel tool calls disabled: Single tool per message (default safe behavior)
if (toolProtocol === TOOL_PROTOCOL.XML) {
// Once a tool result has been collected, ignore all other tool
// uses since we should only ever present one tool result per
// message (XML protocol only).
cline.didAlreadyUseTool = true
} else if (toolProtocol === TOOL_PROTOCOL.NATIVE && !isMultipleNativeToolCallsEnabled) {
// For native protocol with experimental flag disabled, enforce single tool per message
} else if (toolProtocol === TOOL_PROTOCOL.NATIVE && !parallelToolCallsEnabled) {
// For native protocol with parallel tool calls disabled, enforce single tool per message
cline.didAlreadyUseTool = true
}
// If toolProtocol is NATIVE and isMultipleNativeToolCallsEnabled is true,
// If toolProtocol is NATIVE and parallelToolCallsEnabled is true,
// allow multiple tool calls in sequence (don't set didAlreadyUseTool)
}