diff --git a/internal/runtime/executor/antigravity_executor.go b/internal/runtime/executor/antigravity_executor.go index e17d525c..ea73c266 100644 --- a/internal/runtime/executor/antigravity_executor.go +++ b/internal/runtime/executor/antigravity_executor.go @@ -1213,7 +1213,6 @@ func (e *AntigravityExecutor) buildRequest(ctx context.Context, auth *cliproxyau // Use the centralized schema cleaner to handle unsupported keywords, // const->enum conversion, and flattening of types/anyOf. strJSON = util.CleanJSONSchemaForAntigravity(strJSON) - payload = []byte(strJSON) } else { strJSON := string(payload) diff --git a/internal/util/gemini_schema.go b/internal/util/gemini_schema.go index ddcee040..867dd4fa 100644 --- a/internal/util/gemini_schema.go +++ b/internal/util/gemini_schema.go @@ -21,6 +21,44 @@ func CleanJSONSchemaForAntigravity(jsonStr string) string { return cleanJSONSchema(jsonStr, true) } +// CleanJSONSchemaForGemini transforms a JSON schema to be compatible with Gemini tool calling. +// It removes unsupported keywords and simplifies schemas, without adding empty-schema placeholders. +func CleanJSONSchemaForGemini(jsonStr string) string { + return cleanJSONSchema(jsonStr, false) +} + +// cleanJSONSchema performs the core cleaning operations on the JSON schema. +func cleanJSONSchema(jsonStr string, addPlaceholder bool) string { + // Phase 1: Convert and add hints + jsonStr = convertRefsToHints(jsonStr) + jsonStr = convertConstToEnum(jsonStr) + jsonStr = convertEnumValuesToStrings(jsonStr) + jsonStr = addEnumHints(jsonStr) + jsonStr = addAdditionalPropertiesHints(jsonStr) + jsonStr = moveConstraintsToDescription(jsonStr) + + // Phase 2: Flatten complex structures + jsonStr = mergeAllOf(jsonStr) + jsonStr = flattenAnyOfOneOf(jsonStr) + jsonStr = flattenTypeArrays(jsonStr) + + // Phase 3: Cleanup + jsonStr = removeUnsupportedKeywords(jsonStr) + if !addPlaceholder { + // Gemini schema cleanup: remove nullable/title and placeholder-only fields. + jsonStr = removeKeywords(jsonStr, []string{"nullable", "title"}) + jsonStr = removePlaceholderFields(jsonStr) + } + jsonStr = cleanupRequiredFields(jsonStr) + // Phase 4: Add placeholder for empty object schemas (Claude VALIDATED mode requirement) + if addPlaceholder { + jsonStr = addEmptySchemaPlaceholder(jsonStr) + } + + return jsonStr +} + +// removeKeywords removes all occurrences of specified keywords from the JSON schema. func removeKeywords(jsonStr string, keywords []string) string { for _, key := range keywords { for _, p := range findPaths(jsonStr, key) { @@ -98,42 +136,6 @@ func removePlaceholderFields(jsonStr string) string { return jsonStr } -// CleanJSONSchemaForGemini transforms a JSON schema to be compatible with Gemini tool calling. -// It removes unsupported keywords and simplifies schemas, without adding empty-schema placeholders. -func CleanJSONSchemaForGemini(jsonStr string) string { - return cleanJSONSchema(jsonStr, false) -} - -func cleanJSONSchema(jsonStr string, addPlaceholder bool) string { - // Phase 1: Convert and add hints - jsonStr = convertRefsToHints(jsonStr) - jsonStr = convertConstToEnum(jsonStr) - jsonStr = convertEnumValuesToStrings(jsonStr) - jsonStr = addEnumHints(jsonStr) - jsonStr = addAdditionalPropertiesHints(jsonStr) - jsonStr = moveConstraintsToDescription(jsonStr) - - // Phase 2: Flatten complex structures - jsonStr = mergeAllOf(jsonStr) - jsonStr = flattenAnyOfOneOf(jsonStr) - jsonStr = flattenTypeArrays(jsonStr) - - // Phase 3: Cleanup - jsonStr = removeUnsupportedKeywords(jsonStr) - if !addPlaceholder { - // Gemini schema cleanup: remove nullable/title and placeholder-only fields. - jsonStr = removeKeywords(jsonStr, []string{"nullable", "title"}) - jsonStr = removePlaceholderFields(jsonStr) - } - jsonStr = cleanupRequiredFields(jsonStr) - // Phase 4: Add placeholder for empty object schemas (Claude VALIDATED mode requirement) - if addPlaceholder { - jsonStr = addEmptySchemaPlaceholder(jsonStr) - } - - return jsonStr -} - // convertRefsToHints converts $ref to description hints (Lazy Hint strategy). func convertRefsToHints(jsonStr string) string { paths := findPaths(jsonStr, "$ref")