fix(wechat): avoid image_url session poison on report follow-ups

Store image-only WeChat messages without running Agent, scrub assistant image_url history, and retry historical-image failures with text-only prompts.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-15 08:21:28 +08:00
parent 4c2bc95462
commit 67b9478155
6 changed files with 147 additions and 127 deletions
+38
View File
@@ -1094,6 +1094,25 @@ export function isWechatHistoricalImageSessionError(message) {
);
}
export const WECHAT_IMAGE_STORED_ACK_TEXT =
'已收到图片。请直接告诉我接下来要做什么,例如:解读报告并生成页面。';
export function prepareWechatIntentForHistoricalImageRetry(intent) {
if (!intent || typeof intent !== 'object') return intent;
const imageUrl = String(intent.media?.publicUrl ?? '').trim();
const agentText = String(intent.agentText ?? '').trim();
if (imageUrl && !agentText.includes(imageUrl)) {
intent.agentText = agentText
? `${agentText}\n\n[附件图片]: ${imageUrl}`
: `[附件图片]: ${imageUrl}`;
}
delete intent.media;
delete intent.attachment;
delete intent.recentMediaItems;
delete intent.recentMediaBatchId;
return intent;
}
export function isRecoverableWechatAgentSessionError(message) {
const normalized = String(message ?? '').trim();
if (!normalized) return false;
@@ -3157,6 +3176,9 @@ export function createWechatMpService({
sessionId = route.sessionId;
await ensureSessionProvider(sessionId);
await rememberWechatUserContext(sessionId, user, { forceBootstrap: route.isNewSession });
if (historicalImageError) {
prepareWechatIntentForHistoricalImageRetry(intent);
}
const retryId = crypto.randomUUID();
const retryStartedAt = Date.now();
const retryPageContinuation = sessionPageContinuation && !historicalImageError;
@@ -3683,6 +3705,22 @@ export function createWechatMpService({
};
intent.agentText = `[图片1]: ${persisted.publicUrl}`;
rememberRecentMedia(inbound.fromUserName, intent);
await persistIntentDetail({ intent, userId: boundUser.userId, rawXmlHash });
if (inbound.msgId && typeof userAuth.finishWechatMpMessage === 'function') {
await userAuth.finishWechatMpMessage({
appId: config.appId,
openid: inbound.fromUserName,
msgId: inbound.msgId,
status: 'done',
agentSessionId: null,
});
}
return {
ok: true,
status: 200,
contentType: 'application/xml; charset=utf-8',
body: await buildPassiveReplyBody(WECHAT_IMAGE_STORED_ACK_TEXT),
};
} catch (error) {
await persistIntentDetail({ intent, userId: boundUser.userId, rawXmlHash });
return {