fix(feishu): render markdown tables as Schema 2.0 interactive cards - #29630
fix(feishu): render markdown tables as Schema 2.0 interactive cards#296301040097629 wants to merge 1 commit into
Conversation
Problem - Feishu's post/tag:md renderer cannot parse markdown tables; causes blank message - Previous workaround downgraded entire message to plain text (msg_type: text) - Schema 1.0 cards lack markdown support for headings, blockquotes, inline code Solution - Tables: render as Schema 2.0 interactive card (white bg, full width) - Pipe-separated headers + data rows (plain text, no **bold** in pipes) - Non-table content renders natively via card tag:markdown - Fallback chain: interactive -> post/md -> text on API error Changes - _render_table_as_md(): parse tables into pipe-separated text - _build_content_card_payload(): Schema 2.0 interactive card wrapper - _build_outbound_payload(): tables -> interactive; rest unchanged - send(): fallback for interactive card API failures - _TABLE_SEPARATOR_RE: module-level regex for table separator rows
|
Thanks for the review, but I don't believe this is a duplicate — the two PRs take fundamentally different approaches: PR #12114 renders tables using Feishu's native This PR (#29630) uses As @Crazy-FuQing noted in the #12114 comments, the approach closest to ours is actually #27990 (which uses card |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for addressing the table-to-plain-text degradation; the underlying current-main behavior is still present at plugins/platforms/feishu/adapter.py:4524-4533.
Problems
- The PR now targets the removed
gateway/platforms/feishu.py; Feishu moved toplugins/platforms/feishu/adapter.pyin5600105478ffde29d7566b45421b100eaa29c4ef, so this needs a considered port rather than a clean cherry-pick. - The stated three-stage fallback is incomplete for exceptions: the post retry at
gateway/platforms/feishu.py:1870runs inside the interactive exception handler. If that retry raises, it returns a send failure instead of reaching text fallback. edit_message()also derives its message type from_build_outbound_payload()(plugins/platforms/feishu/adapter.py:1958on current main), and stream delivery calls it (gateway/stream_consumer.py:1771). The PR adds no interactive-card edit fallback or coverage.- The PR changes no tests despite introducing table parsing, an interactive payload, and new fallback paths.
Suggested changes
- Port the work to the plugin adapter and cover send and edit/streaming routing.
- Centralize and test exception and failed-response transitions for interactive → post → text.
- Validate the CardKit payload through the real Feishu API path; related PR
#27990was closed after reporting a230099failure for its card-markdown route.
This is an automated hermes-sweeper review.
| chunk = _render_table_as_md(chunk) | ||
| msg_type = "post" | ||
| payload = _build_markdown_post_payload(chunk) | ||
| response = await self._feishu_send_with_retry( |
There was a problem hiding this comment.
If this post retry raises, it escapes the interactive exception handler to the outer send failure path and never reaches the text fallback. Route the retry through a common fallback sequence, or catch this retry failure explicitly, and add an exception-path regression test.
Problem
Feishu (Lark) post/tag:md renderer cannot parse markdown tables. Sending table content as
postcauses a blank message on the client. The previous workaround downgraded the entire message to plain text (msg_type: text), losing ALL formatting.Additionally, Feishu interactive cards without
"schema": "2.0"fall back to Schema 1.0, which has severely limited markdown support (no headings, blockquotes, or inline code).Solution
When a message contains a markdown table, render it as a Schema 2.0 interactive card (white background, full width) with pipe-separated headers and data rows. Non-table content renders natively via the card's tag:markdown element (headings, blockquotes, inline code, code blocks all work in Schema 2.0).
Changes
_render_table_as_md(): parse markdown tables into pipe-separated text with plain-text headers (no bold - card markdown does not render bold when | pipe chars are on the same line)_build_content_card_payload(): wrap content in Schema 2.0 interactive card with wide_screen_mode enabled_build_outbound_payload(): tables - interactive card; markdown hints - post/tag:md (unchanged); plain text - text (unchanged)send(): fallback chain interactive - post/md - text if API rejects_TABLE_SEPARATOR_RE: module-level regex for detecting table separator rowsTesting
All 198 existing Feishu adapter tests continue to pass. Tested interactively on Feishu DM with messages containing tables, headings, blockquotes, inline code, code blocks, bold, links, and lists.