feat(feishu): Card 2.0 interactive cards for markdown content#12459
Closed
C-fog wants to merge 11 commits into
Closed
feat(feishu): Card 2.0 interactive cards for markdown content#12459C-fog wants to merge 11 commits into
C-fog wants to merge 11 commits into
Conversation
Add an optional require_mention field to FeishuGroupRule (default True). When set to False for a specific group, the @mention requirement is skipped so the bot responds to all messages from allowed senders. Recommended for private groups containing only the owner and the bot.
Cover four cases: - require_mention=False accepts messages without @mention - require_mention=True still requires @mention (default behavior) - Groups without explicit rule still require @mention (backward compat) - require_mention=False does not bypass sender allowlist/blacklist checks
The boot-md hook created a bare AIAgent() with no model, provider,
api_key or base_url. The internal auto-resolve chain discards the
resolved model, causing every boot-md API call to fail with:
400 — 'model: The model code cannot be empty.'
Fix by passing the resolved model and runtime_kwargs through the
gateway:startup hook context, then forwarding them to AIAgent via
**runtime_kwargs — matching the pattern used by every other AIAgent
call site in the gateway.
Also move the gateway:startup emit to after channel directory build
so that hooks can safely use send_message during startup.
Refs: NousResearch#5239
- Add _count_md_tables() and _split_md_by_table_limit() helpers - send(): pre-check table count, split into multiple messages when >5 - edit_message(): truncate to first 5 tables with notice when >5 - Improve fallback logging with error codes for diagnosis - Add 11 unit tests covering counting, splitting, and truncation Fixes: Card rejected by API when markdown content contains >5 tables, blind fallback to post format causes garbled table rendering.
c71c326 to
9182dc0
Compare
This was referenced Apr 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Upgrade the Feishu adapter to use Card 2.0 schema and add interactive card rendering for Markdown content (tables, code blocks, headings, etc.).
What changed (5 commits)
Refactor + Bug fix:
_send_chunk_with_fallbackfromsend()— centralizes the post→text fallback logic into a reusable method_build_outbound_payloadnow detects pure Markdown tables that were previously missed by_MARKDOWN_HINT_RE, causing them to render as raw|characters in text modeCard 2.0 upgrade:
use_interactive_cards_for_markdown: truein Feishu config (default:false)Why
Feishu
postmessages do not render Markdown tables — they display as raw|characters with no borders or alignment. Card 2.0 provides significantly better rendering for complex Markdown structures (tables, code blocks, headings, blockquotes, lists).Post vs Card 2.0 rendering comparison:
Top: Post message renders table as raw
|characters with no structure. Bottom: Card 2.0 renders a proper table with borders and alignment.Design decisions
use_interactive_cards_for_markdowndefaults tofalse; existing users are unaffected_COMPLEX_MARKDOWN_REonly matches block-level structures (tables, fenced code blocks, headings, blockquotes, lists, horizontal rules). Inline formatting (**bold**,*italic*,[links]()) continues to use post messages which handle them well_FEISHU_CARD_MAX_BYTES) are skipped before sending, avoiding wasted API calls. Falls back to post, then text"value": {...}to"behaviors": [{"type": "callback", "value": {...}}]. However,_on_card_action_triggerreadsaction.valuefrom the SDK event object, which is format-agnostic — Card 2.0behaviorsis transparent at the Feishu API level. No changes needed to callback handling codeedit_messagealso follows the interactive→post→text fallback chain. Cross-type editing is best-effort; in practice this rarely triggers since edit content matches the original send pathFiles changed
gateway/platforms/feishu.py— ~300 lines changedtests/gateway/test_feishu.py— 12 new test cases (116 total, all passing)Test plan
use_interactive_cards_for_markdown=false→ no behavior change from upstream