Describe the bug
When FEISHU_CARD_STREAMING_MODE=card, messages are delivered as CardKit interactive cards but with no visible typewriter/streaming effect. The full reply appears all at once after the agent finishes generating.
Root cause
In card mode, the core creates a draft placeholder (message_id="draft") because GatewayAdapter::show_streaming_placeholder() returns false. All incremental edit_message commands for the draft are skipped by the Feishu adapter dispatch seam because "draft" fails is_valid_feishu_message_id.
The only delivery happens at turn end via try_send_initial_card, which creates a CardKit card with the full accumulated text at once — no incremental updates.
Expected behavior
CardKit cards should display a typewriter effect as the agent streams content, matching how auto mode behaves after post-to-card promotion.
Reproduction
- Set
FEISHU_CARD_STREAMING_MODE=card
- Send a long prompt to trigger multi-second agent response
- Observe: card appears with complete text at end, no incremental updates
Proposed fix
Make GatewayAdapter::show_streaming_placeholder() return true, so the core sends a real Feishu post first. The existing post-to-card promotion path in handle_card_edit/promote_and_respond takes over on the first edit, and subsequent edits stream through update_card_stream.
Relevant code
adapter.rs:751 — draft placeholder when show_streaming_placeholder() is false
gateway.rs:733 — show_streaming_placeholder returns false by default
feishu.rs:2538 — draft skip seam (is_valid_feishu_message_id)
feishu.rs:2642 — try_send_initial_card one-shot delivery
feishu.rs:2806 — handle_card_edit post-to-card promotion
Describe the bug
When
FEISHU_CARD_STREAMING_MODE=card, messages are delivered as CardKit interactive cards but with no visible typewriter/streaming effect. The full reply appears all at once after the agent finishes generating.Root cause
In
cardmode, the core creates a draft placeholder (message_id="draft") becauseGatewayAdapter::show_streaming_placeholder()returnsfalse. All incrementaledit_messagecommands for the draft are skipped by the Feishu adapter dispatch seam because"draft"failsis_valid_feishu_message_id.The only delivery happens at turn end via
try_send_initial_card, which creates a CardKit card with the full accumulated text at once — no incremental updates.Expected behavior
CardKit cards should display a typewriter effect as the agent streams content, matching how
automode behaves after post-to-card promotion.Reproduction
FEISHU_CARD_STREAMING_MODE=cardProposed fix
Make
GatewayAdapter::show_streaming_placeholder()returntrue, so the core sends a real Feishu post first. The existing post-to-card promotion path inhandle_card_edit/promote_and_respondtakes over on the first edit, and subsequent edits stream throughupdate_card_stream.Relevant code
adapter.rs:751— draft placeholder whenshow_streaming_placeholder()is falsegateway.rs:733—show_streaming_placeholderreturnsfalseby defaultfeishu.rs:2538— draft skip seam (is_valid_feishu_message_id)feishu.rs:2642—try_send_initial_cardone-shot deliveryfeishu.rs:2806—handle_card_editpost-to-card promotion