Files
memind/scripts/verify-schedule-reminder-routing.mjs
T
john 9dfafb99ca
Memind CI / Test, build, and release guards (push) Successful in 3m43s
fix(schedule): harden reminder utterance routing for WeChat ITL
Expand ASR normalization and colloquial reminder parsing so simple timed reminders route to L1 confirm cards instead of the agent, and disable schedule-guard false failures when ITL is enabled.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-24 18:02:19 +08:00

109 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* Verify WeChat reminder utterances route to ITL timed_reminder (L1), not agent_schedule.
*/
import assert from 'node:assert/strict';
import { classifyUserIntent } from '../intent-classifier.mjs';
import { parseScheduleIntent, tryResolveTimedReminderIntent } from '../schedule-intent.mjs';
import { hasReminderSetupCue } from '../schedule-utterance-normalize.mjs';
const timezone = 'Asia/Shanghai';
const now = Date.UTC(2026, 7, 24, 9, 0, 0); // 2026-08-24 17:00 Asia/Shanghai
const matrix = [
{
text: '设置一个提醒,今天下午 17 :08要开会',
expect: { kind: 'timed_reminder', action: 'create_timed_reminder', title: '要开会', hour: 17, minute: 8 },
},
{
text: '设置每天1800提醒打卡',
expect: { kind: 'timed_reminder', action: 'create_timed_reminder', title: '打卡', recurrence: 'daily', hour: 18 },
},
{
text: '加个提醒明天9点开会',
expect: { kind: 'timed_reminder', action: 'create_timed_reminder', title: '开会', hour: 9 },
},
{
text: '添加提醒后天10点体检',
expect: { kind: 'timed_reminder', action: 'create_timed_reminder', title: '体检', hour: 10 },
},
{
text: '创建提醒明早6点跑步',
expect: { kind: 'timed_reminder', action: 'create_timed_reminder', title: '跑步', hour: 6 },
},
{
text: '备忘提醒下午3点交报告',
expect: { kind: 'timed_reminder', action: 'create_timed_reminder', title: '交报告', hour: 15 },
},
{
text: '安排一个提醒今晚8点',
expect: { kind: 'timed_reminder', action: 'create_timed_reminder', clarify: ['reminder_title'], hour: 20 },
},
{
text: '定个闹钟明天7点起床',
expect: { kind: 'timed_reminder', action: 'create_timed_reminder', title: '起床', hour: 7 },
},
];
let passed = 0;
let failed = 0;
function pass(label) {
passed += 1;
console.log(`${label}`);
}
function fail(label, detail) {
failed += 1;
console.error(`${label}: ${detail}`);
}
for (const row of matrix) {
const compact = String(row.text).replace(/\s+/g, '');
if (!hasReminderSetupCue(compact)) {
fail(row.text, 'missing reminder setup cue');
continue;
}
const parsed = parseScheduleIntent(row.text, { timezone, now })
?? tryResolveTimedReminderIntent(row.text, { timezone, now });
if (parsed?.action !== row.expect.action) {
fail(row.text, `parse action ${parsed?.action} !== ${row.expect.action}`);
continue;
}
if (row.expect.title && parsed.title !== row.expect.title) {
fail(row.text, `title ${parsed.title} !== ${row.expect.title}`);
continue;
}
if (row.expect.hour != null && parsed.hour !== row.expect.hour) {
fail(row.text, `hour ${parsed.hour} !== ${row.expect.hour}`);
continue;
}
if (row.expect.minute != null && parsed.minute !== row.expect.minute) {
fail(row.text, `minute ${parsed.minute} !== ${row.expect.minute}`);
continue;
}
if (row.expect.recurrence && parsed.recurrence !== row.expect.recurrence) {
fail(row.text, `recurrence ${parsed.recurrence} !== ${row.expect.recurrence}`);
continue;
}
if (row.expect.clarify) {
assert.deepEqual(parsed.needsClarification, row.expect.clarify);
}
const classified = classifyUserIntent(row.text, { timezone, now });
if (classified.kind !== row.expect.kind) {
fail(row.text, `classified kind ${classified.kind} !== ${row.expect.kind}`);
continue;
}
if (classified.action === 'agent_schedule') {
fail(row.text, 'must not route to agent_schedule');
continue;
}
pass(row.text);
}
console.log(`\nschedule reminder routing: ${passed} passed, ${failed} failed`);
process.exit(failed > 0 ? 1 : 0);