Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 4 additions & 2 deletions src/api/providers/openai-native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion src/core/task/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading