d8463829f7
When a user has exactly one active automation task, cancel it by taskId after listTasks instead of relying on Goose when the LLM provider fails. Co-authored-by: Cursor <cursoragent@cursor.com>
146 lines
4.3 KiB
JavaScript
146 lines
4.3 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { handleWechatScheduledTaskIntent } from './scheduled-task.mjs';
|
|
|
|
test('handleWechatScheduledTaskIntent passes create requests to goose', async () => {
|
|
const reply = await handleWechatScheduledTaskIntent({
|
|
intent: {
|
|
msgType: 'text',
|
|
agentText: '每天6点帮我做今日新闻页面',
|
|
msgId: 'msg-1',
|
|
},
|
|
user: { userId: 'user-1' },
|
|
scheduledTaskService: {
|
|
async createTask() {
|
|
throw new Error('should not create from inbound regex');
|
|
},
|
|
},
|
|
});
|
|
assert.equal(reply, null);
|
|
});
|
|
|
|
test('handleWechatScheduledTaskIntent passes incomplete create requests to goose', async () => {
|
|
const reply = await handleWechatScheduledTaskIntent({
|
|
intent: {
|
|
msgType: 'text',
|
|
agentText: '帮我设一个定时自动任务',
|
|
msgId: 'msg-1',
|
|
},
|
|
user: { userId: 'user-1' },
|
|
scheduledTaskService: {
|
|
async createTask() {
|
|
throw new Error('should not create from inbound regex');
|
|
},
|
|
},
|
|
});
|
|
assert.equal(reply, null);
|
|
});
|
|
|
|
test('handleWechatScheduledTaskIntent cancels the only active task in inbound', async () => {
|
|
const calls = [];
|
|
const reply = await handleWechatScheduledTaskIntent({
|
|
intent: {
|
|
msgType: 'text',
|
|
agentText: '取消定时推送苏州天气任务',
|
|
msgId: 'msg-123-1',
|
|
},
|
|
user: { userId: 'user-123' },
|
|
scheduledTaskService: {
|
|
async listTasks() {
|
|
return [{
|
|
id: 'task-1',
|
|
title: '每天早上6:30推送苏州市天气预报',
|
|
recurrence: 'daily',
|
|
hour: 6,
|
|
minute: 30,
|
|
timezone: 'Asia/Shanghai',
|
|
}];
|
|
},
|
|
async cancelTask(payload) {
|
|
calls.push(payload);
|
|
return {
|
|
id: 'task-1',
|
|
title: '每天早上6:30推送苏州市天气预报',
|
|
status: 'cancelled',
|
|
};
|
|
},
|
|
},
|
|
});
|
|
assert.match(reply, /已取消定时任务/u);
|
|
assert.deepEqual(calls, [{ userId: 'user-123', taskId: 'task-1' }]);
|
|
});
|
|
|
|
test('handleWechatScheduledTaskIntent passes cancel to goose when multiple active tasks', async () => {
|
|
const reply = await handleWechatScheduledTaskIntent({
|
|
intent: {
|
|
msgType: 'text',
|
|
agentText: '取消定时推送苏州天气任务',
|
|
msgId: 'msg-123-2',
|
|
},
|
|
user: { userId: 'user-123' },
|
|
scheduledTaskService: {
|
|
async listTasks() {
|
|
return [
|
|
{ id: 'task-1', title: '苏州天气', recurrence: 'daily', hour: 6, minute: 30, timezone: 'Asia/Shanghai' },
|
|
{ id: 'task-2', title: '新闻早报', recurrence: 'daily', hour: 5, minute: 30, timezone: 'Asia/Shanghai' },
|
|
];
|
|
},
|
|
async cancelTask() {
|
|
throw new Error('should not cancel from inbound when ambiguous');
|
|
},
|
|
},
|
|
});
|
|
assert.equal(reply, null);
|
|
});
|
|
|
|
test('handleWechatScheduledTaskIntent ignores non automation text', async () => {
|
|
const reply = await handleWechatScheduledTaskIntent({
|
|
intent: {
|
|
msgType: 'text',
|
|
agentText: '明天下午三点提醒我开会',
|
|
msgId: 'msg-1',
|
|
},
|
|
user: { userId: 'user-1' },
|
|
scheduledTaskService: {
|
|
async createTask() {
|
|
throw new Error('should not create');
|
|
},
|
|
},
|
|
});
|
|
assert.equal(reply, null);
|
|
});
|
|
|
|
test('handleWechatScheduledTaskIntent still lists tasks', async () => {
|
|
const reply = await handleWechatScheduledTaskIntent({
|
|
intent: {
|
|
msgType: 'text',
|
|
agentText: '看看我的定时自动任务',
|
|
msgId: 'msg-1',
|
|
},
|
|
user: { userId: 'user-1' },
|
|
scheduledTaskService: {
|
|
async listTasks() {
|
|
return [{ title: '新闻页面', recurrence: 'daily', hour: 6, minute: 0, timezone: 'Asia/Shanghai' }];
|
|
},
|
|
},
|
|
});
|
|
assert.match(reply, /新闻页面/u);
|
|
});
|
|
|
|
test('handleWechatScheduledTaskIntent lists tasks for 有哪些 phrasing', async () => {
|
|
const reply = await handleWechatScheduledTaskIntent({
|
|
intent: {
|
|
msgType: 'text',
|
|
agentText: '我有哪些定时任务',
|
|
msgId: 'msg-2',
|
|
},
|
|
user: { userId: 'user-1' },
|
|
scheduledTaskService: {
|
|
async listTasks() {
|
|
return [{ title: '苏州天气', recurrence: 'daily', hour: 6, minute: 30, timezone: 'Asia/Shanghai' }];
|
|
},
|
|
},
|
|
});
|
|
assert.match(reply, /苏州天气/u);
|
|
});
|