openclaw - ✅(Solved) Fix [Feishu] Tool-call-heavy replies create multiple cards after streaming completes [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#71977Fetched 2026-04-27 05:36:36
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
0
Author
Timeline (top)
cross-referenced ×3closed ×1commented ×1

Root Cause

In monitor.account-BSdTHVBX.js, the deliver callback at line ~1280:

if (info?.kind === "final" && streamingEnabled && useCard) {
    startStreaming();  // Creates NEW card
    ...
}

Each final segment has different text content, so deliveredFinalTexts dedup (line 1272) does not match. A new streaming card is created and immediately closed for each segment.

disableBlockStreaming: true is correctly set for Feishu (line 1366), so this is not a block streaming issue.

Fix Action

Fix / Workaround

Actual behavior

  • Card 1: Main reply with streaming effect (correct content) ✅
  • Cards 2-N: Each subsequent final delivery segment (tool result text) creates a new card, opened for ~1 second then closed ❌
  • Log shows dispatch complete (queuedFinal=true, replies=4~12)

PR fix notes

PR #72294: fix(feishu): suppress late streaming card finals

Description (problem / solution / changelog)

Summary

  • suppress distinct late final text deliveries after a Feishu streaming card has already closed for the current reply
  • keep media attachments deliverable even when the late text is suppressed
  • add regression coverage for the multi-final streaming-card closeout path

Fixes #71977

Validation

  • pnpm test extensions/feishu/src/reply-dispatcher.test.ts
  • pnpm check:changed

Notes

  • Branch commit includes only extensions/feishu/src/reply-dispatcher.ts and extensions/feishu/src/reply-dispatcher.test.ts.

Changed files

  • extensions/feishu/src/reply-dispatcher.test.ts (modified, +81/-0)
  • extensions/feishu/src/reply-dispatcher.ts (modified, +20/-5)

Code Example

if (info?.kind === "final" && streamingEnabled && useCard) {
    startStreaming();  // Creates NEW card
    ...
}
RAW_BUFFERClick to expand / collapse

Bug

When using Feishu with streaming: true and renderMode: "card", replies that involve multiple tool calls produce multiple cards (one streaming card + N additional cards).

Environment

  • OpenClaw: 2026.4.24 (cbcfdf6)
  • Feishu channel, WebSocket mode
  • Config: streaming: true, renderMode: "card", blockStreamingDefault: "off"

Reproduction

  1. Send a message that triggers 3+ tool calls (e.g. exec, read, edit)
  2. Observe Feishu output

Expected behavior

One streaming card with the complete reply.

Actual behavior

  • Card 1: Main reply with streaming effect (correct content) ✅
  • Cards 2-N: Each subsequent final delivery segment (tool result text) creates a new card, opened for ~1 second then closed ❌
  • Log shows dispatch complete (queuedFinal=true, replies=4~12)

Root cause analysis

In monitor.account-BSdTHVBX.js, the deliver callback at line ~1280:

if (info?.kind === "final" && streamingEnabled && useCard) {
    startStreaming();  // Creates NEW card
    ...
}

Each final segment has different text content, so deliveredFinalTexts dedup (line 1272) does not match. A new streaming card is created and immediately closed for each segment.

disableBlockStreaming: true is correctly set for Feishu (line 1366), so this is not a block streaming issue.

Impact

Extremely poor UX: user sees a correct streaming card followed by 5-10 additional 1-second cards containing intermediate content. The last card a user sees is NOT the final answer but an intermediate fragment, making conversation flow unreadable.

Related issues

  • #46872 (closed) — same symptom, supposedly fixed but not for multi-tool-call scenario
  • #65993 (closed) — same pattern reported by another user
  • #68491 (merged) — fixes onIdle/final race but not distinct-text finals
  • #55027 (open) — related block streaming limitation

Suggested fix

After the streaming card is closed, subsequent final segments should either:

  1. Be appended to the closed card (if Feishu Card Kit supports update-after-close)
  2. Be silently suppressed (streaming card already contains the full response)
  3. Be delivered as plain text messages instead of new cards

extent analysis

TL;DR

Modify the deliver callback to append or suppress subsequent final segments instead of creating new cards.

Guidance

  • Investigate Feishu Card Kit's support for updating cards after they are closed to determine the best approach for appending subsequent final segments.
  • Consider silently suppressing subsequent final segments if the streaming card already contains the full response.
  • Evaluate delivering subsequent final segments as plain text messages instead of new cards to improve user experience.
  • Review related issues (#46872, #65993, #68491, #55027) to ensure the chosen solution addresses all scenarios and edge cases.

Example

if (info?.kind === "final" && streamingEnabled && useCard) {
    if (streamingCardAlreadyExists) {
        // Append or update the existing streaming card if possible
        // or suppress the segment if the card already contains the full response
    } else {
        startStreaming();  // Creates NEW card
        ...
    }
}

Notes

The solution may depend on the specific capabilities of Feishu Card Kit and the desired user experience. Thorough testing will be necessary to ensure the chosen approach works correctly in all scenarios.

Recommendation

Apply a workaround to modify the deliver callback to append or suppress subsequent final segments, as upgrading to a fixed version is not mentioned in the issue. This approach allows for a targeted solution to the specific problem described.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

One streaming card with the complete reply.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING