Skip to content

fix(gateway/feishu): always route outbound via post + md tag - #28030

Open
0x5446 wants to merge 1 commit into
NousResearch:mainfrom
0x5446:fix/feishu-always-post-md
Open

fix(gateway/feishu): always route outbound via post + md tag#28030
0x5446 wants to merge 1 commit into
NousResearch:mainfrom
0x5446:fix/feishu-always-post-md

Conversation

@0x5446

@0x5446 0x5446 commented May 18, 2026

Copy link
Copy Markdown

Summary

FeishuAdapter._build_outbound_payload previously used two regex heuristics to choose between msg_type=text and msg_type=post. Both heuristics produced visible misrendering:

  1. _MARKDOWN_TABLE_RE force-downgraded any message containing a GFM table to msg_type=text. The downgrade made the entire message — headers, bold, lists, code, the table itself — render as raw markdown source on both Lark (international) and Feishu (CN) clients.
  2. _MARKDOWN_HINT_RE over-matched on incidental punctuation (_ * # > in shell output, stack traces, prose) and under-matched on legitimate markdown that didn't fit its narrow patterns — yielding inconsistent styling between similar-looking messages.

Fix

Always route outbound messages through post + the md tag.

Empirical testing on current Lark and Feishu clients shows the md tag is a strict superset of msg_type=text:

Content type md tag result
Plain prose renders identically to text
URLs auto-linked
Mentions work
Emoji display correctly
Special chars (_*#>) literal
Multi-line preserved
Markdown tables render as native tables ✅

The outer _feishu_send_with_retry still catches the rare "content format of the post type is incorrect" API error and falls back to msg_type=text, so the safety net stays.

Drops both regex constants and the conditional branching — one code path, one render mode.

Tests

  • tests/gateway/test_feishu.py: 200/200 pass
  • Added regression test test_outbound_payload_routes_table_to_post_not_text — pins the table-bug fix
  • Added regression test test_outbound_payload_plain_text_uses_post_md — pins the strict-superset claim
  • Updated existing text-mode assertion that no longer applies

Verification

Validated end-to-end through the live gateway adapter (not a raw API bypass) on Lark international — plain text, special chars, URLs, multi-line+emoji, and a markdown table all rendered correctly.

The previous _build_outbound_payload had two heuristics that caused
visible misrendering:

1. _MARKDOWN_TABLE_RE downgraded any message containing a GFM table
   to msg_type=text, which made the ENTIRE message (headers, bold,
   lists, code, the table itself) render as raw markdown source on
   both Lark and Feishu clients.
2. _MARKDOWN_HINT_RE over-matched on incidental punctuation (`_*#>`
   in shell output, code traces, prose) and under-matched on
   legitimate markdown that didn't fit its narrow patterns — yielding
   inconsistent styling.

Empirical testing on current Lark (international) and Feishu (CN)
clients shows the post-type `md` tag is a strict superset of
msg_type=text: plain prose, URLs, mentions, emoji, multi-line text,
special characters, and markdown tables all render correctly. The
outer _feishu_send_with_retry already falls back to text if the API
ever rejects a specific payload, so the safety net stays.

Drops both regex constants and the conditional branching; one code
path, one render mode.

Regression test added for the table case (the most user-visible bug)
and the plain-text case (to pin the strict-superset claim).
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/feishu Feishu / Lark adapter P2 Medium — degraded but workaround exists labels May 18, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Competing fix for the long-standing Feishu table rendering issue family (#9549, #27469). Also competing with open PRs: #26108, #27739, #27922, #22259, #16474. This PR takes the most aggressive approach — always routing through post + md tag and removing the regex heuristics entirely.

@teknium1

teknium1 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Thanks for the focused Feishu rendering investigation. The current table-to-text behavior is still present, but this patch needs rework before it can be safely salvaged.

Problems

  • The patch changes the removed gateway/platforms/feishu.py; current main moved the adapter to plugins/platforms/feishu/adapter.py in 560010547. Current tests likewise import plugins.platforms.feishu.adapter (for example tests/gateway/test_feishu.py:489).
  • The proposed universal post route is not protected against accepted-but-misrendered payloads: the fallback in plugins/platforms/feishu/adapter.py:1913-1936 only handles explicit post-format rejection. Linked discussion on [Feishu] Markdown tables not rendering in Feishu messages #9549 reports post md silently dropping GFM tables, while this PR's tests validate payload serialization rather than Feishu/Lark rendering.

Suggested changes

This is an automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 13, 2026
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 P2 Medium — degraded but workaround exists platform/feishu Feishu / Lark adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants