Conversation
…evs#10019) QQ renders rich-media messages (msg_type=7) with the image above the text, so a text-then-image MessageChain arrives visually reversed. Markdown keeps the original component order, but the adapter dropped markdown whenever the chain carried an image and fell back to msg_type=7. When the chain carries only publicly hosted images plus text, build the markdown body with the image inlined and keep msg_type=2, skipping both the image download and the rich-media upload. Chains with local or base64 images keep using the rich-media path, because markdown images must reference a publicly reachable URL that the platform fetches itself. Both send paths are updated: the session send path and the reply path.
Contributor
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py" line_range="375-377" />
<code_context>
+ markdown_with_images = (
+ None
+ if use_md is False or stream is not None
+ else QQOfficialMessageEvent._build_markdown_with_public_images(
+ message_to_send
+ )
+ )
+
</code_context>
<issue_to_address>
**issue (broader_impact):** Multiple public images are split into separate MessageChains before `_build_markdown_with_public_images()` runs, because `_split_message_chain_by_media()` treats every second image as a new message. A chain such as `[Plain, Image1, Plain, Image2]` is therefore sent as multiple QQ messages instead of one markdown body preserving the original component order.
**Triggers:** When a message chain contains two or more image components.
**Suggested fix:** Detect an all-public-image chain before media splitting, or change the splitter to keep public images together for markdown rendering.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 1 finding to address first, and a public image URL is now passed directly to QQ in markdown, changing who fetches the resource and allowing malformed or unexpected URLs to affect the delivered message. Reverting stops future occurrences, but messages already sent and any external fetches or URL exposure cannot be undone.
Blocking findings: astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py:377
… intact Testing the markdown path against a real QQ bot surfaced two problems. 1. The generated markdown concatenated text and image with no line break, so QQ rendered the image inline and it overlapped the surrounding text. Each image now sits on its own block. 2. A chain carrying several public images was still split by media, producing one message per image. Markdown can carry several images in a single message, so markdown chains are no longer split. Tests assert the block separation and cover the multi-image case.
nina-ysml
force-pushed
the
feat/10019-qqofficial-markdown-images
branch
from
September 10, 2026 15:12
63dc7d9 to
27d7ffd
Compare
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
QQ renders rich-media messages (
msg_type=7) with the image above the text, so a[Plain, Image]MessageChain arrives visually reversed (#10019). Markdown keeps the original component order, but the adapter dropped markdown whenever the chain carried an image and fell back tomsg_type=7.Fix
When a chain carries only publicly hosted images (plus text), build the markdown body with the image inlined and keep
msg_type=2:_build_markdown_with_public_images()renderstext + in the original component order.At/Record/Video/File), and chains with local or base64 images, keep the existing rich-media path, because markdown images must reference a publicly reachable URL.Both send paths are covered:
_send_by_session_common(session / proactive send) and_post_send_one(reply).Scope note: ARK cards
The issue also asks to evaluate encapsulating ARK structured cards as a
MergeMessagesubstitute. Per the official docs (消息类型 scene support table), structured cards are receive-only for bots in both 单聊 and 群聊 (发 ❌ / 收 ✅), so ARK cannot replaceMergeMessagehere. That part is therefore not implemented in this PR.Tests
test_ws_group_markdown_with_public_image_embeds_image— session send pathtest_group_reply_markdown_with_public_image_embeds_image— reply pathBoth assert
msg_type == 2, nomediafield, the image URL present inmarkdown.content, and the text ordered before the image. Both fail before this change and pass after it. The other qqofficial tests are unaffected.Refs #10019
Summary by Sourcery
Preserve QQ message ordering by embedding publicly hosted images in markdown messages instead of falling back to rich media.
New Features:
Bug Fixes:
Enhancements:
Tests: