feat: #3614852 Offer the chat microphone, reading replies aloud, and a switch for the mode dropdown
Issue: https://www.drupal.org/project/ai_agent_modes/issues/3614852
What this does
deep-chat draws both chat surfaces this module works with, and has speech built in, but neither surface exposes it: the AI Chatbot block strips speechToText and microphone from the settings it renders after its own hook_deepchat_settings has run, and the Drupal Canvas AI panel is mounted by the Canvas editor's React bundle, so there is no render array to configure. Both are reached the way the mode dropdown already reaches them: a behaviour rides along with each surface's own library and sets the properties on the mounted <deep-chat> element.
No patch to drupal/ai or drupal/canvas. Verified against pristine copies of both.
Speech to text
A microphone with four placements, and every option deep-chat documents: dictation language (a list, with let the browser choose and follow the page language), interim results, stop recording after sending, send after a pause in speaking and its length, interim and final text colours, voice commands, and corrections for words the recogniser mishears.
The chosen side is kept: a microphone asked for the left stays on the left as the send button and the mode dropdown appear. The dropdown is this module's own, so it gives way — it shifts over and narrows — rather than the button drifting across the row or being thrown outside the box. Placement is worked out in the message box's own coordinate space, so there is no measure-and-nudge loop.
Text to speech
Read each reply aloud, with language, voice, pitch, speed and volume. The voice list is filled in by the browser, because the installed voices differ by machine, and each entry says whether it speaks on this device or is an online voice: an online voice is synthesised on the vendor's servers, so the reply text is sent there.
A switch for the mode dropdown
Off means off: no library is attached to either surface, the options endpoint returns nothing, the selector block renders nothing, and the classic chat form is left alone. One check, ModeManagerInterface::dropdownEnabled(), asked by every surface.
Per AI Assistant
An AI Agent Modes section on the assistant's own form carries three choices — the microphone, its placement, and reading aloud — each defaulting to use the site setting, which stores nothing at all so an assistant that overrode nothing exports clean.
Screenshots
Mode dropdown tab: the switch, and the Drupal Canvas AI placements as cards
Microphone tab
Reading replies aloud tab
The three per-assistant choices
The Canvas AI input row: attach, microphone, mode dropdown, send
Privacy
Recognition and synthesis are the browser's own Web Speech support: this module sends nothing to any service and needs no key. The browser is another matter, and the form says so instead of promising locality — Chromium-based browsers recognise in the cloud, so the audio leaves the machine through the browser. Azure is deliberately not offered, because it needs a key or token in configuration; hook_ai_agent_modes_speech_alter() is there for a site that wants it with a short-lived token of its own.
Both halves ship off, and the two post-update hooks write them off on an existing site, so an update can never start recording or reading aloud by itself.
Based on the merged #3613643
#3613643 has merged, and this branch is a single commit on top of it: the diff is only the speech and dropdown-switch work.
Testing
- PHPCS (Drupal, DrupalPractice) clean; Stylelint and Prettier clean against Drupal core's configs.
- 63 PHPUnit tests pass (unit and kernel), including a new kernel test that the three per-assistant overrides store and clear, and a unit test that the dropdown switch attaches nothing when off.
- A new webship-js feature,
08-01-01-speech.feature, covers both switches, the four placements, the languages, the voice commands and the restore-the-defaults pass. - Driven by hand in a real browser on Varbase 11 (Drupal 11.4) with
drupal/ai1.4.5,ai_agents1.3.2 anddrupal/canvas1.9.0: both surfaces, all four placements, the off state, and the per-assistant overrides. gitlab-ci-localcould not run this project's pipeline: the Drupal templates emit a rules expression it fails to evaluate, so CI here is the first full run.
Dictation itself was not driven end to end — that needs a microphone device and a granted permission, which the automated browser has neither of.
Checkpoints:
- File an issue
- Addition/Change/Update/Fix
- Testing to ensure no regression
- Automated unit testing coverage
- Automated functional testing coverage
- UX/UI designer responsibilities
- Readability
- Accessibility
- Performance
- Security
- Developer Documentation
- User Guide Documentation
- Reviewed by human
- Code review by maintainers
- Full testing and approval
- Credit contributors
- Review with the product owner
- Release notes snippet
- Release
AI usage: prepared with Claude and reviewed by a human before pushing, per the Drupal AI policy.




