Skip to content

Image suggestions with LLM - #6190

Merged
taitus merged 6 commits into
consuldemocracy:masterfrom
danesjenovdan:image-suggestions
Mar 9, 2026
Merged

Image suggestions with LLM#6190
taitus merged 6 commits into
consuldemocracy:masterfrom
danesjenovdan:image-suggestions

Conversation

@stirkac

@stirkac stirkac commented Dec 20, 2025

Copy link
Copy Markdown
Collaborator

Objectives

Since users might not have their own image to include on their purpose, we introduce AI-powered image suggestions next to the upload image button, to allow stock images from Pexels API to be added to the resource.

We reuse as much as possible of the existing infrastructure:

  • expand upon Images::NestedComponent to render the suggestions button
  • reuse DirectUploads model for storing everything related to the images

Visual Changes

  • Added setting to LLM Settings
llm-configuration-en
  • Suggest image with AI button on Image input
upload-form-with-button-en
  • Image suggestions
suggested-images-grid-en
  • Attached image when image is selected
selected-image-preview-en

Notes

Read through docs/en/features/image_suggestions.md for a deeper explanation.

@stirkac
stirkac force-pushed the image-suggestions branch 2 times, most recently from ef761cd to 4141a21 Compare December 22, 2025 07:59
@taitus taitus self-assigned this Jan 13, 2026

@taitus taitus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @stirkac

Thanks for the PR 👏 . I've left a few comments on the code. They're mostly minor suggestions and questions.

Feel free to ask if anything needs clarification.

I still need to go through the tests and documentation, but I’ll do that shortly.

Comment thread app/components/attachable/fields_component.html.erb Outdated
Comment thread app/components/budgets/investments/form_component.html.erb Outdated
Comment thread app/components/images/suggest_images_component.html.erb Outdated
Comment thread app/components/images/suggest_images_component.html.erb Outdated
Comment thread app/components/images/suggest_images_component.rb Outdated
Comment thread app/lib/image_suggestions/pexels.rb Outdated
Comment thread app/lib/image_suggestions/pexels.rb
Comment thread app/lib/image_suggestions/pexels.rb Outdated
Comment thread app/views/image_suggestions/attach.js.erb Outdated
Comment thread config/locales/en/images.yml Outdated
@stirkac
stirkac force-pushed the image-suggestions branch 2 times, most recently from 67cb30c to 4268c56 Compare January 30, 2026 18:08
@stirkac

stirkac commented Jan 30, 2026

Copy link
Copy Markdown
Collaborator Author

I believe I addressed the raised concerns, along with UX improvements to the feature. Turned out to be a bit more complex that initially expected due to some edge cases.

@taitus taitus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @stirkac 👋

Thanks again for the PR! I've left a few comments on the code (mostly small suggestions, questions, and potential simplifications).

I've also attached a small patch in one of the comments with a possible alternative approach, just as a proposal to make the discussion easier.

Let me know what you think, and happy to iterate or clarify anything 👍

Comment thread app/components/images/suggested_images_component.html.erb Outdated
Comment thread app/controllers/image_suggestions_controller.rb Outdated
def create
@resource_type = params[:resource_type]
@resource_id = params[:resource_id]
@resource_attributes = params.require(@resource_type.parameterize.underscore).permit!.except(:subtitle)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any thoughts on this one? 🤔

Comment thread app/lib/image_suggestions/llm/client.rb Outdated
Comment thread app/lib/image_suggestions/pexels.rb Outdated
Comment thread app/components/images/suggested_images_component.html.erb Outdated
Comment thread app/components/images/suggested_images_component.html.erb Outdated
Comment thread app/components/images/suggested_images_component.rb
Comment thread app/assets/javascripts/imageable.js Outdated
Comment thread app/assets/javascripts/imageable.js Outdated
@stirkac
stirkac force-pushed the image-suggestions branch 3 times, most recently from e8cd6fa to e3626cd Compare February 22, 2026 14:53
@taitus taitus added the AI label Feb 23, 2026

@taitus taitus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, @stirkac 👋

Thanks a lot for the PR and for all the iterations so far 🙏

Most of my remaining comments are small documentation suggestions, plus a few minor adjustments to the specs.

For the feedback on the tests, I've shared a .patch in this comment that applies all the discussed changes to the specs in one go:

image-suggestions-tests-and-docs.patch

While reviewing the test coverage, I noticed that although all the components are being tested, we were missing a system spec. I've added one under spec/system/ in the patch mainly as an example (it may need further tweaks)

The patch also updates an existing system spec (system/admin/settings_spec.rb) to include the AI Image Suggestions setting.

Let me know what you think, and thanks again!

Comment thread app/assets/javascripts/imageable.js
Comment thread app/controllers/image_suggestions_controller.rb Outdated
Comment thread docs/en/features/image_suggestions.md Outdated
Comment thread docs/en/features/image_suggestions.md Outdated
Comment thread docs/en/features/image_suggestions.md Outdated
Comment thread spec/lib/image_suggestions/pexels_spec.rb
Comment thread spec/shared/system/remotely_translatable.rb Outdated
Comment thread spec/lib/image_suggestions/llm/client_spec.rb
Comment thread spec/lib/image_suggestions/pexels_spec.rb
Comment thread spec/shared/system/remotely_translatable.rb Outdated
@taitus
taitus force-pushed the image-suggestions branch 9 times, most recently from 9aec0ed to dfea25b Compare March 6, 2026 13:56

@javierm javierm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@taitus I've left a few comments regarding the Spanish documentation. Let me know what you think! 😉

Comment thread docs/es/SUMMARY.md
Comment thread docs/es/features/image_suggestions.md Outdated
Comment thread docs/es/features/image_suggestions.md Outdated
Comment thread docs/es/features/image_suggestions.md Outdated
Comment thread docs/es/features/image_suggestions.md Outdated
Comment thread docs/es/features/image_suggestions.md Outdated
Comment thread docs/es/features/image_suggestions.md Outdated
Comment thread docs/es/features/image_suggestions.md Outdated
Comment thread docs/es/features/image_suggestions.md Outdated
Comment thread docs/es/features/image_suggestions.md Outdated
@taitus
taitus force-pushed the image-suggestions branch from dfea25b to aa5d64b Compare March 6, 2026 14:06
@stirkac
stirkac force-pushed the image-suggestions branch from aa5d64b to 5f064e3 Compare March 9, 2026 07:08
stirkac added 6 commits March 9, 2026 09:00
Introduce the Pexels client dependency used to search and download
stock images. Also bump ruby_llm to 1.9.x to support the LLM-based
query generation used for image suggestions.
Introduce the `llm.use_ai_image_suggestions` feature flag and expose
it in the LLM settings tab in the admin interface.

Also document the required `pexels_access_key` in the secrets example
configuration.
Introduce ImageSuggestions::Pexels as a small wrapper around the
Pexels API to search and download stock images.

This client is used by the image suggestions flow to retrieve images
that can later be attached as if they were uploaded by the user.
Introduce ImageSuggestions::Llm::Client to generate Pexels search
queries from the title and description fields of a resource.

The prompt definition is stored in `llm_prompts.yml`.
Introduce image suggestions next to the upload image button using
stock images from the Pexels service.

The feature uses an LLM to extract context from the title and
description fields of the resource and generate a search query
for the Pexels API.

Selected images are downloaded through the server and attached
as if they were uploaded by the user.

In imageable.js we remove the "_method" parameter when serializing
the form data because the request reuses the edit form. If left
in place Rails would interpret the request as PATCH/PUT instead
of creating a new image suggestion.
Document the image suggestions feature, including usage instructions,
screenshots and links from the project SUMMARY.
@taitus
taitus force-pushed the image-suggestions branch from 5f064e3 to 15022ca Compare March 9, 2026 08:03
@taitus
taitus merged commit b7b9f3c into consuldemocracy:master Mar 9, 2026
15 checks passed
@github-project-automation github-project-automation Bot moved this from Reviewing to Release 2.5.0 in Consul Democracy Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants