const CALENDAR_KEYWORDS = [ '行程', '会议', '约会', '日历', '几点', '安排', '预约', '档期', '出发', '航班', '火车', ]; const MEINPUT_KEYWORDS = [ '输入', '打字', '说过', '原话', '上屏', '写过', '输入过', '发了', '微信', '消息', ]; const CHAT_KEYWORDS = [ '聊天', '对话', '讨论', '聊过', '问过', '你记得', '我们说过', '上次聊', 'agent', '助手', ]; const MEMORY_KEYWORDS = [ '决定', '定了', '之前定的', '记得', '记住', '上次', '当时', '承诺', '约定', ]; const COMMITMENT_KEYWORDS = [ '待办', '要做', '记得', '别忘了', '跟进', '确认', '截止', '交付', '完成', '处理', ]; const IMPORTANCE_KEYWORDS = ['重要', '关键', '紧急', '必须', '大事', '要紧']; const SCHEDULE_QUESTION = /有什么|哪些|什么事|干嘛|做了什么|发生/; const TEMPORAL_QUESTION = /什么时候|何时|几点|哪天/; /** * @param {string} query */ export function analyzeKeywords(query) { const text = String(query ?? ''); const rule_hits = []; const sources = { calendar: 0.35, chat: 0.55, meinput: 0.55, memory_v2: 0.35, }; for (const kw of CALENDAR_KEYWORDS) { if (text.includes(kw)) { sources.calendar = Math.min(1, sources.calendar + 0.15); rule_hits.push(`keyword:calendar:${kw}`); } } for (const kw of MEINPUT_KEYWORDS) { if (text.includes(kw)) { sources.meinput = Math.min(1, sources.meinput + 0.12); rule_hits.push(`keyword:meinput:${kw}`); } } for (const kw of CHAT_KEYWORDS) { if (text.includes(kw)) { sources.chat = Math.min(1, sources.chat + 0.12); rule_hits.push(`keyword:chat:${kw}`); } } for (const kw of MEMORY_KEYWORDS) { if (text.includes(kw)) { sources.memory_v2 = Math.min(1, sources.memory_v2 + 0.12); rule_hits.push(`keyword:memory:${kw}`); } } if (SCHEDULE_QUESTION.test(text)) { sources.calendar += 0.1; sources.chat += 0.08; sources.meinput += 0.08; rule_hits.push('pattern:schedule_question'); } const importance_min = IMPORTANCE_KEYWORDS.some((kw) => text.includes(kw)) ? 0.55 : 0.35; if (importance_min > 0.35) rule_hits.push('filter:importance'); return { sources, rule_hits, importance_min, commitmentKeywords: COMMITMENT_KEYWORDS }; } /** * @param {string} query * @param {{ sources: Record, importance_min: number, commitmentKeywords: string[] }} kw */ export function inferTargets(query, kw) { const text = String(query ?? ''); const targets = []; if (/行程|会议|约会|日历|安排/.test(text)) { targets.push({ type: 'calendar_event', weight: 0.9 }, { type: 'schedule', weight: 0.85 }); } if (/待办|要做|完成|跟进|截止/.test(text)) { targets.push({ type: 'todo', weight: 0.95 }); } if (/决定|定了|承诺|约定/.test(text)) { targets.push({ type: 'commitment', weight: 0.95 }, { type: 'decision', weight: 0.85 }); } if (/重要|关键|紧急/.test(text)) { targets.push({ type: 'important_event', weight: 0.9 }); } if (!targets.length || /什么事|做了什么|发生|输入|说过/.test(text)) { targets.push({ type: 'mention', weight: 0.75 }, { type: 'event', weight: 0.7 }); } const seen = new Set(); return targets.filter((t) => { if (seen.has(t.type)) return false; seen.add(t.type); return true; }); } /** * @param {string} query */ export function inferTemporalMode(query) { const text = String(query ?? ''); if (/说过|提到|安排|定了|计划|要做|记得|别忘了/.test(text) && /昨天|前天|上周|这周/.test(text)) { if (/做了什么|发生了什么|干嘛了/.test(text)) return 'AMBIGUOUS'; if (/说过|提到|定了|安排/.test(text)) return 'MENTIONED_IN'; } if (/有什么安排|行程|会议|几点|今天|明天/.test(text)) return 'PLANNED_IN'; if (/定了哪些|创建|记录/.test(text)) return 'CREATED_IN'; if (/截止|due|要交|到期/.test(text)) return 'DUE_IN'; if (/做了什么|发生了什么|干嘛|什么事/.test(text)) return 'OCCURRED_IN'; if (/重要|什么事/.test(text)) return 'AMBIGUOUS'; return 'AMBIGUOUS'; } /** * @param {string} query */ export function isTemporalRecallQuery(query) { const text = String(query ?? '').trim(); if (!text) return false; if (TEMPORAL_QUESTION.test(text)) return true; if (/今天|昨天|前天|明天|这周|上周|本月|最近|近期|这几天/.test(text)) return true; if (/做了什么|发生了什么|什么事|有什么|哪些|安排|行程|输入过|说过/.test(text)) return true; return false; } export function expandQueries(source, query, commitmentKeywords) { const base = []; const text = String(query ?? ''); if (source === 'meinput') { base.push('会议', '安排', '明天', '今天', '项目', '确认', '跟进', '截止', '记得'); } else if (source === 'chat') { base.push('约', '安排', '明天', '会议', '确认', '跟进', '截止', '记得', '待办'); } else if (source === 'memory_v2') { base.push('commitment', 'decision', 'task', 'todo'); } else if (source === 'calendar') { base.push('会议', '预约', '行程'); } for (const kw of commitmentKeywords) { if (text.includes(kw) && !base.includes(kw)) base.push(kw); } for (const kw of IMPORTANCE_KEYWORDS) { if (text.includes(kw) && !base.includes(kw)) base.push(kw); } return base.slice(0, 12); }