Skip to content

Discord

The Discord bot is a transport for the operator Chat and Intake. It does not run a second agent: a mention, or any human message in a conversation channel, becomes a normal Chat turn on this agent, with the same memory, retrieve, tools, and work intents.

  • @mention → Chat. Mention the bot in a channel or thread. It answers in the same channel, as a reply to the mention.
  • Conversation channels → Chat when addressed. List a channel in discord_conversation_channels and the bot joins the conversation. Clef decides whether each human message is addressed to it or continues its last reply; human-to-human messages, announcements, and unrelated chatter are ignored. The session persists, so follow-ups keep their context. A direct Discord reply to one of the bot’s messages counts as addressed and bypasses the classifier. This needs the privileged Message Content intent and a cloudflare_ai credential.
  • 📥 → Intake. A reply that proposes work (a bug, feature, backlog item, or a suggested issue) carries 📥. An operator who reacts with 📥 files the original message and the assistant reply as an Intake item. The item keeps the Discord message link, the author, and the reply as provenance. Plain answers, status checks, greetings, and Decision drafts do not carry 📥.
  • One Chat session per channel or thread. A thread is a separate session from its parent channel, so use a thread for a side conversation.

The bot ignores its own messages, other bots, reactions from bots, and messages that neither mention it nor arrive in a conversation channel (except DMs when discord_allow_dms=1).

  1. Create a Discord application and bot in the Developer Portal.
  2. Invite the bot with View Channel, Send Messages, Read Message History, Add Reactions, and Send Messages in Threads.
  3. Store the bot token as the discord_bot credential (Credentials → Discord bot).
  4. Optionally set discord_allowed_channels and discord_allowed_users to comma-separated IDs. Empty means every channel/user the bot can see.

Mention-only operation needs no privileged intents: Discord delivers the content of messages that mention the bot. For conversation mode, enable Message Content under Bot → Privileged Gateway Intents, configure cloudflare_ai (or CLOUDFLARE_ACCOUNT_ID/CLOUDFLARE_API_TOKEN), then set discord_conversation_channels to the channel IDs. Without the classifier, conversation mode ignores non-mention messages rather than replying to everything.

The agent starts the gateway when a token is present and discord_bot_enabled is not 0. No public URL or interactions endpoint is needed; the bot uses Discord’s outbound gateway connection.

Each agent runs its own project. Use a separate Discord application and token for each one, and scope it to that project’s channels with discord_allowed_channels:

AgentBotChannels
Steelframe dogfoodSteelframe#steelframe, #dogfood
Steelframe makolateSteelframe Makolate#makolate, #86, #makolate-steelframe

The dogfood and makolate agents have separate databases and credentials, so a mention in #dogfood never reaches the makolate agent. The bot name and avatar are set in Discord; they are not agent config.

KeyDefaultPurpose
discord_bot_enabled10 turns the bot off even with a token.
discord_allowed_channelsemptyComma-separated channel or thread IDs the bot answers in.
discord_allowed_usersemptyComma-separated Discord user IDs allowed to use the bot.
discord_conversation_channelsemptyChannel IDs where Clef decides whether each human message is for the bot. Requires Message Content and cloudflare_ai.
discord_intake_reaction📥Emoji that files an Intake.
discord_allow_dms01 also answers direct messages (no mention required).

STEELFRAME_DISCORD_BOT_TOKEN is a local-testing fallback when the credential is not stored.

Empty allowlists are an open posture: any member who can mention the bot can drive operator Chat. Conversation mode is stronger still: a message Clef judges addressed to the bot runs a Chat turn, so a misclassification can spend a worker. Set at least discord_allowed_channels and discord_allowed_users for an operator agent. The agent logs a warning at startup when either allowlist is empty or conversation mode is on.

  • Discord shows Steelframe is typing… while the Chat turn runs; the indicator is refreshed every ~8 seconds and cleared when the reply is sent.
  • In a mention-only channel, each reply ends with a one-line reminder to mention the bot. In a conversation channel, replies have no reminder: the next addressed message continues the session.
  • Conversation mode is not reply-to-everything. Clef scores whether a message is addressed to the bot or continues its last reply; below the threshold the message is ignored. If the classifier is unavailable, non-mention messages are ignored; mention the bot to force an answer.
  • Chat first. While a Chat turn is running, the agent defers new background worker assignments. An incident burst can still slow the model, but it cannot take the remaining worker slots from the operator’s reply.
  • A Chat turn can take as long as the coding runtime takes. The bot replies once the turn finishes; it does not stream tokens into a message.
  • Discord replies are a chat answer, not a report: the prompt asks for at most ~900 characters and the bot trims a runaway answer at a sentence or word boundary at 1,500. The trailing ellipsis means there is more to ask for; the TUI/GUI Chat is not capped.
  • The bot does not file an Intake automatically. The reaction is the operator’s confirmation, which keeps a chat question from becoming work by accident.
  • Attachments are not read yet; the message text is. A mention with only an attachment gets a reply asking for words.