diff --git a/internal/util/gemini_schema.go b/internal/util/gemini_schema.go index 2daf0a79..33df61f9 100644 --- a/internal/util/gemini_schema.go +++ b/internal/util/gemini_schema.go @@ -344,7 +344,7 @@ func cleanupRequiredFields(jsonStr string) string { } // addEmptySchemaPlaceholder adds a placeholder "reason" property to empty object schemas. -// Claude VALIDATED mode requires at least one property in tool schemas. +// Claude VALIDATED mode requires at least one required property in tool schemas. func addEmptySchemaPlaceholder(jsonStr string) string { // Find all "type" fields paths := findPaths(jsonStr, "type") @@ -364,6 +364,9 @@ func addEmptySchemaPlaceholder(jsonStr string) string { // Check if properties exists and is empty or missing propsPath := joinPath(parentPath, "properties") propsVal := gjson.Get(jsonStr, propsPath) + reqPath := joinPath(parentPath, "required") + reqVal := gjson.Get(jsonStr, reqPath) + hasRequiredProperties := reqVal.IsArray() && len(reqVal.Array()) > 0 needsPlaceholder := false if !propsVal.Exists() { @@ -381,8 +384,17 @@ func addEmptySchemaPlaceholder(jsonStr string) string { jsonStr, _ = sjson.Set(jsonStr, reasonPath+".description", "Brief explanation of why you are calling this tool") // Add to required array - reqPath := joinPath(parentPath, "required") jsonStr, _ = sjson.Set(jsonStr, reqPath, []string{"reason"}) + continue + } + + // If schema has properties but none are required, add a minimal placeholder. + if propsVal.IsObject() && !hasRequiredProperties { + placeholderPath := joinPath(propsPath, "_") + if !gjson.Get(jsonStr, placeholderPath).Exists() { + jsonStr, _ = sjson.Set(jsonStr, placeholderPath+".type", "boolean") + } + jsonStr, _ = sjson.Set(jsonStr, reqPath, []string{"_"}) } }