Files
memind/scripts/verify-rain-chat.mjs
T
john be464a5b8d
Memind CI / Test, build, and release guards (push) Has been cancelled
Add Rain V0 for MeInput full-range chat analysis and delivery tooling.
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>
2026-09-04 13:49:40 +08:00

85 lines
3.0 KiB
JavaScript

#!/usr/bin/env node
/**
* Verify Rain mode: full meinput load + LLM → Goose handoff.
*
* Usage:
* MEMIND_USERNAME=john MEMIND_PASSWORD=981122tj node scripts/verify-rain-chat.mjs
*/
import { loadH5Environment } from './load-env.mjs';
import {
createAgentRun,
createReporter,
extractAssistantTexts,
getSession,
loginViaApi,
resolvePortalBase,
waitForAssistantGrowth,
waitForRunTerminal,
} from './scenario-test-lib.mjs';
import { RAIN_SKILL_NAME } from '../chat-skills.mjs';
loadH5Environment(import.meta.dirname);
const QUERY = process.env.RAIN_VERIFY_QUERY ?? '最近我输入了什么?';
const baseUrl = (process.env.MEMIND_BASE_URL ?? resolvePortalBase(Number(process.env.H5_PORT ?? 8081))).replace(/\/$/, '');
const account = {
username: process.env.MEMIND_USERNAME ?? 'john',
password: process.env.MEMIND_PASSWORD ?? process.env.JOHN_PASSWORD ?? '981122tj',
};
async function main() {
const reporter = createReporter();
console.log(`==> Rain verify\n Portal: ${baseUrl}\n User: ${account.username}\n Query: ${QUERY}\n`);
const auth = await loginViaApi(baseUrl, account, reporter);
const run = await createAgentRun(baseUrl, auth.cookie, {
message: QUERY,
selectedChatSkill: RAIN_SKILL_NAME,
});
// Patch message shape for rain metadata (createAgentRun uses buildUserMessage)
reporter.pass('发起 Rain run', run.runId);
const terminal = await waitForRunTerminal(baseUrl, auth.cookie, run.runId, 180000);
if (terminal.status !== 'succeeded') {
const errText = String(terminal.error ?? terminal.lastError ?? '');
if (/Arrearage|Access denied/i.test(errText)) {
reporter.fail('run 终态', `LLM 账户欠费/不可用,非 Rain 逻辑错误:${errText.slice(0, 120)}`);
} else {
reporter.fail('run 终态', terminal.status ?? errText.slice(0, 120) ?? 'unknown');
}
} else {
reporter.pass('run 终态', 'succeeded');
}
const sessionId = run.sessionId ?? terminal.sessionId ?? terminal.agent_session_id;
const session = await getSession(baseUrl, auth.cookie, sessionId);
const texts = extractAssistantTexts(session.session ?? session.payload ?? session);
const reply = texts.join('\n').trim();
if (!reply) {
reporter.fail('助手回复', '空');
} else {
console.log('\n--- assistant ---\n', reply.slice(0, 800), '\n---\n');
reporter.pass('助手回复', `${reply.length} 字符`);
if (/疲惫|车载冰箱|便签页面内容对所有人可见|TKMind 记忆系统/u.test(reply) && !/MeInput|输入|项目|手机|Rain/u.test(reply)) {
reporter.fail('注入隔离', '回复像 Memory V2,未体现 MeInput');
} else {
reporter.pass('注入隔离', '未检测到典型长期记忆污染');
}
if (/0\.\d{4}/.test(reply) && /关联值|评分|权重/u.test(reply)) {
reporter.fail('分数泄漏', '回复含 recall 分数语义');
} else {
reporter.pass('分数泄漏', '未检测到');
}
}
process.exit(reporter.summary());
}
main().catch((err) => {
console.error(err);
process.exit(1);
});