import assert from 'node:assert/strict'; import test from 'node:test'; import { parseScheduleIntent, shouldUseScheduleAssistant } from './schedule-intent.mjs'; import { nextDailyRunAt } from './schedule-time.mjs'; test('parses daily 7am todo digest request', () => { const intent = parseScheduleIntent('每天早上 7 点给我发一天的待办记录'); assert.equal(intent.action, 'create_daily_todo_digest'); assert.equal(intent.hour, 7); assert.equal(intent.minute, 0); }); test('parses daily digest request for today todos in direct wording', () => { const intent = parseScheduleIntent('每天早上7点把当天待办发给我'); assert.equal(intent.action, 'create_daily_todo_digest'); assert.equal(intent.hour, 7); assert.equal(intent.minute, 0); }); test('parses daily digest request with concise today wording', () => { const intent = parseScheduleIntent('每天7点发我今天待办'); assert.equal(intent.action, 'create_daily_todo_digest'); assert.equal(intent.hour, 7); assert.equal(intent.minute, 0); }); test('parses daily digest request with chinese numeral time', () => { const intent = parseScheduleIntent('以后每天早上七点把当天任务发送给我'); assert.equal(intent.action, 'create_daily_todo_digest'); assert.equal(intent.hour, 7); assert.equal(intent.minute, 0); }); test('parses daily digest request with half hour', () => { const intent = parseScheduleIntent('每天早上7点半把今天待办推送给我'); assert.equal(intent.action, 'create_daily_todo_digest'); assert.equal(intent.hour, 7); assert.equal(intent.minute, 30); }); test('daily todo digest asks for time when missing', () => { const intent = parseScheduleIntent('每天给我发一天的待办记录'); assert.equal(intent.action, 'create_daily_todo_digest'); assert.deepEqual(intent.needsClarification, ['digest_time']); }); test('daily digest asks for time when only says send today todos', () => { const intent = parseScheduleIntent('每天把当天待办发给我'); assert.equal(intent.action, 'create_daily_todo_digest'); assert.deepEqual(intent.needsClarification, ['digest_time']); }); test('parses balance low reminder request', () => { const intent = parseScheduleIntent('余额低于 20 元提醒我'); assert.equal(intent.action, 'create_balance_alert'); assert.equal(intent.thresholdCents, 2000); }); test('balance reminder asks for threshold when missing', () => { const intent = parseScheduleIntent('余额不足提醒我'); assert.equal(intent.action, 'create_balance_alert'); assert.deepEqual(intent.needsClarification, ['threshold']); }); test('parses plain todo record request with quoted title', () => { const intent = parseScheduleIntent('帮我记一下「🍽️ 跟段吃饭」'); assert.equal(intent.action, 'create_todo'); assert.equal(intent.title, '🍽️ 跟段吃饭'); }); test('plain todo record request asks for title when missing', () => { const intent = parseScheduleIntent('帮我记一下'); assert.equal(intent.action, 'create_todo'); assert.deepEqual(intent.needsClarification, ['todo_title']); }); test('parses setting a todo with common colloquial wording', () => { const intent = parseScheduleIntent('帮我设置一个代办一会儿跟段段吃饭'); assert.equal(intent.action, 'create_todo'); assert.equal(intent.title, '一会儿跟段段吃饭'); }); test('parses typo variant for todo wording', () => { const intent = parseScheduleIntent('帮我设置一个带办明天交周报'); assert.equal(intent.action, 'schedule_agent'); }); test('schedule assistant catches reminder-style requests', () => { assert.equal(shouldUseScheduleAssistant('明天早上六点去跑步,五点半提醒我'), true); assert.equal(shouldUseScheduleAssistant('帮我做个页面'), false); }); test('schedule assistant catches production ASR typo for todo', () => { const intent = parseScheduleIntent('明天早上六点去跑步帮我设下一个代拜'); assert.equal(intent.action, 'schedule_agent'); assert.equal(shouldUseScheduleAssistant('明天早上六点去跑步帮我设下一个代拜'), true); }); test('reminder todo request routes to schedule assistant instead of plain todo shortcut', () => { const intent = parseScheduleIntent('帮我设置一个代办明天早上六点去跑步记得在五点半的时候提醒我'); assert.equal(intent.action, 'schedule_agent'); }); test('specific dated reminder still routes to schedule assistant', () => { const intent = parseScheduleIntent('明天下午三点提醒我开会'); assert.equal(intent.action, 'none'); assert.equal(shouldUseScheduleAssistant('明天下午三点提醒我开会'), true); }); test('simple schedule query still works', () => { const intent = parseScheduleIntent('看看我的待办'); assert.equal(intent.action, 'query_schedule'); }); test('nextDailyRunAt rolls to tomorrow when today time has passed', () => { const now = Date.UTC(2026, 5, 17, 23, 30, 0); // 2026-06-18 07:30 Asia/Shanghai const next = nextDailyRunAt({ hour: 7, minute: 0, timezone: 'Asia/Shanghai', now }); assert.equal(next, Date.UTC(2026, 5, 18, 23, 0, 0)); // 2026-06-19 07:00 Asia/Shanghai });