Files
memind/wechat-intent-router.test.mjs
T
john 91e140d402
Memind CI / Test, build, and release guards (push) Failing after 8s
feat(wechat): add admin-pluggable LLM intent router separate from H5.
Give WeChat MP its own chat.general→page.generate LLM refinement layer with memindadm toggles, shadow mode, and canary openids so service account routing stays independent of the H5 chatIntentRouter.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 20:57:41 +08:00

156 lines
5.3 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';
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');
});