Files
2026-07-07 12:10:21 +08:00

122 lines
4.1 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { handleWechatScheduleIntent } from './schedule.mjs';
function createScheduleService() {
return {
async createItem(payload) {
return { id: 'item-1', ...payload };
},
async createDailyTodoDigest(payload) {
return { id: 'digest-1', minute: payload.minute, hour: payload.hour, ...payload };
},
async createBalanceLowAlert(payload) {
return { id: 'balance-1', ...payload };
},
async buildTodoDigestText() {
return '今天有 2 条待办。';
},
};
}
test('schedule handler keeps rule-based parsing as first priority', async () => {
let llmCalled = false;
const reply = await handleWechatScheduleIntent({
intent: { agentText: '帮我记一下 跟进合同', msgId: 'msg-1' },
user: { userId: 'user-1' },
scheduleService: createScheduleService(),
wechatScheduleLlmConfigService: { async isScheduleLlmEnabled() { return true; } },
llmProviderService: {
async createChatCompletion() {
llmCalled = true;
return { ok: true, reply: '{"action":"none"}' };
},
},
});
assert.match(reply, /已记录到待办列表/);
assert.equal(llmCalled, false);
});
test('schedule handler can use llm fallback for ambiguous todo text', async () => {
const reply = await handleWechatScheduleIntent({
intent: { agentText: '下周把合同发给客户,别忘了', msgId: 'msg-2' },
user: { userId: 'user-1' },
scheduleService: createScheduleService(),
wechatScheduleLlmConfigService: { async isScheduleLlmEnabled() { return true; } },
llmProviderService: {
async createChatCompletion() {
return {
ok: true,
reply: '{"action":"create_todo","title":"把合同发给客户"}',
};
},
},
});
assert.match(reply, /把合同发给客户/);
});
test('schedule handler directly handles daily digest shortcut phrase', async () => {
const reply = await handleWechatScheduleIntent({
intent: { agentText: '每天早上7点把当天待办发给我', msgId: 'msg-digest-1' },
user: { userId: 'user-1' },
scheduleService: createScheduleService(),
});
assert.match(reply, /已设置/);
assert.match(reply, /每天早上 7点/);
});
test('schedule handler does not call llm when switch is off', async () => {
let llmCalled = false;
const reply = await handleWechatScheduleIntent({
intent: { agentText: '别忘了报销', msgId: 'msg-4' },
user: { userId: 'user-1' },
scheduleService: createScheduleService(),
wechatScheduleLlmConfigService: { async isScheduleLlmEnabled() { return false; } },
llmProviderService: {
async createChatCompletion() {
llmCalled = true;
return { ok: true, reply: '{"action":"create_todo","title":"报销"}' };
},
},
});
assert.equal(reply, null);
assert.equal(llmCalled, false);
});
test('schedule handler falls back quietly when llm request fails', async () => {
const warnings = [];
const reply = await handleWechatScheduleIntent({
intent: { agentText: '别忘了报销', msgId: 'msg-5' },
user: { userId: 'user-1' },
scheduleService: createScheduleService(),
wechatScheduleLlmConfigService: { async isScheduleLlmEnabled() { return true; } },
llmProviderService: {
async createChatCompletion() {
return { ok: false, message: 'provider unavailable' };
},
},
logger: { warn: (...args) => warnings.push(args.join(' ')) },
});
assert.equal(reply, null);
assert.equal(warnings.length, 1);
assert.match(warnings[0], /provider unavailable/);
});
test('schedule handler falls through for llm schedule_agent results', async () => {
const reply = await handleWechatScheduleIntent({
intent: { agentText: '明天下午三点提醒我开会', msgId: 'msg-3' },
user: { userId: 'user-1' },
scheduleService: createScheduleService(),
wechatScheduleLlmConfigService: { async isScheduleLlmEnabled() { return true; } },
llmProviderService: {
async createChatCompletion() {
return {
ok: true,
reply: '{"action":"schedule_agent"}',
};
},
},
});
assert.equal(reply, null);
});