From 178539590f9d9ef56bb552599deba6bb8a451cff Mon Sep 17 00:00:00 2001 From: toki Date: Sat, 15 Aug 2026 16:11:40 +0900 Subject: [PATCH] =?UTF-8?q?fix(openai):=20=EB=8B=A8=EC=9D=BC=20selector=20?= =?UTF-8?q?=EB=8F=84=EA=B5=AC=EB=A5=BC=20required=EB=A1=9C=20=EC=A0=95?= =?UTF-8?q?=EA=B7=9C=ED=99=94=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/edge/internal/openai/provider_model_rewrite.go | 4 +--- .../internal/openai/provider_model_rewrite_test.go | 11 +++-------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/apps/edge/internal/openai/provider_model_rewrite.go b/apps/edge/internal/openai/provider_model_rewrite.go index 6e529682..034ce0c3 100644 --- a/apps/edge/internal/openai/provider_model_rewrite.go +++ b/apps/edge/internal/openai/provider_model_rewrite.go @@ -184,9 +184,7 @@ func prepareHotPathSelectorCanonicalTools(tunnel edgeservice.SubmitProviderTunne }, }, }} - root["tool_choice"] = map[string]any{ - "type": "function", "function": map[string]any{"name": hotPathArtifactPairToolName}, - } + root["tool_choice"] = "required" delete(root, "parallel_tool_calls") return json.Marshal(root) } diff --git a/apps/edge/internal/openai/provider_model_rewrite_test.go b/apps/edge/internal/openai/provider_model_rewrite_test.go index 3c0100dd..02e72095 100644 --- a/apps/edge/internal/openai/provider_model_rewrite_test.go +++ b/apps/edge/internal/openai/provider_model_rewrite_test.go @@ -388,9 +388,7 @@ func TestHotPathSelectorCanonicalWriteToolReplacesCallerCommandSchema(t *testing if function["name"] != hotPathArtifactPairToolName || properties["goal"] == nil || properties["steps"] == nil || properties["verification"] == nil || properties["command"] != nil { t.Fatalf("canonical write function=%+v", function) } - choice := request["tool_choice"].(map[string]any) - chosenFunction := choice["function"].(map[string]any) - if choice["type"] != "function" || chosenFunction["name"] != hotPathArtifactPairToolName || request["parallel_tool_calls"] != nil { + if request["tool_choice"] != "required" || request["parallel_tool_calls"] != nil { t.Fatalf("pair-write must force one atomic tool call: %+v", request) } } @@ -443,8 +441,7 @@ func TestAnthropicCallerWorkspaceSelectorUsesCanonicalProviderOperation(t *testi t.Fatalf("OpenAI selector tunnel=%+v", prepared) } tool := tools[0].(map[string]any) - choice := request["tool_choice"].(map[string]any) - if tool["name"] != hotPathArtifactPairToolName || choice["type"] != "function" || choice["name"] != hotPathArtifactPairToolName || request["max_output_tokens"] != float64(maxHotPathSelectorOutputTokens) { + if tool["name"] != hotPathArtifactPairToolName || request["tool_choice"] != "required" || request["max_output_tokens"] != float64(maxHotPathSelectorOutputTokens) { t.Fatalf("OpenAI selector request=%+v", request) } if !strings.Contains(request["instructions"].(string), "Operation: pair-write") { @@ -456,9 +453,7 @@ func TestAnthropicCallerWorkspaceSelectorUsesCanonicalProviderOperation(t *testi t.Fatalf("Gemini selector tunnel=%+v", prepared) } function := tools[0].(map[string]any)["function"].(map[string]any) - choice := request["tool_choice"].(map[string]any) - chosenFunction := choice["function"].(map[string]any) - if function["name"] != hotPathArtifactPairToolName || choice["type"] != "function" || chosenFunction["name"] != hotPathArtifactPairToolName || request["max_tokens"] != float64(maxHotPathSelectorOutputTokens) { + if function["name"] != hotPathArtifactPairToolName || request["tool_choice"] != "required" || request["max_tokens"] != float64(maxHotPathSelectorOutputTokens) { t.Fatalf("Gemini selector request=%+v", request) } messages := anySlice(request["messages"])