mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-09-11 14:47:58 +08:00
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:
@@ -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)
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user