fix: isolate WeChat runtime delivery path

This commit is contained in:
john
2026-07-28 09:33:25 +08:00
parent 5a13950bc3
commit 7f9453433c
8 changed files with 226 additions and 9 deletions
+88
View File
@@ -333,6 +333,94 @@ test('Page Data requests always rotate away from an existing WeChat route', () =
assert.equal(shouldForceNewWechatAgentSession({ kind: 'chat.general' }, '换新会话'), true);
});
test('WeChat session reset acknowledges without sending the control text to Agent', async () => {
const token = 'token';
const timestamp = '1710000000';
const nonce = 'nonce';
const sentPayloads = [];
const finishedMessages = [];
let activeRoute = { agentSessionId: 'session-old' };
let startedSessions = 0;
let agentReplies = 0;
const sessionOrigins = [];
const service = createBoundWechatService({
token,
startAgentSession: async (input) => {
startedSessions += 1;
assert.equal(input.origin, 'wechat');
return { id: 'session-new' };
},
userAuth: {
async getWechatAgentRoute() {
return activeRoute;
},
async clearWechatAgentRoute() {
activeRoute = null;
},
async upsertWechatAgentRoute({ agentSessionId }) {
activeRoute = { agentSessionId };
},
async setSessionOrigin(sessionId, origin) {
sessionOrigins.push({ sessionId, origin });
},
async finishWechatMpMessage(input) {
finishedMessages.push(input);
},
},
sessionApiFetch: async (_sessionId, pathname) => {
if (pathname.includes('/reply')) {
agentReplies += 1;
throw new Error('session reset must not reach Agent');
}
return new Response('{}', {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
},
wechatFetch: async (url, init = {}) => {
if (String(url).includes('/cgi-bin/stable_token')) {
return new Response(JSON.stringify({
access_token: 'access-1',
expires_in: 7200,
}), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
}
if (String(url).includes('/cgi-bin/message/custom/send')) {
sentPayloads.push(JSON.parse(init.body));
return new Response(JSON.stringify({ errcode: 0, errmsg: 'ok' }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
}
throw new Error(`unexpected wechat url: ${url}`);
},
});
const result = await service.handleInboundMessage(
inboundXml({ content: '新会话' }),
{
timestamp,
nonce,
signature: signatureFor(token, timestamp, nonce),
},
);
await result.task;
assert.equal(startedSessions, 1);
assert.equal(agentReplies, 0);
assert.equal(activeRoute?.agentSessionId, 'session-new');
assert.deepEqual(sessionOrigins, [{
sessionId: 'session-new',
origin: 'wechat',
}]);
assert.match(sentPayloads[0]?.text?.content ?? '', /已切换到新会话/);
assert.equal(finishedMessages.at(-1)?.status, 'done');
assert.equal(finishedMessages.at(-1)?.agentSessionId, 'session-new');
});
test('WeChat Page Data repair intent receives the guarded repair workflow', () => {
assert.equal(isWechatPageDataTask('提交失败,数据没有保存成功'), true);
assert.equal(isWechatPageDataTask('修复问卷的 Page Data 绑定'), true);