fix(grok): handle typed invalid tool unions

This commit is contained in:
Whisper-stark
2026-08-27 21:03:23 +08:00
parent f4820c00dc
commit fd872550d5
2 changed files with 36 additions and 3 deletions
@@ -1159,8 +1159,7 @@ func sanitizeGrokResponsesTools(body []byte) ([]byte, error) {
}
func grokFunctionParametersHaveInvalidUnionRoot(parameters gjson.Result) bool {
if !parameters.Exists() || !parameters.IsObject() ||
strings.EqualFold(strings.TrimSpace(parameters.Get("type").String()), "object") {
if !parameters.Exists() || !parameters.IsObject() {
return false
}
for _, keyword := range []string{"anyOf", "oneOf"} {
@@ -398,7 +398,7 @@ func TestSanitizeGrokResponsesToolsRemovesDeferredFlagsWithToolSearch(t *testing
func TestSanitizeGrokResponsesToolsSimplifiesInvalidRootUnion(t *testing.T) {
body := []byte(`{"tools":[
{"type":"function","name":"mcp__codex_app__automation_update","strict":true,"parameters":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"}}},{"type":"null"}]}},
{"type":"function","name":"object_only","strict":true,"parameters":{"anyOf":[{"type":"object","properties":{"a":{"type":"string"}}},{"type":"object","properties":{"b":{"type":"integer"}}}]}}
{"type":"function","name":"object_only","strict":true,"parameters":{"type":"object","anyOf":[{"type":"object","properties":{"a":{"type":"string"}}},{"type":"object","properties":{"b":{"type":"integer"}}}]}}
]}`)
patched, err := sanitizeGrokResponsesTools(body)
@@ -417,6 +417,40 @@ func TestSanitizeGrokResponsesToolsSimplifiesInvalidRootUnion(t *testing.T) {
require.Equal(t, gjson.True, objectOnly.Get("strict").Type)
}
func TestPatchGrokResponsesBodySimplifiesTypedInvalidRootUnion(t *testing.T) {
body := []byte(`{
"model":"grok-4.6",
"metadata":{"session_id":"abc"},
"tools":[{
"type":"namespace",
"name":"mcp__codex_app",
"tools":[{
"type":"function",
"name":"automation_update",
"strict":true,
"parameters":{
"type":"object",
"oneOf":[{"$ref":"#/$defs/update"},{"type":"null"}],
"$defs":{"update":{"type":"object","properties":{"id":{"type":"string"}}}}
}
}]
}]
}`)
patched, _, err := patchGrokResponsesBodyWithClientTools(body, "grok-4.6")
require.NoError(t, err)
require.True(t, json.Valid(patched))
require.False(t, gjson.GetBytes(patched, "metadata").Exists())
tool := gjson.GetBytes(patched, `tools.#(name=="mcp__codex_app__automation_update")`)
require.Equal(t, "object", tool.Get("parameters.type").String())
require.True(t, tool.Get("parameters.properties").IsObject())
require.True(t, tool.Get("parameters.additionalProperties").Bool())
require.False(t, tool.Get("parameters.oneOf").Exists())
require.False(t, tool.Get("parameters.$defs").Exists())
require.Equal(t, gjson.False, tool.Get("strict").Type)
}
func TestSanitizeGrokResponsesToolsKeepsToolChoiceOnlyWithSupportedTools(t *testing.T) {
t.Parallel()