Merge pull request #3884 from CHOS1N11111/codex/add-parallel-tool-calls-compat

Add parallel_tool_calls compatibility mapping
This commit is contained in:
Wesley Liddick
2026-07-10 11:01:03 +08:00
committed by GitHub
5 changed files with 48 additions and 6 deletions
@@ -28,6 +28,7 @@ func ResponsesToChatCompletionsRequest(req *ResponsesRequest) (*ChatCompletionsR
TopP: req.TopP,
Stream: req.Stream,
ServiceTier: req.ServiceTier,
ParallelToolCalls: req.ParallelToolCalls,
}
if req.Reasoning != nil {
out.ReasoningEffort = req.Reasoning.Effort
@@ -127,6 +127,26 @@ func TestResponsesToChatCompletionsRequest_TextFormatJsonSchema(t *testing.T) {
}`, string(out.ResponseFormat))
}
func TestResponsesToChatCompletionsRequest_ParallelToolCalls(t *testing.T) {
parallel := false
req := &ResponsesRequest{
Model: "gpt-4o",
Input: json.RawMessage(`[
{"role":"user","content":"Use tools"}
]`),
ParallelToolCalls: &parallel,
}
out, err := ResponsesToChatCompletionsRequest(req)
require.NoError(t, err)
require.NotNil(t, out.ParallelToolCalls)
assert.False(t, *out.ParallelToolCalls)
payload, err := json.Marshal(out)
require.NoError(t, err)
assert.Contains(t, string(payload), `"parallel_tool_calls":false`)
}
func chatMessageRoles(messages []ChatMessage) []string {
roles := make([]string, 0, len(messages))
for _, message := range messages {
@@ -531,6 +531,25 @@ func TestChatCompletionsToResponses_ServiceTier(t *testing.T) {
assert.Equal(t, "flex", resp.ServiceTier)
}
func TestChatCompletionsToResponses_ParallelToolCalls(t *testing.T) {
for _, value := range []bool{false, true} {
req := &ChatCompletionsRequest{
Model: "gpt-4o",
ParallelToolCalls: &value,
Messages: []ChatMessage{{Role: "user", Content: json.RawMessage(`"Hi"`)}},
}
resp, err := ChatCompletionsToResponses(req)
require.NoError(t, err)
require.NotNil(t, resp.ParallelToolCalls)
assert.Equal(t, value, *resp.ParallelToolCalls)
payload, err := json.Marshal(resp)
require.NoError(t, err)
assert.Contains(t, string(payload), `"parallel_tool_calls":`+string(mustMarshalJSON(t, value)))
}
}
// ---------------------------------------------------------------------------
// temperature / top_p stripping for reasoning models
// ---------------------------------------------------------------------------
@@ -27,12 +27,13 @@ func ChatCompletionsToResponses(req *ChatCompletionsRequest) (*ResponsesRequest,
}
out := &ResponsesRequest{
Model: req.Model,
Instructions: req.Instructions,
Input: inputJSON,
Stream: true, // upstream always streams
Include: []string{"reasoning.encrypted_content"},
ServiceTier: req.ServiceTier,
Model: req.Model,
Instructions: req.Instructions,
Input: inputJSON,
Stream: true, // upstream always streams
Include: []string{"reasoning.encrypted_content"},
ServiceTier: req.ServiceTier,
ParallelToolCalls: req.ParallelToolCalls,
}
// Reasoning models (gpt-5.x) do not accept sampling parameters.
+1
View File
@@ -435,6 +435,7 @@ type ChatCompletionsRequest struct {
Stream bool `json:"stream,omitempty"`
StreamOptions *ChatStreamOptions `json:"stream_options,omitempty"`
Tools []ChatTool `json:"tools,omitempty"`
ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
ToolChoice json.RawMessage `json:"tool_choice,omitempty"`
ReasoningEffort string `json:"reasoning_effort,omitempty"` // "low" | "medium" | "high" | "xhigh"
ServiceTier string `json:"service_tier,omitempty"`