feat(gateway): render markdown tables as native CardKit v2 table comp… - #48334
feat(gateway): render markdown tables as native CardKit v2 table comp…#48334protectione055 wants to merge 1 commit into
Conversation
…onents in Feishu Feishu's `md` tag does not render markdown tables, causing messages with tables to render blank on the client. This commit adds CardKit v2 table rendering as the primary rendering path, with a multi-tier fallback to code_block post rows for alignment preservation. This implementation is based on the approach pioneered by chapaofan/Hermes-feishu-to-table (https://github.com/chapaofan/Hermes-feishu-to-table) which solved the same problem with CardKit v2 table components. Co-authored-by: chapaofan <chapaofan@users.noreply.github.com>
|
Duplicate of #12114 — same feature, same mechanism: render markdown tables as native Feishu CardKit v2 |
Thanks for the review! A few points on why I believe this PR has value beyond #12114: Key differences from #12114
Happy to incorporate feedback or rebase if maintainers prefer a different direction. |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for the native-table approach. Current main still sends detected Markdown tables as plain text at plugins/platforms/feishu/adapter.py:4528-4530, so the feature premise remains valid.
Problems
- The claimed delivery fallback is unreachable for a rejected interactive card: PR head
gateway/platforms/feishu.py:4573-4574returnsinteractive, but the unchanged fallback conditions in the same head only acceptmsg_type == "post"(:2075,:2086,:2124). _parse_markdown_table()has no fenced-code state and starts a table for any pipe row (gateway/platforms/feishu.py:225-230), so pipe rows inside a fenced code block are converted despite the stated fence-aware behavior.- The PR adds no tests for table payloads, fenced code, or interactive-card rejection.
- The adapter moved to
plugins/platforms/feishu/adapter.pyin560010547; this branch modifies the old path and is currently dirty.
Suggested changes
- Port the focused behavior to the bundled plugin, add interactive rejection fallback in both send and edit paths, and cover the parser and fallback matrix in
tests/gateway/test_feishu.py.
Automated hermes-sweeper review.
| table_lines = [] | ||
|
|
||
| for line in lines: | ||
| if _MARKDOWN_TABLE_LINE_RE.match(line): |
There was a problem hiding this comment.
This starts a native table for any pipe-delimited row, including rows inside a fenced code block because this parser has no fence state. Require a GFM header-plus-divider sequence and track fences before converting segments.
| # Force plain text for anything that looks like a markdown table. | ||
| # 1. Try CardKit v2 interactive card with native table rendering first | ||
| card = _build_interactive_card_with_tables(content) | ||
| if card is not None: |
There was a problem hiding this comment.
This return makes the later post/code-block branch unreachable for every parsed table. The send/edit fallback code still only handles msg_type == "post", so an API-rejected interactive card has no delivery fallback; add an interactive rejection path in both send and edit flows.
What changed and why
Feishu's
mdtag does not render markdown tables, causing messages with tables to render blank on the client. This PR adds CardKit v2 table rendering as the primary rendering path, with a multi-tier fallback.Before: Any message containing markdown tables was force-sent as plain text — loss of table structure, no alignment, no formatting.
After: A 3-tier dispatch in
_build_outbound_payload:tablecomponent — tables render properly with column headers and aligned rowsHow to test
hermes gateway runlocally with Feishu configuredPlatforms tested
Attribution
This implementation is based on the approach pioneered by chapaofan/Hermes-feishu-to-table.