e13df82021
Memind CI / Test, build, and release guards (push) Failing after 14m19s
Stop ITL regex from intercepting new messages before Agent execution; move scheduled task and schedule write confirmation to MCP tool calls with draft commit on 确认. Co-authored-by: Cursor <cursoragent@cursor.com>
147 lines
4.4 KiB
JavaScript
147 lines
4.4 KiB
JavaScript
import { resolveScheduleTimestamp } from './schedule-time.mjs';
|
|
import { shouldAutoCreateReminderAtStart } from './schedule-service.mjs';
|
|
import {
|
|
isScheduledTaskWorkerEnabled,
|
|
scheduledTaskWorkerDisabledMessage,
|
|
} from './scheduled-task-worker-config.mjs';
|
|
|
|
export async function executeScheduledTaskCreateTool(args, {
|
|
userId,
|
|
scheduledTaskService,
|
|
timezone = 'Asia/Shanghai',
|
|
env = process.env,
|
|
} = {}) {
|
|
if (!scheduledTaskService) throw new Error('scheduledTaskService 不可用');
|
|
const task = await scheduledTaskService.createTask({
|
|
userId,
|
|
title: args.title ?? null,
|
|
taskSpec: args.taskSpec,
|
|
recurrence: args.recurrence ?? 'daily',
|
|
runAtLocal: args.runAtLocal ?? null,
|
|
hour: args.hour ?? null,
|
|
minute: args.minute ?? 0,
|
|
weekday: args.weekday ?? null,
|
|
timezone: args.timezone ?? timezone,
|
|
notifyChannel: args.notifyChannel ?? 'both',
|
|
sourceChannel: args.sourceChannel ?? 'agent',
|
|
sourceMessageId: args.sourceMessageId ?? null,
|
|
sourceText: args.sourceText ?? null,
|
|
});
|
|
const workerWarning = isScheduledTaskWorkerEnabled(env)
|
|
? null
|
|
: scheduledTaskWorkerDisabledMessage(env);
|
|
return workerWarning ? { ...task, workerWarning } : task;
|
|
}
|
|
|
|
export async function executeScheduleCreateItemTool(args, {
|
|
userId,
|
|
scheduleService,
|
|
timezone = 'Asia/Shanghai',
|
|
} = {}) {
|
|
if (!scheduleService) throw new Error('scheduleService 不可用');
|
|
const tz = args.timezone ?? timezone;
|
|
const startAt = resolveScheduleTimestamp({
|
|
epochMs: args.startAt,
|
|
localString: args.startLocal,
|
|
timezone: tz,
|
|
fieldName: '开始时间',
|
|
});
|
|
const endAt = resolveScheduleTimestamp({
|
|
epochMs: args.endAt,
|
|
localString: args.endLocal,
|
|
timezone: tz,
|
|
fieldName: '结束时间',
|
|
});
|
|
const dueAt = resolveScheduleTimestamp({
|
|
epochMs: args.dueAt,
|
|
localString: args.dueLocal,
|
|
timezone: tz,
|
|
fieldName: '截止时间',
|
|
});
|
|
const item = await scheduleService.createItem({
|
|
userId,
|
|
kind: args.kind,
|
|
title: args.title,
|
|
description: args.description ?? null,
|
|
startAt,
|
|
endAt,
|
|
dueAt,
|
|
allDay: Boolean(args.allDay),
|
|
timezone: tz,
|
|
location: args.location ?? null,
|
|
sourceChannel: args.sourceChannel ?? 'agent',
|
|
sourceMessageId: args.sourceMessageId ?? null,
|
|
sourceText: args.sourceText ?? null,
|
|
metadata: args.metadata ?? { source: 'agent_tool' },
|
|
});
|
|
let remindAt = resolveScheduleTimestamp({
|
|
epochMs: args.remindAt,
|
|
localString: args.remindLocal,
|
|
timezone: tz,
|
|
fieldName: '提醒时间',
|
|
});
|
|
if (
|
|
remindAt == null
|
|
&& shouldAutoCreateReminderAtStart({
|
|
title: args.title,
|
|
description: args.description,
|
|
startAt,
|
|
noReminder: Boolean(args.noReminder),
|
|
})
|
|
) {
|
|
remindAt = startAt;
|
|
}
|
|
if (remindAt != null) {
|
|
const reminder = await scheduleService.createReminder({
|
|
userId,
|
|
itemId: item.id,
|
|
remindAt,
|
|
offsetMinutes: args.offsetMinutes ?? null,
|
|
channel: args.channel ?? 'wechat',
|
|
});
|
|
return { item, reminder };
|
|
}
|
|
return { item };
|
|
}
|
|
|
|
export async function executeScheduleCreateReminderTool(args, {
|
|
userId,
|
|
scheduleService,
|
|
timezone = 'Asia/Shanghai',
|
|
} = {}) {
|
|
if (!scheduleService) throw new Error('scheduleService 不可用');
|
|
const tz = args.timezone ?? timezone;
|
|
const remindAt = resolveScheduleTimestamp({
|
|
epochMs: args.remindAt,
|
|
localString: args.remindLocal,
|
|
timezone: tz,
|
|
fieldName: '提醒时间',
|
|
});
|
|
if (remindAt == null) throw new Error('缺少提醒时间 remindLocal 或 remindAt');
|
|
const reminder = await scheduleService.createReminder({
|
|
userId,
|
|
itemId: args.itemId,
|
|
remindAt,
|
|
offsetMinutes: args.offsetMinutes ?? null,
|
|
channel: args.channel ?? 'wechat',
|
|
});
|
|
return reminder;
|
|
}
|
|
|
|
export async function commitAgentSideEffectTool(toolName, toolArgs, services) {
|
|
const name = String(toolName ?? '').trim();
|
|
if (name === 'scheduled_task_create') {
|
|
const task = await executeScheduledTaskCreateTool(toolArgs, services);
|
|
return { kind: 'scheduled_task', task };
|
|
}
|
|
if (name === 'schedule_create_item') {
|
|
const result = await executeScheduleCreateItemTool(toolArgs, services);
|
|
return { kind: 'schedule_item', ...result };
|
|
}
|
|
if (name === 'schedule_create_reminder') {
|
|
const reminder = await executeScheduleCreateReminderTool(toolArgs, services);
|
|
return { kind: 'schedule_reminder', reminder };
|
|
}
|
|
throw new Error(`不支持的 agent 副作用工具:${name}`);
|
|
}
|