Skip to content

feat(ai): per-channel response mode (off / mention-only / vibe) #264

@BillChirico

Description

@BillChirico

Overview

Allow server admins to control how the AI bot responds in each channel. Three modes, configurable per channel from the dashboard.

Response Modes

Mode Behavior
Off Bot never responds in this channel
Mention only Bot only responds when directly @mentioned (default for all channels)
Vibe Bot responds whenever it judges the conversation warrants a reply

Default: All channels start in mention mode. Admins opt individual channels into vibe or off.

Config Schema

{
  "ai": {
    "channelModes": {
      "123456789": "off",
      "987654321": "vibe"
    },
    "defaultChannelMode": "mention"
  }
}

Channels absent from channelModes inherit defaultChannelMode. This keeps the config small — only overrides need to be stored.

Backend Changes

  • src/modules/ai.js — before handling any message, resolve the effective mode:
    const mode = config.ai.channelModes?.[channel.id] ?? config.ai.defaultChannelMode ?? 'mention';
    if (mode === 'off') return;
    if (mode === 'mention' && !message.mentions.has(client.user)) return;
    // mode === 'vibe' — fall through to AI judgment
  • Existing blockedChannelIds still applies (hard block, no response at all)
  • src/api/routes/config.jschannelModes must be in SAFE_CONFIG_KEYS

Dashboard UI/UX

Channel Mode List (primary UI)

  • Lives in the AI config section, below the existing AI toggles
  • Shows all channels in the server (fetched from Discord API)
  • Grouped by category (mirrors Discord's channel list layout)
  • Each channel row has:
    • Channel icon + name
    • A 3-option segmented control (pill selector): Off · Mention · Vibe
    • Active mode highlighted; default (mention) shown with a subtle "default" badge so it's clear nothing is explicitly set
  • Channels with non-default settings bubble to the top or get a visual indicator (e.g. colored dot)
  • Search/filter bar to find a channel quickly
  • "Reset all to default" button

Mode Selector Component

┌─────────────────────────────────────────────┐
│ # general                                    │
│              [ Off ] [ Mention ✓] [ Vibe ]  │
├─────────────────────────────────────────────┤
│ # announcements                              │
│              [ Off ✓] [ Mention ] [ Vibe ]  │
├─────────────────────────────────────────────┤
│ # random                                     │
│              [ Off ] [ Mention ] [ Vibe ✓]  │
└─────────────────────────────────────────────┘
  • Segmented control (not a dropdown) — all 3 options visible at a glance, one tap to switch
  • Mobile-first: control stacks below the channel name on narrow screens
  • Saving: changes are staged and saved with the rest of the config (no per-row auto-save)
  • Empty state: "No channels found" when search returns nothing

Global Default Setting

Above the channel list, a single prominent selector sets the server-wide default:

Default mode for all channels
[ Off ] [ Mention (recommended) ✓] [ Vibe ]

Changing this updates all channels that haven't been explicitly overridden.

Acceptance Criteria

  • ai.defaultChannelMode config field, defaults to 'mention'
  • ai.channelModes map, starts empty (channels inherit default)
  • Bot respects mode before processing any AI message
  • vibe mode still uses existing AI judgment logic (no additional prompting needed)
  • Dashboard shows all channels grouped by category
  • Segmented 3-option control per channel, mobile-responsive
  • Global default selector at the top of the section
  • Non-default channels visually distinguished
  • Search to filter channels
  • "Reset to default" per channel and globally
  • channelModes in SAFE_CONFIG_KEYS
  • Unit tests for mode resolution logic
  • Existing blockedChannelIds behavior unchanged

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions