fix(wecom): raise the image upload cap to the platform's 10 MB (#8174)

* fix(wecom): raise the image upload cap to the platform's 10 MB

`send_file` capped images at 2 MB and files at 20 MB. 2 MB is the *voice*
limit in WeCom's aibot media-upload protocol; images are allowed up to 10 MB
(developer.work.weixin.qq.com/document/path/101917). Every 2-10 MB image was
therefore dropped before upload, and the turn arrived without its chart.

Raise the image cap to 10 MB. The 512 KiB chunk size keeps a 10 MB upload at
20 chunks, well under the protocol's 100-chunk limit.

* docs(changelog): record the WeCom image-cap fix

Adds the Unreleased -> Fixed -> channels entry for #8174 to CHANGELOG.md and
CHANGELOG_zh.md.
This commit is contained in:
mosifu 2026-11-12 17:16:42 +08:00 committed by GitHub
parent 416a0647a4
commit 51cc489c8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 77 additions and 1 deletions

View File

@ -60,6 +60,12 @@ This section accumulates work toward the **2.3.0** milestone
### Fixed
- **channels:** WeCom no longer drops images between 2 MB and 10 MB. The
adapter capped image uploads at 2 MB — the voice limit in the same protocol —
so a larger chart was skipped before upload and the turn arrived without it.
The cap now matches the platform's 10 MB for images; the 20 MB file limit is
unchanged. ([#8174])
- **threads:** Deleting a conversation on Windows no longer fails with
`Failed to delete local thread data.` when the workspace holds a file whose
path exceeds `MAX_PATH`. The thread directory is now resolved through the
@ -16341,3 +16347,4 @@ with **180 merged pull requests** since the first 2.0 milestone tag.
[#8126]: https://github.com/bytedance/deer-flow/pull/8126
[#8131]: https://github.com/bytedance/deer-flow/pull/8131
[#8151]: https://github.com/bytedance/deer-flow/pull/8151
[#8174]: https://github.com/bytedance/deer-flow/pull/8174

View File

@ -26,6 +26,9 @@
### 修复
- **通道:** 企业微信不再丢弃 2–10 MB 的图片。此前适配器把图片上限定为 2 MB(同一协议中语音的限制),
超出即在上传前被跳过,消息到达时缺少图片。现在图片上限与平台的 10 MB 对齐;普通文件 20 MB 的限制不变。([#8174])
- **通道:** WeCom 群聊中 `@机器人 /new` 这类带提及的命令现在按命令执行。WeCom 会把提及保留在
正文里,而命令识别要求裸的前导 `/`,于是群里的 `/new`、`/status` 被当成聊天轮次。现在仅在命令
识别时跳过前导提及;普通聊天保留提及,`/connect` 行为不变。与飞书、钉钉的处理一致。([#8118])
@ -12872,3 +12875,4 @@ DeerFlow 2.0 是围绕"超级智能体"框架的彻底重写,核心包含子
[#8064]: https://github.com/bytedance/deer-flow/pull/8064
[#8118]: https://github.com/bytedance/deer-flow/pull/8118
[#8126]: https://github.com/bytedance/deer-flow/pull/8126
[#8174]: https://github.com/bytedance/deer-flow/pull/8174

View File

@ -447,7 +447,11 @@ class WeComChannel(Channel):
return False
media_type = "image" if attachment.is_image else "file"
size_limit = 2 * 1024 * 1024 if attachment.is_image else 20 * 1024 * 1024
# aibot media upload limits: image 10 MB, voice 2 MB, video 10 MB,
# file 20 MB (https://developer.work.weixin.qq.com/document/path/101917).
# The image cap used to be 2 MB — the voice limit — which dropped every
# 2-10 MB image before it was uploaded.
size_limit = 10 * 1024 * 1024 if attachment.is_image else 20 * 1024 * 1024
if attachment.size > size_limit:
logger.warning(
"[WeCom] %s too large (%d bytes), skipping: %s",

View File

@ -1822,3 +1822,64 @@ def test_embedded_upload_retries_claim_collision(tmp_path, monkeypatch, channel_
advertised = "/mnt/user-data/uploads/report_2.pdf"
assert advertised in result.text
assert synced == ([] if mounted else [(advertised, payload)])
class TestWecomMediaSizeLimits:
"""WeCom's aibot media upload accepts images up to 10 MB.
The adapter used to cap images at 2 MB — the *voice* limit in the same
protocol — and silently skipped anything larger before uploading it, so a
2-10 MB chart never reached the user. See
https://developer.work.weixin.qq.com/document/path/101917
"""
@staticmethod
def _channel():
from types import SimpleNamespace
from app.channels.wecom import WeComChannel
channel = WeComChannel(MessageBus(), {})
channel._ws_client = SimpleNamespace(reply=AsyncMock())
channel._upload_media_ws = AsyncMock(return_value="media-1")
return channel
def test_image_above_two_megabytes_reaches_the_uploader(self, tmp_path):
channel = self._channel()
msg = _file_reply(tmp_path, channel_name="wecom")
channel._ws_frames[msg.thread_ts] = {"body": {"msgid": msg.thread_ts}}
channel._ws_stream_ids[msg.thread_ts] = "stream-1"
path = tmp_path / "chart.png"
path.write_bytes(b"\x89PNG\r\n\x1a\n")
attachment = ResolvedAttachment(
"/mnt/user-data/outputs/chart.png",
path,
"chart.png",
"image/png",
5 * 1024 * 1024,
True,
)
assert _run(channel.send_file(msg, attachment)) is True
channel._upload_media_ws.assert_awaited_once()
def test_image_above_the_platform_limit_is_still_skipped(self, tmp_path):
channel = self._channel()
msg = _file_reply(tmp_path, channel_name="wecom")
channel._ws_frames[msg.thread_ts] = {"body": {"msgid": msg.thread_ts}}
channel._ws_stream_ids[msg.thread_ts] = "stream-1"
path = tmp_path / "huge.png"
path.write_bytes(b"\x89PNG\r\n\x1a\n")
attachment = ResolvedAttachment(
"/mnt/user-data/outputs/huge.png",
path,
"huge.png",
"image/png",
11 * 1024 * 1024,
True,
)
assert _run(channel.send_file(msg, attachment)) is False
channel._upload_media_ws.assert_not_awaited()