Skip to content

fix: send file attachments before final stream reply in WeCom WebSocket channel#2729

Open
highland0971 wants to merge 1 commit intobytedance:mainfrom
highland0971:pr/fix-wecom-file-timing
Open

fix: send file attachments before final stream reply in WeCom WebSocket channel#2729
highland0971 wants to merge 1 commit intobytedance:mainfrom
highland0971:pr/fix-wecom-file-timing

Conversation

@highland0971
Copy link
Copy Markdown

PR 3: Fix WeCom File Attachment Timing — Send Before Final Stream Reply

Problem

On the WeCom (WeChat Work / 企业微信) channel, file attachments sent using
send_file after a final stream reply (reply_stream(is_final=True)) are
silently ignored by WeCom. The WeCom WebSocket protocol closes the stream
context after the final reply, so any subsequent send_file calls fail without
clear error feedback.

This means users receive the AI's text response but never receive the
associated file artifacts
generated by the agent.

Root Cause

The WeComChannel.on_send() method was structured as:

  1. Call self.send(msg) — which sends the text reply (including is_final=True)
  2. Iterate over msg.attachments and call self.send_file()
  3. Clear WebSocket context

When step 1 sends is_final=True, WeCom WebSocket closes the message context,
and step 2's file uploads are ignored.

Additionally, the send_file method itself also had an early return for
is_final=False messages, which blocked non-final attachments from being sent.

Fix

wecom.py — Reorder send sequence

  • File attachments are now sent BEFORE the final stream reply when
    msg.is_final=True.
  • For non-final messages, attachments continue to be sent after the reply
    (since the stream context remains open).
  • The WebSocket context clearing (_clear_ws_context) remains at the end.

New send order for final messages:

  1. Send file attachments (send_file)
  2. Send text reply (send / reply_stream(is_final=True))
  3. Clear WebSocket context

Testing

  • Verified in production: file artifacts now arrive alongside the AI's
    final response on WeCom.
  • No regression on non-WeCom channels (the fix is WeCom-specific).

Files Changed

  • backend/app/channels/wecom.py

…et channel

# PR 3: Fix WeCom File Attachment Timing — Send Before Final Stream Reply

## Problem

On the WeCom (WeChat Work / 企业微信) channel, file attachments sent using 
`send_file` after a final stream reply (`reply_stream(is_final=True)`) are 
**silently ignored** by WeCom. The WeCom WebSocket protocol closes the stream 
context after the final reply, so any subsequent `send_file` calls fail without 
clear error feedback.

This means users receive the AI's text response but **never receive the 
associated file artifacts** generated by the agent.

## Root Cause

The `WeComChannel.on_send()` method was structured as:
1. Call `self.send(msg)` — which sends the text reply (including `is_final=True`)
2. Iterate over `msg.attachments` and call `self.send_file()`
3. Clear WebSocket context

When step 1 sends `is_final=True`, WeCom WebSocket closes the message context, 
and step 2's file uploads are ignored.

Additionally, the `send_file` method itself also had an early return for 
`is_final=False` messages, which blocked non-final attachments from being sent.

## Fix

### wecom.py — Reorder send sequence
- **File attachments are now sent BEFORE the final stream reply** when 
  `msg.is_final=True`.
- For non-final messages, attachments continue to be sent after the reply 
  (since the stream context remains open).
- The WebSocket context clearing (`_clear_ws_context`) remains at the end.

New send order for final messages:
1. Send file attachments (`send_file`)
2. Send text reply (`send` / `reply_stream(is_final=True)`)
3. Clear WebSocket context

## Testing
- Verified in production: file artifacts now arrive alongside the AI's 
  final response on WeCom.
- No regression on non-WeCom channels (the fix is WeCom-specific).

## Files Changed
- `backend/app/channels/wecom.py`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant