e13df82021
Memind CI / Test, build, and release guards (push) Failing after 14m19s
Stop ITL regex from intercepting new messages before Agent execution; move scheduled task and schedule write confirmation to MCP tool calls with draft commit on 确认. Co-authored-by: Cursor <cursoragent@cursor.com>
151 lines
4.5 KiB
JavaScript
151 lines
4.5 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { handleWechatIntentTransaction } from './intent-transaction.mjs';
|
|
|
|
function createDraftStore(initial = null) {
|
|
let pending = initial;
|
|
return {
|
|
async getPendingDraft(userId) {
|
|
return pending?.userId === userId ? pending : null;
|
|
},
|
|
async createDraft(payload) {
|
|
pending = {
|
|
id: 'draft-1',
|
|
userId: payload.userId,
|
|
layer: payload.layer,
|
|
draftType: payload.draftType,
|
|
actionLevel: payload.actionLevel,
|
|
title: payload.title,
|
|
payload: payload.payload,
|
|
cardText: payload.cardText,
|
|
status: 'draft',
|
|
};
|
|
return pending;
|
|
},
|
|
async cancelDraft(id, userId) {
|
|
if (pending?.id === id && pending.userId === userId) pending = null;
|
|
return { id, status: 'cancelled' };
|
|
},
|
|
async markDraftCommitted(id, userId, committedRef) {
|
|
if (pending?.id === id && pending.userId === userId) {
|
|
pending = { ...pending, status: 'committed', committedRef };
|
|
}
|
|
return pending;
|
|
},
|
|
};
|
|
}
|
|
|
|
function createScheduleService() {
|
|
return {
|
|
async createItem(payload) {
|
|
return { id: 'item-1', ...payload };
|
|
},
|
|
async createReminder(payload) {
|
|
return { id: 'reminder-1', ...payload };
|
|
},
|
|
};
|
|
}
|
|
|
|
const enabledEnv = { H5_INTENT_TRANSACTION_ENABLED: '1', H5_DEFAULT_TIMEZONE: 'Asia/Shanghai' };
|
|
|
|
test('intent transaction returns null when feature disabled', async () => {
|
|
const reply = await handleWechatIntentTransaction({
|
|
intent: { agentText: '下午2点半提醒我开会', msgId: 'm1' },
|
|
user: { userId: 'user-1' },
|
|
intentDraftService: createDraftStore(),
|
|
scheduleService: createScheduleService(),
|
|
env: { H5_INTENT_TRANSACTION_ENABLED: '0' },
|
|
});
|
|
assert.equal(reply, null);
|
|
});
|
|
|
|
test('intent transaction passes through new messages to goose', async () => {
|
|
const drafts = createDraftStore();
|
|
const reply = await handleWechatIntentTransaction({
|
|
intent: { agentText: '下午2点半提醒我开项目计划例会', msgId: 'm2' },
|
|
user: { userId: 'user-1' },
|
|
intentDraftService: drafts,
|
|
scheduleService: createScheduleService(),
|
|
env: enabledEnv,
|
|
});
|
|
assert.equal(reply, null);
|
|
assert.equal(await drafts.getPendingDraft('user-1'), null);
|
|
});
|
|
|
|
test('intent transaction passes through page generation with auto refresh wording', async () => {
|
|
const reply = await handleWechatIntentTransaction({
|
|
intent: {
|
|
agentText: '我想帮我做一个页面,页面上每天自动更新天气',
|
|
msgId: 'm-page',
|
|
},
|
|
user: { userId: 'user-1' },
|
|
intentDraftService: createDraftStore(),
|
|
scheduleService: createScheduleService(),
|
|
env: enabledEnv,
|
|
});
|
|
assert.equal(reply, null);
|
|
});
|
|
|
|
test('intent transaction commits pending draft after user confirms', async () => {
|
|
const drafts = createDraftStore({
|
|
id: 'draft-1',
|
|
userId: 'user-1',
|
|
layer: 'L1',
|
|
draftType: 'timed_reminder',
|
|
title: '项目计划例会',
|
|
status: 'draft',
|
|
payload: {
|
|
title: '项目计划例会',
|
|
remindLocal: '2026-08-28 14:30',
|
|
hour: 14,
|
|
minute: 30,
|
|
recurrence: 'once',
|
|
sourceChannel: 'agent',
|
|
},
|
|
});
|
|
const scheduleService = createScheduleService();
|
|
const calls = [];
|
|
scheduleService.createItem = async (payload) => {
|
|
calls.push(['createItem', payload.title]);
|
|
return { id: 'item-1', ...payload };
|
|
};
|
|
scheduleService.createReminder = async (payload) => {
|
|
calls.push(['createReminder', payload.itemId]);
|
|
return { id: 'reminder-1', ...payload };
|
|
};
|
|
|
|
const reply = await handleWechatIntentTransaction({
|
|
intent: { agentText: '确认', msgId: 'm4' },
|
|
user: { userId: 'user-1' },
|
|
intentDraftService: drafts,
|
|
scheduleService,
|
|
env: enabledEnv,
|
|
});
|
|
assert.match(reply, /已设置提醒/);
|
|
assert.equal(calls.length, 2);
|
|
});
|
|
|
|
test('intent transaction cancels pending draft', async () => {
|
|
const drafts = createDraftStore({
|
|
id: 'draft-1',
|
|
userId: 'user-1',
|
|
layer: 'L2',
|
|
draftType: 'agent_tool',
|
|
title: '定时任务',
|
|
status: 'draft',
|
|
payload: {
|
|
toolName: 'scheduled_task_create',
|
|
toolArgs: { taskSpec: '做新闻页面', hour: 6 },
|
|
},
|
|
});
|
|
const reply = await handleWechatIntentTransaction({
|
|
intent: { agentText: '取消', msgId: 'm5' },
|
|
user: { userId: 'user-1' },
|
|
intentDraftService: drafts,
|
|
scheduleService: createScheduleService(),
|
|
env: enabledEnv,
|
|
});
|
|
assert.match(reply, /已取消/);
|
|
assert.equal(await drafts.getPendingDraft('user-1'), null);
|
|
});
|