Skip to content

feat(feishu): render markdown tables via Card-Kit 2.0 interactive cards - #79410

Open
foottube wants to merge 2 commits into
NousResearch:mainfrom
foottube:feat/feishu-card-kit-tables
Open

foottube wants to merge 2 commits into
NousResearch:mainfrom
foottube:feat/feishu-card-kit-tables

Conversation

@foottube

@foottube foottube commented Aug 5, 2026

Copy link
Copy Markdown

What does this PR do?

Feishu post-type messages with tag: "md" elements do not render GitHub-style pipe tables — table content arrives as raw or dropped markup. This PR detects markdown table blocks in outbound messages and renders them as interactive cards using the Card-Kit 2.0 native table component, the only stable table rendering path in Feishu. Prose around a table is preserved as markdown card elements in the same card.

Type of Change

  • ✨ New feature (non-breaking change that adds functionality)
  • ✅ Tests (adding or improving test coverage)

Changes Made

  • plugins/platforms/feishu/adapter.py
    • Detect GFM pipe tables in _build_outbound_payload before the generic markdown path
    • Build Card-Kit 2.0 interactive cards (schema: "2.0") with native table elements (column-keyed rows) for multi-column tables
    • Fall back to an ASCII code-fence table inside a post message for single-column/degenerate tables or card build failures
    • New config toggle platforms.feishu.extra.table_mode: "card" (default, Card-Kit) | "ascii" (always ASCII code-fence)
    • _build_outbound_payload reads the table mode defensively (getattr with a "card" default) so it keeps working on bare instances, per the test contract in tests/gateway/test_feishu_table_markdown.py
  • tests/gateway/test_feishu.py
    • test_send_uses_interactive_card_for_markdown_table: asserts msg_type=interactive, schema: "2.0", and a native table element with the expected column-keyed rows
  • tests/gateway/test_feishu_table_markdown.py

How to Test

  1. Configure the Feishu platform (default settings, or explicitly platforms.feishu.extra.table_mode: card)
  2. Send a message containing a markdown pipe table, e.g. | A | B |\n|---|---|\n| 1 | 2 |
  3. The message arrives as an interactive card with a rendered table; surrounding prose renders as card markdown
  4. Set table_mode: ascii and repeat — the table arrives as a code-fenced ASCII table inside a post message
  5. Run the adapter tests:
    • python -m pytest tests/gateway/test_feishu.py tests/gateway/test_feishu_table_markdown.py -q (79 passed)

Relationship to #52786 and Existing Similar PRs

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (feat(feishu):)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this feature (no unrelated commits)
  • I've run the relevant tests and they pass: tests/gateway/test_feishu.py + tests/gateway/test_feishu_table_markdown.py 79/79; tests/gateway/ full directory 4847 passed (4 pre-existing failures in test_feishu_approval_buttons.py, test_discord_send.py, test_session_store_prune.py are unrelated to this PR — those files are untouched)
  • I've added tests for my changes
  • I've tested on my platform: Ubuntu 22.04 (Linux) via a live Feishu gateway

Documentation & Housekeeping

  • I've updated relevant documentation (docstrings) — N/A for README/docs
  • cli-config.yaml.example — N/A: the new key is a per-platform extra passthrough (same mechanism as existing keys such as require_mention)
  • I've updated CONTRIBUTING.md or AGENTS.md — N/A (no architecture or workflow change)
  • I've considered cross-platform impact — N/A (pure Python, no OS-specific code)
  • I've updated tool descriptions/schemas — N/A (no tool behavior change)

Feishu post-type `md` elements do not render GitHub-style pipe tables, so
agent responses containing tables arrive as raw or dropped markup. Detect
markdown table blocks in outbound content and render them as interactive
cards using the Card-Kit 2.0 native `table` component — the only stable
table rendering path in Feishu. Surrounding prose is preserved as
`markdown` card elements.

- Table card uses schema 2.0 with column-keyed rows
- Single-column or degenerate tables fall back to an ASCII code-fence
  table inside a post message
- Card build failures fall back to the same ASCII path
- Configurable via platforms.feishu.extra.table_mode: 'card' (default)
  or 'ascii' to skip Card-Kit entirely
- `_build_outbound_payload` reads table mode defensively (getattr with a
  'card' default) so it keeps working on bare instances per the test
  contract in tests/gateway/test_feishu_table_markdown.py

Tests:
- Add test_send_uses_interactive_card_for_markdown_table asserting
  msg_type=interactive, schema 2.0 and a native table element
- Update tests/gateway/test_feishu_table_markdown.py: the NousResearch#52786 intent
  (never downgrade a table to plain text) is preserved; the default
  table_mode now asserts the interactive card path, and ascii mode
  asserts the post + ASCII code-fence path
@alt-glitch alt-glitch added type/feature New feature or request comp/plugins Plugin system and bundled plugins platform/feishu Feishu / Lark adapter P3 Low — cosmetic, nice to have duplicate This issue or pull request already exists labels Aug 5, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

This was generated by AI during triage.

Duplicate of #12114: both route Feishu markdown tables to Card 2.0 interactive cards using native table elements.

@foottube

foottube commented Aug 5, 2026

Copy link
Copy Markdown
Author

Thanks for the triage note. I searched existing PRs (including #12114) before opening this one, and I'd respectfully push back on the duplicate flag — the two PRs are not on comparable bases:

For reference, the same stale-path issue applies to #46727 and #38453 (both modify gateway/platforms/feishu.py), and #61496/#62926 target the current path but ship no tests. If maintainers prefer to consolidate the surviving implementations, I'm happy to rebase or coordinate — otherwise, could this be re-checked?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have platform/feishu Feishu / Lark adapter type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants