Skip to content

feat: Implement parallel_tool_calls in Responses API #4123

@anastasds

Description

@anastasds

🚀 Describe the new functionality needed

The Responses API does not implement parallel_tool_calls. This parameter controls whether more than one function call can be generated per conversational turn and defaults to true, as further explained here.

Demonstration

The intended functionality was verified against the OpenAI Responses API:

With parallel_tool_calls = true, for "check the weather in paris and new york" with a custom get_weather function defined, you get:

{
  "id": "resp_014f5a31967ccc9b00690dff589148819eb9a4e8a6f9dcb9d7",
  "object": "response",
  "created_at": 1762525016,
  "status": "completed",
...
  "model": "gpt-4.1-2025-04-14",
  "output": [
    {
      "id": "fc_014f5a31967ccc9b00690dff59eb24819ea32d6e09b54bfda3",
      "type": "function_call",
      "status": "completed",
      "arguments": "{\"city\":\"Paris\"}",
      "call_id": "call_wD7QAYoGibJ9AiAeHfbO7siC",
      "name": "get_weather"
    },
    {
      "id": "fc_014f5a31967ccc9b00690dff5a0048819ea9511f129abb4012",
      "type": "function_call",
      "status": "completed",
      "arguments": "{\"city\":\"New York\"}",
      "call_id": "call_qjvFAXVGN2gYofgcWL2oJ0H4",
      "name": "get_weather"
    }
  ],

With parallel_tool_calls = false instead you get the first function call for Paris:

{
  "id": "resp_07bb3df5e23388db00690dff6a9f04819f9d3f684a2860e3ba",
  "object": "response",
  "created_at": 1762525034,
  "status": "completed",
...
  "model": "gpt-4.1-2025-04-14",
  "output": [
    {
      "id": "fc_07bb3df5e23388db00690dff6bd220819fa57fc8339d02fe79",
      "type": "function_call",
      "status": "completed",
      "arguments": "{\"city\":\"Paris\"}",
      "call_id": "call_CgwW210BtwtgtBnepEtbs49E",
      "name": "get_weather"
    }
  ],

After that, you need to reference this response ID in 'previous_response_id', and include the results of executing your get_weather call client side:

curl https://api.openai.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer REDACTED" \
  -d '{
    "model": "gpt-4.1",
    "input": [
      {
        "role": "user",
        "content": "Check the weather in Paris and New York."
      },
      {
        "call_id": "call_QQoOe5xngTrVeEhBAylU5Wq4",
        "type": "function_call_output",
        "output": "18 c"
      }
    ],
    "tools": [
      {
        "type": "function",
        "name": "get_weather",
        "description": "Get the current weather in a city",
        "parameters": {
          "type": "object",
          "properties": {
            "city": { "type": "string" }
          },
          "required": ["city"]
        }
      }
    ],
    "previous_response_id": "resp_01ac8d2bbf5c091100690e0159d754819fad9ae58a17545d2d",
    "parallel_tool_calls": false,
    "max_tool_calls": 4
  }'

and then it responds to you with the next get_weather call:

{
  "id": "resp_01ac8d2bbf5c091100690e04c65d1c819f99f997d3d8a562c6",
  "object": "response",
  "created_at": 1762526406,
  "status": "completed",
...
  "model": "gpt-4.1-2025-04-14",
  "output": [
    {
      "id": "fc_01ac8d2bbf5c091100690e04c77c60819f98c1a8784d9bde87",
      "type": "function_call",
      "status": "completed",
      "arguments": "{\"city\":\"New York\"}",
      "call_id": "call_v2tZ2Cqixtnkov62beASkTPx",
      "name": "get_weather"
    }
  ],

Note that now it's giving the function call for New York, and you keep going in this manner until done.

💡 Why is this needed? What if we don't build it?

This is required for full compatibility with the OpenAI Responses API.

Other thoughts

This looks like it will require multiple PRs as the parallel_tool_calls is not available in the client SDK, and fully testing it using existing test utils for helping verify multi-turn functionality will require it to be there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions