--- AI TRACKER METADATA ---
Update Summary: Introduce AI Agents and tools to create entire page templates
Check-in Date: MM/DD/YYYY (US format) [When we should see progress/get an update]
Due Date: MM/DD/YYYY (US format) [When the issue should be fully completed]
Blocked by: [#XXXXXX] (New issues on new lines)
Additional Collaborators: @username1, @username2
AI Tracker found here: https://www.drupalstarforge.ai/
--- END METADATA ---
Overview
Once #3530733: Introduce AI Agents and tools to Build Pages from components 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.
Proposed resolution
- Added a new sub-agent canvas_template_builder_agent to the orchestrator.
- For a request like “Create a template for the homepage of an ice cream shop website”, the agent will create the main body of the page and add the components to the content region.
- A header and footer can be added using subsequent prompts like “Add a suitable header” and “Add a suitable footer.”. This will be handled by the page builder agent
- A prompt like “Create a template for the homepage of an ice cream shop website, with proper header and footer” would generate the header + page body + footer.
- 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.
- If multiple regions are enabled, the user can specify how to use each region through the configuration (Canvas AI Theme Region Settings).
- For example: if a sidebar region is enabled, an instruction like “Place the sidebar menu in this region when generating templates” can be given.
Implementation details
A new AI agent, “Drupal Canvas Template Builder Agent,” has been added to generate complete Canvas pages using AI. This agent receives the following data as context:
- The list of available components via the
Drupal\canvas_ai\Plugin\AiFunctionCall\GetComponentContexttool. - The current layout of the Canvas page via the
Drupal\canvas_ai\Plugin\AiFunctionCall\GetCurrentLayouttool. - Details of the available regions and their descriptions via the
[canvas_ai:available_regions]token.
The agent generates the page layout in YAML format, as shown below:
content:
- js.hero_banner:
props:
mainHeading: "Discover the Best Cat Foods for Your Feline Friend"
photo:
src: "https://placehold.co/800x600@2x.png?alternateWidths=https%3A%2F%2Fplacehold.co%2F%7Bwidth%7Dx%7Bheight%7D%402x.png"
alt: "Example image placeholder"
width: 800
height: 600
intent: primary
- js.paragraph:
props:
body: "Welcome to Cat Food Central – your trusted source for expert advice, product reviews, and nutrition tips to keep your cat healthy and happy."
- sdc.canvas_test_sdc.columns:
props:
columns: 3
slots:
column_1:
- js.product_card:
props:
productImage:
src: "https://placehold.co/800x600@2x.png?alternateWidths=https%3A%2F%2Fplacehold.co%2F%7Bwidth%7Dx%7Bheight%7D%402x.png"
alt: "Example image placeholder"
width: 800
height: 600
productName: "Dry Cat Food"
productPrice: "$15"
column_2:
- js.product_card:
props:
productImage:
src: "https://placehold.co/800x600@2x.png?alternateWidths=https%3A%2F%2Fplacehold.co%2F%7Bwidth%7Dx%7Bheight%7D%402x.png"
alt: "Example image placeholder"
width: 800
height: 600
productName: "Wet Cat Food"
productPrice: "$20"
column_3:
- js.product_card:
props:
productImage:
src: "https://placehold.co/800x600@2x.png?alternateWidths=https%3A%2F%2Fplacehold.co%2F%7Bwidth%7Dx%7Bheight%7D%402x.png"
alt: "Example image placeholder"
width: 800
height: 600
productName: "Grain-Free Options"
productPrice: "$25"
- js.paragraph:
props:
body: "Find out which type of food best matches your cat’s age, breed, and dietary needs through our guides and expert recommendations."
- js.cta_section:
props:
mainHeading: "Ready to Give Your Cat the Best Nutrition?"
description: "Sign up for our newsletter to receive exclusive tips, reviews, and special offers tailored for passionate cat parents."
ctaText: "Subscribe Now"
ctaLink: "https://example.com"
intent: primary
This YAML is keyed by region name, and the values describe the components to be placed within each region.
A new tool, Drupal\canvas_ai\Plugin\AiFunctionCall\SetAIGeneratedTemplateData, has been added to the agent. This tool receives the YAML output from the agent, validates it, and uses the helper function CanvasAiPageBuilderHelper::processSetTemplateDataToolInput to convert it into a format usable by the addNewComponentToLayout thunk, which places each component on the page at the correct position.
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, Drupal\canvas_ai\Form\CanvasAIThemeRegionSettingsForm,
has been created. The [canvas_ai:available_regions] token derives its value from this configuration.
The prompt of the Canvas AI Orchestrator 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 Drupal Canvas Metadata Generation Agent and the Drupal Canvas Title Generation Agent to generate the page title and metadata.
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:
“Create a homepage template for a cookie shop website with a proper header and footer.”
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 CanvasBuilder::getAgentDescription(). We already have the Drupal Canvas Page Builder Agent, which focuses on adding one or more components or creating a section composed of multiple components. For example:
“Add three testimonials sharing positive feedback about a pizza shop below the CTA component on the page.”
“Create an ‘Our Services’ section for an IT agency providing Drupal migration services.”
Currently, the status message displayed when this agent is triggered is “Building the page”, which can be confusing to users. Therefore, this message has been changed to “Finding components to place.”
When the Drupal Canvas Template Builder Agent is triggered, the status message displayed will be “Designing the page.”
Added a post update hook to rebuild routes as some routes related to canvas ai configs have been updated in the MR
User interface changes
DEMO
Model used: GPT-4.1
| Comment | File | Size | Author |
|---|---|---|---|
| #90 | test_drupal_canvas_ai_orchestrator__page_builder_vs_template_builder.zip | 2.3 KB | marcus_johansson |
| #87 | Drupal Canvas.mp4 | 1.61 MB | akhil babu |
| #65 | text-color.png | 300.78 KB | narendrar |
| #65 | empty-title.png | 405.92 KB | narendrar |
| #59 | 4.1.png | 28.41 KB | akhil babu |
Issue fork canvas-3533079
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Issue fork experience_builder-3533079
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
akhil babuThis is now unblocked as #3530733: Introduce AI Agents and tools to Build Pages from components has been merged.
Comment #4
akhil babuComment #5
akhil babuComment #6
akhil babuComment #7
akhil babuComment #8
akhil babuComment #9
kunal.sachdev commentedTested it locally, but the thing which is not working as expected is that the final message about the template is created successfully is shown before and then the message about creating the footer section is shown. Attached the screen recording showing how it's working.
Comment #10
marcus_johansson commentedThere is a lot of complexity that I think can be solved via this: https://git.drupalcode.org/project/experience_builder/-/merge_requests/1.... Please look if it makes sense to move over to that.
Some other NITs
Comment #11
lauriiiSomething that's important here is that right now there's only one page template, which means that the header and footer apply to all pages within the site. We may introduce the concept of multiple page templates in future but it seems that we have to build this with the assumption that they are global.
Some example prompts to test:
Comment #12
akhil babuGoing to close the current MR. The current approach generates a header and footer for all templates. When generating a template, the agent should generate only the main content of the page. The header and footer will be generated only if the user explicitly requests them. By default, all components will be placed in the content region. Header/footer componetnst would be placed in corresponding header/footer regions if available
Comment #13
akhil babuComment #14
akhil babuComment #21
yautja_cetanu commentedComment #22
akhil babuI have updated the implementation.
A new form has been added under Configuration >> AI >> XB AI Theme Region Settings, which can be used to provide descriptions for different regions when global regions are enabled. These descriptions help the AI use the regions more effectively.
By default, only the main body will be generated during template generation.
The header and footer will be generated only if explicitly requested.
Header and footer components will be placed in the corresponding global regions if available. otherwise, they will be placed in the content region.
The following types of prompts are expected to work:
Comment #23
akhil babuComment #24
kristen polSwitching to the correct tag
Comment #25
akhil babu#3533881: Generate title and metadata for pages created from components using AI has landed. So this issue needs a rebase
Comment #26
akhil babuRebased and added tests. Ready for review
Comment #27
akhil babuComment #29
narendrarTried to test it manually, but I am getting below error:
Error: Call to undefined method Drupal\xb_ai\XbAiPageBuilderHelper::extractComponentIds() in Drupal\xb_ai\Plugin\AiFunctionCall\SetAIGeneratedTemplateData->execute()Prompt:
Generate a footer for a restaurant site with location/hours, menu links, social media, and reservation buttonComment #30
akhil babuThat method was removed in #3537422: XB AI: Validate AI generated Components before adding to XB. We should use the validation added in that issue here.
Comment #31
akhil babuComment #32
akhil babuThis is now blocked by #3543519: XB AI: Bring back the 'to' option in addNewComponentToLayout call in AiWizard.tsx
Comment #33
akhil babuComment #34
akhil babuThis is now ready for review. It extends on the code changes made in #3543744: Canvas AI: Create a common service for validations. So that issue must be merged first before reviewing this
Comment #35
yautja_cetanu commented(How we bring the Salsa digital stuff):
https://github.com/salsadigitalauorg/xb_metadata/
Things Marcus thinks:
Things Akhil thinks:
Anand:
Comment #36
akhil babuComment #38
akhil babu#3544614: Canvas AI: Agent should pass values to image props correctly is a blocker now.
Comment #39
akhil babuLinking to current blockers
Comment #40
catia_penas commentedComment #41
catia_penas commentedComment #42
lauriiiHave we considered refinements to the header and footer here at all? For example, "I'd like to add a 'Start free trial" button in the header that links to #" or "I'd like to add a 'Contact' link that links to '/contact' to the header".
Comment #43
lauriiiAlso, what would happen if user provided a prompt "Make the header sticky so it stays at the top on scroll"? This seems like a common use case which we should think through. Usually you'd probably have some kind of header component which the AI probably should modify in this scenario. Alternatively if the header is an SDC, it could create a new component that wraps the existing component to add the sticky header behavior.
Comment #44
akhil babuIf the prompt is like Create a homepage template for a pizza shop website with a proper header and footer. Add a ‘Start free trial’ button in the header that links to #. Also add a ‘Contact’ link that links to ‘/contact’ in the header, then the Template Builder agent being developed here would be able to place all those components.
If the template has been generated with a prompt like Create a homepage template for a pizza shop website with a proper header and footer, and the user makes a follow up request such as Add a ‘Contact’ link that links to ‘/contact’ in the header, this will be delegated to the Page Builder agent added in #3530733: Introduce AI Agents and tools to Build Pages from components.
At the moment, this isn’t possible, as both AI agents can only add new components. We have to implement uupdating already placed components in a followup issue
Edit: Created #3549232: Canvas AI: Updating page contents with agents to support updating components, once placed
Comment #46
akhil babuComment #47
akhil babuReady for review
Comment #48
akhil babuNow that #3540211: XB AI: User selection should be taken into account while building page is merged, this needs some updates
Comment #49
akhil babuReady for review
Comment #50
narendrarTested it manually and below are some observations:-
Create a template for the homepage of an ice cream shop website:It is observed that it did not place button in Empty button slot for hero component. Also content slot is empty in spacer and desired content is placed below spacer.Create a template for the homepage of an ice cream shop website, with proper header and footer: If content in header/footer region exists, it places duplicate components also.Comment #52
akhil babuThanks for the feedbacks narendrar,
- Done
Create a template for the homepage of an ice cream shop website: It is observed that it did not place button in Empty button slot for hero component. Also content slot is empty in spacer and desired content is placed below spacer.
This can be enforced from the component description settings form.
If user explicitly asks to generte headera and footer, agent will generate contents even if those regions already have components. I think we could open a followup to optimize this behaviour
Comment #53
akhil babuComment #54
narendrarTest is failing at https://git.drupalcode.org/issue/canvas-3533079/-/jobs/7002673#L2055
Comment #55
akhil babu🤔 The tests appear to run correctly locally.
Edit: The same test failed in the initial commit as well (https://git.drupalcode.org/project/canvas/-/merge_requests/18/diffs?comm...)
Edit 2: Previously the image prop values for the sdc.canvas_test_sdc.card were hardcoded in the test.
Though it ran correctly in local, it failed in CI, probably due to some change in the src path, I assume.
I have updated the test to load the default values from the component itself and the test is passing now
Comment #56
akhil babuCreated https://www.drupal.org/project/canvas/issues/3553998 as a follow-up as per #52.
Comment #57
narendrarPrompt
Create a header for a restaurant site with logo, search bar and main navigation menucreated component instead of templateSee:
But similar prompt for footer created correct template
Generate a footer for a restaurant site with location/hours, menu links, social media, and reservation buttonComment #58
akhil babuUpdated the orchestrator prompt to fix #57. While testing it, I observed another issue
I am using the OpenAI provider to test the prompt:
“Create a header for a restaurant site with a logo, search bar, and main navigation menu.”
The GPT-4.1 model often doesn’t delegate the task to the corresponding sub-agent. It simply says “Your request will be processed.”

I tried the same prompt with GPT-4.1-mini, but this time it refused to create the header, saying that the entity type is not a Canvas page, even though it actually was.
I created #3554026: Canvas AI: Refine the orchestrator prompt to move the entity_type check and title/metadata generation logic to the orchestrator so that the Template Builder and Page Builder agents can focus only on their core tasks. This should at least help fix the latter issue.
The issue with 4.1 is a bit more complicated . I've often observed that it claims it’s going to use a tool, but never actually does.One option is to use the check added in #3548107: Add possibility to check if a tool was run. However, that may not be the optimal solution, because we can't always guarantee that the orchestrator or any sub-agent should use a specific tool.
For example:
Comment #59
akhil babuComment #60
kristen polI get those sometimes with 4.1 as well where it says it’s going to process it but it doesn’t
Comment #61
akhil babuComment #62
akhil babuThanks for the detailed review. I have pushed the required changes. The template builder prompt is also updated as #3554026: Canvas AI: Refine the orchestrator prompt is now merged. It now focuses only on creating the page. Page tite/metadata generation and Entity type validation is now handled by the orchestrator. So, the frequency of occurrence of the issue mentioned in #58 should also decrease.
Comment #63
akhil babuThis would require refactoring once #3555464: CanvasBuilder::render() logic around specific tool response is unclear lands
Comment #64
narendrarIS needs to be updated based on rename of xb -> Canvas, currently supported feature, follow-ups etc
Comment #65
narendrarTitle and description does not seems to be getting generated.

Placed component are not displayed if text color matches background. Not sure if this can be fixed here, but a follow-up to track can be helpful.

Comment #66
akhil babuRgarding #65, this might be specific to anthropic claude models. I am using openai and title and descriptions are getting generated correctly.
The component description settings form can be used to add instructiins specific to each components (Eg: If there is a theme prop with light and dark options, when to use the 'light' prop and when to use 'dark'). The agent will consider these instructions when generating the template
Comment #67
narendrarCreated issue for #65
Comment #68
akhil babuChecking this today
Comment #69
akhil babuI have pushed some updates:
1. Previously, the template builder was responsible for generating headers and footers. Now:
Because, the page builder agent can now add components to multiple regions or positions at the same time, a prompt like “Add a header and footer for a page about comic books” will work. The components will be placed in the appropriate regions.
2. With the above change, the `SetTemplateData` tool used by the template builder agent no longer requires the reference_nodepath argument.This argument was originally needed to place footer components in the correct position. Since the page builder now handles this, the argument can be removed.As a result, the
canvasAiPagebuilderHelper::processComponentsBelow()method can also be removed.3. Updated the orchestrator prompt. Even though it may look like many changes, most of them are spacing and structural improvements, along with new template-builder–specific instructions.
4. Updated the polling messages as follows, since these are more accurate functionally:
Comment #70
akhil babuComment #72
tedbowI was a bit bit confused about this issue since it references "page templates" I thought this was going to be somehow related to "Content Templates"
re the summary
Since we have 1 thing canvas UI called "template", which are Content Templates, I was expecting this build that. I am wonder if the user would expect that? Especially if they were familiar with Canvas. What prompt would the user use if added an agent to make content templates, which though would also know as just "template"?
Comment #73
tedbowI will continue reviewing this tomorrow but for now needs work for https://git.drupalcode.org/project/canvas/-/merge_requests/18#note_633128 and other comments.
Comment #74
tedbowSee MR comments as to what is left. mostly https://git.drupalcode.org/project/canvas/-/merge_requests/18#note_634116
Comment #75
tedbowSee my MR comment I think this need to be tested
Comment #76
akhil babuin https://git.drupalcode.org/project/canvas/-/merge_requests/18/diffs?comm..., I have added the following
The functional test to validate the form was throwing config validation errors like 'Schema errors for canvas_ai.theme_region.settings with the following errors: canvas_ai.theme_region.settings:region_descriptions.stark missing schema ' upon saving the form. I had to add
protected $strictConfigSchema = FALSE;to disable strict config schema validation. This error does not happen on manually saving the form. So not sure why the test was throwing the errorComment #77
penyaskitoSadly strict config schema is not enabled by default, only in tests, as core (and contrib) don't provide
FullyValidatableschemas for everything.In Drupal Canvas we aim to provide that. So
canvas_ai.theme_region.settingsschema might be incorrect here?I cannot provide more info, as I didn't fully review but that's where I'd start looking.
Comment #78
akhil babuGonna check this today
Comment #79
akhil babuUpdated the schema of theme region settings config and the test is passing now. Thanks
Comment #80
neha_bawankar commentedAs per the description above , when we request to create a template -- it should just add content in content region no header and footer , but that is not the case here. Has the functionality implementation changed here ?


Before
After
Comment #81
akhil babuLooks like hallucination. Is it happening consistently?
Here is how it is supposed to work
If the prompt is in the format "Create a template for the homepage of an ice cream shop" -> Create the page layout without header and footer. Components should be mainly placed in the 'Content' region. It can also place components in other regions like Sidebar if enabled.
If the prompt is in the format "Create a template for the homepage of an ice cream shop with a header and footer" -> Create the page layout with header and footer. Header and footer components will be placed in corresponding regions if available . Else all components will be placed in the content region
Comment #82
vipin.mittal18Comment #83
vipin.mittal18Yes, it hallucinates with Anthropic Sonnet 3.7 but works perfectly with Sonnet 4.5.
Comment #84
wim leersThis MR is 99 days old now!
It was tagged in #64, almost 2 months ago, for needing an issue summary update. That seems to be doubly true right now, if we want to land this any time soon — especially given we're at 83 comments, 47 commits and a +1400,-200 diff. 🙏
Comment #85
akhil babuComment #86
akhil babuComment #87
akhil babuThanks., I have updated the issue summary and attaching a new demo as well. Please review
Comment #88
marcus_johansson commentedComment #89
rakhimandhania commentedComment #90
marcus_johansson commentedFeature wise this seems to work quite well.
I have also added a small test suite for the agents test module to test so its picking builder agent and template agent at the correct times. See: https://www.drupal.org/files/issues/2026-01-20/test_drupal_canvas_ai_orc...
I will continue and do code review.
Comment #91
marcus_johansson commentedI've also specifically asked it to give examples when it would choose what (OpenAI GPT-4.1). Maybe @akhilbabu can verify that this seems correct?
10 Examples for Choosing the Template Agent
10 Examples for Choosing the Builder Agent
Comment #92
marcus_johansson commentedAdded some comments
Comment #93
marcus_johansson commentedComment #94
akhil babuComment #95
akhil babuThanks. I have pushed the changes. From #91, all suggetsions for the template builder are valid. But for page builder the following are invalid
The page builder agent can currently only add new components to a page. It does not support updating existing components, including editing content, moving components, or deleting them. We already have an issue open for this #3549232: Canvas AI: Updating page contents with agents, and I am working on it.
I tried adding the instruction "Only component addition is currently supported. No tools are available to update, move, or delete existing components." to the orchestrator agent. After that change, the orchestrator no longer suggested update-related examples when asked for sample prompts where the page builder would be used. However, if I ask it to change the title of an existing heading component, it still calls the page builder agent.
Because of this, we likely need to update the prompts for both agents to stop this. I would prefer not to make those changes here, since this work is specifically focused on the template builder.
Comment #96
jibranAfter enabling the Canvas AI module in the latest Drupal CMS, I was able to create the page, but it didn't update the page title from "Untitled " to the generated title. I have enabled all the blocks at
/admin/appearance/componentComment #97
akhil babuCould you confirm whether you're using an Anthropic model (specifically Claude 3.7 Sonnet)? This is a known issue with that model.
Comment #98
jibranI tried a few more prompts, and it worked without any issues. The title was set correctly everytime. I'm unable to reproduce the bug mentioned in #96.
I also went through the code, and the only thing I was able to find was a missing post update hook to
\Drupal::service("router.builder")->rebuild();as we are adding a new route and update a few existing URI so we neeed to rebuild the route cache.Comment #99
marcus_johansson commentedJust to say, that all issues I found are resolved.
Comment #100
akhil babuThanks @jibran, @marcus_johansson
I have now added the post update hook as well.
Comment #101
akhil babuCreated #3571260: Canvas AI: The Page Builder should inform users that it cannot edit a component once it has already been placed on the page as per #95
Comment #102
jibranThank you for adding post update hook. However, the post update hook should be part of canvas_ai, not canvas.
Comment #103
akhil babuThanks. Moved the hook to the canvas ai module
Comment #104
jibranThank you, the MR looks good now. Given #99 and my my review is addressed, I'm going to set it to RTBC.
Comment #106
narendrarComment #109
rakhimandhania commented