Skip to content

feat(discord): smart auto-thread mode with race-fix and proper defaults#1035

Open
Hypn0sis wants to merge 12 commits intoRightNow-AI:mainfrom
Hypn0sis:feat/discord-smart-thread
Open

feat(discord): smart auto-thread mode with race-fix and proper defaults#1035
Hypn0sis wants to merge 12 commits intoRightNow-AI:mainfrom
Hypn0sis:feat/discord-smart-thread

Conversation

@Hypn0sis
Copy link
Copy Markdown

Summary

Adds a smart auto-thread mode for the Discord adapter and fixes two bugs introduced during its development.

Changes

New feature: auto_thread = "smart"

Adds a new mode alongside the existing true/false options. When set to smart, the bot creates a Discord thread only when it is @mentioned — not for every message in a server channel.

[channels.discord]
auto_thread = "smart"   # "false" (default) | "true" | "smart"

Bug fix: default changed from "true" to "false"

The previous default caused the bot to auto-thread every group message even without being mentioned. The default is now "false" (opt-in).

Bug fix: thread name derived from message content

Thread names were "Thread for {sender}" which is meaningless. Now the thread name is the first ~100 chars of the message text (Discord's limit), with <@mention> prefixes stripped.

Bug fix: eliminate race-window duplicate responses when @tagged

Discord sends MESSAGE_UPDATE (embed resolution) ~100–500 ms after MESSAGE_CREATE. The dedup guard only inserted the message-id into threaded_message_ids after create_thread() completed (async HTTP, up to ~2 s), so MESSAGE_UPDATE could slip through and produce a second free-channel response alongside the thread reply.

Fix: mark the message-id as seen immediately when MESSAGE_CREATE is forwarded to the stream — before the bridge picks it up.

Refactor: auto-thread creation moved after policy guards

Thread is now created only after DM/group policy, RBAC, and rate-limit checks all pass — prevents creating empty/orphan threads for rejected messages.

Hypnosis and others added 12 commits April 11, 2026 01:27
MESSAGE_UPDATE from Discord (embed resolution) arrives ~100-500ms after
MESSAGE_CREATE. The previous dedup only inserted into threaded_message_ids
*after* adapter.create_thread() completed (async HTTP, ~500ms-2s), so
MESSAGE_UPDATE could slip through before the guard was set, producing a
second free-channel response alongside the thread response.

Fix: insert the message_id into threaded_message_ids immediately when
MESSAGE_CREATE is forwarded to the stream — before the bridge even picks
it up. This closes the race window entirely.

Also move auto-thread creation in bridge.rs to after all policy guards
(rate-limit, RBAC) so threads are never created for rejected messages,
and propagate existing thread_id unconditionally so replies inside a
bot-created thread are always routed back into that thread.
…read name

- default auto_thread was "true" so every group message got threaded
  even without @mention; change default to "false" (opt-in)
- thread name was "Thread for {sender}" which is meaningless; now
  derives from message content (strips <@mention> prefix, truncates
  to Discord 100-char limit, falls back to sender name if empty)
wasmtime 41.0.4 had 10 CVEs (RUSTSEC-2026-0085..0096) including two
critical sandbox-escape vulnerabilities. Upgraded to 43.0.1 which fixes
all of them.

rumqttc 0.24 pulled in rustls-webpki 0.102.8 (RUSTSEC-2026-0049, faulty
CRL matching). rumqttc 0.25 resolves the transitive dependency.

copy and func_wrap closures must return wasmtime::Result<T>.
… CVE

rumqttc 0.25 still pins rustls-webpki 0.102.8 (RUSTSEC-2026-0049)
via its default use-rustls feature. The MQTT adapter does not actually
use TLS (the use_tls branch is a no-op stub), so switch to
use-native-tls with default-features = false to eliminate the
vulnerable transitive dependency entirely.
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