8f88eec2bd
Memind CI / Test, build, and release guards (push) Successful in 4m40s
Add channel prefixes, pin edit targets in Cursor prompts, and force fresh sessions for page refine URLs so DeepSeek/Goose chat history does not pollute page tasks. Co-authored-by: Cursor <cursoragent@cursor.com>
197 lines
6.8 KiB
JavaScript
197 lines
6.8 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {
|
|
createWechatIntentRouter,
|
|
isWechatIntentLlmEligible,
|
|
normalizeWechatLlmIntent,
|
|
parseWechatIntentJson,
|
|
resolveWechatIntentRouterPolicy,
|
|
shouldRefineWechatIntent,
|
|
} from './wechat-intent-router.mjs';
|
|
import {
|
|
createWechatIntentRouterConfigService,
|
|
defaultsFromEnv,
|
|
} from './wechat-intent-router-config.mjs';
|
|
import { isPageGenerateText } from './wechat/intent/patterns.mjs';
|
|
import { classifyWechatIntent } from './wechat/intent/classifier.mjs';
|
|
|
|
test('classifyWechatIntent honors channel prefix for chat vs page', () => {
|
|
assert.equal(
|
|
classifyWechatIntent({ msgType: 'text', agentText: '【聊天】帮我做一个游玩攻略页面' }).kind,
|
|
'chat.general',
|
|
);
|
|
assert.equal(
|
|
classifyWechatIntent({ msgType: 'text', agentText: '【改页】public/demo.html 更详细' }).kind,
|
|
'page.generate',
|
|
);
|
|
});
|
|
|
|
test('isPageGenerateText matches travel guide requests without explicit 页面', () => {
|
|
assert.equal(
|
|
isPageGenerateText('帮我做一个嵊泗 3 天 2 晚的游玩攻略吧,可能'),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
isPageGenerateText('现帮我做一个嵊泗 3 天 2 晚的游玩攻略页面,'),
|
|
true,
|
|
);
|
|
});
|
|
|
|
test('isPageGenerateText matches page refine and MindSpace URL edit requests', () => {
|
|
assert.equal(
|
|
isPageGenerateText('页面还不够详细,必须详细到时间节点'),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
isPageGenerateText('这个页面还不够详细,必须详细到时间节点,把页面更新更详细和完整'),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
isPageGenerateText(
|
|
'https://m.tkmind.cn/MindSpace/a70ff537-8908-486e-9b6c-042e07cc25db/public/shengsi-3day-guide.html这个页面还不够详细,必须详细到时间节点,把页面更新更详细和完整',
|
|
),
|
|
true,
|
|
);
|
|
});
|
|
|
|
test('resolveWechatIntentRouterPolicy reads env defaults', () => {
|
|
const policy = resolveWechatIntentRouterPolicy({
|
|
MEMIND_WECHAT_INTENT_LLM_ENABLED: '1',
|
|
MEMIND_WECHAT_INTENT_LLM_SHADOW: '0',
|
|
MEMIND_WECHAT_INTENT_MODEL: 'deepseek-v4-pro',
|
|
MEMIND_WECHAT_INTENT_MIN_CONFIDENCE: '0.7',
|
|
MEMIND_WECHAT_INTENT_TIMEOUT_MS: '5000',
|
|
MEMIND_WECHAT_INTENT_CANARY_OPENIDS: 'openid-a, openid-b',
|
|
});
|
|
assert.equal(policy.enabled, true);
|
|
assert.equal(policy.shadowMode, false);
|
|
assert.equal(policy.model, 'deepseek-v4-pro');
|
|
assert.equal(policy.minConfidence, 0.7);
|
|
assert.equal(policy.timeoutMs, 5000);
|
|
assert.deepEqual(policy.canaryOpenids, ['openid-a', 'openid-b']);
|
|
});
|
|
|
|
test('shouldRefineWechatIntent only refines chat.general', () => {
|
|
assert.equal(shouldRefineWechatIntent({ kind: 'chat.general' }, '整理成一篇给读者看的文章'), true);
|
|
assert.equal(shouldRefineWechatIntent({ kind: 'page.generate' }, '生成 HTML 页面'), false);
|
|
assert.equal(shouldRefineWechatIntent({ kind: 'greeting' }, '你好'), false);
|
|
});
|
|
|
|
test('isWechatIntentLlmEligible respects canary openids', () => {
|
|
const policy = { enabled: true, canaryOpenids: ['openid-a'] };
|
|
assert.equal(isWechatIntentLlmEligible({ policy, openid: 'openid-a' }), true);
|
|
assert.equal(isWechatIntentLlmEligible({ policy, openid: 'openid-b' }), false);
|
|
assert.equal(isWechatIntentLlmEligible({ policy: { enabled: true, canaryOpenids: [] }, openid: 'x' }), true);
|
|
});
|
|
|
|
test('createWechatIntentRouter upgrades chat.general to page.generate in active mode', async () => {
|
|
const router = createWechatIntentRouter({
|
|
policy: resolveWechatIntentRouterPolicy({
|
|
MEMIND_WECHAT_INTENT_LLM_ENABLED: '1',
|
|
MEMIND_WECHAT_INTENT_LLM_SHADOW: '0',
|
|
MEMIND_WECHAT_INTENT_MIN_CONFIDENCE: '0.6',
|
|
}),
|
|
llmProviderService: {
|
|
async createChatCompletion() {
|
|
return {
|
|
ok: true,
|
|
reply: JSON.stringify({
|
|
kind: 'page.generate',
|
|
confidence: 0.92,
|
|
reason: '用户希望整理成可发布页面',
|
|
}),
|
|
model: 'deepseek-v4-pro',
|
|
};
|
|
},
|
|
},
|
|
});
|
|
|
|
const result = await router.refineIntent({
|
|
ruleIntent: { kind: 'chat.general', text: '帮我整理成一篇给读者看的专题页' },
|
|
text: '帮我整理成一篇给读者看的专题页',
|
|
openid: 'openid-a',
|
|
});
|
|
|
|
assert.equal(result.kind, 'page.generate');
|
|
assert.equal(result.intentSource, 'llm');
|
|
assert.equal(result.wantsDocx, false);
|
|
});
|
|
|
|
test('createWechatIntentRouter keeps baseline in shadow mode', async () => {
|
|
const router = createWechatIntentRouter({
|
|
policy: resolveWechatIntentRouterPolicy({
|
|
MEMIND_WECHAT_INTENT_LLM_ENABLED: '1',
|
|
MEMIND_WECHAT_INTENT_LLM_SHADOW: '1',
|
|
}),
|
|
llmProviderService: {
|
|
async createChatCompletion() {
|
|
return {
|
|
ok: true,
|
|
reply: JSON.stringify({
|
|
kind: 'page.generate',
|
|
confidence: 0.95,
|
|
reason: 'shadow',
|
|
}),
|
|
};
|
|
},
|
|
},
|
|
});
|
|
|
|
const result = await router.refineIntent({
|
|
ruleIntent: { kind: 'chat.general', text: '整理成文章' },
|
|
text: '整理成文章',
|
|
});
|
|
|
|
assert.equal(result.kind, 'chat.general');
|
|
assert.equal(result.intentSource, 'rules');
|
|
assert.equal(result.llmShadow?.wouldChangeKind, true);
|
|
});
|
|
|
|
test('wechat intent router config service persists admin toggles', async () => {
|
|
const rows = new Map();
|
|
const pool = {
|
|
async query(sql, params = []) {
|
|
if (String(sql).includes('CREATE TABLE')) return [[]];
|
|
if (String(sql).includes('SELECT config_json')) {
|
|
const row = rows.get(params[0]);
|
|
return [row ? [row] : []];
|
|
}
|
|
if (String(sql).includes('INSERT INTO')) {
|
|
rows.set(params[0], {
|
|
config_json: params[1],
|
|
updated_by: params[2],
|
|
updated_at: params[3],
|
|
});
|
|
return [{ affectedRows: 1 }];
|
|
}
|
|
throw new Error(`unexpected sql: ${sql}`);
|
|
},
|
|
};
|
|
|
|
const service = createWechatIntentRouterConfigService(pool, {
|
|
env: defaultsFromEnv({}),
|
|
});
|
|
const saved = await service.updateConfig({
|
|
enabled: true,
|
|
shadowMode: true,
|
|
model: 'deepseek-v4-flash',
|
|
canaryOpenids: 'openid-test',
|
|
}, { updatedBy: 'admin-1' });
|
|
|
|
assert.equal(saved.enabled, true);
|
|
assert.equal(saved.shadowMode, true);
|
|
assert.equal(saved.model, 'deepseek-v4-flash');
|
|
assert.deepEqual(saved.canaryOpenids, ['openid-test']);
|
|
|
|
const runtime = await service.getRuntimeState();
|
|
assert.equal(runtime.overrides.MEMIND_WECHAT_INTENT_LLM_ENABLED, '1');
|
|
assert.equal(runtime.overrides.MEMIND_WECHAT_INTENT_LLM_SHADOW, '1');
|
|
assert.equal(runtime.overrides.MEMIND_WECHAT_INTENT_MODEL, 'deepseek-v4-flash');
|
|
});
|
|
|
|
test('parseWechatIntentJson accepts fenced JSON', () => {
|
|
const parsed = parseWechatIntentJson('```json\n{"kind":"page.generate","confidence":0.8}\n```');
|
|
assert.equal(parsed.kind, 'page.generate');
|
|
assert.equal(normalizeWechatLlmIntent(parsed).kind, 'page.generate');
|
|
});
|