AI Assistant Integration for Shortcodes

The page builder includes an AI assistant that writes sections and rewrites text. For plugin authors the important part is that it can place your shortcodes on a page, using only the information in your shortcode definition.

Inactive out of the box

The assistant's code, editor panel and endpoint are part of the core, but this release registers no settings screen for it. It stays hidden until the page_builder_ai_* settings described below are written, and the signed-in user holds edit page. Treat it as an optional capability: your shortcodes must work fine without it.

How a request flows

Editor chat panel (ai-agent.js)
  -> POST admin/page-builder/ai/generate        route admin.page-builder.ai.generate
       middleware: admin stack (auth, verified, 2fa), throttle:page-builder-ai (default 20/min per user), can:edit page
  -> PageBuilderAiManager::generate()
       prompt = request + page context + capability catalogue (PageBuilderCapabilityCatalog)
       provider adapter (OpenAI, Anthropic, Gemini, Azure OpenAI, OpenAI-compatible)
  -> PageBuilderAiSanitizer      strips anything not allowed, reports warnings
  -> editor inserts the HTML (and any approved images, imported to the media library)

How your shortcode becomes visible to the AI

The capability catalogue lists every registered shortcode unless its definition opts out. For each one the model receives:

Catalogue fieldComes from
id, name, tag, groupThe arguments of ShortcodeDefinition::make($id, $name, $tag, $category)
description->description(): write it for a reader who has never seen your plugin
attributesYour traits: name, label, type, required, default, allowed values (the trait's options), min, max
module->ai(['module' => 'testimonials']); defaults to core
functional_form->ai(['form_handler' => '...']), for shortcodes that render a working form (the core contact form, Booking's form)

php — in your shortcode definition

return ShortcodeDefinition::make('testimonials', __('testimonials::testimonials.block'), 'x-shortcode-testimonials', 'testimonials')
    ->description('Shows published customer testimonials as cards or a slider.')
    ->ai(['enabled' => true, 'module' => 'testimonials'])
    // ... defaults(), traits() ...
;

// A block that only makes sense when placed by hand:
->ai(['enabled' => false])

Opt out for shortcodes that show personal data, depend on context the AI cannot know (a "current product" block), or are only useful inside one template.

What the sanitizer lets through

Everything the model returns passes through PageBuilderAiSanitizer before it reaches the canvas:

The practical rule: give your traits real options lists and sensible defaults. The tighter the trait, the more likely the assistant produces a working block.

Configuration reference

The assistant reads these settings (database settings, read with setting()):

SettingDefaultMeaning
page_builder_ai_enabledfalseMaster switch
page_builder_ai_provideropenaiopenai, anthropic, gemini, azure_openai or openai_compatible
page_builder_ai_modelthe provider's defaultA model id from PageBuilderAiRegistry::providers()
page_builder_ai_{provider}_api_key—Encrypted. Store the value returned by PageBuilderAiSecretStore::encrypt(); a plain value is treated as missing
page_builder_ai_{provider}_endpoint, _base_url, _deployment, _custom_model, _organization_id, _project_id—Provider-specific, required where the registry says so (Azure needs endpoint and deployment; OpenAI-compatible needs base URL and model)
page_builder_ai_temperature, _max_output_tokens, _timeout0.4, 2000, 45Generation limits
page_builder_ai_rate_limit20Requests per minute per user (1–120)
page_builder_ai_text_rewriting, _section_generation, _context_enabledtrueTurn individual actions and page context off
page_builder_ai_max_prompt_length, _max_context_size6000, 30000Characters

php — e.g. in a deployment command or your own settings handler

use Akaunting\Setting\Facade as Setting;
use App\Services\PageBuilder\AI\PageBuilderAiSecretStore;

Setting::set('page_builder_ai_enabled', true);
Setting::set('page_builder_ai_provider', 'anthropic');
Setting::set('page_builder_ai_anthropic_api_key', app(PageBuilderAiSecretStore::class)->encrypt($apiKey));
Setting::save();

The secret store encrypts with the application key, so a key saved on one site cannot be read on another, and rotating APP_KEY invalidates it.

Limits you should know about