fix(feishu): render markdown tables as interactive card table components#25453
Open
wait4xx wants to merge 1 commit into
Open
fix(feishu): render markdown tables as interactive card table components#25453wait4xx wants to merge 1 commit into
wait4xx wants to merge 1 commit into
Conversation
Markdown tables sent via the Feishu channel are displayed as raw source code because Feishu's post-type 'md' elements do not support table syntax. Convert markdown table content into Feishu Interactive Card JSON (schema 2.0) with native table components. Non-table markdown content is preserved as card markdown elements in the same message, with full markdown syntax support (headings, blockquotes, inline code, code blocks, etc.). Changes in gateway/platforms/feishu.py (~180 lines added): - _ParsedTable / _ContentSegment: data structures for parsed content - _parse_markdown_table(): parse pipe-delimited table text to headers/rows - _extract_tables_and_prose(): split mixed content into ordered segments, skipping tables inside fenced code blocks - _build_table_element(): convert parsed table to Feishu card table JSON - _build_table_card_payload(): assemble full interactive card (JSON 2.0) with markdown + table elements, with 100KB/5-table/50-column safeguards - _build_outbound_payload(): route table content to interactive cards instead of plain text - send(): add interactive -> text fallback on API failure Safety: - Tables inside fenced code blocks are not parsed (preserved as text) - Card JSON size limited to 100KB; falls back to text on overflow - Max 5 tables per card, max 50 columns per table (Feishu limits) - Full fallback chain: interactive card -> text on any send failure Co-Authored-By: wait4xx <X@alumni.nudt.edu.cn> Co-Authored-By: GLM 5.1
ea38aae to
8605a29
Compare
This was referenced May 17, 2026
14 tasks
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.
Summary
Fixes #25452
When AI responses contain markdown tables, the Feishu channel displays raw
markdown syntax instead of rendered tables. This PR converts table content
into Feishu Interactive Card JSON (schema 2.0) with native
tablecomponents.Non-table markdown is preserved in card
markdownelements with full syntaxsupport (headings, blockquotes, inline code, code blocks).
Before / After
text— raw markdown source displayedinteractivecard (JSON 2.0) — native table + full markdown renderingpost(unchanged)post(unchanged)text(unchanged)text(unchanged)Changes
gateway/platforms/feishu.pyNew functions:
_parse_markdown_table()— parse pipe-delimited table text to structured data_extract_tables_and_prose()— split mixed content into ordered segments_build_table_element()— convert parsed table to Feishu card table JSON_build_table_card_payload()— assemble interactive card (JSON 2.0) with safeguardsModified functions:
_build_outbound_payload()— route table content to interactive cardssend()— add interactive → text fallback on API failureSafety
post,text) completely unaffectedTest Plan
posttype (unchanged)texttype (unchanged)