Skip to content

AI-filled address and link fields

Version v1

Initialising viewer…

You can apply this model as a recipe (Drupal 10.3 or later) to your own Drupal site:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
## Import recipe
composer require drupal-eca-recipe/eca_lib_0048

# Apply recipe with Drush (requires version 13 or later):
drush recipe ../recipes/eca_lib_0048

# Apply recipe without Drush:
cd web && php core/scripts/drupal recipe ../recipes/eca_lib_0048

# Rebuilding caches is optional, sometimes required:
drush cr

Purpose

Two buttons on the Business node form ask an AI chat model for facts that an editor would otherwise look up by hand. "Look up the address" fills the compound Address field, "Look up the website" fills the Link field. Both read the node title and the body text of the form that is open at that moment, so they work on a node that has never been saved.

How the compound fill works

A compound field stores several properties per item, so a single string cannot fill it. Both "Set field widget value" actions therefore enable "Interpret above value as YAML format" (use_yaml: true) and return a mapping of the field's property names: country_code, organization, address_line1, address_line2, locality, administrative_area and postal_code for the address field, uri and title for the link field. ECA parses that YAML first and replaces tokens per leaf value afterwards, so every property carries its own token. A token starts with [, which YAML reads as the start of a list, so each one is wrapped in double quotes: locality: "[address_data:locality]".

Both events set "Restrict by widget kind" to compound fields (fill_strategies: compound), and the form display enables "Fill the field directly" on both buttons. Without direct fill the button offers the suggestions dialog, which cannot present a mapping. The compound fill runs while the form is processed rather than in JavaScript, so a form with unrelated validation errors shows those errors instead of a filled field.

How the AI answer becomes field properties

Each branch strips the tags from the body, sends the title and that plain text to the Chat action with a strict JSON schema, and receives the response as a string. Tamper: Encode/Decode in Json Decode mode turns it into structured data under address_data or website_data, and the fill action addresses the leaves as [address_data:postal_code] or [website_data:uri].

The raw response keeps a token of its own, address_ai_response or website_ai_response, because decoding a token into its own name would discard the string the failure branch logs. Nothing reaches the widget until the decoded response carries a country code, or a URI for the website; the unusable case goes to the eca_ai_lookup log channel.

The editor has the last word

A button fills the widget and nothing else. It never saves the node, so review the address and the website before you save: the prompt asks for an empty string rather than a guess, but an AI model can still be confident and wrong.

The address module validates the value against the address format of the country when the node is saved. administrative_area belongs to some formats only, California is CA while a German address has no such property, and a value the format does not use is rejected. Correct those cases in the widget before saving.

Requires an unreleased ECA Field Widget Actions

The compound fill and the use_yaml setting arrived after 1.0.0-beta2, so this model needs a newer 1.0.x-dev (see issue #3588902). Neither fill_strategies: compound nor use_yaml exists in that release, and the recipe's composer.json always asks for any version, so check the installed version by hand.

Before you run it

Select a chat model that supports structured output in both chat actions, "Ask AI for the postal address" and "Ask AI for the website". Without structured output the schema is ignored and the response does not decode. Each click waits for the provider, which takes a few seconds.

Requirements

This recipe installs address, link, node, text, path and field_widget_actions next to eca, eca_base, eca_field_widget_actions, eca_log, eca_tamper, ai_integration_eca and modeler_api. No core recipe provides a Business content type, so the recipe ships it with its body, field_address and field_website fields and its form and view displays.

Dependencies

  • module
    • ai_integration_eca
    • eca_base
    • eca_field_widget_actions
    • eca_log
    • eca_tamper
    • modeler_api

Used plugins

Events

Conditions

Actions