mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-24 03:29:17 +00:00
When _auto_create_thread() creates a thread from a user message via message.create_thread(), Discord fires a second MESSAGE_CREATE event for the 'thread starter message'. That starter message carries message.id == thread.id and may arrive with type=default instead of type=21 (thread_starter_message), so the existing type filter in on_message does not catch it — triggering a second call into _handle_message and thus a second agent run and response. Fix: after _auto_create_thread succeeds and returns a thread, pre-seed the dedup cache with str(thread.id) via self._dedup.is_duplicate(). The dedup cache is the same TTL-based MessageDeduplicator that already guards against Discord RESUME event replays. Calling is_duplicate() marks the ID as seen; when the duplicate thread-starter MESSAGE_CREATE arrives, on_message's guard returns True and the event is dropped. This is a minimal, targeted fix: - No new state: reuses the existing _dedup instance - No timing/race: the pre-seed happens synchronously inside the async _handle_message, before the thread-starter event can be dispatched - Scoped: only fires when auto-threading is enabled AND thread creation succeeds (thread object is not None) Also adds tests in tests/gateway/test_discord_double_dispatch.py covering the pre-seed behaviour, failure modes (thread creation fails, auto-thread disabled), and dedup cache integrity. Closes #51057