Overview

Currently CanvasAiPageBuilderHelper::getAllComponentsKeyedBySource() does this

      if ($source === SingleDirectoryComponent::SOURCE_PLUGIN_ID) {
        $this->processSdc($component, $sdc_definitions, $output);
      }
      elseif ($source === JsComponent::SOURCE_PLUGIN_ID) {
        $this->processCodeComponents($component, $output, $available_components[$component_id]);
      }
      else {
        // Other sources: id, name, description (description = name)
        $output[$source]['components'][$component_id] = [
          'id' => $component_id,
          'name' => $component->label(),
          'description' => $component->label(),
        ];
      }

So for blocks, only the ID, name, and description are passed as context to the agent. However, this causes issues when the agent decides to use a block with required props (e.g., the System Branding block), because AiResponseValidator::validateComponentStructure() will throw errors like:

Component validation errors: components.0.[block.system_branding_block].props.: 'label' is a required key. components.0.[block.system_branding_block].props.: 'label_display' is a required key. components.0.[block.system_branding_block].props.: 'use_site_logo' is a required key. components.0.[block.system_branding_block].props.: 'use_site_name' is a required key. components.0.[block.system_branding_block].props.: 'use_site_slogan' is a required key

Proposed resolution

Expose the props of blocks to the agent.

Currently, _addNewComponentToLayout in layoutModelSlice.ts only sets field values for components that have the propSources property . Block components do not have this property.

    const buildInitialData = (component: CanvasComponent): ComponentModel => {
      if (isPropSourceComponent(component)) {  // Block components return false for this check.
        const initialData: EvaluatedComponentModel = {
          resolved: {},
          source: {},
        };
        Object.keys(component.propSources).forEach((propName) => {
          const prop = component.propSources[propName];
          // These will be needed when we support client-side preview updates.
          initialData.resolved[propName] = prop.default_values?.resolved || [];
          // These are the values the server needs.
          // @todo Reduce the verbosity of this in https://drupal.org/i/3463996
          //   and https://drupal.org/i/3528043 to send less data.
          initialData.source[propName] = {
            expression: prop.expression,
            sourceType: prop.sourceType,
            value: prop.default_values?.source || [],
            sourceTypeSettings: prop.sourceTypeSettings || undefined,
          };
        });
        return initialData;
      }
      return {
        resolved: {},
      };

This means it is not possible to place a block component with specific configuration values. For example, when the AI agent tries to place a Site Branding block with values like:

  {                                                                                                                      
    "use_site_logo": true,                                                                                               
    "use_site_name": true                                                                                                
  }

these values are ignored because block components lack propSources. As a result, block components are always placed with their default configuration, regardless of what values the AI specifies.

User interface changes

Issue fork canvas-3569120

Command icon 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

akhil babu created an issue. See original summary.

akhil babu’s picture

Issue summary: View changes
akhil babu’s picture

Issue summary: View changes
akhil babu’s picture

Status: Active » Needs work
Issue tags: +Needs tests

We need tests to ensure that prop values are properly fetched and the CanvasAiComponentDescriptionSettingsForm displays fields to override the description of these props. These can be added once #3558241: Canvas AI: CanvasAiComponentDescriptionSettingsForm redirects to 'canvas.api.config.list' after submission is merged as it already adds many tests to this from

arianraeesi’s picture

Issue tags: +AI Product Development

scott falconer made their first commit to this issue’s fork.

scott falconer’s picture

Status: Needs work » Needs review

- Added block component prop extraction in CanvasAiPageBuilderHelper by mapping block config schema keys to props (defaults/required/enum) so AI sees required block inputs.
- Added a kernel test that generates system_branding_block and asserts block props appear in AI context.
- UI: guard removeMediaFields() so non‑prop components (blocks) don’t attempt propSource filtering when placing components.

Notes
- test coverage from #3558241 is now in MR;
- BlockComponentFormTest failure is tracked separately in #3570699 (test fix handled there).

MR:
- https://git.drupalcode.org/project/canvas/-/merge_requests/498

Testing:
- ddev phpcs
- ddev exec drush ev 'Drupal::service("account_switcher")->switchTo(Drupal::entityTypeManager()->getStorage("user")->load(1)); print Drupal::service("canvas_ai.page_builder_helper")->getComponentContextForAi(); Drupal::service("account_switcher")->switchBack();' | rg -n "system_branding_block|use_site_logo|use_site_name|use_site_slogan"
- ddev exec bash -lc 'cd /var/www/html/web && SIMPLETEST_DB=mysql://db:db@db/db ../vendor/bin/phpunit -c core/phpunit.xml.dist modules/contrib/canvas/modules/canvas_ai/tests/src/Kernel/CanvasAiPageBuilderHelperTest.php' (passes; existing deprecations about RunTestsInSeparateProcesses, ApiContentUpdateForDemoController service id, and canvas_requirements)
- ddev exec bash -lc 'cd /var/www/html/web && SIMPLETEST_DB=mysql://db:db@db/db SIMPLETEST_BASE_URL=https://canvas-dev.ddev.site:8443 BROWSERTEST_OUTPUT_DIRECTORY=/var/www/html/web/sites/simpletest/browser_output ../vendor/bin/phpunit -c core/phpunit.xml.dist modules/contrib/canvas/tests/src/Functional/BlockComponentFormTest.php' (fails at line 46; tracked in https://www.drupal.org/project/canvas/issues/3570699)

AI disclosure:
- AI assistance used. Output reviewed and tests run manually.

mglaman’s picture

Status: Needs review » Needs work

1. Seems like having `ui/src/components/aiExtension/AiWizard.tsx` check `isPropSourceComponent` is a big fix that could avoid bugs without exposing block inputs in this issue
2. test and code style nits

scott falconer’s picture

Status: Needs work » Needs review

- Enum helper now always returns an array; caller checks
count($enum) > 0 before setting enum.
- Kernel test now uses User::create(['uid' => 1]) for current user
setup.
-/BlockComponent.php: getExplicitInputDefinitions() is now public.
-- Using only getExplicitInputDefinitions() dropped the label prop (because schema label keys are stripped
there), which broke CanvasAiPageBuilderHelperTest.
-- - The final implementation keeps label and other expected block props while still using source-plugin
explicit schema data.
- AiWizard.tsx isPropSourceComponent guard comment is already
present in MR code.
- ui/src/components/aiExtension/AiWizard.tsx:205

akhil babu’s picture

Assigned: akhil babu » Unassigned
Status: Needs review » Active

There are conflicts in the MR now

akhil babu’s picture

Status: Active » Needs work
akhil babu’s picture

Assigned: Unassigned » akhil babu
akhil babu’s picture

Assigned: akhil babu » Unassigned
Status: Needs work » Needs review