Problem/Motivation

AI Plus delivers UI side effects (page refresh, open-link navigation, workspace toolbar updates) from server-side AI tool execution to the browser. The current mechanism injects hidden HTML trigger spans into the chat response text and uses a MutationObserver on DeepChat's shadow DOM to detect them.

This approach has several problems:

  • Fragile timing — the observer must attach before the shadow DOM renders, and DeepChat's initialization order is not guaranteed
  • Single-fire — only one trigger span per response type, no way to queue multiple commands of the same kind
  • Untestable — behavior depends on DOM mutation timing in a shadow root
  • Split architecture — polling mode (interval-based change-check) and instant mode (trigger span detection) are two separate code paths solving the same problem differently, doubling maintenance surface
  • State API pollution — uses Drupal State to communicate between the AI tool request and the subsequent polling/trigger request, leaking per-user ephemeral data into a global store

Proposed resolution

Replace the HTML injection pattern with Drupal's native AJAX command system, piggybacking on the DeepChat JSON response:

  1. UiCommandQueue — shared in-memory queue where event subscribers add CommandInterface objects during the request
  2. DeepChatResponseListener — a kernel.response listener on the ai_chatbot.api route that flushes the queue and injects rendered commands as a drupal_commands array into the JSON response
  3. ai-plus-command-processor.js — wraps DeepChat's responseInterceptor to extract drupal_commands and execute them via Drupal.ajax().success()

Comments

tim bozeman created an issue. See original summary.

  • tim bozeman committed 173b37df on 1.0.x
    task: #3591600 Replace HTML injection pattern with AJAX command pipeline...
tim bozeman’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.