hermes - 💡(How to fix) Fix Feishu: MEDIA attachments sent via topic/thread reply land in main conversation instead of thread [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

Two problems in the MEDIA delivery pipeline:

Fix Action

Fixed

Code Example

effective_reply_to = reply_to
if not effective_reply_to and metadata and metadata.get("thread_id"):
    effective_reply_to = metadata.get("reply_to_message_id")  # None!

---

def _thread_metadata_for_source(self, source, reply_to_message_id=None):
    thread_id = getattr(source, "thread_id", None)
    if thread_id is None:
        return None
    metadata = {"thread_id": thread_id}
    if reply_to_message_id is not None:
        metadata["reply_to_message_id"] = reply_to_message_id
    return metadata
RAW_BUFFERClick to expand / collapse

Bug Description

When a user replies to the bot in a Feishu topic/thread (话题), the agent's text response is correctly delivered inside the thread. However, any MEDIA attachments (images, files, audio) extracted from MEDIA:<path> tags in the response are delivered to the main conversation (主会话) instead of staying within the thread.

Steps to Reproduce

  1. User replies to a message in a Feishu thread (话题)
  2. Agent generates a response containing MEDIA:/path/to/image.png
  3. Text response is delivered correctly inside the thread ✅
  4. Image/file attachment lands in the main conversation ❌

Root Cause

Two problems in the MEDIA delivery pipeline:

Problem 1: _deliver_media_from_response() doesn't pass reply_to

In gateway/run.py ~line 11592, _deliver_media_from_response() calls adapter.send_multiple_images(chat_id=..., images=..., metadata=_thread_meta) — but only passes metadata (with thread_id), never a reply_to. The text reply goes through send() with reply_to=parent_message_id, but media attachments go through a separate path that lacks this.

Problem 2: _thread_metadata_for_source() doesn't populate reply_to_message_id for Feishu

In gateway/run.py ~line 13819, _thread_metadata_for_source() builds metadata as {"thread_id": thread_id} — that's only thread_id, with no reply_to_message_id. The Feishu adapter's _send_raw_message() at gateway/platforms/feishu.py line 4371 tries to recover:

effective_reply_to = reply_to
if not effective_reply_to and metadata and metadata.get("thread_id"):
    effective_reply_to = metadata.get("reply_to_message_id")  # None!

Since reply_to_message_id is absent, effective_reply_to stays None, and the code falls to the CreateMessage path (with thread_id as receive_id) instead of the ReplyMessage path (with reply_in_thread=True).

Why text works but media doesn't

  • Text replies: send()_feishu_send_with_retry(reply_to=parent_id)ReplyMessage with reply_in_thread=True
  • Media attachments: send_multiple_images()send_image_file(reply_to=None, metadata={"thread_id": ...})CreateMessage with receive_id=thread_id

Expected Behavior

MEDIA attachments sent in response to a message inside a Feishu thread should be delivered inside the same thread.

Proposed Fix

Two changes needed:

Fix 1: gateway/run.py_thread_metadata_for_source()

Add reply_to_message_id to the metadata for all platforms:

def _thread_metadata_for_source(self, source, reply_to_message_id=None):
    thread_id = getattr(source, "thread_id", None)
    if thread_id is None:
        return None
    metadata = {"thread_id": thread_id}
    if reply_to_message_id is not None:
        metadata["reply_to_message_id"] = reply_to_message_id
    return metadata

Fix 2: gateway/platforms/feishu.py_send_raw_message()

When there's a thread_id in metadata but no effective_reply_to, the Feishu adapter should either (a) use ReplyMessage with reply_in_thread=True instead of CreateMessage, or (b) find the correct reply_to message ID within the thread to anchor the media attachment.

Environment

  • Hermes version: Latest
  • Feishu platform adapter
  • All media types affected: images (send_image_file), files (send_document), audio (send_voice), video (send_video)

Related Code Locations

  • gateway/platforms/feishu.py: _send_raw_message() (line 4362), send_image_file() (line 2093)
  • gateway/run.py: _deliver_media_from_response() (line 11534), _thread_metadata_for_source() (line 13819)
  • gateway/platforms/base.py: send_multiple_images() (line 2141)

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING