Files
memind/intent-query-guard.mjs
T
john d58dc2a251 feat(wechat): add Intent Transaction Layer with unified task schema
Introduce Draft → Confirm → Commit flow for WeChat schedule intents behind
feature flags, plus h5_tasks dual-write/read aggregation and rollout scripts
so reminders and automations get explicit user confirmation before persisting.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-24 15:59:17 +08:00

65 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { formatUnifiedTaskListReply } from './task-unified-service.mjs';
function normalizeCompact(text) {
return String(text ?? '').replace(/\s+/g, '').trim();
}
/** Layer 0: 只读查询,禁止 Draft / Commit */
export function detectQueryGuard(text) {
const compact = normalizeCompact(text);
if (!compact) return false;
if (/看看我的待办/u.test(compact)) return true;
if (/查看我的(?:待办|日程|行程|计划)/u.test(compact)) return true;
if (/(?:列出|看看).{0,8}(?:定时|自动).{0,8}任务/u.test(compact)) return true;
if (/(?:有没有|是否有).{0,16}(?:定时|自动).{0,8}任务/u.test(compact)) return true;
if (/(?:取消|停止|关闭|删除).{0,8}(?:定时|提醒|任务)/u.test(compact)) return false;
const queryCue = /(?:查一下|查询|看看有没有|有没有(?!新的)|是否有|是否已有|是否还在|是否设置|我有哪些|有哪些提醒|有没有执行|有没有设置)/u.test(compact);
const createCue = /(?:帮我设置|请设置|创建|添加|记一下|设个|设一个|每天|每日|帮我每天|到点提醒)/u.test(compact)
|| (/(?:定时任务|自动任务)/u.test(compact) && !queryCue);
if (queryCue && !createCue) return true;
if (/^查/u.test(compact) && /(?:任务|提醒|定时)/u.test(compact) && !/(?:设置|创建)/u.test(compact)) return true;
return false;
}
export async function formatQueryGuardReply(text, {
scheduleService,
scheduledTaskService,
taskUnifiedService = null,
userId,
timezone = 'Asia/Shanghai',
env = process.env,
} = {}) {
const compact = normalizeCompact(text);
if (/待办/u.test(compact) && scheduleService?.buildTodoDigestText) {
return scheduleService.buildTodoDigestText({ userId, timezone });
}
if (/(?:定时|自动).{0,8}任务/u.test(compact)) {
if (taskUnifiedService?.listUserTasks) {
const tasks = await taskUnifiedService.listUserTasks({ userId, status: 'active', limit: 10, timezone });
return formatUnifiedTaskListReply(tasks, { timezone });
}
if (scheduledTaskService?.listTasks) {
const tasks = await scheduledTaskService.listTasks({ userId, status: 'active', limit: 10 });
return formatScheduledTaskListReply(tasks);
}
}
return '这是查询请求,我不会新建或修改任何提醒/任务。如需设置,请直接说「下午 2 点半提醒我开会」或「每天 6 点帮我做新闻页面」。';
}
function formatScheduledTaskListReply(tasks) {
if (!tasks?.length) return '你当前没有进行中的定时自动任务。';
const lines = ['你的定时自动任务:'];
for (const task of tasks.slice(0, 10)) {
const when = task.recurrence === 'once'
? new Date(Number(task.nextRunAt)).toLocaleString('zh-CN', { timeZone: task.timezone || 'Asia/Shanghai', hour12: false })
: `${String(task.hour).padStart(2, '0')}:${String(task.minute ?? 0).padStart(2, '0')}`;
lines.push(`- ${task.title}${task.recurrence} ${when}`);
}
return lines.join('\n');
}