$value ) { if ( ! in_array( $key, self::GEMINI_ALLOWED, true ) ) { continue; } if ( 'format' === $key && ! in_array( $value, self::GEMINI_ALLOWED_FORMATS, true ) ) { continue; } if ( 'properties' === $key && is_array( $value ) ) { $props = []; foreach ( $value as $prop => $prop_schema ) { $props[ $prop ] = is_array( $prop_schema ) ? self::forGemini( $prop_schema ) : $prop_schema; } // Gemini rejects empty properties objects on type:object nodes. if ( ! empty( $props ) ) { $clean['properties'] = $props; } continue; } if ( 'items' === $key && is_array( $value ) ) { $clean['items'] = self::forGemini( $value ); continue; } $clean[ $key ] = $value; } // An object schema with no properties confuses Gemini — degrade gracefully. if ( isset( $clean['type'] ) && 'object' === $clean['type'] && empty( $clean['properties'] ) ) { $clean['properties'] = [ '_' => [ 'type' => 'string', 'description' => 'Unused placeholder.', ], ]; } return $clean; } }