fix: check discord attachment size in _parse_message to reuse its image detection

Co-authored-by: cowagent <cow@cowagent.ai>
This commit is contained in:
zhayujieandcowagent committed 2026-10-16 12:26:25 +08:00
1 parent 8c439c9479
commit 13d489e1ce
2 files changed
+16 -12

No files matched your search

+9 -12
View File
@@ -306,12 +306,18 @@ class DiscordChannel(ChatChannel):
att = attachments[0]
content_type = (att.content_type or "").lower()
name = att.filename or str(att.id)
path = await self._download_attachment(att, name)
if not path:
return (None, None, "")
is_image = content_type.startswith("image/") or name.lower().endswith(
(".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp")
)
# attachment.save() buffers the whole body, so check the reported size first.
limit = MAX_IMAGE_BYTES if is_image else MAX_FILE_BYTES
size = getattr(att, "size", None)
if isinstance(size, int) and size > limit:
logger.warning(f"[Discord] attachment {name} is {size} bytes, over the {limit} limit; skipped")
return (None, None, "")
path = await self._download_attachment(att, name)
if not path:
return (None, None, "")
if is_image:
return (ContextType.IMAGE, path, text)
return (ContextType.FILE, path, text)
@@ -324,15 +330,6 @@ class DiscordChannel(ChatChannel):
async def _download_attachment(self, attachment, name: str):
"""Download a discord attachment into the local tmp dir; return path or None."""
try:
# attachment.save() buffers the whole body, and Discord reports the size up front:
# refuse an oversized upload instead of pulling it into memory (same caps as the
# other channels' inbound media).
is_image = (getattr(attachment, "content_type", None) or "").lower().startswith("image/")
limit = MAX_IMAGE_BYTES if is_image else MAX_FILE_BYTES
size = getattr(attachment, "size", None)
if isinstance(size, int) and size > limit:
logger.warning(f"[Discord] attachment {name} is {size} bytes, over the {limit} limit; skipped")
return None
tmp_dir = DiscordMessage.get_tmp_dir()
safe_name = re.sub(r"[^\w.\-]", "_", name)
# Prefix with attachment id to avoid name collisions
@@ -51,6 +51,13 @@ def test_oversized_image_uses_the_image_limit():
assert att.saved == []
def test_image_without_content_type_uses_the_image_limit():
att = _Attachment(MAX_IMAGE_BYTES + 1, content_type="", filename="big.png")
assert _parse(att) == (None, None, "")
assert att.saved == []
def test_attachment_within_the_limit_is_still_downloaded():
att = _Attachment(1024)