Skip to content

feat(feishu): add render_mode for interactive card rendering - #46191

Open
kindle4send wants to merge 1 commit into
NousResearch:mainfrom
kindle4send:pr-feishu-render-mode
Open

feat(feishu): add render_mode for interactive card rendering#46191
kindle4send wants to merge 1 commit into
NousResearch:mainfrom
kindle4send:pr-feishu-render-mode

Conversation

@kindle4send

Copy link
Copy Markdown

Feishu post-type md elements cannot render markdown tables — sending table content as post causes blank messages. Interactive cards (schema 2.0) support full markdown including tables and code blocks.

This commit adds a render_mode setting that controls how outbound text messages are rendered:

  • "auto" (default): use interactive card when content contains code blocks or markdown tables; plain text / post otherwise.
  • "card": always use interactive card.
  • "raw": always use text/post (legacy behaviour, no cards).

Changes:

  • Add render_mode field to FeishuAdapterSettings with config/env loading.
  • Add _should_use_card() to detect code blocks and tables.
  • Add _build_card_payload() for schema 2.0 interactive card format.
  • Modify _build_outbound_payload() to route through card when appropriate.
  • Add interactive card fallback in send() (card → post → text).
  • Modify edit_message() to use PATCH API for card messages.
  • Bridge render_mode from config.yaml to adapter extra in config.py.
  • Add test_feishu_render_mode.py (23 tests).
  • Update existing post-row-splitting test to use render_mode=raw.

Config example:
feishu:
render_mode: auto # auto | card | raw

Or via env: FEISHU_RENDER_MODE=card

What does this PR do?

Related Issue

Fixes #

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

How to Test

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform:

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

  • This skill is broadly useful to most users (if bundled) — see Contributing Guide
  • SKILL.md follows the standard format (frontmatter, trigger conditions, steps, pitfalls)
  • No external dependencies that aren't already available (prefer stdlib, curl, existing Hermes tools)
  • I've tested the skill end-to-end: hermes --toolsets skills -q "Use the X skill to do Y"

Screenshots / Logs

Feishu post-type md elements cannot render markdown tables — sending
table content as post causes blank messages.  Interactive cards
(schema 2.0) support full markdown including tables and code blocks.

This commit adds a render_mode setting that controls how outbound text
messages are rendered:

  - "auto" (default): use interactive card when content contains code
    blocks or markdown tables; plain text / post otherwise.
  - "card": always use interactive card.
  - "raw": always use text/post (legacy behaviour, no cards).

Changes:
- Add render_mode field to FeishuAdapterSettings with config/env loading.
- Add _should_use_card() to detect code blocks and tables.
- Add _build_card_payload() for schema 2.0 interactive card format.
- Modify _build_outbound_payload() to route through card when appropriate.
- Add interactive card fallback in send() (card → post → text).
- Modify edit_message() to use PATCH API for card messages.
- Bridge render_mode from config.yaml to adapter extra in config.py.
- Add test_feishu_render_mode.py (23 tests).
- Update existing post-row-splitting test to use render_mode=raw.

Config example:
  feishu:
    render_mode: auto   # auto | card | raw

Or via env: FEISHU_RENDER_MODE=card
@alt-glitch alt-glitch added type/feature New feature or request 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 #39045 (feat(feishu): add configurable render modes for gateway replies) — same feishu.render_mode config with the identical auto | card | raw semantics routing tables/code blocks through schema 2.0 interactive cards, in the same files (gateway/config.py + feishu.py). Part of the saturated Feishu table-rendering cluster. Consolidating on the earlier open PR.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for addressing Feishu table and code-block rendering. The underlying current-main limitation is real: plugins/platforms/feishu/adapter.py:4524-4534 converts markdown tables to plain text.

Problems

  • The PR modifies the retired gateway/platforms/feishu.py path. Current main moved the adapter to plugins/platforms/feishu/adapter.py in 5600105478ffde29d7566b45421b100eaa29c4ef, so this needs a plugin-surface port rather than a direct apply.
  • The new PATCH decision is based on the new content type, while gateway/stream_consumer.py:1704-1775 edits an already-sent streaming preview. A text preview that later receives a table/code fence can be patched as a card without any retained original message-type state.
  • The new user-facing FEISHU_RENDER_MODE conflicts with AGENTS.md:102-107, which reserves .env for credentials and requires behavior settings in config.yaml.

Suggested changes

  • Port the implementation/tests to plugins/platforms/feishu/adapter.py, retain feishu.render_mode as config-only, and add a streaming text-preview-to-card regression test.
  • Add the render-mode behavior and card capability setup to website/docs/user-guide/messaging/feishu.md.

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-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 14, 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-contained Sweeper blast radius: contained — one narrow path / opt-in / few users 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/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants