From b0a3481ea870a6d38e24fd8a1df62586dd98ba5a Mon Sep 17 00:00:00 2001 From: Danni Friedland Date: Fri, 3 Apr 2026 20:36:37 +0200 Subject: [PATCH 1/2] feat: forward parallel_tool_calls to Responses API body --- lib/req_llm/providers/openai/responses_api.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/req_llm/providers/openai/responses_api.ex b/lib/req_llm/providers/openai/responses_api.ex index f292786c..cb58a7a7 100644 --- a/lib/req_llm/providers/openai/responses_api.ex +++ b/lib/req_llm/providers/openai/responses_api.ex @@ -619,6 +619,7 @@ defmodule ReqLLM.Providers.OpenAI.ResponsesAPI do |> maybe_put_string("reasoning", reasoning) |> maybe_put_string("tools", tools) |> maybe_put_string("tool_choice", tool_choice) + |> maybe_put_string("parallel_tool_calls", opts_map[:parallel_tool_calls]) |> maybe_put_string("service_tier", service_tier) |> maybe_put_string("text", text_format) From 7f227973d3810a886ce3dd6cd8685ba36ee1a24e Mon Sep 17 00:00:00 2001 From: Danni Friedland Date: Sat, 11 Apr 2026 21:25:02 +0200 Subject: [PATCH 2/2] test: cover parallel_tool_calls encoding in Responses API Add unit tests for forwarding parallel_tool_calls to the Responses API body, including true, false, and omitted cases. --- .../openai/responses_api_unit_test.exs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/provider/openai/responses_api_unit_test.exs b/test/provider/openai/responses_api_unit_test.exs index 6eb126d1..e6477c4e 100644 --- a/test/provider/openai/responses_api_unit_test.exs +++ b/test/provider/openai/responses_api_unit_test.exs @@ -235,6 +235,33 @@ defmodule Provider.OpenAI.ResponsesAPIUnitTest do assert body["tool_choice"] == %{"type" => "function", "name" => "search"} end + test "encodes parallel_tool_calls true" do + request = build_request(parallel_tool_calls: true) + + encoded = ResponsesAPI.encode_body(request) + body = Jason.decode!(encoded.body) + + assert body["parallel_tool_calls"] == true + end + + test "encodes parallel_tool_calls false" do + request = build_request(parallel_tool_calls: false) + + encoded = ResponsesAPI.encode_body(request) + body = Jason.decode!(encoded.body) + + assert body["parallel_tool_calls"] == false + end + + test "omits parallel_tool_calls when not set" do + request = build_request([]) + + encoded = ResponsesAPI.encode_body(request) + body = Jason.decode!(encoded.body) + + refute Map.has_key?(body, "parallel_tool_calls") + end + test "encodes reasoning effort with atom" do request = build_request(reasoning_effort: :medium) @@ -1430,6 +1457,7 @@ defmodule Provider.OpenAI.ResponsesAPIUnitTest do max_tokens: Keyword.get(opts, :max_tokens), tools: Keyword.get(opts, :tools), tool_choice: Keyword.get(opts, :tool_choice), + parallel_tool_calls: Keyword.get(opts, :parallel_tool_calls), reasoning_effort: Keyword.get(opts, :reasoning_effort), provider_options: provider_opts }