Skip to content

fix(feishu): route markdown through Card 2.0 interactive cards (v0.18.2 port) - #68507

Closed
Mr8rock wants to merge 1 commit into
NousResearch:mainfrom
Mr8rock:fix/feishu-markdown-card-v2-v0.18
Closed

Mr8rock wants to merge 1 commit into
NousResearch:mainfrom
Mr8rock:fix/feishu-markdown-card-v2-v0.18

Conversation

@Mr8rock

@Mr8rock Mr8rock commented Jul 21, 2026

Copy link
Copy Markdown

Summary

Ports the Card 2.0 markdown fix from #45036 to Hermes v0.18.2 via manual port (not cherry-pick) per the sweeper review on #45036 comment 4969941933.

The original PR was opened against the 422-line pre-v0.17.0 gateway/platforms/feishu.py. After release 9de9c25f6 (and the file-move commit referenced by the sweeper) the active adapter is plugins/platforms/feishu/adapter.py (5662 lines in v0.18.2). A cherry-pick of the original commit fails because the source path no longer exists.

What changed (in plugins/platforms/feishu/adapter.py)

  • _build_outbound_payload now routes markdown through Feishu Card 2.0 (schema: "2.0", tag: "markdown") — the full CommonMark renderer — instead of the stripped-down tag: "md" post element that silently drops tables, code blocks, lists, headings, italic, strikethrough, and blockquotes.
  • Plain prose (no markdown hints) still goes as plain text — no behavior change for non-markdown messages.
  • _POST_CONTENT_INVALID_RE extended to detect card-rejection errors ("invalid card content" / "invalid content format").
  • 3 fallback sites in the send/edit pipeline now treat both "post" and "interactive" as fallback-eligible (msg_type in ("post", "interactive")).

What was deliberately not changed

Per the sweeper review:

  • _build_markdown_post_rows is preserved as-is. It is still live — referenced by _build_post_payload() and _build_media_post_payload() for media captions. The original PR rewrote it, but the sweeper review flagged this as out of scope. No caption regression test was added because no caption behavior changed.
  • _build_markdown_post_payload is also untouched; cards are not used for media captions.

Tests

pytest tests/gateway/test_feishu.py208 passed on clean v0.18.2 (HEAD 8e734810d).

  • 6 assertions in _build_outbound_payload consumers updated to expect msg_type="interactive" and Card 2.0 schema ({"schema": "2.0", "body": {"elements": [{"tag": "markdown", "content": ...}]}}) instead of post rows.
  • All _build_post_payload unit tests untouched (the helper still serves media captions).

Why a separate PR (vs. reviving #45036)

#45036's diff targets the old gateway/platforms/feishu.py path, which no longer exists in main. The fix has been a saturated-cluster casualty (tracking issue #27469, canonical partial fix #12114) — opening a fresh PR with a clean rebase on current main and a body that links the original avoids the duplicate-closure risk and gives maintainers a diff that actually applies.

Refs

….2 port)

Port of the Card 2.0 markdown fix from PR NousResearch#45036 (#30bb6d078) to Hermes
v0.18.2 where the Feishu adapter moved from gateway/platforms/feishu.py
to plugins/platforms/feishu/adapter.py (5662 lines).

The original PR was opened against the 422-line pre-v0.17.0 adapter.
After the rename in release commit 9de9c25 (v0.18.0 chore: release),
the diff no longer matches any tracked file — even though the underlying
bug (tag:"md" post renderer doesn't support tables/code blocks/lists/
headings/italic/strikethrough/blockquotes) persists in main and breaks
Feishu users.

Fix:
  * _build_outbound_payload routes markdown content through Card 2.0
    (schema: "2.0", tag: "markdown") — Feishu's full CommonMark renderer.
  * Plain prose still goes as plain text.
  * _POST_CONTENT_INVALID_RE extended to detect card-rejection errors
    ("invalid card content" / "invalid content format") so the existing
    send/edit fallback pipeline catches them and falls back to text.
  * 3 fallback sites in the send pipeline now treat both "post" and
    "interactive" as fall-back-eligible message types.

Tests:
  * 6 existing assertions updated to expect msg_type="interactive" and
    Card 2.0 schema instead of post rows.
  * _build_post_payload unit tests untouched (helper still used by media
    captions and edit fallback).
  * 208/208 tests pass on clean v0.18.2 (8e73481).

Refs:
  * PR NousResearch#45036 — original fix (still open, never merged)
  * Issue NousResearch#27469 — saturated cluster tracker
  * Issue NousResearch#12114 — canonical "tag:\"table\"" partial fix
@Mr8rock

Mr8rock commented Jul 21, 2026

Copy link
Copy Markdown
Author

cc @hermes-sweeper

Manual port of #45036 to current main (base c9c9bb33fc, parent of head). Drops the _build_markdown_post_rows rewrite per your earlier note on #45036 — that helper is preserved as-is and still serves media captions via _build_post_payload() / _build_media_post_payload().

What this PR changes:

  • _build_outbound_payload routes markdown through Card 2.0 (schema: "2.0", tag: "markdown")
  • Plain prose still dispatched as msg_type: text
  • _POST_CONTENT_INVALID_RE extended to catch card-rejection errors
  • 3 fallback sites treat both "post" and "interactive" as fallback-eligible
  • 210 tests passing (tests/gateway/test_feishu.py)

This is a manual port, not a cherry-pick — per your guidance on #45036.

Diff: 2 files, +67 / -44. Branch: Mr8rock:fix/feishu-markdown-card-v2-v0.18.

Will keep an eye on #27469 cluster for any reviewer-consolidation signal.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins platform/feishu Feishu / Lark adapter labels Jul 21, 2026
@alt-glitch

Copy link
Copy Markdown

This was generated by AI during triage.

Related: #68084 already implements the current-path table-only Card 2.0 route. This PR instead sends all detected Markdown through an interactive card, so these are competing scopes rather than duplicates.

@Mr8rock

Mr8rock commented Jul 21, 2026

Copy link
Copy Markdown
Author

Thanks @alt-glitch. Noted — #68121 (post+md path) takes precedence here.

Will leave #68507 open as a Card 2.0 fallback in case #68121 turns up regressions on the markdown table / mixed-content paths. No further pushes from my side; not adding noise to the review queue.

Closing the loop on this thread. Will re-engage if I see regression reports.

@teknium1

Copy link
Copy Markdown
Collaborator

Thanks for the careful current-path port and for preserving the media-caption post builder.

Automated hermes-sweeper review found the user-visible Markdown/table routing issue is already implemented on main through the supported native post/md route rather than Card 2.0:

  • plugins/platforms/feishu/adapter.py:4587-4604 routes recognized Markdown, including tables, through post and _build_markdown_post_payload().
  • tests/gateway/test_feishu_table_markdown.py:66-125 covers both table-only and mixed prose/table content staying on the Markdown post path with content preserved.
  • The implementation landed in a660630986 (fix(feishu): render markdown tables via post+md, not text downgrade) and is in release v2026.7.20 via merged PR fix(feishu): render markdown tables via post+md, remove force-text downgrade #68121.

Closing as implemented on main.

@teknium1 teknium1 closed this Jul 30, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jul 30, 2026
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 P3 Low — cosmetic, nice to have platform/feishu Feishu / Lark adapter sweeper:implemented-on-main Sweeper: behavior already present on current main type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants