fix(openai): only include parallel_tool_calls when explicitly enabled

This change reverts the parallel_tool_calls handling to only include it
when explicitly set to true (metadata?.parallelToolCalls === true).

Root cause: Commit ed35b09aa changed the default from false to true,
which caused models like GLM4.5 that do not support this parameter
to get stuck in a loop when reading files repeatedly.

The fix affects:
- src/api/providers/openai.ts (OpenAI-compatible handler)
- src/api/providers/base-openai-compatible-provider.ts (base class for other providers)

This ensures compatibility with models that do not support the
parallel_tool_calls parameter while still allowing it for models
that explicitly enable it.

Fixes #11071
This commit is contained in:
Roo Code 2026-01-29 14:04:01 +00:00
parent 40b2bdc4d0
commit 58d5f9daa7
3 changed files with 5 additions and 7 deletions

View file

@ -635,7 +635,6 @@ describe("OpenAiHandler", () => {
temperature: 0,
tools: undefined,
tool_choice: undefined,
parallel_tool_calls: true,
},
{ path: "/models/chat/completions" },
)
@ -684,7 +683,6 @@ describe("OpenAiHandler", () => {
],
tools: undefined,
tool_choice: undefined,
parallel_tool_calls: true,
},
{ path: "/models/chat/completions" },
)

View file

@ -95,7 +95,7 @@ export abstract class BaseOpenAiCompatibleProvider<ModelName extends string>
stream_options: { include_usage: true },
tools: this.convertToolsForOpenAI(metadata?.tools),
tool_choice: metadata?.tool_choice,
parallel_tool_calls: metadata?.parallelToolCalls ?? true,
...(metadata?.parallelToolCalls === true && { parallel_tool_calls: true }),
}
// Add thinking parameter if reasoning is enabled and model supports it

View file

@ -161,7 +161,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
...(reasoning && reasoning),
tools: this.convertToolsForOpenAI(metadata?.tools),
tool_choice: metadata?.tool_choice,
parallel_tool_calls: metadata?.parallelToolCalls ?? true,
...(metadata?.parallelToolCalls === true && { parallel_tool_calls: true }),
}
// Add max_tokens if needed
@ -229,7 +229,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
// Tools are always present (minimum ALWAYS_AVAILABLE_TOOLS)
tools: this.convertToolsForOpenAI(metadata?.tools),
tool_choice: metadata?.tool_choice,
parallel_tool_calls: metadata?.parallelToolCalls ?? true,
...(metadata?.parallelToolCalls === true && { parallel_tool_calls: true }),
}
// Add max_tokens if needed
@ -348,7 +348,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
// Tools are always present (minimum ALWAYS_AVAILABLE_TOOLS)
tools: this.convertToolsForOpenAI(metadata?.tools),
tool_choice: metadata?.tool_choice,
parallel_tool_calls: metadata?.parallelToolCalls ?? true,
...(metadata?.parallelToolCalls === true && { parallel_tool_calls: true }),
}
// O3 family models do not support the deprecated max_tokens parameter
@ -382,7 +382,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
// Tools are always present (minimum ALWAYS_AVAILABLE_TOOLS)
tools: this.convertToolsForOpenAI(metadata?.tools),
tool_choice: metadata?.tool_choice,
parallel_tool_calls: metadata?.parallelToolCalls ?? true,
...(metadata?.parallelToolCalls === true && { parallel_tool_calls: true }),
}
// O3 family models do not support the deprecated max_tokens parameter