fix(feishu): comprehensive topic thread reply fix (A+B+C+D) - #18121
Closed
highland0971 wants to merge 4 commits into
Closed
fix(feishu): comprehensive topic thread reply fix (A+B+C+D)#18121highland0971 wants to merge 4 commits into
highland0971 wants to merge 4 commits into
Conversation
- feat(feishu): add markdown table rendering support - fix(feishu): silent message drop handling - fix(feishu): ensure replies stay inside topic threads in group chats
- Set NO_COLOR=1 env var to disable colors in agent-browser CLI - Add fallback regex to strip any remaining ANSI sequences - Fixes JSON parse failures from escape codes like \x1b[A (cursor up)
Previous regex \x1b/[a-z]* was greedy and consumed trailing letters. Fixed to \x1b/ which only matches the ESC+/ sequence. Example: \x1b/tabs now correctly becomes 'tabs' instead of ''. Also expanded pattern to handle: - CSI sequences with private mode params (\x1b[?25h) - OSC sequences (\x1b]...BEL) - Single ESC+letter sequences (\x1bM) - Non-standard ESC+/ sequences
Fixes Feishu bot replies creating new topics instead of staying inside the existing topic thread in topic-mode groups. A. Inbound: root_id → thread_id + reply_to_message_id fallback B. Outbound: om_/omt_ ID prefix handling, thread_id delivery via create C. Gateway: initial_reply_to_id in StreamConsumer, reply_to in callbacks D. Defense: reply failure fallback stays in thread (no new topic spawn)
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes Feishu/Lark bot replies creating new topics instead of staying inside the existing topic thread in topic-mode groups (话题模式群).
This is a comprehensive fix that addresses all four root-cause layers simultaneously, combining insights from 10 previous community PRs that each addressed only part of the problem.
Root Cause Analysis
The bug has four interrelated causes:
Inbound (A): Feishu topic messages have
root_idbut notthread_id. The code only readthread_id, so topic context was silently lost.Outbound (B): When
reply_tois absent (progress/status/approval messages),_send_raw_messagefalls through toim.v1.message.createwithreceive_id_type="chat_id", which creates a new topic instead of posting inside the existing one.Gateway (C): Mid-turn messages (stream consumer first-send, progress updates, status callbacks, interim commentary, background review, approval cards) all lack
reply_to, so they can't use the reply API to stay in-thread.Defense (D): When a reply fails (message withdrawn, error codes 230011/231003), the code falls back to
createwithreply_to=None, which spawns a new topic in topic-mode groups.Changes Made
A. Inbound:
root_id→thread_idfallback (feishu.py)_process_inbound_message: extractroot_idand use it as fallback for boththread_id(topic routing) andreply_to_message_id(reply anchor chain)B. Outbound:
om_/omt_ID prefix handling (feishu.py)_send_raw_message: distinguish Feishu's two ID prefixes:om_(message ID) → use asreply_tovia reply API (most reliable in-thread delivery)omt_(topic/thread ID) → usereceive_id_type="thread_id"via create APIthread_id→ fall back tochat_id(unchanged behavior)C. Gateway: propagate
reply_toto all mid-turn messagesstream_consumer.py: newinitial_reply_to_idparameter onGatewayStreamConsumer; used in first-send, fallback-final, and commentary pathsrun.py: passevent_message_idasinitial_reply_to_idfor Feishu topic threads; add_progress_reply_toforsend_progress_messagesand all status/callback sendsD. Defense: reply failure fallback stays in thread (
feishu.py)_feishu_send_with_retry: when reply fails with 230011/231003, ifthread_idis anom_ID, retry reply to it instead of falling back tocreate(which would spawn a new topic)Related PRs
This supersedes and consolidates:
How to Test
python -m pytest tests/gateway/test_feishu.py tests/gateway/test_stream_consumer.py -qTest Results
Real-world verification: Deployed to a production Hermes instance and tested in both group-topic and P2P-topic scenarios — all message types (final response, tool progress, streaming, approval cards) correctly stay inside the originating topic thread.