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>
85 lines
3.0 KiB
JavaScript
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);
|
|
});
|