5de58af9ed
Use a lightweight LLM over active task lists to pick taskId for cancel, exclude page.generate from scheduled-task inbound, and remove single-task auto-cancel so Cursor page generation stays isolated. Co-authored-by: Cursor <cursoragent@cursor.com>
86 lines
2.4 KiB
JavaScript
86 lines
2.4 KiB
JavaScript
import assert from 'node:assert/strict';
|
||
import test from 'node:test';
|
||
import {
|
||
buildScheduledTaskListPayload,
|
||
normalizeScheduledTaskManageLlmDecision,
|
||
resolveScheduledTaskCancelWithLlm,
|
||
} from './wechat-scheduled-task-manage-llm.mjs';
|
||
|
||
const tasks = [
|
||
{
|
||
id: 'task-suzhou',
|
||
title: '每天早上6:30推送苏州市天气预报',
|
||
recurrence: 'daily',
|
||
hour: 6,
|
||
minute: 30,
|
||
taskSpec: '查询苏州天气并推送',
|
||
},
|
||
{
|
||
id: 'task-news',
|
||
title: '每日新闻早报页面(5:30)',
|
||
recurrence: 'daily',
|
||
hour: 5,
|
||
minute: 30,
|
||
taskSpec: '生成新闻早报页面',
|
||
},
|
||
];
|
||
|
||
test('buildScheduledTaskListPayload maps active tasks for llm input', () => {
|
||
const payload = buildScheduledTaskListPayload(tasks);
|
||
assert.equal(payload.length, 2);
|
||
assert.equal(payload[0].taskId, 'task-suzhou');
|
||
assert.match(payload[0].taskSpec, /苏州/u);
|
||
});
|
||
|
||
test('normalizeScheduledTaskManageLlmDecision accepts valid cancel taskId', () => {
|
||
const decision = normalizeScheduledTaskManageLlmDecision({
|
||
action: 'cancel',
|
||
taskId: 'task-news',
|
||
}, tasks);
|
||
assert.deepEqual(decision, { action: 'cancel', taskId: 'task-news' });
|
||
});
|
||
|
||
test('normalizeScheduledTaskManageLlmDecision rejects unknown taskId', () => {
|
||
const decision = normalizeScheduledTaskManageLlmDecision({
|
||
action: 'cancel',
|
||
taskId: 'missing',
|
||
}, tasks);
|
||
assert.deepEqual(decision, { action: 'none' });
|
||
});
|
||
|
||
test('resolveScheduledTaskCancelWithLlm can pick the matching task', async () => {
|
||
const reply = await resolveScheduledTaskCancelWithLlm({
|
||
text: '取消定时推送苏州天气任务',
|
||
tasks,
|
||
llmProviderService: {
|
||
async createChatCompletion() {
|
||
return {
|
||
ok: true,
|
||
reply: JSON.stringify({ action: 'cancel', taskId: 'task-suzhou' }),
|
||
};
|
||
},
|
||
},
|
||
});
|
||
assert.deepEqual(reply, { action: 'cancel', taskId: 'task-suzhou' });
|
||
});
|
||
|
||
test('resolveScheduledTaskCancelWithLlm returns clarify when ambiguous', async () => {
|
||
const reply = await resolveScheduledTaskCancelWithLlm({
|
||
text: '帮我取消定时任务',
|
||
tasks,
|
||
llmProviderService: {
|
||
async createChatCompletion() {
|
||
return {
|
||
ok: true,
|
||
reply: JSON.stringify({
|
||
action: 'clarify',
|
||
message: '你是想取消苏州天气,还是 5:30 新闻早报?',
|
||
}),
|
||
};
|
||
},
|
||
},
|
||
});
|
||
assert.equal(reply.action, 'clarify');
|
||
assert.match(reply.message, /新闻早报/u);
|
||
});
|