fix(codex): explicitly default function tool strict to false

- Forward `strict` as `false` when omitted in function tools to prevent upstream Responses API from defaulting it to `true`.

Closes: #5555
This commit is contained in:
Luis Pater
2026-09-07 22:52:24 +08:00
parent 8696585cea
commit d01516c120
2 changed files with 57 additions and 0 deletions

View File

@@ -467,6 +467,10 @@ func ConvertOpenAIRequestToCodex(modelName string, inputRawJSON []byte, stream b
}
if v := fn.Get("strict"); v.Exists() {
item, _ = sjson.SetBytes(item, "strict", v.Value())
} else {
// Chat Completions defaults strict to false while the Responses API
// defaults it to true, so an omitted value must be forwarded explicitly.
item, _ = sjson.SetBytes(item, "strict", false)
}
}
toolItems = append(toolItems, item)

View File

@@ -1404,3 +1404,56 @@ func TestToolsDefinitionTranslated(t *testing.T) {
t.Errorf("tool 'search' not found in output tools: %s", gjson.Get(result, "tools").Raw)
}
}
func TestFunctionToolStrictDefaultsToFalse(t *testing.T) {
input := []byte(`{
"model": "gpt-5.6-sol",
"messages": [
{"role": "user", "content": "Hi"}
],
"tools": [
{
"type": "function",
"function": {
"name": "omitted",
"parameters": {"type": "object", "properties": {"query": {"type": "string"}}}
}
},
{
"type": "function",
"function": {
"name": "explicit_true",
"strict": true,
"parameters": {"type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"], "additionalProperties": false}
}
},
{
"type": "function",
"function": {
"name": "explicit_false",
"strict": false,
"parameters": {"type": "object", "properties": {"query": {"type": "string"}}}
}
}
]
}`)
out := ConvertOpenAIRequestToCodex("gpt-5.6-sol", input, true)
tools := gjson.GetBytes(out, "tools").Array()
if len(tools) != 3 {
t.Fatalf("expected 3 tools, got %d: %s", len(tools), gjson.GetBytes(out, "tools").Raw)
}
expected := map[string]bool{"omitted": false, "explicit_true": true, "explicit_false": false}
for _, tool := range tools {
name := tool.Get("name").String()
strict := tool.Get("strict")
if !strict.Exists() {
t.Errorf("tool %q: strict missing in output: %s", name, tool.Raw)
continue
}
if strict.Bool() != expected[name] {
t.Errorf("tool %q: strict = %v, want %v", name, strict.Bool(), expected[name])
}
}
}