Problem/Motivation

All three image-based field validation rules — AI image constraint (AiImageConstraintValidator, vision chat), AI image classification constraint (AiImageClassificationConstraintValidator) and AI object detection constraint (AiObjectDetectionConstraintValidator) — send the full-size original upload to the provider. Each loads the File and wraps it unchanged with $image->setFileFromFile($file).

For the vision-chat rule that is wasteful: most vision models bill image input as tokens proportional to the image's dimensions, so a multi-megapixel upload costs many times more tokens than is needed to answer a yes/no validation question. For the classification and object-detection rules a full-size original means a larger payload, slower requests and, on hosted providers, higher cost — even though the model rarely needs the original resolution. Drupal already ships the tool to fix this: image styles produce a downscaled derivative.

Proposed resolution

Add an optional Image style setting to each of the three image rules. When a style is selected, the validator runs the upload through that image style and sends the derivative to the provider instead of the original; when left empty it falls back to the original (current behaviour), so the change is fully backward compatible.

Implementation

Mirror the change across the three rule/validator pairs.

1. Rule plugins — in AiImageConstraintFieldValidationRule, AiImageClassificationConstraintFieldValidationRule and AiObjectDetectionConstraintFieldValidationRule: add 'image_style' => NULL to defaultConfiguration(), add a select element in buildConfigurationForm() populated by \Drupal\image\Entity\ImageStyle::loadMultiple() (with an empty "— Original —" option), and persist it in submitConfigurationForm(). Expose the value on the constraint so the validator can read $constraint->image_style.

2. Validators — after the File is loaded and before building the ImageFile, branch on the configured style:
$image = new ImageFile();
if a style id is set, load it, compute $uri = $style->buildUri($file->getFileUri());, create the derivative when missing with $style->createDerivative($file->getFileUri(), $uri); and feed it in with $image->setFileFromUri($uri); — otherwise keep $image->setFileFromFile($file);. AbstractFileBase already provides setFileFromUri(), so no new AI-core API is needed.

Files to touch: src/Plugin/FieldValidationRule/AiImageConstraintFieldValidationRule.php, src/Plugin/FieldValidationRule/AiImageClassificationConstraintFieldValidationRule.php, src/Plugin/FieldValidationRule/AiObjectDetectionConstraintFieldValidationRule.php, src/Plugin/Validation/Constraint/AiImageConstraintValidator.php, src/Plugin/Validation/Constraint/AiImageClassificationConstraintValidator.php, src/Plugin/Validation/Constraint/AiObjectDetectionConstraintValidator.php (plus the matching *Constraint.php classes to declare the new public property).

Notes

Image styles only apply to raster derivatives — guard against failure and fall back to the original when createDerivative() returns FALSE (e.g. SVG or an unsupported MIME type) so validation never hard-fails on a derivative problem. The token saving is most pronounced for the vision-chat AI image constraint, where input tokens scale with image dimensions, but reduced upload size benefits the classification and detection rules too. Recommend a sensible downscale (for example a ~1024px-bounded style) as guidance in the field description, and add the selected style as a config dependency of the field so exports stay consistent.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

marcus_johansson created an issue. See original summary.

marcus_johansson’s picture

Issue summary: View changes
abhisekmazumdar’s picture

Assigned: Unassigned » abhisekmazumdar

abhisekmazumdar’s picture

Assigned: abhisekmazumdar » Unassigned
Status: Active » Needs review

I have implemented the proposed resolution. Its ready for review.

What changed across all three image-based rule plugins

  • An "Image style" select is added to each rule's config form, populated from ImageStyle::loadMultiple() with a blank "Original (no style)" option at the top.
  • The config key is imageStyle (lowerCamel, required by Drupal coding standards). The three matching *Constraint.php classes each declare public $imageStyle = NULL;.
  • All three validators now call a shared applyImageStyle() helper added to AiConstraintValidatorBase. It loads the image style entity, builds the derivative URI via $style->buildUri(), creates the derivative if missing, and calls setFileFromUri(). If derivative creation fails (SVG, unsupported MIME, read-only filesystem), it falls back to setFileFromFile().
  • calculateDependencies() is implemented on all three rule plugins so the selected style is tracked as a config dependency of the rule set.
  • drupal:image added as a hard dependency in ai_validations.info.yml.

Existing rule sets with no imageStyle stored are unaffected.

abhisekmazumdar’s picture

Testing steps

Repeat the steps below for each of the three rule types: AI image constraint, AI image classification constraint, and AI object detection constraint.

  1. Open the rule set edit form and add a new rule of the relevant type.
  2. Confirm an "Image style" select appears, listing all available styles on the site plus "— Original (no style) —" as the default selection.
  3. Select a downscale style (e.g. Medium). Fill in the other required fields and save.
  4. Edit the rule again. Confirm the saved style is pre-selected on the form.
  5. Submit a content form that has the image field. Confirm validation runs and the result matches the rule configuration (violation fired or not).
  6. Edit the rule, switch back to "— Original (no style) —", save, and confirm validation still works.

Optional: config export check

Export config after saving a rule with a style selected. Open the rule set YAML and confirm the chosen image style appears under dependencies.config, e.g. image.style.medium.

marcus_johansson’s picture

Assigned: Unassigned » marcus_johansson
marcus_johansson’s picture

Assigned: marcus_johansson » Unassigned
Status: Needs review » Needs work

Just added NIT. Feel free ot merge and skip if you want or fix and merge.

abhisekmazumdar’s picture

Status: Needs work » Reviewed & tested by the community

  • abhisekmazumdar committed 807cffac on 1.3.x
    test: #3601250 Fix deprecated getMockForAbstractClass and correct @todo...

  • abhisekmazumdar committed 6bce1686 on 1.3.x
    feat: #3601250 Add image style option to image-based validation rules to...
abhisekmazumdar’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.