Every toggle row in the chat integrations menu (filters, Web Search, Image, Code Interpreter, Tools, Skills) is a button whose on/off state was carried only by the decorative Switch inside it. Screen readers announced the row name and nothing else, so there was no way to tell whether a tool or feature was active without looking at it.
Each row button now carries aria-pressed, and the Switch wrapper is marked inert so the nested role=switch stops competing with the row for the announcement and stops adding a nameless tab stop. Hit testing skips inert content, so clicking the switch still toggles the row.
Tool rows that are not yet authenticated omit aria-pressed: activating those starts an OAuth redirect rather than toggling, so announcing them as an unpressed toggle would be wrong.
The Web Search, Image and Code Interpreter rows also had a state-flipping aria-label ("Disable Web Search") on top of aria-pressed, which announces as "Disable Web Search, pressed" and reads as the opposite of the truth. Removed: the visible row text already names each control.
Fixes#17150
* fix: enforce the image generation flag on the legacy chat feature path
* fix: refresh the config store when image generation is disabled in admin settings
* fix: hide active feature pills when the feature is no longer available
Clicking "Merged Response" in a multi-model chat often made the merging model answer with "It appears that the responses provided from the other models were empty".
The merge handler collected each model's answer via `history.messages[id].content`. Assistant messages are persisted by the backend with `output` only (`upsert_message_to_chat_by_id_and_message_id` writes `done`/`role`/`output`, never `content`), so `content` is only populated in the browser session that generated the responses, where the streaming handler mirrors it. Once the chat is reloaded from the database, every assistant message has `content: ''` and the merge request is sent with a list of empty strings, which is exactly what the merging model then reports. That is why the failure looks random: merging works right after generating, and fails after a refresh or when reopening the chat.
Read the responses through `getOutputText(message.output) || message.content`, the same fallback already used by every other read site (`ResponseMessage`, `Overview/Node`, `SearchModal`, `ChatItem`, `ChatMenu`, `Navbar/Menu`).
Fixes#26962