Add smart ACK provider for WeChat MP replies
Replace fixed ackText with a rule-based AckProvider that picks response templates by message type and intent (translate, summary, rewrite, poster, ppt, mindmap, code, search, schedule). Pure sync, zero I/O, auto-falls back to config.ackText on any error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,30 @@ function parseHourMinute(text) {
|
||||
return { hour, minute };
|
||||
}
|
||||
|
||||
function extractTodoTitle(text) {
|
||||
const original = String(text ?? '').trim();
|
||||
if (!original) return null;
|
||||
const quoted = original.match(/[「『【((“"']([^」』】))”"']{1,80})[」』】))”"']/);
|
||||
if (quoted?.[1]) {
|
||||
const title = quoted[1].trim();
|
||||
if (title) return title;
|
||||
}
|
||||
const trailingCommand = original.match(
|
||||
/^(.{1,80}?)(?:帮我)?(?:设|设置|设下|记)(?:一个|下一个)?(?:待办|代办|带办|代拜)(?:吧|一下)?$/u,
|
||||
);
|
||||
if (trailingCommand?.[1]) {
|
||||
const title = trailingCommand[1].trim();
|
||||
if (title) return title;
|
||||
}
|
||||
const cleaned = original
|
||||
.replace(
|
||||
/^.*?(?:不用提醒|先记一下|帮我记一下|帮我记|记一下|添加待办|添加任务|记个待办|记个任务|设置一个待办|设置一个代办|设置一个带办|设置一个代拜|设置下一个代拜|设下一个代拜|帮我设置一个待办|帮我设置一个代办|帮我设置一个带办|帮我设置一个代拜|待办|代办|带办|代拜|任务)(?:[::,,、\s]+)?/u,
|
||||
'',
|
||||
)
|
||||
.trim();
|
||||
return cleaned || null;
|
||||
}
|
||||
|
||||
export function parseScheduleIntent(text) {
|
||||
const compact = normalizeText(text);
|
||||
if (!compact) return { action: 'none' };
|
||||
@@ -63,13 +87,51 @@ export function parseScheduleIntent(text) {
|
||||
};
|
||||
}
|
||||
|
||||
const wantsBalanceAlert = /(余额|钱包|账户).*(不足|低于|提醒|预警|通知)|余额不足|低余额|余额预警/.test(compact);
|
||||
if (wantsBalanceAlert) {
|
||||
const thresholdMatch = compact.match(/(?:低于|少于|不足|小于)(\d{1,6})(?:元|块|rmb|人民币|cny)?/i);
|
||||
const thresholdYuan = thresholdMatch ? Number(thresholdMatch[1]) : null;
|
||||
const thresholdCents = thresholdYuan == null ? null : Math.max(0, Math.round(thresholdYuan * 100));
|
||||
return thresholdCents == null
|
||||
? { action: 'create_balance_alert', needsClarification: ['threshold'] }
|
||||
: { action: 'create_balance_alert', thresholdCents };
|
||||
}
|
||||
|
||||
if (/看看|查看|看下|列出/.test(compact) && /(待办|日程|行程|计划|任务)/.test(compact)) {
|
||||
return { action: 'query_schedule' };
|
||||
}
|
||||
|
||||
const wantsTodoRecord =
|
||||
/(不用提醒|先记一下|帮我记一下|帮我记|记一下|添加待办|添加任务|记个待办|记个任务|设置一个待办|设置一个代办|设置一个带办|设置一个代拜|设置下一个代拜|设下一个代拜|帮我设置一个待办|帮我设置一个代办|帮我设置一个带办|帮我设置一个代拜|待办|代办|带办|代拜|任务)/.test(
|
||||
compact,
|
||||
);
|
||||
if (wantsTodoRecord) {
|
||||
const explicitNoReminder = /(不用提醒|不提醒|先记一下)/.test(compact);
|
||||
const hasScheduleTime = /(提醒|闹钟|叫我|今天|今晚|明天|后天|早上|上午|中午|下午|晚上|[0-9零一二两三四五六七八九十]{1,3}(点|:|:))/.test(
|
||||
compact,
|
||||
);
|
||||
if (!explicitNoReminder && hasScheduleTime) {
|
||||
return { action: 'schedule_agent' };
|
||||
}
|
||||
const title = extractTodoTitle(text);
|
||||
if (!title) {
|
||||
return { action: 'create_todo', needsClarification: ['todo_title'] };
|
||||
}
|
||||
return { action: 'create_todo', title };
|
||||
}
|
||||
|
||||
return { action: 'none' };
|
||||
}
|
||||
|
||||
export function isScheduleIntent(intent) {
|
||||
return intent?.action && intent.action !== 'none';
|
||||
}
|
||||
|
||||
export function shouldUseScheduleAssistant(text) {
|
||||
const compact = normalizeText(text);
|
||||
if (!compact) return false;
|
||||
if (isScheduleIntent(parseScheduleIntent(text))) return true;
|
||||
const scheduleKeywords = /(提醒|待办|代办|带办|代拜|日程|行程|安排|计划|闹钟)/;
|
||||
const timeKeywords = /(今天|今晚|明天|后天|早上|上午|中午|下午|晚上|\d{1,2}[点::])/;
|
||||
return scheduleKeywords.test(compact) && timeKeywords.test(compact);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user