be464a5b8d
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>
100 lines
3.9 KiB
JavaScript
100 lines
3.9 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { resolveRainTimeRange, RAIN_DEFAULT_DAYS } from './rain-service/time-range.mjs';
|
|
import { formatMeinputFullBlock } from './rain-service/meinput-full.mjs';
|
|
import { buildRainGooseHandoffText, stripRainSkillPrefix } from './rain-service/llm-analysis.mjs';
|
|
import {
|
|
RAIN_SKILL_NAME,
|
|
isRainModeMessage,
|
|
filterChatSkills,
|
|
CHAT_SKILL_DEFINITIONS,
|
|
} from './chat-skills.mjs';
|
|
|
|
test('resolveRainTimeRange defaults to 3 days when no time hint', () => {
|
|
const now = new Date('2026-09-04T12:00:00+08:00');
|
|
const result = resolveRainTimeRange('帮我总结最近的输入', now);
|
|
assert.equal(result.needsClarification, false);
|
|
assert.equal(result.source, 'default_3d');
|
|
assert.ok(result.range?.start);
|
|
assert.ok(result.range?.end);
|
|
const spanMs =
|
|
new Date(result.range.end).getTime() - new Date(result.range.start).getTime();
|
|
assert.ok(spanMs >= RAIN_DEFAULT_DAYS * 24 * 60 * 60 * 1000 - 60_000);
|
|
});
|
|
|
|
test('resolveRainTimeRange asks clarification for ambiguous phrases', () => {
|
|
const result = resolveRainTimeRange('前几天我在做什么', new Date('2026-09-04T12:00:00+08:00'));
|
|
assert.equal(result.needsClarification, true);
|
|
assert.match(result.clarificationQuestion ?? '', /起止时间/);
|
|
});
|
|
|
|
test('resolveRainTimeRange parses yesterday explicitly', () => {
|
|
const now = new Date('2026-09-04T12:00:00+08:00');
|
|
const result = resolveRainTimeRange('我昨天输入了什么', now);
|
|
assert.equal(result.needsClarification, false);
|
|
assert.equal(result.source, 'user_explicit');
|
|
assert.equal(result.label, 'yesterday');
|
|
});
|
|
|
|
test('formatMeinputFullBlock lists every record with timestamp', () => {
|
|
const block = formatMeinputFullBlock(
|
|
[
|
|
{
|
|
created_at: '2026-09-02T19:42:16.541Z',
|
|
text: '项目',
|
|
app_name: 'Cursor',
|
|
app_bundle_id: 'com.cursor',
|
|
},
|
|
{
|
|
created_at: '2026-09-02T19:46:15.181Z',
|
|
text: '手机',
|
|
app_name: null,
|
|
app_bundle_id: 'com.apple.mobile',
|
|
},
|
|
],
|
|
{
|
|
range: { start: '2026-09-01T00:00:00.000Z', end: '2026-09-04T00:00:00.000Z' },
|
|
label: '近3天',
|
|
},
|
|
);
|
|
assert.match(block, /MeInput 原始输入 · Rain/);
|
|
assert.match(block, /项目/);
|
|
assert.match(block, /手机/);
|
|
assert.match(block, /2026-09-02 19:42:16/);
|
|
assert.doesNotMatch(block, /0\.2795/);
|
|
});
|
|
|
|
test('buildRainGooseHandoffText carries analysis to agent', () => {
|
|
const text = buildRainGooseHandoffText({
|
|
userQuery: '最近我输入了什么',
|
|
timeRangeLabel: '近3天',
|
|
recordCount: 12,
|
|
analysis: '用户在 Cursor 中输入了项目相关词',
|
|
userGoal: '回顾输入',
|
|
suggestedNextSteps: ['给用户时间线总结'],
|
|
});
|
|
assert.match(text, /Rain · MeInput 分析简报/);
|
|
assert.match(text, /用户在 Cursor 中输入了项目相关词/);
|
|
assert.match(text, /最近我输入了什么/);
|
|
});
|
|
|
|
test('isRainModeMessage detects selected rain skill', () => {
|
|
assert.equal(
|
|
isRainModeMessage({ metadata: { memindRun: { selectedChatSkill: RAIN_SKILL_NAME } } }),
|
|
true,
|
|
);
|
|
assert.equal(isRainModeMessage({ metadata: { memindRun: { selectedChatSkill: 'web' } } }), false);
|
|
});
|
|
|
|
test('filterChatSkills hides page templates by default', () => {
|
|
const options = CHAT_SKILL_DEFINITIONS.map((def) => ({ ...def, buildPrompt: () => '' }));
|
|
const filtered = filterChatSkills(options, { grantedSkills: ['page-template-travel'], canPublish: true });
|
|
assert.ok(filtered.some((item) => item.id === RAIN_SKILL_NAME));
|
|
assert.equal(filtered.some((item) => item.id === 'page-template-travel'), false);
|
|
});
|
|
|
|
test('stripRainSkillPrefix removes rain prompt header', () => {
|
|
const text = stripRainSkillPrefix('【Rain · MeInput 输入分析】请描述要分析的时间区间和你的诉求。未写时间则默认近3天;区间不明确时我会先追问。我的问题是:总结输入');
|
|
assert.equal(text, '总结输入');
|
|
});
|