Introduce AI Agents and tools to create entire page templates using available component entities
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3533079. --> Reported by: [akhil babu](https://www.drupal.org/user/3632866) Related to !18 !1368 !1322 >>> <p>--- AI TRACKER METADATA ---<br> <strong>Update Summary: </strong>Introduce AI Agents and tools to create entire page templates<br> <strong>Check-in Date: </strong>MM/DD/YYYY (US format) [When we should see progress/get an update]<br> <strong>Due Date:</strong> MM/DD/YYYY (US format) [When the issue should be fully completed]<br> <strong>Blocked by:</strong> [#XXXXXX] (New issues on new lines)<br> <strong>Additional Collaborators:</strong> @username1, @username2<br> AI Tracker found here: <a href="https://www.drupalstarforge.ai/" title="AI Tracker">https://www.drupalstarforge.ai/</a><br> --- END METADATA ---</p> <h3 id="overview">Overview</h3> <p>Once <span class="drupalorg-gitlab-issue-link project-issue-status-info project-issue-status-7"><a href="https://www.drupal.org/project/experience_builder/issues/3530733" title="Status: Closed (fixed)">#3530733: Introduce AI Agents and tools to Build Pages from components</a></span> gets merged, extend the code and introduce new AI agents and tools that can generate a fullpage template by strategically assembling the most suitable component entities.</p> <h3 id="proposed-resolution">Proposed resolution</h3> <ul> <li>Added a new sub-agent canvas_template_builder_agent to the orchestrator.</li> <li>For a request like &ldquo;Create a template for the homepage of an ice cream shop website&rdquo;, the agent will create the main body of the page and add the components to the content region.</li> <li>A header and footer can be added using subsequent prompts like &ldquo;Add a suitable header&rdquo; and &ldquo;Add a suitable footer.&rdquo;. This will be handled by the page builder agent</li> <li>A prompt like &ldquo;Create a template for the homepage of an ice cream shop website, with proper header and footer&rdquo; would generate the header + page body + footer. </li> <li>If dedicated header and footer regions exist, then the header/footer components will be placed in their corresponding regions. Otherwise, everything will be added to the content region.</li> <li>If multiple regions are enabled, the user can specify how to use each region through the configuration (Canvas AI Theme Region Settings).</li> <li>For example: if a sidebar region is enabled, an instruction like &ldquo;Place the sidebar menu in this region when generating templates&rdquo; can be given.</li> </ul> <h3 id="proposed-resolution">Implementation details</h3> <p>A new AI agent, &ldquo;Drupal Canvas Template Builder Agent,&rdquo; has been added to generate complete Canvas pages using AI. This agent receives the following data as context:</p> <ul> <li>The list of available components via the<code> Drupal\canvas_ai\Plugin\AiFunctionCall\GetComponentContext </code>tool.</li> <li>The current layout of the Canvas page via the <code>Drupal\canvas_ai\Plugin\AiFunctionCall\GetCurrentLayout</code> tool.</li> <li>Details of the available regions and their descriptions via the <code>[canvas_ai:available_regions] </code>token.</li> </ul> <p>The agent generates the page layout in YAML format, as shown below:</p> <pre>content:<br>&nbsp; - js.hero_banner:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mainHeading: "Discover the Best Cat Foods for Your Feline Friend"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; photo:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src: "https://placehold.co/800x600@2x.png?alternateWidths=https%3A%2F%2Fplacehold.co%2F%7Bwidth%7Dx%7Bheight%7D%402x.png"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alt: "Example image placeholder"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width: 800<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height: 600<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intent: primary<br><br>&nbsp; - js.paragraph:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; body: "Welcome to Cat Food Central &ndash; your trusted source for expert advice, product reviews, and nutrition tips to keep your cat healthy and happy."<br><br>&nbsp; - sdc.canvas_test_sdc.columns:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; columns: 3<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; slots:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column_1:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - js.product_card:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; productImage:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src: "https://placehold.co/800x600@2x.png?alternateWidths=https%3A%2F%2Fplacehold.co%2F%7Bwidth%7Dx%7Bheight%7D%402x.png"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alt: "Example image placeholder"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width: 800<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height: 600<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; productName: "Dry Cat Food"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; productPrice: "$15"<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column_2:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - js.product_card:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; productImage:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src: "https://placehold.co/800x600@2x.png?alternateWidths=https%3A%2F%2Fplacehold.co%2F%7Bwidth%7Dx%7Bheight%7D%402x.png"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alt: "Example image placeholder"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width: 800<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height: 600<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; productName: "Wet Cat Food"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; productPrice: "$20"<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column_3:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - js.product_card:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; productImage:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src: "https://placehold.co/800x600@2x.png?alternateWidths=https%3A%2F%2Fplacehold.co%2F%7Bwidth%7Dx%7Bheight%7D%402x.png"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alt: "Example image placeholder"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width: 800<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height: 600<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; productName: "Grain-Free Options"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; productPrice: "$25"<br><br>&nbsp; - js.paragraph:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; body: "Find out which type of food best matches your cat&rsquo;s age, breed, and dietary needs through our guides and expert recommendations."<br><br>&nbsp; - js.cta_section:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mainHeading: "Ready to Give Your Cat the Best Nutrition?"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; description: "Sign up for our newsletter to receive exclusive tips, reviews, and special offers tailored for passionate cat parents."<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctaText: "Subscribe Now"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctaLink: "https://example.com"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intent: primary</pre><p> This YAML is keyed by region name, and the values describe the components to be placed within each region.<br> A new tool, <code>Drupal\canvas_ai\Plugin\AiFunctionCall\SetAIGeneratedTemplateData</code>, has been added to the agent. This tool receives the YAML output from the agent, validates it, and uses the helper function <code>CanvasAiPageBuilderHelper::processSetTemplateDataToolInput</code> to convert it into a format usable by the <code>addNewComponentToLayout </code>thunk, which places each component on the page at the correct position.</p> <p>When multiple regions are enabled in Canvas, site builders can provide descriptions for each region to guide how the AI should use them when generating a page. For this purpose, a configuration form,<code> Drupal\canvas_ai\Form\CanvasAIThemeRegionSettingsForm</code>,<br> has been created. The<code> [canvas_ai:available_regions]</code> token derives its value from this configuration.</p> <p>The prompt of the <code>Canvas AI Orchestrator</code> agent has been updated to trigger the new Drupal Canvas Template Builder Agent for entire page generation. During this process, if the Canvas page title and description are empty, the orchestrator will also trigger the <code>Drupal Canvas Metadata Generation Agent</code> and the <code>Drupal Canvas Title Generation Agent</code> to generate the page title and metadata.</p> <p>By default, the Template Builder Agent generates only the page body when asked to create a complete page. Dedicated header and footer sections are generated only when explicitly requested for example:</p> <p>&ldquo;Create a homepage template for a cookie shop website with a proper header and footer.&rdquo;</p> <p>When a user interacts with the agents through the chatbot, a status message is displayed in the chatbot indicating which sub-agent has been triggered by the orchestrator. This status message is coming from <code>CanvasBuilder::getAgentDescription()</code>. We already have the <code>Drupal Canvas Page Builder Agent</code>, which focuses on adding one or more components or creating a section composed of multiple components. For example:</p> <p>&ldquo;Add three testimonials sharing positive feedback about a pizza shop below the CTA component on the page.&rdquo;<br> &ldquo;Create an &lsquo;Our Services&rsquo; section for an IT agency providing Drupal migration services.&rdquo;</p> <p>Currently, the status message displayed when this agent is triggered is &ldquo;Building the page&rdquo;, which can be confusing to users. Therefore, this message has been changed to &ldquo;Finding components to place.&rdquo;</p> <p>When the Drupal Canvas Template Builder Agent is triggered, the status message displayed will be &ldquo;Designing the page.&rdquo;</p> <p>Added a post update hook to rebuild routes as some routes related to canvas ai configs have been updated in the MR</p> <h3 id="ui-changes">User interface changes</h3> <p><a href="https://www.drupal.org/files/issues/2025-07-28/xb-ai-template.mp4" title="/files/issues/2025-07-28/xb-ai-template.mp4">DEMO</a><br> Model used: GPT-4.1</p> > Related issue: [Issue #3530733](https://www.drupal.org/node/3530733) > Related issue: [Issue #3543519](https://www.drupal.org/node/3543519) > Related issue: [Issue #3544614](https://www.drupal.org/node/3544614) > Related issue: [Issue #3545378](https://www.drupal.org/node/3545378) > Related issue: [Issue #3549232](https://www.drupal.org/node/3549232) > Related issue: [Issue #3557567](https://www.drupal.org/node/3557567) > Related issue: [Issue #3530701](https://www.drupal.org/node/3530701)
issue