feat(wechat): add Intent Transaction Layer with unified task schema

Introduce Draft → Confirm → Commit flow for WeChat schedule intents behind
feature flags, plus h5_tasks dual-write/read aggregation and rollout scripts
so reminders and automations get explicit user confirmation before persisting.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-24 15:59:17 +08:00
parent b93c92a3e2
commit d58dc2a251
45 changed files with 4972 additions and 30 deletions
+39
View File
@@ -28,6 +28,7 @@ import {
} from './wechat/customer-service-deferred.mjs';
import { guardScheduleConfirmationReply } from './wechat/handlers/schedule-guard.mjs';
import { handleWechatScheduleIntent } from './wechat/handlers/schedule.mjs';
import { handleWechatIntentTransaction } from './wechat/handlers/intent-transaction.mjs';
import { handleWechatScheduledTaskIntent } from './wechat/handlers/scheduled-task.mjs';
import {
buildStatusText,
@@ -1598,6 +1599,8 @@ export function createWechatMpService({
submitSessionReply = null,
scheduleService = null,
scheduledTaskService = null,
intentDraftService = null,
taskUnifiedService = null,
wechatScheduleLlmConfigService = null,
llmProviderService = null,
chatIntentRouter = null,
@@ -3993,6 +3996,42 @@ export function createWechatMpService({
};
}
const intentTransactionReply =
intent.msgType === 'text' || intent.msgType === 'voice'
? await handleWechatIntentTransaction({
intent,
user: boundUser,
intentDraftService,
taskUnifiedService,
scheduleService,
scheduledTaskService,
logger,
}).catch((err) => {
logger.warn?.(
'WeChat MP intent transaction handling failed open:',
err instanceof Error ? err.message : err,
);
return null;
})
: null;
if (intentTransactionReply) {
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(intentTransactionReply),
};
}
const scheduledTaskReply =
intent.msgType === 'text' || intent.msgType === 'voice'
? await handleWechatScheduledTaskIntent({