Decompose: CONV-004: Discord Bot Integration #134

Closed
opened 2026-04-11 03:13:00 +00:00 by Mark · 3 comments
Owner

Parent: CONV-004: Discord Bot Integration
Original: #134

Overview

Discord bot that bridges Discord channels to mesh intents. This decomposition splits the work into 5 dependency-ordered phases.


P1: Discord Bot Foundation

Goal: Get a Discord bot process running alongside the mesh stack, with token management, connection lifecycle, and presence/heartbeat.

Approach candidates:

  • Standalone Python process using discord.py library, managed as a container alongside existing docker services
  • Integration into the existing docker/api_gateway.py Flask process as a background thread (simpler deployment, coupling risk)
  • Separate CLI entrypoint (cli/commands/discord_bot.py) that can run as a sidecar

Outputs:

  • docker/discord_bot.py — Discord client process with startup/shutdown lifecycle
  • config/discord.yaml — Discord token config (loaded from env, not committed)
  • Token loading via existing secrets management (substrate/secrets_manager.py)
  • Docker Compose integration (docker/docker-compose.yml) — optional sidecar or managed process
  • Health check endpoint exposed for monitoring

Acceptance criteria:

  • Bot authenticates with Discord and stays connected (reconnects on disconnect)
  • Token loaded from secure env/config, never hardcoded
  • Bot presence shows "online" with appropriate activity status
  • Container/service starts/stops cleanly with the mesh stack
  • Health endpoint reports bot connection state
  • Graceful shutdown on SIGTERM

Files touched: docker/discord_bot.py, config/discord.yaml (create), docker/docker-compose.yml (amend), substrate/secrets_manager.py (possibly extend for Discord token)


P2: Intent Bridge — Discord to Mesh Translation

Goal: Translate incoming Discord messages into mesh intents that the existing intent routing infrastructure can process. Map Discord threads to mesh threads.

Approach candidates:

  • New runtime/discord_ingress.py module that implements the MeshIntent protocol used by runtime/intent_router.py
  • Extend existing runtime/ingress_coordinator.py with a Discord-specific handler
  • Use existing substrate/backplane.py API for intent submission — the ingress pattern is already established by the REST API in docker/api_gateway.py

Outputs:

  • runtime/discord_ingress.py — Discord-to-mesh intent translation module
  • Thread mapping: Discord thread/channel ID ↔ mesh thread ID (via existing substrate/ledger.py or substrate/task_store.py)
  • Tests in tests/unit/test_discord_ingress.py and tests/integration/test_discord_ingress.py

Acceptance criteria:

  • Incoming Discord message creates a mesh intent with correct intent type metadata
  • Discord thread/channel IDs map to mesh threads; replies in Discord thread continue the same mesh conversation
  • New Discord thread spawns new mesh thread automatically
  • Existing mesh thread intents (conversational, research, write) are all routable from Discord
  • Unit tests cover message→intent parsing for plain text, attachments, and reply chains
  • Integration test verifies end-to-end: message in → intent routed → response generated

Files touched: runtime/discord_ingress.py (create), runtime/__init__.py (amend), tests/unit/test_discord_ingress.py (create), tests/integration/test_discord_ingress.py (create)


P3: Commands & @Mentions

Goal: Support @mention direct invocation and slash commands (/write, /research, /chat, /status) that map to specific mesh intent types.

Approach candidates:

  • Discord @bot mention → generic chat intent (the message body is the prompt)
  • Slash commands registered via discord.py app_commands / hybrid commands
  • /write → intent type write, /research → research, /chat → default conversational
  • /status → query mesh node health and report back
  • Named parameters on slash commands (e.g., /write --style academic --length 500)

Outputs:

  • Slash command registration in docker/discord_bot.py
  • Command→intent-type mapping table (config-driven)
  • Tests for each slash command

Acceptance criteria:

  • @bot ping → mesh intent processes the text, response sent back
  • /write <prompt> triggers a write intent, result delivered as Discord message
  • /research <query> triggers a research intent
  • /chat <message> triggers a conversational intent
  • /status returns mesh health summary (shows connected workers, queue depth)
  • Unknown commands return a helpful error listing available commands
  • Slash commands work in both guild channels and DMs

Files touched: docker/discord_bot.py (amend — add command handlers), config/discord.yaml (amend — command config), tests/unit/test_discord_commands.py (create)


P4: Response Delivery

Goal: Format mesh results for Discord delivery — handle the 2000-char message limit, multi-message for long responses, rich embeds, typing indicators, and file attachments.

Approach candidates:

  • Split long responses at natural boundaries (paragraphs, code blocks) into Discord messages
  • Embeds for structured output: title, description, fields, color-coded by intent type
  • Typing indicator while mesh intent is processing (periodic progress updates)
  • File uploads for artifacts (code snippets, reports, generated content)
  • Model-generated summary + full artifact as follow-up

Outputs:

  • Response formatter in runtime/discord_ingress.py or separate runtime/discord_response.py
  • Embeds for structured output types (research findings, write artifacts, status reports)
  • Chunked message delivery for long content
  • Typing indicator integration during processing

Acceptance criteria:

  • Messages under 2000 chars delivered as single message
  • Messages over 2000 chars split across multiple messages with continuation markers
  • Research results formatted as Discord embed (title, summary, key findings as fields)
  • Write artifacts sent as embedded preview + optional file attachment
  • Bot shows typing indicator while mesh is processing
  • Error messages formatted distinctly (red embed, clear error prefix)
  • Code blocks preserve formatting in mono-spaced Discord blocks

Files touched: runtime/discord_ingress.py (amend), runtime/discord_response.py (create), runtime/__init__.py (amend), tests/unit/test_discord_response.py (create)


P5: Permissions & Governance

Goal: Role-based access control, channel restrictions, rate limiting per user. Ensure the bot follows Discord governance best practices.

Approach candidates:

  • YAML-based channel allow/deny list in config/discord.yaml
  • Discord role-based access — users need specific roles to use certain commands
  • Rate limiting: per-user cooldown (configurable, e.g. 5 calls/min for /research, unlimited /chat)
  • Admin role for configuration management (set allowed channels, adjust rate limits)
  • Privacy: message content not logged/stored outside mesh conversation history

Outputs:

  • Permission checker in runtime/discord_permissions.py
  • Channel allow/deny rules in config
  • Rate limiter per user per command category
  • Tests for permission enforcement

Acceptance criteria:

  • Channel allowlist: bot only responds in configured channels; silent in non-allowed channels
  • Role-based gating: /research requires researcher role; /write requires author role
  • Per-user cooldown enforced: hitting limit returns a rate-limit embed with retry-after info
  • Admin commands (/config, /allow channel) gated to admin role only
  • No Discord message content leaks into unsecured logs or caches
  • Unit tests verify: unauthorized user gets denied, authorized user passes, rate limit fires after N calls in window

Files touched: runtime/discord_permissions.py (create), config/discord.yaml (amend), docker/discord_bot.py (amend — wire permission checks), tests/unit/test_discord_permissions.py (create)


  • CONV-001: Conversation Interface Infrastructure
  • CONV-002: Multi-turn Context Management

Decomposed from Mark/mesh-seed#134

**Parent:** CONV-004: Discord Bot Integration **Original:** https://forgejo.tail018ac4.ts.net/Mark/mesh-seed/issues/134 ## Overview Discord bot that bridges Discord channels to mesh intents. This decomposition splits the work into 5 dependency-ordered phases. --- ### P1: Discord Bot Foundation **Goal:** Get a Discord bot process running alongside the mesh stack, with token management, connection lifecycle, and presence/heartbeat. **Approach candidates:** - Standalone Python process using `discord.py` library, managed as a container alongside existing docker services - Integration into the existing `docker/api_gateway.py` Flask process as a background thread (simpler deployment, coupling risk) - Separate CLI entrypoint (`cli/commands/discord_bot.py`) that can run as a sidecar **Outputs:** - `docker/discord_bot.py` — Discord client process with startup/shutdown lifecycle - `config/discord.yaml` — Discord token config (loaded from env, not committed) - Token loading via existing secrets management (`substrate/secrets_manager.py`) - Docker Compose integration (`docker/docker-compose.yml`) — optional sidecar or managed process - Health check endpoint exposed for monitoring **Acceptance criteria:** - [ ] Bot authenticates with Discord and stays connected (reconnects on disconnect) - [ ] Token loaded from secure env/config, never hardcoded - [ ] Bot presence shows "online" with appropriate activity status - [ ] Container/service starts/stops cleanly with the mesh stack - [ ] Health endpoint reports bot connection state - [ ] Graceful shutdown on SIGTERM **Files touched:** `docker/discord_bot.py`, `config/discord.yaml` (create), `docker/docker-compose.yml` (amend), `substrate/secrets_manager.py` (possibly extend for Discord token) --- ### P2: Intent Bridge — Discord to Mesh Translation **Goal:** Translate incoming Discord messages into mesh intents that the existing intent routing infrastructure can process. Map Discord threads to mesh threads. **Approach candidates:** - New `runtime/discord_ingress.py` module that implements the `MeshIntent` protocol used by `runtime/intent_router.py` - Extend existing `runtime/ingress_coordinator.py` with a Discord-specific handler - Use existing `substrate/backplane.py` API for intent submission — the ingress pattern is already established by the REST API in `docker/api_gateway.py` **Outputs:** - `runtime/discord_ingress.py` — Discord-to-mesh intent translation module - Thread mapping: Discord thread/channel ID ↔ mesh thread ID (via existing `substrate/ledger.py` or `substrate/task_store.py`) - Tests in `tests/unit/test_discord_ingress.py` and `tests/integration/test_discord_ingress.py` **Acceptance criteria:** - [ ] Incoming Discord message creates a mesh intent with correct intent type metadata - [ ] Discord thread/channel IDs map to mesh threads; replies in Discord thread continue the same mesh conversation - [ ] New Discord thread spawns new mesh thread automatically - [ ] Existing mesh thread intents (`conversational`, `research`, `write`) are all routable from Discord - [ ] Unit tests cover message→intent parsing for plain text, attachments, and reply chains - [ ] Integration test verifies end-to-end: message in → intent routed → response generated **Files touched:** `runtime/discord_ingress.py` (create), `runtime/__init__.py` (amend), `tests/unit/test_discord_ingress.py` (create), `tests/integration/test_discord_ingress.py` (create) --- ### P3: Commands & @Mentions **Goal:** Support @mention direct invocation and slash commands (`/write`, `/research`, `/chat`, `/status`) that map to specific mesh intent types. **Approach candidates:** - Discord `@bot` mention → generic chat intent (the message body is the prompt) - Slash commands registered via `discord.py` `app_commands` / hybrid commands - `/write` → intent type `write`, `/research` → `research`, `/chat` → default conversational - `/status` → query mesh node health and report back - Named parameters on slash commands (e.g., `/write --style academic --length 500`) **Outputs:** - Slash command registration in `docker/discord_bot.py` - Command→intent-type mapping table (config-driven) - Tests for each slash command **Acceptance criteria:** - [ ] `@bot ping` → mesh intent processes the text, response sent back - [ ] `/write <prompt>` triggers a write intent, result delivered as Discord message - [ ] `/research <query>` triggers a research intent - [ ] `/chat <message>` triggers a conversational intent - [ ] `/status` returns mesh health summary (shows connected workers, queue depth) - [ ] Unknown commands return a helpful error listing available commands - [ ] Slash commands work in both guild channels and DMs **Files touched:** `docker/discord_bot.py` (amend — add command handlers), `config/discord.yaml` (amend — command config), `tests/unit/test_discord_commands.py` (create) --- ### P4: Response Delivery **Goal:** Format mesh results for Discord delivery — handle the 2000-char message limit, multi-message for long responses, rich embeds, typing indicators, and file attachments. **Approach candidates:** - Split long responses at natural boundaries (paragraphs, code blocks) into Discord messages - Embeds for structured output: title, description, fields, color-coded by intent type - Typing indicator while mesh intent is processing (periodic progress updates) - File uploads for artifacts (code snippets, reports, generated content) - Model-generated summary + full artifact as follow-up **Outputs:** - Response formatter in `runtime/discord_ingress.py` or separate `runtime/discord_response.py` - Embeds for structured output types (research findings, write artifacts, status reports) - Chunked message delivery for long content - Typing indicator integration during processing **Acceptance criteria:** - [ ] Messages under 2000 chars delivered as single message - [ ] Messages over 2000 chars split across multiple messages with continuation markers - [ ] Research results formatted as Discord embed (title, summary, key findings as fields) - [ ] Write artifacts sent as embedded preview + optional file attachment - [ ] Bot shows typing indicator while mesh is processing - [ ] Error messages formatted distinctly (red embed, clear error prefix) - [ ] Code blocks preserve formatting in mono-spaced Discord blocks **Files touched:** `runtime/discord_ingress.py` (amend), `runtime/discord_response.py` (create), `runtime/__init__.py` (amend), `tests/unit/test_discord_response.py` (create) --- ### P5: Permissions & Governance **Goal:** Role-based access control, channel restrictions, rate limiting per user. Ensure the bot follows Discord governance best practices. **Approach candidates:** - YAML-based channel allow/deny list in `config/discord.yaml` - Discord role-based access — users need specific roles to use certain commands - Rate limiting: per-user cooldown (configurable, e.g. 5 calls/min for `/research`, unlimited `/chat`) - Admin role for configuration management (set allowed channels, adjust rate limits) - Privacy: message content not logged/stored outside mesh conversation history **Outputs:** - Permission checker in `runtime/discord_permissions.py` - Channel allow/deny rules in config - Rate limiter per user per command category - Tests for permission enforcement **Acceptance criteria:** - [ ] Channel allowlist: bot only responds in configured channels; silent in non-allowed channels - [ ] Role-based gating: `/research` requires `researcher` role; `/write` requires `author` role - [ ] Per-user cooldown enforced: hitting limit returns a rate-limit embed with retry-after info - [ ] Admin commands (`/config`, `/allow channel`) gated to admin role only - [ ] No Discord message content leaks into unsecured logs or caches - [ ] Unit tests verify: unauthorized user gets denied, authorized user passes, rate limit fires after N calls in window **Files touched:** `runtime/discord_permissions.py` (create), `config/discord.yaml` (amend), `docker/discord_bot.py` (amend — wire permission checks), `tests/unit/test_discord_permissions.py` (create) --- ## Related - CONV-001: Conversation Interface Infrastructure - CONV-002: Multi-turn Context Management _Decomposed from Mark/mesh-seed#134_
Author
Owner

Auto-triage: needs decompose

Marked triage-approved + needs-decompose. decompose-executor will pick this up and break it into implementable sub-issues.

## Auto-triage: needs decompose Marked `triage-approved` + `needs-decompose`. decompose-executor will pick this up and break it into implementable sub-issues.
Mark changed title from CONV-004: Discord Bot Integration to Decompose: CONV-004: Discord Bot Integration 2026-07-15 11:33:51 +00:00
Author
Owner

This issue has been decomposed into the following sub-issues:

# Title Phase Scope
#231 Discord Bot Foundation Goal: Get a Discord bot process running alongside the mesh stack, with token
#232 Intent Bridge — Discord to Mesh Translation Goal: Translate incoming Discord messages into mesh intents that the existin
#233 Commands & @Mentions Goal: Support @mention direct invocation and slash commands (/write, `/res
#234 Response Delivery Goal: Format mesh results for Discord delivery — handle the 2000-char messag
#235 Permissions & Governance Goal: Role-based access control, channel restrictions, rate limiting per use

Each sub-issue awaits triage pipeline assessment before queue routing.

This issue has been decomposed into the following sub-issues: | # | Title | Phase Scope | |---|-------|-------------| | #231 | Discord Bot Foundation | **Goal:** Get a Discord bot process running alongside the mesh stack, with token | | #232 | Intent Bridge — Discord to Mesh Translation | **Goal:** Translate incoming Discord messages into mesh intents that the existin | | #233 | Commands & @Mentions | **Goal:** Support @mention direct invocation and slash commands (`/write`, `/res | | #234 | Response Delivery | **Goal:** Format mesh results for Discord delivery — handle the 2000-char messag | | #235 | Permissions & Governance | **Goal:** Role-based access control, channel restrictions, rate limiting per use | Each sub-issue awaits triage pipeline assessment before queue routing.
Author
Owner

Decomposed into #231, #232, #233, #234, #235. Closing parent; sub-issues tracked separately.

Decomposed into #231, #232, #233, #234, #235. Closing parent; sub-issues tracked separately.
Mark 2026-07-16 05:50:56 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Mark/mesh-seed#134
No description provided.