fix(wechat): yield schedule handler when scheduled-task intent matches
Stop schedule todo replies from intercepting cancel/list/create automation requests, and recognize 有哪些 for inbound scheduled task listing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -164,7 +164,7 @@ export function parseScheduledTaskIntent(text, { now = Date.now(), timezone = 'A
|
|||||||
return { action: 'cancel_scheduled_task' };
|
return { action: 'cancel_scheduled_task' };
|
||||||
}
|
}
|
||||||
|
|
||||||
const wantsList = /(?:查看|看看|列出|我的).{0,12}(?:定时|自动).{0,12}(?:任务|自动化)/u.test(compact)
|
const wantsList = /(?:查看|看看|列出|我的|有哪些).{0,12}(?:定时|自动).{0,12}(?:任务|自动化)/u.test(compact)
|
||||||
|| /(?:list|show).{0,12}(?:scheduled|automation).{0,12}tasks/iu.test(compact);
|
|| /(?:list|show).{0,12}(?:scheduled|automation).{0,12}tasks/iu.test(compact);
|
||||||
if (wantsList) {
|
if (wantsList) {
|
||||||
return { action: 'list_scheduled_tasks' };
|
return { action: 'list_scheduled_tasks' };
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ test('scheduled automation takes precedence over schedule assistant keyword over
|
|||||||
test('parses cancel and list intents', () => {
|
test('parses cancel and list intents', () => {
|
||||||
assert.equal(parseScheduledTaskIntent('取消我的定时任务').action, 'cancel_scheduled_task');
|
assert.equal(parseScheduledTaskIntent('取消我的定时任务').action, 'cancel_scheduled_task');
|
||||||
assert.equal(parseScheduledTaskIntent('看看我的定时自动任务').action, 'list_scheduled_tasks');
|
assert.equal(parseScheduledTaskIntent('看看我的定时自动任务').action, 'list_scheduled_tasks');
|
||||||
|
assert.equal(parseScheduledTaskIntent('我有哪些定时任务').action, 'list_scheduled_tasks');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('parses one-shot tonight schedule with task spec', () => {
|
test('parses one-shot tonight schedule with task spec', () => {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { isScheduleIntent, parseScheduleIntent } from '../../schedule-intent.mjs';
|
import { isScheduleIntent, parseScheduleIntent } from '../../schedule-intent.mjs';
|
||||||
import { formatLocalTime, resolveScheduleTimestamp } from '../../schedule-time.mjs';
|
import { formatLocalTime, resolveScheduleTimestamp } from '../../schedule-time.mjs';
|
||||||
|
import { isScheduledTaskIntent, parseScheduledTaskIntent } from '../../scheduled-task-intent.mjs';
|
||||||
|
|
||||||
function normalizeHour(value) {
|
function normalizeHour(value) {
|
||||||
const hour = Number(value);
|
const hour = Number(value);
|
||||||
@@ -160,6 +161,10 @@ export async function handleWechatScheduleIntent({
|
|||||||
logger = console,
|
logger = console,
|
||||||
}) {
|
}) {
|
||||||
if (!scheduleService) return null;
|
if (!scheduleService) return null;
|
||||||
|
const scheduledTaskIntent = parseScheduledTaskIntent(intent.agentText);
|
||||||
|
if (isScheduledTaskIntent(scheduledTaskIntent)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const scheduleIntent = await resolveScheduleIntent({
|
const scheduleIntent = await resolveScheduleIntent({
|
||||||
text: intent.agentText,
|
text: intent.agentText,
|
||||||
wechatScheduleLlmConfigService,
|
wechatScheduleLlmConfigService,
|
||||||
|
|||||||
@@ -182,3 +182,35 @@ test('schedule handler falls through for multi-time reminder requests', async ()
|
|||||||
});
|
});
|
||||||
assert.equal(reply, null);
|
assert.equal(reply, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('schedule handler yields cancel scheduled task requests to goose', async () => {
|
||||||
|
let scheduleCalled = false;
|
||||||
|
const reply = await handleWechatScheduleIntent({
|
||||||
|
intent: { agentText: '取消定时推送苏州天气任务', msgId: 'msg-cancel-1' },
|
||||||
|
user: { userId: 'user-123' },
|
||||||
|
scheduleService: {
|
||||||
|
async createItem() {
|
||||||
|
scheduleCalled = true;
|
||||||
|
return { id: 'item-1' };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
assert.equal(reply, null);
|
||||||
|
assert.equal(scheduleCalled, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('schedule handler yields list scheduled task requests to scheduled-task handler', async () => {
|
||||||
|
let scheduleCalled = false;
|
||||||
|
const reply = await handleWechatScheduleIntent({
|
||||||
|
intent: { agentText: '我有哪些定时任务', msgId: 'msg-list-1' },
|
||||||
|
user: { userId: 'user-123' },
|
||||||
|
scheduleService: {
|
||||||
|
async createItem() {
|
||||||
|
scheduleCalled = true;
|
||||||
|
return { id: 'item-1' };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
assert.equal(reply, null);
|
||||||
|
assert.equal(scheduleCalled, false);
|
||||||
|
});
|
||||||
|
|||||||
@@ -86,3 +86,20 @@ test('handleWechatScheduledTaskIntent still lists tasks', async () => {
|
|||||||
});
|
});
|
||||||
assert.match(reply, /新闻页面/u);
|
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);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user