Add Rain V0 for MeInput full-range chat analysis and delivery tooling.
Memind CI / Test, build, and release guards (push) Has been cancelled

Introduce rain-service orchestration, browser-safe chat skill filtering, MeInput
adapter helpers, and verify/deploy scripts so Rain mode can summarize recent input
without Memory V2 pollution.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-09-04 13:49:40 +08:00
parent b2a5caf67d
commit be464a5b8d
18 changed files with 1475 additions and 50 deletions
+105
View File
@@ -0,0 +1,105 @@
import { parseTimeScope } from '../temporal-recall-service/time-parser.mjs';
export const RAIN_DEFAULT_DAYS = 3;
const TZ_OFFSET_MIN = Number(process.env.TEMPORAL_RECALL_TZ_OFFSET_MIN ?? 480);
/** @param {Date} anchor @param {number} deltaDays */
function addDays(anchor, deltaDays) {
const shifted = new Date(anchor.getTime() + TZ_OFFSET_MIN * 60_000);
const ms =
Date.UTC(
shifted.getUTCFullYear(),
shifted.getUTCMonth(),
shifted.getUTCDate() + deltaDays,
0,
0,
0,
0,
) - TZ_OFFSET_MIN * 60_000;
return new Date(ms);
}
/** @param {Date} anchor */
function endOfDay(anchor) {
const p = new Date(anchor.getTime() + TZ_OFFSET_MIN * 60_000);
const ms =
Date.UTC(p.getUTCFullYear(), p.getUTCMonth(), p.getUTCDate() + 1, 0, 0, 0, 0) -
TZ_OFFSET_MIN * 60_000;
return new Date(ms);
}
const AMBIGUOUS_TIME_PATTERNS = [
/前几天/u,
/那段(?:时间|日子)/u,
/上次(?:那)?(?:段|个)/u,
/大概.{0,6}(?:昨天|前天|上周|几)/u,
/左右/u,
/不太确定.{0,8}时间/u,
];
const EXPLICIT_TIME_HINT =
/昨天|昨日|今天|今日|明天|明日|前天|后天|上周|这周|本周|这个月|本月|上个月|\d{1,2}\s*月|\d{1,2}\s*[:]\d{2}|最近\s*\d+\s*天|最近一周|最近1周|\d{4}-\d{2}-\d{2}/u;
/**
* @param {string} query
* @param {Date} [now]
*/
export function resolveRainTimeRange(query, now = new Date()) {
const text = String(query ?? '').trim();
for (const pattern of AMBIGUOUS_TIME_PATTERNS) {
if (pattern.test(text)) {
return {
needsClarification: true,
clarificationQuestion:
'请说明要分析 MeInput 输入记录的起止时间(例如「9月2日 18:00 到 9月4日 10:00」,或「昨天全天」)。若你不补充,我将默认使用近 3 天。',
range: null,
source: 'ambiguous',
label: null,
};
}
}
if (!EXPLICIT_TIME_HINT.test(text)) {
const end = endOfDay(now);
const start = addDays(now, -RAIN_DEFAULT_DAYS);
return {
needsClarification: false,
range: { start: start.toISOString(), end: end.toISOString() },
source: 'default_3d',
label: `${RAIN_DEFAULT_DAYS}`,
};
}
const scope = parseTimeScope(text, now);
const isDefaultFallback =
scope.rule_hits?.includes('time:default_week') ||
scope.rule_hits?.includes('time:recent_fuzzy');
if (isDefaultFallback && /最近|近期|这几天/u.test(text) && !/最近\s*\d+\s*天/u.test(text)) {
const end = endOfDay(now);
const start = addDays(now, -RAIN_DEFAULT_DAYS);
return {
needsClarification: false,
range: { start: start.toISOString(), end: end.toISOString() },
source: 'default_3d',
label: `${RAIN_DEFAULT_DAYS}`,
};
}
return {
needsClarification: false,
range: scope.mention_range,
source: 'user_explicit',
label: scope.relative_label,
};
}
export function formatRainTimeRangeLabel(range, meta = {}) {
if (!range?.start || !range?.end) return meta.label ?? '未指定';
const start = range.start.slice(0, 16).replace('T', ' ');
const end = range.end.slice(0, 16).replace('T', ' ');
const suffix = meta.source === 'default_3d' ? '(默认近3天)' : '';
return `${start} ~ ${end}${suffix}`;
}