Skip to content

fix(gateway): stream consumer first message drops thread context#13077

Closed
hrygo wants to merge 2 commits into
NousResearch:mainfrom
hrygo:fix/stream-consumer-thread-routing
Closed

fix(gateway): stream consumer first message drops thread context#13077
hrygo wants to merge 2 commits into
NousResearch:mainfrom
hrygo:fix/stream-consumer-thread-routing

Conversation

@hrygo

@hrygo hrygo commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Problem

When a user @mentions the bot inside a group topic thread (Feishu group topic / Slack thread / Telegram forum), the first streamed message chunk is sent via message.create with receive_id=chat_id (the main group) instead of being threaded into the topic. The response — including any visible thinking/reasoning — appears in the main group chat rather than the topic thread.

This is a cross-platform architecture defect in GatewayStreamConsumer that has been reported multiple times across different platforms:

Root Cause

Two bugs:

Bug 1: GatewayStreamConsumer sends first chunk without reply_to

gateway/stream_consumer.py_send_or_edit() first-message path:

# BEFORE — no reply_to passed
result = await self.adapter.send(
    chat_id=self.chat_id,
    content=text,
    metadata=self.metadata,
)

self._message_id is None on the first send, and no fallback reply_to is provided. The adapter receives reply_to=None → falls to message.create with receive_id=chat_id → message lands in main chat.

Meanwhile, the non-streaming path in base.py has always correctly passed reply_to=event.message_id. This is why short answers work fine — only streaming (long answers / tool-heavy responses) triggers the bug.

Bug 2: FeishuAdapter._send_raw_message fallback loses thread context

When message.reply fails (e.g. message withdrawn, error codes in _FEISHU_REPLY_FALLBACK_CODES) and falls back to message.create, the fallback uses receive_id=chat_id even though metadata.thread_id is available — as independently identified in #9916.

Fix (3 files)

File Change
gateway/stream_consumer.py __init__ accepts optional initial_reply_to_id; _send_or_edit passes it as reply_to on first send
gateway/platforms/feishu.py _send_raw_message fallback checks metadata.thread_id, uses receive_id_type="thread_id" instead of "chat_id"
gateway/run.py Both GatewayStreamConsumer creation sites (proxy path L8000 + local path L8575) pass initial_reply_to_id=event_message_id

Affected Platforms

Any platform using topic/thread routing:

Reproduction

  1. Create a group chat topic in Feishu (or forum topic in Telegram)
  2. @mention the bot inside the topic thread
  3. Ask something that triggers a long response or tool use (streaming)
  4. Observe: the streamed response appears in the main group chat, not in the topic thread
  5. Short non-streaming answers work correctly

Backward Compatibility

initial_reply_to_id defaults to None — no impact on existing code or platforms without thread routing.

Closes

Closes #6969
Closes #9916
Closes #7355

…tream-consumer-thread-routing

Cherry-picked commits:
- 5500c7d8 fix(gateway): stream consumer first message drops thread context
- e84403b9 test(gateway): add regression tests for stream consumer thread routing

Fixes: Streaming first message drops thread/topic context in Feishu group topics,
Slack threads, Telegram forum topics. Also fixes Feishu fallback path (reply→create)
to use thread_id instead of chat_id.
@hrygo hrygo force-pushed the fix/stream-consumer-thread-routing branch from 2d7860a to 7554711 Compare May 9, 2026 01:25
…path

When the first streamed message exceeds the platform length limit and
gets split into chunks, _send_new_chunk was called with self._message_id
(which is None on first send), dropping thread routing entirely.

Fallback to self._initial_reply_to_id so overflow chunks land in the
correct topic/thread.

Also fix a fragile test assertion that could be silently skipped.
teknium1 pushed a commit that referenced this pull request May 10, 2026
Cherry-picked from PR #13077 commits:
- 5500c7d8 fix(gateway): stream consumer first message drops thread context
- e84403b9 test(gateway): add regression tests for stream consumer thread routing

Fixes: Streaming first message drops thread/topic context in Feishu group
topics, Slack threads, Telegram forum topics. Adds initial_reply_to_id
ctor arg to GatewayStreamConsumer, threaded through _send_or_edit and
_send_new_chunk. Also fixes Feishu _send_raw_message fallback path
(reply -> create) to use receive_id_type='thread_id' so the new message
lands in the correct topic instead of the main channel.

Authored by hrygo via PR #13077 (re-attributed from the bot-authored
salvage commit on the original branch).
@teknium1

Copy link
Copy Markdown
Contributor

Merged via salvage PR #23437 (#23437). Your two commits were cherry-picked onto current main with your authorship preserved (re-attributed from the bot-authored commit on your branch to hrygo). We added a test compat fix so the new Feishu fallback test runs in environments without the lark SDK installed, plus an AUTHOR_MAP entry. Conflict against PR #23420 (just-landed #10748 fix) was resolved by merging both fixes in the same chunk loop. Thanks for the fix — this also closes paths #6969 and #9916 as a side effect.

@teknium1 teknium1 closed this May 10, 2026
JZKK720 pushed a commit to JZKK720/hermes-agent that referenced this pull request May 11, 2026
Cherry-picked from PR NousResearch#13077 commits:
- 5500c7d8 fix(gateway): stream consumer first message drops thread context
- e84403b9 test(gateway): add regression tests for stream consumer thread routing

Fixes: Streaming first message drops thread/topic context in Feishu group
topics, Slack threads, Telegram forum topics. Adds initial_reply_to_id
ctor arg to GatewayStreamConsumer, threaded through _send_or_edit and
_send_new_chunk. Also fixes Feishu _send_raw_message fallback path
(reply -> create) to use receive_id_type='thread_id' so the new message
lands in the correct topic instead of the main channel.

Authored by hrygo via PR NousResearch#13077 (re-attributed from the bot-authored
salvage commit on the original branch).
rmulligan pushed a commit to rmulligan/hermes-agent that referenced this pull request May 11, 2026
Cherry-picked from PR NousResearch#13077 commits:
- 5500c7d8 fix(gateway): stream consumer first message drops thread context
- e84403b9 test(gateway): add regression tests for stream consumer thread routing

Fixes: Streaming first message drops thread/topic context in Feishu group
topics, Slack threads, Telegram forum topics. Adds initial_reply_to_id
ctor arg to GatewayStreamConsumer, threaded through _send_or_edit and
_send_new_chunk. Also fixes Feishu _send_raw_message fallback path
(reply -> create) to use receive_id_type='thread_id' so the new message
lands in the correct topic instead of the main channel.

Authored by hrygo via PR NousResearch#13077 (re-attributed from the bot-authored
salvage commit on the original branch).
JinyuID pushed a commit to JinyuID/hermes-agent that referenced this pull request May 11, 2026
Cherry-picked from PR NousResearch#13077 commits:
- 5500c7d8 fix(gateway): stream consumer first message drops thread context
- e84403b9 test(gateway): add regression tests for stream consumer thread routing

Fixes: Streaming first message drops thread/topic context in Feishu group
topics, Slack threads, Telegram forum topics. Adds initial_reply_to_id
ctor arg to GatewayStreamConsumer, threaded through _send_or_edit and
_send_new_chunk. Also fixes Feishu _send_raw_message fallback path
(reply -> create) to use receive_id_type='thread_id' so the new message
lands in the correct topic instead of the main channel.

Authored by hrygo via PR NousResearch#13077 (re-attributed from the bot-authored
salvage commit on the original branch).
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
Cherry-picked from PR NousResearch#13077 commits:
- 5500c7d8 fix(gateway): stream consumer first message drops thread context
- e84403b9 test(gateway): add regression tests for stream consumer thread routing

Fixes: Streaming first message drops thread/topic context in Feishu group
topics, Slack threads, Telegram forum topics. Adds initial_reply_to_id
ctor arg to GatewayStreamConsumer, threaded through _send_or_edit and
_send_new_chunk. Also fixes Feishu _send_raw_message fallback path
(reply -> create) to use receive_id_type='thread_id' so the new message
lands in the correct topic instead of the main channel.

Authored by hrygo via PR NousResearch#13077 (re-attributed from the bot-authored
salvage commit on the original branch).
jsboige pushed a commit to jsboige/hermes-agent that referenced this pull request May 14, 2026
Cherry-picked from PR NousResearch#13077 commits:
- 5500c7d8 fix(gateway): stream consumer first message drops thread context
- e84403b9 test(gateway): add regression tests for stream consumer thread routing

Fixes: Streaming first message drops thread/topic context in Feishu group
topics, Slack threads, Telegram forum topics. Adds initial_reply_to_id
ctor arg to GatewayStreamConsumer, threaded through _send_or_edit and
_send_new_chunk. Also fixes Feishu _send_raw_message fallback path
(reply -> create) to use receive_id_type='thread_id' so the new message
lands in the correct topic instead of the main channel.

Authored by hrygo via PR NousResearch#13077 (re-attributed from the bot-authored
salvage commit on the original branch).
AlexFoxD pushed a commit to AlexFoxD/hermes-agent that referenced this pull request May 21, 2026
Cherry-picked from PR NousResearch#13077 commits:
- 5500c7d8 fix(gateway): stream consumer first message drops thread context
- e84403b9 test(gateway): add regression tests for stream consumer thread routing

Fixes: Streaming first message drops thread/topic context in Feishu group
topics, Slack threads, Telegram forum topics. Adds initial_reply_to_id
ctor arg to GatewayStreamConsumer, threaded through _send_or_edit and
_send_new_chunk. Also fixes Feishu _send_raw_message fallback path
(reply -> create) to use receive_id_type='thread_id' so the new message
lands in the correct topic instead of the main channel.

Authored by hrygo via PR NousResearch#13077 (re-attributed from the bot-authored
salvage commit on the original branch).
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
Cherry-picked from PR NousResearch#13077 commits:
- 5500c7d8 fix(gateway): stream consumer first message drops thread context
- e84403b9 test(gateway): add regression tests for stream consumer thread routing

Fixes: Streaming first message drops thread/topic context in Feishu group
topics, Slack threads, Telegram forum topics. Adds initial_reply_to_id
ctor arg to GatewayStreamConsumer, threaded through _send_or_edit and
_send_new_chunk. Also fixes Feishu _send_raw_message fallback path
(reply -> create) to use receive_id_type='thread_id' so the new message
lands in the correct topic instead of the main channel.

Authored by hrygo via PR NousResearch#13077 (re-attributed from the bot-authored
salvage commit on the original branch).
Seven74AI pushed a commit to Seven74AI/hermes-agent that referenced this pull request Jun 13, 2026
Cherry-picked from PR NousResearch#13077 commits:
- 5500c7d8 fix(gateway): stream consumer first message drops thread context
- e84403b9 test(gateway): add regression tests for stream consumer thread routing

Fixes: Streaming first message drops thread/topic context in Feishu group
topics, Slack threads, Telegram forum topics. Adds initial_reply_to_id
ctor arg to GatewayStreamConsumer, threaded through _send_or_edit and
_send_new_chunk. Also fixes Feishu _send_raw_message fallback path
(reply -> create) to use receive_id_type='thread_id' so the new message
lands in the correct topic instead of the main channel.

Authored by hrygo via PR NousResearch#13077 (re-attributed from the bot-authored
salvage commit on the original branch).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P1 High — major feature broken, no workaround platform/feishu Feishu / Lark adapter type/bug Something isn't working

Projects

None yet

5 participants