Skip to content

fix(feishu): use JSON 2.0 interactive cards for markdown messages (fixes table rendering) - #45907

Closed
whutlichao wants to merge 1 commit into
NousResearch:mainfrom
whutlichao:fix/feishu-markdown-cards-json2
Closed

fix(feishu): use JSON 2.0 interactive cards for markdown messages (fixes table rendering)#45907
whutlichao wants to merge 1 commit into
NousResearch:mainfrom
whutlichao:fix/feishu-markdown-cards-json2

Conversation

@whutlichao

Copy link
Copy Markdown

Summary

Feishu post-type md elements do not render markdown tables. When table content was detected, the code fell back to msg_type=text (plain text), losing all formatting entirely.

This PR switches markdown content to Feishu interactive cards (msg_type=interactive) using JSON 2.0 structure so the card's "tag": "markdown" element properly renders tables, code blocks, lists, headings, and all other markdown formatting.

Key changes:

  • Add _build_markdown_card_payload() — builds JSON 2.0 card with a markdown element
  • _build_outbound_payload() — returns interactive type for markdown content (including tables)
  • _feishu_send_with_retry() — expanded short-circuit to interactive type
  • send() / edit_message() — expanded fallback logic to interactive type

Background

Feishu card markdown elements support tables only in JSON 2.0 structure (with "schema": "2.0" and elements under body.elements). See: https://open.feishu.cn/document/feishu-cards/card-json-v2-components/content-components/rich-text

Testing

All 205 existing Feishu tests pass.

…xes table rendering)

Feishu post-type 'md' elements do not render markdown tables. When
table content was detected, the code fell back to plain text mode
(msg_type=text), losing all formatting entirely.

Switch to Feishu interactive cards (msg_type=interactive) with
JSON 2.0 structure so the card's "tag": "markdown" element properly
renders tables, code blocks, lists, headings and all other markdown.

Key changes:
- Add _build_markdown_card_payload() — builds JSON 2.0 card
- _build_outbound_payload() — returns interactive for markdown content
- _feishu_send_with_retry() — expanded short-circuit to interactive type
- send() / edit_message() — expanded fallback logic to interactive type

Feishu docs: tables in markdown elements require JSON 2.0:
https://open.feishu.cn/document/feishu-cards/card-json-v2-components/content-components/rich-text
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/feishu Feishu / Lark adapter P3 Low — cosmetic, nice to have duplicate This issue or pull request already exists labels Jun 14, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #12114 (canonical, earliest open) — same Feishu markdown-table fix via Card JSON 2.0 / interactive cards. Part of the saturated Feishu table-rendering cluster (#25453, #26429, etc.).

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for addressing a real Feishu formatting gap: current main still sends detected GFM tables as plain text at plugins/platforms/feishu/adapter.py:4524-4533.

Problems

  • The production diff targets gateway/platforms/feishu.py, but that adapter was moved to plugins/platforms/feishu/adapter.py by 5600105478ffde29d7566b45421b100eaa29c4ef; the patch does not apply to current main.
  • The changed tests contain no GFM pipe-table input and do not assert a table-capable payload. They only convert existing non-table markdown expectations to interactive.
  • _build_outbound_payload() changes all _MARKDOWN_HINT_RE content to interactive cards, while current main keeps non-table markdown on the post path (plugins/platforms/feishu/adapter.py:4531-4532). Canonical duplicate fix(feishu): render markdown tables via card v2 table component #12114 takes the narrower native Card JSON 2.0 table-component route.

Suggested changes

  • Port the change to the bundled Feishu plugin and add table-specific payload tests.
  • Preserve the post route for non-table markdown and verify the table rendering strategy against the canonical work.

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 14, 2026
@whutlichao whutlichao closed this by deleting the head repository Jul 29, 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 duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have 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