Skip to content

feat(feishu): enable streaming card replies in thread/topic mode#45278

Closed
maoku-family wants to merge 1 commit intoopenclaw:mainfrom
mao-family:feat/feishu-streaming-in-threads
Closed

feat(feishu): enable streaming card replies in thread/topic mode#45278
maoku-family wants to merge 1 commit intoopenclaw:mainfrom
mao-family:feat/feishu-streaming-in-threads

Conversation

@maoku-family
Copy link
Copy Markdown

Summary

Remove the !threadReplyMode guard from streamingEnabled in reply-dispatcher.ts, enabling streaming card replies in Feishu topic/thread mode.

Problem

When threadReply: true is configured (topic group mode), streaming cards are disabled and responses fall back to plain text reply calls. This means users in topic groups don't get the streaming card UX that works in normal chats.

Change

-  // Card streaming may miss thread affinity in topic contexts; use direct replies there.
-  const streamingEnabled =
-    !threadReplyMode && account.config?.streaming !== false && renderMode !== "raw";
+  // Card streaming with rootId should route to topics correctly; enable for all modes.
+  const streamingEnabled =
+    account.config?.streaming !== false && renderMode !== "raw";

Why this is safe

The streaming card API already passes root_id for topic routing. The original guard was conservative — in practice, cards render correctly in topic groups.

Testing

Verified locally in a Feishu topic group with threadReply: true:

  • Streaming cards render correctly in topics
  • Cards are properly threaded under the correct topic
  • No regression in non-thread mode

Previously, streaming card replies were disabled when threadReply mode
was active (threadReplyMode === true). This was a conservative guard
added because card streaming might miss thread affinity.

In practice, the streaming card API already passes root_id correctly
for topic routing, so there is no functional reason to disable it.
Removing the !threadReplyMode guard allows streaming cards in topic
groups, providing a consistent UX across all reply modes.

Verified locally: streaming cards render correctly in Feishu topic
groups with threadReply enabled.
@openclaw-barnacle openclaw-barnacle Bot added channel: feishu Channel integration: feishu size: XS labels Mar 13, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 13, 2026

Greptile Summary

This PR removes the !threadReplyMode guard from streamingEnabled in reply-dispatcher.ts, enabling Feishu streaming card replies in topic/thread group mode (threadReply: true).

The change is safe for the most common scenario: when replyToMessageId is present, streaming-card.ts selects the reply send-mode with reply_in_thread: true, which the codebase already documents as the reliable routing path for cards in Feishu topics. The only edge case to be aware of is when replyToMessageId is absent but rootId is set — the root_create path is used, and streaming-card.ts explicitly notes that root_id may be silently ignored for card-id format references. The PR's new comment slightly overstates root_id reliability; a small documentation correction is suggested.

Confidence Score: 4/5

  • This PR is safe to merge; the functional change is correct for the common reply-to-message scenario, with only a minor documentation inconsistency.
  • The guard removal is minimal and well-scoped. The reply send-mode (triggered when replyToMessageId is present) reliably threads streaming cards in Feishu topics. The one-point deduction is for the inconsistency between the PR's new comment and the existing caveat in streaming-card.ts regarding root_id reliability in root_create mode — a non-critical documentation issue rather than a runtime risk.
  • No files require special attention beyond the minor comment update suggested in reply-dispatcher.ts.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/feishu/src/reply-dispatcher.ts
Line: 139-141

Comment:
**New comment contradicts existing `streaming-card.ts` caveat**

The updated comment states _"Card streaming with rootId should route to topics correctly"_, but `streaming-card.ts` lines 221–224 contain an explicit, opposing note:

```
// Prefer message.reply when we have a reply target — reply_in_thread
// reliably routes streaming cards into Feishu topics, whereas
// message.create with root_id may silently ignore root_id for card
// references (card_id format).
```

The `root_create` send-mode (used when `rootId` is set but `replyToMessageId` is absent) may **silently drop the `root_id`**, meaning the streaming card won't be threaded under the correct topic in that scenario. The change is safe for the common case where `replyToMessageId` is present (which selects the `reply` send-mode with `reply_in_thread: true`), but the justification comment overstates the reliability of `root_id` routing.

Consider updating the comment to reflect the nuance:

```suggestion
  // reply_in_thread reliably routes cards into topics; root_create path may silently
  // drop root_id for card references — but replyToMessageId is typically always set
  // in thread contexts, making this safe in practice.
  const streamingEnabled =
    account.config?.streaming !== false && renderMode !== "raw";
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 329bc5d

Comment on lines +139 to +141
// Card streaming with rootId should route to topics correctly; enable for all modes.
const streamingEnabled =
!threadReplyMode && account.config?.streaming !== false && renderMode !== "raw";
account.config?.streaming !== false && renderMode !== "raw";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New comment contradicts existing streaming-card.ts caveat

The updated comment states "Card streaming with rootId should route to topics correctly", but streaming-card.ts lines 221–224 contain an explicit, opposing note:

// Prefer message.reply when we have a reply target — reply_in_thread
// reliably routes streaming cards into Feishu topics, whereas
// message.create with root_id may silently ignore root_id for card
// references (card_id format).

The root_create send-mode (used when rootId is set but replyToMessageId is absent) may silently drop the root_id, meaning the streaming card won't be threaded under the correct topic in that scenario. The change is safe for the common case where replyToMessageId is present (which selects the reply send-mode with reply_in_thread: true), but the justification comment overstates the reliability of root_id routing.

Consider updating the comment to reflect the nuance:

Suggested change
// Card streaming with rootId should route to topics correctly; enable for all modes.
const streamingEnabled =
!threadReplyMode && account.config?.streaming !== false && renderMode !== "raw";
account.config?.streaming !== false && renderMode !== "raw";
// reply_in_thread reliably routes cards into topics; root_create path may silently
// drop root_id for card references — but replyToMessageId is typically always set
// in thread contexts, making this safe in practice.
const streamingEnabled =
account.config?.streaming !== false && renderMode !== "raw";
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/feishu/src/reply-dispatcher.ts
Line: 139-141

Comment:
**New comment contradicts existing `streaming-card.ts` caveat**

The updated comment states _"Card streaming with rootId should route to topics correctly"_, but `streaming-card.ts` lines 221–224 contain an explicit, opposing note:

```
// Prefer message.reply when we have a reply target — reply_in_thread
// reliably routes streaming cards into Feishu topics, whereas
// message.create with root_id may silently ignore root_id for card
// references (card_id format).
```

The `root_create` send-mode (used when `rootId` is set but `replyToMessageId` is absent) may **silently drop the `root_id`**, meaning the streaming card won't be threaded under the correct topic in that scenario. The change is safe for the common case where `replyToMessageId` is present (which selects the `reply` send-mode with `reply_in_thread: true`), but the justification comment overstates the reliability of `root_id` routing.

Consider updating the comment to reflect the nuance:

```suggestion
  // reply_in_thread reliably routes cards into topics; root_create path may silently
  // drop root_id for card references — but replyToMessageId is typically always set
  // in thread contexts, making this safe in practice.
  const streamingEnabled =
    account.config?.streaming !== false && renderMode !== "raw";
```

How can I resolve this? If you propose a fix, please make it concise.

@vincentkoc vincentkoc self-assigned this Apr 25, 2026
@vincentkoc vincentkoc added dedupe:child Duplicate issue/PR child in dedupe cluster close:superseded PR close reason labels Apr 25, 2026
@vincentkoc
Copy link
Copy Markdown
Member

Closing as superseded by #71542. The merged fix enables Feishu streaming cards for topic/thread replies and keeps the reply metadata (replyToMessageId, replyInThread, and rootId) covered by dispatcher tests.

Thanks for pushing the thread-mode path. If topic routing still misses affinity in a live Feishu room, reopen with the message/thread ids and we can narrow it to the send-mode layer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu close:superseded PR close reason dedupe:child Duplicate issue/PR child in dedupe cluster size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants