Skip to content

fix(feishu): render markdown tables as interactive card table components#25453

Open
wait4xx wants to merge 1 commit into
NousResearch:mainfrom
wait4xx:fix/feishu-interactive-card-table
Open

fix(feishu): render markdown tables as interactive card table components#25453
wait4xx wants to merge 1 commit into
NousResearch:mainfrom
wait4xx:fix/feishu-interactive-card-table

Conversation

@wait4xx

@wait4xx wait4xx commented May 14, 2026

Copy link
Copy Markdown

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 table components.
Non-table markdown is preserved in card markdown elements with full syntax
support (headings, blockquotes, inline code, code blocks).

Before / After

Before After
Contains tables text — raw markdown source displayed interactive card (JSON 2.0) — native table + full markdown rendering
No tables post (unchanged) post (unchanged)
Plain text text (unchanged) text (unchanged)

Changes

File Change
gateway/platforms/feishu.py ~230 lines added

New 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 safeguards

Modified functions:

  • _build_outbound_payload() — route table content to interactive cards
  • send() — add interactive → text fallback on API failure

Safety

  • Tables inside fenced code blocks are not parsed
  • Card JSON size limited to 100KB (Feishu API limit)
  • Max 5 tables per card, 50 columns per table
  • Full fallback chain: interactive card → text on any send failure
  • Non-table messages (post, text) completely unaffected

Test Plan

  • Verified single table renders correctly in Feishu DM
  • Verified mixed content (text + table + text) renders correctly
  • Verified 4 tables + markdown + code blocks + separators in one card
  • Verified tables inside code blocks are not parsed (preserved as text)
  • Verified non-table markdown messages still use post type (unchanged)
  • Verified plain text messages still use text type (unchanged)
  • Verified Card JSON 2.0 renders headings, blockquotes, inline code, code blocks natively

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/feishu Feishu / Lark adapter labels May 14, 2026
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
@wait4xx wait4xx force-pushed the fix/feishu-interactive-card-table branch from ea38aae to 8605a29 Compare May 14, 2026 05:58
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 type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feishu channel displays markdown tables as raw source code instead of rendering them

2 participants