Skip to content

feat(discord): tag forwarded messages with channel/thread/DM context#1555

Merged
asheshgoplani merged 3 commits into
asheshgoplani:mainfrom
torres-hike:feat/discord-thread-context
Jul 12, 2026
Merged

feat(discord): tag forwarded messages with channel/thread/DM context#1555
asheshgoplani merged 3 commits into
asheshgoplani:mainfrom
torres-hike:feat/discord-thread-context

Conversation

@tkohout

@tkohout tkohout commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

What

The Discord bridge forwarded a user's message text to the conductor with no indication of where it came from. The Slack path already enriches messages with a [from:… (id)] [channel:#… (id)] prefix (see resolve_slack_channel); Discord did not — so a conductor answering a Discord request couldn't tell which channel, thread, or DM it originated in, and couldn't reference it back.

This adds build_discord_context_tag() and prepends it in on_message, mirroring the Slack convention so a conductor sees a consistent shape from either platform.

Message examples

Given user alice sending deploy the thing, the conductor now receives:

Origin Forwarded to conductor
Regular channel [from:alice (987654321)] [channel:#general (456)] deploy the thing
Inside a thread [from:alice (987654321)] [thread:#deploy-thread (789) in #general] deploy the thing
Private thread [from:alice (987654321)] [thread:#secret (791) in #ops] deploy the thing
Direct message [from:alice (987654321)] [dm] deploy the thing

Compared with the existing Slack output for the same message:

[from:alice (U123)] [channel:#general (C456)] deploy the thing

The from / channel / dm tags match Slack exactly. Discord additionally emits a [thread:#name (id) in #parent] variant — Slack has no inline equivalent because it routes threads out-of-band via thread_ts rather than tagging them in the message body. Parent falls back to ? if it can't be resoldisplay_namename?`.

Summary by CodeRabbit

Summary

  • New Features

    • Discord messages now include a formatted prefix with sender identity and message location (channel, thread—including parent when available—or DM) when forwarded to the session.
  • Tests

    • Added unit tests validating the context-prefix formatting for standard channels, threads, DMs, and multiple fallback scenarios (missing display name, missing parent name, and missing channel name).

The Discord bridge forwarded message text to the conductor with no
indication of where it came from. Slack messages already carry a
`[from:... (id)] [channel:#... (id)]` prefix (see resolve_slack_channel);
Discord did not, so the conductor could not tell which channel, thread,
or DM a request originated in.

Add build_discord_context_tag() and prepend it in on_message, mirroring
the Slack convention. Discord additionally emits a
`[thread:#name (id) in #parent]` variant for messages sent inside a
thread — Slack has no inline equivalent because it routes threads via
thread_ts instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GN4ktNBa9zcKUXvV6HPZu
@tkohout tkohout requested a review from asheshgoplani as a code owner July 2, 2026 06:52
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 67616600-b6ab-4472-b0a3-67bffe0e5eb9

📥 Commits

Reviewing files that changed from the base of the PR and between 9149355 and 3d455a3.

📒 Files selected for processing (1)
  • internal/session/test_discord_message_enrichment.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/session/test_discord_message_enrichment.py

📝 Walkthrough

Walkthrough

This change adds Discord message context tagging in the bridge, prepends the tag before forwarding messages to the conductor, and adds tests for the tag format and fallback cases.

Changes

Discord Context Tagging

Layer / File(s) Summary
Context tag helper and message wiring
internal/session/conductor_bridge.py
Adds build_discord_context_tag(message) to format author and channel/thread/DM context, and prepends it to cleaned_msg in the Discord on_message flow before conductor routing.
Context tag test coverage
internal/session/test_discord_message_enrichment.py
Adds a test module that mirrors the tag-building logic and asserts exact output for regular channels, threads, DMs, and author/channel fallback cases.

Sequence Diagram(s)

sequenceDiagram
  participant DiscordMessage
  participant conductor_bridge
  participant ConductorSession
  DiscordMessage->>conductor_bridge: on_message(message)
  conductor_bridge->>conductor_bridge: build_discord_context_tag(message)
  conductor_bridge->>ConductorSession: cleaned_msg with context tag
Loading

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 7
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title uses Conventional Commits format and clearly describes the Discord message-context tagging change.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Remote_parity ✅ Passed PASS: PR only changes Discord session bridging/tests; the only cmd/agent-deck edit is a version bump, with no TUI behavior changes in internal/ui/ or cmd/agent-deck/.
Test_coverage_per_surface ✅ Passed PASS: the feature is confined to the Discord remote bridge, and it adds dedicated tests covering channel, thread, DM, and fallback cases.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/session/conductor_bridge.py (1)

2245-2269: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

No test coverage for the new helper.

Slack's equivalent tagging logic has dedicated unit tests (internal/session/test_slack_message_enrichment.py), but build_discord_context_tag has no analogous tests covering the channel/thread/DM branches, fallback name handling, or the final tag format.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/session/conductor_bridge.py` around lines 2245 - 2269, Add unit
tests for build_discord_context_tag in conductor_bridge to cover the DM, thread,
and normal channel branches, plus fallback author/channel naming when
display_name, name, or parent are missing. Mirror the style of the existing
Slack tests by asserting the exact final tag format for each case, including
thread parent formatting and the combined [from:...]
[channel:...]/[thread:...]/[dm] output.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/session/conductor_bridge.py`:
- Around line 2245-2269: The thread/DM handling in build_discord_context_tag is
currently unreachable because on_message filters out anything whose channel id
does not match bot.target_channel_id before this helper runs. Update the message
gating in on_message so it also allows child thread channels under the target
channel and any intended DM path, then keep build_discord_context_tag as the
place that formats private/thread/channel tags using message.channel and its
type.

---

Nitpick comments:
In `@internal/session/conductor_bridge.py`:
- Around line 2245-2269: Add unit tests for build_discord_context_tag in
conductor_bridge to cover the DM, thread, and normal channel branches, plus
fallback author/channel naming when display_name, name, or parent are missing.
Mirror the style of the existing Slack tests by asserting the exact final tag
format for each case, including thread parent formatting and the combined
[from:...] [channel:...]/[thread:...]/[dm] output.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0751d61c-2fb7-4505-b3da-c84cf8014d48

📥 Commits

Reviewing files that changed from the base of the PR and between 0e11487 and 6e6dcfa.

📒 Files selected for processing (1)
  • internal/session/conductor_bridge.py

Comment thread internal/session/conductor_bridge.py
…ches

Addresses CodeRabbit review on asheshgoplani#1555: the Slack tagging logic has
test_slack_message_enrichment.py but build_discord_context_tag had none.

Mirrors the Slack test style (a faithful mirror of the closure) and
asserts the exact tag format for regular channels, public/private
threads, threads with an unresolvable parent, DMs, and the author/
channel name fallbacks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GN4ktNBa9zcKUXvV6HPZu

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/session/test_discord_message_enrichment.py (1)

39-49: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider covering the news_thread branch.

thread_types includes news_thread, but no test exercises it. Minor coverage gap, same shape as the existing public/private thread tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/session/test_discord_message_enrichment.py` around lines 39 - 49,
Add a test case that exercises the `news_thread` branch in
`test_discord_message_enrichment.py` so `thread_types` is covered for all thread
variants. Reuse the same pattern as the existing public/private thread coverage
by creating a `discord.ChannelType.news_thread` channel with a parent, then
assert the generated `chan_tag` matches the thread format in the enrichment
logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/session/test_discord_message_enrichment.py`:
- Around line 39-49: Add a test case that exercises the `news_thread` branch in
`test_discord_message_enrichment.py` so `thread_types` is covered for all thread
variants. Reuse the same pattern as the existing public/private thread coverage
by creating a `discord.ChannelType.news_thread` channel with a parent, then
assert the generated `chan_tag` matches the thread format in the enrichment
logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: cf451648-6392-4e2c-befe-5d0b887d97c4

📥 Commits

Reviewing files that changed from the base of the PR and between 6e6dcfa and 9149355.

📒 Files selected for processing (1)
  • internal/session/test_discord_message_enrichment.py

Copy link
Copy Markdown
Owner

🤖 autopilot: no CI checks found for this PR. Autopilot cannot assess safety without CI results — please trigger CI and ensure all checks pass before this is eligible for merge.


Generated by Claude Code

Addresses CodeRabbit nitpick on asheshgoplani#1555: thread_types includes news_thread
but no test exercised it. Adds an announcement-thread case matching the
public/private thread coverage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GN4ktNBa9zcKUXvV6HPZu
@asheshgoplani asheshgoplani merged commit f9b98bd into asheshgoplani:main Jul 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants