Skip to content

feat(feishu): add opt-in Card v2 final responses - #50384

Closed
leavrcn wants to merge 8 commits into
NousResearch:mainfrom
leavrcn:local/restore-feishu-final-card-20260622
Closed

leavrcn wants to merge 8 commits into
NousResearch:mainfrom
leavrcn:local/restore-feishu-final-card-20260622

Conversation

@leavrcn

@leavrcn leavrcn commented Jun 21, 2026

Copy link
Copy Markdown

Summary

  • add a platform-neutral final-response document IR plus conservative Markdown parsing
  • render Feishu assistant final responses as Card JSON v2 behind platforms.feishu.extra.final_response_format: legacy | auto | card (default remains legacy)
  • enforce Feishu Card v2 bounds before transport: serialized request size, markdown element size, table count/columns/page size, and lossless multi-card partitioning
  • keep MEDIA:/unsupported attachments on the legacy path and support safe image-in-card final replies
  • prevent command, ephemeral, and unanchored thread/topic responses from leaking into the Card v2 path
  • make multi-card and legacy multi-chunk delivery lossless: once any part is visible, later failure reports PARTIALLY_DELIVERED and suppresses full-payload retry/fallback
  • document the new modes in English and Simplified Chinese

Safety / compatibility

  • no behavior change without the hermes_final_response semantic marker and explicit Feishu format configuration
  • invalid format values fall back to legacy
  • unanchored thread/topic responses never send an interactive card to the parent chat
  • unknown document blocks fail fast instead of being silently dropped
  • explicit FinalDeliveryState values are validated against SendResult.success

Verification

  • ruff, compileall, and git diff --check: passed
  • focused Feishu/Card/renderer/runtime suite: 349 passed (-n 0)
  • all tests/gateway/test_feishu*.py: 527 passed (-n 0)
  • real Feishu API smoke:
    • DM final response fetched back as interactive
    • multi-card CJK and anchored thread cases passed in the earlier smoke run
    • unanchored thread used receive_id_type=thread_id with a non-interactive legacy payload, never targeted the parent chat, and created no visible message on the historical-topic rejection
    • default/legacy mode fetched back as post
  • canonical full suite executed before the final conflict-free rebase in four scripts/run_tests.sh --slice I/4 shards:
    • 33 failures across 14 unrelated files in this root/live-profile environment
    • 2 shard-only failures passed immediately on isolated rerun
    • 28 failures across 10 files reproduced on that candidate's exact base
    • the remaining 3 are connected-home leakage from the live weixin profile in cron/Kanban tests; this branch does not modify those components
    • no Feishu/Card/renderer/final-delivery focused test failed
  • after rebasing all commits onto current origin/main, static checks, the 349-test focused suite, and the real Feishu smoke all passed again
  • late independent review blockers were closed with regression tests: mismatched direct tables degrade losslessly, public element limits are validated/clamped, string delivery states normalize to the enum before identity-based fallback decisions, public fenced-code parsing preserves trailing newlines, and ambiguous interactive timeouts (raised exceptions and returned-failure strings) suppress cross-format fallback

@leavrcn
leavrcn force-pushed the local/restore-feishu-final-card-20260622 branch from 8851d6f to 42eb42b Compare June 21, 2026 19:56
@alt-glitch alt-glitch added type/feature New feature or request comp/gateway Gateway runner, session dispatch, delivery platform/feishu Feishu / Lark adapter P2 Medium — degraded but workaround exists labels Jun 21, 2026
@leavrcn
leavrcn force-pushed the local/restore-feishu-final-card-20260622 branch from 42eb42b to 4efe81e Compare July 12, 2026 11:33
@leavrcn leavrcn changed the title feat(feishu): restore final response cards feat(feishu): add opt-in Card v2 final responses Jul 12, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Thanks for the opt-in Feishu implementation. The premise remains present on the inspected main: final text reaches BasePlatformAdapter._send_with_retry() at gateway/platforms/base.py:5029, while FeishuAdapter._build_outbound_payload() only selects legacy text/post payloads and deliberately sends Markdown tables as plain text at plugins/platforms/feishu/adapter.py:4524-4534.

The PR keeps activation in the existing platform-specific PlatformConfig.extra surface (gateway/config.py:476-477) and defaults the new behavior to legacy mode. Static inspection found no concrete correctness defect in the changed implementation. GitHub reports the branch mergeable, although it is behind the inspected checkout and should receive normal post-merge validation.

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-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 15, 2026
@leavrcn leavrcn closed this Sep 7, 2026
@leavrcn
leavrcn deleted the local/restore-feishu-final-card-20260622 branch September 7, 2026 17:24
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 P2 Medium — degraded but workaround exists platform/feishu Feishu / Lark adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform 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