feat: wire MULTIPLE_NATIVE_TOOL_CALLS experiment to OpenAI parallel_tool_calls (#9621)

This commit is contained in:
Hannes Rudolph 2025-11-26 15:12:54 -07:00 committed by GitHub
parent 240bc0b6b1
commit 3208f6f6dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 3 deletions

View file

@ -89,6 +89,13 @@ export interface ApiHandlerCreateMessageMetadata {
* Used by providers to determine whether to include native tool definitions.
*/
toolProtocol?: ToolProtocol
/**
* Controls whether the model can return multiple tool calls in a single response.
* When true, parallel tool calls are enabled (OpenAI's parallel_tool_calls=true).
* When false (default), only one tool call is returned per response.
* Only applies when toolProtocol is "native".
*/
parallelToolCalls?: boolean
}
export interface ApiHandler {

View file

@ -299,10 +299,12 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio
...(metadata?.tool_choice && { tool_choice: metadata.tool_choice }),
}
// For native tool protocol, explicitly disable parallel tool calls.
// For native tool protocol, control parallel tool calls based on the metadata flag.
// When parallelToolCalls is true, allow parallel tool calls (OpenAI's parallel_tool_calls=true).
// When false (default), explicitly disable parallel tool calls (false).
// For XML or when protocol is unset, omit the field entirely so the API default applies.
if (metadata?.toolProtocol === "native") {
body.parallel_tool_calls = false
body.parallel_tool_calls = metadata.parallelToolCalls ?? false
}
// Include text.verbosity only when the model explicitly supports it

View file

@ -3452,11 +3452,19 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
})
}
// Resolve parallel tool calls setting from experiment (will move to per-API-profile setting later)
const parallelToolCallsEnabled = experiments.isEnabled(
state?.experiments ?? {},
EXPERIMENT_IDS.MULTIPLE_NATIVE_TOOL_CALLS,
)
const metadata: ApiHandlerCreateMessageMetadata = {
mode: mode,
taskId: this.taskId,
// Include tools and tool protocol when using native protocol and model supports it
...(shouldIncludeTools ? { tools: allTools, tool_choice: "auto", toolProtocol } : {}),
...(shouldIncludeTools
? { tools: allTools, tool_choice: "auto", toolProtocol, parallelToolCalls: parallelToolCallsEnabled }
: {}),
}
// Create an AbortController to allow cancelling the request mid-stream