@@ -21,6 +21,44 @@ func CleanJSONSchemaForAntigravity(jsonStr string) string {
2121 return cleanJSONSchema (jsonStr , true )
2222}
2323
24+ // CleanJSONSchemaForGemini transforms a JSON schema to be compatible with Gemini tool calling.
25+ // It removes unsupported keywords and simplifies schemas, without adding empty-schema placeholders.
26+ func CleanJSONSchemaForGemini (jsonStr string ) string {
27+ return cleanJSONSchema (jsonStr , false )
28+ }
29+
30+ // cleanJSONSchema performs the core cleaning operations on the JSON schema.
31+ func cleanJSONSchema (jsonStr string , addPlaceholder bool ) string {
32+ // Phase 1: Convert and add hints
33+ jsonStr = convertRefsToHints (jsonStr )
34+ jsonStr = convertConstToEnum (jsonStr )
35+ jsonStr = convertEnumValuesToStrings (jsonStr )
36+ jsonStr = addEnumHints (jsonStr )
37+ jsonStr = addAdditionalPropertiesHints (jsonStr )
38+ jsonStr = moveConstraintsToDescription (jsonStr )
39+
40+ // Phase 2: Flatten complex structures
41+ jsonStr = mergeAllOf (jsonStr )
42+ jsonStr = flattenAnyOfOneOf (jsonStr )
43+ jsonStr = flattenTypeArrays (jsonStr )
44+
45+ // Phase 3: Cleanup
46+ jsonStr = removeUnsupportedKeywords (jsonStr )
47+ if ! addPlaceholder {
48+ // Gemini schema cleanup: remove nullable/title and placeholder-only fields.
49+ jsonStr = removeKeywords (jsonStr , []string {"nullable" , "title" })
50+ jsonStr = removePlaceholderFields (jsonStr )
51+ }
52+ jsonStr = cleanupRequiredFields (jsonStr )
53+ // Phase 4: Add placeholder for empty object schemas (Claude VALIDATED mode requirement)
54+ if addPlaceholder {
55+ jsonStr = addEmptySchemaPlaceholder (jsonStr )
56+ }
57+
58+ return jsonStr
59+ }
60+
61+ // removeKeywords removes all occurrences of specified keywords from the JSON schema.
2462func removeKeywords (jsonStr string , keywords []string ) string {
2563 for _ , key := range keywords {
2664 for _ , p := range findPaths (jsonStr , key ) {
@@ -98,42 +136,6 @@ func removePlaceholderFields(jsonStr string) string {
98136 return jsonStr
99137}
100138
101- // CleanJSONSchemaForGemini transforms a JSON schema to be compatible with Gemini tool calling.
102- // It removes unsupported keywords and simplifies schemas, without adding empty-schema placeholders.
103- func CleanJSONSchemaForGemini (jsonStr string ) string {
104- return cleanJSONSchema (jsonStr , false )
105- }
106-
107- func cleanJSONSchema (jsonStr string , addPlaceholder bool ) string {
108- // Phase 1: Convert and add hints
109- jsonStr = convertRefsToHints (jsonStr )
110- jsonStr = convertConstToEnum (jsonStr )
111- jsonStr = convertEnumValuesToStrings (jsonStr )
112- jsonStr = addEnumHints (jsonStr )
113- jsonStr = addAdditionalPropertiesHints (jsonStr )
114- jsonStr = moveConstraintsToDescription (jsonStr )
115-
116- // Phase 2: Flatten complex structures
117- jsonStr = mergeAllOf (jsonStr )
118- jsonStr = flattenAnyOfOneOf (jsonStr )
119- jsonStr = flattenTypeArrays (jsonStr )
120-
121- // Phase 3: Cleanup
122- jsonStr = removeUnsupportedKeywords (jsonStr )
123- if ! addPlaceholder {
124- // Gemini schema cleanup: remove nullable/title and placeholder-only fields.
125- jsonStr = removeKeywords (jsonStr , []string {"nullable" , "title" })
126- jsonStr = removePlaceholderFields (jsonStr )
127- }
128- jsonStr = cleanupRequiredFields (jsonStr )
129- // Phase 4: Add placeholder for empty object schemas (Claude VALIDATED mode requirement)
130- if addPlaceholder {
131- jsonStr = addEmptySchemaPlaceholder (jsonStr )
132- }
133-
134- return jsonStr
135- }
136-
137139// convertRefsToHints converts $ref to description hints (Lazy Hint strategy).
138140func convertRefsToHints (jsonStr string ) string {
139141 paths := findPaths (jsonStr , "$ref" )
0 commit comments