feat: #3621892 Add a Views Agent development assistant submodule

Closes #3621892

Summary

Adds a new submodule, views_agent_dev_assistant, that gives site builders a ready-to-use chat interface for the Views Agent: an orchestrator ai_agent (wired to the Content Type, Field, Taxonomy, and Views sub-agents), the ai_assistant_api assistant that wraps it, and a chatbot block placed in the Gin toolbar.

The module depends on ai_agents_views, ai_assistant_api, ai_chatbot, gin_toolbar, and block - real module dependencies, so enabling it cascades everything else automatically. Gin cannot be declared the same way (a module's dependencies can only list other modules, not themes), so it is handled the way gin_toolbar itself already handles this: hook_requirements() checks for it and reports an install-blocking error if missing, without ever force-installing it. A #[Hook('themes_installed')] implementation then creates the chatbot block retroactively if Gin is installed after this module already was.

Changes

  • modules/views_agent_dev_assistant/views_agent_dev_assistant.info.yml: new submodule, with the module dependencies above.
  • modules/views_agent_dev_assistant/views_agent_dev_assistant.install: hook_requirements(), modeled on gin_toolbar_requirements().
  • modules/views_agent_dev_assistant/src/Hook/ViewsAgentDevAssistantHooks.php: #[Hook('themes_installed')] retroactively installs this module's own config/optional once Gin is installed.
  • modules/views_agent_dev_assistant/config/install/ai_agents.ai_agent.drupal_assistant.yml and config/install/ai_assistant_api.ai_assistant.drupal_assistant.yml: the orchestrator agent and the assistant that wraps it. Both declare an enforced dependency on this module, so uninstalling it removes them.
  • modules/views_agent_dev_assistant/config/optional/block.block.drupal_assistant_chatbot.yml: the chatbot block. In config/optional, not config/install, because it targets the Gin theme and needs to be skippable if Gin is not there yet; also declares the enforced dependency above.
  • modules/views_agent_dev_assistant/tests/src/Kernel/ViewsAgentDevAssistantInstallTest.php: 5 new Kernel tests (see Test plan).
  • modules/views_agent_dev_assistant/README.md: install instructions and the reasoning behind each of the above.
  • phpstan.neon: two new ignoreErrors entries scoped to the new submodule's tests/ and src/Hook/ directories, for the same class of Drupal-reflection false positive already ignored elsewhere in this project (a test's $modules property, and an OO hook's constructor and hook method, both invoked reflectively rather than through a traceable call).

Test plan

  • testInstallCascadesDependenciesAndCreatesConfig: installing this module alone installs every dependency and creates the agent, assistant, and block correctly when Gin is already present.
  • testInstallWithoutGinSkipsTheBlock: installing without Gin still creates the agent and assistant, and skips the block instead of creating one that targets a missing theme.
  • testInstallingGinAfterwardsCreatesTheBlock: installing Gin after this module creates the previously-skipped block retroactively.
  • testRequirementsHook: exercises hook_requirements() across the non-install phase, missing Gin, and Gin present.
  • testUninstallRemovesShippedConfig: uninstalling removes all three shipped config objects.
  • Full suite for ai_agents_views plus the new submodule: 68/68 tests, 675 assertions, no failures (1 pre-existing unrelated skip).
  • PHPCS (Drupal, DrupalPractice) and PHPStan (level 1) both clean on the new submodule.

Closes #3621892

AI-Generated: Yes (Used Claude Code to design and implement the submodule, including working through several iterations on how to handle the Gin theme prerequisite - first a custom recipe with a hard-fail config action, then a plain hook_install() that force-installed Gin, settling on the hook_requirements() + retroactive themes_installed hook approach here after empirically checking how each option actually behaves - and to write and verify the test coverage.)

Merge request reports

Loading