0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-08 17:53:55 +08:00
discourse/plugins/discourse-ai/spec
Gabriel Grubba 9c09e988b3
FEATURE: Approve AI moderation actions inline in bot chat DMs (#41565)
> Was stacked on #41497, which has since merged. This PR is now rebased
onto `main` and contains only the chat-approval work.

### What

Lets a moderator approve or reject an AI-bot moderation tool action
(`suspend_user` / `silence_user`) **inside a Chat direct message with
the bot**, instead of leaving for the `/review` queue — the chat
counterpart to the base PR's inline PM/topic card.

When the bot queues one of these actions in a DM, it posts a message
with **Approve / Reject** buttons rendered via the Chat plugin's native
interactive **blocks**. Clicking performs the queued action through the
existing `ReviewableAiToolAction` backend (credited to the approving
moderator) and rewrites the message to its resolved state, removing the
buttons.

### How

- `bot.rb` — `enqueue_tool_for_approval` branches on chat context: in
chat it emits a `:chat_approval` signal; in PM/topic it keeps the
existing inline card.
- `playground.rb` — `reply_to_chat_message` posts a bot chat message
carrying the Approve/Reject blocks, in the **same DM thread as the bot's
reply** (AI-bot DM replies are threaded by design). DM channels only.
- `chat_tool_approval.rb` — builds/parses the button `action_id`s,
builds the blocks, and handles the `chat_message_interaction` event:
performs the reviewable and rewrites the message. Runs synchronously so
the buttons clear before the request returns.
- `entry_point.rb` — registers the `:chat_message_interaction` listener.

### Authorization

`Chat::CreateMessageInteraction` only checks channel visibility, so
staff-gating is enforced here: the handler requires
`Reviewable.viewable_by(user)` **and** `Reviewable#perform` re-checks
(`ensure_performed_by_is_a_real_person!` + the approver's guardian).
Non-staff clicks are ignored. A crafted `action_id` can't target another
reviewable — core only matches `action_id`s present in that message's
own blocks.

### Core-chat changes (3 lines)

The blocks system was built for **create-time-only** blocks; nothing had
ever mutated a message's `blocks` after creation. Clearing the buttons
on approve/reject is the first such case, which required:

- `chat-message.js` — make `blocks` a `@tracked` property (so
reassigning it re-renders).
- `chat-channel-subscription-manager.js` +
`chat-channel-thread-subscription-manager.js` — refresh `message.blocks`
in `handleEditMessage` (so the block-clearing edit reaches the client,
in both the channel and thread views).

All are no-ops for the only other block user (category blocks, which are
never edited after creation).

### Testing

`plugins/discourse-ai/spec/lib/ai_bot/chat_tool_approval_spec.rb` —
action-id round-trip, block shape, staff gating, foreign/stale
action-ids, approve/reject, failure surfacing, and an end-to-end run
through the real `Chat::CreateMessageInteraction` service. The existing
`playground_spec.rb` chat-DM tests (threaded conversation + context)
continue to pass. Verified manually in a bot DM.
2026-07-13 17:08:35 -03:00
..
configuration FEATURE: Provider-native built-in tools for agents (web search) (#40809) 2026-06-16 14:37:51 -03:00
db/migrate FEATURE: Add category scope for AI translations (#41585) 2026-07-10 09:39:20 +08:00
evals DEV: Update models in config and the DE runner (#41082) 2026-06-22 21:29:07 +08:00
fabricators FEATURE: add cost limits to LLM quotas (#41277) 2026-06-30 15:59:24 +10:00
fixtures DEV: AI persona to agent migration (#38319) 2026-03-10 15:59:45 +11:00
integration DEV: Tidy plugin API key scope resource names (#38640) 2026-03-17 13:03:42 +11:00
jobs FEATURE: Add category scope for AI translations (#41585) 2026-07-10 09:39:20 +08:00
lib FEATURE: Approve AI moderation actions inline in bot chat DMs (#41565) 2026-07-13 17:08:35 -03:00
models FEATURE: Add AI agent suspend/silence tools with inline approval review (#41497) 2026-07-10 10:59:51 -03:00
reports
requests FEATURE: Add category scope for AI translations (#41585) 2026-07-10 09:39:20 +08:00
serializers FEATURE: retry transient and rate-limited LLM completion requests (#41237) 2026-06-30 09:45:26 +10:00
services DEV: Fix a flake in credit_status_checker_spec (#40092) 2026-05-16 18:46:01 +02:00
shared/inference
support DEV: Add DiscourseAi.register_feature public API (#39127) 2026-05-12 10:16:07 +08:00
system FEATURE: Add category scope for AI translations (#41585) 2026-07-10 09:39:20 +08:00
tasks DEV: Fix deprecations in plugins specs and silence output (#39257) 2026-04-15 00:00:46 +02:00
plugin_helper.rb DEV: Fix tags_locale_detection_backfill spec flakes (#39553) 2026-04-27 10:45:04 +02:00
plugin_spec.rb DEV: Remove deprecated AI plugin settings (#37459) 2026-02-03 05:39:38 -08:00