We built one plugin with a builder-neutral core and one adapter per form builder. The browser never tells the server what the form looks like: the server rebuilds the field schema from the stored form every time.
Key design decisions
- One normalized field schema. Each adapter turns its builder's form definition (CF7 form-tags, WPForms form JSON, Gravity Forms field objects) into the same shape:
{ id, name, label, type, required, options[], role }. Paste-to-fill, corrections and the spam gate only ever see that shape.
- Server-built schema, never trusted from the browser. The public
/parse route takes only a form key, a token and the pasted text. Target fields, labels and choice options come from get_fields() on the server, and the AI's answer is constrained by a response schema whose id is an enum of those fields.
- Layered public endpoint. Same-origin check, a per-IP rate limit, a signed per-form token (an HMAC over form key and expiry, valid 12 hours, so it survives full-page caches), the form must exist and have the feature enabled, and a site-wide daily AI cap.
- Fill only what is empty. The frontend writes only into empty fields, highlights them, offers a one-click Undo and never submits the form. Choice answers must match an existing option or they are dropped.
- Corrections without AI. Email domain typos (
gmial.com → gmail.com), E.164 phone formatting for 70+ countries and name casing run locally in the browser, with no network call.
- Spam gate in each builder's own mechanism. One
Spam_Gate returns allow, block, spam or flag; the adapters translate that into wpcf7_spam / wpcf7_before_send_mail, WPForms' wpforms_process errors and spam_reason, or Gravity Forms' gform_validation / gform_entry_is_spam.
- Privacy by construction. The classifier sees "Label: value" lines only; email addresses are reduced to their domain and phone numbers are never sent. The spam log stores salted SHA-256 hashes and a 140-character redacted excerpt, and rows expire after 90 days by default.
- Explicit failure policy. If the AI is unreachable or the daily cap is hit, the site owner chooses fail-open (deliver and log the outage) or fail-closed (block with a message).
Architecture
The plugin is PHP 7.4+ with a React admin built with @wordpress/scripts. A shared core used across DEV3's plugins provides the Google Gemini API client (structured output with maxLength caps, gemini-2.5-flash by default), encrypted key storage, rate limiting, usage logs and licensing. On top of it sit the three adapters, the paste-to-fill extractor, the classifier, the spam gate and the log repository. Each builder gets a native settings panel: a CF7 editor tab, a WPForms Settings section with a per-field "Smart paste source" toggle, and a Gravity Forms Form Settings section.